1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc.
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
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.
37 The following diagram shows how redisplay code is invoked. As you
38 can see, Lisp calls redisplay and vice versa. Under window systems
39 like X, some portions of the redisplay code are also called
40 asynchronously during mouse movement or expose events. It is very
41 important that these code parts do NOT use the C library (malloc,
42 free) because many C libraries under Unix are not reentrant. They
43 may also NOT call functions of the Lisp interpreter which could
44 change the interpreter's state. If you don't follow these rules,
45 you will encounter bugs which are very hard to explain.
47 +--------------+ redisplay +----------------+
48 | Lisp machine |---------------->| Redisplay code |<--+
49 +--------------+ (xdisp.c) +----------------+ |
51 +----------------------------------+ |
52 Don't use this path when called |
55 expose_window (asynchronous) |
57 X expose events -----+
59 What does redisplay do? Obviously, it has to figure out somehow what
60 has been changed since the last time the display has been updated,
61 and to make these changes visible. Preferably it would do that in
62 a moderately intelligent way, i.e. fast.
64 Changes in buffer text can be deduced from window and buffer
65 structures, and from some global variables like `beg_unchanged' and
66 `end_unchanged'. The contents of the display are additionally
67 recorded in a `glyph matrix', a two-dimensional matrix of glyph
68 structures. Each row in such a matrix corresponds to a line on the
69 display, and each glyph in a row corresponds to a column displaying
70 a character, an image, or what else. This matrix is called the
71 `current glyph matrix' or `current matrix' in redisplay
74 For buffer parts that have been changed since the last update, a
75 second glyph matrix is constructed, the so called `desired glyph
76 matrix' or short `desired matrix'. Current and desired matrix are
77 then compared to find a cheap way to update the display, e.g. by
78 reusing part of the display by scrolling lines.
80 You will find a lot of redisplay optimizations when you start
81 looking at the innards of redisplay. The overall goal of all these
82 optimizations is to make redisplay fast because it is done
83 frequently. Some of these optimizations are implemented by the
88 This function tries to update the display if the text in the
89 window did not change and did not scroll, only point moved, and
90 it did not move off the displayed portion of the text.
92 . try_window_reusing_current_matrix
94 This function reuses the current matrix of a window when text
95 has not changed, but the window start changed (e.g., due to
100 This function attempts to redisplay a window by reusing parts of
101 its existing display. It finds and reuses the part that was not
102 changed, and redraws the rest.
106 This function performs the full redisplay of a single window
107 assuming that its fonts were not changed and that the cursor
108 will not end up in the scroll margins. (Loading fonts requires
109 re-adjustment of dimensions of glyph matrices, which makes this
110 method impossible to use.)
112 These optimizations are tried in sequence (some can be skipped if
113 it is known that they are not applicable). If none of the
114 optimizations were successful, redisplay calls redisplay_windows,
115 which performs a full redisplay of all windows.
119 Desired matrices are always built per Emacs window. The function
120 `display_line' is the central function to look at if you are
121 interested. It constructs one row in a desired matrix given an
122 iterator structure containing both a buffer position and a
123 description of the environment in which the text is to be
124 displayed. But this is too early, read on.
126 Characters and pixmaps displayed for a range of buffer text depend
127 on various settings of buffers and windows, on overlays and text
128 properties, on display tables, on selective display. The good news
129 is that all this hairy stuff is hidden behind a small set of
130 interface functions taking an iterator structure (struct it)
133 Iteration over things to be displayed is then simple. It is
134 started by initializing an iterator with a call to init_iterator.
135 Calls to get_next_display_element fill the iterator structure with
136 relevant information about the next thing to display. Calls to
137 set_iterator_to_next move the iterator to the next thing.
139 Besides this, an iterator also contains information about the
140 display environment in which glyphs for display elements are to be
141 produced. It has fields for the width and height of the display,
142 the information whether long lines are truncated or continued, a
143 current X and Y position, and lots of other stuff you can better
146 Glyphs in a desired matrix are normally constructed in a loop
147 calling get_next_display_element and then PRODUCE_GLYPHS. The call
148 to PRODUCE_GLYPHS will fill the iterator structure with pixel
149 information about the element being displayed and at the same time
150 produce glyphs for it. If the display element fits on the line
151 being displayed, set_iterator_to_next is called next, otherwise the
152 glyphs produced are discarded. The function display_line is the
153 workhorse of filling glyph rows in the desired matrix with glyphs.
154 In addition to producing glyphs, it also handles line truncation
155 and continuation, word wrap, and cursor positioning (for the
156 latter, see also set_cursor_from_row).
160 That just couldn't be all, could it? What about terminal types not
161 supporting operations on sub-windows of the screen? To update the
162 display on such a terminal, window-based glyph matrices are not
163 well suited. To be able to reuse part of the display (scrolling
164 lines up and down), we must instead have a view of the whole
165 screen. This is what `frame matrices' are for. They are a trick.
167 Frames on terminals like above have a glyph pool. Windows on such
168 a frame sub-allocate their glyph memory from their frame's glyph
169 pool. The frame itself is given its own glyph matrices. By
170 coincidence---or maybe something else---rows in window glyph
171 matrices are slices of corresponding rows in frame matrices. Thus
172 writing to window matrices implicitly updates a frame matrix which
173 provides us with the view of the whole screen that we originally
174 wanted to have without having to move many bytes around. To be
175 honest, there is a little bit more done, but not much more. If you
176 plan to extend that code, take a look at dispnew.c. The function
177 build_frame_matrix is a good starting point.
179 Bidirectional display.
181 Bidirectional display adds quite some hair to this already complex
182 design. The good news are that a large portion of that hairy stuff
183 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
184 reordering engine which is called by set_iterator_to_next and
185 returns the next character to display in the visual order. See
186 commentary on bidi.c for more details. As far as redisplay is
187 concerned, the effect of calling bidi_move_to_visually_next, the
188 main interface of the reordering engine, is that the iterator gets
189 magically placed on the buffer or string position that is to be
190 displayed next. In other words, a linear iteration through the
191 buffer/string is replaced with a non-linear one. All the rest of
192 the redisplay is oblivious to the bidi reordering.
194 Well, almost oblivious---there are still complications, most of
195 them due to the fact that buffer and string positions no longer
196 change monotonously with glyph indices in a glyph row. Moreover,
197 for continued lines, the buffer positions may not even be
198 monotonously changing with vertical positions. Also, accounting
199 for face changes, overlays, etc. becomes more complex because
200 non-linear iteration could potentially skip many positions with
201 changes, and then cross them again on the way back...
203 One other prominent effect of bidirectional display is that some
204 paragraphs of text need to be displayed starting at the right
205 margin of the window---the so-called right-to-left, or R2L
206 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
207 which have their reversed_p flag set. The bidi reordering engine
208 produces characters in such rows starting from the character which
209 should be the rightmost on display. PRODUCE_GLYPHS then reverses
210 the order, when it fills up the glyph row whose reversed_p flag is
211 set, by prepending each new glyph to what is already there, instead
212 of appending it. When the glyph row is complete, the function
213 extend_face_to_end_of_line fills the empty space to the left of the
214 leftmost character with special glyphs, which will display as,
215 well, empty. On text terminals, these special glyphs are simply
216 blank characters. On graphics terminals, there's a single stretch
217 glyph with suitably computed width. Both the blanks and the
218 stretch glyph are given the face of the background of the line.
219 This way, the terminal-specific back-end can still draw the glyphs
220 left to right, even for R2L lines.
222 Note one important detail mentioned above: that the bidi reordering
223 engine, driven by the iterator, produces characters in R2L rows
224 starting at the character that will be the rightmost on display.
225 As far as the iterator is concerned, the geometry of such rows is
226 still left to right, i.e. the iterator "thinks" the first character
227 is at the leftmost pixel position. The iterator does not know that
228 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
229 delivers. This is important when functions from the the move_it_*
230 family are used to get to certain screen position or to match
231 screen coordinates with buffer coordinates: these functions use the
232 iterator geometry, which is left to right even in R2L paragraphs.
233 This works well with most callers of move_it_*, because they need
234 to get to a specific column, and columns are still numbered in the
235 reading order, i.e. the rightmost character in a R2L paragraph is
236 still column zero. But some callers do not get well with this; a
237 notable example is mouse clicks that need to find the character
238 that corresponds to certain pixel coordinates. See
239 buffer_posn_from_coords in dispnew.c for how this is handled. */
247 #include "keyboard.h"
250 #include "termchar.h"
251 #include "dispextern.h"
253 #include "character.h"
256 #include "commands.h"
260 #include "termhooks.h"
261 #include "termopts.h"
262 #include "intervals.h"
265 #include "region-cache.h"
268 #include "blockinput.h"
270 #ifdef HAVE_X_WINDOWS
285 #ifndef FRAME_X_OUTPUT
286 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
289 #define INFINITY 10000000
291 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
292 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
293 Lisp_Object Qwindow_text_change_functions
, Vwindow_text_change_functions
;
294 Lisp_Object Qredisplay_end_trigger_functions
, Vredisplay_end_trigger_functions
;
295 Lisp_Object Qinhibit_point_motion_hooks
;
296 Lisp_Object QCeval
, QCfile
, QCdata
, QCpropertize
;
297 Lisp_Object Qfontified
;
298 Lisp_Object Qgrow_only
;
299 Lisp_Object Qinhibit_eval_during_redisplay
;
300 Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
301 Lisp_Object Qright_to_left
, Qleft_to_right
;
304 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
307 Lisp_Object Qarrow
, Qhand
, Qtext
;
309 Lisp_Object Qrisky_local_variable
;
311 /* Holds the list (error). */
312 Lisp_Object list_of_error
;
314 /* Functions called to fontify regions of text. */
316 Lisp_Object Vfontification_functions
;
317 Lisp_Object Qfontification_functions
;
319 /* Non-nil means automatically select any window when the mouse
320 cursor moves into it. */
321 Lisp_Object Vmouse_autoselect_window
;
323 Lisp_Object Vwrap_prefix
, Qwrap_prefix
;
324 Lisp_Object Vline_prefix
, Qline_prefix
;
326 /* Non-zero means draw tool bar buttons raised when the mouse moves
329 int auto_raise_tool_bar_buttons_p
;
331 /* Non-zero means to reposition window if cursor line is only partially visible. */
333 int make_cursor_line_fully_visible_p
;
335 /* Margin below tool bar in pixels. 0 or nil means no margin.
336 If value is `internal-border-width' or `border-width',
337 the corresponding frame parameter is used. */
339 Lisp_Object Vtool_bar_border
;
341 /* Margin around tool bar buttons in pixels. */
343 Lisp_Object Vtool_bar_button_margin
;
345 /* Thickness of shadow to draw around tool bar buttons. */
347 EMACS_INT tool_bar_button_relief
;
349 /* Non-nil means automatically resize tool-bars so that all tool-bar
350 items are visible, and no blank lines remain.
352 If value is `grow-only', only make tool-bar bigger. */
354 Lisp_Object Vauto_resize_tool_bars
;
356 /* Type of tool bar. Can be symbols image, text, both or both-hroiz. */
358 Lisp_Object Vtool_bar_style
;
360 /* Maximum number of characters a label can have to be shown. */
362 EMACS_INT tool_bar_max_label_size
;
364 /* Non-zero means draw block and hollow cursor as wide as the glyph
365 under it. For example, if a block cursor is over a tab, it will be
366 drawn as wide as that tab on the display. */
368 int x_stretch_cursor_p
;
370 /* Non-nil means don't actually do any redisplay. */
372 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
374 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
376 int inhibit_eval_during_redisplay
;
378 /* Names of text properties relevant for redisplay. */
380 Lisp_Object Qdisplay
;
382 /* Symbols used in text property values. */
384 Lisp_Object Vdisplay_pixels_per_inch
;
385 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
386 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qraise
;
389 Lisp_Object Qmargin
, Qpointer
;
390 Lisp_Object Qline_height
;
392 /* Non-nil means highlight trailing whitespace. */
394 Lisp_Object Vshow_trailing_whitespace
;
396 /* Non-nil means escape non-break space and hyphens. */
398 Lisp_Object Vnobreak_char_display
;
400 #ifdef HAVE_WINDOW_SYSTEM
402 /* Test if overflow newline into fringe. Called with iterator IT
403 at or past right window margin, and with IT->current_x set. */
405 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
406 (!NILP (Voverflow_newline_into_fringe) \
407 && FRAME_WINDOW_P ((IT)->f) \
408 && ((IT)->bidi_it.paragraph_dir == R2L \
409 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
410 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
411 && (IT)->current_x == (IT)->last_visible_x \
412 && (IT)->line_wrap != WORD_WRAP)
414 #else /* !HAVE_WINDOW_SYSTEM */
415 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
416 #endif /* HAVE_WINDOW_SYSTEM */
418 /* Test if the display element loaded in IT is a space or tab
419 character. This is used to determine word wrapping. */
421 #define IT_DISPLAYING_WHITESPACE(it) \
422 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
424 /* Non-nil means show the text cursor in void text areas
425 i.e. in blank areas after eol and eob. This used to be
426 the default in 21.3. */
428 Lisp_Object Vvoid_text_area_pointer
;
430 /* Name of the face used to highlight trailing whitespace. */
432 Lisp_Object Qtrailing_whitespace
;
434 /* Name and number of the face used to highlight escape glyphs. */
436 Lisp_Object Qescape_glyph
;
438 /* Name and number of the face used to highlight non-breaking spaces. */
440 Lisp_Object Qnobreak_space
;
442 /* The symbol `image' which is the car of the lists used to represent
443 images in Lisp. Also a tool bar style. */
447 /* The image map types. */
448 Lisp_Object QCmap
, QCpointer
;
449 Lisp_Object Qrect
, Qcircle
, Qpoly
;
451 /* Tool bar styles */
452 Lisp_Object Qboth
, Qboth_horiz
, Qtext_image_horiz
;
454 /* Non-zero means print newline to stdout before next mini-buffer
457 int noninteractive_need_newline
;
459 /* Non-zero means print newline to message log before next message. */
461 static int message_log_need_newline
;
463 /* Three markers that message_dolog uses.
464 It could allocate them itself, but that causes trouble
465 in handling memory-full errors. */
466 static Lisp_Object message_dolog_marker1
;
467 static Lisp_Object message_dolog_marker2
;
468 static Lisp_Object message_dolog_marker3
;
470 /* The buffer position of the first character appearing entirely or
471 partially on the line of the selected window which contains the
472 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
473 redisplay optimization in redisplay_internal. */
475 static struct text_pos this_line_start_pos
;
477 /* Number of characters past the end of the line above, including the
478 terminating newline. */
480 static struct text_pos this_line_end_pos
;
482 /* The vertical positions and the height of this line. */
484 static int this_line_vpos
;
485 static int this_line_y
;
486 static int this_line_pixel_height
;
488 /* X position at which this display line starts. Usually zero;
489 negative if first character is partially visible. */
491 static int this_line_start_x
;
493 /* Buffer that this_line_.* variables are referring to. */
495 static struct buffer
*this_line_buffer
;
497 /* Nonzero means truncate lines in all windows less wide than the
500 Lisp_Object Vtruncate_partial_width_windows
;
502 /* A flag to control how to display unibyte 8-bit character. */
504 int unibyte_display_via_language_environment
;
506 /* Nonzero means we have more than one non-mini-buffer-only frame.
507 Not guaranteed to be accurate except while parsing
508 frame-title-format. */
512 Lisp_Object Vglobal_mode_string
;
515 /* List of variables (symbols) which hold markers for overlay arrows.
516 The symbols on this list are examined during redisplay to determine
517 where to display overlay arrows. */
519 Lisp_Object Voverlay_arrow_variable_list
;
521 /* Marker for where to display an arrow on top of the buffer text. */
523 Lisp_Object Voverlay_arrow_position
;
525 /* String to display for the arrow. Only used on terminal frames. */
527 Lisp_Object Voverlay_arrow_string
;
529 /* Values of those variables at last redisplay are stored as
530 properties on `overlay-arrow-position' symbol. However, if
531 Voverlay_arrow_position is a marker, last-arrow-position is its
532 numerical position. */
534 Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
536 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
537 properties on a symbol in overlay-arrow-variable-list. */
539 Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
541 /* Like mode-line-format, but for the title bar on a visible frame. */
543 Lisp_Object Vframe_title_format
;
545 /* Like mode-line-format, but for the title bar on an iconified frame. */
547 Lisp_Object Vicon_title_format
;
549 /* List of functions to call when a window's size changes. These
550 functions get one arg, a frame on which one or more windows' sizes
553 static Lisp_Object Vwindow_size_change_functions
;
555 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
557 /* Nonzero if an overlay arrow has been displayed in this window. */
559 static int overlay_arrow_seen
;
561 /* Nonzero means highlight the region even in nonselected windows. */
563 int highlight_nonselected_windows
;
565 /* If cursor motion alone moves point off frame, try scrolling this
566 many lines up or down if that will bring it back. */
568 static EMACS_INT scroll_step
;
570 /* Nonzero means scroll just far enough to bring point back on the
571 screen, when appropriate. */
573 static EMACS_INT scroll_conservatively
;
575 /* Recenter the window whenever point gets within this many lines of
576 the top or bottom of the window. This value is translated into a
577 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
578 that there is really a fixed pixel height scroll margin. */
580 EMACS_INT scroll_margin
;
582 /* Number of windows showing the buffer of the selected window (or
583 another buffer with the same base buffer). keyboard.c refers to
588 /* Vector containing glyphs for an ellipsis `...'. */
590 static Lisp_Object default_invis_vector
[3];
592 /* Zero means display the mode-line/header-line/menu-bar in the default face
593 (this slightly odd definition is for compatibility with previous versions
594 of emacs), non-zero means display them using their respective faces.
596 This variable is deprecated. */
598 int mode_line_inverse_video
;
600 /* Prompt to display in front of the mini-buffer contents. */
602 Lisp_Object minibuf_prompt
;
604 /* Width of current mini-buffer prompt. Only set after display_line
605 of the line that contains the prompt. */
607 int minibuf_prompt_width
;
609 /* This is the window where the echo area message was displayed. It
610 is always a mini-buffer window, but it may not be the same window
611 currently active as a mini-buffer. */
613 Lisp_Object echo_area_window
;
615 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
616 pushes the current message and the value of
617 message_enable_multibyte on the stack, the function restore_message
618 pops the stack and displays MESSAGE again. */
620 Lisp_Object Vmessage_stack
;
622 /* Nonzero means multibyte characters were enabled when the echo area
623 message was specified. */
625 int message_enable_multibyte
;
627 /* Nonzero if we should redraw the mode lines on the next redisplay. */
629 int update_mode_lines
;
631 /* Nonzero if window sizes or contents have changed since last
632 redisplay that finished. */
634 int windows_or_buffers_changed
;
636 /* Nonzero means a frame's cursor type has been changed. */
638 int cursor_type_changed
;
640 /* Nonzero after display_mode_line if %l was used and it displayed a
643 int line_number_displayed
;
645 /* Maximum buffer size for which to display line numbers. */
647 Lisp_Object Vline_number_display_limit
;
649 /* Line width to consider when repositioning for line number display. */
651 static EMACS_INT line_number_display_limit_width
;
653 /* Number of lines to keep in the message log buffer. t means
654 infinite. nil means don't log at all. */
656 Lisp_Object Vmessage_log_max
;
658 /* The name of the *Messages* buffer, a string. */
660 static Lisp_Object Vmessages_buffer_name
;
662 /* Current, index 0, and last displayed echo area message. Either
663 buffers from echo_buffers, or nil to indicate no message. */
665 Lisp_Object echo_area_buffer
[2];
667 /* The buffers referenced from echo_area_buffer. */
669 static Lisp_Object echo_buffer
[2];
671 /* A vector saved used in with_area_buffer to reduce consing. */
673 static Lisp_Object Vwith_echo_area_save_vector
;
675 /* Non-zero means display_echo_area should display the last echo area
676 message again. Set by redisplay_preserve_echo_area. */
678 static int display_last_displayed_message_p
;
680 /* Nonzero if echo area is being used by print; zero if being used by
683 int message_buf_print
;
685 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
687 Lisp_Object Qinhibit_menubar_update
;
688 int inhibit_menubar_update
;
690 /* When evaluating expressions from menu bar items (enable conditions,
691 for instance), this is the frame they are being processed for. */
693 Lisp_Object Vmenu_updating_frame
;
695 /* Maximum height for resizing mini-windows. Either a float
696 specifying a fraction of the available height, or an integer
697 specifying a number of lines. */
699 Lisp_Object Vmax_mini_window_height
;
701 /* Non-zero means messages should be displayed with truncated
702 lines instead of being continued. */
704 int message_truncate_lines
;
705 Lisp_Object Qmessage_truncate_lines
;
707 /* Set to 1 in clear_message to make redisplay_internal aware
708 of an emptied echo area. */
710 static int message_cleared_p
;
712 /* How to blink the default frame cursor off. */
713 Lisp_Object Vblink_cursor_alist
;
715 /* A scratch glyph row with contents used for generating truncation
716 glyphs. Also used in direct_output_for_insert. */
718 #define MAX_SCRATCH_GLYPHS 100
719 struct glyph_row scratch_glyph_row
;
720 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
722 /* Ascent and height of the last line processed by move_it_to. */
724 static int last_max_ascent
, last_height
;
726 /* Non-zero if there's a help-echo in the echo area. */
728 int help_echo_showing_p
;
730 /* If >= 0, computed, exact values of mode-line and header-line height
731 to use in the macros CURRENT_MODE_LINE_HEIGHT and
732 CURRENT_HEADER_LINE_HEIGHT. */
734 int current_mode_line_height
, current_header_line_height
;
736 /* The maximum distance to look ahead for text properties. Values
737 that are too small let us call compute_char_face and similar
738 functions too often which is expensive. Values that are too large
739 let us call compute_char_face and alike too often because we
740 might not be interested in text properties that far away. */
742 #define TEXT_PROP_DISTANCE_LIMIT 100
746 /* Variables to turn off display optimizations from Lisp. */
748 int inhibit_try_window_id
, inhibit_try_window_reusing
;
749 int inhibit_try_cursor_movement
;
751 /* Non-zero means print traces of redisplay if compiled with
754 int trace_redisplay_p
;
756 #endif /* GLYPH_DEBUG */
758 #ifdef DEBUG_TRACE_MOVE
759 /* Non-zero means trace with TRACE_MOVE to stderr. */
762 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
764 #define TRACE_MOVE(x) (void) 0
767 /* Non-zero means automatically scroll windows horizontally to make
770 int automatic_hscrolling_p
;
771 Lisp_Object Qauto_hscroll_mode
;
773 /* How close to the margin can point get before the window is scrolled
775 EMACS_INT hscroll_margin
;
777 /* How much to scroll horizontally when point is inside the above margin. */
778 Lisp_Object Vhscroll_step
;
780 /* The variable `resize-mini-windows'. If nil, don't resize
781 mini-windows. If t, always resize them to fit the text they
782 display. If `grow-only', let mini-windows grow only until they
785 Lisp_Object Vresize_mini_windows
;
787 /* Buffer being redisplayed -- for redisplay_window_error. */
789 struct buffer
*displayed_buffer
;
791 /* Space between overline and text. */
793 EMACS_INT overline_margin
;
795 /* Require underline to be at least this many screen pixels below baseline
796 This to avoid underline "merging" with the base of letters at small
797 font sizes, particularly when x_use_underline_position_properties is on. */
799 EMACS_INT underline_minimum_offset
;
801 /* Value returned from text property handlers (see below). */
806 HANDLED_RECOMPUTE_PROPS
,
807 HANDLED_OVERLAY_STRING_CONSUMED
,
811 /* A description of text properties that redisplay is interested
816 /* The name of the property. */
819 /* A unique index for the property. */
822 /* A handler function called to set up iterator IT from the property
823 at IT's current position. Value is used to steer handle_stop. */
824 enum prop_handled (*handler
) (struct it
*it
);
827 static enum prop_handled
handle_face_prop (struct it
*);
828 static enum prop_handled
handle_invisible_prop (struct it
*);
829 static enum prop_handled
handle_display_prop (struct it
*);
830 static enum prop_handled
handle_composition_prop (struct it
*);
831 static enum prop_handled
handle_overlay_change (struct it
*);
832 static enum prop_handled
handle_fontified_prop (struct it
*);
834 /* Properties handled by iterators. */
836 static struct props it_props
[] =
838 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
839 /* Handle `face' before `display' because some sub-properties of
840 `display' need to know the face. */
841 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
842 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
843 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
844 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
848 /* Value is the position described by X. If X is a marker, value is
849 the marker_position of X. Otherwise, value is X. */
851 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
853 /* Enumeration returned by some move_it_.* functions internally. */
857 /* Not used. Undefined value. */
860 /* Move ended at the requested buffer position or ZV. */
861 MOVE_POS_MATCH_OR_ZV
,
863 /* Move ended at the requested X pixel position. */
866 /* Move within a line ended at the end of a line that must be
870 /* Move within a line ended at the end of a line that would
871 be displayed truncated. */
874 /* Move within a line ended at a line end. */
878 /* This counter is used to clear the face cache every once in a while
879 in redisplay_internal. It is incremented for each redisplay.
880 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
883 #define CLEAR_FACE_CACHE_COUNT 500
884 static int clear_face_cache_count
;
886 /* Similarly for the image cache. */
888 #ifdef HAVE_WINDOW_SYSTEM
889 #define CLEAR_IMAGE_CACHE_COUNT 101
890 static int clear_image_cache_count
;
893 /* Non-zero while redisplay_internal is in progress. */
897 /* Non-zero means don't free realized faces. Bound while freeing
898 realized faces is dangerous because glyph matrices might still
901 int inhibit_free_realized_faces
;
902 Lisp_Object Qinhibit_free_realized_faces
;
904 /* If a string, XTread_socket generates an event to display that string.
905 (The display is done in read_char.) */
907 Lisp_Object help_echo_string
;
908 Lisp_Object help_echo_window
;
909 Lisp_Object help_echo_object
;
912 /* Temporary variable for XTread_socket. */
914 Lisp_Object previous_help_echo_string
;
916 /* Null glyph slice */
918 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
920 /* Platform-independent portion of hourglass implementation. */
922 /* Non-zero means we're allowed to display a hourglass pointer. */
923 int display_hourglass_p
;
925 /* Non-zero means an hourglass cursor is currently shown. */
926 int hourglass_shown_p
;
928 /* If non-null, an asynchronous timer that, when it expires, displays
929 an hourglass cursor on all frames. */
930 struct atimer
*hourglass_atimer
;
932 /* Number of seconds to wait before displaying an hourglass cursor. */
933 Lisp_Object Vhourglass_delay
;
935 /* Default number of seconds to wait before displaying an hourglass
937 #define DEFAULT_HOURGLASS_DELAY 1
940 /* Function prototypes. */
942 static void setup_for_ellipsis (struct it
*, int);
943 static void mark_window_display_accurate_1 (struct window
*, int);
944 static int single_display_spec_string_p (Lisp_Object
, Lisp_Object
);
945 static int display_prop_string_p (Lisp_Object
, Lisp_Object
);
946 static int cursor_row_p (struct window
*, struct glyph_row
*);
947 static int redisplay_mode_lines (Lisp_Object
, int);
948 static char *decode_mode_spec_coding (Lisp_Object
, char *, int);
950 static Lisp_Object
get_it_property (struct it
*it
, Lisp_Object prop
);
952 static void handle_line_prefix (struct it
*);
954 static void pint2str (char *, int, int);
955 static void pint2hrstr (char *, int, int);
956 static struct text_pos
run_window_scroll_functions (Lisp_Object
,
958 static void reconsider_clip_changes (struct window
*, struct buffer
*);
959 static int text_outside_line_unchanged_p (struct window
*, int, int);
960 static void store_mode_line_noprop_char (char);
961 static int store_mode_line_noprop (const unsigned char *, int, int);
962 static void x_consider_frame_title (Lisp_Object
);
963 static void handle_stop (struct it
*);
964 static void handle_stop_backwards (struct it
*, EMACS_INT
);
965 static int tool_bar_lines_needed (struct frame
*, int *);
966 static int single_display_spec_intangible_p (Lisp_Object
);
967 static void ensure_echo_area_buffers (void);
968 static Lisp_Object
unwind_with_echo_area_buffer (Lisp_Object
);
969 static Lisp_Object
with_echo_area_buffer_unwind_data (struct window
*);
970 static int with_echo_area_buffer (struct window
*, int,
971 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
972 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
973 static void clear_garbaged_frames (void);
974 static int current_message_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
975 static int truncate_message_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
976 static int set_message_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
977 static int display_echo_area (struct window
*);
978 static int display_echo_area_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
979 static int resize_mini_window_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
980 static Lisp_Object
unwind_redisplay (Lisp_Object
);
981 static int string_char_and_length (const unsigned char *, int *);
982 static struct text_pos
display_prop_end (struct it
*, Lisp_Object
,
984 static int compute_window_start_on_continuation_line (struct window
*);
985 static Lisp_Object
safe_eval_handler (Lisp_Object
);
986 static void insert_left_trunc_glyphs (struct it
*);
987 static struct glyph_row
*get_overlay_arrow_glyph_row (struct window
*,
989 static void extend_face_to_end_of_line (struct it
*);
990 static int append_space_for_newline (struct it
*, int);
991 static int cursor_row_fully_visible_p (struct window
*, int, int);
992 static int try_scrolling (Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int);
993 static int try_cursor_movement (Lisp_Object
, struct text_pos
, int *);
994 static int trailing_whitespace_p (int);
995 static int message_log_check_duplicate (int, int, int, int);
996 static void push_it (struct it
*);
997 static void pop_it (struct it
*);
998 static void sync_frame_with_window_matrix_rows (struct window
*);
999 static void select_frame_for_redisplay (Lisp_Object
);
1000 static void redisplay_internal (int);
1001 static int echo_area_display (int);
1002 static void redisplay_windows (Lisp_Object
);
1003 static void redisplay_window (Lisp_Object
, int);
1004 static Lisp_Object
redisplay_window_error (Lisp_Object
);
1005 static Lisp_Object
redisplay_window_0 (Lisp_Object
);
1006 static Lisp_Object
redisplay_window_1 (Lisp_Object
);
1007 static int update_menu_bar (struct frame
*, int, int);
1008 static int try_window_reusing_current_matrix (struct window
*);
1009 static int try_window_id (struct window
*);
1010 static int display_line (struct it
*);
1011 static int display_mode_lines (struct window
*);
1012 static int display_mode_line (struct window
*, enum face_id
, Lisp_Object
);
1013 static int display_mode_element (struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int);
1014 static int store_mode_line_string (const char *, Lisp_Object
, int, int, int, Lisp_Object
);
1015 static const char *decode_mode_spec (struct window
*, int, int, int,
1017 static void display_menu_bar (struct window
*);
1018 static int display_count_lines (int, int, int, int, int *);
1019 static int display_string (const unsigned char *, Lisp_Object
, Lisp_Object
,
1020 EMACS_INT
, EMACS_INT
, struct it
*, int, int, int, int);
1021 static void compute_line_metrics (struct it
*);
1022 static void run_redisplay_end_trigger_hook (struct it
*);
1023 static int get_overlay_strings (struct it
*, int);
1024 static int get_overlay_strings_1 (struct it
*, int, int);
1025 static void next_overlay_string (struct it
*);
1026 static void reseat (struct it
*, struct text_pos
, int);
1027 static void reseat_1 (struct it
*, struct text_pos
, int);
1028 static void back_to_previous_visible_line_start (struct it
*);
1029 void reseat_at_previous_visible_line_start (struct it
*);
1030 static void reseat_at_next_visible_line_start (struct it
*, int);
1031 static int next_element_from_ellipsis (struct it
*);
1032 static int next_element_from_display_vector (struct it
*);
1033 static int next_element_from_string (struct it
*);
1034 static int next_element_from_c_string (struct it
*);
1035 static int next_element_from_buffer (struct it
*);
1036 static int next_element_from_composition (struct it
*);
1037 static int next_element_from_image (struct it
*);
1038 static int next_element_from_stretch (struct it
*);
1039 static void load_overlay_strings (struct it
*, int);
1040 static int init_from_display_pos (struct it
*, struct window
*,
1041 struct display_pos
*);
1042 static void reseat_to_string (struct it
*, const unsigned char *,
1043 Lisp_Object
, int, int, int, int);
1044 static enum move_it_result
1045 move_it_in_display_line_to (struct it
*, EMACS_INT
, int,
1046 enum move_operation_enum
);
1047 void move_it_vertically_backward (struct it
*, int);
1048 static void init_to_row_start (struct it
*, struct window
*,
1049 struct glyph_row
*);
1050 static int init_to_row_end (struct it
*, struct window
*,
1051 struct glyph_row
*);
1052 static void back_to_previous_line_start (struct it
*);
1053 static int forward_to_next_line_start (struct it
*, int *);
1054 static struct text_pos
string_pos_nchars_ahead (struct text_pos
,
1056 static struct text_pos
string_pos (int, Lisp_Object
);
1057 static struct text_pos
c_string_pos (int, const unsigned char *, int);
1058 static int number_of_chars (const unsigned char *, int);
1059 static void compute_stop_pos (struct it
*);
1060 static void compute_string_pos (struct text_pos
*, struct text_pos
,
1062 static int face_before_or_after_it_pos (struct it
*, int);
1063 static EMACS_INT
next_overlay_change (EMACS_INT
);
1064 static int handle_single_display_spec (struct it
*, Lisp_Object
,
1065 Lisp_Object
, Lisp_Object
,
1066 struct text_pos
*, int);
1067 static int underlying_face_id (struct it
*);
1068 static int in_ellipses_for_invisible_text_p (struct display_pos
*,
1071 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1072 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1074 #ifdef HAVE_WINDOW_SYSTEM
1076 static void update_tool_bar (struct frame
*, int);
1077 static void build_desired_tool_bar_string (struct frame
*f
);
1078 static int redisplay_tool_bar (struct frame
*);
1079 static void display_tool_bar_line (struct it
*, int);
1080 static void notice_overwritten_cursor (struct window
*,
1081 enum glyph_row_area
,
1082 int, int, int, int);
1083 static void append_stretch_glyph (struct it
*, Lisp_Object
,
1085 static int coords_in_mouse_face_p (struct window
*, int, int);
1089 #endif /* HAVE_WINDOW_SYSTEM */
1092 /***********************************************************************
1093 Window display dimensions
1094 ***********************************************************************/
1096 /* Return the bottom boundary y-position for text lines in window W.
1097 This is the first y position at which a line cannot start.
1098 It is relative to the top of the window.
1100 This is the height of W minus the height of a mode line, if any. */
1103 window_text_bottom_y (struct window
*w
)
1105 int height
= WINDOW_TOTAL_HEIGHT (w
);
1107 if (WINDOW_WANTS_MODELINE_P (w
))
1108 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
1112 /* Return the pixel width of display area AREA of window W. AREA < 0
1113 means return the total width of W, not including fringes to
1114 the left and right of the window. */
1117 window_box_width (struct window
*w
, int area
)
1119 int cols
= XFASTINT (w
->total_cols
);
1122 if (!w
->pseudo_window_p
)
1124 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
1126 if (area
== TEXT_AREA
)
1128 if (INTEGERP (w
->left_margin_cols
))
1129 cols
-= XFASTINT (w
->left_margin_cols
);
1130 if (INTEGERP (w
->right_margin_cols
))
1131 cols
-= XFASTINT (w
->right_margin_cols
);
1132 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
1134 else if (area
== LEFT_MARGIN_AREA
)
1136 cols
= (INTEGERP (w
->left_margin_cols
)
1137 ? XFASTINT (w
->left_margin_cols
) : 0);
1140 else if (area
== RIGHT_MARGIN_AREA
)
1142 cols
= (INTEGERP (w
->right_margin_cols
)
1143 ? XFASTINT (w
->right_margin_cols
) : 0);
1148 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1152 /* Return the pixel height of the display area of window W, not
1153 including mode lines of W, if any. */
1156 window_box_height (struct window
*w
)
1158 struct frame
*f
= XFRAME (w
->frame
);
1159 int height
= WINDOW_TOTAL_HEIGHT (w
);
1161 xassert (height
>= 0);
1163 /* Note: the code below that determines the mode-line/header-line
1164 height is essentially the same as that contained in the macro
1165 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1166 the appropriate glyph row has its `mode_line_p' flag set,
1167 and if it doesn't, uses estimate_mode_line_height instead. */
1169 if (WINDOW_WANTS_MODELINE_P (w
))
1171 struct glyph_row
*ml_row
1172 = (w
->current_matrix
&& w
->current_matrix
->rows
1173 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1175 if (ml_row
&& ml_row
->mode_line_p
)
1176 height
-= ml_row
->height
;
1178 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1181 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1183 struct glyph_row
*hl_row
1184 = (w
->current_matrix
&& w
->current_matrix
->rows
1185 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1187 if (hl_row
&& hl_row
->mode_line_p
)
1188 height
-= hl_row
->height
;
1190 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1193 /* With a very small font and a mode-line that's taller than
1194 default, we might end up with a negative height. */
1195 return max (0, height
);
1198 /* Return the window-relative coordinate of the left edge of display
1199 area AREA of window W. AREA < 0 means return the left edge of the
1200 whole window, to the right of the left fringe of W. */
1203 window_box_left_offset (struct window
*w
, int area
)
1207 if (w
->pseudo_window_p
)
1210 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1212 if (area
== TEXT_AREA
)
1213 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1214 + window_box_width (w
, LEFT_MARGIN_AREA
));
1215 else if (area
== RIGHT_MARGIN_AREA
)
1216 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1217 + window_box_width (w
, LEFT_MARGIN_AREA
)
1218 + window_box_width (w
, TEXT_AREA
)
1219 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1221 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1222 else if (area
== LEFT_MARGIN_AREA
1223 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1224 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1230 /* Return the window-relative coordinate of the right edge of display
1231 area AREA of window W. AREA < 0 means return the right edge of the
1232 whole window, to the left of the right fringe of W. */
1235 window_box_right_offset (struct window
*w
, int area
)
1237 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1240 /* Return the frame-relative coordinate of the left edge of display
1241 area AREA of window W. AREA < 0 means return the left edge of the
1242 whole window, to the right of the left fringe of W. */
1245 window_box_left (struct window
*w
, int area
)
1247 struct frame
*f
= XFRAME (w
->frame
);
1250 if (w
->pseudo_window_p
)
1251 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1253 x
= (WINDOW_LEFT_EDGE_X (w
)
1254 + window_box_left_offset (w
, area
));
1260 /* Return the frame-relative coordinate of the right edge of display
1261 area AREA of window W. AREA < 0 means return the right edge of the
1262 whole window, to the left of the right fringe of W. */
1265 window_box_right (struct window
*w
, int area
)
1267 return window_box_left (w
, area
) + window_box_width (w
, area
);
1270 /* Get the bounding box of the display area AREA of window W, without
1271 mode lines, in frame-relative coordinates. AREA < 0 means the
1272 whole window, not including the left and right fringes of
1273 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1274 coordinates of the upper-left corner of the box. Return in
1275 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1278 window_box (struct window
*w
, int area
, int *box_x
, int *box_y
,
1279 int *box_width
, int *box_height
)
1282 *box_width
= window_box_width (w
, area
);
1284 *box_height
= window_box_height (w
);
1286 *box_x
= window_box_left (w
, area
);
1289 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1290 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1291 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1296 /* Get the bounding box of the display area AREA of window W, without
1297 mode lines. AREA < 0 means the whole window, not including the
1298 left and right fringe of the window. Return in *TOP_LEFT_X
1299 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1300 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1301 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1305 window_box_edges (struct window
*w
, int area
, int *top_left_x
, int *top_left_y
,
1306 int *bottom_right_x
, int *bottom_right_y
)
1308 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1310 *bottom_right_x
+= *top_left_x
;
1311 *bottom_right_y
+= *top_left_y
;
1316 /***********************************************************************
1318 ***********************************************************************/
1320 /* Return the bottom y-position of the line the iterator IT is in.
1321 This can modify IT's settings. */
1324 line_bottom_y (struct it
*it
)
1326 int line_height
= it
->max_ascent
+ it
->max_descent
;
1327 int line_top_y
= it
->current_y
;
1329 if (line_height
== 0)
1332 line_height
= last_height
;
1333 else if (IT_CHARPOS (*it
) < ZV
)
1335 move_it_by_lines (it
, 1, 1);
1336 line_height
= (it
->max_ascent
|| it
->max_descent
1337 ? it
->max_ascent
+ it
->max_descent
1342 struct glyph_row
*row
= it
->glyph_row
;
1344 /* Use the default character height. */
1345 it
->glyph_row
= NULL
;
1346 it
->what
= IT_CHARACTER
;
1349 PRODUCE_GLYPHS (it
);
1350 line_height
= it
->ascent
+ it
->descent
;
1351 it
->glyph_row
= row
;
1355 return line_top_y
+ line_height
;
1359 /* Return 1 if position CHARPOS is visible in window W.
1360 CHARPOS < 0 means return info about WINDOW_END position.
1361 If visible, set *X and *Y to pixel coordinates of top left corner.
1362 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1363 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1366 pos_visible_p (struct window
*w
, int charpos
, int *x
, int *y
,
1367 int *rtop
, int *rbot
, int *rowh
, int *vpos
)
1370 struct text_pos top
;
1372 struct buffer
*old_buffer
= NULL
;
1374 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w
))))
1377 if (XBUFFER (w
->buffer
) != current_buffer
)
1379 old_buffer
= current_buffer
;
1380 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1383 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1385 /* Compute exact mode line heights. */
1386 if (WINDOW_WANTS_MODELINE_P (w
))
1387 current_mode_line_height
1388 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1389 current_buffer
->mode_line_format
);
1391 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1392 current_header_line_height
1393 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1394 current_buffer
->header_line_format
);
1396 start_display (&it
, w
, top
);
1397 move_it_to (&it
, charpos
, -1, it
.last_visible_y
-1, -1,
1398 (charpos
>= 0 ? MOVE_TO_POS
: 0) | MOVE_TO_Y
);
1400 if (charpos
>= 0 && IT_CHARPOS (it
) >= charpos
)
1402 /* We have reached CHARPOS, or passed it. How the call to
1403 move_it_to can overshoot: (i) If CHARPOS is on invisible
1404 text, move_it_to stops at the end of the invisible text,
1405 after CHARPOS. (ii) If CHARPOS is in a display vector,
1406 move_it_to stops on its last glyph. */
1407 int top_x
= it
.current_x
;
1408 int top_y
= it
.current_y
;
1409 enum it_method it_method
= it
.method
;
1410 /* Calling line_bottom_y may change it.method, it.position, etc. */
1411 int bottom_y
= (last_height
= 0, line_bottom_y (&it
));
1412 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1414 if (top_y
< window_top_y
)
1415 visible_p
= bottom_y
> window_top_y
;
1416 else if (top_y
< it
.last_visible_y
)
1420 if (it_method
== GET_FROM_DISPLAY_VECTOR
)
1422 /* We stopped on the last glyph of a display vector.
1423 Try and recompute. Hack alert! */
1424 if (charpos
< 2 || top
.charpos
>= charpos
)
1425 top_x
= it
.glyph_row
->x
;
1429 start_display (&it2
, w
, top
);
1430 move_it_to (&it2
, charpos
- 1, -1, -1, -1, MOVE_TO_POS
);
1431 get_next_display_element (&it2
);
1432 PRODUCE_GLYPHS (&it2
);
1433 if (ITERATOR_AT_END_OF_LINE_P (&it2
)
1434 || it2
.current_x
> it2
.last_visible_x
)
1435 top_x
= it
.glyph_row
->x
;
1438 top_x
= it2
.current_x
;
1439 top_y
= it2
.current_y
;
1445 *y
= max (top_y
+ max (0, it
.max_ascent
- it
.ascent
), window_top_y
);
1446 *rtop
= max (0, window_top_y
- top_y
);
1447 *rbot
= max (0, bottom_y
- it
.last_visible_y
);
1448 *rowh
= max (0, (min (bottom_y
, it
.last_visible_y
)
1449 - max (top_y
, window_top_y
)));
1458 if (IT_CHARPOS (it
) < ZV
&& FETCH_BYTE (IT_BYTEPOS (it
)) != '\n')
1459 move_it_by_lines (&it
, 1, 0);
1460 if (charpos
< IT_CHARPOS (it
)
1461 || (it
.what
== IT_EOB
&& charpos
== IT_CHARPOS (it
)))
1464 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1466 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1467 *rtop
= max (0, -it2
.current_y
);
1468 *rbot
= max (0, ((it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
)
1469 - it
.last_visible_y
));
1470 *rowh
= max (0, (min (it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
,
1472 - max (it2
.current_y
,
1473 WINDOW_HEADER_LINE_HEIGHT (w
))));
1479 set_buffer_internal_1 (old_buffer
);
1481 current_header_line_height
= current_mode_line_height
= -1;
1483 if (visible_p
&& XFASTINT (w
->hscroll
) > 0)
1484 *x
-= XFASTINT (w
->hscroll
) * WINDOW_FRAME_COLUMN_WIDTH (w
);
1487 /* Debugging code. */
1489 fprintf (stderr
, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1490 charpos
, w
->vscroll
, *x
, *y
, *rtop
, *rbot
, *rowh
, *vpos
);
1492 fprintf (stderr
, "-pv pt=%d vs=%d\n", charpos
, w
->vscroll
);
1499 /* Return the next character from STR which is MAXLEN bytes long.
1500 Return in *LEN the length of the character. This is like
1501 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1502 we find one, we return a `?', but with the length of the invalid
1506 string_char_and_length (const unsigned char *str
, int *len
)
1510 c
= STRING_CHAR_AND_LENGTH (str
, *len
);
1511 if (!CHAR_VALID_P (c
, 1))
1512 /* We may not change the length here because other places in Emacs
1513 don't use this function, i.e. they silently accept invalid
1522 /* Given a position POS containing a valid character and byte position
1523 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1525 static struct text_pos
1526 string_pos_nchars_ahead (struct text_pos pos
, Lisp_Object string
, int nchars
)
1528 xassert (STRINGP (string
) && nchars
>= 0);
1530 if (STRING_MULTIBYTE (string
))
1532 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1533 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1538 string_char_and_length (p
, &len
);
1539 p
+= len
, rest
-= len
;
1540 xassert (rest
>= 0);
1542 BYTEPOS (pos
) += len
;
1546 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1552 /* Value is the text position, i.e. character and byte position,
1553 for character position CHARPOS in STRING. */
1555 static INLINE
struct text_pos
1556 string_pos (int charpos
, Lisp_Object string
)
1558 struct text_pos pos
;
1559 xassert (STRINGP (string
));
1560 xassert (charpos
>= 0);
1561 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1566 /* Value is a text position, i.e. character and byte position, for
1567 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1568 means recognize multibyte characters. */
1570 static struct text_pos
1571 c_string_pos (int charpos
, const unsigned char *s
, int multibyte_p
)
1573 struct text_pos pos
;
1575 xassert (s
!= NULL
);
1576 xassert (charpos
>= 0);
1580 int rest
= strlen (s
), len
;
1582 SET_TEXT_POS (pos
, 0, 0);
1585 string_char_and_length (s
, &len
);
1586 s
+= len
, rest
-= len
;
1587 xassert (rest
>= 0);
1589 BYTEPOS (pos
) += len
;
1593 SET_TEXT_POS (pos
, charpos
, charpos
);
1599 /* Value is the number of characters in C string S. MULTIBYTE_P
1600 non-zero means recognize multibyte characters. */
1603 number_of_chars (const unsigned char *s
, int multibyte_p
)
1609 int rest
= strlen (s
), len
;
1610 unsigned char *p
= (unsigned char *) s
;
1612 for (nchars
= 0; rest
> 0; ++nchars
)
1614 string_char_and_length (p
, &len
);
1615 rest
-= len
, p
+= len
;
1619 nchars
= strlen (s
);
1625 /* Compute byte position NEWPOS->bytepos corresponding to
1626 NEWPOS->charpos. POS is a known position in string STRING.
1627 NEWPOS->charpos must be >= POS.charpos. */
1630 compute_string_pos (struct text_pos
*newpos
, struct text_pos pos
, Lisp_Object string
)
1632 xassert (STRINGP (string
));
1633 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1635 if (STRING_MULTIBYTE (string
))
1636 *newpos
= string_pos_nchars_ahead (pos
, string
,
1637 CHARPOS (*newpos
) - CHARPOS (pos
));
1639 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1643 Return an estimation of the pixel height of mode or header lines on
1644 frame F. FACE_ID specifies what line's height to estimate. */
1647 estimate_mode_line_height (struct frame
*f
, enum face_id face_id
)
1649 #ifdef HAVE_WINDOW_SYSTEM
1650 if (FRAME_WINDOW_P (f
))
1652 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1654 /* This function is called so early when Emacs starts that the face
1655 cache and mode line face are not yet initialized. */
1656 if (FRAME_FACE_CACHE (f
))
1658 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1662 height
= FONT_HEIGHT (face
->font
);
1663 if (face
->box_line_width
> 0)
1664 height
+= 2 * face
->box_line_width
;
1675 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1676 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1677 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1678 not force the value into range. */
1681 pixel_to_glyph_coords (FRAME_PTR f
, register int pix_x
, register int pix_y
,
1682 int *x
, int *y
, NativeRectangle
*bounds
, int noclip
)
1685 #ifdef HAVE_WINDOW_SYSTEM
1686 if (FRAME_WINDOW_P (f
))
1688 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1689 even for negative values. */
1691 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1693 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1695 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1696 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1699 STORE_NATIVE_RECT (*bounds
,
1700 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1701 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1702 FRAME_COLUMN_WIDTH (f
) - 1,
1703 FRAME_LINE_HEIGHT (f
) - 1);
1709 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1710 pix_x
= FRAME_TOTAL_COLS (f
);
1714 else if (pix_y
> FRAME_LINES (f
))
1715 pix_y
= FRAME_LINES (f
);
1725 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1726 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1727 can't tell the positions because W's display is not up to date,
1731 glyph_to_pixel_coords (struct window
*w
, int hpos
, int vpos
,
1732 int *frame_x
, int *frame_y
)
1734 #ifdef HAVE_WINDOW_SYSTEM
1735 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1739 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1740 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1742 if (display_completed
)
1744 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1745 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1746 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1752 hpos
+= glyph
->pixel_width
;
1756 /* If first glyph is partially visible, its first visible position is still 0. */
1768 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1769 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1780 #ifdef HAVE_WINDOW_SYSTEM
1782 /* Find the glyph under window-relative coordinates X/Y in window W.
1783 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1784 strings. Return in *HPOS and *VPOS the row and column number of
1785 the glyph found. Return in *AREA the glyph area containing X.
1786 Value is a pointer to the glyph found or null if X/Y is not on
1787 text, or we can't tell because W's current matrix is not up to
1792 x_y_to_hpos_vpos (struct window
*w
, int x
, int y
, int *hpos
, int *vpos
,
1793 int *dx
, int *dy
, int *area
)
1795 struct glyph
*glyph
, *end
;
1796 struct glyph_row
*row
= NULL
;
1799 /* Find row containing Y. Give up if some row is not enabled. */
1800 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1802 row
= MATRIX_ROW (w
->current_matrix
, i
);
1803 if (!row
->enabled_p
)
1805 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1812 /* Give up if Y is not in the window. */
1813 if (i
== w
->current_matrix
->nrows
)
1816 /* Get the glyph area containing X. */
1817 if (w
->pseudo_window_p
)
1824 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1826 *area
= LEFT_MARGIN_AREA
;
1827 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1829 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1832 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1836 *area
= RIGHT_MARGIN_AREA
;
1837 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1841 /* Find glyph containing X. */
1842 glyph
= row
->glyphs
[*area
];
1843 end
= glyph
+ row
->used
[*area
];
1845 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1847 x
-= glyph
->pixel_width
;
1857 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1860 *hpos
= glyph
- row
->glyphs
[*area
];
1866 Convert frame-relative x/y to coordinates relative to window W.
1867 Takes pseudo-windows into account. */
1870 frame_to_window_pixel_xy (struct window
*w
, int *x
, int *y
)
1872 if (w
->pseudo_window_p
)
1874 /* A pseudo-window is always full-width, and starts at the
1875 left edge of the frame, plus a frame border. */
1876 struct frame
*f
= XFRAME (w
->frame
);
1877 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1878 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1882 *x
-= WINDOW_LEFT_EDGE_X (w
);
1883 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1888 Return in RECTS[] at most N clipping rectangles for glyph string S.
1889 Return the number of stored rectangles. */
1892 get_glyph_string_clip_rects (struct glyph_string
*s
, NativeRectangle
*rects
, int n
)
1899 if (s
->row
->full_width_p
)
1901 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1902 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1903 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1905 /* Unless displaying a mode or menu bar line, which are always
1906 fully visible, clip to the visible part of the row. */
1907 if (s
->w
->pseudo_window_p
)
1908 r
.height
= s
->row
->visible_height
;
1910 r
.height
= s
->height
;
1914 /* This is a text line that may be partially visible. */
1915 r
.x
= window_box_left (s
->w
, s
->area
);
1916 r
.width
= window_box_width (s
->w
, s
->area
);
1917 r
.height
= s
->row
->visible_height
;
1921 if (r
.x
< s
->clip_head
->x
)
1923 if (r
.width
>= s
->clip_head
->x
- r
.x
)
1924 r
.width
-= s
->clip_head
->x
- r
.x
;
1927 r
.x
= s
->clip_head
->x
;
1930 if (r
.x
+ r
.width
> s
->clip_tail
->x
+ s
->clip_tail
->background_width
)
1932 if (s
->clip_tail
->x
+ s
->clip_tail
->background_width
>= r
.x
)
1933 r
.width
= s
->clip_tail
->x
+ s
->clip_tail
->background_width
- r
.x
;
1938 /* If S draws overlapping rows, it's sufficient to use the top and
1939 bottom of the window for clipping because this glyph string
1940 intentionally draws over other lines. */
1941 if (s
->for_overlaps
)
1943 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1944 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1946 /* Alas, the above simple strategy does not work for the
1947 environments with anti-aliased text: if the same text is
1948 drawn onto the same place multiple times, it gets thicker.
1949 If the overlap we are processing is for the erased cursor, we
1950 take the intersection with the rectagle of the cursor. */
1951 if (s
->for_overlaps
& OVERLAPS_ERASED_CURSOR
)
1953 XRectangle rc
, r_save
= r
;
1955 rc
.x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (s
->w
, s
->w
->phys_cursor
.x
);
1956 rc
.y
= s
->w
->phys_cursor
.y
;
1957 rc
.width
= s
->w
->phys_cursor_width
;
1958 rc
.height
= s
->w
->phys_cursor_height
;
1960 x_intersect_rectangles (&r_save
, &rc
, &r
);
1965 /* Don't use S->y for clipping because it doesn't take partially
1966 visible lines into account. For example, it can be negative for
1967 partially visible lines at the top of a window. */
1968 if (!s
->row
->full_width_p
1969 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1970 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1972 r
.y
= max (0, s
->row
->y
);
1975 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1977 /* If drawing the cursor, don't let glyph draw outside its
1978 advertised boundaries. Cleartype does this under some circumstances. */
1979 if (s
->hl
== DRAW_CURSOR
)
1981 struct glyph
*glyph
= s
->first_glyph
;
1986 r
.width
-= s
->x
- r
.x
;
1989 r
.width
= min (r
.width
, glyph
->pixel_width
);
1991 /* If r.y is below window bottom, ensure that we still see a cursor. */
1992 height
= min (glyph
->ascent
+ glyph
->descent
,
1993 min (FRAME_LINE_HEIGHT (s
->f
), s
->row
->visible_height
));
1994 max_y
= window_text_bottom_y (s
->w
) - height
;
1995 max_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, max_y
);
1996 if (s
->ybase
- glyph
->ascent
> max_y
)
2003 /* Don't draw cursor glyph taller than our actual glyph. */
2004 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
2005 if (height
< r
.height
)
2007 max_y
= r
.y
+ r
.height
;
2008 r
.y
= min (max_y
, max (r
.y
, s
->ybase
+ glyph
->descent
- height
));
2009 r
.height
= min (max_y
- r
.y
, height
);
2016 XRectangle r_save
= r
;
2018 if (! x_intersect_rectangles (&r_save
, s
->row
->clip
, &r
))
2022 if ((s
->for_overlaps
& OVERLAPS_BOTH
) == 0
2023 || ((s
->for_overlaps
& OVERLAPS_BOTH
) == OVERLAPS_BOTH
&& n
== 1))
2025 #ifdef CONVERT_FROM_XRECT
2026 CONVERT_FROM_XRECT (r
, *rects
);
2034 /* If we are processing overlapping and allowed to return
2035 multiple clipping rectangles, we exclude the row of the glyph
2036 string from the clipping rectangle. This is to avoid drawing
2037 the same text on the environment with anti-aliasing. */
2038 #ifdef CONVERT_FROM_XRECT
2041 XRectangle
*rs
= rects
;
2043 int i
= 0, row_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, s
->row
->y
);
2045 if (s
->for_overlaps
& OVERLAPS_PRED
)
2048 if (r
.y
+ r
.height
> row_y
)
2051 rs
[i
].height
= row_y
- r
.y
;
2057 if (s
->for_overlaps
& OVERLAPS_SUCC
)
2060 if (r
.y
< row_y
+ s
->row
->visible_height
)
2062 if (r
.y
+ r
.height
> row_y
+ s
->row
->visible_height
)
2064 rs
[i
].y
= row_y
+ s
->row
->visible_height
;
2065 rs
[i
].height
= r
.y
+ r
.height
- rs
[i
].y
;
2074 #ifdef CONVERT_FROM_XRECT
2075 for (i
= 0; i
< n
; i
++)
2076 CONVERT_FROM_XRECT (rs
[i
], rects
[i
]);
2083 Return in *NR the clipping rectangle for glyph string S. */
2086 get_glyph_string_clip_rect (struct glyph_string
*s
, NativeRectangle
*nr
)
2088 get_glyph_string_clip_rects (s
, nr
, 1);
2093 Return the position and height of the phys cursor in window W.
2094 Set w->phys_cursor_width to width of phys cursor.
2098 get_phys_cursor_geometry (struct window
*w
, struct glyph_row
*row
,
2099 struct glyph
*glyph
, int *xp
, int *yp
, int *heightp
)
2101 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2102 int x
, y
, wd
, h
, h0
, y0
;
2104 /* Compute the width of the rectangle to draw. If on a stretch
2105 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2106 rectangle as wide as the glyph, but use a canonical character
2108 wd
= glyph
->pixel_width
- 1;
2109 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2113 x
= w
->phys_cursor
.x
;
2120 if (glyph
->type
== STRETCH_GLYPH
2121 && !x_stretch_cursor_p
)
2122 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
2123 w
->phys_cursor_width
= wd
;
2125 y
= w
->phys_cursor
.y
+ row
->ascent
- glyph
->ascent
;
2127 /* If y is below window bottom, ensure that we still see a cursor. */
2128 h0
= min (FRAME_LINE_HEIGHT (f
), row
->visible_height
);
2130 h
= max (h0
, glyph
->ascent
+ glyph
->descent
);
2131 h0
= min (h0
, glyph
->ascent
+ glyph
->descent
);
2133 y0
= WINDOW_HEADER_LINE_HEIGHT (w
);
2136 h
= max (h
- (y0
- y
) + 1, h0
);
2141 y0
= window_text_bottom_y (w
) - h0
;
2149 *xp
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, x
);
2150 *yp
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
);
2155 * Remember which glyph the mouse is over.
2159 remember_mouse_glyph (struct frame
*f
, int gx
, int gy
, NativeRectangle
*rect
)
2163 struct glyph_row
*r
, *gr
, *end_row
;
2164 enum window_part part
;
2165 enum glyph_row_area area
;
2166 int x
, y
, width
, height
;
2168 /* Try to determine frame pixel position and size of the glyph under
2169 frame pixel coordinates X/Y on frame F. */
2171 if (!f
->glyphs_initialized_p
2172 || (window
= window_from_coordinates (f
, gx
, gy
, &part
, &x
, &y
, 0),
2175 width
= FRAME_SMALLEST_CHAR_WIDTH (f
);
2176 height
= FRAME_SMALLEST_FONT_HEIGHT (f
);
2180 w
= XWINDOW (window
);
2181 width
= WINDOW_FRAME_COLUMN_WIDTH (w
);
2182 height
= WINDOW_FRAME_LINE_HEIGHT (w
);
2184 r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
2185 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
2187 if (w
->pseudo_window_p
)
2190 part
= ON_MODE_LINE
; /* Don't adjust margin. */
2196 case ON_LEFT_MARGIN
:
2197 area
= LEFT_MARGIN_AREA
;
2200 case ON_RIGHT_MARGIN
:
2201 area
= RIGHT_MARGIN_AREA
;
2204 case ON_HEADER_LINE
:
2206 gr
= (part
== ON_HEADER_LINE
2207 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
2208 : MATRIX_MODE_LINE_ROW (w
->current_matrix
));
2211 goto text_glyph_row_found
;
2218 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2219 if (r
->y
+ r
->height
> y
)
2225 text_glyph_row_found
:
2228 struct glyph
*g
= gr
->glyphs
[area
];
2229 struct glyph
*end
= g
+ gr
->used
[area
];
2231 height
= gr
->height
;
2232 for (gx
= gr
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
2233 if (gx
+ g
->pixel_width
> x
)
2238 if (g
->type
== IMAGE_GLYPH
)
2240 /* Don't remember when mouse is over image, as
2241 image may have hot-spots. */
2242 STORE_NATIVE_RECT (*rect
, 0, 0, 0, 0);
2245 width
= g
->pixel_width
;
2249 /* Use nominal char spacing at end of line. */
2251 gx
+= (x
/ width
) * width
;
2254 if (part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
)
2255 gx
+= window_box_left_offset (w
, area
);
2259 /* Use nominal line height at end of window. */
2260 gx
= (x
/ width
) * width
;
2262 gy
+= (y
/ height
) * height
;
2266 case ON_LEFT_FRINGE
:
2267 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2268 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
)
2269 : window_box_right_offset (w
, LEFT_MARGIN_AREA
));
2270 width
= WINDOW_LEFT_FRINGE_WIDTH (w
);
2273 case ON_RIGHT_FRINGE
:
2274 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2275 ? window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2276 : window_box_right_offset (w
, TEXT_AREA
));
2277 width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
2281 gx
= (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
2283 : (window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2284 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2285 ? WINDOW_RIGHT_FRINGE_WIDTH (w
)
2287 width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
2291 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2292 if (r
->y
+ r
->height
> y
)
2299 height
= gr
->height
;
2302 /* Use nominal line height at end of window. */
2304 gy
+= (y
/ height
) * height
;
2311 /* If there is no glyph under the mouse, then we divide the screen
2312 into a grid of the smallest glyph in the frame, and use that
2315 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2316 round down even for negative values. */
2322 gx
= (gx
/ width
) * width
;
2323 gy
= (gy
/ height
) * height
;
2328 gx
+= WINDOW_LEFT_EDGE_X (w
);
2329 gy
+= WINDOW_TOP_EDGE_Y (w
);
2332 STORE_NATIVE_RECT (*rect
, gx
, gy
, width
, height
);
2334 /* Visible feedback for debugging. */
2337 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2338 f
->output_data
.x
->normal_gc
,
2339 gx
, gy
, width
, height
);
2345 #endif /* HAVE_WINDOW_SYSTEM */
2348 /***********************************************************************
2349 Lisp form evaluation
2350 ***********************************************************************/
2352 /* Error handler for safe_eval and safe_call. */
2355 safe_eval_handler (Lisp_Object arg
)
2357 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
2362 /* Evaluate SEXPR and return the result, or nil if something went
2363 wrong. Prevent redisplay during the evaluation. */
2365 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2366 Return the result, or nil if something went wrong. Prevent
2367 redisplay during the evaluation. */
2370 safe_call (int nargs
, Lisp_Object
*args
)
2374 if (inhibit_eval_during_redisplay
)
2378 int count
= SPECPDL_INDEX ();
2379 struct gcpro gcpro1
;
2382 gcpro1
.nvars
= nargs
;
2383 specbind (Qinhibit_redisplay
, Qt
);
2384 /* Use Qt to ensure debugger does not run,
2385 so there is no possibility of wanting to redisplay. */
2386 val
= internal_condition_case_n (Ffuncall
, nargs
, args
, Qt
,
2389 val
= unbind_to (count
, val
);
2396 /* Call function FN with one argument ARG.
2397 Return the result, or nil if something went wrong. */
2400 safe_call1 (Lisp_Object fn
, Lisp_Object arg
)
2402 Lisp_Object args
[2];
2405 return safe_call (2, args
);
2408 static Lisp_Object Qeval
;
2411 safe_eval (Lisp_Object sexpr
)
2413 return safe_call1 (Qeval
, sexpr
);
2416 /* Call function FN with one argument ARG.
2417 Return the result, or nil if something went wrong. */
2420 safe_call2 (Lisp_Object fn
, Lisp_Object arg1
, Lisp_Object arg2
)
2422 Lisp_Object args
[3];
2426 return safe_call (3, args
);
2431 /***********************************************************************
2433 ***********************************************************************/
2437 /* Define CHECK_IT to perform sanity checks on iterators.
2438 This is for debugging. It is too slow to do unconditionally. */
2444 if (it
->method
== GET_FROM_STRING
)
2446 xassert (STRINGP (it
->string
));
2447 xassert (IT_STRING_CHARPOS (*it
) >= 0);
2451 xassert (IT_STRING_CHARPOS (*it
) < 0);
2452 if (it
->method
== GET_FROM_BUFFER
)
2454 /* Check that character and byte positions agree. */
2455 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
2460 xassert (it
->current
.dpvec_index
>= 0);
2462 xassert (it
->current
.dpvec_index
< 0);
2465 #define CHECK_IT(IT) check_it ((IT))
2469 #define CHECK_IT(IT) (void) 0
2476 /* Check that the window end of window W is what we expect it
2477 to be---the last row in the current matrix displaying text. */
2480 check_window_end (w
)
2483 if (!MINI_WINDOW_P (w
)
2484 && !NILP (w
->window_end_valid
))
2486 struct glyph_row
*row
;
2487 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
2488 XFASTINT (w
->window_end_vpos
)),
2490 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
2491 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
2495 #define CHECK_WINDOW_END(W) check_window_end ((W))
2497 #else /* not GLYPH_DEBUG */
2499 #define CHECK_WINDOW_END(W) (void) 0
2501 #endif /* not GLYPH_DEBUG */
2505 /***********************************************************************
2506 Iterator initialization
2507 ***********************************************************************/
2509 /* Initialize IT for displaying current_buffer in window W, starting
2510 at character position CHARPOS. CHARPOS < 0 means that no buffer
2511 position is specified which is useful when the iterator is assigned
2512 a position later. BYTEPOS is the byte position corresponding to
2513 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2515 If ROW is not null, calls to produce_glyphs with IT as parameter
2516 will produce glyphs in that row.
2518 BASE_FACE_ID is the id of a base face to use. It must be one of
2519 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2520 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2521 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2523 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2524 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2525 will be initialized to use the corresponding mode line glyph row of
2526 the desired matrix of W. */
2529 init_iterator (struct it
*it
, struct window
*w
,
2530 EMACS_INT charpos
, EMACS_INT bytepos
,
2531 struct glyph_row
*row
, enum face_id base_face_id
)
2533 int highlight_region_p
;
2534 enum face_id remapped_base_face_id
= base_face_id
;
2536 /* Some precondition checks. */
2537 xassert (w
!= NULL
&& it
!= NULL
);
2538 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2541 /* If face attributes have been changed since the last redisplay,
2542 free realized faces now because they depend on face definitions
2543 that might have changed. Don't free faces while there might be
2544 desired matrices pending which reference these faces. */
2545 if (face_change_count
&& !inhibit_free_realized_faces
)
2547 face_change_count
= 0;
2548 free_all_realized_faces (Qnil
);
2551 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2552 if (! NILP (Vface_remapping_alist
))
2553 remapped_base_face_id
= lookup_basic_face (XFRAME (w
->frame
), base_face_id
);
2555 /* Use one of the mode line rows of W's desired matrix if
2559 if (base_face_id
== MODE_LINE_FACE_ID
2560 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2561 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2562 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2563 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2567 memset (it
, 0, sizeof *it
);
2568 it
->current
.overlay_string_index
= -1;
2569 it
->current
.dpvec_index
= -1;
2570 it
->base_face_id
= remapped_base_face_id
;
2572 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2574 /* The window in which we iterate over current_buffer: */
2575 XSETWINDOW (it
->window
, w
);
2577 it
->f
= XFRAME (w
->frame
);
2581 /* Extra space between lines (on window systems only). */
2582 if (base_face_id
== DEFAULT_FACE_ID
2583 && FRAME_WINDOW_P (it
->f
))
2585 if (NATNUMP (current_buffer
->extra_line_spacing
))
2586 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2587 else if (FLOATP (current_buffer
->extra_line_spacing
))
2588 it
->extra_line_spacing
= (XFLOAT_DATA (current_buffer
->extra_line_spacing
)
2589 * FRAME_LINE_HEIGHT (it
->f
));
2590 else if (it
->f
->extra_line_spacing
> 0)
2591 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2592 it
->max_extra_line_spacing
= 0;
2595 /* If realized faces have been removed, e.g. because of face
2596 attribute changes of named faces, recompute them. When running
2597 in batch mode, the face cache of the initial frame is null. If
2598 we happen to get called, make a dummy face cache. */
2599 if (FRAME_FACE_CACHE (it
->f
) == NULL
)
2600 init_frame_faces (it
->f
);
2601 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2602 recompute_basic_faces (it
->f
);
2604 /* Current value of the `slice', `space-width', and 'height' properties. */
2605 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2606 it
->space_width
= Qnil
;
2607 it
->font_height
= Qnil
;
2608 it
->override_ascent
= -1;
2610 /* Are control characters displayed as `^C'? */
2611 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2613 /* -1 means everything between a CR and the following line end
2614 is invisible. >0 means lines indented more than this value are
2616 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2617 ? XFASTINT (current_buffer
->selective_display
)
2618 : (!NILP (current_buffer
->selective_display
)
2620 it
->selective_display_ellipsis_p
2621 = !NILP (current_buffer
->selective_display_ellipses
);
2623 /* Display table to use. */
2624 it
->dp
= window_display_table (w
);
2626 /* Are multibyte characters enabled in current_buffer? */
2627 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2629 /* Do we need to reorder bidirectional text? Not if this is a
2630 unibyte buffer: by definition, none of the single-byte characters
2631 are strong R2L, so no reordering is needed. And bidi.c doesn't
2632 support unibyte buffers anyway. */
2634 = !NILP (current_buffer
->bidi_display_reordering
) && it
->multibyte_p
;
2636 /* Non-zero if we should highlight the region. */
2638 = (!NILP (Vtransient_mark_mode
)
2639 && !NILP (current_buffer
->mark_active
)
2640 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2642 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2643 start and end of a visible region in window IT->w. Set both to
2644 -1 to indicate no region. */
2645 if (highlight_region_p
2646 /* Maybe highlight only in selected window. */
2647 && (/* Either show region everywhere. */
2648 highlight_nonselected_windows
2649 /* Or show region in the selected window. */
2650 || w
== XWINDOW (selected_window
)
2651 /* Or show the region if we are in the mini-buffer and W is
2652 the window the mini-buffer refers to. */
2653 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2654 && WINDOWP (minibuf_selected_window
)
2655 && w
== XWINDOW (minibuf_selected_window
))))
2657 int charpos
= marker_position (current_buffer
->mark
);
2658 it
->region_beg_charpos
= min (PT
, charpos
);
2659 it
->region_end_charpos
= max (PT
, charpos
);
2662 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2664 /* Get the position at which the redisplay_end_trigger hook should
2665 be run, if it is to be run at all. */
2666 if (MARKERP (w
->redisplay_end_trigger
)
2667 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2668 it
->redisplay_end_trigger_charpos
2669 = marker_position (w
->redisplay_end_trigger
);
2670 else if (INTEGERP (w
->redisplay_end_trigger
))
2671 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2673 /* Correct bogus values of tab_width. */
2674 it
->tab_width
= XINT (current_buffer
->tab_width
);
2675 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2678 /* Are lines in the display truncated? */
2679 if (base_face_id
!= DEFAULT_FACE_ID
2680 || XINT (it
->w
->hscroll
)
2681 || (! WINDOW_FULL_WIDTH_P (it
->w
)
2682 && ((!NILP (Vtruncate_partial_width_windows
)
2683 && !INTEGERP (Vtruncate_partial_width_windows
))
2684 || (INTEGERP (Vtruncate_partial_width_windows
)
2685 && (WINDOW_TOTAL_COLS (it
->w
)
2686 < XINT (Vtruncate_partial_width_windows
))))))
2687 it
->line_wrap
= TRUNCATE
;
2688 else if (NILP (current_buffer
->truncate_lines
))
2689 it
->line_wrap
= NILP (current_buffer
->word_wrap
)
2690 ? WINDOW_WRAP
: WORD_WRAP
;
2692 it
->line_wrap
= TRUNCATE
;
2694 /* Get dimensions of truncation and continuation glyphs. These are
2695 displayed as fringe bitmaps under X, so we don't need them for such
2697 if (!FRAME_WINDOW_P (it
->f
))
2699 if (it
->line_wrap
== TRUNCATE
)
2701 /* We will need the truncation glyph. */
2702 xassert (it
->glyph_row
== NULL
);
2703 produce_special_glyphs (it
, IT_TRUNCATION
);
2704 it
->truncation_pixel_width
= it
->pixel_width
;
2708 /* We will need the continuation glyph. */
2709 xassert (it
->glyph_row
== NULL
);
2710 produce_special_glyphs (it
, IT_CONTINUATION
);
2711 it
->continuation_pixel_width
= it
->pixel_width
;
2714 /* Reset these values to zero because the produce_special_glyphs
2715 above has changed them. */
2716 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2717 it
->phys_ascent
= it
->phys_descent
= 0;
2720 /* Set this after getting the dimensions of truncation and
2721 continuation glyphs, so that we don't produce glyphs when calling
2722 produce_special_glyphs, above. */
2723 it
->glyph_row
= row
;
2724 it
->area
= TEXT_AREA
;
2726 /* Forget any previous info about this row being reversed. */
2728 it
->glyph_row
->reversed_p
= 0;
2730 /* Get the dimensions of the display area. The display area
2731 consists of the visible window area plus a horizontally scrolled
2732 part to the left of the window. All x-values are relative to the
2733 start of this total display area. */
2734 if (base_face_id
!= DEFAULT_FACE_ID
)
2736 /* Mode lines, menu bar in terminal frames. */
2737 it
->first_visible_x
= 0;
2738 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2743 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2744 it
->last_visible_x
= (it
->first_visible_x
2745 + window_box_width (w
, TEXT_AREA
));
2747 /* If we truncate lines, leave room for the truncator glyph(s) at
2748 the right margin. Otherwise, leave room for the continuation
2749 glyph(s). Truncation and continuation glyphs are not inserted
2750 for window-based redisplay. */
2751 if (!FRAME_WINDOW_P (it
->f
))
2753 if (it
->line_wrap
== TRUNCATE
)
2754 it
->last_visible_x
-= it
->truncation_pixel_width
;
2756 it
->last_visible_x
-= it
->continuation_pixel_width
;
2759 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2760 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2763 /* Leave room for a border glyph. */
2764 if (!FRAME_WINDOW_P (it
->f
)
2765 && !WINDOW_RIGHTMOST_P (it
->w
))
2766 it
->last_visible_x
-= 1;
2768 it
->last_visible_y
= window_text_bottom_y (w
);
2770 /* For mode lines and alike, arrange for the first glyph having a
2771 left box line if the face specifies a box. */
2772 if (base_face_id
!= DEFAULT_FACE_ID
)
2776 it
->face_id
= remapped_base_face_id
;
2778 /* If we have a boxed mode line, make the first character appear
2779 with a left box line. */
2780 face
= FACE_FROM_ID (it
->f
, remapped_base_face_id
);
2781 if (face
->box
!= FACE_NO_BOX
)
2782 it
->start_of_box_run_p
= 1;
2785 /* If we are to reorder bidirectional text, init the bidi
2789 /* Note the paragraph direction that this buffer wants to
2791 if (EQ (current_buffer
->bidi_paragraph_direction
, Qleft_to_right
))
2792 it
->paragraph_embedding
= L2R
;
2793 else if (EQ (current_buffer
->bidi_paragraph_direction
, Qright_to_left
))
2794 it
->paragraph_embedding
= R2L
;
2796 it
->paragraph_embedding
= NEUTRAL_DIR
;
2797 bidi_init_it (charpos
, bytepos
, &it
->bidi_it
);
2800 /* If a buffer position was specified, set the iterator there,
2801 getting overlays and face properties from that position. */
2802 if (charpos
>= BUF_BEG (current_buffer
))
2804 it
->end_charpos
= ZV
;
2806 IT_CHARPOS (*it
) = charpos
;
2808 /* Compute byte position if not specified. */
2809 if (bytepos
< charpos
)
2810 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2812 IT_BYTEPOS (*it
) = bytepos
;
2814 it
->start
= it
->current
;
2816 /* Compute faces etc. */
2817 reseat (it
, it
->current
.pos
, 1);
2824 /* Initialize IT for the display of window W with window start POS. */
2827 start_display (struct it
*it
, struct window
*w
, struct text_pos pos
)
2829 struct glyph_row
*row
;
2830 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2832 row
= w
->desired_matrix
->rows
+ first_vpos
;
2833 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2834 it
->first_vpos
= first_vpos
;
2836 /* Don't reseat to previous visible line start if current start
2837 position is in a string or image. */
2838 if (it
->method
== GET_FROM_BUFFER
&& it
->line_wrap
!= TRUNCATE
)
2840 int start_at_line_beg_p
;
2841 int first_y
= it
->current_y
;
2843 /* If window start is not at a line start, skip forward to POS to
2844 get the correct continuation lines width. */
2845 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2846 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2847 if (!start_at_line_beg_p
)
2851 reseat_at_previous_visible_line_start (it
);
2852 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2854 new_x
= it
->current_x
+ it
->pixel_width
;
2856 /* If lines are continued, this line may end in the middle
2857 of a multi-glyph character (e.g. a control character
2858 displayed as \003, or in the middle of an overlay
2859 string). In this case move_it_to above will not have
2860 taken us to the start of the continuation line but to the
2861 end of the continued line. */
2862 if (it
->current_x
> 0
2863 && it
->line_wrap
!= TRUNCATE
/* Lines are continued. */
2864 && (/* And glyph doesn't fit on the line. */
2865 new_x
> it
->last_visible_x
2866 /* Or it fits exactly and we're on a window
2868 || (new_x
== it
->last_visible_x
2869 && FRAME_WINDOW_P (it
->f
))))
2871 if (it
->current
.dpvec_index
>= 0
2872 || it
->current
.overlay_string_index
>= 0)
2874 set_iterator_to_next (it
, 1);
2875 move_it_in_display_line_to (it
, -1, -1, 0);
2878 it
->continuation_lines_width
+= it
->current_x
;
2881 /* We're starting a new display line, not affected by the
2882 height of the continued line, so clear the appropriate
2883 fields in the iterator structure. */
2884 it
->max_ascent
= it
->max_descent
= 0;
2885 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2887 it
->current_y
= first_y
;
2889 it
->current_x
= it
->hpos
= 0;
2895 /* Return 1 if POS is a position in ellipses displayed for invisible
2896 text. W is the window we display, for text property lookup. */
2899 in_ellipses_for_invisible_text_p (struct display_pos
*pos
, struct window
*w
)
2901 Lisp_Object prop
, window
;
2903 int charpos
= CHARPOS (pos
->pos
);
2905 /* If POS specifies a position in a display vector, this might
2906 be for an ellipsis displayed for invisible text. We won't
2907 get the iterator set up for delivering that ellipsis unless
2908 we make sure that it gets aware of the invisible text. */
2909 if (pos
->dpvec_index
>= 0
2910 && pos
->overlay_string_index
< 0
2911 && CHARPOS (pos
->string_pos
) < 0
2913 && (XSETWINDOW (window
, w
),
2914 prop
= Fget_char_property (make_number (charpos
),
2915 Qinvisible
, window
),
2916 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2918 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2920 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2927 /* Initialize IT for stepping through current_buffer in window W,
2928 starting at position POS that includes overlay string and display
2929 vector/ control character translation position information. Value
2930 is zero if there are overlay strings with newlines at POS. */
2933 init_from_display_pos (struct it
*it
, struct window
*w
, struct display_pos
*pos
)
2935 EMACS_INT charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2936 int i
, overlay_strings_with_newlines
= 0;
2938 /* If POS specifies a position in a display vector, this might
2939 be for an ellipsis displayed for invisible text. We won't
2940 get the iterator set up for delivering that ellipsis unless
2941 we make sure that it gets aware of the invisible text. */
2942 if (in_ellipses_for_invisible_text_p (pos
, w
))
2948 /* Keep in mind: the call to reseat in init_iterator skips invisible
2949 text, so we might end up at a position different from POS. This
2950 is only a problem when POS is a row start after a newline and an
2951 overlay starts there with an after-string, and the overlay has an
2952 invisible property. Since we don't skip invisible text in
2953 display_line and elsewhere immediately after consuming the
2954 newline before the row start, such a POS will not be in a string,
2955 but the call to init_iterator below will move us to the
2957 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2959 /* This only scans the current chunk -- it should scan all chunks.
2960 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2961 to 16 in 22.1 to make this a lesser problem. */
2962 for (i
= 0; i
< it
->n_overlay_strings
&& i
< OVERLAY_STRING_CHUNK_SIZE
; ++i
)
2964 const char *s
= SDATA (it
->overlay_strings
[i
]);
2965 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2967 while (s
< e
&& *s
!= '\n')
2972 overlay_strings_with_newlines
= 1;
2977 /* If position is within an overlay string, set up IT to the right
2979 if (pos
->overlay_string_index
>= 0)
2983 /* If the first overlay string happens to have a `display'
2984 property for an image, the iterator will be set up for that
2985 image, and we have to undo that setup first before we can
2986 correct the overlay string index. */
2987 if (it
->method
== GET_FROM_IMAGE
)
2990 /* We already have the first chunk of overlay strings in
2991 IT->overlay_strings. Load more until the one for
2992 pos->overlay_string_index is in IT->overlay_strings. */
2993 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
2995 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
2996 it
->current
.overlay_string_index
= 0;
2999 load_overlay_strings (it
, 0);
3000 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
3004 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
3005 relative_index
= (it
->current
.overlay_string_index
3006 % OVERLAY_STRING_CHUNK_SIZE
);
3007 it
->string
= it
->overlay_strings
[relative_index
];
3008 xassert (STRINGP (it
->string
));
3009 it
->current
.string_pos
= pos
->string_pos
;
3010 it
->method
= GET_FROM_STRING
;
3013 if (CHARPOS (pos
->string_pos
) >= 0)
3015 /* Recorded position is not in an overlay string, but in another
3016 string. This can only be a string from a `display' property.
3017 IT should already be filled with that string. */
3018 it
->current
.string_pos
= pos
->string_pos
;
3019 xassert (STRINGP (it
->string
));
3022 /* Restore position in display vector translations, control
3023 character translations or ellipses. */
3024 if (pos
->dpvec_index
>= 0)
3026 if (it
->dpvec
== NULL
)
3027 get_next_display_element (it
);
3028 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
3029 it
->current
.dpvec_index
= pos
->dpvec_index
;
3033 return !overlay_strings_with_newlines
;
3037 /* Initialize IT for stepping through current_buffer in window W
3038 starting at ROW->start. */
3041 init_to_row_start (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3043 init_from_display_pos (it
, w
, &row
->start
);
3044 it
->start
= row
->start
;
3045 it
->continuation_lines_width
= row
->continuation_lines_width
;
3050 /* Initialize IT for stepping through current_buffer in window W
3051 starting in the line following ROW, i.e. starting at ROW->end.
3052 Value is zero if there are overlay strings with newlines at ROW's
3056 init_to_row_end (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3060 if (init_from_display_pos (it
, w
, &row
->end
))
3062 if (row
->continued_p
)
3063 it
->continuation_lines_width
3064 = row
->continuation_lines_width
+ row
->pixel_width
;
3075 /***********************************************************************
3077 ***********************************************************************/
3079 /* Called when IT reaches IT->stop_charpos. Handle text property and
3080 overlay changes. Set IT->stop_charpos to the next position where
3084 handle_stop (struct it
*it
)
3086 enum prop_handled handled
;
3087 int handle_overlay_change_p
;
3091 it
->current
.dpvec_index
= -1;
3092 handle_overlay_change_p
= !it
->ignore_overlay_strings_at_pos_p
;
3093 it
->ignore_overlay_strings_at_pos_p
= 0;
3096 /* Use face of preceding text for ellipsis (if invisible) */
3097 if (it
->selective_display_ellipsis_p
)
3098 it
->saved_face_id
= it
->face_id
;
3102 handled
= HANDLED_NORMALLY
;
3104 /* Call text property handlers. */
3105 for (p
= it_props
; p
->handler
; ++p
)
3107 handled
= p
->handler (it
);
3109 if (handled
== HANDLED_RECOMPUTE_PROPS
)
3111 else if (handled
== HANDLED_RETURN
)
3113 /* We still want to show before and after strings from
3114 overlays even if the actual buffer text is replaced. */
3115 if (!handle_overlay_change_p
3117 || !get_overlay_strings_1 (it
, 0, 0))
3120 setup_for_ellipsis (it
, 0);
3121 /* When handling a display spec, we might load an
3122 empty string. In that case, discard it here. We
3123 used to discard it in handle_single_display_spec,
3124 but that causes get_overlay_strings_1, above, to
3125 ignore overlay strings that we must check. */
3126 if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3130 else if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3134 it
->ignore_overlay_strings_at_pos_p
= 1;
3135 it
->string_from_display_prop_p
= 0;
3136 handle_overlay_change_p
= 0;
3138 handled
= HANDLED_RECOMPUTE_PROPS
;
3141 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
3142 handle_overlay_change_p
= 0;
3145 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
3147 /* Don't check for overlay strings below when set to deliver
3148 characters from a display vector. */
3149 if (it
->method
== GET_FROM_DISPLAY_VECTOR
)
3150 handle_overlay_change_p
= 0;
3152 /* Handle overlay changes.
3153 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3154 if it finds overlays. */
3155 if (handle_overlay_change_p
)
3156 handled
= handle_overlay_change (it
);
3161 setup_for_ellipsis (it
, 0);
3165 while (handled
== HANDLED_RECOMPUTE_PROPS
);
3167 /* Determine where to stop next. */
3168 if (handled
== HANDLED_NORMALLY
)
3169 compute_stop_pos (it
);
3173 /* Compute IT->stop_charpos from text property and overlay change
3174 information for IT's current position. */
3177 compute_stop_pos (struct it
*it
)
3179 register INTERVAL iv
, next_iv
;
3180 Lisp_Object object
, limit
, position
;
3181 EMACS_INT charpos
, bytepos
;
3183 /* If nowhere else, stop at the end. */
3184 it
->stop_charpos
= it
->end_charpos
;
3186 if (STRINGP (it
->string
))
3188 /* Strings are usually short, so don't limit the search for
3190 object
= it
->string
;
3192 charpos
= IT_STRING_CHARPOS (*it
);
3193 bytepos
= IT_STRING_BYTEPOS (*it
);
3199 /* If next overlay change is in front of the current stop pos
3200 (which is IT->end_charpos), stop there. Note: value of
3201 next_overlay_change is point-max if no overlay change
3203 charpos
= IT_CHARPOS (*it
);
3204 bytepos
= IT_BYTEPOS (*it
);
3205 pos
= next_overlay_change (charpos
);
3206 if (pos
< it
->stop_charpos
)
3207 it
->stop_charpos
= pos
;
3209 /* If showing the region, we have to stop at the region
3210 start or end because the face might change there. */
3211 if (it
->region_beg_charpos
> 0)
3213 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
3214 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
3215 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
3216 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
3219 /* Set up variables for computing the stop position from text
3220 property changes. */
3221 XSETBUFFER (object
, current_buffer
);
3222 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
3225 /* Get the interval containing IT's position. Value is a null
3226 interval if there isn't such an interval. */
3227 position
= make_number (charpos
);
3228 iv
= validate_interval_range (object
, &position
, &position
, 0);
3229 if (!NULL_INTERVAL_P (iv
))
3231 Lisp_Object values_here
[LAST_PROP_IDX
];
3234 /* Get properties here. */
3235 for (p
= it_props
; p
->handler
; ++p
)
3236 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
3238 /* Look for an interval following iv that has different
3240 for (next_iv
= next_interval (iv
);
3241 (!NULL_INTERVAL_P (next_iv
)
3243 || XFASTINT (limit
) > next_iv
->position
));
3244 next_iv
= next_interval (next_iv
))
3246 for (p
= it_props
; p
->handler
; ++p
)
3248 Lisp_Object new_value
;
3250 new_value
= textget (next_iv
->plist
, *p
->name
);
3251 if (!EQ (values_here
[p
->idx
], new_value
))
3259 if (!NULL_INTERVAL_P (next_iv
))
3261 if (INTEGERP (limit
)
3262 && next_iv
->position
>= XFASTINT (limit
))
3263 /* No text property change up to limit. */
3264 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
3266 /* Text properties change in next_iv. */
3267 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
3271 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
,
3272 it
->stop_charpos
, it
->string
);
3274 xassert (STRINGP (it
->string
)
3275 || (it
->stop_charpos
>= BEGV
3276 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
3280 /* Return the position of the next overlay change after POS in
3281 current_buffer. Value is point-max if no overlay change
3282 follows. This is like `next-overlay-change' but doesn't use
3286 next_overlay_change (EMACS_INT pos
)
3290 Lisp_Object
*overlays
;
3293 /* Get all overlays at the given position. */
3294 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
3296 /* If any of these overlays ends before endpos,
3297 use its ending point instead. */
3298 for (i
= 0; i
< noverlays
; ++i
)
3303 oend
= OVERLAY_END (overlays
[i
]);
3304 oendpos
= OVERLAY_POSITION (oend
);
3305 endpos
= min (endpos
, oendpos
);
3313 /***********************************************************************
3315 ***********************************************************************/
3317 /* Handle changes in the `fontified' property of the current buffer by
3318 calling hook functions from Qfontification_functions to fontify
3321 static enum prop_handled
3322 handle_fontified_prop (struct it
*it
)
3324 Lisp_Object prop
, pos
;
3325 enum prop_handled handled
= HANDLED_NORMALLY
;
3327 if (!NILP (Vmemory_full
))
3330 /* Get the value of the `fontified' property at IT's current buffer
3331 position. (The `fontified' property doesn't have a special
3332 meaning in strings.) If the value is nil, call functions from
3333 Qfontification_functions. */
3334 if (!STRINGP (it
->string
)
3336 && !NILP (Vfontification_functions
)
3337 && !NILP (Vrun_hooks
)
3338 && (pos
= make_number (IT_CHARPOS (*it
)),
3339 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
3340 /* Ignore the special cased nil value always present at EOB since
3341 no amount of fontifying will be able to change it. */
3342 NILP (prop
) && IT_CHARPOS (*it
) < Z
))
3344 int count
= SPECPDL_INDEX ();
3347 val
= Vfontification_functions
;
3348 specbind (Qfontification_functions
, Qnil
);
3350 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
3351 safe_call1 (val
, pos
);
3354 Lisp_Object globals
, fn
;
3355 struct gcpro gcpro1
, gcpro2
;
3358 GCPRO2 (val
, globals
);
3360 for (; CONSP (val
); val
= XCDR (val
))
3366 /* A value of t indicates this hook has a local
3367 binding; it means to run the global binding too.
3368 In a global value, t should not occur. If it
3369 does, we must ignore it to avoid an endless
3371 for (globals
= Fdefault_value (Qfontification_functions
);
3373 globals
= XCDR (globals
))
3375 fn
= XCAR (globals
);
3377 safe_call1 (fn
, pos
);
3381 safe_call1 (fn
, pos
);
3387 unbind_to (count
, Qnil
);
3389 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3390 something. This avoids an endless loop if they failed to
3391 fontify the text for which reason ever. */
3392 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
3393 handled
= HANDLED_RECOMPUTE_PROPS
;
3401 /***********************************************************************
3403 ***********************************************************************/
3405 /* Set up iterator IT from face properties at its current position.
3406 Called from handle_stop. */
3408 static enum prop_handled
3409 handle_face_prop (struct it
*it
)
3412 EMACS_INT next_stop
;
3414 if (!STRINGP (it
->string
))
3417 = face_at_buffer_position (it
->w
,
3419 it
->region_beg_charpos
,
3420 it
->region_end_charpos
,
3423 + TEXT_PROP_DISTANCE_LIMIT
),
3424 0, it
->base_face_id
);
3426 /* Is this a start of a run of characters with box face?
3427 Caveat: this can be called for a freshly initialized
3428 iterator; face_id is -1 in this case. We know that the new
3429 face will not change until limit, i.e. if the new face has a
3430 box, all characters up to limit will have one. But, as
3431 usual, we don't know whether limit is really the end. */
3432 if (new_face_id
!= it
->face_id
)
3434 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3436 /* If new face has a box but old face has not, this is
3437 the start of a run of characters with box, i.e. it has
3438 a shadow on the left side. The value of face_id of the
3439 iterator will be -1 if this is the initial call that gets
3440 the face. In this case, we have to look in front of IT's
3441 position and see whether there is a face != new_face_id. */
3442 it
->start_of_box_run_p
3443 = (new_face
->box
!= FACE_NO_BOX
3444 && (it
->face_id
>= 0
3445 || IT_CHARPOS (*it
) == BEG
3446 || new_face_id
!= face_before_it_pos (it
)));
3447 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3452 int base_face_id
, bufpos
;
3454 Lisp_Object from_overlay
3455 = (it
->current
.overlay_string_index
>= 0
3456 ? it
->string_overlays
[it
->current
.overlay_string_index
]
3459 /* See if we got to this string directly or indirectly from
3460 an overlay property. That includes the before-string or
3461 after-string of an overlay, strings in display properties
3462 provided by an overlay, their text properties, etc.
3464 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3465 if (! NILP (from_overlay
))
3466 for (i
= it
->sp
- 1; i
>= 0; i
--)
3468 if (it
->stack
[i
].current
.overlay_string_index
>= 0)
3470 = it
->string_overlays
[it
->stack
[i
].current
.overlay_string_index
];
3471 else if (! NILP (it
->stack
[i
].from_overlay
))
3472 from_overlay
= it
->stack
[i
].from_overlay
;
3474 if (!NILP (from_overlay
))
3478 if (! NILP (from_overlay
))
3480 bufpos
= IT_CHARPOS (*it
);
3481 /* For a string from an overlay, the base face depends
3482 only on text properties and ignores overlays. */
3484 = face_for_overlay_string (it
->w
,
3486 it
->region_beg_charpos
,
3487 it
->region_end_charpos
,
3490 + TEXT_PROP_DISTANCE_LIMIT
),
3498 /* For strings from a `display' property, use the face at
3499 IT's current buffer position as the base face to merge
3500 with, so that overlay strings appear in the same face as
3501 surrounding text, unless they specify their own
3503 base_face_id
= underlying_face_id (it
);
3506 new_face_id
= face_at_string_position (it
->w
,
3508 IT_STRING_CHARPOS (*it
),
3510 it
->region_beg_charpos
,
3511 it
->region_end_charpos
,
3515 /* Is this a start of a run of characters with box? Caveat:
3516 this can be called for a freshly allocated iterator; face_id
3517 is -1 is this case. We know that the new face will not
3518 change until the next check pos, i.e. if the new face has a
3519 box, all characters up to that position will have a
3520 box. But, as usual, we don't know whether that position
3521 is really the end. */
3522 if (new_face_id
!= it
->face_id
)
3524 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3525 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3527 /* If new face has a box but old face hasn't, this is the
3528 start of a run of characters with box, i.e. it has a
3529 shadow on the left side. */
3530 it
->start_of_box_run_p
3531 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
3532 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3536 it
->face_id
= new_face_id
;
3537 return HANDLED_NORMALLY
;
3541 /* Return the ID of the face ``underlying'' IT's current position,
3542 which is in a string. If the iterator is associated with a
3543 buffer, return the face at IT's current buffer position.
3544 Otherwise, use the iterator's base_face_id. */
3547 underlying_face_id (struct it
*it
)
3549 int face_id
= it
->base_face_id
, i
;
3551 xassert (STRINGP (it
->string
));
3553 for (i
= it
->sp
- 1; i
>= 0; --i
)
3554 if (NILP (it
->stack
[i
].string
))
3555 face_id
= it
->stack
[i
].face_id
;
3561 /* Compute the face one character before or after the current position
3562 of IT. BEFORE_P non-zero means get the face in front of IT's
3563 position. Value is the id of the face. */
3566 face_before_or_after_it_pos (struct it
*it
, int before_p
)
3569 EMACS_INT next_check_charpos
;
3570 struct text_pos pos
;
3572 xassert (it
->s
== NULL
);
3574 if (STRINGP (it
->string
))
3576 int bufpos
, base_face_id
;
3578 /* No face change past the end of the string (for the case
3579 we are padding with spaces). No face change before the
3581 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
3582 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
3585 /* Set pos to the position before or after IT's current position. */
3587 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
3589 /* For composition, we must check the character after the
3591 pos
= (it
->what
== IT_COMPOSITION
3592 ? string_pos (IT_STRING_CHARPOS (*it
)
3593 + it
->cmp_it
.nchars
, it
->string
)
3594 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
3596 if (it
->current
.overlay_string_index
>= 0)
3597 bufpos
= IT_CHARPOS (*it
);
3601 base_face_id
= underlying_face_id (it
);
3603 /* Get the face for ASCII, or unibyte. */
3604 face_id
= face_at_string_position (it
->w
,
3608 it
->region_beg_charpos
,
3609 it
->region_end_charpos
,
3610 &next_check_charpos
,
3613 /* Correct the face for charsets different from ASCII. Do it
3614 for the multibyte case only. The face returned above is
3615 suitable for unibyte text if IT->string is unibyte. */
3616 if (STRING_MULTIBYTE (it
->string
))
3618 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
3619 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
3621 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3623 c
= string_char_and_length (p
, &len
);
3624 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, CHARPOS (pos
), it
->string
);
3629 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3630 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3633 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3634 pos
= it
->current
.pos
;
3637 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3640 if (it
->what
== IT_COMPOSITION
)
3641 /* For composition, we must check the position after the
3643 pos
.charpos
+= it
->cmp_it
.nchars
, pos
.bytepos
+= it
->len
;
3645 INC_TEXT_POS (pos
, it
->multibyte_p
);
3648 /* Determine face for CHARSET_ASCII, or unibyte. */
3649 face_id
= face_at_buffer_position (it
->w
,
3651 it
->region_beg_charpos
,
3652 it
->region_end_charpos
,
3653 &next_check_charpos
,
3656 /* Correct the face for charsets different from ASCII. Do it
3657 for the multibyte case only. The face returned above is
3658 suitable for unibyte text if current_buffer is unibyte. */
3659 if (it
->multibyte_p
)
3661 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3662 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3663 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, CHARPOS (pos
), Qnil
);
3672 /***********************************************************************
3674 ***********************************************************************/
3676 /* Set up iterator IT from invisible properties at its current
3677 position. Called from handle_stop. */
3679 static enum prop_handled
3680 handle_invisible_prop (struct it
*it
)
3682 enum prop_handled handled
= HANDLED_NORMALLY
;
3684 if (STRINGP (it
->string
))
3686 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3688 /* Get the value of the invisible text property at the
3689 current position. Value will be nil if there is no such
3691 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3692 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3695 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3697 handled
= HANDLED_RECOMPUTE_PROPS
;
3699 /* Get the position at which the next change of the
3700 invisible text property can be found in IT->string.
3701 Value will be nil if the property value is the same for
3702 all the rest of IT->string. */
3703 XSETINT (limit
, SCHARS (it
->string
));
3704 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3707 /* Text at current position is invisible. The next
3708 change in the property is at position end_charpos.
3709 Move IT's current position to that position. */
3710 if (INTEGERP (end_charpos
)
3711 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3713 struct text_pos old
;
3714 old
= it
->current
.string_pos
;
3715 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3716 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3720 /* The rest of the string is invisible. If this is an
3721 overlay string, proceed with the next overlay string
3722 or whatever comes and return a character from there. */
3723 if (it
->current
.overlay_string_index
>= 0)
3725 next_overlay_string (it
);
3726 /* Don't check for overlay strings when we just
3727 finished processing them. */
3728 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3732 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3733 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3741 EMACS_INT newpos
, next_stop
, start_charpos
, tem
;
3742 Lisp_Object pos
, prop
, overlay
;
3744 /* First of all, is there invisible text at this position? */
3745 tem
= start_charpos
= IT_CHARPOS (*it
);
3746 pos
= make_number (tem
);
3747 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3749 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3751 /* If we are on invisible text, skip over it. */
3752 if (invis_p
&& start_charpos
< it
->end_charpos
)
3754 /* Record whether we have to display an ellipsis for the
3756 int display_ellipsis_p
= invis_p
== 2;
3758 handled
= HANDLED_RECOMPUTE_PROPS
;
3760 /* Loop skipping over invisible text. The loop is left at
3761 ZV or with IT on the first char being visible again. */
3764 /* Try to skip some invisible text. Return value is the
3765 position reached which can be equal to where we start
3766 if there is nothing invisible there. This skips both
3767 over invisible text properties and overlays with
3768 invisible property. */
3769 newpos
= skip_invisible (tem
, &next_stop
, ZV
, it
->window
);
3771 /* If we skipped nothing at all we weren't at invisible
3772 text in the first place. If everything to the end of
3773 the buffer was skipped, end the loop. */
3774 if (newpos
== tem
|| newpos
>= ZV
)
3778 /* We skipped some characters but not necessarily
3779 all there are. Check if we ended up on visible
3780 text. Fget_char_property returns the property of
3781 the char before the given position, i.e. if we
3782 get invis_p = 0, this means that the char at
3783 newpos is visible. */
3784 pos
= make_number (newpos
);
3785 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3786 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3789 /* If we ended up on invisible text, proceed to
3790 skip starting with next_stop. */
3794 /* If there are adjacent invisible texts, don't lose the
3795 second one's ellipsis. */
3797 display_ellipsis_p
= 1;
3801 /* The position newpos is now either ZV or on visible text. */
3802 if (it
->bidi_p
&& newpos
< ZV
)
3804 /* With bidi iteration, the region of invisible text
3805 could start and/or end in the middle of a non-base
3806 embedding level. Therefore, we need to skip
3807 invisible text using the bidi iterator, starting at
3808 IT's current position, until we find ourselves
3809 outside the invisible text. Skipping invisible text
3810 _after_ bidi iteration avoids affecting the visual
3811 order of the displayed text when invisible properties
3812 are added or removed. */
3813 if (it
->bidi_it
.first_elt
)
3815 /* If we were `reseat'ed to a new paragraph,
3816 determine the paragraph base direction. We need
3817 to do it now because next_element_from_buffer may
3818 not have a chance to do it, if we are going to
3819 skip any text at the beginning, which resets the
3821 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
3825 bidi_move_to_visually_next (&it
->bidi_it
);
3827 while (it
->stop_charpos
<= it
->bidi_it
.charpos
3828 && it
->bidi_it
.charpos
< newpos
);
3829 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
3830 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
3831 /* If we overstepped NEWPOS, record its position in the
3832 iterator, so that we skip invisible text if later the
3833 bidi iteration lands us in the invisible region
3835 if (IT_CHARPOS (*it
) >= newpos
)
3836 it
->prev_stop
= newpos
;
3840 IT_CHARPOS (*it
) = newpos
;
3841 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3844 /* If there are before-strings at the start of invisible
3845 text, and the text is invisible because of a text
3846 property, arrange to show before-strings because 20.x did
3847 it that way. (If the text is invisible because of an
3848 overlay property instead of a text property, this is
3849 already handled in the overlay code.) */
3851 && get_overlay_strings (it
, it
->stop_charpos
))
3853 handled
= HANDLED_RECOMPUTE_PROPS
;
3854 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3856 else if (display_ellipsis_p
)
3858 /* Make sure that the glyphs of the ellipsis will get
3859 correct `charpos' values. If we would not update
3860 it->position here, the glyphs would belong to the
3861 last visible character _before_ the invisible
3862 text, which confuses `set_cursor_from_row'.
3864 We use the last invisible position instead of the
3865 first because this way the cursor is always drawn on
3866 the first "." of the ellipsis, whenever PT is inside
3867 the invisible text. Otherwise the cursor would be
3868 placed _after_ the ellipsis when the point is after the
3869 first invisible character. */
3870 if (!STRINGP (it
->object
))
3872 it
->position
.charpos
= newpos
- 1;
3873 it
->position
.bytepos
= CHAR_TO_BYTE (it
->position
.charpos
);
3876 /* Let the ellipsis display before
3877 considering any properties of the following char.
3878 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3879 handled
= HANDLED_RETURN
;
3888 /* Make iterator IT return `...' next.
3889 Replaces LEN characters from buffer. */
3892 setup_for_ellipsis (struct it
*it
, int len
)
3894 /* Use the display table definition for `...'. Invalid glyphs
3895 will be handled by the method returning elements from dpvec. */
3896 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3898 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3899 it
->dpvec
= v
->contents
;
3900 it
->dpend
= v
->contents
+ v
->size
;
3904 /* Default `...'. */
3905 it
->dpvec
= default_invis_vector
;
3906 it
->dpend
= default_invis_vector
+ 3;
3909 it
->dpvec_char_len
= len
;
3910 it
->current
.dpvec_index
= 0;
3911 it
->dpvec_face_id
= -1;
3913 /* Remember the current face id in case glyphs specify faces.
3914 IT's face is restored in set_iterator_to_next.
3915 saved_face_id was set to preceding char's face in handle_stop. */
3916 if (it
->saved_face_id
< 0 || it
->saved_face_id
!= it
->face_id
)
3917 it
->saved_face_id
= it
->face_id
= DEFAULT_FACE_ID
;
3919 it
->method
= GET_FROM_DISPLAY_VECTOR
;
3925 /***********************************************************************
3927 ***********************************************************************/
3929 /* Set up iterator IT from `display' property at its current position.
3930 Called from handle_stop.
3931 We return HANDLED_RETURN if some part of the display property
3932 overrides the display of the buffer text itself.
3933 Otherwise we return HANDLED_NORMALLY. */
3935 static enum prop_handled
3936 handle_display_prop (struct it
*it
)
3938 Lisp_Object prop
, object
, overlay
;
3939 struct text_pos
*position
;
3940 /* Nonzero if some property replaces the display of the text itself. */
3941 int display_replaced_p
= 0;
3943 if (STRINGP (it
->string
))
3945 object
= it
->string
;
3946 position
= &it
->current
.string_pos
;
3950 XSETWINDOW (object
, it
->w
);
3951 position
= &it
->current
.pos
;
3954 /* Reset those iterator values set from display property values. */
3955 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
3956 it
->space_width
= Qnil
;
3957 it
->font_height
= Qnil
;
3960 /* We don't support recursive `display' properties, i.e. string
3961 values that have a string `display' property, that have a string
3962 `display' property etc. */
3963 if (!it
->string_from_display_prop_p
)
3964 it
->area
= TEXT_AREA
;
3966 prop
= get_char_property_and_overlay (make_number (position
->charpos
),
3967 Qdisplay
, object
, &overlay
);
3969 return HANDLED_NORMALLY
;
3970 /* Now OVERLAY is the overlay that gave us this property, or nil
3971 if it was a text property. */
3973 if (!STRINGP (it
->string
))
3974 object
= it
->w
->buffer
;
3977 /* Simple properties. */
3978 && !EQ (XCAR (prop
), Qimage
)
3979 && !EQ (XCAR (prop
), Qspace
)
3980 && !EQ (XCAR (prop
), Qwhen
)
3981 && !EQ (XCAR (prop
), Qslice
)
3982 && !EQ (XCAR (prop
), Qspace_width
)
3983 && !EQ (XCAR (prop
), Qheight
)
3984 && !EQ (XCAR (prop
), Qraise
)
3985 /* Marginal area specifications. */
3986 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3987 && !EQ (XCAR (prop
), Qleft_fringe
)
3988 && !EQ (XCAR (prop
), Qright_fringe
)
3989 && !NILP (XCAR (prop
)))
3991 for (; CONSP (prop
); prop
= XCDR (prop
))
3993 if (handle_single_display_spec (it
, XCAR (prop
), object
, overlay
,
3994 position
, display_replaced_p
))
3996 display_replaced_p
= 1;
3997 /* If some text in a string is replaced, `position' no
3998 longer points to the position of `object'. */
3999 if (STRINGP (object
))
4004 else if (VECTORP (prop
))
4007 for (i
= 0; i
< ASIZE (prop
); ++i
)
4008 if (handle_single_display_spec (it
, AREF (prop
, i
), object
, overlay
,
4009 position
, display_replaced_p
))
4011 display_replaced_p
= 1;
4012 /* If some text in a string is replaced, `position' no
4013 longer points to the position of `object'. */
4014 if (STRINGP (object
))
4020 if (handle_single_display_spec (it
, prop
, object
, overlay
,
4022 display_replaced_p
= 1;
4025 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
4029 /* Value is the position of the end of the `display' property starting
4030 at START_POS in OBJECT. */
4032 static struct text_pos
4033 display_prop_end (struct it
*it
, Lisp_Object object
, struct text_pos start_pos
)
4036 struct text_pos end_pos
;
4038 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
4039 Qdisplay
, object
, Qnil
);
4040 CHARPOS (end_pos
) = XFASTINT (end
);
4041 if (STRINGP (object
))
4042 compute_string_pos (&end_pos
, start_pos
, it
->string
);
4044 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
4050 /* Set up IT from a single `display' specification PROP. OBJECT
4051 is the object in which the `display' property was found. *POSITION
4052 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4053 means that we previously saw a display specification which already
4054 replaced text display with something else, for example an image;
4055 we ignore such properties after the first one has been processed.
4057 OVERLAY is the overlay this `display' property came from,
4058 or nil if it was a text property.
4060 If PROP is a `space' or `image' specification, and in some other
4061 cases too, set *POSITION to the position where the `display'
4064 Value is non-zero if something was found which replaces the display
4065 of buffer or string text. */
4068 handle_single_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4069 Lisp_Object overlay
, struct text_pos
*position
,
4070 int display_replaced_before_p
)
4073 Lisp_Object location
, value
;
4074 struct text_pos start_pos
, save_pos
;
4077 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4078 If the result is non-nil, use VALUE instead of SPEC. */
4080 if (CONSP (spec
) && EQ (XCAR (spec
), Qwhen
))
4089 if (!NILP (form
) && !EQ (form
, Qt
))
4091 int count
= SPECPDL_INDEX ();
4092 struct gcpro gcpro1
;
4094 /* Bind `object' to the object having the `display' property, a
4095 buffer or string. Bind `position' to the position in the
4096 object where the property was found, and `buffer-position'
4097 to the current position in the buffer. */
4098 specbind (Qobject
, object
);
4099 specbind (Qposition
, make_number (CHARPOS (*position
)));
4100 specbind (Qbuffer_position
,
4101 make_number (STRINGP (object
)
4102 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
4104 form
= safe_eval (form
);
4106 unbind_to (count
, Qnil
);
4112 /* Handle `(height HEIGHT)' specifications. */
4114 && EQ (XCAR (spec
), Qheight
)
4115 && CONSP (XCDR (spec
)))
4117 if (!FRAME_WINDOW_P (it
->f
))
4120 it
->font_height
= XCAR (XCDR (spec
));
4121 if (!NILP (it
->font_height
))
4123 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4124 int new_height
= -1;
4126 if (CONSP (it
->font_height
)
4127 && (EQ (XCAR (it
->font_height
), Qplus
)
4128 || EQ (XCAR (it
->font_height
), Qminus
))
4129 && CONSP (XCDR (it
->font_height
))
4130 && INTEGERP (XCAR (XCDR (it
->font_height
))))
4132 /* `(+ N)' or `(- N)' where N is an integer. */
4133 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
4134 if (EQ (XCAR (it
->font_height
), Qplus
))
4136 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
4138 else if (FUNCTIONP (it
->font_height
))
4140 /* Call function with current height as argument.
4141 Value is the new height. */
4143 height
= safe_call1 (it
->font_height
,
4144 face
->lface
[LFACE_HEIGHT_INDEX
]);
4145 if (NUMBERP (height
))
4146 new_height
= XFLOATINT (height
);
4148 else if (NUMBERP (it
->font_height
))
4150 /* Value is a multiple of the canonical char height. */
4153 face
= FACE_FROM_ID (it
->f
,
4154 lookup_basic_face (it
->f
, DEFAULT_FACE_ID
));
4155 new_height
= (XFLOATINT (it
->font_height
)
4156 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
4160 /* Evaluate IT->font_height with `height' bound to the
4161 current specified height to get the new height. */
4162 int count
= SPECPDL_INDEX ();
4164 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
4165 value
= safe_eval (it
->font_height
);
4166 unbind_to (count
, Qnil
);
4168 if (NUMBERP (value
))
4169 new_height
= XFLOATINT (value
);
4173 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
4179 /* Handle `(space-width WIDTH)'. */
4181 && EQ (XCAR (spec
), Qspace_width
)
4182 && CONSP (XCDR (spec
)))
4184 if (!FRAME_WINDOW_P (it
->f
))
4187 value
= XCAR (XCDR (spec
));
4188 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
4189 it
->space_width
= value
;
4194 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4196 && EQ (XCAR (spec
), Qslice
))
4200 if (!FRAME_WINDOW_P (it
->f
))
4203 if (tem
= XCDR (spec
), CONSP (tem
))
4205 it
->slice
.x
= XCAR (tem
);
4206 if (tem
= XCDR (tem
), CONSP (tem
))
4208 it
->slice
.y
= XCAR (tem
);
4209 if (tem
= XCDR (tem
), CONSP (tem
))
4211 it
->slice
.width
= XCAR (tem
);
4212 if (tem
= XCDR (tem
), CONSP (tem
))
4213 it
->slice
.height
= XCAR (tem
);
4221 /* Handle `(raise FACTOR)'. */
4223 && EQ (XCAR (spec
), Qraise
)
4224 && CONSP (XCDR (spec
)))
4226 if (!FRAME_WINDOW_P (it
->f
))
4229 #ifdef HAVE_WINDOW_SYSTEM
4230 value
= XCAR (XCDR (spec
));
4231 if (NUMBERP (value
))
4233 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4234 it
->voffset
= - (XFLOATINT (value
)
4235 * (FONT_HEIGHT (face
->font
)));
4237 #endif /* HAVE_WINDOW_SYSTEM */
4242 /* Don't handle the other kinds of display specifications
4243 inside a string that we got from a `display' property. */
4244 if (it
->string_from_display_prop_p
)
4247 /* Characters having this form of property are not displayed, so
4248 we have to find the end of the property. */
4249 start_pos
= *position
;
4250 *position
= display_prop_end (it
, object
, start_pos
);
4253 /* Stop the scan at that end position--we assume that all
4254 text properties change there. */
4255 it
->stop_charpos
= position
->charpos
;
4257 /* Handle `(left-fringe BITMAP [FACE])'
4258 and `(right-fringe BITMAP [FACE])'. */
4260 && (EQ (XCAR (spec
), Qleft_fringe
)
4261 || EQ (XCAR (spec
), Qright_fringe
))
4262 && CONSP (XCDR (spec
)))
4264 int face_id
= lookup_basic_face (it
->f
, DEFAULT_FACE_ID
);
4267 if (!FRAME_WINDOW_P (it
->f
))
4268 /* If we return here, POSITION has been advanced
4269 across the text with this property. */
4272 #ifdef HAVE_WINDOW_SYSTEM
4273 value
= XCAR (XCDR (spec
));
4274 if (!SYMBOLP (value
)
4275 || !(fringe_bitmap
= lookup_fringe_bitmap (value
)))
4276 /* If we return here, POSITION has been advanced
4277 across the text with this property. */
4280 if (CONSP (XCDR (XCDR (spec
))))
4282 Lisp_Object face_name
= XCAR (XCDR (XCDR (spec
)));
4283 int face_id2
= lookup_derived_face (it
->f
, face_name
,
4289 /* Save current settings of IT so that we can restore them
4290 when we are finished with the glyph property value. */
4292 save_pos
= it
->position
;
4293 it
->position
= *position
;
4295 it
->position
= save_pos
;
4297 it
->area
= TEXT_AREA
;
4298 it
->what
= IT_IMAGE
;
4299 it
->image_id
= -1; /* no image */
4300 it
->position
= start_pos
;
4301 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
4302 it
->method
= GET_FROM_IMAGE
;
4303 it
->from_overlay
= Qnil
;
4304 it
->face_id
= face_id
;
4306 /* Say that we haven't consumed the characters with
4307 `display' property yet. The call to pop_it in
4308 set_iterator_to_next will clean this up. */
4309 *position
= start_pos
;
4311 if (EQ (XCAR (spec
), Qleft_fringe
))
4313 it
->left_user_fringe_bitmap
= fringe_bitmap
;
4314 it
->left_user_fringe_face_id
= face_id
;
4318 it
->right_user_fringe_bitmap
= fringe_bitmap
;
4319 it
->right_user_fringe_face_id
= face_id
;
4321 #endif /* HAVE_WINDOW_SYSTEM */
4325 /* Prepare to handle `((margin left-margin) ...)',
4326 `((margin right-margin) ...)' and `((margin nil) ...)'
4327 prefixes for display specifications. */
4328 location
= Qunbound
;
4329 if (CONSP (spec
) && CONSP (XCAR (spec
)))
4333 value
= XCDR (spec
);
4335 value
= XCAR (value
);
4338 if (EQ (XCAR (tem
), Qmargin
)
4339 && (tem
= XCDR (tem
),
4340 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
4342 || EQ (tem
, Qleft_margin
)
4343 || EQ (tem
, Qright_margin
))))
4347 if (EQ (location
, Qunbound
))
4353 /* After this point, VALUE is the property after any
4354 margin prefix has been stripped. It must be a string,
4355 an image specification, or `(space ...)'.
4357 LOCATION specifies where to display: `left-margin',
4358 `right-margin' or nil. */
4360 valid_p
= (STRINGP (value
)
4361 #ifdef HAVE_WINDOW_SYSTEM
4362 || (FRAME_WINDOW_P (it
->f
) && valid_image_p (value
))
4363 #endif /* not HAVE_WINDOW_SYSTEM */
4364 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
4366 if (valid_p
&& !display_replaced_before_p
)
4368 /* Save current settings of IT so that we can restore them
4369 when we are finished with the glyph property value. */
4370 save_pos
= it
->position
;
4371 it
->position
= *position
;
4373 it
->position
= save_pos
;
4374 it
->from_overlay
= overlay
;
4376 if (NILP (location
))
4377 it
->area
= TEXT_AREA
;
4378 else if (EQ (location
, Qleft_margin
))
4379 it
->area
= LEFT_MARGIN_AREA
;
4381 it
->area
= RIGHT_MARGIN_AREA
;
4383 if (STRINGP (value
))
4386 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4387 it
->current
.overlay_string_index
= -1;
4388 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4389 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
4390 it
->method
= GET_FROM_STRING
;
4391 it
->stop_charpos
= 0;
4392 it
->string_from_display_prop_p
= 1;
4393 /* Say that we haven't consumed the characters with
4394 `display' property yet. The call to pop_it in
4395 set_iterator_to_next will clean this up. */
4396 if (BUFFERP (object
))
4397 *position
= start_pos
;
4399 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
4401 it
->method
= GET_FROM_STRETCH
;
4403 *position
= it
->position
= start_pos
;
4405 #ifdef HAVE_WINDOW_SYSTEM
4408 it
->what
= IT_IMAGE
;
4409 it
->image_id
= lookup_image (it
->f
, value
);
4410 it
->position
= start_pos
;
4411 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
4412 it
->method
= GET_FROM_IMAGE
;
4414 /* Say that we haven't consumed the characters with
4415 `display' property yet. The call to pop_it in
4416 set_iterator_to_next will clean this up. */
4417 *position
= start_pos
;
4419 #endif /* HAVE_WINDOW_SYSTEM */
4424 /* Invalid property or property not supported. Restore
4425 POSITION to what it was before. */
4426 *position
= start_pos
;
4431 /* Check if SPEC is a display sub-property value whose text should be
4432 treated as intangible. */
4435 single_display_spec_intangible_p (Lisp_Object prop
)
4437 /* Skip over `when FORM'. */
4438 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
4452 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4453 we don't need to treat text as intangible. */
4454 if (EQ (XCAR (prop
), Qmargin
))
4462 || EQ (XCAR (prop
), Qleft_margin
)
4463 || EQ (XCAR (prop
), Qright_margin
))
4467 return (CONSP (prop
)
4468 && (EQ (XCAR (prop
), Qimage
)
4469 || EQ (XCAR (prop
), Qspace
)));
4473 /* Check if PROP is a display property value whose text should be
4474 treated as intangible. */
4477 display_prop_intangible_p (Lisp_Object prop
)
4480 && CONSP (XCAR (prop
))
4481 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
4483 /* A list of sub-properties. */
4484 while (CONSP (prop
))
4486 if (single_display_spec_intangible_p (XCAR (prop
)))
4491 else if (VECTORP (prop
))
4493 /* A vector of sub-properties. */
4495 for (i
= 0; i
< ASIZE (prop
); ++i
)
4496 if (single_display_spec_intangible_p (AREF (prop
, i
)))
4500 return single_display_spec_intangible_p (prop
);
4506 /* Return 1 if PROP is a display sub-property value containing STRING. */
4509 single_display_spec_string_p (Lisp_Object prop
, Lisp_Object string
)
4511 if (EQ (string
, prop
))
4514 /* Skip over `when FORM'. */
4515 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
4524 /* Skip over `margin LOCATION'. */
4525 if (EQ (XCAR (prop
), Qmargin
))
4536 return CONSP (prop
) && EQ (XCAR (prop
), string
);
4540 /* Return 1 if STRING appears in the `display' property PROP. */
4543 display_prop_string_p (Lisp_Object prop
, Lisp_Object string
)
4546 && CONSP (XCAR (prop
))
4547 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
4549 /* A list of sub-properties. */
4550 while (CONSP (prop
))
4552 if (single_display_spec_string_p (XCAR (prop
), string
))
4557 else if (VECTORP (prop
))
4559 /* A vector of sub-properties. */
4561 for (i
= 0; i
< ASIZE (prop
); ++i
)
4562 if (single_display_spec_string_p (AREF (prop
, i
), string
))
4566 return single_display_spec_string_p (prop
, string
);
4571 /* Look for STRING in overlays and text properties in W's buffer,
4572 between character positions FROM and TO (excluding TO).
4573 BACK_P non-zero means look back (in this case, TO is supposed to be
4575 Value is the first character position where STRING was found, or
4576 zero if it wasn't found before hitting TO.
4578 W's buffer must be current.
4580 This function may only use code that doesn't eval because it is
4581 called asynchronously from note_mouse_highlight. */
4584 string_buffer_position_lim (struct window
*w
, Lisp_Object string
,
4585 EMACS_INT from
, EMACS_INT to
, int back_p
)
4587 Lisp_Object limit
, prop
, pos
;
4590 pos
= make_number (from
);
4592 if (!back_p
) /* looking forward */
4594 limit
= make_number (min (to
, ZV
));
4595 while (!found
&& !EQ (pos
, limit
))
4597 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
4598 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
4601 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
,
4605 else /* looking back */
4607 limit
= make_number (max (to
, BEGV
));
4608 while (!found
&& !EQ (pos
, limit
))
4610 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
4611 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
4614 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
4619 return found
? XINT (pos
) : 0;
4622 /* Determine which buffer position in W's buffer STRING comes from.
4623 AROUND_CHARPOS is an approximate position where it could come from.
4624 Value is the buffer position or 0 if it couldn't be determined.
4626 W's buffer must be current.
4628 This function is necessary because we don't record buffer positions
4629 in glyphs generated from strings (to keep struct glyph small).
4630 This function may only use code that doesn't eval because it is
4631 called asynchronously from note_mouse_highlight. */
4634 string_buffer_position (struct window
*w
, Lisp_Object string
, EMACS_INT around_charpos
)
4636 Lisp_Object limit
, prop
, pos
;
4637 const int MAX_DISTANCE
= 1000;
4638 EMACS_INT found
= string_buffer_position_lim (w
, string
, around_charpos
,
4639 around_charpos
+ MAX_DISTANCE
,
4643 found
= string_buffer_position_lim (w
, string
, around_charpos
,
4644 around_charpos
- MAX_DISTANCE
, 1);
4650 /***********************************************************************
4651 `composition' property
4652 ***********************************************************************/
4654 /* Set up iterator IT from `composition' property at its current
4655 position. Called from handle_stop. */
4657 static enum prop_handled
4658 handle_composition_prop (struct it
*it
)
4660 Lisp_Object prop
, string
;
4661 EMACS_INT pos
, pos_byte
, start
, end
;
4663 if (STRINGP (it
->string
))
4667 pos
= IT_STRING_CHARPOS (*it
);
4668 pos_byte
= IT_STRING_BYTEPOS (*it
);
4669 string
= it
->string
;
4670 s
= SDATA (string
) + pos_byte
;
4671 it
->c
= STRING_CHAR (s
);
4675 pos
= IT_CHARPOS (*it
);
4676 pos_byte
= IT_BYTEPOS (*it
);
4678 it
->c
= FETCH_CHAR (pos_byte
);
4681 /* If there's a valid composition and point is not inside of the
4682 composition (in the case that the composition is from the current
4683 buffer), draw a glyph composed from the composition components. */
4684 if (find_composition (pos
, -1, &start
, &end
, &prop
, string
)
4685 && COMPOSITION_VALID_P (start
, end
, prop
)
4686 && (STRINGP (it
->string
) || (PT
<= start
|| PT
>= end
)))
4690 if (STRINGP (it
->string
))
4691 pos_byte
= string_char_to_byte (it
->string
, start
);
4693 pos_byte
= CHAR_TO_BYTE (start
);
4695 it
->cmp_it
.id
= get_composition_id (start
, pos_byte
, end
- start
,
4698 if (it
->cmp_it
.id
>= 0)
4701 it
->cmp_it
.nchars
= COMPOSITION_LENGTH (prop
);
4702 it
->cmp_it
.nglyphs
= -1;
4706 return HANDLED_NORMALLY
;
4711 /***********************************************************************
4713 ***********************************************************************/
4715 /* The following structure is used to record overlay strings for
4716 later sorting in load_overlay_strings. */
4718 struct overlay_entry
4720 Lisp_Object overlay
;
4727 /* Set up iterator IT from overlay strings at its current position.
4728 Called from handle_stop. */
4730 static enum prop_handled
4731 handle_overlay_change (struct it
*it
)
4733 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
4734 return HANDLED_RECOMPUTE_PROPS
;
4736 return HANDLED_NORMALLY
;
4740 /* Set up the next overlay string for delivery by IT, if there is an
4741 overlay string to deliver. Called by set_iterator_to_next when the
4742 end of the current overlay string is reached. If there are more
4743 overlay strings to display, IT->string and
4744 IT->current.overlay_string_index are set appropriately here.
4745 Otherwise IT->string is set to nil. */
4748 next_overlay_string (struct it
*it
)
4750 ++it
->current
.overlay_string_index
;
4751 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
4753 /* No more overlay strings. Restore IT's settings to what
4754 they were before overlay strings were processed, and
4755 continue to deliver from current_buffer. */
4757 it
->ellipsis_p
= (it
->stack
[it
->sp
- 1].display_ellipsis_p
!= 0);
4760 || (NILP (it
->string
)
4761 && it
->method
== GET_FROM_BUFFER
4762 && it
->stop_charpos
>= BEGV
4763 && it
->stop_charpos
<= it
->end_charpos
));
4764 it
->current
.overlay_string_index
= -1;
4765 it
->n_overlay_strings
= 0;
4767 /* If we're at the end of the buffer, record that we have
4768 processed the overlay strings there already, so that
4769 next_element_from_buffer doesn't try it again. */
4770 if (NILP (it
->string
) && IT_CHARPOS (*it
) >= it
->end_charpos
)
4771 it
->overlay_strings_at_end_processed_p
= 1;
4775 /* There are more overlay strings to process. If
4776 IT->current.overlay_string_index has advanced to a position
4777 where we must load IT->overlay_strings with more strings, do
4779 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
4781 if (it
->current
.overlay_string_index
&& i
== 0)
4782 load_overlay_strings (it
, 0);
4784 /* Initialize IT to deliver display elements from the overlay
4786 it
->string
= it
->overlay_strings
[i
];
4787 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4788 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
4789 it
->method
= GET_FROM_STRING
;
4790 it
->stop_charpos
= 0;
4791 if (it
->cmp_it
.stop_pos
>= 0)
4792 it
->cmp_it
.stop_pos
= 0;
4799 /* Compare two overlay_entry structures E1 and E2. Used as a
4800 comparison function for qsort in load_overlay_strings. Overlay
4801 strings for the same position are sorted so that
4803 1. All after-strings come in front of before-strings, except
4804 when they come from the same overlay.
4806 2. Within after-strings, strings are sorted so that overlay strings
4807 from overlays with higher priorities come first.
4809 2. Within before-strings, strings are sorted so that overlay
4810 strings from overlays with higher priorities come last.
4812 Value is analogous to strcmp. */
4816 compare_overlay_entries (const void *e1
, const void *e2
)
4818 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4819 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4822 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4824 /* Let after-strings appear in front of before-strings if
4825 they come from different overlays. */
4826 if (EQ (entry1
->overlay
, entry2
->overlay
))
4827 result
= entry1
->after_string_p
? 1 : -1;
4829 result
= entry1
->after_string_p
? -1 : 1;
4831 else if (entry1
->after_string_p
)
4832 /* After-strings sorted in order of decreasing priority. */
4833 result
= entry2
->priority
- entry1
->priority
;
4835 /* Before-strings sorted in order of increasing priority. */
4836 result
= entry1
->priority
- entry2
->priority
;
4842 /* Load the vector IT->overlay_strings with overlay strings from IT's
4843 current buffer position, or from CHARPOS if that is > 0. Set
4844 IT->n_overlays to the total number of overlay strings found.
4846 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4847 a time. On entry into load_overlay_strings,
4848 IT->current.overlay_string_index gives the number of overlay
4849 strings that have already been loaded by previous calls to this
4852 IT->add_overlay_start contains an additional overlay start
4853 position to consider for taking overlay strings from, if non-zero.
4854 This position comes into play when the overlay has an `invisible'
4855 property, and both before and after-strings. When we've skipped to
4856 the end of the overlay, because of its `invisible' property, we
4857 nevertheless want its before-string to appear.
4858 IT->add_overlay_start will contain the overlay start position
4861 Overlay strings are sorted so that after-string strings come in
4862 front of before-string strings. Within before and after-strings,
4863 strings are sorted by overlay priority. See also function
4864 compare_overlay_entries. */
4867 load_overlay_strings (struct it
*it
, int charpos
)
4869 Lisp_Object overlay
, window
, str
, invisible
;
4870 struct Lisp_Overlay
*ov
;
4873 int n
= 0, i
, j
, invis_p
;
4874 struct overlay_entry
*entries
4875 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4878 charpos
= IT_CHARPOS (*it
);
4880 /* Append the overlay string STRING of overlay OVERLAY to vector
4881 `entries' which has size `size' and currently contains `n'
4882 elements. AFTER_P non-zero means STRING is an after-string of
4884 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4887 Lisp_Object priority; \
4891 int new_size = 2 * size; \
4892 struct overlay_entry *old = entries; \
4894 (struct overlay_entry *) alloca (new_size \
4895 * sizeof *entries); \
4896 memcpy (entries, old, size * sizeof *entries); \
4900 entries[n].string = (STRING); \
4901 entries[n].overlay = (OVERLAY); \
4902 priority = Foverlay_get ((OVERLAY), Qpriority); \
4903 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4904 entries[n].after_string_p = (AFTER_P); \
4909 /* Process overlay before the overlay center. */
4910 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4912 XSETMISC (overlay
, ov
);
4913 xassert (OVERLAYP (overlay
));
4914 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4915 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4920 /* Skip this overlay if it doesn't start or end at IT's current
4922 if (end
!= charpos
&& start
!= charpos
)
4925 /* Skip this overlay if it doesn't apply to IT->w. */
4926 window
= Foverlay_get (overlay
, Qwindow
);
4927 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4930 /* If the text ``under'' the overlay is invisible, both before-
4931 and after-strings from this overlay are visible; start and
4932 end position are indistinguishable. */
4933 invisible
= Foverlay_get (overlay
, Qinvisible
);
4934 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4936 /* If overlay has a non-empty before-string, record it. */
4937 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4938 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4940 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4942 /* If overlay has a non-empty after-string, record it. */
4943 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4944 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4946 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4949 /* Process overlays after the overlay center. */
4950 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4952 XSETMISC (overlay
, ov
);
4953 xassert (OVERLAYP (overlay
));
4954 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4955 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4957 if (start
> charpos
)
4960 /* Skip this overlay if it doesn't start or end at IT's current
4962 if (end
!= charpos
&& start
!= charpos
)
4965 /* Skip this overlay if it doesn't apply to IT->w. */
4966 window
= Foverlay_get (overlay
, Qwindow
);
4967 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4970 /* If the text ``under'' the overlay is invisible, it has a zero
4971 dimension, and both before- and after-strings apply. */
4972 invisible
= Foverlay_get (overlay
, Qinvisible
);
4973 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4975 /* If overlay has a non-empty before-string, record it. */
4976 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4977 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4979 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4981 /* If overlay has a non-empty after-string, record it. */
4982 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4983 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4985 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4988 #undef RECORD_OVERLAY_STRING
4992 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
4994 /* Record the total number of strings to process. */
4995 it
->n_overlay_strings
= n
;
4997 /* IT->current.overlay_string_index is the number of overlay strings
4998 that have already been consumed by IT. Copy some of the
4999 remaining overlay strings to IT->overlay_strings. */
5001 j
= it
->current
.overlay_string_index
;
5002 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
5004 it
->overlay_strings
[i
] = entries
[j
].string
;
5005 it
->string_overlays
[i
++] = entries
[j
++].overlay
;
5012 /* Get the first chunk of overlay strings at IT's current buffer
5013 position, or at CHARPOS if that is > 0. Value is non-zero if at
5014 least one overlay string was found. */
5017 get_overlay_strings_1 (struct it
*it
, int charpos
, int compute_stop_p
)
5019 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5020 process. This fills IT->overlay_strings with strings, and sets
5021 IT->n_overlay_strings to the total number of strings to process.
5022 IT->pos.overlay_string_index has to be set temporarily to zero
5023 because load_overlay_strings needs this; it must be set to -1
5024 when no overlay strings are found because a zero value would
5025 indicate a position in the first overlay string. */
5026 it
->current
.overlay_string_index
= 0;
5027 load_overlay_strings (it
, charpos
);
5029 /* If we found overlay strings, set up IT to deliver display
5030 elements from the first one. Otherwise set up IT to deliver
5031 from current_buffer. */
5032 if (it
->n_overlay_strings
)
5034 /* Make sure we know settings in current_buffer, so that we can
5035 restore meaningful values when we're done with the overlay
5038 compute_stop_pos (it
);
5039 xassert (it
->face_id
>= 0);
5041 /* Save IT's settings. They are restored after all overlay
5042 strings have been processed. */
5043 xassert (!compute_stop_p
|| it
->sp
== 0);
5045 /* When called from handle_stop, there might be an empty display
5046 string loaded. In that case, don't bother saving it. */
5047 if (!STRINGP (it
->string
) || SCHARS (it
->string
))
5050 /* Set up IT to deliver display elements from the first overlay
5052 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5053 it
->string
= it
->overlay_strings
[0];
5054 it
->from_overlay
= Qnil
;
5055 it
->stop_charpos
= 0;
5056 xassert (STRINGP (it
->string
));
5057 it
->end_charpos
= SCHARS (it
->string
);
5058 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5059 it
->method
= GET_FROM_STRING
;
5063 it
->current
.overlay_string_index
= -1;
5068 get_overlay_strings (struct it
*it
, int charpos
)
5071 it
->method
= GET_FROM_BUFFER
;
5073 (void) get_overlay_strings_1 (it
, charpos
, 1);
5077 /* Value is non-zero if we found at least one overlay string. */
5078 return STRINGP (it
->string
);
5083 /***********************************************************************
5084 Saving and restoring state
5085 ***********************************************************************/
5087 /* Save current settings of IT on IT->stack. Called, for example,
5088 before setting up IT for an overlay string, to be able to restore
5089 IT's settings to what they were after the overlay string has been
5093 push_it (struct it
*it
)
5095 struct iterator_stack_entry
*p
;
5097 xassert (it
->sp
< IT_STACK_SIZE
);
5098 p
= it
->stack
+ it
->sp
;
5100 p
->stop_charpos
= it
->stop_charpos
;
5101 p
->prev_stop
= it
->prev_stop
;
5102 p
->base_level_stop
= it
->base_level_stop
;
5103 p
->cmp_it
= it
->cmp_it
;
5104 xassert (it
->face_id
>= 0);
5105 p
->face_id
= it
->face_id
;
5106 p
->string
= it
->string
;
5107 p
->method
= it
->method
;
5108 p
->from_overlay
= it
->from_overlay
;
5111 case GET_FROM_IMAGE
:
5112 p
->u
.image
.object
= it
->object
;
5113 p
->u
.image
.image_id
= it
->image_id
;
5114 p
->u
.image
.slice
= it
->slice
;
5116 case GET_FROM_STRETCH
:
5117 p
->u
.stretch
.object
= it
->object
;
5120 p
->position
= it
->position
;
5121 p
->current
= it
->current
;
5122 p
->end_charpos
= it
->end_charpos
;
5123 p
->string_nchars
= it
->string_nchars
;
5125 p
->multibyte_p
= it
->multibyte_p
;
5126 p
->avoid_cursor_p
= it
->avoid_cursor_p
;
5127 p
->space_width
= it
->space_width
;
5128 p
->font_height
= it
->font_height
;
5129 p
->voffset
= it
->voffset
;
5130 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
5131 p
->display_ellipsis_p
= 0;
5132 p
->line_wrap
= it
->line_wrap
;
5137 iterate_out_of_display_property (struct it
*it
)
5139 /* Maybe initialize paragraph direction. If we are at the beginning
5140 of a new paragraph, next_element_from_buffer may not have a
5141 chance to do that. */
5142 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< ZV
)
5143 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
5144 /* prev_stop can be zero, so check against BEGV as well. */
5145 while (it
->bidi_it
.charpos
>= BEGV
5146 && it
->prev_stop
<= it
->bidi_it
.charpos
5147 && it
->bidi_it
.charpos
< CHARPOS (it
->position
))
5148 bidi_move_to_visually_next (&it
->bidi_it
);
5149 /* Record the stop_pos we just crossed, for when we cross it
5151 if (it
->bidi_it
.charpos
> CHARPOS (it
->position
))
5152 it
->prev_stop
= CHARPOS (it
->position
);
5153 /* If we ended up not where pop_it put us, resync IT's
5154 positional members with the bidi iterator. */
5155 if (it
->bidi_it
.charpos
!= CHARPOS (it
->position
))
5157 SET_TEXT_POS (it
->position
,
5158 it
->bidi_it
.charpos
, it
->bidi_it
.bytepos
);
5159 it
->current
.pos
= it
->position
;
5163 /* Restore IT's settings from IT->stack. Called, for example, when no
5164 more overlay strings must be processed, and we return to delivering
5165 display elements from a buffer, or when the end of a string from a
5166 `display' property is reached and we return to delivering display
5167 elements from an overlay string, or from a buffer. */
5170 pop_it (struct it
*it
)
5172 struct iterator_stack_entry
*p
;
5174 xassert (it
->sp
> 0);
5176 p
= it
->stack
+ it
->sp
;
5177 it
->stop_charpos
= p
->stop_charpos
;
5178 it
->prev_stop
= p
->prev_stop
;
5179 it
->base_level_stop
= p
->base_level_stop
;
5180 it
->cmp_it
= p
->cmp_it
;
5181 it
->face_id
= p
->face_id
;
5182 it
->current
= p
->current
;
5183 it
->position
= p
->position
;
5184 it
->string
= p
->string
;
5185 it
->from_overlay
= p
->from_overlay
;
5186 if (NILP (it
->string
))
5187 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
5188 it
->method
= p
->method
;
5191 case GET_FROM_IMAGE
:
5192 it
->image_id
= p
->u
.image
.image_id
;
5193 it
->object
= p
->u
.image
.object
;
5194 it
->slice
= p
->u
.image
.slice
;
5196 case GET_FROM_STRETCH
:
5197 it
->object
= p
->u
.comp
.object
;
5199 case GET_FROM_BUFFER
:
5200 it
->object
= it
->w
->buffer
;
5203 /* Bidi-iterate until we get out of the portion of text, if
5204 any, covered by a `display' text property or an overlay
5205 with `display' property. (We cannot just jump there,
5206 because the internal coherency of the bidi iterator state
5207 can not be preserved across such jumps.) We also must
5208 determine the paragraph base direction if the overlay we
5209 just processed is at the beginning of a new
5211 iterate_out_of_display_property (it
);
5214 case GET_FROM_STRING
:
5215 it
->object
= it
->string
;
5217 case GET_FROM_DISPLAY_VECTOR
:
5219 it
->method
= GET_FROM_C_STRING
;
5220 else if (STRINGP (it
->string
))
5221 it
->method
= GET_FROM_STRING
;
5224 it
->method
= GET_FROM_BUFFER
;
5225 it
->object
= it
->w
->buffer
;
5228 it
->end_charpos
= p
->end_charpos
;
5229 it
->string_nchars
= p
->string_nchars
;
5231 it
->multibyte_p
= p
->multibyte_p
;
5232 it
->avoid_cursor_p
= p
->avoid_cursor_p
;
5233 it
->space_width
= p
->space_width
;
5234 it
->font_height
= p
->font_height
;
5235 it
->voffset
= p
->voffset
;
5236 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
5237 it
->line_wrap
= p
->line_wrap
;
5242 /***********************************************************************
5244 ***********************************************************************/
5246 /* Set IT's current position to the previous line start. */
5249 back_to_previous_line_start (struct it
*it
)
5251 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
5252 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
5256 /* Move IT to the next line start.
5258 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5259 we skipped over part of the text (as opposed to moving the iterator
5260 continuously over the text). Otherwise, don't change the value
5263 Newlines may come from buffer text, overlay strings, or strings
5264 displayed via the `display' property. That's the reason we can't
5265 simply use find_next_newline_no_quit.
5267 Note that this function may not skip over invisible text that is so
5268 because of text properties and immediately follows a newline. If
5269 it would, function reseat_at_next_visible_line_start, when called
5270 from set_iterator_to_next, would effectively make invisible
5271 characters following a newline part of the wrong glyph row, which
5272 leads to wrong cursor motion. */
5275 forward_to_next_line_start (struct it
*it
, int *skipped_p
)
5277 int old_selective
, newline_found_p
, n
;
5278 const int MAX_NEWLINE_DISTANCE
= 500;
5280 /* If already on a newline, just consume it to avoid unintended
5281 skipping over invisible text below. */
5282 if (it
->what
== IT_CHARACTER
5284 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
5286 set_iterator_to_next (it
, 0);
5291 /* Don't handle selective display in the following. It's (a)
5292 unnecessary because it's done by the caller, and (b) leads to an
5293 infinite recursion because next_element_from_ellipsis indirectly
5294 calls this function. */
5295 old_selective
= it
->selective
;
5298 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5299 from buffer text. */
5300 for (n
= newline_found_p
= 0;
5301 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
5302 n
+= STRINGP (it
->string
) ? 0 : 1)
5304 if (!get_next_display_element (it
))
5306 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
5307 set_iterator_to_next (it
, 0);
5310 /* If we didn't find a newline near enough, see if we can use a
5312 if (!newline_found_p
)
5314 int start
= IT_CHARPOS (*it
);
5315 int limit
= find_next_newline_no_quit (start
, 1);
5318 xassert (!STRINGP (it
->string
));
5320 /* If there isn't any `display' property in sight, and no
5321 overlays, we can just use the position of the newline in
5323 if (it
->stop_charpos
>= limit
5324 || ((pos
= Fnext_single_property_change (make_number (start
),
5326 Qnil
, make_number (limit
)),
5328 && next_overlay_change (start
) == ZV
))
5330 IT_CHARPOS (*it
) = limit
;
5331 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
5332 *skipped_p
= newline_found_p
= 1;
5336 while (get_next_display_element (it
)
5337 && !newline_found_p
)
5339 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
5340 set_iterator_to_next (it
, 0);
5345 it
->selective
= old_selective
;
5346 return newline_found_p
;
5350 /* Set IT's current position to the previous visible line start. Skip
5351 invisible text that is so either due to text properties or due to
5352 selective display. Caution: this does not change IT->current_x and
5356 back_to_previous_visible_line_start (struct it
*it
)
5358 while (IT_CHARPOS (*it
) > BEGV
)
5360 back_to_previous_line_start (it
);
5362 if (IT_CHARPOS (*it
) <= BEGV
)
5365 /* If selective > 0, then lines indented more than its value are
5367 if (it
->selective
> 0
5368 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
5369 (double) it
->selective
)) /* iftc */
5372 /* Check the newline before point for invisibility. */
5375 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
) - 1),
5376 Qinvisible
, it
->window
);
5377 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
5381 if (IT_CHARPOS (*it
) <= BEGV
)
5388 Lisp_Object val
, overlay
;
5390 /* If newline is part of a composition, continue from start of composition */
5391 if (find_composition (IT_CHARPOS (*it
), -1, &beg
, &end
, &val
, Qnil
)
5392 && beg
< IT_CHARPOS (*it
))
5395 /* If newline is replaced by a display property, find start of overlay
5396 or interval and continue search from that point. */
5398 pos
= --IT_CHARPOS (it2
);
5401 it2
.string_from_display_prop_p
= 0;
5402 if (handle_display_prop (&it2
) == HANDLED_RETURN
5403 && !NILP (val
= get_char_property_and_overlay
5404 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
5405 && (OVERLAYP (overlay
)
5406 ? (beg
= OVERLAY_POSITION (OVERLAY_START (overlay
)))
5407 : get_property_and_range (pos
, Qdisplay
, &val
, &beg
, &end
, Qnil
)))
5410 /* Newline is not replaced by anything -- so we are done. */
5416 IT_CHARPOS (*it
) = beg
;
5417 IT_BYTEPOS (*it
) = buf_charpos_to_bytepos (current_buffer
, beg
);
5421 it
->continuation_lines_width
= 0;
5423 xassert (IT_CHARPOS (*it
) >= BEGV
);
5424 xassert (IT_CHARPOS (*it
) == BEGV
5425 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
5430 /* Reseat iterator IT at the previous visible line start. Skip
5431 invisible text that is so either due to text properties or due to
5432 selective display. At the end, update IT's overlay information,
5433 face information etc. */
5436 reseat_at_previous_visible_line_start (struct it
*it
)
5438 back_to_previous_visible_line_start (it
);
5439 reseat (it
, it
->current
.pos
, 1);
5444 /* Reseat iterator IT on the next visible line start in the current
5445 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5446 preceding the line start. Skip over invisible text that is so
5447 because of selective display. Compute faces, overlays etc at the
5448 new position. Note that this function does not skip over text that
5449 is invisible because of text properties. */
5452 reseat_at_next_visible_line_start (struct it
*it
, int on_newline_p
)
5454 int newline_found_p
, skipped_p
= 0;
5456 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
5458 /* Skip over lines that are invisible because they are indented
5459 more than the value of IT->selective. */
5460 if (it
->selective
> 0)
5461 while (IT_CHARPOS (*it
) < ZV
5462 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
5463 (double) it
->selective
)) /* iftc */
5465 xassert (IT_BYTEPOS (*it
) == BEGV
5466 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
5467 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
5470 /* Position on the newline if that's what's requested. */
5471 if (on_newline_p
&& newline_found_p
)
5473 if (STRINGP (it
->string
))
5475 if (IT_STRING_CHARPOS (*it
) > 0)
5477 --IT_STRING_CHARPOS (*it
);
5478 --IT_STRING_BYTEPOS (*it
);
5481 else if (IT_CHARPOS (*it
) > BEGV
)
5485 reseat (it
, it
->current
.pos
, 0);
5489 reseat (it
, it
->current
.pos
, 0);
5496 /***********************************************************************
5497 Changing an iterator's position
5498 ***********************************************************************/
5500 /* Change IT's current position to POS in current_buffer. If FORCE_P
5501 is non-zero, always check for text properties at the new position.
5502 Otherwise, text properties are only looked up if POS >=
5503 IT->check_charpos of a property. */
5506 reseat (struct it
*it
, struct text_pos pos
, int force_p
)
5508 int original_pos
= IT_CHARPOS (*it
);
5510 reseat_1 (it
, pos
, 0);
5512 /* Determine where to check text properties. Avoid doing it
5513 where possible because text property lookup is very expensive. */
5515 || CHARPOS (pos
) > it
->stop_charpos
5516 || CHARPOS (pos
) < original_pos
)
5520 /* For bidi iteration, we need to prime prev_stop and
5521 base_level_stop with our best estimations. */
5522 if (CHARPOS (pos
) < it
->prev_stop
)
5524 handle_stop_backwards (it
, BEGV
);
5525 if (CHARPOS (pos
) < it
->base_level_stop
)
5526 it
->base_level_stop
= 0;
5528 else if (CHARPOS (pos
) > it
->stop_charpos
5529 && it
->stop_charpos
>= BEGV
)
5530 handle_stop_backwards (it
, it
->stop_charpos
);
5537 it
->prev_stop
= it
->base_level_stop
= 0;
5546 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5547 IT->stop_pos to POS, also. */
5550 reseat_1 (struct it
*it
, struct text_pos pos
, int set_stop_p
)
5552 /* Don't call this function when scanning a C string. */
5553 xassert (it
->s
== NULL
);
5555 /* POS must be a reasonable value. */
5556 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
5558 it
->current
.pos
= it
->position
= pos
;
5559 it
->end_charpos
= ZV
;
5561 it
->current
.dpvec_index
= -1;
5562 it
->current
.overlay_string_index
= -1;
5563 IT_STRING_CHARPOS (*it
) = -1;
5564 IT_STRING_BYTEPOS (*it
) = -1;
5566 it
->string_from_display_prop_p
= 0;
5567 it
->method
= GET_FROM_BUFFER
;
5568 it
->object
= it
->w
->buffer
;
5569 it
->area
= TEXT_AREA
;
5570 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
5572 it
->string_from_display_prop_p
= 0;
5573 it
->face_before_selective_p
= 0;
5575 it
->bidi_it
.first_elt
= 1;
5579 it
->stop_charpos
= CHARPOS (pos
);
5580 it
->base_level_stop
= CHARPOS (pos
);
5585 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5586 If S is non-null, it is a C string to iterate over. Otherwise,
5587 STRING gives a Lisp string to iterate over.
5589 If PRECISION > 0, don't return more then PRECISION number of
5590 characters from the string.
5592 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5593 characters have been returned. FIELD_WIDTH < 0 means an infinite
5596 MULTIBYTE = 0 means disable processing of multibyte characters,
5597 MULTIBYTE > 0 means enable it,
5598 MULTIBYTE < 0 means use IT->multibyte_p.
5600 IT must be initialized via a prior call to init_iterator before
5601 calling this function. */
5604 reseat_to_string (struct it
*it
, const unsigned char *s
, Lisp_Object string
,
5605 int charpos
, int precision
, int field_width
, int multibyte
)
5607 /* No region in strings. */
5608 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
5610 /* No text property checks performed by default, but see below. */
5611 it
->stop_charpos
= -1;
5613 /* Set iterator position and end position. */
5614 memset (&it
->current
, 0, sizeof it
->current
);
5615 it
->current
.overlay_string_index
= -1;
5616 it
->current
.dpvec_index
= -1;
5617 xassert (charpos
>= 0);
5619 /* If STRING is specified, use its multibyteness, otherwise use the
5620 setting of MULTIBYTE, if specified. */
5622 it
->multibyte_p
= multibyte
> 0;
5626 xassert (STRINGP (string
));
5627 it
->string
= string
;
5629 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
5630 it
->method
= GET_FROM_STRING
;
5631 it
->current
.string_pos
= string_pos (charpos
, string
);
5638 /* Note that we use IT->current.pos, not it->current.string_pos,
5639 for displaying C strings. */
5640 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
5641 if (it
->multibyte_p
)
5643 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
5644 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
5648 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
5649 it
->end_charpos
= it
->string_nchars
= strlen (s
);
5652 it
->method
= GET_FROM_C_STRING
;
5655 /* PRECISION > 0 means don't return more than PRECISION characters
5657 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
5658 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
5660 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5661 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5662 FIELD_WIDTH < 0 means infinite field width. This is useful for
5663 padding with `-' at the end of a mode line. */
5664 if (field_width
< 0)
5665 field_width
= INFINITY
;
5666 if (field_width
> it
->end_charpos
- charpos
)
5667 it
->end_charpos
= charpos
+ field_width
;
5669 /* Use the standard display table for displaying strings. */
5670 if (DISP_TABLE_P (Vstandard_display_table
))
5671 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
5673 it
->stop_charpos
= charpos
;
5674 if (s
== NULL
&& it
->multibyte_p
)
5676 EMACS_INT endpos
= SCHARS (it
->string
);
5677 if (endpos
> it
->end_charpos
)
5678 endpos
= it
->end_charpos
;
5679 composition_compute_stop_pos (&it
->cmp_it
, charpos
, -1, endpos
,
5687 /***********************************************************************
5689 ***********************************************************************/
5691 /* Map enum it_method value to corresponding next_element_from_* function. */
5693 static int (* get_next_element
[NUM_IT_METHODS
]) (struct it
*it
) =
5695 next_element_from_buffer
,
5696 next_element_from_display_vector
,
5697 next_element_from_string
,
5698 next_element_from_c_string
,
5699 next_element_from_image
,
5700 next_element_from_stretch
5703 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5706 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5707 (possibly with the following characters). */
5709 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5710 ((IT)->cmp_it.id >= 0 \
5711 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5712 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5713 END_CHARPOS, (IT)->w, \
5714 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5718 /* Load IT's display element fields with information about the next
5719 display element from the current position of IT. Value is zero if
5720 end of buffer (or C string) is reached. */
5722 static struct frame
*last_escape_glyph_frame
= NULL
;
5723 static unsigned last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
5724 static int last_escape_glyph_merged_face_id
= 0;
5727 get_next_display_element (struct it
*it
)
5729 /* Non-zero means that we found a display element. Zero means that
5730 we hit the end of what we iterate over. Performance note: the
5731 function pointer `method' used here turns out to be faster than
5732 using a sequence of if-statements. */
5736 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
5738 if (it
->what
== IT_CHARACTER
)
5740 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5741 and only if (a) the resolved directionality of that character
5743 /* FIXME: Do we need an exception for characters from display
5745 if (it
->bidi_p
&& it
->bidi_it
.type
== STRONG_R
)
5746 it
->c
= bidi_mirror_char (it
->c
);
5747 /* Map via display table or translate control characters.
5748 IT->c, IT->len etc. have been set to the next character by
5749 the function call above. If we have a display table, and it
5750 contains an entry for IT->c, translate it. Don't do this if
5751 IT->c itself comes from a display table, otherwise we could
5752 end up in an infinite recursion. (An alternative could be to
5753 count the recursion depth of this function and signal an
5754 error when a certain maximum depth is reached.) Is it worth
5756 if (success_p
&& it
->dpvec
== NULL
)
5759 struct charset
*unibyte
= CHARSET_FROM_ID (charset_unibyte
);
5760 enum { char_is_other
= 0, char_is_nbsp
, char_is_soft_hyphen
}
5761 nbsp_or_shy
= char_is_other
;
5762 int decoded
= it
->c
;
5765 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
5768 struct Lisp_Vector
*v
= XVECTOR (dv
);
5770 /* Return the first character from the display table
5771 entry, if not empty. If empty, don't display the
5772 current character. */
5775 it
->dpvec_char_len
= it
->len
;
5776 it
->dpvec
= v
->contents
;
5777 it
->dpend
= v
->contents
+ v
->size
;
5778 it
->current
.dpvec_index
= 0;
5779 it
->dpvec_face_id
= -1;
5780 it
->saved_face_id
= it
->face_id
;
5781 it
->method
= GET_FROM_DISPLAY_VECTOR
;
5786 set_iterator_to_next (it
, 0);
5791 if (unibyte_display_via_language_environment
5792 && !ASCII_CHAR_P (it
->c
))
5793 decoded
= DECODE_CHAR (unibyte
, it
->c
);
5795 if (it
->c
>= 0x80 && ! NILP (Vnobreak_char_display
))
5797 if (it
->multibyte_p
)
5798 nbsp_or_shy
= (it
->c
== 0xA0 ? char_is_nbsp
5799 : it
->c
== 0xAD ? char_is_soft_hyphen
5801 else if (unibyte_display_via_language_environment
)
5802 nbsp_or_shy
= (decoded
== 0xA0 ? char_is_nbsp
5803 : decoded
== 0xAD ? char_is_soft_hyphen
5807 /* Translate control characters into `\003' or `^C' form.
5808 Control characters coming from a display table entry are
5809 currently not translated because we use IT->dpvec to hold
5810 the translation. This could easily be changed but I
5811 don't believe that it is worth doing.
5813 If it->multibyte_p is nonzero, non-printable non-ASCII
5814 characters are also translated to octal form.
5816 If it->multibyte_p is zero, eight-bit characters that
5817 don't have corresponding multibyte char code are also
5818 translated to octal form. */
5820 ? (it
->area
!= TEXT_AREA
5821 /* In mode line, treat \n, \t like other crl chars. */
5824 && (it
->glyph_row
->mode_line_p
|| it
->avoid_cursor_p
))
5825 || (it
->c
!= '\n' && it
->c
!= '\t'))
5828 ? ! CHAR_PRINTABLE_P (it
->c
)
5829 : (! unibyte_display_via_language_environment
5831 : (decoded
>= 0x80 && decoded
< 0xA0))))))
5833 /* IT->c is a control character which must be displayed
5834 either as '\003' or as `^C' where the '\\' and '^'
5835 can be defined in the display table. Fill
5836 IT->ctl_chars with glyphs for what we have to
5837 display. Then, set IT->dpvec to these glyphs. */
5840 int face_id
, lface_id
= 0 ;
5843 /* Handle control characters with ^. */
5845 if (it
->c
< 128 && it
->ctl_arrow_p
)
5849 g
= '^'; /* default glyph for Control */
5850 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5852 && (gc
= DISP_CTRL_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
5853 && GLYPH_CODE_CHAR_VALID_P (gc
))
5855 g
= GLYPH_CODE_CHAR (gc
);
5856 lface_id
= GLYPH_CODE_FACE (gc
);
5860 face_id
= merge_faces (it
->f
, Qt
, lface_id
, it
->face_id
);
5862 else if (it
->f
== last_escape_glyph_frame
5863 && it
->face_id
== last_escape_glyph_face_id
)
5865 face_id
= last_escape_glyph_merged_face_id
;
5869 /* Merge the escape-glyph face into the current face. */
5870 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
5872 last_escape_glyph_frame
= it
->f
;
5873 last_escape_glyph_face_id
= it
->face_id
;
5874 last_escape_glyph_merged_face_id
= face_id
;
5877 XSETINT (it
->ctl_chars
[0], g
);
5878 XSETINT (it
->ctl_chars
[1], it
->c
^ 0100);
5880 goto display_control
;
5883 /* Handle non-break space in the mode where it only gets
5886 if (EQ (Vnobreak_char_display
, Qt
)
5887 && nbsp_or_shy
== char_is_nbsp
)
5889 /* Merge the no-break-space face into the current face. */
5890 face_id
= merge_faces (it
->f
, Qnobreak_space
, 0,
5894 XSETINT (it
->ctl_chars
[0], ' ');
5896 goto display_control
;
5899 /* Handle sequences that start with the "escape glyph". */
5901 /* the default escape glyph is \. */
5902 escape_glyph
= '\\';
5905 && (gc
= DISP_ESCAPE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
5906 && GLYPH_CODE_CHAR_VALID_P (gc
))
5908 escape_glyph
= GLYPH_CODE_CHAR (gc
);
5909 lface_id
= GLYPH_CODE_FACE (gc
);
5913 /* The display table specified a face.
5914 Merge it into face_id and also into escape_glyph. */
5915 face_id
= merge_faces (it
->f
, Qt
, lface_id
,
5918 else if (it
->f
== last_escape_glyph_frame
5919 && it
->face_id
== last_escape_glyph_face_id
)
5921 face_id
= last_escape_glyph_merged_face_id
;
5925 /* Merge the escape-glyph face into the current face. */
5926 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
5928 last_escape_glyph_frame
= it
->f
;
5929 last_escape_glyph_face_id
= it
->face_id
;
5930 last_escape_glyph_merged_face_id
= face_id
;
5933 /* Handle soft hyphens in the mode where they only get
5936 if (EQ (Vnobreak_char_display
, Qt
)
5937 && nbsp_or_shy
== char_is_soft_hyphen
)
5940 XSETINT (it
->ctl_chars
[0], '-');
5942 goto display_control
;
5945 /* Handle non-break space and soft hyphen
5946 with the escape glyph. */
5950 XSETINT (it
->ctl_chars
[0], escape_glyph
);
5951 it
->c
= (nbsp_or_shy
== char_is_nbsp
? ' ' : '-');
5952 XSETINT (it
->ctl_chars
[1], it
->c
);
5954 goto display_control
;
5958 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
5962 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5963 if (CHAR_BYTE8_P (it
->c
))
5965 str
[0] = CHAR_TO_BYTE8 (it
->c
);
5968 else if (it
->c
< 256)
5975 /* It's an invalid character, which shouldn't
5976 happen actually, but due to bugs it may
5977 happen. Let's print the char as is, there's
5978 not much meaningful we can do with it. */
5980 str
[1] = it
->c
>> 8;
5981 str
[2] = it
->c
>> 16;
5982 str
[3] = it
->c
>> 24;
5986 for (i
= 0; i
< len
; i
++)
5989 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
5990 /* Insert three more glyphs into IT->ctl_chars for
5991 the octal display of the character. */
5992 g
= ((str
[i
] >> 6) & 7) + '0';
5993 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
5994 g
= ((str
[i
] >> 3) & 7) + '0';
5995 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
5996 g
= (str
[i
] & 7) + '0';
5997 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
6003 /* Set up IT->dpvec and return first character from it. */
6004 it
->dpvec_char_len
= it
->len
;
6005 it
->dpvec
= it
->ctl_chars
;
6006 it
->dpend
= it
->dpvec
+ ctl_len
;
6007 it
->current
.dpvec_index
= 0;
6008 it
->dpvec_face_id
= face_id
;
6009 it
->saved_face_id
= it
->face_id
;
6010 it
->method
= GET_FROM_DISPLAY_VECTOR
;
6017 #ifdef HAVE_WINDOW_SYSTEM
6018 /* Adjust face id for a multibyte character. There are no multibyte
6019 character in unibyte text. */
6020 if ((it
->what
== IT_CHARACTER
|| it
->what
== IT_COMPOSITION
)
6023 && FRAME_WINDOW_P (it
->f
))
6025 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
6027 if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
>= 0)
6029 /* Automatic composition with glyph-string. */
6030 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
6032 it
->face_id
= face_for_font (it
->f
, LGSTRING_FONT (gstring
), face
);
6036 int pos
= (it
->s
? -1
6037 : STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
6038 : IT_CHARPOS (*it
));
6040 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
, pos
, it
->string
);
6045 /* Is this character the last one of a run of characters with
6046 box? If yes, set IT->end_of_box_run_p to 1. */
6050 if (it
->method
== GET_FROM_STRING
&& it
->sp
)
6052 int face_id
= underlying_face_id (it
);
6053 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
6057 if (face
->box
== FACE_NO_BOX
)
6059 /* If the box comes from face properties in a
6060 display string, check faces in that string. */
6061 int string_face_id
= face_after_it_pos (it
);
6062 it
->end_of_box_run_p
6063 = (FACE_FROM_ID (it
->f
, string_face_id
)->box
6066 /* Otherwise, the box comes from the underlying face.
6067 If this is the last string character displayed, check
6068 the next buffer location. */
6069 else if ((IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
) - 1)
6070 && (it
->current
.overlay_string_index
6071 == it
->n_overlay_strings
- 1))
6075 struct text_pos pos
= it
->current
.pos
;
6076 INC_TEXT_POS (pos
, it
->multibyte_p
);
6078 next_face_id
= face_at_buffer_position
6079 (it
->w
, CHARPOS (pos
), it
->region_beg_charpos
,
6080 it
->region_end_charpos
, &ignore
,
6081 (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
), 0,
6083 it
->end_of_box_run_p
6084 = (FACE_FROM_ID (it
->f
, next_face_id
)->box
6091 int face_id
= face_after_it_pos (it
);
6092 it
->end_of_box_run_p
6093 = (face_id
!= it
->face_id
6094 && FACE_FROM_ID (it
->f
, face_id
)->box
== FACE_NO_BOX
);
6098 /* Value is 0 if end of buffer or string reached. */
6103 /* Move IT to the next display element.
6105 RESEAT_P non-zero means if called on a newline in buffer text,
6106 skip to the next visible line start.
6108 Functions get_next_display_element and set_iterator_to_next are
6109 separate because I find this arrangement easier to handle than a
6110 get_next_display_element function that also increments IT's
6111 position. The way it is we can first look at an iterator's current
6112 display element, decide whether it fits on a line, and if it does,
6113 increment the iterator position. The other way around we probably
6114 would either need a flag indicating whether the iterator has to be
6115 incremented the next time, or we would have to implement a
6116 decrement position function which would not be easy to write. */
6119 set_iterator_to_next (struct it
*it
, int reseat_p
)
6121 /* Reset flags indicating start and end of a sequence of characters
6122 with box. Reset them at the start of this function because
6123 moving the iterator to a new position might set them. */
6124 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
6128 case GET_FROM_BUFFER
:
6129 /* The current display element of IT is a character from
6130 current_buffer. Advance in the buffer, and maybe skip over
6131 invisible lines that are so because of selective display. */
6132 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
6133 reseat_at_next_visible_line_start (it
, 0);
6134 else if (it
->cmp_it
.id
>= 0)
6136 /* We are currently getting glyphs from a composition. */
6141 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
6142 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
6143 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
6145 it
->cmp_it
.from
= it
->cmp_it
.to
;
6150 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6152 it
->stop_charpos
, Qnil
);
6155 else if (! it
->cmp_it
.reversed_p
)
6157 /* Composition created while scanning forward. */
6158 /* Update IT's char/byte positions to point to the first
6159 character of the next grapheme cluster, or to the
6160 character visually after the current composition. */
6161 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
6162 bidi_move_to_visually_next (&it
->bidi_it
);
6163 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6164 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6166 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
6168 /* Proceed to the next grapheme cluster. */
6169 it
->cmp_it
.from
= it
->cmp_it
.to
;
6173 /* No more grapheme clusters in this composition.
6174 Find the next stop position. */
6175 EMACS_INT stop
= it
->stop_charpos
;
6176 if (it
->bidi_it
.scan_dir
< 0)
6177 /* Now we are scanning backward and don't know
6180 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6181 IT_BYTEPOS (*it
), stop
, Qnil
);
6186 /* Composition created while scanning backward. */
6187 /* Update IT's char/byte positions to point to the last
6188 character of the previous grapheme cluster, or the
6189 character visually after the current composition. */
6190 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
6191 bidi_move_to_visually_next (&it
->bidi_it
);
6192 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6193 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6194 if (it
->cmp_it
.from
> 0)
6196 /* Proceed to the previous grapheme cluster. */
6197 it
->cmp_it
.to
= it
->cmp_it
.from
;
6201 /* No more grapheme clusters in this composition.
6202 Find the next stop position. */
6203 EMACS_INT stop
= it
->stop_charpos
;
6204 if (it
->bidi_it
.scan_dir
< 0)
6205 /* Now we are scanning backward and don't know
6208 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6209 IT_BYTEPOS (*it
), stop
, Qnil
);
6215 xassert (it
->len
!= 0);
6219 IT_BYTEPOS (*it
) += it
->len
;
6220 IT_CHARPOS (*it
) += 1;
6224 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
6225 /* If this is a new paragraph, determine its base
6226 direction (a.k.a. its base embedding level). */
6227 if (it
->bidi_it
.new_paragraph
)
6228 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
6229 bidi_move_to_visually_next (&it
->bidi_it
);
6230 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6231 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6232 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
6234 /* As the scan direction was changed, we must
6235 re-compute the stop position for composition. */
6236 EMACS_INT stop
= it
->stop_charpos
;
6237 if (it
->bidi_it
.scan_dir
< 0)
6239 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6240 IT_BYTEPOS (*it
), stop
, Qnil
);
6243 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
6247 case GET_FROM_C_STRING
:
6248 /* Current display element of IT is from a C string. */
6249 IT_BYTEPOS (*it
) += it
->len
;
6250 IT_CHARPOS (*it
) += 1;
6253 case GET_FROM_DISPLAY_VECTOR
:
6254 /* Current display element of IT is from a display table entry.
6255 Advance in the display table definition. Reset it to null if
6256 end reached, and continue with characters from buffers/
6258 ++it
->current
.dpvec_index
;
6260 /* Restore face of the iterator to what they were before the
6261 display vector entry (these entries may contain faces). */
6262 it
->face_id
= it
->saved_face_id
;
6264 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
6266 int recheck_faces
= it
->ellipsis_p
;
6269 it
->method
= GET_FROM_C_STRING
;
6270 else if (STRINGP (it
->string
))
6271 it
->method
= GET_FROM_STRING
;
6274 it
->method
= GET_FROM_BUFFER
;
6275 it
->object
= it
->w
->buffer
;
6279 it
->current
.dpvec_index
= -1;
6281 /* Skip over characters which were displayed via IT->dpvec. */
6282 if (it
->dpvec_char_len
< 0)
6283 reseat_at_next_visible_line_start (it
, 1);
6284 else if (it
->dpvec_char_len
> 0)
6286 if (it
->method
== GET_FROM_STRING
6287 && it
->n_overlay_strings
> 0)
6288 it
->ignore_overlay_strings_at_pos_p
= 1;
6289 it
->len
= it
->dpvec_char_len
;
6290 set_iterator_to_next (it
, reseat_p
);
6293 /* Maybe recheck faces after display vector */
6295 it
->stop_charpos
= IT_CHARPOS (*it
);
6299 case GET_FROM_STRING
:
6300 /* Current display element is a character from a Lisp string. */
6301 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
6302 if (it
->cmp_it
.id
>= 0)
6304 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
6305 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
6306 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
6307 it
->cmp_it
.from
= it
->cmp_it
.to
;
6311 composition_compute_stop_pos (&it
->cmp_it
,
6312 IT_STRING_CHARPOS (*it
),
6313 IT_STRING_BYTEPOS (*it
),
6314 it
->stop_charpos
, it
->string
);
6319 IT_STRING_BYTEPOS (*it
) += it
->len
;
6320 IT_STRING_CHARPOS (*it
) += 1;
6323 consider_string_end
:
6325 if (it
->current
.overlay_string_index
>= 0)
6327 /* IT->string is an overlay string. Advance to the
6328 next, if there is one. */
6329 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
6332 next_overlay_string (it
);
6334 setup_for_ellipsis (it
, 0);
6339 /* IT->string is not an overlay string. If we reached
6340 its end, and there is something on IT->stack, proceed
6341 with what is on the stack. This can be either another
6342 string, this time an overlay string, or a buffer. */
6343 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
6347 if (it
->method
== GET_FROM_STRING
)
6348 goto consider_string_end
;
6353 case GET_FROM_IMAGE
:
6354 case GET_FROM_STRETCH
:
6355 /* The position etc with which we have to proceed are on
6356 the stack. The position may be at the end of a string,
6357 if the `display' property takes up the whole string. */
6358 xassert (it
->sp
> 0);
6360 if (it
->method
== GET_FROM_STRING
)
6361 goto consider_string_end
;
6365 /* There are no other methods defined, so this should be a bug. */
6369 xassert (it
->method
!= GET_FROM_STRING
6370 || (STRINGP (it
->string
)
6371 && IT_STRING_CHARPOS (*it
) >= 0));
6374 /* Load IT's display element fields with information about the next
6375 display element which comes from a display table entry or from the
6376 result of translating a control character to one of the forms `^C'
6379 IT->dpvec holds the glyphs to return as characters.
6380 IT->saved_face_id holds the face id before the display vector--it
6381 is restored into IT->face_id in set_iterator_to_next. */
6384 next_element_from_display_vector (struct it
*it
)
6389 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
6391 it
->face_id
= it
->saved_face_id
;
6393 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6394 That seemed totally bogus - so I changed it... */
6395 gc
= it
->dpvec
[it
->current
.dpvec_index
];
6397 if (GLYPH_CODE_P (gc
) && GLYPH_CODE_CHAR_VALID_P (gc
))
6399 it
->c
= GLYPH_CODE_CHAR (gc
);
6400 it
->len
= CHAR_BYTES (it
->c
);
6402 /* The entry may contain a face id to use. Such a face id is
6403 the id of a Lisp face, not a realized face. A face id of
6404 zero means no face is specified. */
6405 if (it
->dpvec_face_id
>= 0)
6406 it
->face_id
= it
->dpvec_face_id
;
6409 int lface_id
= GLYPH_CODE_FACE (gc
);
6411 it
->face_id
= merge_faces (it
->f
, Qt
, lface_id
,
6416 /* Display table entry is invalid. Return a space. */
6417 it
->c
= ' ', it
->len
= 1;
6419 /* Don't change position and object of the iterator here. They are
6420 still the values of the character that had this display table
6421 entry or was translated, and that's what we want. */
6422 it
->what
= IT_CHARACTER
;
6427 /* Load IT with the next display element from Lisp string IT->string.
6428 IT->current.string_pos is the current position within the string.
6429 If IT->current.overlay_string_index >= 0, the Lisp string is an
6433 next_element_from_string (struct it
*it
)
6435 struct text_pos position
;
6437 xassert (STRINGP (it
->string
));
6438 xassert (IT_STRING_CHARPOS (*it
) >= 0);
6439 position
= it
->current
.string_pos
;
6441 /* Time to check for invisible text? */
6442 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
6443 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
6447 /* Since a handler may have changed IT->method, we must
6449 return GET_NEXT_DISPLAY_ELEMENT (it
);
6452 if (it
->current
.overlay_string_index
>= 0)
6454 /* Get the next character from an overlay string. In overlay
6455 strings, There is no field width or padding with spaces to
6457 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
6462 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
6463 IT_STRING_BYTEPOS (*it
), SCHARS (it
->string
))
6464 && next_element_from_composition (it
))
6468 else if (STRING_MULTIBYTE (it
->string
))
6470 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
6471 const unsigned char *s
= (SDATA (it
->string
)
6472 + IT_STRING_BYTEPOS (*it
));
6473 it
->c
= string_char_and_length (s
, &it
->len
);
6477 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
6483 /* Get the next character from a Lisp string that is not an
6484 overlay string. Such strings come from the mode line, for
6485 example. We may have to pad with spaces, or truncate the
6486 string. See also next_element_from_c_string. */
6487 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
6492 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
6494 /* Pad with spaces. */
6495 it
->c
= ' ', it
->len
= 1;
6496 CHARPOS (position
) = BYTEPOS (position
) = -1;
6498 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
6499 IT_STRING_BYTEPOS (*it
), it
->string_nchars
)
6500 && next_element_from_composition (it
))
6504 else if (STRING_MULTIBYTE (it
->string
))
6506 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
6507 const unsigned char *s
= (SDATA (it
->string
)
6508 + IT_STRING_BYTEPOS (*it
));
6509 it
->c
= string_char_and_length (s
, &it
->len
);
6513 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
6518 /* Record what we have and where it came from. */
6519 it
->what
= IT_CHARACTER
;
6520 it
->object
= it
->string
;
6521 it
->position
= position
;
6526 /* Load IT with next display element from C string IT->s.
6527 IT->string_nchars is the maximum number of characters to return
6528 from the string. IT->end_charpos may be greater than
6529 IT->string_nchars when this function is called, in which case we
6530 may have to return padding spaces. Value is zero if end of string
6531 reached, including padding spaces. */
6534 next_element_from_c_string (struct it
*it
)
6539 it
->what
= IT_CHARACTER
;
6540 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
6543 /* IT's position can be greater IT->string_nchars in case a field
6544 width or precision has been specified when the iterator was
6546 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
6548 /* End of the game. */
6552 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
6554 /* Pad with spaces. */
6555 it
->c
= ' ', it
->len
= 1;
6556 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
6558 else if (it
->multibyte_p
)
6560 /* Implementation note: The calls to strlen apparently aren't a
6561 performance problem because there is no noticeable performance
6562 difference between Emacs running in unibyte or multibyte mode. */
6563 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
6564 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
), &it
->len
);
6567 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
6573 /* Set up IT to return characters from an ellipsis, if appropriate.
6574 The definition of the ellipsis glyphs may come from a display table
6575 entry. This function fills IT with the first glyph from the
6576 ellipsis if an ellipsis is to be displayed. */
6579 next_element_from_ellipsis (struct it
*it
)
6581 if (it
->selective_display_ellipsis_p
)
6582 setup_for_ellipsis (it
, it
->len
);
6585 /* The face at the current position may be different from the
6586 face we find after the invisible text. Remember what it
6587 was in IT->saved_face_id, and signal that it's there by
6588 setting face_before_selective_p. */
6589 it
->saved_face_id
= it
->face_id
;
6590 it
->method
= GET_FROM_BUFFER
;
6591 it
->object
= it
->w
->buffer
;
6592 reseat_at_next_visible_line_start (it
, 1);
6593 it
->face_before_selective_p
= 1;
6596 return GET_NEXT_DISPLAY_ELEMENT (it
);
6600 /* Deliver an image display element. The iterator IT is already
6601 filled with image information (done in handle_display_prop). Value
6606 next_element_from_image (struct it
*it
)
6608 it
->what
= IT_IMAGE
;
6609 it
->ignore_overlay_strings_at_pos_p
= 0;
6614 /* Fill iterator IT with next display element from a stretch glyph
6615 property. IT->object is the value of the text property. Value is
6619 next_element_from_stretch (struct it
*it
)
6621 it
->what
= IT_STRETCH
;
6625 /* Scan forward from CHARPOS in the current buffer, until we find a
6626 stop position > current IT's position. Then handle the stop
6627 position before that. This is called when we bump into a stop
6628 position while reordering bidirectional text. CHARPOS should be
6629 the last previously processed stop_pos (or BEGV, if none were
6630 processed yet) whose position is less that IT's current
6634 handle_stop_backwards (struct it
*it
, EMACS_INT charpos
)
6636 EMACS_INT where_we_are
= IT_CHARPOS (*it
);
6637 struct display_pos save_current
= it
->current
;
6638 struct text_pos save_position
= it
->position
;
6639 struct text_pos pos1
;
6640 EMACS_INT next_stop
;
6642 /* Scan in strict logical order. */
6646 it
->prev_stop
= charpos
;
6647 SET_TEXT_POS (pos1
, charpos
, CHAR_TO_BYTE (charpos
));
6648 reseat_1 (it
, pos1
, 0);
6649 compute_stop_pos (it
);
6650 /* We must advance forward, right? */
6651 if (it
->stop_charpos
<= it
->prev_stop
)
6653 charpos
= it
->stop_charpos
;
6655 while (charpos
<= where_we_are
);
6657 next_stop
= it
->stop_charpos
;
6658 it
->stop_charpos
= it
->prev_stop
;
6660 it
->current
= save_current
;
6661 it
->position
= save_position
;
6663 it
->stop_charpos
= next_stop
;
6666 /* Load IT with the next display element from current_buffer. Value
6667 is zero if end of buffer reached. IT->stop_charpos is the next
6668 position at which to stop and check for text properties or buffer
6672 next_element_from_buffer (struct it
*it
)
6676 xassert (IT_CHARPOS (*it
) >= BEGV
);
6678 /* With bidi reordering, the character to display might not be the
6679 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6680 we were reseat()ed to a new buffer position, which is potentially
6681 a different paragraph. */
6682 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
6684 it
->bidi_it
.charpos
= IT_CHARPOS (*it
);
6685 it
->bidi_it
.bytepos
= IT_BYTEPOS (*it
);
6686 if (it
->bidi_it
.bytepos
== ZV_BYTE
)
6688 /* Nothing to do, but reset the FIRST_ELT flag, like
6689 bidi_paragraph_init does, because we are not going to
6691 it
->bidi_it
.first_elt
= 0;
6693 else if (it
->bidi_it
.bytepos
== BEGV_BYTE
6694 /* FIXME: Should support all Unicode line separators. */
6695 || FETCH_CHAR (it
->bidi_it
.bytepos
- 1) == '\n'
6696 || FETCH_CHAR (it
->bidi_it
.bytepos
) == '\n')
6698 /* If we are at the beginning of a line, we can produce the
6699 next element right away. */
6700 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
6701 bidi_move_to_visually_next (&it
->bidi_it
);
6705 int orig_bytepos
= IT_BYTEPOS (*it
);
6707 /* We need to prime the bidi iterator starting at the line's
6708 beginning, before we will be able to produce the next
6710 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
), -1);
6711 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
6712 it
->bidi_it
.charpos
= IT_CHARPOS (*it
);
6713 it
->bidi_it
.bytepos
= IT_BYTEPOS (*it
);
6714 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
6717 /* Now return to buffer position where we were asked to
6718 get the next display element, and produce that. */
6719 bidi_move_to_visually_next (&it
->bidi_it
);
6721 while (it
->bidi_it
.bytepos
!= orig_bytepos
6722 && it
->bidi_it
.bytepos
< ZV_BYTE
);
6725 it
->bidi_it
.first_elt
= 0; /* paranoia: bidi.c does this */
6726 /* Adjust IT's position information to where we ended up. */
6727 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6728 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6729 SET_TEXT_POS (it
->position
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
6731 EMACS_INT stop
= it
->stop_charpos
;
6732 if (it
->bidi_it
.scan_dir
< 0)
6734 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6735 IT_BYTEPOS (*it
), stop
, Qnil
);
6739 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
6741 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
6743 int overlay_strings_follow_p
;
6745 /* End of the game, except when overlay strings follow that
6746 haven't been returned yet. */
6747 if (it
->overlay_strings_at_end_processed_p
)
6748 overlay_strings_follow_p
= 0;
6751 it
->overlay_strings_at_end_processed_p
= 1;
6752 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
6755 if (overlay_strings_follow_p
)
6756 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
6760 it
->position
= it
->current
.pos
;
6764 else if (!(!it
->bidi_p
6765 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
6766 || IT_CHARPOS (*it
) == it
->stop_charpos
))
6768 /* With bidi non-linear iteration, we could find ourselves
6769 far beyond the last computed stop_charpos, with several
6770 other stop positions in between that we missed. Scan
6771 them all now, in buffer's logical order, until we find
6772 and handle the last stop_charpos that precedes our
6773 current position. */
6774 handle_stop_backwards (it
, it
->stop_charpos
);
6775 return GET_NEXT_DISPLAY_ELEMENT (it
);
6781 /* Take note of the stop position we just moved across,
6782 for when we will move back across it. */
6783 it
->prev_stop
= it
->stop_charpos
;
6784 /* If we are at base paragraph embedding level, take
6785 note of the last stop position seen at this
6787 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
6788 it
->base_level_stop
= it
->stop_charpos
;
6791 return GET_NEXT_DISPLAY_ELEMENT (it
);
6795 /* We can sometimes back up for reasons that have nothing
6796 to do with bidi reordering. E.g., compositions. The
6797 code below is only needed when we are above the base
6798 embedding level, so test for that explicitly. */
6799 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
)
6800 && IT_CHARPOS (*it
) < it
->prev_stop
)
6802 if (it
->base_level_stop
<= 0)
6803 it
->base_level_stop
= BEGV
;
6804 if (IT_CHARPOS (*it
) < it
->base_level_stop
)
6806 handle_stop_backwards (it
, it
->base_level_stop
);
6807 return GET_NEXT_DISPLAY_ELEMENT (it
);
6811 /* No face changes, overlays etc. in sight, so just return a
6812 character from current_buffer. */
6816 /* Maybe run the redisplay end trigger hook. Performance note:
6817 This doesn't seem to cost measurable time. */
6818 if (it
->redisplay_end_trigger_charpos
6820 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
6821 run_redisplay_end_trigger_hook (it
);
6823 stop
= it
->bidi_it
.scan_dir
< 0 ? -1 : it
->end_charpos
;
6824 if (CHAR_COMPOSED_P (it
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6826 && next_element_from_composition (it
))
6831 /* Get the next character, maybe multibyte. */
6832 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
6833 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
6834 it
->c
= STRING_CHAR_AND_LENGTH (p
, it
->len
);
6836 it
->c
= *p
, it
->len
= 1;
6838 /* Record what we have and where it came from. */
6839 it
->what
= IT_CHARACTER
;
6840 it
->object
= it
->w
->buffer
;
6841 it
->position
= it
->current
.pos
;
6843 /* Normally we return the character found above, except when we
6844 really want to return an ellipsis for selective display. */
6849 /* A value of selective > 0 means hide lines indented more
6850 than that number of columns. */
6851 if (it
->selective
> 0
6852 && IT_CHARPOS (*it
) + 1 < ZV
6853 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
6854 IT_BYTEPOS (*it
) + 1,
6855 (double) it
->selective
)) /* iftc */
6857 success_p
= next_element_from_ellipsis (it
);
6858 it
->dpvec_char_len
= -1;
6861 else if (it
->c
== '\r' && it
->selective
== -1)
6863 /* A value of selective == -1 means that everything from the
6864 CR to the end of the line is invisible, with maybe an
6865 ellipsis displayed for it. */
6866 success_p
= next_element_from_ellipsis (it
);
6867 it
->dpvec_char_len
= -1;
6872 /* Value is zero if end of buffer reached. */
6873 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
6878 /* Run the redisplay end trigger hook for IT. */
6881 run_redisplay_end_trigger_hook (struct it
*it
)
6883 Lisp_Object args
[3];
6885 /* IT->glyph_row should be non-null, i.e. we should be actually
6886 displaying something, or otherwise we should not run the hook. */
6887 xassert (it
->glyph_row
);
6889 /* Set up hook arguments. */
6890 args
[0] = Qredisplay_end_trigger_functions
;
6891 args
[1] = it
->window
;
6892 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
6893 it
->redisplay_end_trigger_charpos
= 0;
6895 /* Since we are *trying* to run these functions, don't try to run
6896 them again, even if they get an error. */
6897 it
->w
->redisplay_end_trigger
= Qnil
;
6898 Frun_hook_with_args (3, args
);
6900 /* Notice if it changed the face of the character we are on. */
6901 handle_face_prop (it
);
6905 /* Deliver a composition display element. Unlike the other
6906 next_element_from_XXX, this function is not registered in the array
6907 get_next_element[]. It is called from next_element_from_buffer and
6908 next_element_from_string when necessary. */
6911 next_element_from_composition (struct it
*it
)
6913 it
->what
= IT_COMPOSITION
;
6914 it
->len
= it
->cmp_it
.nbytes
;
6915 if (STRINGP (it
->string
))
6919 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
6920 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
6923 it
->position
= it
->current
.string_pos
;
6924 it
->object
= it
->string
;
6925 it
->c
= composition_update_it (&it
->cmp_it
, IT_STRING_CHARPOS (*it
),
6926 IT_STRING_BYTEPOS (*it
), it
->string
);
6932 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
6933 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
6936 if (it
->bidi_it
.new_paragraph
)
6937 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
6938 /* Resync the bidi iterator with IT's new position.
6939 FIXME: this doesn't support bidirectional text. */
6940 while (it
->bidi_it
.charpos
< IT_CHARPOS (*it
))
6941 bidi_move_to_visually_next (&it
->bidi_it
);
6945 it
->position
= it
->current
.pos
;
6946 it
->object
= it
->w
->buffer
;
6947 it
->c
= composition_update_it (&it
->cmp_it
, IT_CHARPOS (*it
),
6948 IT_BYTEPOS (*it
), Qnil
);
6955 /***********************************************************************
6956 Moving an iterator without producing glyphs
6957 ***********************************************************************/
6959 /* Check if iterator is at a position corresponding to a valid buffer
6960 position after some move_it_ call. */
6962 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6963 ((it)->method == GET_FROM_STRING \
6964 ? IT_STRING_CHARPOS (*it) == 0 \
6968 /* Move iterator IT to a specified buffer or X position within one
6969 line on the display without producing glyphs.
6971 OP should be a bit mask including some or all of these bits:
6972 MOVE_TO_X: Stop upon reaching x-position TO_X.
6973 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6974 Regardless of OP's value, stop upon reaching the end of the display line.
6976 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6977 This means, in particular, that TO_X includes window's horizontal
6980 The return value has several possible values that
6981 say what condition caused the scan to stop:
6983 MOVE_POS_MATCH_OR_ZV
6984 - when TO_POS or ZV was reached.
6987 -when TO_X was reached before TO_POS or ZV were reached.
6990 - when we reached the end of the display area and the line must
6994 - when we reached the end of the display area and the line is
6998 - when we stopped at a line end, i.e. a newline or a CR and selective
7001 static enum move_it_result
7002 move_it_in_display_line_to (struct it
*it
,
7003 EMACS_INT to_charpos
, int to_x
,
7004 enum move_operation_enum op
)
7006 enum move_it_result result
= MOVE_UNDEFINED
;
7007 struct glyph_row
*saved_glyph_row
;
7008 struct it wrap_it
, atpos_it
, atx_it
;
7010 enum it_method prev_method
= it
->method
;
7011 EMACS_INT prev_pos
= IT_CHARPOS (*it
);
7013 /* Don't produce glyphs in produce_glyphs. */
7014 saved_glyph_row
= it
->glyph_row
;
7015 it
->glyph_row
= NULL
;
7017 /* Use wrap_it to save a copy of IT wherever a word wrap could
7018 occur. Use atpos_it to save a copy of IT at the desired buffer
7019 position, if found, so that we can scan ahead and check if the
7020 word later overshoots the window edge. Use atx_it similarly, for
7026 #define BUFFER_POS_REACHED_P() \
7027 ((op & MOVE_TO_POS) != 0 \
7028 && BUFFERP (it->object) \
7029 && (IT_CHARPOS (*it) == to_charpos \
7030 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7031 && (it->method == GET_FROM_BUFFER \
7032 || (it->method == GET_FROM_DISPLAY_VECTOR \
7033 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7035 /* If there's a line-/wrap-prefix, handle it. */
7036 if (it
->hpos
== 0 && it
->method
== GET_FROM_BUFFER
7037 && it
->current_y
< it
->last_visible_y
)
7038 handle_line_prefix (it
);
7042 int x
, i
, ascent
= 0, descent
= 0;
7044 /* Utility macro to reset an iterator with x, ascent, and descent. */
7045 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7046 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7047 (IT)->max_descent = descent)
7049 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7051 if ((op
& MOVE_TO_POS
) != 0
7052 && BUFFERP (it
->object
)
7053 && it
->method
== GET_FROM_BUFFER
7054 && ((!it
->bidi_p
&& IT_CHARPOS (*it
) > to_charpos
)
7056 && (prev_method
== GET_FROM_IMAGE
7057 || prev_method
== GET_FROM_STRETCH
)
7058 /* Passed TO_CHARPOS from left to right. */
7059 && ((prev_pos
< to_charpos
7060 && IT_CHARPOS (*it
) > to_charpos
)
7061 /* Passed TO_CHARPOS from right to left. */
7062 || (prev_pos
> to_charpos
7063 && IT_CHARPOS (*it
) < to_charpos
)))))
7065 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
7067 result
= MOVE_POS_MATCH_OR_ZV
;
7070 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
7071 /* If wrap_it is valid, the current position might be in a
7072 word that is wrapped. So, save the iterator in
7073 atpos_it and continue to see if wrapping happens. */
7077 prev_method
= it
->method
;
7078 if (it
->method
== GET_FROM_BUFFER
)
7079 prev_pos
= IT_CHARPOS (*it
);
7080 /* Stop when ZV reached.
7081 We used to stop here when TO_CHARPOS reached as well, but that is
7082 too soon if this glyph does not fit on this line. So we handle it
7083 explicitly below. */
7084 if (!get_next_display_element (it
))
7086 result
= MOVE_POS_MATCH_OR_ZV
;
7090 if (it
->line_wrap
== TRUNCATE
)
7092 if (BUFFER_POS_REACHED_P ())
7094 result
= MOVE_POS_MATCH_OR_ZV
;
7100 if (it
->line_wrap
== WORD_WRAP
)
7102 if (IT_DISPLAYING_WHITESPACE (it
))
7106 /* We have reached a glyph that follows one or more
7107 whitespace characters. If the position is
7108 already found, we are done. */
7109 if (atpos_it
.sp
>= 0)
7112 result
= MOVE_POS_MATCH_OR_ZV
;
7118 result
= MOVE_X_REACHED
;
7121 /* Otherwise, we can wrap here. */
7128 /* Remember the line height for the current line, in case
7129 the next element doesn't fit on the line. */
7130 ascent
= it
->max_ascent
;
7131 descent
= it
->max_descent
;
7133 /* The call to produce_glyphs will get the metrics of the
7134 display element IT is loaded with. Record the x-position
7135 before this display element, in case it doesn't fit on the
7139 PRODUCE_GLYPHS (it
);
7141 if (it
->area
!= TEXT_AREA
)
7143 set_iterator_to_next (it
, 1);
7147 /* The number of glyphs we get back in IT->nglyphs will normally
7148 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7149 character on a terminal frame, or (iii) a line end. For the
7150 second case, IT->nglyphs - 1 padding glyphs will be present.
7151 (On X frames, there is only one glyph produced for a
7152 composite character.)
7154 The behavior implemented below means, for continuation lines,
7155 that as many spaces of a TAB as fit on the current line are
7156 displayed there. For terminal frames, as many glyphs of a
7157 multi-glyph character are displayed in the current line, too.
7158 This is what the old redisplay code did, and we keep it that
7159 way. Under X, the whole shape of a complex character must
7160 fit on the line or it will be completely displayed in the
7163 Note that both for tabs and padding glyphs, all glyphs have
7167 /* More than one glyph or glyph doesn't fit on line. All
7168 glyphs have the same width. */
7169 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
7171 int x_before_this_char
= x
;
7172 int hpos_before_this_char
= it
->hpos
;
7174 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
7176 new_x
= x
+ single_glyph_width
;
7178 /* We want to leave anything reaching TO_X to the caller. */
7179 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
7181 if (BUFFER_POS_REACHED_P ())
7183 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
7184 goto buffer_pos_reached
;
7185 if (atpos_it
.sp
< 0)
7188 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
7193 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
7196 result
= MOVE_X_REACHED
;
7202 IT_RESET_X_ASCENT_DESCENT (&atx_it
);
7207 if (/* Lines are continued. */
7208 it
->line_wrap
!= TRUNCATE
7209 && (/* And glyph doesn't fit on the line. */
7210 new_x
> it
->last_visible_x
7211 /* Or it fits exactly and we're on a window
7213 || (new_x
== it
->last_visible_x
7214 && FRAME_WINDOW_P (it
->f
))))
7216 if (/* IT->hpos == 0 means the very first glyph
7217 doesn't fit on the line, e.g. a wide image. */
7219 || (new_x
== it
->last_visible_x
7220 && FRAME_WINDOW_P (it
->f
)))
7223 it
->current_x
= new_x
;
7225 /* The character's last glyph just barely fits
7227 if (i
== it
->nglyphs
- 1)
7229 /* If this is the destination position,
7230 return a position *before* it in this row,
7231 now that we know it fits in this row. */
7232 if (BUFFER_POS_REACHED_P ())
7234 if (it
->line_wrap
!= WORD_WRAP
7237 it
->hpos
= hpos_before_this_char
;
7238 it
->current_x
= x_before_this_char
;
7239 result
= MOVE_POS_MATCH_OR_ZV
;
7242 if (it
->line_wrap
== WORD_WRAP
7246 atpos_it
.current_x
= x_before_this_char
;
7247 atpos_it
.hpos
= hpos_before_this_char
;
7251 set_iterator_to_next (it
, 1);
7252 /* On graphical terminals, newlines may
7253 "overflow" into the fringe if
7254 overflow-newline-into-fringe is non-nil.
7255 On text-only terminals, newlines may
7256 overflow into the last glyph on the
7258 if (!FRAME_WINDOW_P (it
->f
)
7259 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
7261 if (!get_next_display_element (it
))
7263 result
= MOVE_POS_MATCH_OR_ZV
;
7266 if (BUFFER_POS_REACHED_P ())
7268 if (ITERATOR_AT_END_OF_LINE_P (it
))
7269 result
= MOVE_POS_MATCH_OR_ZV
;
7271 result
= MOVE_LINE_CONTINUED
;
7274 if (ITERATOR_AT_END_OF_LINE_P (it
))
7276 result
= MOVE_NEWLINE_OR_CR
;
7283 IT_RESET_X_ASCENT_DESCENT (it
);
7285 if (wrap_it
.sp
>= 0)
7292 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
7294 result
= MOVE_LINE_CONTINUED
;
7298 if (BUFFER_POS_REACHED_P ())
7300 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
7301 goto buffer_pos_reached
;
7302 if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
7305 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
7309 if (new_x
> it
->first_visible_x
)
7311 /* Glyph is visible. Increment number of glyphs that
7312 would be displayed. */
7317 if (result
!= MOVE_UNDEFINED
)
7320 else if (BUFFER_POS_REACHED_P ())
7323 IT_RESET_X_ASCENT_DESCENT (it
);
7324 result
= MOVE_POS_MATCH_OR_ZV
;
7327 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
7329 /* Stop when TO_X specified and reached. This check is
7330 necessary here because of lines consisting of a line end,
7331 only. The line end will not produce any glyphs and we
7332 would never get MOVE_X_REACHED. */
7333 xassert (it
->nglyphs
== 0);
7334 result
= MOVE_X_REACHED
;
7338 /* Is this a line end? If yes, we're done. */
7339 if (ITERATOR_AT_END_OF_LINE_P (it
))
7341 result
= MOVE_NEWLINE_OR_CR
;
7345 if (it
->method
== GET_FROM_BUFFER
)
7346 prev_pos
= IT_CHARPOS (*it
);
7347 /* The current display element has been consumed. Advance
7349 set_iterator_to_next (it
, 1);
7351 /* Stop if lines are truncated and IT's current x-position is
7352 past the right edge of the window now. */
7353 if (it
->line_wrap
== TRUNCATE
7354 && it
->current_x
>= it
->last_visible_x
)
7356 if (!FRAME_WINDOW_P (it
->f
)
7357 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
7359 if (!get_next_display_element (it
)
7360 || BUFFER_POS_REACHED_P ())
7362 result
= MOVE_POS_MATCH_OR_ZV
;
7365 if (ITERATOR_AT_END_OF_LINE_P (it
))
7367 result
= MOVE_NEWLINE_OR_CR
;
7371 result
= MOVE_LINE_TRUNCATED
;
7374 #undef IT_RESET_X_ASCENT_DESCENT
7377 #undef BUFFER_POS_REACHED_P
7379 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7380 restore the saved iterator. */
7381 if (atpos_it
.sp
>= 0)
7383 else if (atx_it
.sp
>= 0)
7388 /* Restore the iterator settings altered at the beginning of this
7390 it
->glyph_row
= saved_glyph_row
;
7394 /* For external use. */
7396 move_it_in_display_line (struct it
*it
,
7397 EMACS_INT to_charpos
, int to_x
,
7398 enum move_operation_enum op
)
7400 if (it
->line_wrap
== WORD_WRAP
7401 && (op
& MOVE_TO_X
))
7403 struct it save_it
= *it
;
7404 int skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
7405 /* When word-wrap is on, TO_X may lie past the end
7406 of a wrapped line. Then it->current is the
7407 character on the next line, so backtrack to the
7408 space before the wrap point. */
7409 if (skip
== MOVE_LINE_CONTINUED
)
7411 int prev_x
= max (it
->current_x
- 1, 0);
7413 move_it_in_display_line_to
7414 (it
, -1, prev_x
, MOVE_TO_X
);
7418 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
7422 /* Move IT forward until it satisfies one or more of the criteria in
7423 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7425 OP is a bit-mask that specifies where to stop, and in particular,
7426 which of those four position arguments makes a difference. See the
7427 description of enum move_operation_enum.
7429 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7430 screen line, this function will set IT to the next position >
7434 move_it_to (struct it
*it
, int to_charpos
, int to_x
, int to_y
, int to_vpos
, int op
)
7436 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
7437 int line_height
, line_start_x
= 0, reached
= 0;
7441 if (op
& MOVE_TO_VPOS
)
7443 /* If no TO_CHARPOS and no TO_X specified, stop at the
7444 start of the line TO_VPOS. */
7445 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
7447 if (it
->vpos
== to_vpos
)
7453 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
7457 /* TO_VPOS >= 0 means stop at TO_X in the line at
7458 TO_VPOS, or at TO_POS, whichever comes first. */
7459 if (it
->vpos
== to_vpos
)
7465 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
7467 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
7472 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
7474 /* We have reached TO_X but not in the line we want. */
7475 skip
= move_it_in_display_line_to (it
, to_charpos
,
7477 if (skip
== MOVE_POS_MATCH_OR_ZV
)
7485 else if (op
& MOVE_TO_Y
)
7487 struct it it_backup
;
7489 if (it
->line_wrap
== WORD_WRAP
)
7492 /* TO_Y specified means stop at TO_X in the line containing
7493 TO_Y---or at TO_CHARPOS if this is reached first. The
7494 problem is that we can't really tell whether the line
7495 contains TO_Y before we have completely scanned it, and
7496 this may skip past TO_X. What we do is to first scan to
7499 If TO_X is not specified, use a TO_X of zero. The reason
7500 is to make the outcome of this function more predictable.
7501 If we didn't use TO_X == 0, we would stop at the end of
7502 the line which is probably not what a caller would expect
7504 skip
= move_it_in_display_line_to
7505 (it
, to_charpos
, ((op
& MOVE_TO_X
) ? to_x
: 0),
7506 (MOVE_TO_X
| (op
& MOVE_TO_POS
)));
7508 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7509 if (skip
== MOVE_POS_MATCH_OR_ZV
)
7511 else if (skip
== MOVE_X_REACHED
)
7513 /* If TO_X was reached, we want to know whether TO_Y is
7514 in the line. We know this is the case if the already
7515 scanned glyphs make the line tall enough. Otherwise,
7516 we must check by scanning the rest of the line. */
7517 line_height
= it
->max_ascent
+ it
->max_descent
;
7518 if (to_y
>= it
->current_y
7519 && to_y
< it
->current_y
+ line_height
)
7525 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
7526 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
7528 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
7529 line_height
= it
->max_ascent
+ it
->max_descent
;
7530 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
7532 if (to_y
>= it
->current_y
7533 && to_y
< it
->current_y
+ line_height
)
7535 /* If TO_Y is in this line and TO_X was reached
7536 above, we scanned too far. We have to restore
7537 IT's settings to the ones before skipping. */
7544 if (skip
== MOVE_POS_MATCH_OR_ZV
)
7550 /* Check whether TO_Y is in this line. */
7551 line_height
= it
->max_ascent
+ it
->max_descent
;
7552 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
7554 if (to_y
>= it
->current_y
7555 && to_y
< it
->current_y
+ line_height
)
7557 /* When word-wrap is on, TO_X may lie past the end
7558 of a wrapped line. Then it->current is the
7559 character on the next line, so backtrack to the
7560 space before the wrap point. */
7561 if (skip
== MOVE_LINE_CONTINUED
7562 && it
->line_wrap
== WORD_WRAP
)
7564 int prev_x
= max (it
->current_x
- 1, 0);
7566 skip
= move_it_in_display_line_to
7567 (it
, -1, prev_x
, MOVE_TO_X
);
7576 else if (BUFFERP (it
->object
)
7577 && (it
->method
== GET_FROM_BUFFER
7578 || it
->method
== GET_FROM_STRETCH
)
7579 && IT_CHARPOS (*it
) >= to_charpos
)
7580 skip
= MOVE_POS_MATCH_OR_ZV
;
7582 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
7586 case MOVE_POS_MATCH_OR_ZV
:
7590 case MOVE_NEWLINE_OR_CR
:
7591 set_iterator_to_next (it
, 1);
7592 it
->continuation_lines_width
= 0;
7595 case MOVE_LINE_TRUNCATED
:
7596 it
->continuation_lines_width
= 0;
7597 reseat_at_next_visible_line_start (it
, 0);
7598 if ((op
& MOVE_TO_POS
) != 0
7599 && IT_CHARPOS (*it
) > to_charpos
)
7606 case MOVE_LINE_CONTINUED
:
7607 /* For continued lines ending in a tab, some of the glyphs
7608 associated with the tab are displayed on the current
7609 line. Since it->current_x does not include these glyphs,
7610 we use it->last_visible_x instead. */
7613 it
->continuation_lines_width
+= it
->last_visible_x
;
7614 /* When moving by vpos, ensure that the iterator really
7615 advances to the next line (bug#847, bug#969). Fixme:
7616 do we need to do this in other circumstances? */
7617 if (it
->current_x
!= it
->last_visible_x
7618 && (op
& MOVE_TO_VPOS
)
7619 && !(op
& (MOVE_TO_X
| MOVE_TO_POS
)))
7621 line_start_x
= it
->current_x
+ it
->pixel_width
7622 - it
->last_visible_x
;
7623 set_iterator_to_next (it
, 0);
7627 it
->continuation_lines_width
+= it
->current_x
;
7634 /* Reset/increment for the next run. */
7635 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
7636 it
->current_x
= line_start_x
;
7639 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
7641 last_height
= it
->max_ascent
+ it
->max_descent
;
7642 last_max_ascent
= it
->max_ascent
;
7643 it
->max_ascent
= it
->max_descent
= 0;
7648 /* On text terminals, we may stop at the end of a line in the middle
7649 of a multi-character glyph. If the glyph itself is continued,
7650 i.e. it is actually displayed on the next line, don't treat this
7651 stopping point as valid; move to the next line instead (unless
7652 that brings us offscreen). */
7653 if (!FRAME_WINDOW_P (it
->f
)
7655 && IT_CHARPOS (*it
) == to_charpos
7656 && it
->what
== IT_CHARACTER
7658 && it
->line_wrap
== WINDOW_WRAP
7659 && it
->current_x
== it
->last_visible_x
- 1
7662 && it
->vpos
< XFASTINT (it
->w
->window_end_vpos
))
7664 it
->continuation_lines_width
+= it
->current_x
;
7665 it
->current_x
= it
->hpos
= it
->max_ascent
= it
->max_descent
= 0;
7666 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
7668 last_height
= it
->max_ascent
+ it
->max_descent
;
7669 last_max_ascent
= it
->max_ascent
;
7672 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
7676 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7678 If DY > 0, move IT backward at least that many pixels. DY = 0
7679 means move IT backward to the preceding line start or BEGV. This
7680 function may move over more than DY pixels if IT->current_y - DY
7681 ends up in the middle of a line; in this case IT->current_y will be
7682 set to the top of the line moved to. */
7685 move_it_vertically_backward (struct it
*it
, int dy
)
7694 start_pos
= IT_CHARPOS (*it
);
7696 /* Estimate how many newlines we must move back. */
7697 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
7699 /* Set the iterator's position that many lines back. */
7700 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
7701 back_to_previous_visible_line_start (it
);
7703 /* Reseat the iterator here. When moving backward, we don't want
7704 reseat to skip forward over invisible text, set up the iterator
7705 to deliver from overlay strings at the new position etc. So,
7706 use reseat_1 here. */
7707 reseat_1 (it
, it
->current
.pos
, 1);
7709 /* We are now surely at a line start. */
7710 it
->current_x
= it
->hpos
= 0;
7711 it
->continuation_lines_width
= 0;
7713 /* Move forward and see what y-distance we moved. First move to the
7714 start of the next line so that we get its height. We need this
7715 height to be able to tell whether we reached the specified
7718 it2
.max_ascent
= it2
.max_descent
= 0;
7721 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
7722 MOVE_TO_POS
| MOVE_TO_VPOS
);
7724 while (!IT_POS_VALID_AFTER_MOVE_P (&it2
));
7725 xassert (IT_CHARPOS (*it
) >= BEGV
);
7728 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
7729 xassert (IT_CHARPOS (*it
) >= BEGV
);
7730 /* H is the actual vertical distance from the position in *IT
7731 and the starting position. */
7732 h
= it2
.current_y
- it
->current_y
;
7733 /* NLINES is the distance in number of lines. */
7734 nlines
= it2
.vpos
- it
->vpos
;
7736 /* Correct IT's y and vpos position
7737 so that they are relative to the starting point. */
7743 /* DY == 0 means move to the start of the screen line. The
7744 value of nlines is > 0 if continuation lines were involved. */
7746 move_it_by_lines (it
, nlines
, 1);
7750 /* The y-position we try to reach, relative to *IT.
7751 Note that H has been subtracted in front of the if-statement. */
7752 int target_y
= it
->current_y
+ h
- dy
;
7753 int y0
= it3
.current_y
;
7754 int y1
= line_bottom_y (&it3
);
7755 int line_height
= y1
- y0
;
7757 /* If we did not reach target_y, try to move further backward if
7758 we can. If we moved too far backward, try to move forward. */
7759 if (target_y
< it
->current_y
7760 /* This is heuristic. In a window that's 3 lines high, with
7761 a line height of 13 pixels each, recentering with point
7762 on the bottom line will try to move -39/2 = 19 pixels
7763 backward. Try to avoid moving into the first line. */
7764 && (it
->current_y
- target_y
7765 > min (window_box_height (it
->w
), line_height
* 2 / 3))
7766 && IT_CHARPOS (*it
) > BEGV
)
7768 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
7769 target_y
- it
->current_y
));
7770 dy
= it
->current_y
- target_y
;
7771 goto move_further_back
;
7773 else if (target_y
>= it
->current_y
+ line_height
7774 && IT_CHARPOS (*it
) < ZV
)
7776 /* Should move forward by at least one line, maybe more.
7778 Note: Calling move_it_by_lines can be expensive on
7779 terminal frames, where compute_motion is used (via
7780 vmotion) to do the job, when there are very long lines
7781 and truncate-lines is nil. That's the reason for
7782 treating terminal frames specially here. */
7784 if (!FRAME_WINDOW_P (it
->f
))
7785 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
7790 move_it_by_lines (it
, 1, 1);
7792 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
7799 /* Move IT by a specified amount of pixel lines DY. DY negative means
7800 move backwards. DY = 0 means move to start of screen line. At the
7801 end, IT will be on the start of a screen line. */
7804 move_it_vertically (struct it
*it
, int dy
)
7807 move_it_vertically_backward (it
, -dy
);
7810 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
7811 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
7812 MOVE_TO_POS
| MOVE_TO_Y
);
7813 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
7815 /* If buffer ends in ZV without a newline, move to the start of
7816 the line to satisfy the post-condition. */
7817 if (IT_CHARPOS (*it
) == ZV
7819 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
7820 move_it_by_lines (it
, 0, 0);
7825 /* Move iterator IT past the end of the text line it is in. */
7828 move_it_past_eol (struct it
*it
)
7830 enum move_it_result rc
;
7832 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
7833 if (rc
== MOVE_NEWLINE_OR_CR
)
7834 set_iterator_to_next (it
, 0);
7838 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7839 negative means move up. DVPOS == 0 means move to the start of the
7840 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7841 NEED_Y_P is zero, IT->current_y will be left unchanged.
7843 Further optimization ideas: If we would know that IT->f doesn't use
7844 a face with proportional font, we could be faster for
7845 truncate-lines nil. */
7848 move_it_by_lines (struct it
*it
, int dvpos
, int need_y_p
)
7850 struct position pos
;
7852 /* The commented-out optimization uses vmotion on terminals. This
7853 gives bad results, because elements like it->what, on which
7854 callers such as pos_visible_p rely, aren't updated. */
7855 /* if (!FRAME_WINDOW_P (it->f))
7857 struct text_pos textpos;
7859 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7860 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7861 reseat (it, textpos, 1);
7862 it->vpos += pos.vpos;
7863 it->current_y += pos.vpos;
7869 /* DVPOS == 0 means move to the start of the screen line. */
7870 move_it_vertically_backward (it
, 0);
7871 xassert (it
->current_x
== 0 && it
->hpos
== 0);
7872 /* Let next call to line_bottom_y calculate real line height */
7877 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
7878 if (!IT_POS_VALID_AFTER_MOVE_P (it
))
7879 move_it_to (it
, IT_CHARPOS (*it
) + 1, -1, -1, -1, MOVE_TO_POS
);
7884 int start_charpos
, i
;
7886 /* Start at the beginning of the screen line containing IT's
7887 position. This may actually move vertically backwards,
7888 in case of overlays, so adjust dvpos accordingly. */
7890 move_it_vertically_backward (it
, 0);
7893 /* Go back -DVPOS visible lines and reseat the iterator there. */
7894 start_charpos
= IT_CHARPOS (*it
);
7895 for (i
= -dvpos
; i
> 0 && IT_CHARPOS (*it
) > BEGV
; --i
)
7896 back_to_previous_visible_line_start (it
);
7897 reseat (it
, it
->current
.pos
, 1);
7899 /* Move further back if we end up in a string or an image. */
7900 while (!IT_POS_VALID_AFTER_MOVE_P (it
))
7902 /* First try to move to start of display line. */
7904 move_it_vertically_backward (it
, 0);
7906 if (IT_POS_VALID_AFTER_MOVE_P (it
))
7908 /* If start of line is still in string or image,
7909 move further back. */
7910 back_to_previous_visible_line_start (it
);
7911 reseat (it
, it
->current
.pos
, 1);
7915 it
->current_x
= it
->hpos
= 0;
7917 /* Above call may have moved too far if continuation lines
7918 are involved. Scan forward and see if it did. */
7920 it2
.vpos
= it2
.current_y
= 0;
7921 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
7922 it
->vpos
-= it2
.vpos
;
7923 it
->current_y
-= it2
.current_y
;
7924 it
->current_x
= it
->hpos
= 0;
7926 /* If we moved too far back, move IT some lines forward. */
7927 if (it2
.vpos
> -dvpos
)
7929 int delta
= it2
.vpos
+ dvpos
;
7931 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
7932 /* Move back again if we got too far ahead. */
7933 if (IT_CHARPOS (*it
) >= start_charpos
)
7939 /* Return 1 if IT points into the middle of a display vector. */
7942 in_display_vector_p (struct it
*it
)
7944 return (it
->method
== GET_FROM_DISPLAY_VECTOR
7945 && it
->current
.dpvec_index
> 0
7946 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
7950 /***********************************************************************
7952 ***********************************************************************/
7955 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7959 add_to_log (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
7961 Lisp_Object args
[3];
7962 Lisp_Object msg
, fmt
;
7965 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
7968 /* Do nothing if called asynchronously. Inserting text into
7969 a buffer may call after-change-functions and alike and
7970 that would means running Lisp asynchronously. */
7971 if (handling_signal
)
7975 GCPRO4 (fmt
, msg
, arg1
, arg2
);
7977 args
[0] = fmt
= build_string (format
);
7980 msg
= Fformat (3, args
);
7982 len
= SBYTES (msg
) + 1;
7983 SAFE_ALLOCA (buffer
, char *, len
);
7984 memcpy (buffer
, SDATA (msg
), len
);
7986 message_dolog (buffer
, len
- 1, 1, 0);
7993 /* Output a newline in the *Messages* buffer if "needs" one. */
7996 message_log_maybe_newline (void)
7998 if (message_log_need_newline
)
7999 message_dolog ("", 0, 1, 0);
8003 /* Add a string M of length NBYTES to the message log, optionally
8004 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8005 nonzero, means interpret the contents of M as multibyte. This
8006 function calls low-level routines in order to bypass text property
8007 hooks, etc. which might not be safe to run.
8009 This may GC (insert may run before/after change hooks),
8010 so the buffer M must NOT point to a Lisp string. */
8013 message_dolog (const char *m
, int nbytes
, int nlflag
, int multibyte
)
8015 if (!NILP (Vmemory_full
))
8018 if (!NILP (Vmessage_log_max
))
8020 struct buffer
*oldbuf
;
8021 Lisp_Object oldpoint
, oldbegv
, oldzv
;
8022 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
8023 int point_at_end
= 0;
8025 Lisp_Object old_deactivate_mark
, tem
;
8026 struct gcpro gcpro1
;
8028 old_deactivate_mark
= Vdeactivate_mark
;
8029 oldbuf
= current_buffer
;
8030 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
8031 current_buffer
->undo_list
= Qt
;
8033 oldpoint
= message_dolog_marker1
;
8034 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
8035 oldbegv
= message_dolog_marker2
;
8036 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
8037 oldzv
= message_dolog_marker3
;
8038 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
8039 GCPRO1 (old_deactivate_mark
);
8047 BEGV_BYTE
= BEG_BYTE
;
8050 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
8052 /* Insert the string--maybe converting multibyte to single byte
8053 or vice versa, so that all the text fits the buffer. */
8055 && NILP (current_buffer
->enable_multibyte_characters
))
8057 int i
, c
, char_bytes
;
8058 unsigned char work
[1];
8060 /* Convert a multibyte string to single-byte
8061 for the *Message* buffer. */
8062 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
8064 c
= string_char_and_length (m
+ i
, &char_bytes
);
8065 work
[0] = (ASCII_CHAR_P (c
)
8067 : multibyte_char_to_unibyte (c
, Qnil
));
8068 insert_1_both (work
, 1, 1, 1, 0, 0);
8071 else if (! multibyte
8072 && ! NILP (current_buffer
->enable_multibyte_characters
))
8074 int i
, c
, char_bytes
;
8075 unsigned char *msg
= (unsigned char *) m
;
8076 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
8077 /* Convert a single-byte string to multibyte
8078 for the *Message* buffer. */
8079 for (i
= 0; i
< nbytes
; i
++)
8082 MAKE_CHAR_MULTIBYTE (c
);
8083 char_bytes
= CHAR_STRING (c
, str
);
8084 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
8088 insert_1 (m
, nbytes
, 1, 0, 0);
8092 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
8093 insert_1 ("\n", 1, 1, 0, 0);
8095 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
8097 this_bol_byte
= PT_BYTE
;
8099 /* See if this line duplicates the previous one.
8100 If so, combine duplicates. */
8103 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
8105 prev_bol_byte
= PT_BYTE
;
8107 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
8108 this_bol
, this_bol_byte
);
8111 del_range_both (prev_bol
, prev_bol_byte
,
8112 this_bol
, this_bol_byte
, 0);
8118 /* If you change this format, don't forget to also
8119 change message_log_check_duplicate. */
8120 sprintf (dupstr
, " [%d times]", dup
);
8121 duplen
= strlen (dupstr
);
8122 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
8123 insert_1 (dupstr
, duplen
, 1, 0, 1);
8128 /* If we have more than the desired maximum number of lines
8129 in the *Messages* buffer now, delete the oldest ones.
8130 This is safe because we don't have undo in this buffer. */
8132 if (NATNUMP (Vmessage_log_max
))
8134 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
8135 -XFASTINT (Vmessage_log_max
) - 1, 0);
8136 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
8139 BEGV
= XMARKER (oldbegv
)->charpos
;
8140 BEGV_BYTE
= marker_byte_position (oldbegv
);
8149 ZV
= XMARKER (oldzv
)->charpos
;
8150 ZV_BYTE
= marker_byte_position (oldzv
);
8154 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
8156 /* We can't do Fgoto_char (oldpoint) because it will run some
8158 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
8159 XMARKER (oldpoint
)->bytepos
);
8162 unchain_marker (XMARKER (oldpoint
));
8163 unchain_marker (XMARKER (oldbegv
));
8164 unchain_marker (XMARKER (oldzv
));
8166 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
8167 set_buffer_internal (oldbuf
);
8169 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
8170 message_log_need_newline
= !nlflag
;
8171 Vdeactivate_mark
= old_deactivate_mark
;
8176 /* We are at the end of the buffer after just having inserted a newline.
8177 (Note: We depend on the fact we won't be crossing the gap.)
8178 Check to see if the most recent message looks a lot like the previous one.
8179 Return 0 if different, 1 if the new one should just replace it, or a
8180 value N > 1 if we should also append " [N times]". */
8183 message_log_check_duplicate (int prev_bol
, int prev_bol_byte
,
8184 int this_bol
, int this_bol_byte
)
8187 int len
= Z_BYTE
- 1 - this_bol_byte
;
8189 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
8190 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
8192 for (i
= 0; i
< len
; i
++)
8194 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
8202 if (*p1
++ == ' ' && *p1
++ == '[')
8205 while (*p1
>= '0' && *p1
<= '9')
8206 n
= n
* 10 + *p1
++ - '0';
8207 if (strncmp (p1
, " times]\n", 8) == 0)
8214 /* Display an echo area message M with a specified length of NBYTES
8215 bytes. The string may include null characters. If M is 0, clear
8216 out any existing message, and let the mini-buffer text show
8219 This may GC, so the buffer M must NOT point to a Lisp string. */
8222 message2 (const char *m
, int nbytes
, int multibyte
)
8224 /* First flush out any partial line written with print. */
8225 message_log_maybe_newline ();
8227 message_dolog (m
, nbytes
, 1, multibyte
);
8228 message2_nolog (m
, nbytes
, multibyte
);
8232 /* The non-logging counterpart of message2. */
8235 message2_nolog (const char *m
, int nbytes
, int multibyte
)
8237 struct frame
*sf
= SELECTED_FRAME ();
8238 message_enable_multibyte
= multibyte
;
8240 if (FRAME_INITIAL_P (sf
))
8242 if (noninteractive_need_newline
)
8243 putc ('\n', stderr
);
8244 noninteractive_need_newline
= 0;
8246 fwrite (m
, nbytes
, 1, stderr
);
8247 if (cursor_in_echo_area
== 0)
8248 fprintf (stderr
, "\n");
8251 /* A null message buffer means that the frame hasn't really been
8252 initialized yet. Error messages get reported properly by
8253 cmd_error, so this must be just an informative message; toss it. */
8254 else if (INTERACTIVE
8255 && sf
->glyphs_initialized_p
8256 && FRAME_MESSAGE_BUF (sf
))
8258 Lisp_Object mini_window
;
8261 /* Get the frame containing the mini-buffer
8262 that the selected frame is using. */
8263 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8264 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
8266 FRAME_SAMPLE_VISIBILITY (f
);
8267 if (FRAME_VISIBLE_P (sf
)
8268 && ! FRAME_VISIBLE_P (f
))
8269 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
8273 set_message (m
, Qnil
, nbytes
, multibyte
);
8274 if (minibuffer_auto_raise
)
8275 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
8278 clear_message (1, 1);
8280 do_pending_window_change (0);
8281 echo_area_display (1);
8282 do_pending_window_change (0);
8283 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
8284 (*FRAME_TERMINAL (f
)->frame_up_to_date_hook
) (f
);
8289 /* Display an echo area message M with a specified length of NBYTES
8290 bytes. The string may include null characters. If M is not a
8291 string, clear out any existing message, and let the mini-buffer
8294 This function cancels echoing. */
8297 message3 (Lisp_Object m
, int nbytes
, int multibyte
)
8299 struct gcpro gcpro1
;
8302 clear_message (1,1);
8305 /* First flush out any partial line written with print. */
8306 message_log_maybe_newline ();
8312 SAFE_ALLOCA (buffer
, char *, nbytes
);
8313 memcpy (buffer
, SDATA (m
), nbytes
);
8314 message_dolog (buffer
, nbytes
, 1, multibyte
);
8317 message3_nolog (m
, nbytes
, multibyte
);
8323 /* The non-logging version of message3.
8324 This does not cancel echoing, because it is used for echoing.
8325 Perhaps we need to make a separate function for echoing
8326 and make this cancel echoing. */
8329 message3_nolog (Lisp_Object m
, int nbytes
, int multibyte
)
8331 struct frame
*sf
= SELECTED_FRAME ();
8332 message_enable_multibyte
= multibyte
;
8334 if (FRAME_INITIAL_P (sf
))
8336 if (noninteractive_need_newline
)
8337 putc ('\n', stderr
);
8338 noninteractive_need_newline
= 0;
8340 fwrite (SDATA (m
), nbytes
, 1, stderr
);
8341 if (cursor_in_echo_area
== 0)
8342 fprintf (stderr
, "\n");
8345 /* A null message buffer means that the frame hasn't really been
8346 initialized yet. Error messages get reported properly by
8347 cmd_error, so this must be just an informative message; toss it. */
8348 else if (INTERACTIVE
8349 && sf
->glyphs_initialized_p
8350 && FRAME_MESSAGE_BUF (sf
))
8352 Lisp_Object mini_window
;
8356 /* Get the frame containing the mini-buffer
8357 that the selected frame is using. */
8358 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8359 frame
= XWINDOW (mini_window
)->frame
;
8362 FRAME_SAMPLE_VISIBILITY (f
);
8363 if (FRAME_VISIBLE_P (sf
)
8364 && !FRAME_VISIBLE_P (f
))
8365 Fmake_frame_visible (frame
);
8367 if (STRINGP (m
) && SCHARS (m
) > 0)
8369 set_message (NULL
, m
, nbytes
, multibyte
);
8370 if (minibuffer_auto_raise
)
8371 Fraise_frame (frame
);
8372 /* Assume we are not echoing.
8373 (If we are, echo_now will override this.) */
8374 echo_message_buffer
= Qnil
;
8377 clear_message (1, 1);
8379 do_pending_window_change (0);
8380 echo_area_display (1);
8381 do_pending_window_change (0);
8382 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
8383 (*FRAME_TERMINAL (f
)->frame_up_to_date_hook
) (f
);
8388 /* Display a null-terminated echo area message M. If M is 0, clear
8389 out any existing message, and let the mini-buffer text show through.
8391 The buffer M must continue to exist until after the echo area gets
8392 cleared or some other message gets displayed there. Do not pass
8393 text that is stored in a Lisp string. Do not pass text in a buffer
8394 that was alloca'd. */
8397 message1 (const char *m
)
8399 message2 (m
, (m
? strlen (m
) : 0), 0);
8403 /* The non-logging counterpart of message1. */
8406 message1_nolog (const char *m
)
8408 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
8411 /* Display a message M which contains a single %s
8412 which gets replaced with STRING. */
8415 message_with_string (const char *m
, Lisp_Object string
, int log
)
8417 CHECK_STRING (string
);
8423 if (noninteractive_need_newline
)
8424 putc ('\n', stderr
);
8425 noninteractive_need_newline
= 0;
8426 fprintf (stderr
, m
, SDATA (string
));
8427 if (!cursor_in_echo_area
)
8428 fprintf (stderr
, "\n");
8432 else if (INTERACTIVE
)
8434 /* The frame whose minibuffer we're going to display the message on.
8435 It may be larger than the selected frame, so we need
8436 to use its buffer, not the selected frame's buffer. */
8437 Lisp_Object mini_window
;
8438 struct frame
*f
, *sf
= SELECTED_FRAME ();
8440 /* Get the frame containing the minibuffer
8441 that the selected frame is using. */
8442 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8443 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
8445 /* A null message buffer means that the frame hasn't really been
8446 initialized yet. Error messages get reported properly by
8447 cmd_error, so this must be just an informative message; toss it. */
8448 if (FRAME_MESSAGE_BUF (f
))
8450 Lisp_Object args
[2], message
;
8451 struct gcpro gcpro1
, gcpro2
;
8453 args
[0] = build_string (m
);
8454 args
[1] = message
= string
;
8455 GCPRO2 (args
[0], message
);
8458 message
= Fformat (2, args
);
8461 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
8463 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
8467 /* Print should start at the beginning of the message
8468 buffer next time. */
8469 message_buf_print
= 0;
8475 /* Dump an informative message to the minibuf. If M is 0, clear out
8476 any existing message, and let the mini-buffer text show through. */
8479 vmessage (const char *m
, va_list ap
)
8485 if (noninteractive_need_newline
)
8486 putc ('\n', stderr
);
8487 noninteractive_need_newline
= 0;
8488 vfprintf (stderr
, m
, ap
);
8489 if (cursor_in_echo_area
== 0)
8490 fprintf (stderr
, "\n");
8494 else if (INTERACTIVE
)
8496 /* The frame whose mini-buffer we're going to display the message
8497 on. It may be larger than the selected frame, so we need to
8498 use its buffer, not the selected frame's buffer. */
8499 Lisp_Object mini_window
;
8500 struct frame
*f
, *sf
= SELECTED_FRAME ();
8502 /* Get the frame containing the mini-buffer
8503 that the selected frame is using. */
8504 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8505 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
8507 /* A null message buffer means that the frame hasn't really been
8508 initialized yet. Error messages get reported properly by
8509 cmd_error, so this must be just an informative message; toss
8511 if (FRAME_MESSAGE_BUF (f
))
8517 len
= doprnt (FRAME_MESSAGE_BUF (f
),
8518 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, ap
);
8520 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
8525 /* Print should start at the beginning of the message
8526 buffer next time. */
8527 message_buf_print
= 0;
8533 message (const char *m
, ...)
8542 /* The non-logging version of message. */
8545 message_nolog (const char *m
, ...)
8547 Lisp_Object old_log_max
;
8550 old_log_max
= Vmessage_log_max
;
8551 Vmessage_log_max
= Qnil
;
8553 Vmessage_log_max
= old_log_max
;
8558 /* Display the current message in the current mini-buffer. This is
8559 only called from error handlers in process.c, and is not time
8563 update_echo_area (void)
8565 if (!NILP (echo_area_buffer
[0]))
8568 string
= Fcurrent_message ();
8569 message3 (string
, SBYTES (string
),
8570 !NILP (current_buffer
->enable_multibyte_characters
));
8575 /* Make sure echo area buffers in `echo_buffers' are live.
8576 If they aren't, make new ones. */
8579 ensure_echo_area_buffers (void)
8583 for (i
= 0; i
< 2; ++i
)
8584 if (!BUFFERP (echo_buffer
[i
])
8585 || NILP (XBUFFER (echo_buffer
[i
])->name
))
8588 Lisp_Object old_buffer
;
8591 old_buffer
= echo_buffer
[i
];
8592 sprintf (name
, " *Echo Area %d*", i
);
8593 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
8594 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
8595 /* to force word wrap in echo area -
8596 it was decided to postpone this*/
8597 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8599 for (j
= 0; j
< 2; ++j
)
8600 if (EQ (old_buffer
, echo_area_buffer
[j
]))
8601 echo_area_buffer
[j
] = echo_buffer
[i
];
8606 /* Call FN with args A1..A4 with either the current or last displayed
8607 echo_area_buffer as current buffer.
8609 WHICH zero means use the current message buffer
8610 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8611 from echo_buffer[] and clear it.
8613 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8614 suitable buffer from echo_buffer[] and clear it.
8616 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8617 that the current message becomes the last displayed one, make
8618 choose a suitable buffer for echo_area_buffer[0], and clear it.
8620 Value is what FN returns. */
8623 with_echo_area_buffer (struct window
*w
, int which
,
8624 int (*fn
) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
8625 EMACS_INT a1
, Lisp_Object a2
, EMACS_INT a3
, EMACS_INT a4
)
8628 int this_one
, the_other
, clear_buffer_p
, rc
;
8629 int count
= SPECPDL_INDEX ();
8631 /* If buffers aren't live, make new ones. */
8632 ensure_echo_area_buffers ();
8637 this_one
= 0, the_other
= 1;
8639 this_one
= 1, the_other
= 0;
8642 this_one
= 0, the_other
= 1;
8645 /* We need a fresh one in case the current echo buffer equals
8646 the one containing the last displayed echo area message. */
8647 if (!NILP (echo_area_buffer
[this_one
])
8648 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
8649 echo_area_buffer
[this_one
] = Qnil
;
8652 /* Choose a suitable buffer from echo_buffer[] is we don't
8654 if (NILP (echo_area_buffer
[this_one
]))
8656 echo_area_buffer
[this_one
]
8657 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
8658 ? echo_buffer
[the_other
]
8659 : echo_buffer
[this_one
]);
8663 buffer
= echo_area_buffer
[this_one
];
8665 /* Don't get confused by reusing the buffer used for echoing
8666 for a different purpose. */
8667 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
8670 record_unwind_protect (unwind_with_echo_area_buffer
,
8671 with_echo_area_buffer_unwind_data (w
));
8673 /* Make the echo area buffer current. Note that for display
8674 purposes, it is not necessary that the displayed window's buffer
8675 == current_buffer, except for text property lookup. So, let's
8676 only set that buffer temporarily here without doing a full
8677 Fset_window_buffer. We must also change w->pointm, though,
8678 because otherwise an assertions in unshow_buffer fails, and Emacs
8680 set_buffer_internal_1 (XBUFFER (buffer
));
8684 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
8687 current_buffer
->undo_list
= Qt
;
8688 current_buffer
->read_only
= Qnil
;
8689 specbind (Qinhibit_read_only
, Qt
);
8690 specbind (Qinhibit_modification_hooks
, Qt
);
8692 if (clear_buffer_p
&& Z
> BEG
)
8695 xassert (BEGV
>= BEG
);
8696 xassert (ZV
<= Z
&& ZV
>= BEGV
);
8698 rc
= fn (a1
, a2
, a3
, a4
);
8700 xassert (BEGV
>= BEG
);
8701 xassert (ZV
<= Z
&& ZV
>= BEGV
);
8703 unbind_to (count
, Qnil
);
8708 /* Save state that should be preserved around the call to the function
8709 FN called in with_echo_area_buffer. */
8712 with_echo_area_buffer_unwind_data (struct window
*w
)
8715 Lisp_Object vector
, tmp
;
8717 /* Reduce consing by keeping one vector in
8718 Vwith_echo_area_save_vector. */
8719 vector
= Vwith_echo_area_save_vector
;
8720 Vwith_echo_area_save_vector
= Qnil
;
8723 vector
= Fmake_vector (make_number (7), Qnil
);
8725 XSETBUFFER (tmp
, current_buffer
); ASET (vector
, i
, tmp
); ++i
;
8726 ASET (vector
, i
, Vdeactivate_mark
); ++i
;
8727 ASET (vector
, i
, make_number (windows_or_buffers_changed
)); ++i
;
8731 XSETWINDOW (tmp
, w
); ASET (vector
, i
, tmp
); ++i
;
8732 ASET (vector
, i
, w
->buffer
); ++i
;
8733 ASET (vector
, i
, make_number (XMARKER (w
->pointm
)->charpos
)); ++i
;
8734 ASET (vector
, i
, make_number (XMARKER (w
->pointm
)->bytepos
)); ++i
;
8739 for (; i
< end
; ++i
)
8740 ASET (vector
, i
, Qnil
);
8743 xassert (i
== ASIZE (vector
));
8748 /* Restore global state from VECTOR which was created by
8749 with_echo_area_buffer_unwind_data. */
8752 unwind_with_echo_area_buffer (Lisp_Object vector
)
8754 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
8755 Vdeactivate_mark
= AREF (vector
, 1);
8756 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
8758 if (WINDOWP (AREF (vector
, 3)))
8761 Lisp_Object buffer
, charpos
, bytepos
;
8763 w
= XWINDOW (AREF (vector
, 3));
8764 buffer
= AREF (vector
, 4);
8765 charpos
= AREF (vector
, 5);
8766 bytepos
= AREF (vector
, 6);
8769 set_marker_both (w
->pointm
, buffer
,
8770 XFASTINT (charpos
), XFASTINT (bytepos
));
8773 Vwith_echo_area_save_vector
= vector
;
8778 /* Set up the echo area for use by print functions. MULTIBYTE_P
8779 non-zero means we will print multibyte. */
8782 setup_echo_area_for_printing (int multibyte_p
)
8784 /* If we can't find an echo area any more, exit. */
8785 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
8788 ensure_echo_area_buffers ();
8790 if (!message_buf_print
)
8792 /* A message has been output since the last time we printed.
8793 Choose a fresh echo area buffer. */
8794 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
8795 echo_area_buffer
[0] = echo_buffer
[1];
8797 echo_area_buffer
[0] = echo_buffer
[0];
8799 /* Switch to that buffer and clear it. */
8800 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
8801 current_buffer
->truncate_lines
= Qnil
;
8805 int count
= SPECPDL_INDEX ();
8806 specbind (Qinhibit_read_only
, Qt
);
8807 /* Note that undo recording is always disabled. */
8809 unbind_to (count
, Qnil
);
8811 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
8813 /* Set up the buffer for the multibyteness we need. */
8815 != !NILP (current_buffer
->enable_multibyte_characters
))
8816 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
8818 /* Raise the frame containing the echo area. */
8819 if (minibuffer_auto_raise
)
8821 struct frame
*sf
= SELECTED_FRAME ();
8822 Lisp_Object mini_window
;
8823 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8824 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
8827 message_log_maybe_newline ();
8828 message_buf_print
= 1;
8832 if (NILP (echo_area_buffer
[0]))
8834 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
8835 echo_area_buffer
[0] = echo_buffer
[1];
8837 echo_area_buffer
[0] = echo_buffer
[0];
8840 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
8842 /* Someone switched buffers between print requests. */
8843 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
8844 current_buffer
->truncate_lines
= Qnil
;
8850 /* Display an echo area message in window W. Value is non-zero if W's
8851 height is changed. If display_last_displayed_message_p is
8852 non-zero, display the message that was last displayed, otherwise
8853 display the current message. */
8856 display_echo_area (struct window
*w
)
8858 int i
, no_message_p
, window_height_changed_p
, count
;
8860 /* Temporarily disable garbage collections while displaying the echo
8861 area. This is done because a GC can print a message itself.
8862 That message would modify the echo area buffer's contents while a
8863 redisplay of the buffer is going on, and seriously confuse
8865 count
= inhibit_garbage_collection ();
8867 /* If there is no message, we must call display_echo_area_1
8868 nevertheless because it resizes the window. But we will have to
8869 reset the echo_area_buffer in question to nil at the end because
8870 with_echo_area_buffer will sets it to an empty buffer. */
8871 i
= display_last_displayed_message_p
? 1 : 0;
8872 no_message_p
= NILP (echo_area_buffer
[i
]);
8874 window_height_changed_p
8875 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
8876 display_echo_area_1
,
8877 (EMACS_INT
) w
, Qnil
, 0, 0);
8880 echo_area_buffer
[i
] = Qnil
;
8882 unbind_to (count
, Qnil
);
8883 return window_height_changed_p
;
8887 /* Helper for display_echo_area. Display the current buffer which
8888 contains the current echo area message in window W, a mini-window,
8889 a pointer to which is passed in A1. A2..A4 are currently not used.
8890 Change the height of W so that all of the message is displayed.
8891 Value is non-zero if height of W was changed. */
8894 display_echo_area_1 (EMACS_INT a1
, Lisp_Object a2
, EMACS_INT a3
, EMACS_INT a4
)
8896 struct window
*w
= (struct window
*) a1
;
8898 struct text_pos start
;
8899 int window_height_changed_p
= 0;
8901 /* Do this before displaying, so that we have a large enough glyph
8902 matrix for the display. If we can't get enough space for the
8903 whole text, display the last N lines. That works by setting w->start. */
8904 window_height_changed_p
= resize_mini_window (w
, 0);
8906 /* Use the starting position chosen by resize_mini_window. */
8907 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
8910 clear_glyph_matrix (w
->desired_matrix
);
8911 XSETWINDOW (window
, w
);
8912 try_window (window
, start
, 0);
8914 return window_height_changed_p
;
8918 /* Resize the echo area window to exactly the size needed for the
8919 currently displayed message, if there is one. If a mini-buffer
8920 is active, don't shrink it. */
8923 resize_echo_area_exactly (void)
8925 if (BUFFERP (echo_area_buffer
[0])
8926 && WINDOWP (echo_area_window
))
8928 struct window
*w
= XWINDOW (echo_area_window
);
8930 Lisp_Object resize_exactly
;
8932 if (minibuf_level
== 0)
8933 resize_exactly
= Qt
;
8935 resize_exactly
= Qnil
;
8937 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
8938 (EMACS_INT
) w
, resize_exactly
, 0, 0);
8941 ++windows_or_buffers_changed
;
8942 ++update_mode_lines
;
8943 redisplay_internal (0);
8949 /* Callback function for with_echo_area_buffer, when used from
8950 resize_echo_area_exactly. A1 contains a pointer to the window to
8951 resize, EXACTLY non-nil means resize the mini-window exactly to the
8952 size of the text displayed. A3 and A4 are not used. Value is what
8953 resize_mini_window returns. */
8956 resize_mini_window_1 (EMACS_INT a1
, Lisp_Object exactly
, EMACS_INT a3
, EMACS_INT a4
)
8958 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
8962 /* Resize mini-window W to fit the size of its contents. EXACT_P
8963 means size the window exactly to the size needed. Otherwise, it's
8964 only enlarged until W's buffer is empty.
8966 Set W->start to the right place to begin display. If the whole
8967 contents fit, start at the beginning. Otherwise, start so as
8968 to make the end of the contents appear. This is particularly
8969 important for y-or-n-p, but seems desirable generally.
8971 Value is non-zero if the window height has been changed. */
8974 resize_mini_window (struct window
*w
, int exact_p
)
8976 struct frame
*f
= XFRAME (w
->frame
);
8977 int window_height_changed_p
= 0;
8979 xassert (MINI_WINDOW_P (w
));
8981 /* By default, start display at the beginning. */
8982 set_marker_both (w
->start
, w
->buffer
,
8983 BUF_BEGV (XBUFFER (w
->buffer
)),
8984 BUF_BEGV_BYTE (XBUFFER (w
->buffer
)));
8986 /* Don't resize windows while redisplaying a window; it would
8987 confuse redisplay functions when the size of the window they are
8988 displaying changes from under them. Such a resizing can happen,
8989 for instance, when which-func prints a long message while
8990 we are running fontification-functions. We're running these
8991 functions with safe_call which binds inhibit-redisplay to t. */
8992 if (!NILP (Vinhibit_redisplay
))
8995 /* Nil means don't try to resize. */
8996 if (NILP (Vresize_mini_windows
)
8997 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
9000 if (!FRAME_MINIBUF_ONLY_P (f
))
9003 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
9004 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
9005 int height
, max_height
;
9006 int unit
= FRAME_LINE_HEIGHT (f
);
9007 struct text_pos start
;
9008 struct buffer
*old_current_buffer
= NULL
;
9010 if (current_buffer
!= XBUFFER (w
->buffer
))
9012 old_current_buffer
= current_buffer
;
9013 set_buffer_internal (XBUFFER (w
->buffer
));
9016 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
9018 /* Compute the max. number of lines specified by the user. */
9019 if (FLOATP (Vmax_mini_window_height
))
9020 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
9021 else if (INTEGERP (Vmax_mini_window_height
))
9022 max_height
= XINT (Vmax_mini_window_height
);
9024 max_height
= total_height
/ 4;
9026 /* Correct that max. height if it's bogus. */
9027 max_height
= max (1, max_height
);
9028 max_height
= min (total_height
, max_height
);
9030 /* Find out the height of the text in the window. */
9031 if (it
.line_wrap
== TRUNCATE
)
9036 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
9037 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
9038 height
= it
.current_y
+ last_height
;
9040 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
9041 height
-= min (it
.extra_line_spacing
, it
.max_extra_line_spacing
);
9042 height
= (height
+ unit
- 1) / unit
;
9045 /* Compute a suitable window start. */
9046 if (height
> max_height
)
9048 height
= max_height
;
9049 init_iterator (&it
, w
, ZV
, ZV_BYTE
, NULL
, DEFAULT_FACE_ID
);
9050 move_it_vertically_backward (&it
, (height
- 1) * unit
);
9051 start
= it
.current
.pos
;
9054 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
9055 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
9057 if (EQ (Vresize_mini_windows
, Qgrow_only
))
9059 /* Let it grow only, until we display an empty message, in which
9060 case the window shrinks again. */
9061 if (height
> WINDOW_TOTAL_LINES (w
))
9063 int old_height
= WINDOW_TOTAL_LINES (w
);
9064 freeze_window_starts (f
, 1);
9065 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
9066 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
9068 else if (height
< WINDOW_TOTAL_LINES (w
)
9069 && (exact_p
|| BEGV
== ZV
))
9071 int old_height
= WINDOW_TOTAL_LINES (w
);
9072 freeze_window_starts (f
, 0);
9073 shrink_mini_window (w
);
9074 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
9079 /* Always resize to exact size needed. */
9080 if (height
> WINDOW_TOTAL_LINES (w
))
9082 int old_height
= WINDOW_TOTAL_LINES (w
);
9083 freeze_window_starts (f
, 1);
9084 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
9085 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
9087 else if (height
< WINDOW_TOTAL_LINES (w
))
9089 int old_height
= WINDOW_TOTAL_LINES (w
);
9090 freeze_window_starts (f
, 0);
9091 shrink_mini_window (w
);
9095 freeze_window_starts (f
, 1);
9096 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
9099 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
9103 if (old_current_buffer
)
9104 set_buffer_internal (old_current_buffer
);
9107 return window_height_changed_p
;
9111 /* Value is the current message, a string, or nil if there is no
9115 current_message (void)
9119 if (!BUFFERP (echo_area_buffer
[0]))
9123 with_echo_area_buffer (0, 0, current_message_1
,
9124 (EMACS_INT
) &msg
, Qnil
, 0, 0);
9126 echo_area_buffer
[0] = Qnil
;
9134 current_message_1 (EMACS_INT a1
, Lisp_Object a2
, EMACS_INT a3
, EMACS_INT a4
)
9136 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
9139 *msg
= make_buffer_string (BEG
, Z
, 1);
9146 /* Push the current message on Vmessage_stack for later restauration
9147 by restore_message. Value is non-zero if the current message isn't
9148 empty. This is a relatively infrequent operation, so it's not
9149 worth optimizing. */
9155 msg
= current_message ();
9156 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
9157 return STRINGP (msg
);
9161 /* Restore message display from the top of Vmessage_stack. */
9164 restore_message (void)
9168 xassert (CONSP (Vmessage_stack
));
9169 msg
= XCAR (Vmessage_stack
);
9171 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
9173 message3_nolog (msg
, 0, 0);
9177 /* Handler for record_unwind_protect calling pop_message. */
9180 pop_message_unwind (Lisp_Object dummy
)
9186 /* Pop the top-most entry off Vmessage_stack. */
9191 xassert (CONSP (Vmessage_stack
));
9192 Vmessage_stack
= XCDR (Vmessage_stack
);
9196 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9197 exits. If the stack is not empty, we have a missing pop_message
9201 check_message_stack (void)
9203 if (!NILP (Vmessage_stack
))
9208 /* Truncate to NCHARS what will be displayed in the echo area the next
9209 time we display it---but don't redisplay it now. */
9212 truncate_echo_area (int nchars
)
9215 echo_area_buffer
[0] = Qnil
;
9216 /* A null message buffer means that the frame hasn't really been
9217 initialized yet. Error messages get reported properly by
9218 cmd_error, so this must be just an informative message; toss it. */
9219 else if (!noninteractive
9221 && !NILP (echo_area_buffer
[0]))
9223 struct frame
*sf
= SELECTED_FRAME ();
9224 if (FRAME_MESSAGE_BUF (sf
))
9225 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
9230 /* Helper function for truncate_echo_area. Truncate the current
9231 message to at most NCHARS characters. */
9234 truncate_message_1 (EMACS_INT nchars
, Lisp_Object a2
, EMACS_INT a3
, EMACS_INT a4
)
9236 if (BEG
+ nchars
< Z
)
9237 del_range (BEG
+ nchars
, Z
);
9239 echo_area_buffer
[0] = Qnil
;
9244 /* Set the current message to a substring of S or STRING.
9246 If STRING is a Lisp string, set the message to the first NBYTES
9247 bytes from STRING. NBYTES zero means use the whole string. If
9248 STRING is multibyte, the message will be displayed multibyte.
9250 If S is not null, set the message to the first LEN bytes of S. LEN
9251 zero means use the whole string. MULTIBYTE_P non-zero means S is
9252 multibyte. Display the message multibyte in that case.
9254 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9255 to t before calling set_message_1 (which calls insert).
9259 set_message (const char *s
, Lisp_Object string
, int nbytes
, int multibyte_p
)
9261 message_enable_multibyte
9262 = ((s
&& multibyte_p
)
9263 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
9265 with_echo_area_buffer (0, -1, set_message_1
,
9266 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
9267 message_buf_print
= 0;
9268 help_echo_showing_p
= 0;
9272 /* Helper function for set_message. Arguments have the same meaning
9273 as there, with A1 corresponding to S and A2 corresponding to STRING
9274 This function is called with the echo area buffer being
9278 set_message_1 (EMACS_INT a1
, Lisp_Object a2
, EMACS_INT nbytes
, EMACS_INT multibyte_p
)
9280 const char *s
= (const char *) a1
;
9281 Lisp_Object string
= a2
;
9283 /* Change multibyteness of the echo buffer appropriately. */
9284 if (message_enable_multibyte
9285 != !NILP (current_buffer
->enable_multibyte_characters
))
9286 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
9288 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
9290 /* Insert new message at BEG. */
9291 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
9293 if (STRINGP (string
))
9298 nbytes
= SBYTES (string
);
9299 nchars
= string_byte_to_char (string
, nbytes
);
9301 /* This function takes care of single/multibyte conversion. We
9302 just have to ensure that the echo area buffer has the right
9303 setting of enable_multibyte_characters. */
9304 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
9309 nbytes
= strlen (s
);
9311 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
9313 /* Convert from multi-byte to single-byte. */
9315 unsigned char work
[1];
9317 /* Convert a multibyte string to single-byte. */
9318 for (i
= 0; i
< nbytes
; i
+= n
)
9320 c
= string_char_and_length (s
+ i
, &n
);
9321 work
[0] = (ASCII_CHAR_P (c
)
9323 : multibyte_char_to_unibyte (c
, Qnil
));
9324 insert_1_both (work
, 1, 1, 1, 0, 0);
9327 else if (!multibyte_p
9328 && !NILP (current_buffer
->enable_multibyte_characters
))
9330 /* Convert from single-byte to multi-byte. */
9332 const unsigned char *msg
= (const unsigned char *) s
;
9333 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
9335 /* Convert a single-byte string to multibyte. */
9336 for (i
= 0; i
< nbytes
; i
++)
9339 MAKE_CHAR_MULTIBYTE (c
);
9340 n
= CHAR_STRING (c
, str
);
9341 insert_1_both (str
, 1, n
, 1, 0, 0);
9345 insert_1 (s
, nbytes
, 1, 0, 0);
9352 /* Clear messages. CURRENT_P non-zero means clear the current
9353 message. LAST_DISPLAYED_P non-zero means clear the message
9357 clear_message (int current_p
, int last_displayed_p
)
9361 echo_area_buffer
[0] = Qnil
;
9362 message_cleared_p
= 1;
9365 if (last_displayed_p
)
9366 echo_area_buffer
[1] = Qnil
;
9368 message_buf_print
= 0;
9371 /* Clear garbaged frames.
9373 This function is used where the old redisplay called
9374 redraw_garbaged_frames which in turn called redraw_frame which in
9375 turn called clear_frame. The call to clear_frame was a source of
9376 flickering. I believe a clear_frame is not necessary. It should
9377 suffice in the new redisplay to invalidate all current matrices,
9378 and ensure a complete redisplay of all windows. */
9381 clear_garbaged_frames (void)
9385 Lisp_Object tail
, frame
;
9386 int changed_count
= 0;
9388 FOR_EACH_FRAME (tail
, frame
)
9390 struct frame
*f
= XFRAME (frame
);
9392 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
9396 Fredraw_frame (frame
);
9397 f
->force_flush_display_p
= 1;
9399 clear_current_matrices (f
);
9408 ++windows_or_buffers_changed
;
9413 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9414 is non-zero update selected_frame. Value is non-zero if the
9415 mini-windows height has been changed. */
9418 echo_area_display (int update_frame_p
)
9420 Lisp_Object mini_window
;
9423 int window_height_changed_p
= 0;
9424 struct frame
*sf
= SELECTED_FRAME ();
9426 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9427 w
= XWINDOW (mini_window
);
9428 f
= XFRAME (WINDOW_FRAME (w
));
9430 /* Don't display if frame is invisible or not yet initialized. */
9431 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
9434 #ifdef HAVE_WINDOW_SYSTEM
9435 /* When Emacs starts, selected_frame may be the initial terminal
9436 frame. If we let this through, a message would be displayed on
9438 if (FRAME_INITIAL_P (XFRAME (selected_frame
)))
9440 #endif /* HAVE_WINDOW_SYSTEM */
9442 /* Redraw garbaged frames. */
9444 clear_garbaged_frames ();
9446 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
9448 echo_area_window
= mini_window
;
9449 window_height_changed_p
= display_echo_area (w
);
9450 w
->must_be_updated_p
= 1;
9452 /* Update the display, unless called from redisplay_internal.
9453 Also don't update the screen during redisplay itself. The
9454 update will happen at the end of redisplay, and an update
9455 here could cause confusion. */
9456 if (update_frame_p
&& !redisplaying_p
)
9460 /* If the display update has been interrupted by pending
9461 input, update mode lines in the frame. Due to the
9462 pending input, it might have been that redisplay hasn't
9463 been called, so that mode lines above the echo area are
9464 garbaged. This looks odd, so we prevent it here. */
9465 if (!display_completed
)
9466 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
9468 if (window_height_changed_p
9469 /* Don't do this if Emacs is shutting down. Redisplay
9470 needs to run hooks. */
9471 && !NILP (Vrun_hooks
))
9473 /* Must update other windows. Likewise as in other
9474 cases, don't let this update be interrupted by
9476 int count
= SPECPDL_INDEX ();
9477 specbind (Qredisplay_dont_pause
, Qt
);
9478 windows_or_buffers_changed
= 1;
9479 redisplay_internal (0);
9480 unbind_to (count
, Qnil
);
9482 else if (FRAME_WINDOW_P (f
) && n
== 0)
9484 /* Window configuration is the same as before.
9485 Can do with a display update of the echo area,
9486 unless we displayed some mode lines. */
9487 update_single_window (w
, 1);
9488 FRAME_RIF (f
)->flush_display (f
);
9491 update_frame (f
, 1, 1);
9493 /* If cursor is in the echo area, make sure that the next
9494 redisplay displays the minibuffer, so that the cursor will
9495 be replaced with what the minibuffer wants. */
9496 if (cursor_in_echo_area
)
9497 ++windows_or_buffers_changed
;
9500 else if (!EQ (mini_window
, selected_window
))
9501 windows_or_buffers_changed
++;
9503 /* Last displayed message is now the current message. */
9504 echo_area_buffer
[1] = echo_area_buffer
[0];
9505 /* Inform read_char that we're not echoing. */
9506 echo_message_buffer
= Qnil
;
9508 /* Prevent redisplay optimization in redisplay_internal by resetting
9509 this_line_start_pos. This is done because the mini-buffer now
9510 displays the message instead of its buffer text. */
9511 if (EQ (mini_window
, selected_window
))
9512 CHARPOS (this_line_start_pos
) = 0;
9514 return window_height_changed_p
;
9519 /***********************************************************************
9520 Mode Lines and Frame Titles
9521 ***********************************************************************/
9523 /* A buffer for constructing non-propertized mode-line strings and
9524 frame titles in it; allocated from the heap in init_xdisp and
9525 resized as needed in store_mode_line_noprop_char. */
9527 static char *mode_line_noprop_buf
;
9529 /* The buffer's end, and a current output position in it. */
9531 static char *mode_line_noprop_buf_end
;
9532 static char *mode_line_noprop_ptr
;
9534 #define MODE_LINE_NOPROP_LEN(start) \
9535 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9538 MODE_LINE_DISPLAY
= 0,
9544 /* Alist that caches the results of :propertize.
9545 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9546 static Lisp_Object mode_line_proptrans_alist
;
9548 /* List of strings making up the mode-line. */
9549 static Lisp_Object mode_line_string_list
;
9551 /* Base face property when building propertized mode line string. */
9552 static Lisp_Object mode_line_string_face
;
9553 static Lisp_Object mode_line_string_face_prop
;
9556 /* Unwind data for mode line strings */
9558 static Lisp_Object Vmode_line_unwind_vector
;
9561 format_mode_line_unwind_data (struct buffer
*obuf
,
9565 Lisp_Object vector
, tmp
;
9567 /* Reduce consing by keeping one vector in
9568 Vwith_echo_area_save_vector. */
9569 vector
= Vmode_line_unwind_vector
;
9570 Vmode_line_unwind_vector
= Qnil
;
9573 vector
= Fmake_vector (make_number (8), Qnil
);
9575 ASET (vector
, 0, make_number (mode_line_target
));
9576 ASET (vector
, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9577 ASET (vector
, 2, mode_line_string_list
);
9578 ASET (vector
, 3, save_proptrans
? mode_line_proptrans_alist
: Qt
);
9579 ASET (vector
, 4, mode_line_string_face
);
9580 ASET (vector
, 5, mode_line_string_face_prop
);
9583 XSETBUFFER (tmp
, obuf
);
9586 ASET (vector
, 6, tmp
);
9587 ASET (vector
, 7, owin
);
9593 unwind_format_mode_line (Lisp_Object vector
)
9595 mode_line_target
= XINT (AREF (vector
, 0));
9596 mode_line_noprop_ptr
= mode_line_noprop_buf
+ XINT (AREF (vector
, 1));
9597 mode_line_string_list
= AREF (vector
, 2);
9598 if (! EQ (AREF (vector
, 3), Qt
))
9599 mode_line_proptrans_alist
= AREF (vector
, 3);
9600 mode_line_string_face
= AREF (vector
, 4);
9601 mode_line_string_face_prop
= AREF (vector
, 5);
9603 if (!NILP (AREF (vector
, 7)))
9604 /* Select window before buffer, since it may change the buffer. */
9605 Fselect_window (AREF (vector
, 7), Qt
);
9607 if (!NILP (AREF (vector
, 6)))
9609 set_buffer_internal_1 (XBUFFER (AREF (vector
, 6)));
9610 ASET (vector
, 6, Qnil
);
9613 Vmode_line_unwind_vector
= vector
;
9618 /* Store a single character C for the frame title in mode_line_noprop_buf.
9619 Re-allocate mode_line_noprop_buf if necessary. */
9622 store_mode_line_noprop_char (char c
)
9624 /* If output position has reached the end of the allocated buffer,
9625 double the buffer's size. */
9626 if (mode_line_noprop_ptr
== mode_line_noprop_buf_end
)
9628 int len
= MODE_LINE_NOPROP_LEN (0);
9629 int new_size
= 2 * len
* sizeof *mode_line_noprop_buf
;
9630 mode_line_noprop_buf
= (char *) xrealloc (mode_line_noprop_buf
, new_size
);
9631 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ new_size
;
9632 mode_line_noprop_ptr
= mode_line_noprop_buf
+ len
;
9635 *mode_line_noprop_ptr
++ = c
;
9639 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9640 mode_line_noprop_ptr. STR is the string to store. Do not copy
9641 characters that yield more columns than PRECISION; PRECISION <= 0
9642 means copy the whole string. Pad with spaces until FIELD_WIDTH
9643 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9644 pad. Called from display_mode_element when it is used to build a
9648 store_mode_line_noprop (const unsigned char *str
, int field_width
, int precision
)
9653 /* Copy at most PRECISION chars from STR. */
9654 nbytes
= strlen (str
);
9655 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
9657 store_mode_line_noprop_char (*str
++);
9659 /* Fill up with spaces until FIELD_WIDTH reached. */
9660 while (field_width
> 0
9663 store_mode_line_noprop_char (' ');
9670 /***********************************************************************
9672 ***********************************************************************/
9674 #ifdef HAVE_WINDOW_SYSTEM
9676 /* Set the title of FRAME, if it has changed. The title format is
9677 Vicon_title_format if FRAME is iconified, otherwise it is
9678 frame_title_format. */
9681 x_consider_frame_title (Lisp_Object frame
)
9683 struct frame
*f
= XFRAME (frame
);
9685 if (FRAME_WINDOW_P (f
)
9686 || FRAME_MINIBUF_ONLY_P (f
)
9687 || f
->explicit_name
)
9689 /* Do we have more than one visible frame on this X display? */
9696 int count
= SPECPDL_INDEX ();
9698 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
9700 Lisp_Object other_frame
= XCAR (tail
);
9701 struct frame
*tf
= XFRAME (other_frame
);
9704 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
9705 && !FRAME_MINIBUF_ONLY_P (tf
)
9706 && !EQ (other_frame
, tip_frame
)
9707 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
9711 /* Set global variable indicating that multiple frames exist. */
9712 multiple_frames
= CONSP (tail
);
9714 /* Switch to the buffer of selected window of the frame. Set up
9715 mode_line_target so that display_mode_element will output into
9716 mode_line_noprop_buf; then display the title. */
9717 record_unwind_protect (unwind_format_mode_line
,
9718 format_mode_line_unwind_data
9719 (current_buffer
, selected_window
, 0));
9721 Fselect_window (f
->selected_window
, Qt
);
9722 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
9723 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
9725 mode_line_target
= MODE_LINE_TITLE
;
9726 title_start
= MODE_LINE_NOPROP_LEN (0);
9727 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
9728 NULL
, DEFAULT_FACE_ID
);
9729 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
9730 len
= MODE_LINE_NOPROP_LEN (title_start
);
9731 title
= mode_line_noprop_buf
+ title_start
;
9732 unbind_to (count
, Qnil
);
9734 /* Set the title only if it's changed. This avoids consing in
9735 the common case where it hasn't. (If it turns out that we've
9736 already wasted too much time by walking through the list with
9737 display_mode_element, then we might need to optimize at a
9738 higher level than this.) */
9739 if (! STRINGP (f
->name
)
9740 || SBYTES (f
->name
) != len
9741 || memcmp (title
, SDATA (f
->name
), len
) != 0)
9742 x_implicitly_set_name (f
, make_string (title
, len
), Qnil
);
9746 #endif /* not HAVE_WINDOW_SYSTEM */
9751 /***********************************************************************
9753 ***********************************************************************/
9756 /* Prepare for redisplay by updating menu-bar item lists when
9757 appropriate. This can call eval. */
9760 prepare_menu_bars (void)
9763 struct gcpro gcpro1
, gcpro2
;
9765 Lisp_Object tooltip_frame
;
9767 #ifdef HAVE_WINDOW_SYSTEM
9768 tooltip_frame
= tip_frame
;
9770 tooltip_frame
= Qnil
;
9773 /* Update all frame titles based on their buffer names, etc. We do
9774 this before the menu bars so that the buffer-menu will show the
9775 up-to-date frame titles. */
9776 #ifdef HAVE_WINDOW_SYSTEM
9777 if (windows_or_buffers_changed
|| update_mode_lines
)
9779 Lisp_Object tail
, frame
;
9781 FOR_EACH_FRAME (tail
, frame
)
9784 if (!EQ (frame
, tooltip_frame
)
9785 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
9786 x_consider_frame_title (frame
);
9789 #endif /* HAVE_WINDOW_SYSTEM */
9791 /* Update the menu bar item lists, if appropriate. This has to be
9792 done before any actual redisplay or generation of display lines. */
9793 all_windows
= (update_mode_lines
9794 || buffer_shared
> 1
9795 || windows_or_buffers_changed
);
9798 Lisp_Object tail
, frame
;
9799 int count
= SPECPDL_INDEX ();
9800 /* 1 means that update_menu_bar has run its hooks
9801 so any further calls to update_menu_bar shouldn't do so again. */
9802 int menu_bar_hooks_run
= 0;
9804 record_unwind_save_match_data ();
9806 FOR_EACH_FRAME (tail
, frame
)
9810 /* Ignore tooltip frame. */
9811 if (EQ (frame
, tooltip_frame
))
9814 /* If a window on this frame changed size, report that to
9815 the user and clear the size-change flag. */
9816 if (FRAME_WINDOW_SIZES_CHANGED (f
))
9818 Lisp_Object functions
;
9820 /* Clear flag first in case we get an error below. */
9821 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
9822 functions
= Vwindow_size_change_functions
;
9823 GCPRO2 (tail
, functions
);
9825 while (CONSP (functions
))
9827 if (!EQ (XCAR (functions
), Qt
))
9828 call1 (XCAR (functions
), frame
);
9829 functions
= XCDR (functions
);
9835 menu_bar_hooks_run
= update_menu_bar (f
, 0, menu_bar_hooks_run
);
9836 #ifdef HAVE_WINDOW_SYSTEM
9837 update_tool_bar (f
, 0);
9840 if (windows_or_buffers_changed
9842 ns_set_doc_edited (f
, Fbuffer_modified_p
9843 (XWINDOW (f
->selected_window
)->buffer
));
9848 unbind_to (count
, Qnil
);
9852 struct frame
*sf
= SELECTED_FRAME ();
9853 update_menu_bar (sf
, 1, 0);
9854 #ifdef HAVE_WINDOW_SYSTEM
9855 update_tool_bar (sf
, 1);
9861 /* Update the menu bar item list for frame F. This has to be done
9862 before we start to fill in any display lines, because it can call
9865 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9867 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9868 already ran the menu bar hooks for this redisplay, so there
9869 is no need to run them again. The return value is the
9870 updated value of this flag, to pass to the next call. */
9873 update_menu_bar (struct frame
*f
, int save_match_data
, int hooks_run
)
9876 register struct window
*w
;
9878 /* If called recursively during a menu update, do nothing. This can
9879 happen when, for instance, an activate-menubar-hook causes a
9881 if (inhibit_menubar_update
)
9884 window
= FRAME_SELECTED_WINDOW (f
);
9885 w
= XWINDOW (window
);
9887 if (FRAME_WINDOW_P (f
)
9889 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9890 || defined (HAVE_NS) || defined (USE_GTK)
9891 FRAME_EXTERNAL_MENU_BAR (f
)
9893 FRAME_MENU_BAR_LINES (f
) > 0
9895 : FRAME_MENU_BAR_LINES (f
) > 0)
9897 /* If the user has switched buffers or windows, we need to
9898 recompute to reflect the new bindings. But we'll
9899 recompute when update_mode_lines is set too; that means
9900 that people can use force-mode-line-update to request
9901 that the menu bar be recomputed. The adverse effect on
9902 the rest of the redisplay algorithm is about the same as
9903 windows_or_buffers_changed anyway. */
9904 if (windows_or_buffers_changed
9905 /* This used to test w->update_mode_line, but we believe
9906 there is no need to recompute the menu in that case. */
9907 || update_mode_lines
9908 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
9909 < BUF_MODIFF (XBUFFER (w
->buffer
)))
9910 != !NILP (w
->last_had_star
))
9911 || ((!NILP (Vtransient_mark_mode
)
9912 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9913 != !NILP (w
->region_showing
)))
9915 struct buffer
*prev
= current_buffer
;
9916 int count
= SPECPDL_INDEX ();
9918 specbind (Qinhibit_menubar_update
, Qt
);
9920 set_buffer_internal_1 (XBUFFER (w
->buffer
));
9921 if (save_match_data
)
9922 record_unwind_save_match_data ();
9923 if (NILP (Voverriding_local_map_menu_flag
))
9925 specbind (Qoverriding_terminal_local_map
, Qnil
);
9926 specbind (Qoverriding_local_map
, Qnil
);
9931 /* Run the Lucid hook. */
9932 safe_run_hooks (Qactivate_menubar_hook
);
9934 /* If it has changed current-menubar from previous value,
9935 really recompute the menu-bar from the value. */
9936 if (! NILP (Vlucid_menu_bar_dirty_flag
))
9937 call0 (Qrecompute_lucid_menubar
);
9939 safe_run_hooks (Qmenu_bar_update_hook
);
9944 XSETFRAME (Vmenu_updating_frame
, f
);
9945 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
9947 /* Redisplay the menu bar in case we changed it. */
9948 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9949 || defined (HAVE_NS) || defined (USE_GTK)
9950 if (FRAME_WINDOW_P (f
))
9952 #if defined (HAVE_NS)
9953 /* All frames on Mac OS share the same menubar. So only
9954 the selected frame should be allowed to set it. */
9955 if (f
== SELECTED_FRAME ())
9957 set_frame_menubar (f
, 0, 0);
9960 /* On a terminal screen, the menu bar is an ordinary screen
9961 line, and this makes it get updated. */
9962 w
->update_mode_line
= Qt
;
9963 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9964 /* In the non-toolkit version, the menu bar is an ordinary screen
9965 line, and this makes it get updated. */
9966 w
->update_mode_line
= Qt
;
9967 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9969 unbind_to (count
, Qnil
);
9970 set_buffer_internal_1 (prev
);
9979 /***********************************************************************
9981 ***********************************************************************/
9983 #ifdef HAVE_WINDOW_SYSTEM
9986 Nominal cursor position -- where to draw output.
9987 HPOS and VPOS are window relative glyph matrix coordinates.
9988 X and Y are window relative pixel coordinates. */
9990 struct cursor_pos output_cursor
;
9994 Set the global variable output_cursor to CURSOR. All cursor
9995 positions are relative to updated_window. */
9998 set_output_cursor (struct cursor_pos
*cursor
)
10000 output_cursor
.hpos
= cursor
->hpos
;
10001 output_cursor
.vpos
= cursor
->vpos
;
10002 output_cursor
.x
= cursor
->x
;
10003 output_cursor
.y
= cursor
->y
;
10008 Set a nominal cursor position.
10010 HPOS and VPOS are column/row positions in a window glyph matrix. X
10011 and Y are window text area relative pixel positions.
10013 If this is done during an update, updated_window will contain the
10014 window that is being updated and the position is the future output
10015 cursor position for that window. If updated_window is null, use
10016 selected_window and display the cursor at the given position. */
10019 x_cursor_to (int vpos
, int hpos
, int y
, int x
)
10023 /* If updated_window is not set, work on selected_window. */
10024 if (updated_window
)
10025 w
= updated_window
;
10027 w
= XWINDOW (selected_window
);
10029 /* Set the output cursor. */
10030 output_cursor
.hpos
= hpos
;
10031 output_cursor
.vpos
= vpos
;
10032 output_cursor
.x
= x
;
10033 output_cursor
.y
= y
;
10035 /* If not called as part of an update, really display the cursor.
10036 This will also set the cursor position of W. */
10037 if (updated_window
== NULL
)
10040 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
10041 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional
)
10042 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10047 #endif /* HAVE_WINDOW_SYSTEM */
10050 /***********************************************************************
10052 ***********************************************************************/
10054 #ifdef HAVE_WINDOW_SYSTEM
10056 /* Where the mouse was last time we reported a mouse event. */
10058 FRAME_PTR last_mouse_frame
;
10060 /* Tool-bar item index of the item on which a mouse button was pressed
10063 int last_tool_bar_item
;
10067 update_tool_bar_unwind (Lisp_Object frame
)
10069 selected_frame
= frame
;
10073 /* Update the tool-bar item list for frame F. This has to be done
10074 before we start to fill in any display lines. Called from
10075 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10076 and restore it here. */
10079 update_tool_bar (struct frame
*f
, int save_match_data
)
10081 #if defined (USE_GTK) || defined (HAVE_NS)
10082 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
10084 int do_update
= WINDOWP (f
->tool_bar_window
)
10085 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
10090 Lisp_Object window
;
10093 window
= FRAME_SELECTED_WINDOW (f
);
10094 w
= XWINDOW (window
);
10096 /* If the user has switched buffers or windows, we need to
10097 recompute to reflect the new bindings. But we'll
10098 recompute when update_mode_lines is set too; that means
10099 that people can use force-mode-line-update to request
10100 that the menu bar be recomputed. The adverse effect on
10101 the rest of the redisplay algorithm is about the same as
10102 windows_or_buffers_changed anyway. */
10103 if (windows_or_buffers_changed
10104 || !NILP (w
->update_mode_line
)
10105 || update_mode_lines
10106 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
10107 < BUF_MODIFF (XBUFFER (w
->buffer
)))
10108 != !NILP (w
->last_had_star
))
10109 || ((!NILP (Vtransient_mark_mode
)
10110 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
10111 != !NILP (w
->region_showing
)))
10113 struct buffer
*prev
= current_buffer
;
10114 int count
= SPECPDL_INDEX ();
10115 Lisp_Object frame
, new_tool_bar
;
10116 int new_n_tool_bar
;
10117 struct gcpro gcpro1
;
10119 /* Set current_buffer to the buffer of the selected
10120 window of the frame, so that we get the right local
10122 set_buffer_internal_1 (XBUFFER (w
->buffer
));
10124 /* Save match data, if we must. */
10125 if (save_match_data
)
10126 record_unwind_save_match_data ();
10128 /* Make sure that we don't accidentally use bogus keymaps. */
10129 if (NILP (Voverriding_local_map_menu_flag
))
10131 specbind (Qoverriding_terminal_local_map
, Qnil
);
10132 specbind (Qoverriding_local_map
, Qnil
);
10135 GCPRO1 (new_tool_bar
);
10137 /* We must temporarily set the selected frame to this frame
10138 before calling tool_bar_items, because the calculation of
10139 the tool-bar keymap uses the selected frame (see
10140 `tool-bar-make-keymap' in tool-bar.el). */
10141 record_unwind_protect (update_tool_bar_unwind
, selected_frame
);
10142 XSETFRAME (frame
, f
);
10143 selected_frame
= frame
;
10145 /* Build desired tool-bar items from keymaps. */
10146 new_tool_bar
= tool_bar_items (Fcopy_sequence (f
->tool_bar_items
),
10149 /* Redisplay the tool-bar if we changed it. */
10150 if (new_n_tool_bar
!= f
->n_tool_bar_items
10151 || NILP (Fequal (new_tool_bar
, f
->tool_bar_items
)))
10153 /* Redisplay that happens asynchronously due to an expose event
10154 may access f->tool_bar_items. Make sure we update both
10155 variables within BLOCK_INPUT so no such event interrupts. */
10157 f
->tool_bar_items
= new_tool_bar
;
10158 f
->n_tool_bar_items
= new_n_tool_bar
;
10159 w
->update_mode_line
= Qt
;
10165 unbind_to (count
, Qnil
);
10166 set_buffer_internal_1 (prev
);
10172 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10173 F's desired tool-bar contents. F->tool_bar_items must have
10174 been set up previously by calling prepare_menu_bars. */
10177 build_desired_tool_bar_string (struct frame
*f
)
10179 int i
, size
, size_needed
;
10180 struct gcpro gcpro1
, gcpro2
, gcpro3
;
10181 Lisp_Object image
, plist
, props
;
10183 image
= plist
= props
= Qnil
;
10184 GCPRO3 (image
, plist
, props
);
10186 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10187 Otherwise, make a new string. */
10189 /* The size of the string we might be able to reuse. */
10190 size
= (STRINGP (f
->desired_tool_bar_string
)
10191 ? SCHARS (f
->desired_tool_bar_string
)
10194 /* We need one space in the string for each image. */
10195 size_needed
= f
->n_tool_bar_items
;
10197 /* Reuse f->desired_tool_bar_string, if possible. */
10198 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
10199 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
10200 make_number (' '));
10203 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
10204 Fremove_text_properties (make_number (0), make_number (size
),
10205 props
, f
->desired_tool_bar_string
);
10208 /* Put a `display' property on the string for the images to display,
10209 put a `menu_item' property on tool-bar items with a value that
10210 is the index of the item in F's tool-bar item vector. */
10211 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
10213 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10215 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
10216 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
10217 int hmargin
, vmargin
, relief
, idx
, end
;
10219 /* If image is a vector, choose the image according to the
10221 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
10222 if (VECTORP (image
))
10226 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10227 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
10230 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10231 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
10233 xassert (ASIZE (image
) >= idx
);
10234 image
= AREF (image
, idx
);
10239 /* Ignore invalid image specifications. */
10240 if (!valid_image_p (image
))
10243 /* Display the tool-bar button pressed, or depressed. */
10244 plist
= Fcopy_sequence (XCDR (image
));
10246 /* Compute margin and relief to draw. */
10247 relief
= (tool_bar_button_relief
>= 0
10248 ? tool_bar_button_relief
10249 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
10250 hmargin
= vmargin
= relief
;
10252 if (INTEGERP (Vtool_bar_button_margin
)
10253 && XINT (Vtool_bar_button_margin
) > 0)
10255 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
10256 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
10258 else if (CONSP (Vtool_bar_button_margin
))
10260 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
10261 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
10262 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
10264 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
10265 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
10266 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
10269 if (auto_raise_tool_bar_buttons_p
)
10271 /* Add a `:relief' property to the image spec if the item is
10275 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
10282 /* If image is selected, display it pressed, i.e. with a
10283 negative relief. If it's not selected, display it with a
10285 plist
= Fplist_put (plist
, QCrelief
,
10287 ? make_number (-relief
)
10288 : make_number (relief
)));
10293 /* Put a margin around the image. */
10294 if (hmargin
|| vmargin
)
10296 if (hmargin
== vmargin
)
10297 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
10299 plist
= Fplist_put (plist
, QCmargin
,
10300 Fcons (make_number (hmargin
),
10301 make_number (vmargin
)));
10304 /* If button is not enabled, and we don't have special images
10305 for the disabled state, make the image appear disabled by
10306 applying an appropriate algorithm to it. */
10307 if (!enabled_p
&& idx
< 0)
10308 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
10310 /* Put a `display' text property on the string for the image to
10311 display. Put a `menu-item' property on the string that gives
10312 the start of this item's properties in the tool-bar items
10314 image
= Fcons (Qimage
, plist
);
10315 props
= list4 (Qdisplay
, image
,
10316 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
10318 /* Let the last image hide all remaining spaces in the tool bar
10319 string. The string can be longer than needed when we reuse a
10320 previous string. */
10321 if (i
+ 1 == f
->n_tool_bar_items
)
10322 end
= SCHARS (f
->desired_tool_bar_string
);
10325 Fadd_text_properties (make_number (i
), make_number (end
),
10326 props
, f
->desired_tool_bar_string
);
10334 /* Display one line of the tool-bar of frame IT->f.
10336 HEIGHT specifies the desired height of the tool-bar line.
10337 If the actual height of the glyph row is less than HEIGHT, the
10338 row's height is increased to HEIGHT, and the icons are centered
10339 vertically in the new height.
10341 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10342 count a final empty row in case the tool-bar width exactly matches
10347 display_tool_bar_line (struct it
*it
, int height
)
10349 struct glyph_row
*row
= it
->glyph_row
;
10350 int max_x
= it
->last_visible_x
;
10351 struct glyph
*last
;
10353 prepare_desired_row (row
);
10354 row
->y
= it
->current_y
;
10356 /* Note that this isn't made use of if the face hasn't a box,
10357 so there's no need to check the face here. */
10358 it
->start_of_box_run_p
= 1;
10360 while (it
->current_x
< max_x
)
10362 int x
, n_glyphs_before
, i
, nglyphs
;
10363 struct it it_before
;
10365 /* Get the next display element. */
10366 if (!get_next_display_element (it
))
10368 /* Don't count empty row if we are counting needed tool-bar lines. */
10369 if (height
< 0 && !it
->hpos
)
10374 /* Produce glyphs. */
10375 n_glyphs_before
= row
->used
[TEXT_AREA
];
10378 PRODUCE_GLYPHS (it
);
10380 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
10382 x
= it_before
.current_x
;
10383 while (i
< nglyphs
)
10385 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
10387 if (x
+ glyph
->pixel_width
> max_x
)
10389 /* Glyph doesn't fit on line. Backtrack. */
10390 row
->used
[TEXT_AREA
] = n_glyphs_before
;
10392 /* If this is the only glyph on this line, it will never fit on the
10393 toolbar, so skip it. But ensure there is at least one glyph,
10394 so we don't accidentally disable the tool-bar. */
10395 if (n_glyphs_before
== 0
10396 && (it
->vpos
> 0 || IT_STRING_CHARPOS (*it
) < it
->end_charpos
-1))
10402 x
+= glyph
->pixel_width
;
10406 /* Stop at line ends. */
10407 if (ITERATOR_AT_END_OF_LINE_P (it
))
10410 set_iterator_to_next (it
, 1);
10415 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
10417 /* Use default face for the border below the tool bar.
10419 FIXME: When auto-resize-tool-bars is grow-only, there is
10420 no additional border below the possibly empty tool-bar lines.
10421 So to make the extra empty lines look "normal", we have to
10422 use the tool-bar face for the border too. */
10423 if (!row
->displays_text_p
&& !EQ (Vauto_resize_tool_bars
, Qgrow_only
))
10424 it
->face_id
= DEFAULT_FACE_ID
;
10426 extend_face_to_end_of_line (it
);
10427 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
10428 last
->right_box_line_p
= 1;
10429 if (last
== row
->glyphs
[TEXT_AREA
])
10430 last
->left_box_line_p
= 1;
10432 /* Make line the desired height and center it vertically. */
10433 if ((height
-= it
->max_ascent
+ it
->max_descent
) > 0)
10435 /* Don't add more than one line height. */
10436 height
%= FRAME_LINE_HEIGHT (it
->f
);
10437 it
->max_ascent
+= height
/ 2;
10438 it
->max_descent
+= (height
+ 1) / 2;
10441 compute_line_metrics (it
);
10443 /* If line is empty, make it occupy the rest of the tool-bar. */
10444 if (!row
->displays_text_p
)
10446 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
10447 row
->visible_height
= row
->height
;
10448 row
->ascent
= row
->phys_ascent
= 0;
10449 row
->extra_line_spacing
= 0;
10452 row
->full_width_p
= 1;
10453 row
->continued_p
= 0;
10454 row
->truncated_on_left_p
= 0;
10455 row
->truncated_on_right_p
= 0;
10457 it
->current_x
= it
->hpos
= 0;
10458 it
->current_y
+= row
->height
;
10464 /* Max tool-bar height. */
10466 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10467 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10469 /* Value is the number of screen lines needed to make all tool-bar
10470 items of frame F visible. The number of actual rows needed is
10471 returned in *N_ROWS if non-NULL. */
10474 tool_bar_lines_needed (struct frame
*f
, int *n_rows
)
10476 struct window
*w
= XWINDOW (f
->tool_bar_window
);
10478 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10479 the desired matrix, so use (unused) mode-line row as temporary row to
10480 avoid destroying the first tool-bar row. */
10481 struct glyph_row
*temp_row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
10483 /* Initialize an iterator for iteration over
10484 F->desired_tool_bar_string in the tool-bar window of frame F. */
10485 init_iterator (&it
, w
, -1, -1, temp_row
, TOOL_BAR_FACE_ID
);
10486 it
.first_visible_x
= 0;
10487 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
10488 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
10490 while (!ITERATOR_AT_END_P (&it
))
10492 clear_glyph_row (temp_row
);
10493 it
.glyph_row
= temp_row
;
10494 display_tool_bar_line (&it
, -1);
10496 clear_glyph_row (temp_row
);
10498 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10500 *n_rows
= it
.vpos
> 0 ? it
.vpos
: -1;
10502 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
10506 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
10508 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
10509 (Lisp_Object frame
)
10516 frame
= selected_frame
;
10518 CHECK_FRAME (frame
);
10519 f
= XFRAME (frame
);
10521 if (WINDOWP (f
->tool_bar_window
)
10522 || (w
= XWINDOW (f
->tool_bar_window
),
10523 WINDOW_TOTAL_LINES (w
) > 0))
10525 update_tool_bar (f
, 1);
10526 if (f
->n_tool_bar_items
)
10528 build_desired_tool_bar_string (f
);
10529 nlines
= tool_bar_lines_needed (f
, NULL
);
10533 return make_number (nlines
);
10537 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10538 height should be changed. */
10541 redisplay_tool_bar (struct frame
*f
)
10545 struct glyph_row
*row
;
10547 #if defined (USE_GTK) || defined (HAVE_NS)
10548 if (FRAME_EXTERNAL_TOOL_BAR (f
))
10549 update_frame_tool_bar (f
);
10553 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10554 do anything. This means you must start with tool-bar-lines
10555 non-zero to get the auto-sizing effect. Or in other words, you
10556 can turn off tool-bars by specifying tool-bar-lines zero. */
10557 if (!WINDOWP (f
->tool_bar_window
)
10558 || (w
= XWINDOW (f
->tool_bar_window
),
10559 WINDOW_TOTAL_LINES (w
) == 0))
10562 /* Set up an iterator for the tool-bar window. */
10563 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
10564 it
.first_visible_x
= 0;
10565 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
10566 row
= it
.glyph_row
;
10568 /* Build a string that represents the contents of the tool-bar. */
10569 build_desired_tool_bar_string (f
);
10570 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
10572 if (f
->n_tool_bar_rows
== 0)
10576 if ((nlines
= tool_bar_lines_needed (f
, &f
->n_tool_bar_rows
),
10577 nlines
!= WINDOW_TOTAL_LINES (w
)))
10580 int old_height
= WINDOW_TOTAL_LINES (w
);
10582 XSETFRAME (frame
, f
);
10583 Fmodify_frame_parameters (frame
,
10584 Fcons (Fcons (Qtool_bar_lines
,
10585 make_number (nlines
)),
10587 if (WINDOW_TOTAL_LINES (w
) != old_height
)
10589 clear_glyph_matrix (w
->desired_matrix
);
10590 fonts_changed_p
= 1;
10596 /* Display as many lines as needed to display all tool-bar items. */
10598 if (f
->n_tool_bar_rows
> 0)
10600 int border
, rows
, height
, extra
;
10602 if (INTEGERP (Vtool_bar_border
))
10603 border
= XINT (Vtool_bar_border
);
10604 else if (EQ (Vtool_bar_border
, Qinternal_border_width
))
10605 border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
10606 else if (EQ (Vtool_bar_border
, Qborder_width
))
10607 border
= f
->border_width
;
10613 rows
= f
->n_tool_bar_rows
;
10614 height
= max (1, (it
.last_visible_y
- border
) / rows
);
10615 extra
= it
.last_visible_y
- border
- height
* rows
;
10617 while (it
.current_y
< it
.last_visible_y
)
10620 if (extra
> 0 && rows
-- > 0)
10622 h
= (extra
+ rows
- 1) / rows
;
10625 display_tool_bar_line (&it
, height
+ h
);
10630 while (it
.current_y
< it
.last_visible_y
)
10631 display_tool_bar_line (&it
, 0);
10634 /* It doesn't make much sense to try scrolling in the tool-bar
10635 window, so don't do it. */
10636 w
->desired_matrix
->no_scrolling_p
= 1;
10637 w
->must_be_updated_p
= 1;
10639 if (!NILP (Vauto_resize_tool_bars
))
10641 int max_tool_bar_height
= MAX_FRAME_TOOL_BAR_HEIGHT (f
);
10642 int change_height_p
= 0;
10644 /* If we couldn't display everything, change the tool-bar's
10645 height if there is room for more. */
10646 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
10647 && it
.current_y
< max_tool_bar_height
)
10648 change_height_p
= 1;
10650 row
= it
.glyph_row
- 1;
10652 /* If there are blank lines at the end, except for a partially
10653 visible blank line at the end that is smaller than
10654 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10655 if (!row
->displays_text_p
10656 && row
->height
>= FRAME_LINE_HEIGHT (f
))
10657 change_height_p
= 1;
10659 /* If row displays tool-bar items, but is partially visible,
10660 change the tool-bar's height. */
10661 if (row
->displays_text_p
10662 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
10663 && MATRIX_ROW_BOTTOM_Y (row
) < max_tool_bar_height
)
10664 change_height_p
= 1;
10666 /* Resize windows as needed by changing the `tool-bar-lines'
10667 frame parameter. */
10668 if (change_height_p
)
10671 int old_height
= WINDOW_TOTAL_LINES (w
);
10673 int nlines
= tool_bar_lines_needed (f
, &nrows
);
10675 change_height_p
= ((EQ (Vauto_resize_tool_bars
, Qgrow_only
)
10676 && !f
->minimize_tool_bar_window_p
)
10677 ? (nlines
> old_height
)
10678 : (nlines
!= old_height
));
10679 f
->minimize_tool_bar_window_p
= 0;
10681 if (change_height_p
)
10683 XSETFRAME (frame
, f
);
10684 Fmodify_frame_parameters (frame
,
10685 Fcons (Fcons (Qtool_bar_lines
,
10686 make_number (nlines
)),
10688 if (WINDOW_TOTAL_LINES (w
) != old_height
)
10690 clear_glyph_matrix (w
->desired_matrix
);
10691 f
->n_tool_bar_rows
= nrows
;
10692 fonts_changed_p
= 1;
10699 f
->minimize_tool_bar_window_p
= 0;
10704 /* Get information about the tool-bar item which is displayed in GLYPH
10705 on frame F. Return in *PROP_IDX the index where tool-bar item
10706 properties start in F->tool_bar_items. Value is zero if
10707 GLYPH doesn't display a tool-bar item. */
10710 tool_bar_item_info (struct frame
*f
, struct glyph
*glyph
, int *prop_idx
)
10716 /* This function can be called asynchronously, which means we must
10717 exclude any possibility that Fget_text_property signals an
10719 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
10720 charpos
= max (0, charpos
);
10722 /* Get the text property `menu-item' at pos. The value of that
10723 property is the start index of this item's properties in
10724 F->tool_bar_items. */
10725 prop
= Fget_text_property (make_number (charpos
),
10726 Qmenu_item
, f
->current_tool_bar_string
);
10727 if (INTEGERP (prop
))
10729 *prop_idx
= XINT (prop
);
10739 /* Get information about the tool-bar item at position X/Y on frame F.
10740 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10741 the current matrix of the tool-bar window of F, or NULL if not
10742 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10743 item in F->tool_bar_items. Value is
10745 -1 if X/Y is not on a tool-bar item
10746 0 if X/Y is on the same item that was highlighted before.
10750 get_tool_bar_item (struct frame
*f
, int x
, int y
, struct glyph
**glyph
,
10751 int *hpos
, int *vpos
, int *prop_idx
)
10753 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10754 struct window
*w
= XWINDOW (f
->tool_bar_window
);
10757 /* Find the glyph under X/Y. */
10758 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
10759 if (*glyph
== NULL
)
10762 /* Get the start of this tool-bar item's properties in
10763 f->tool_bar_items. */
10764 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
10767 /* Is mouse on the highlighted item? */
10768 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
10769 && *vpos
>= dpyinfo
->mouse_face_beg_row
10770 && *vpos
<= dpyinfo
->mouse_face_end_row
10771 && (*vpos
> dpyinfo
->mouse_face_beg_row
10772 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
10773 && (*vpos
< dpyinfo
->mouse_face_end_row
10774 || *hpos
< dpyinfo
->mouse_face_end_col
10775 || dpyinfo
->mouse_face_past_end
))
10783 Handle mouse button event on the tool-bar of frame F, at
10784 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10785 0 for button release. MODIFIERS is event modifiers for button
10789 handle_tool_bar_click (struct frame
*f
, int x
, int y
, int down_p
,
10790 unsigned int modifiers
)
10792 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10793 struct window
*w
= XWINDOW (f
->tool_bar_window
);
10794 int hpos
, vpos
, prop_idx
;
10795 struct glyph
*glyph
;
10796 Lisp_Object enabled_p
;
10798 /* If not on the highlighted tool-bar item, return. */
10799 frame_to_window_pixel_xy (w
, &x
, &y
);
10800 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
10803 /* If item is disabled, do nothing. */
10804 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
10805 if (NILP (enabled_p
))
10810 /* Show item in pressed state. */
10811 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
10812 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
10813 last_tool_bar_item
= prop_idx
;
10817 Lisp_Object key
, frame
;
10818 struct input_event event
;
10819 EVENT_INIT (event
);
10821 /* Show item in released state. */
10822 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
10823 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
10825 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
10827 XSETFRAME (frame
, f
);
10828 event
.kind
= TOOL_BAR_EVENT
;
10829 event
.frame_or_window
= frame
;
10831 kbd_buffer_store_event (&event
);
10833 event
.kind
= TOOL_BAR_EVENT
;
10834 event
.frame_or_window
= frame
;
10836 event
.modifiers
= modifiers
;
10837 kbd_buffer_store_event (&event
);
10838 last_tool_bar_item
= -1;
10843 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10844 tool-bar window-relative coordinates X/Y. Called from
10845 note_mouse_highlight. */
10848 note_tool_bar_highlight (struct frame
*f
, int x
, int y
)
10850 Lisp_Object window
= f
->tool_bar_window
;
10851 struct window
*w
= XWINDOW (window
);
10852 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10854 struct glyph
*glyph
;
10855 struct glyph_row
*row
;
10857 Lisp_Object enabled_p
;
10859 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
10860 int mouse_down_p
, rc
;
10862 /* Function note_mouse_highlight is called with negative x(y
10863 values when mouse moves outside of the frame. */
10864 if (x
<= 0 || y
<= 0)
10866 clear_mouse_face (dpyinfo
);
10870 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
10873 /* Not on tool-bar item. */
10874 clear_mouse_face (dpyinfo
);
10878 /* On same tool-bar item as before. */
10879 goto set_help_echo
;
10881 clear_mouse_face (dpyinfo
);
10883 /* Mouse is down, but on different tool-bar item? */
10884 mouse_down_p
= (dpyinfo
->grabbed
10885 && f
== last_mouse_frame
10886 && FRAME_LIVE_P (f
));
10888 && last_tool_bar_item
!= prop_idx
)
10891 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
10892 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
10894 /* If tool-bar item is not enabled, don't highlight it. */
10895 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
10896 if (!NILP (enabled_p
))
10898 /* Compute the x-position of the glyph. In front and past the
10899 image is a space. We include this in the highlighted area. */
10900 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
10901 for (i
= x
= 0; i
< hpos
; ++i
)
10902 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
10904 /* Record this as the current active region. */
10905 dpyinfo
->mouse_face_beg_col
= hpos
;
10906 dpyinfo
->mouse_face_beg_row
= vpos
;
10907 dpyinfo
->mouse_face_beg_x
= x
;
10908 dpyinfo
->mouse_face_beg_y
= row
->y
;
10909 dpyinfo
->mouse_face_past_end
= 0;
10911 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
10912 dpyinfo
->mouse_face_end_row
= vpos
;
10913 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
10914 dpyinfo
->mouse_face_end_y
= row
->y
;
10915 dpyinfo
->mouse_face_window
= window
;
10916 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
10918 /* Display it as active. */
10919 show_mouse_face (dpyinfo
, draw
);
10920 dpyinfo
->mouse_face_image_state
= draw
;
10925 /* Set help_echo_string to a help string to display for this tool-bar item.
10926 XTread_socket does the rest. */
10927 help_echo_object
= help_echo_window
= Qnil
;
10928 help_echo_pos
= -1;
10929 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
10930 if (NILP (help_echo_string
))
10931 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
10934 #endif /* HAVE_WINDOW_SYSTEM */
10938 /************************************************************************
10939 Horizontal scrolling
10940 ************************************************************************/
10942 static int hscroll_window_tree (Lisp_Object
);
10943 static int hscroll_windows (Lisp_Object
);
10945 /* For all leaf windows in the window tree rooted at WINDOW, set their
10946 hscroll value so that PT is (i) visible in the window, and (ii) so
10947 that it is not within a certain margin at the window's left and
10948 right border. Value is non-zero if any window's hscroll has been
10952 hscroll_window_tree (Lisp_Object window
)
10954 int hscrolled_p
= 0;
10955 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
10956 int hscroll_step_abs
= 0;
10957 double hscroll_step_rel
= 0;
10959 if (hscroll_relative_p
)
10961 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
10962 if (hscroll_step_rel
< 0)
10964 hscroll_relative_p
= 0;
10965 hscroll_step_abs
= 0;
10968 else if (INTEGERP (Vhscroll_step
))
10970 hscroll_step_abs
= XINT (Vhscroll_step
);
10971 if (hscroll_step_abs
< 0)
10972 hscroll_step_abs
= 0;
10975 hscroll_step_abs
= 0;
10977 while (WINDOWP (window
))
10979 struct window
*w
= XWINDOW (window
);
10981 if (WINDOWP (w
->hchild
))
10982 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
10983 else if (WINDOWP (w
->vchild
))
10984 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
10985 else if (w
->cursor
.vpos
>= 0)
10988 int text_area_width
;
10989 struct glyph_row
*current_cursor_row
10990 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
10991 struct glyph_row
*desired_cursor_row
10992 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
10993 struct glyph_row
*cursor_row
10994 = (desired_cursor_row
->enabled_p
10995 ? desired_cursor_row
10996 : current_cursor_row
);
10998 text_area_width
= window_box_width (w
, TEXT_AREA
);
11000 /* Scroll when cursor is inside this scroll margin. */
11001 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
11003 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode
, w
->buffer
))
11004 && ((XFASTINT (w
->hscroll
)
11005 && w
->cursor
.x
<= h_margin
)
11006 || (cursor_row
->enabled_p
11007 && cursor_row
->truncated_on_right_p
11008 && (w
->cursor
.x
>= text_area_width
- h_margin
))))
11012 struct buffer
*saved_current_buffer
;
11016 /* Find point in a display of infinite width. */
11017 saved_current_buffer
= current_buffer
;
11018 current_buffer
= XBUFFER (w
->buffer
);
11020 if (w
== XWINDOW (selected_window
))
11021 pt
= BUF_PT (current_buffer
);
11024 pt
= marker_position (w
->pointm
);
11025 pt
= max (BEGV
, pt
);
11029 /* Move iterator to pt starting at cursor_row->start in
11030 a line with infinite width. */
11031 init_to_row_start (&it
, w
, cursor_row
);
11032 it
.last_visible_x
= INFINITY
;
11033 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
11034 current_buffer
= saved_current_buffer
;
11036 /* Position cursor in window. */
11037 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
11038 hscroll
= max (0, (it
.current_x
11039 - (ITERATOR_AT_END_OF_LINE_P (&it
)
11040 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
11041 : (text_area_width
/ 2))))
11042 / FRAME_COLUMN_WIDTH (it
.f
);
11043 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
11045 if (hscroll_relative_p
)
11046 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
11049 wanted_x
= text_area_width
11050 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
11053 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
11057 if (hscroll_relative_p
)
11058 wanted_x
= text_area_width
* hscroll_step_rel
11061 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
11064 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
11066 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
11068 /* Don't call Fset_window_hscroll if value hasn't
11069 changed because it will prevent redisplay
11071 if (XFASTINT (w
->hscroll
) != hscroll
)
11073 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
11074 w
->hscroll
= make_number (hscroll
);
11083 /* Value is non-zero if hscroll of any leaf window has been changed. */
11084 return hscrolled_p
;
11088 /* Set hscroll so that cursor is visible and not inside horizontal
11089 scroll margins for all windows in the tree rooted at WINDOW. See
11090 also hscroll_window_tree above. Value is non-zero if any window's
11091 hscroll has been changed. If it has, desired matrices on the frame
11092 of WINDOW are cleared. */
11095 hscroll_windows (Lisp_Object window
)
11097 int hscrolled_p
= hscroll_window_tree (window
);
11099 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
11100 return hscrolled_p
;
11105 /************************************************************************
11107 ************************************************************************/
11109 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11110 to a non-zero value. This is sometimes handy to have in a debugger
11115 /* First and last unchanged row for try_window_id. */
11117 int debug_first_unchanged_at_end_vpos
;
11118 int debug_last_unchanged_at_beg_vpos
;
11120 /* Delta vpos and y. */
11122 int debug_dvpos
, debug_dy
;
11124 /* Delta in characters and bytes for try_window_id. */
11126 int debug_delta
, debug_delta_bytes
;
11128 /* Values of window_end_pos and window_end_vpos at the end of
11131 EMACS_INT debug_end_pos
, debug_end_vpos
;
11133 /* Append a string to W->desired_matrix->method. FMT is a printf
11134 format string. A1...A9 are a supplement for a variable-length
11135 argument list. If trace_redisplay_p is non-zero also printf the
11136 resulting string to stderr. */
11139 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
11142 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
11145 char *method
= w
->desired_matrix
->method
;
11146 int len
= strlen (method
);
11147 int size
= sizeof w
->desired_matrix
->method
;
11148 int remaining
= size
- len
- 1;
11150 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
11151 if (len
&& remaining
)
11154 --remaining
, ++len
;
11157 strncpy (method
+ len
, buffer
, remaining
);
11159 if (trace_redisplay_p
)
11160 fprintf (stderr
, "%p (%s): %s\n",
11162 ((BUFFERP (w
->buffer
)
11163 && STRINGP (XBUFFER (w
->buffer
)->name
))
11164 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
11169 #endif /* GLYPH_DEBUG */
11172 /* Value is non-zero if all changes in window W, which displays
11173 current_buffer, are in the text between START and END. START is a
11174 buffer position, END is given as a distance from Z. Used in
11175 redisplay_internal for display optimization. */
11178 text_outside_line_unchanged_p (struct window
*w
, int start
, int end
)
11180 int unchanged_p
= 1;
11182 /* If text or overlays have changed, see where. */
11183 if (XFASTINT (w
->last_modified
) < MODIFF
11184 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
11186 /* Gap in the line? */
11187 if (GPT
< start
|| Z
- GPT
< end
)
11190 /* Changes start in front of the line, or end after it? */
11192 && (BEG_UNCHANGED
< start
- 1
11193 || END_UNCHANGED
< end
))
11196 /* If selective display, can't optimize if changes start at the
11197 beginning of the line. */
11199 && INTEGERP (current_buffer
->selective_display
)
11200 && XINT (current_buffer
->selective_display
) > 0
11201 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
11204 /* If there are overlays at the start or end of the line, these
11205 may have overlay strings with newlines in them. A change at
11206 START, for instance, may actually concern the display of such
11207 overlay strings as well, and they are displayed on different
11208 lines. So, quickly rule out this case. (For the future, it
11209 might be desirable to implement something more telling than
11210 just BEG/END_UNCHANGED.) */
11213 if (BEG
+ BEG_UNCHANGED
== start
11214 && overlay_touches_p (start
))
11216 if (END_UNCHANGED
== end
11217 && overlay_touches_p (Z
- end
))
11221 /* Under bidi reordering, adding or deleting a character in the
11222 beginning of a paragraph, before the first strong directional
11223 character, can change the base direction of the paragraph (unless
11224 the buffer specifies a fixed paragraph direction), which will
11225 require to redisplay the whole paragraph. It might be worthwhile
11226 to find the paragraph limits and widen the range of redisplayed
11227 lines to that, but for now just give up this optimization. */
11228 if (!NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
)
11229 && NILP (XBUFFER (w
->buffer
)->bidi_paragraph_direction
))
11233 return unchanged_p
;
11237 /* Do a frame update, taking possible shortcuts into account. This is
11238 the main external entry point for redisplay.
11240 If the last redisplay displayed an echo area message and that message
11241 is no longer requested, we clear the echo area or bring back the
11242 mini-buffer if that is in use. */
11247 redisplay_internal (0);
11252 overlay_arrow_string_or_property (Lisp_Object var
)
11256 if (val
= Fget (var
, Qoverlay_arrow_string
), STRINGP (val
))
11259 return Voverlay_arrow_string
;
11262 /* Return 1 if there are any overlay-arrows in current_buffer. */
11264 overlay_arrow_in_current_buffer_p (void)
11268 for (vlist
= Voverlay_arrow_variable_list
;
11270 vlist
= XCDR (vlist
))
11272 Lisp_Object var
= XCAR (vlist
);
11275 if (!SYMBOLP (var
))
11277 val
= find_symbol_value (var
);
11279 && current_buffer
== XMARKER (val
)->buffer
)
11286 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11290 overlay_arrows_changed_p (void)
11294 for (vlist
= Voverlay_arrow_variable_list
;
11296 vlist
= XCDR (vlist
))
11298 Lisp_Object var
= XCAR (vlist
);
11299 Lisp_Object val
, pstr
;
11301 if (!SYMBOLP (var
))
11303 val
= find_symbol_value (var
);
11304 if (!MARKERP (val
))
11306 if (! EQ (COERCE_MARKER (val
),
11307 Fget (var
, Qlast_arrow_position
))
11308 || ! (pstr
= overlay_arrow_string_or_property (var
),
11309 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
11315 /* Mark overlay arrows to be updated on next redisplay. */
11318 update_overlay_arrows (int up_to_date
)
11322 for (vlist
= Voverlay_arrow_variable_list
;
11324 vlist
= XCDR (vlist
))
11326 Lisp_Object var
= XCAR (vlist
);
11328 if (!SYMBOLP (var
))
11331 if (up_to_date
> 0)
11333 Lisp_Object val
= find_symbol_value (var
);
11334 Fput (var
, Qlast_arrow_position
,
11335 COERCE_MARKER (val
));
11336 Fput (var
, Qlast_arrow_string
,
11337 overlay_arrow_string_or_property (var
));
11339 else if (up_to_date
< 0
11340 || !NILP (Fget (var
, Qlast_arrow_position
)))
11342 Fput (var
, Qlast_arrow_position
, Qt
);
11343 Fput (var
, Qlast_arrow_string
, Qt
);
11349 /* Return overlay arrow string to display at row.
11350 Return integer (bitmap number) for arrow bitmap in left fringe.
11351 Return nil if no overlay arrow. */
11354 overlay_arrow_at_row (struct it
*it
, struct glyph_row
*row
)
11358 for (vlist
= Voverlay_arrow_variable_list
;
11360 vlist
= XCDR (vlist
))
11362 Lisp_Object var
= XCAR (vlist
);
11365 if (!SYMBOLP (var
))
11368 val
= find_symbol_value (var
);
11371 && current_buffer
== XMARKER (val
)->buffer
11372 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
11374 if (FRAME_WINDOW_P (it
->f
)
11375 /* FIXME: if ROW->reversed_p is set, this should test
11376 the right fringe, not the left one. */
11377 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) > 0)
11379 #ifdef HAVE_WINDOW_SYSTEM
11380 if (val
= Fget (var
, Qoverlay_arrow_bitmap
), SYMBOLP (val
))
11383 if ((fringe_bitmap
= lookup_fringe_bitmap (val
)) != 0)
11384 return make_number (fringe_bitmap
);
11387 return make_number (-1); /* Use default arrow bitmap */
11389 return overlay_arrow_string_or_property (var
);
11396 /* Return 1 if point moved out of or into a composition. Otherwise
11397 return 0. PREV_BUF and PREV_PT are the last point buffer and
11398 position. BUF and PT are the current point buffer and position. */
11401 check_point_in_composition (struct buffer
*prev_buf
, int prev_pt
,
11402 struct buffer
*buf
, int pt
)
11404 EMACS_INT start
, end
;
11406 Lisp_Object buffer
;
11408 XSETBUFFER (buffer
, buf
);
11409 /* Check a composition at the last point if point moved within the
11411 if (prev_buf
== buf
)
11414 /* Point didn't move. */
11417 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
11418 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
11419 && COMPOSITION_VALID_P (start
, end
, prop
)
11420 && start
< prev_pt
&& end
> prev_pt
)
11421 /* The last point was within the composition. Return 1 iff
11422 point moved out of the composition. */
11423 return (pt
<= start
|| pt
>= end
);
11426 /* Check a composition at the current point. */
11427 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
11428 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
11429 && COMPOSITION_VALID_P (start
, end
, prop
)
11430 && start
< pt
&& end
> pt
);
11434 /* Reconsider the setting of B->clip_changed which is displayed
11438 reconsider_clip_changes (struct window
*w
, struct buffer
*b
)
11440 if (b
->clip_changed
11441 && !NILP (w
->window_end_valid
)
11442 && w
->current_matrix
->buffer
== b
11443 && w
->current_matrix
->zv
== BUF_ZV (b
)
11444 && w
->current_matrix
->begv
== BUF_BEGV (b
))
11445 b
->clip_changed
= 0;
11447 /* If display wasn't paused, and W is not a tool bar window, see if
11448 point has been moved into or out of a composition. In that case,
11449 we set b->clip_changed to 1 to force updating the screen. If
11450 b->clip_changed has already been set to 1, we can skip this
11452 if (!b
->clip_changed
11453 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
11457 if (w
== XWINDOW (selected_window
))
11458 pt
= BUF_PT (current_buffer
);
11460 pt
= marker_position (w
->pointm
);
11462 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
11463 || pt
!= XINT (w
->last_point
))
11464 && check_point_in_composition (w
->current_matrix
->buffer
,
11465 XINT (w
->last_point
),
11466 XBUFFER (w
->buffer
), pt
))
11467 b
->clip_changed
= 1;
11472 /* Select FRAME to forward the values of frame-local variables into C
11473 variables so that the redisplay routines can access those values
11477 select_frame_for_redisplay (Lisp_Object frame
)
11479 Lisp_Object tail
, tem
;
11480 Lisp_Object old
= selected_frame
;
11481 struct Lisp_Symbol
*sym
;
11483 xassert (FRAMEP (frame
) && FRAME_LIVE_P (XFRAME (frame
)));
11485 selected_frame
= frame
;
11488 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
11489 if (CONSP (XCAR (tail
))
11490 && (tem
= XCAR (XCAR (tail
)),
11492 && (sym
= indirect_variable (XSYMBOL (tem
)),
11493 sym
->redirect
== SYMBOL_LOCALIZED
)
11494 && sym
->val
.blv
->frame_local
)
11495 /* Use find_symbol_value rather than Fsymbol_value
11496 to avoid an error if it is void. */
11497 find_symbol_value (tem
);
11498 } while (!EQ (frame
, old
) && (frame
= old
, 1));
11502 #define STOP_POLLING \
11503 do { if (! polling_stopped_here) stop_polling (); \
11504 polling_stopped_here = 1; } while (0)
11506 #define RESUME_POLLING \
11507 do { if (polling_stopped_here) start_polling (); \
11508 polling_stopped_here = 0; } while (0)
11511 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11512 response to any user action; therefore, we should preserve the echo
11513 area. (Actually, our caller does that job.) Perhaps in the future
11514 avoid recentering windows if it is not necessary; currently that
11515 causes some problems. */
11518 redisplay_internal (int preserve_echo_area
)
11520 struct window
*w
= XWINDOW (selected_window
);
11523 int must_finish
= 0;
11524 struct text_pos tlbufpos
, tlendpos
;
11525 int number_of_visible_frames
;
11528 int polling_stopped_here
= 0;
11529 Lisp_Object old_frame
= selected_frame
;
11531 /* Non-zero means redisplay has to consider all windows on all
11532 frames. Zero means, only selected_window is considered. */
11533 int consider_all_windows_p
;
11535 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
11537 /* No redisplay if running in batch mode or frame is not yet fully
11538 initialized, or redisplay is explicitly turned off by setting
11539 Vinhibit_redisplay. */
11540 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11541 || !NILP (Vinhibit_redisplay
))
11544 /* Don't examine these until after testing Vinhibit_redisplay.
11545 When Emacs is shutting down, perhaps because its connection to
11546 X has dropped, we should not look at them at all. */
11547 f
= XFRAME (w
->frame
);
11548 sf
= SELECTED_FRAME ();
11550 if (!f
->glyphs_initialized_p
)
11553 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11554 if (popup_activated ())
11558 /* I don't think this happens but let's be paranoid. */
11559 if (redisplaying_p
)
11562 /* Record a function that resets redisplaying_p to its old value
11563 when we leave this function. */
11564 count
= SPECPDL_INDEX ();
11565 record_unwind_protect (unwind_redisplay
,
11566 Fcons (make_number (redisplaying_p
), selected_frame
));
11568 specbind (Qinhibit_free_realized_faces
, Qnil
);
11571 Lisp_Object tail
, frame
;
11573 FOR_EACH_FRAME (tail
, frame
)
11575 struct frame
*f
= XFRAME (frame
);
11576 f
->already_hscrolled_p
= 0;
11581 if (!EQ (old_frame
, selected_frame
)
11582 && FRAME_LIVE_P (XFRAME (old_frame
)))
11583 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11584 selected_frame and selected_window to be temporarily out-of-sync so
11585 when we come back here via `goto retry', we need to resync because we
11586 may need to run Elisp code (via prepare_menu_bars). */
11587 select_frame_for_redisplay (old_frame
);
11590 reconsider_clip_changes (w
, current_buffer
);
11591 last_escape_glyph_frame
= NULL
;
11592 last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
11594 /* If new fonts have been loaded that make a glyph matrix adjustment
11595 necessary, do it. */
11596 if (fonts_changed_p
)
11598 adjust_glyphs (NULL
);
11599 ++windows_or_buffers_changed
;
11600 fonts_changed_p
= 0;
11603 /* If face_change_count is non-zero, init_iterator will free all
11604 realized faces, which includes the faces referenced from current
11605 matrices. So, we can't reuse current matrices in this case. */
11606 if (face_change_count
)
11607 ++windows_or_buffers_changed
;
11609 if ((FRAME_TERMCAP_P (sf
) || FRAME_MSDOS_P (sf
))
11610 && FRAME_TTY (sf
)->previous_frame
!= sf
)
11612 /* Since frames on a single ASCII terminal share the same
11613 display area, displaying a different frame means redisplay
11614 the whole thing. */
11615 windows_or_buffers_changed
++;
11616 SET_FRAME_GARBAGED (sf
);
11618 set_tty_color_mode (FRAME_TTY (sf
), sf
);
11620 FRAME_TTY (sf
)->previous_frame
= sf
;
11623 /* Set the visible flags for all frames. Do this before checking
11624 for resized or garbaged frames; they want to know if their frames
11625 are visible. See the comment in frame.h for
11626 FRAME_SAMPLE_VISIBILITY. */
11628 Lisp_Object tail
, frame
;
11630 number_of_visible_frames
= 0;
11632 FOR_EACH_FRAME (tail
, frame
)
11634 struct frame
*f
= XFRAME (frame
);
11636 FRAME_SAMPLE_VISIBILITY (f
);
11637 if (FRAME_VISIBLE_P (f
))
11638 ++number_of_visible_frames
;
11639 clear_desired_matrices (f
);
11643 /* Notice any pending interrupt request to change frame size. */
11644 do_pending_window_change (1);
11646 /* Clear frames marked as garbaged. */
11647 if (frame_garbaged
)
11648 clear_garbaged_frames ();
11650 /* Build menubar and tool-bar items. */
11651 if (NILP (Vmemory_full
))
11652 prepare_menu_bars ();
11654 if (windows_or_buffers_changed
)
11655 update_mode_lines
++;
11657 /* Detect case that we need to write or remove a star in the mode line. */
11658 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
11660 w
->update_mode_line
= Qt
;
11661 if (buffer_shared
> 1)
11662 update_mode_lines
++;
11665 /* Avoid invocation of point motion hooks by `current_column' below. */
11666 count1
= SPECPDL_INDEX ();
11667 specbind (Qinhibit_point_motion_hooks
, Qt
);
11669 /* If %c is in the mode line, update it if needed. */
11670 if (!NILP (w
->column_number_displayed
)
11671 /* This alternative quickly identifies a common case
11672 where no change is needed. */
11673 && !(PT
== XFASTINT (w
->last_point
)
11674 && XFASTINT (w
->last_modified
) >= MODIFF
11675 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
11676 && (XFASTINT (w
->column_number_displayed
)
11677 != (int) current_column ())) /* iftc */
11678 w
->update_mode_line
= Qt
;
11680 unbind_to (count1
, Qnil
);
11682 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
11684 /* The variable buffer_shared is set in redisplay_window and
11685 indicates that we redisplay a buffer in different windows. See
11687 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
11688 || cursor_type_changed
);
11690 /* If specs for an arrow have changed, do thorough redisplay
11691 to ensure we remove any arrow that should no longer exist. */
11692 if (overlay_arrows_changed_p ())
11693 consider_all_windows_p
= windows_or_buffers_changed
= 1;
11695 /* Normally the message* functions will have already displayed and
11696 updated the echo area, but the frame may have been trashed, or
11697 the update may have been preempted, so display the echo area
11698 again here. Checking message_cleared_p captures the case that
11699 the echo area should be cleared. */
11700 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
11701 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
11702 || (message_cleared_p
11703 && minibuf_level
== 0
11704 /* If the mini-window is currently selected, this means the
11705 echo-area doesn't show through. */
11706 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
11708 int window_height_changed_p
= echo_area_display (0);
11711 /* If we don't display the current message, don't clear the
11712 message_cleared_p flag, because, if we did, we wouldn't clear
11713 the echo area in the next redisplay which doesn't preserve
11715 if (!display_last_displayed_message_p
)
11716 message_cleared_p
= 0;
11718 if (fonts_changed_p
)
11720 else if (window_height_changed_p
)
11722 consider_all_windows_p
= 1;
11723 ++update_mode_lines
;
11724 ++windows_or_buffers_changed
;
11726 /* If window configuration was changed, frames may have been
11727 marked garbaged. Clear them or we will experience
11728 surprises wrt scrolling. */
11729 if (frame_garbaged
)
11730 clear_garbaged_frames ();
11733 else if (EQ (selected_window
, minibuf_window
)
11734 && (current_buffer
->clip_changed
11735 || XFASTINT (w
->last_modified
) < MODIFF
11736 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
11737 && resize_mini_window (w
, 0))
11739 /* Resized active mini-window to fit the size of what it is
11740 showing if its contents might have changed. */
11742 /* FIXME: this causes all frames to be updated, which seems unnecessary
11743 since only the current frame needs to be considered. This function needs
11744 to be rewritten with two variables, consider_all_windows and
11745 consider_all_frames. */
11746 consider_all_windows_p
= 1;
11747 ++windows_or_buffers_changed
;
11748 ++update_mode_lines
;
11750 /* If window configuration was changed, frames may have been
11751 marked garbaged. Clear them or we will experience
11752 surprises wrt scrolling. */
11753 if (frame_garbaged
)
11754 clear_garbaged_frames ();
11758 /* If showing the region, and mark has changed, we must redisplay
11759 the whole window. The assignment to this_line_start_pos prevents
11760 the optimization directly below this if-statement. */
11761 if (((!NILP (Vtransient_mark_mode
)
11762 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
11763 != !NILP (w
->region_showing
))
11764 || (!NILP (w
->region_showing
)
11765 && !EQ (w
->region_showing
,
11766 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
11767 CHARPOS (this_line_start_pos
) = 0;
11769 /* Optimize the case that only the line containing the cursor in the
11770 selected window has changed. Variables starting with this_ are
11771 set in display_line and record information about the line
11772 containing the cursor. */
11773 tlbufpos
= this_line_start_pos
;
11774 tlendpos
= this_line_end_pos
;
11775 if (!consider_all_windows_p
11776 && CHARPOS (tlbufpos
) > 0
11777 && NILP (w
->update_mode_line
)
11778 && !current_buffer
->clip_changed
11779 && !current_buffer
->prevent_redisplay_optimizations_p
11780 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
11781 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
11782 /* Make sure recorded data applies to current buffer, etc. */
11783 && this_line_buffer
== current_buffer
11784 && current_buffer
== XBUFFER (w
->buffer
)
11785 && NILP (w
->force_start
)
11786 && NILP (w
->optional_new_start
)
11787 /* Point must be on the line that we have info recorded about. */
11788 && PT
>= CHARPOS (tlbufpos
)
11789 && PT
<= Z
- CHARPOS (tlendpos
)
11790 /* All text outside that line, including its final newline,
11791 must be unchanged. */
11792 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
11793 CHARPOS (tlendpos
)))
11795 if (CHARPOS (tlbufpos
) > BEGV
11796 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
11797 && (CHARPOS (tlbufpos
) == ZV
11798 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
11799 /* Former continuation line has disappeared by becoming empty. */
11801 else if (XFASTINT (w
->last_modified
) < MODIFF
11802 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
11803 || MINI_WINDOW_P (w
))
11805 /* We have to handle the case of continuation around a
11806 wide-column character (see the comment in indent.c around
11809 For instance, in the following case:
11811 -------- Insert --------
11812 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11813 J_I_ ==> J_I_ `^^' are cursors.
11817 As we have to redraw the line above, we cannot use this
11821 int line_height_before
= this_line_pixel_height
;
11823 /* Note that start_display will handle the case that the
11824 line starting at tlbufpos is a continuation line. */
11825 start_display (&it
, w
, tlbufpos
);
11827 /* Implementation note: It this still necessary? */
11828 if (it
.current_x
!= this_line_start_x
)
11831 TRACE ((stderr
, "trying display optimization 1\n"));
11832 w
->cursor
.vpos
= -1;
11833 overlay_arrow_seen
= 0;
11834 it
.vpos
= this_line_vpos
;
11835 it
.current_y
= this_line_y
;
11836 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
11837 display_line (&it
);
11839 /* If line contains point, is not continued,
11840 and ends at same distance from eob as before, we win. */
11841 if (w
->cursor
.vpos
>= 0
11842 /* Line is not continued, otherwise this_line_start_pos
11843 would have been set to 0 in display_line. */
11844 && CHARPOS (this_line_start_pos
)
11845 /* Line ends as before. */
11846 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
11847 /* Line has same height as before. Otherwise other lines
11848 would have to be shifted up or down. */
11849 && this_line_pixel_height
== line_height_before
)
11851 /* If this is not the window's last line, we must adjust
11852 the charstarts of the lines below. */
11853 if (it
.current_y
< it
.last_visible_y
)
11855 struct glyph_row
*row
11856 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
11857 int delta
, delta_bytes
;
11859 /* We used to distinguish between two cases here,
11860 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11861 when the line ends in a newline or the end of the
11862 buffer's accessible portion. But both cases did
11863 the same, so they were collapsed. */
11865 - CHARPOS (tlendpos
)
11866 - MATRIX_ROW_START_CHARPOS (row
));
11867 delta_bytes
= (Z_BYTE
11868 - BYTEPOS (tlendpos
)
11869 - MATRIX_ROW_START_BYTEPOS (row
));
11871 increment_matrix_positions (w
->current_matrix
,
11872 this_line_vpos
+ 1,
11873 w
->current_matrix
->nrows
,
11874 delta
, delta_bytes
);
11877 /* If this row displays text now but previously didn't,
11878 or vice versa, w->window_end_vpos may have to be
11880 if ((it
.glyph_row
- 1)->displays_text_p
)
11882 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
11883 XSETINT (w
->window_end_vpos
, this_line_vpos
);
11885 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
11886 && this_line_vpos
> 0)
11887 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
11888 w
->window_end_valid
= Qnil
;
11890 /* Update hint: No need to try to scroll in update_window. */
11891 w
->desired_matrix
->no_scrolling_p
= 1;
11894 *w
->desired_matrix
->method
= 0;
11895 debug_method_add (w
, "optimization 1");
11897 #ifdef HAVE_WINDOW_SYSTEM
11898 update_window_fringes (w
, 0);
11905 else if (/* Cursor position hasn't changed. */
11906 PT
== XFASTINT (w
->last_point
)
11907 /* Make sure the cursor was last displayed
11908 in this window. Otherwise we have to reposition it. */
11909 && 0 <= w
->cursor
.vpos
11910 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
11914 do_pending_window_change (1);
11916 /* We used to always goto end_of_redisplay here, but this
11917 isn't enough if we have a blinking cursor. */
11918 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
11919 goto end_of_redisplay
;
11923 /* If highlighting the region, or if the cursor is in the echo area,
11924 then we can't just move the cursor. */
11925 else if (! (!NILP (Vtransient_mark_mode
)
11926 && !NILP (current_buffer
->mark_active
))
11927 && (EQ (selected_window
, current_buffer
->last_selected_window
)
11928 || highlight_nonselected_windows
)
11929 && NILP (w
->region_showing
)
11930 && NILP (Vshow_trailing_whitespace
)
11931 && !cursor_in_echo_area
)
11934 struct glyph_row
*row
;
11936 /* Skip from tlbufpos to PT and see where it is. Note that
11937 PT may be in invisible text. If so, we will end at the
11938 next visible position. */
11939 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
11940 NULL
, DEFAULT_FACE_ID
);
11941 it
.current_x
= this_line_start_x
;
11942 it
.current_y
= this_line_y
;
11943 it
.vpos
= this_line_vpos
;
11945 /* The call to move_it_to stops in front of PT, but
11946 moves over before-strings. */
11947 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
11949 if (it
.vpos
== this_line_vpos
11950 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
11953 xassert (this_line_vpos
== it
.vpos
);
11954 xassert (this_line_y
== it
.current_y
);
11955 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11957 *w
->desired_matrix
->method
= 0;
11958 debug_method_add (w
, "optimization 3");
11967 /* Text changed drastically or point moved off of line. */
11968 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
11971 CHARPOS (this_line_start_pos
) = 0;
11972 consider_all_windows_p
|= buffer_shared
> 1;
11973 ++clear_face_cache_count
;
11974 #ifdef HAVE_WINDOW_SYSTEM
11975 ++clear_image_cache_count
;
11978 /* Build desired matrices, and update the display. If
11979 consider_all_windows_p is non-zero, do it for all windows on all
11980 frames. Otherwise do it for selected_window, only. */
11982 if (consider_all_windows_p
)
11984 Lisp_Object tail
, frame
;
11986 FOR_EACH_FRAME (tail
, frame
)
11987 XFRAME (frame
)->updated_p
= 0;
11989 /* Recompute # windows showing selected buffer. This will be
11990 incremented each time such a window is displayed. */
11993 FOR_EACH_FRAME (tail
, frame
)
11995 struct frame
*f
= XFRAME (frame
);
11997 if (FRAME_WINDOW_P (f
) || FRAME_TERMCAP_P (f
) || f
== sf
)
11999 if (! EQ (frame
, selected_frame
))
12000 /* Select the frame, for the sake of frame-local
12002 select_frame_for_redisplay (frame
);
12004 /* Mark all the scroll bars to be removed; we'll redeem
12005 the ones we want when we redisplay their windows. */
12006 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
12007 FRAME_TERMINAL (f
)->condemn_scroll_bars_hook (f
);
12009 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
12010 redisplay_windows (FRAME_ROOT_WINDOW (f
));
12012 /* The X error handler may have deleted that frame. */
12013 if (!FRAME_LIVE_P (f
))
12016 /* Any scroll bars which redisplay_windows should have
12017 nuked should now go away. */
12018 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
12019 FRAME_TERMINAL (f
)->judge_scroll_bars_hook (f
);
12021 /* If fonts changed, display again. */
12022 /* ??? rms: I suspect it is a mistake to jump all the way
12023 back to retry here. It should just retry this frame. */
12024 if (fonts_changed_p
)
12027 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
12029 /* See if we have to hscroll. */
12030 if (!f
->already_hscrolled_p
)
12032 f
->already_hscrolled_p
= 1;
12033 if (hscroll_windows (f
->root_window
))
12037 /* Prevent various kinds of signals during display
12038 update. stdio is not robust about handling
12039 signals, which can cause an apparent I/O
12041 if (interrupt_input
)
12042 unrequest_sigio ();
12045 /* Update the display. */
12046 set_window_update_flags (XWINDOW (f
->root_window
), 1);
12047 pause
|= update_frame (f
, 0, 0);
12053 if (!EQ (old_frame
, selected_frame
)
12054 && FRAME_LIVE_P (XFRAME (old_frame
)))
12055 /* We played a bit fast-and-loose above and allowed selected_frame
12056 and selected_window to be temporarily out-of-sync but let's make
12057 sure this stays contained. */
12058 select_frame_for_redisplay (old_frame
);
12059 eassert (EQ (XFRAME (selected_frame
)->selected_window
, selected_window
));
12063 /* Do the mark_window_display_accurate after all windows have
12064 been redisplayed because this call resets flags in buffers
12065 which are needed for proper redisplay. */
12066 FOR_EACH_FRAME (tail
, frame
)
12068 struct frame
*f
= XFRAME (frame
);
12071 mark_window_display_accurate (f
->root_window
, 1);
12072 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
12073 FRAME_TERMINAL (f
)->frame_up_to_date_hook (f
);
12078 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
12080 Lisp_Object mini_window
;
12081 struct frame
*mini_frame
;
12083 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
12084 /* Use list_of_error, not Qerror, so that
12085 we catch only errors and don't run the debugger. */
12086 internal_condition_case_1 (redisplay_window_1
, selected_window
,
12088 redisplay_window_error
);
12090 /* Compare desired and current matrices, perform output. */
12093 /* If fonts changed, display again. */
12094 if (fonts_changed_p
)
12097 /* Prevent various kinds of signals during display update.
12098 stdio is not robust about handling signals,
12099 which can cause an apparent I/O error. */
12100 if (interrupt_input
)
12101 unrequest_sigio ();
12104 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
12106 if (hscroll_windows (selected_window
))
12109 XWINDOW (selected_window
)->must_be_updated_p
= 1;
12110 pause
= update_frame (sf
, 0, 0);
12113 /* We may have called echo_area_display at the top of this
12114 function. If the echo area is on another frame, that may
12115 have put text on a frame other than the selected one, so the
12116 above call to update_frame would not have caught it. Catch
12118 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
12119 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
12121 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
12123 XWINDOW (mini_window
)->must_be_updated_p
= 1;
12124 pause
|= update_frame (mini_frame
, 0, 0);
12125 if (!pause
&& hscroll_windows (mini_window
))
12130 /* If display was paused because of pending input, make sure we do a
12131 thorough update the next time. */
12134 /* Prevent the optimization at the beginning of
12135 redisplay_internal that tries a single-line update of the
12136 line containing the cursor in the selected window. */
12137 CHARPOS (this_line_start_pos
) = 0;
12139 /* Let the overlay arrow be updated the next time. */
12140 update_overlay_arrows (0);
12142 /* If we pause after scrolling, some rows in the current
12143 matrices of some windows are not valid. */
12144 if (!WINDOW_FULL_WIDTH_P (w
)
12145 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
12146 update_mode_lines
= 1;
12150 if (!consider_all_windows_p
)
12152 /* This has already been done above if
12153 consider_all_windows_p is set. */
12154 mark_window_display_accurate_1 (w
, 1);
12156 /* Say overlay arrows are up to date. */
12157 update_overlay_arrows (1);
12159 if (FRAME_TERMINAL (sf
)->frame_up_to_date_hook
!= 0)
12160 FRAME_TERMINAL (sf
)->frame_up_to_date_hook (sf
);
12163 update_mode_lines
= 0;
12164 windows_or_buffers_changed
= 0;
12165 cursor_type_changed
= 0;
12168 /* Start SIGIO interrupts coming again. Having them off during the
12169 code above makes it less likely one will discard output, but not
12170 impossible, since there might be stuff in the system buffer here.
12171 But it is much hairier to try to do anything about that. */
12172 if (interrupt_input
)
12176 /* If a frame has become visible which was not before, redisplay
12177 again, so that we display it. Expose events for such a frame
12178 (which it gets when becoming visible) don't call the parts of
12179 redisplay constructing glyphs, so simply exposing a frame won't
12180 display anything in this case. So, we have to display these
12181 frames here explicitly. */
12184 Lisp_Object tail
, frame
;
12187 FOR_EACH_FRAME (tail
, frame
)
12189 int this_is_visible
= 0;
12191 if (XFRAME (frame
)->visible
)
12192 this_is_visible
= 1;
12193 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
12194 if (XFRAME (frame
)->visible
)
12195 this_is_visible
= 1;
12197 if (this_is_visible
)
12201 if (new_count
!= number_of_visible_frames
)
12202 windows_or_buffers_changed
++;
12205 /* Change frame size now if a change is pending. */
12206 do_pending_window_change (1);
12208 /* If we just did a pending size change, or have additional
12209 visible frames, redisplay again. */
12210 if (windows_or_buffers_changed
&& !pause
)
12213 /* Clear the face and image caches.
12215 We used to do this only if consider_all_windows_p. But the cache
12216 needs to be cleared if a timer creates images in the current
12217 buffer (e.g. the test case in Bug#6230). */
12219 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
12221 clear_face_cache (0);
12222 clear_face_cache_count
= 0;
12225 #ifdef HAVE_WINDOW_SYSTEM
12226 if (clear_image_cache_count
> CLEAR_IMAGE_CACHE_COUNT
)
12228 clear_image_caches (Qnil
);
12229 clear_image_cache_count
= 0;
12231 #endif /* HAVE_WINDOW_SYSTEM */
12234 unbind_to (count
, Qnil
);
12239 /* Redisplay, but leave alone any recent echo area message unless
12240 another message has been requested in its place.
12242 This is useful in situations where you need to redisplay but no
12243 user action has occurred, making it inappropriate for the message
12244 area to be cleared. See tracking_off and
12245 wait_reading_process_output for examples of these situations.
12247 FROM_WHERE is an integer saying from where this function was
12248 called. This is useful for debugging. */
12251 redisplay_preserve_echo_area (int from_where
)
12253 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
12255 if (!NILP (echo_area_buffer
[1]))
12257 /* We have a previously displayed message, but no current
12258 message. Redisplay the previous message. */
12259 display_last_displayed_message_p
= 1;
12260 redisplay_internal (1);
12261 display_last_displayed_message_p
= 0;
12264 redisplay_internal (1);
12266 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12267 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional
)
12268 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL
);
12272 /* Function registered with record_unwind_protect in
12273 redisplay_internal. Reset redisplaying_p to the value it had
12274 before redisplay_internal was called, and clear
12275 prevent_freeing_realized_faces_p. It also selects the previously
12276 selected frame, unless it has been deleted (by an X connection
12277 failure during redisplay, for example). */
12280 unwind_redisplay (Lisp_Object val
)
12282 Lisp_Object old_redisplaying_p
, old_frame
;
12284 old_redisplaying_p
= XCAR (val
);
12285 redisplaying_p
= XFASTINT (old_redisplaying_p
);
12286 old_frame
= XCDR (val
);
12287 if (! EQ (old_frame
, selected_frame
)
12288 && FRAME_LIVE_P (XFRAME (old_frame
)))
12289 select_frame_for_redisplay (old_frame
);
12294 /* Mark the display of window W as accurate or inaccurate. If
12295 ACCURATE_P is non-zero mark display of W as accurate. If
12296 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12297 redisplay_internal is called. */
12300 mark_window_display_accurate_1 (struct window
*w
, int accurate_p
)
12302 if (BUFFERP (w
->buffer
))
12304 struct buffer
*b
= XBUFFER (w
->buffer
);
12307 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
12308 w
->last_overlay_modified
12309 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
12311 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
12315 b
->clip_changed
= 0;
12316 b
->prevent_redisplay_optimizations_p
= 0;
12318 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
12319 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
12320 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
12321 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
12323 w
->current_matrix
->buffer
= b
;
12324 w
->current_matrix
->begv
= BUF_BEGV (b
);
12325 w
->current_matrix
->zv
= BUF_ZV (b
);
12327 w
->last_cursor
= w
->cursor
;
12328 w
->last_cursor_off_p
= w
->cursor_off_p
;
12330 if (w
== XWINDOW (selected_window
))
12331 w
->last_point
= make_number (BUF_PT (b
));
12333 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
12339 w
->window_end_valid
= w
->buffer
;
12340 w
->update_mode_line
= Qnil
;
12345 /* Mark the display of windows in the window tree rooted at WINDOW as
12346 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12347 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12348 be redisplayed the next time redisplay_internal is called. */
12351 mark_window_display_accurate (Lisp_Object window
, int accurate_p
)
12355 for (; !NILP (window
); window
= w
->next
)
12357 w
= XWINDOW (window
);
12358 mark_window_display_accurate_1 (w
, accurate_p
);
12360 if (!NILP (w
->vchild
))
12361 mark_window_display_accurate (w
->vchild
, accurate_p
);
12362 if (!NILP (w
->hchild
))
12363 mark_window_display_accurate (w
->hchild
, accurate_p
);
12368 update_overlay_arrows (1);
12372 /* Force a thorough redisplay the next time by setting
12373 last_arrow_position and last_arrow_string to t, which is
12374 unequal to any useful value of Voverlay_arrow_... */
12375 update_overlay_arrows (-1);
12380 /* Return value in display table DP (Lisp_Char_Table *) for character
12381 C. Since a display table doesn't have any parent, we don't have to
12382 follow parent. Do not call this function directly but use the
12383 macro DISP_CHAR_VECTOR. */
12386 disp_char_vector (struct Lisp_Char_Table
*dp
, int c
)
12390 if (ASCII_CHAR_P (c
))
12393 if (SUB_CHAR_TABLE_P (val
))
12394 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
12400 XSETCHAR_TABLE (table
, dp
);
12401 val
= char_table_ref (table
, c
);
12410 /***********************************************************************
12412 ***********************************************************************/
12414 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12417 redisplay_windows (Lisp_Object window
)
12419 while (!NILP (window
))
12421 struct window
*w
= XWINDOW (window
);
12423 if (!NILP (w
->hchild
))
12424 redisplay_windows (w
->hchild
);
12425 else if (!NILP (w
->vchild
))
12426 redisplay_windows (w
->vchild
);
12427 else if (!NILP (w
->buffer
))
12429 displayed_buffer
= XBUFFER (w
->buffer
);
12430 /* Use list_of_error, not Qerror, so that
12431 we catch only errors and don't run the debugger. */
12432 internal_condition_case_1 (redisplay_window_0
, window
,
12434 redisplay_window_error
);
12442 redisplay_window_error (Lisp_Object ignore
)
12444 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
12449 redisplay_window_0 (Lisp_Object window
)
12451 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
12452 redisplay_window (window
, 0);
12457 redisplay_window_1 (Lisp_Object window
)
12459 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
12460 redisplay_window (window
, 1);
12465 /* Increment GLYPH until it reaches END or CONDITION fails while
12466 adding (GLYPH)->pixel_width to X. */
12468 #define SKIP_GLYPHS(glyph, end, x, condition) \
12471 (x) += (glyph)->pixel_width; \
12474 while ((glyph) < (end) && (condition))
12477 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12478 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12479 which positions recorded in ROW differ from current buffer
12482 Return 0 if cursor is not on this row, 1 otherwise. */
12485 set_cursor_from_row (struct window
*w
, struct glyph_row
*row
,
12486 struct glyph_matrix
*matrix
, int delta
, int delta_bytes
,
12489 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
12490 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
12491 struct glyph
*cursor
= NULL
;
12492 /* The last known character position in row. */
12493 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
12495 EMACS_INT pt_old
= PT
- delta
;
12496 EMACS_INT pos_before
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
12497 EMACS_INT pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
12498 struct glyph
*glyph_before
= glyph
- 1, *glyph_after
= end
;
12499 /* A glyph beyond the edge of TEXT_AREA which we should never
12501 struct glyph
*glyphs_end
= end
;
12502 /* Non-zero means we've found a match for cursor position, but that
12503 glyph has the avoid_cursor_p flag set. */
12504 int match_with_avoid_cursor
= 0;
12505 /* Non-zero means we've seen at least one glyph that came from a
12507 int string_seen
= 0;
12508 /* Largest buffer position seen so far during scan of glyph row. */
12509 EMACS_INT bpos_max
= last_pos
;
12510 /* Last buffer position covered by an overlay string with an integer
12511 `cursor' property. */
12512 EMACS_INT bpos_covered
= 0;
12514 /* Skip over glyphs not having an object at the start and the end of
12515 the row. These are special glyphs like truncation marks on
12516 terminal frames. */
12517 if (row
->displays_text_p
)
12519 if (!row
->reversed_p
)
12522 && INTEGERP (glyph
->object
)
12523 && glyph
->charpos
< 0)
12525 x
+= glyph
->pixel_width
;
12529 && INTEGERP ((end
- 1)->object
)
12530 /* CHARPOS is zero for blanks and stretch glyphs
12531 inserted by extend_face_to_end_of_line. */
12532 && (end
- 1)->charpos
<= 0)
12534 glyph_before
= glyph
- 1;
12541 /* If the glyph row is reversed, we need to process it from back
12542 to front, so swap the edge pointers. */
12543 glyphs_end
= end
= glyph
- 1;
12544 glyph
+= row
->used
[TEXT_AREA
] - 1;
12546 while (glyph
> end
+ 1
12547 && INTEGERP (glyph
->object
)
12548 && glyph
->charpos
< 0)
12551 x
-= glyph
->pixel_width
;
12553 if (INTEGERP (glyph
->object
) && glyph
->charpos
< 0)
12555 /* By default, in reversed rows we put the cursor on the
12556 rightmost (first in the reading order) glyph. */
12557 for (g
= end
+ 1; g
< glyph
; g
++)
12558 x
+= g
->pixel_width
;
12560 && INTEGERP ((end
+ 1)->object
)
12561 && (end
+ 1)->charpos
<= 0)
12563 glyph_before
= glyph
+ 1;
12567 else if (row
->reversed_p
)
12569 /* In R2L rows that don't display text, put the cursor on the
12570 rightmost glyph. Case in point: an empty last line that is
12571 part of an R2L paragraph. */
12573 /* Avoid placing the cursor on the last glyph of the row, where
12574 on terminal frames we hold the vertical border between
12575 adjacent windows. */
12576 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w
))
12577 && !WINDOW_RIGHTMOST_P (w
)
12578 && cursor
== row
->glyphs
[LAST_AREA
] - 1)
12580 x
= -1; /* will be computed below, at label compute_x */
12583 /* Step 1: Try to find the glyph whose character position
12584 corresponds to point. If that's not possible, find 2 glyphs
12585 whose character positions are the closest to point, one before
12586 point, the other after it. */
12587 if (!row
->reversed_p
)
12588 while (/* not marched to end of glyph row */
12590 /* glyph was not inserted by redisplay for internal purposes */
12591 && !INTEGERP (glyph
->object
))
12593 if (BUFFERP (glyph
->object
))
12595 EMACS_INT dpos
= glyph
->charpos
- pt_old
;
12597 if (glyph
->charpos
> bpos_max
)
12598 bpos_max
= glyph
->charpos
;
12599 if (!glyph
->avoid_cursor_p
)
12601 /* If we hit point, we've found the glyph on which to
12602 display the cursor. */
12605 match_with_avoid_cursor
= 0;
12608 /* See if we've found a better approximation to
12609 POS_BEFORE or to POS_AFTER. Note that we want the
12610 first (leftmost) glyph of all those that are the
12611 closest from below, and the last (rightmost) of all
12612 those from above. */
12613 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
12615 pos_before
= glyph
->charpos
;
12616 glyph_before
= glyph
;
12618 else if (0 < dpos
&& dpos
<= pos_after
- pt_old
)
12620 pos_after
= glyph
->charpos
;
12621 glyph_after
= glyph
;
12624 else if (dpos
== 0)
12625 match_with_avoid_cursor
= 1;
12627 else if (STRINGP (glyph
->object
))
12629 Lisp_Object chprop
;
12630 int glyph_pos
= glyph
->charpos
;
12632 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
12634 if (INTEGERP (chprop
))
12636 bpos_covered
= bpos_max
+ XINT (chprop
);
12637 /* If the `cursor' property covers buffer positions up
12638 to and including point, we should display cursor on
12639 this glyph. Note that overlays and text properties
12640 with string values stop bidi reordering, so every
12641 buffer position to the left of the string is always
12642 smaller than any position to the right of the
12643 string. Therefore, if a `cursor' property on one
12644 of the string's characters has an integer value, we
12645 will break out of the loop below _before_ we get to
12646 the position match above. IOW, integer values of
12647 the `cursor' property override the "exact match for
12648 point" strategy of positioning the cursor. */
12649 /* Implementation note: bpos_max == pt_old when, e.g.,
12650 we are in an empty line, where bpos_max is set to
12651 MATRIX_ROW_START_CHARPOS, see above. */
12652 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
12661 x
+= glyph
->pixel_width
;
12664 else if (glyph
> end
) /* row is reversed */
12665 while (!INTEGERP (glyph
->object
))
12667 if (BUFFERP (glyph
->object
))
12669 EMACS_INT dpos
= glyph
->charpos
- pt_old
;
12671 if (glyph
->charpos
> bpos_max
)
12672 bpos_max
= glyph
->charpos
;
12673 if (!glyph
->avoid_cursor_p
)
12677 match_with_avoid_cursor
= 0;
12680 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
12682 pos_before
= glyph
->charpos
;
12683 glyph_before
= glyph
;
12685 else if (0 < dpos
&& dpos
<= pos_after
- pt_old
)
12687 pos_after
= glyph
->charpos
;
12688 glyph_after
= glyph
;
12691 else if (dpos
== 0)
12692 match_with_avoid_cursor
= 1;
12694 else if (STRINGP (glyph
->object
))
12696 Lisp_Object chprop
;
12697 int glyph_pos
= glyph
->charpos
;
12699 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
12701 if (INTEGERP (chprop
))
12703 bpos_covered
= bpos_max
+ XINT (chprop
);
12704 /* If the `cursor' property covers buffer positions up
12705 to and including point, we should display cursor on
12707 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
12716 if (glyph
== glyphs_end
) /* don't dereference outside TEXT_AREA */
12718 x
--; /* can't use any pixel_width */
12721 x
-= glyph
->pixel_width
;
12724 /* Step 2: If we didn't find an exact match for point, we need to
12725 look for a proper place to put the cursor among glyphs between
12726 GLYPH_BEFORE and GLYPH_AFTER. */
12727 if (!((row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
12728 && BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
12729 && bpos_covered
< pt_old
)
12731 if (row
->ends_in_ellipsis_p
&& pos_after
== last_pos
)
12733 EMACS_INT ellipsis_pos
;
12735 /* Scan back over the ellipsis glyphs. */
12736 if (!row
->reversed_p
)
12738 ellipsis_pos
= (glyph
- 1)->charpos
;
12739 while (glyph
> row
->glyphs
[TEXT_AREA
]
12740 && (glyph
- 1)->charpos
== ellipsis_pos
)
12741 glyph
--, x
-= glyph
->pixel_width
;
12742 /* That loop always goes one position too far, including
12743 the glyph before the ellipsis. So scan forward over
12745 x
+= glyph
->pixel_width
;
12748 else /* row is reversed */
12750 ellipsis_pos
= (glyph
+ 1)->charpos
;
12751 while (glyph
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
12752 && (glyph
+ 1)->charpos
== ellipsis_pos
)
12753 glyph
++, x
+= glyph
->pixel_width
;
12754 x
-= glyph
->pixel_width
;
12758 else if (match_with_avoid_cursor
12759 /* zero-width characters produce no glyphs */
12760 || ((row
->reversed_p
12761 ? glyph_after
> glyphs_end
12762 : glyph_after
< glyphs_end
)
12763 && eabs (glyph_after
- glyph_before
) == 1))
12765 cursor
= glyph_after
;
12768 else if (string_seen
)
12770 int incr
= row
->reversed_p
? -1 : +1;
12772 /* Need to find the glyph that came out of a string which is
12773 present at point. That glyph is somewhere between
12774 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12775 positioned between POS_BEFORE and POS_AFTER in the
12777 struct glyph
*stop
= glyph_after
;
12778 EMACS_INT pos
= pos_before
;
12781 for (glyph
= glyph_before
+ incr
;
12782 row
->reversed_p
? glyph
> stop
: glyph
< stop
; )
12785 /* Any glyphs that come from the buffer are here because
12786 of bidi reordering. Skip them, and only pay
12787 attention to glyphs that came from some string. */
12788 if (STRINGP (glyph
->object
))
12793 str
= glyph
->object
;
12794 tem
= string_buffer_position_lim (w
, str
, pos
, pos_after
, 0);
12795 if (tem
== 0 /* from overlay */
12798 /* If the string from which this glyph came is
12799 found in the buffer at point, then we've
12800 found the glyph we've been looking for. If
12801 it comes from an overlay (tem == 0), and it
12802 has the `cursor' property on one of its
12803 glyphs, record that glyph as a candidate for
12804 displaying the cursor. (As in the
12805 unidirectional version, we will display the
12806 cursor on the last candidate we find.) */
12807 if (tem
== 0 || tem
== pt_old
)
12809 /* The glyphs from this string could have
12810 been reordered. Find the one with the
12811 smallest string position. Or there could
12812 be a character in the string with the
12813 `cursor' property, which means display
12814 cursor on that character's glyph. */
12815 int strpos
= glyph
->charpos
;
12818 for (glyph
+= incr
;
12819 (row
->reversed_p
? glyph
> stop
: glyph
< stop
)
12820 && EQ (glyph
->object
, str
);
12824 int gpos
= glyph
->charpos
;
12826 cprop
= Fget_char_property (make_number (gpos
),
12834 if (glyph
->charpos
< strpos
)
12836 strpos
= glyph
->charpos
;
12845 pos
= tem
+ 1; /* don't find previous instances */
12847 /* This string is not what we want; skip all of the
12848 glyphs that came from it. */
12851 while ((row
->reversed_p
? glyph
> stop
: glyph
< stop
)
12852 && EQ (glyph
->object
, str
));
12858 /* If we reached the end of the line, and END was from a string,
12859 the cursor is not on this line. */
12861 && (row
->reversed_p
? glyph
<= end
: glyph
>= end
)
12862 && STRINGP (end
->object
)
12863 && row
->continued_p
)
12869 if (cursor
!= NULL
)
12875 /* Need to compute x that corresponds to GLYPH. */
12876 for (g
= row
->glyphs
[TEXT_AREA
], x
= row
->x
; g
< glyph
; g
++)
12878 if (g
>= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
])
12880 x
+= g
->pixel_width
;
12884 /* ROW could be part of a continued line, which, under bidi
12885 reordering, might have other rows whose start and end charpos
12886 occlude point. Only set w->cursor if we found a better
12887 approximation to the cursor position than we have from previously
12888 examined candidate rows belonging to the same continued line. */
12889 if (/* we already have a candidate row */
12890 w
->cursor
.vpos
>= 0
12891 /* that candidate is not the row we are processing */
12892 && MATRIX_ROW (matrix
, w
->cursor
.vpos
) != row
12893 /* the row we are processing is part of a continued line */
12894 && (row
->continued_p
|| MATRIX_ROW_CONTINUATION_LINE_P (row
))
12895 /* Make sure cursor.vpos specifies a row whose start and end
12896 charpos occlude point. This is because some callers of this
12897 function leave cursor.vpos at the row where the cursor was
12898 displayed during the last redisplay cycle. */
12899 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
)) <= pt_old
12900 && pt_old
< MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
)))
12903 MATRIX_ROW_GLYPH_START (matrix
, w
->cursor
.vpos
) + w
->cursor
.hpos
;
12905 /* Don't consider glyphs that are outside TEXT_AREA. */
12906 if (!(row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
))
12908 /* Keep the candidate whose buffer position is the closest to
12910 if (/* previous candidate is a glyph in TEXT_AREA of that row */
12911 w
->cursor
.hpos
>= 0
12912 && w
->cursor
.hpos
< MATRIX_ROW_USED (matrix
, w
->cursor
.vpos
)
12913 && BUFFERP (g1
->object
)
12914 && (g1
->charpos
== pt_old
/* an exact match always wins */
12915 || (BUFFERP (glyph
->object
)
12916 && eabs (g1
->charpos
- pt_old
)
12917 < eabs (glyph
->charpos
- pt_old
))))
12919 /* If this candidate gives an exact match, use that. */
12920 if (!(BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
12921 /* Otherwise, keep the candidate that comes from a row
12922 spanning less buffer positions. This may win when one or
12923 both candidate positions are on glyphs that came from
12924 display strings, for which we cannot compare buffer
12926 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
12927 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
12928 < MATRIX_ROW_END_CHARPOS (row
) - MATRIX_ROW_START_CHARPOS (row
))
12931 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
12933 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
12934 w
->cursor
.y
= row
->y
+ dy
;
12936 if (w
== XWINDOW (selected_window
))
12938 if (!row
->continued_p
12939 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
12942 this_line_buffer
= XBUFFER (w
->buffer
);
12944 CHARPOS (this_line_start_pos
)
12945 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
12946 BYTEPOS (this_line_start_pos
)
12947 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
12949 CHARPOS (this_line_end_pos
)
12950 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
12951 BYTEPOS (this_line_end_pos
)
12952 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
12954 this_line_y
= w
->cursor
.y
;
12955 this_line_pixel_height
= row
->height
;
12956 this_line_vpos
= w
->cursor
.vpos
;
12957 this_line_start_x
= row
->x
;
12960 CHARPOS (this_line_start_pos
) = 0;
12967 /* Run window scroll functions, if any, for WINDOW with new window
12968 start STARTP. Sets the window start of WINDOW to that position.
12970 We assume that the window's buffer is really current. */
12972 static INLINE
struct text_pos
12973 run_window_scroll_functions (Lisp_Object window
, struct text_pos startp
)
12975 struct window
*w
= XWINDOW (window
);
12976 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
12978 if (current_buffer
!= XBUFFER (w
->buffer
))
12981 if (!NILP (Vwindow_scroll_functions
))
12983 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
12984 make_number (CHARPOS (startp
)));
12985 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12986 /* In case the hook functions switch buffers. */
12987 if (current_buffer
!= XBUFFER (w
->buffer
))
12988 set_buffer_internal_1 (XBUFFER (w
->buffer
));
12995 /* Make sure the line containing the cursor is fully visible.
12996 A value of 1 means there is nothing to be done.
12997 (Either the line is fully visible, or it cannot be made so,
12998 or we cannot tell.)
13000 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13001 is higher than window.
13003 A value of 0 means the caller should do scrolling
13004 as if point had gone off the screen. */
13007 cursor_row_fully_visible_p (struct window
*w
, int force_p
, int current_matrix_p
)
13009 struct glyph_matrix
*matrix
;
13010 struct glyph_row
*row
;
13013 if (!make_cursor_line_fully_visible_p
)
13016 /* It's not always possible to find the cursor, e.g, when a window
13017 is full of overlay strings. Don't do anything in that case. */
13018 if (w
->cursor
.vpos
< 0)
13021 matrix
= current_matrix_p
? w
->current_matrix
: w
->desired_matrix
;
13022 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
13024 /* If the cursor row is not partially visible, there's nothing to do. */
13025 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
))
13028 /* If the row the cursor is in is taller than the window's height,
13029 it's not clear what to do, so do nothing. */
13030 window_height
= window_box_height (w
);
13031 if (row
->height
>= window_height
)
13033 if (!force_p
|| MINI_WINDOW_P (w
)
13034 || w
->vscroll
|| w
->cursor
.vpos
== 0)
13041 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13042 non-zero means only WINDOW is redisplayed in redisplay_internal.
13043 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
13044 in redisplay_window to bring a partially visible line into view in
13045 the case that only the cursor has moved.
13047 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13048 last screen line's vertical height extends past the end of the screen.
13052 1 if scrolling succeeded
13054 0 if scrolling didn't find point.
13056 -1 if new fonts have been loaded so that we must interrupt
13057 redisplay, adjust glyph matrices, and try again. */
13063 SCROLLING_NEED_LARGER_MATRICES
13067 try_scrolling (Lisp_Object window
, int just_this_one_p
,
13068 EMACS_INT scroll_conservatively
, EMACS_INT scroll_step
,
13069 int temp_scroll_step
, int last_line_misfit
)
13071 struct window
*w
= XWINDOW (window
);
13072 struct frame
*f
= XFRAME (w
->frame
);
13073 struct text_pos pos
, startp
;
13075 int this_scroll_margin
, scroll_max
, rc
, height
;
13076 int dy
= 0, amount_to_scroll
= 0, scroll_down_p
= 0;
13077 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
13078 Lisp_Object aggressive
;
13079 int scroll_limit
= INT_MAX
/ FRAME_LINE_HEIGHT (f
);
13082 debug_method_add (w
, "try_scrolling");
13085 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
13087 /* Compute scroll margin height in pixels. We scroll when point is
13088 within this distance from the top or bottom of the window. */
13089 if (scroll_margin
> 0)
13090 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4)
13091 * FRAME_LINE_HEIGHT (f
);
13093 this_scroll_margin
= 0;
13095 /* Force scroll_conservatively to have a reasonable value, to avoid
13096 overflow while computing how much to scroll. Note that the user
13097 can supply scroll-conservatively equal to `most-positive-fixnum',
13098 which can be larger than INT_MAX. */
13099 if (scroll_conservatively
> scroll_limit
)
13101 scroll_conservatively
= scroll_limit
;
13102 scroll_max
= INT_MAX
;
13104 else if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
13105 /* Compute how much we should try to scroll maximally to bring
13106 point into view. */
13107 scroll_max
= (max (scroll_step
,
13108 max (scroll_conservatively
, temp_scroll_step
))
13109 * FRAME_LINE_HEIGHT (f
));
13110 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
13111 || NUMBERP (current_buffer
->scroll_up_aggressively
))
13112 /* We're trying to scroll because of aggressive scrolling but no
13113 scroll_step is set. Choose an arbitrary one. */
13114 scroll_max
= 10 * FRAME_LINE_HEIGHT (f
);
13120 /* Decide whether to scroll down. */
13121 if (PT
> CHARPOS (startp
))
13123 int scroll_margin_y
;
13125 /* Compute the pixel ypos of the scroll margin, then move it to
13126 either that ypos or PT, whichever comes first. */
13127 start_display (&it
, w
, startp
);
13128 scroll_margin_y
= it
.last_visible_y
- this_scroll_margin
13129 - FRAME_LINE_HEIGHT (f
) * extra_scroll_margin_lines
;
13130 move_it_to (&it
, PT
, -1, scroll_margin_y
- 1, -1,
13131 (MOVE_TO_POS
| MOVE_TO_Y
));
13133 if (PT
> CHARPOS (it
.current
.pos
))
13135 int y0
= line_bottom_y (&it
);
13136 /* Compute how many pixels below window bottom to stop searching
13137 for PT. This avoids costly search for PT that is far away if
13138 the user limited scrolling by a small number of lines, but
13139 always finds PT if scroll_conservatively is set to a large
13140 number, such as most-positive-fixnum. */
13141 int slack
= max (scroll_max
, 10 * FRAME_LINE_HEIGHT (f
));
13143 slack
>= INT_MAX
- it
.last_visible_y
13145 : it
.last_visible_y
+ slack
;
13147 /* Compute the distance from the scroll margin to PT or to
13148 the scroll limit, whichever comes first. This should
13149 include the height of the cursor line, to make that line
13151 move_it_to (&it
, PT
, -1, y_to_move
,
13152 -1, MOVE_TO_POS
| MOVE_TO_Y
);
13153 dy
= line_bottom_y (&it
) - y0
;
13155 if (dy
> scroll_max
)
13156 return SCROLLING_FAILED
;
13164 /* Point is in or below the bottom scroll margin, so move the
13165 window start down. If scrolling conservatively, move it just
13166 enough down to make point visible. If scroll_step is set,
13167 move it down by scroll_step. */
13168 if (scroll_conservatively
)
13170 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
13171 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
13172 else if (scroll_step
|| temp_scroll_step
)
13173 amount_to_scroll
= scroll_max
;
13176 aggressive
= current_buffer
->scroll_up_aggressively
;
13177 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
13178 if (NUMBERP (aggressive
))
13180 double float_amount
= XFLOATINT (aggressive
) * height
;
13181 amount_to_scroll
= float_amount
;
13182 if (amount_to_scroll
== 0 && float_amount
> 0)
13183 amount_to_scroll
= 1;
13187 if (amount_to_scroll
<= 0)
13188 return SCROLLING_FAILED
;
13190 start_display (&it
, w
, startp
);
13191 if (scroll_max
< INT_MAX
)
13192 move_it_vertically (&it
, amount_to_scroll
);
13195 /* Extra precision for users who set scroll-conservatively
13196 to most-positive-fixnum: make sure the amount we scroll
13197 the window start is never less than amount_to_scroll,
13198 which was computed as distance from window bottom to
13199 point. This matters when lines at window top and lines
13200 below window bottom have different height. */
13201 struct it it1
= it
;
13202 /* We use a temporary it1 because line_bottom_y can modify
13203 its argument, if it moves one line down; see there. */
13204 int start_y
= line_bottom_y (&it1
);
13207 move_it_by_lines (&it
, 1, 1);
13209 } while (line_bottom_y (&it1
) - start_y
< amount_to_scroll
);
13212 /* If STARTP is unchanged, move it down another screen line. */
13213 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
13214 move_it_by_lines (&it
, 1, 1);
13215 startp
= it
.current
.pos
;
13219 struct text_pos scroll_margin_pos
= startp
;
13221 /* See if point is inside the scroll margin at the top of the
13223 if (this_scroll_margin
)
13225 start_display (&it
, w
, startp
);
13226 move_it_vertically (&it
, this_scroll_margin
);
13227 scroll_margin_pos
= it
.current
.pos
;
13230 if (PT
< CHARPOS (scroll_margin_pos
))
13232 /* Point is in the scroll margin at the top of the window or
13233 above what is displayed in the window. */
13236 /* Compute the vertical distance from PT to the scroll
13237 margin position. Give up if distance is greater than
13239 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
13240 start_display (&it
, w
, pos
);
13242 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
13243 it
.last_visible_y
, -1,
13244 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
13245 dy
= it
.current_y
- y0
;
13246 if (dy
> scroll_max
)
13247 return SCROLLING_FAILED
;
13249 /* Compute new window start. */
13250 start_display (&it
, w
, startp
);
13252 if (scroll_conservatively
)
13254 = max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
13255 else if (scroll_step
|| temp_scroll_step
)
13256 amount_to_scroll
= scroll_max
;
13259 aggressive
= current_buffer
->scroll_down_aggressively
;
13260 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
13261 if (NUMBERP (aggressive
))
13263 double float_amount
= XFLOATINT (aggressive
) * height
;
13264 amount_to_scroll
= float_amount
;
13265 if (amount_to_scroll
== 0 && float_amount
> 0)
13266 amount_to_scroll
= 1;
13270 if (amount_to_scroll
<= 0)
13271 return SCROLLING_FAILED
;
13273 move_it_vertically_backward (&it
, amount_to_scroll
);
13274 startp
= it
.current
.pos
;
13278 /* Run window scroll functions. */
13279 startp
= run_window_scroll_functions (window
, startp
);
13281 /* Display the window. Give up if new fonts are loaded, or if point
13283 if (!try_window (window
, startp
, 0))
13284 rc
= SCROLLING_NEED_LARGER_MATRICES
;
13285 else if (w
->cursor
.vpos
< 0)
13287 clear_glyph_matrix (w
->desired_matrix
);
13288 rc
= SCROLLING_FAILED
;
13292 /* Maybe forget recorded base line for line number display. */
13293 if (!just_this_one_p
13294 || current_buffer
->clip_changed
13295 || BEG_UNCHANGED
< CHARPOS (startp
))
13296 w
->base_line_number
= Qnil
;
13298 /* If cursor ends up on a partially visible line,
13299 treat that as being off the bottom of the screen. */
13300 if (! cursor_row_fully_visible_p (w
, extra_scroll_margin_lines
<= 1, 0))
13302 clear_glyph_matrix (w
->desired_matrix
);
13303 ++extra_scroll_margin_lines
;
13306 rc
= SCROLLING_SUCCESS
;
13313 /* Compute a suitable window start for window W if display of W starts
13314 on a continuation line. Value is non-zero if a new window start
13317 The new window start will be computed, based on W's width, starting
13318 from the start of the continued line. It is the start of the
13319 screen line with the minimum distance from the old start W->start. */
13322 compute_window_start_on_continuation_line (struct window
*w
)
13324 struct text_pos pos
, start_pos
;
13325 int window_start_changed_p
= 0;
13327 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
13329 /* If window start is on a continuation line... Window start may be
13330 < BEGV in case there's invisible text at the start of the
13331 buffer (M-x rmail, for example). */
13332 if (CHARPOS (start_pos
) > BEGV
13333 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
13336 struct glyph_row
*row
;
13338 /* Handle the case that the window start is out of range. */
13339 if (CHARPOS (start_pos
) < BEGV
)
13340 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
13341 else if (CHARPOS (start_pos
) > ZV
)
13342 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
13344 /* Find the start of the continued line. This should be fast
13345 because scan_buffer is fast (newline cache). */
13346 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
13347 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
13348 row
, DEFAULT_FACE_ID
);
13349 reseat_at_previous_visible_line_start (&it
);
13351 /* If the line start is "too far" away from the window start,
13352 say it takes too much time to compute a new window start. */
13353 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
13354 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
13356 int min_distance
, distance
;
13358 /* Move forward by display lines to find the new window
13359 start. If window width was enlarged, the new start can
13360 be expected to be > the old start. If window width was
13361 decreased, the new window start will be < the old start.
13362 So, we're looking for the display line start with the
13363 minimum distance from the old window start. */
13364 pos
= it
.current
.pos
;
13365 min_distance
= INFINITY
;
13366 while ((distance
= eabs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
13367 distance
< min_distance
)
13369 min_distance
= distance
;
13370 pos
= it
.current
.pos
;
13371 move_it_by_lines (&it
, 1, 0);
13374 /* Set the window start there. */
13375 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
13376 window_start_changed_p
= 1;
13380 return window_start_changed_p
;
13384 /* Try cursor movement in case text has not changed in window WINDOW,
13385 with window start STARTP. Value is
13387 CURSOR_MOVEMENT_SUCCESS if successful
13389 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13391 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13392 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13393 we want to scroll as if scroll-step were set to 1. See the code.
13395 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13396 which case we have to abort this redisplay, and adjust matrices
13401 CURSOR_MOVEMENT_SUCCESS
,
13402 CURSOR_MOVEMENT_CANNOT_BE_USED
,
13403 CURSOR_MOVEMENT_MUST_SCROLL
,
13404 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13408 try_cursor_movement (Lisp_Object window
, struct text_pos startp
, int *scroll_step
)
13410 struct window
*w
= XWINDOW (window
);
13411 struct frame
*f
= XFRAME (w
->frame
);
13412 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
13415 if (inhibit_try_cursor_movement
)
13419 /* Handle case where text has not changed, only point, and it has
13420 not moved off the frame. */
13421 if (/* Point may be in this window. */
13422 PT
>= CHARPOS (startp
)
13423 /* Selective display hasn't changed. */
13424 && !current_buffer
->clip_changed
13425 /* Function force-mode-line-update is used to force a thorough
13426 redisplay. It sets either windows_or_buffers_changed or
13427 update_mode_lines. So don't take a shortcut here for these
13429 && !update_mode_lines
13430 && !windows_or_buffers_changed
13431 && !cursor_type_changed
13432 /* Can't use this case if highlighting a region. When a
13433 region exists, cursor movement has to do more than just
13435 && !(!NILP (Vtransient_mark_mode
)
13436 && !NILP (current_buffer
->mark_active
))
13437 && NILP (w
->region_showing
)
13438 && NILP (Vshow_trailing_whitespace
)
13439 /* Right after splitting windows, last_point may be nil. */
13440 && INTEGERP (w
->last_point
)
13441 /* This code is not used for mini-buffer for the sake of the case
13442 of redisplaying to replace an echo area message; since in
13443 that case the mini-buffer contents per se are usually
13444 unchanged. This code is of no real use in the mini-buffer
13445 since the handling of this_line_start_pos, etc., in redisplay
13446 handles the same cases. */
13447 && !EQ (window
, minibuf_window
)
13448 /* When splitting windows or for new windows, it happens that
13449 redisplay is called with a nil window_end_vpos or one being
13450 larger than the window. This should really be fixed in
13451 window.c. I don't have this on my list, now, so we do
13452 approximately the same as the old redisplay code. --gerd. */
13453 && INTEGERP (w
->window_end_vpos
)
13454 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
13455 && (FRAME_WINDOW_P (f
)
13456 || !overlay_arrow_in_current_buffer_p ()))
13458 int this_scroll_margin
, top_scroll_margin
;
13459 struct glyph_row
*row
= NULL
;
13462 debug_method_add (w
, "cursor movement");
13465 /* Scroll if point within this distance from the top or bottom
13466 of the window. This is a pixel value. */
13467 if (scroll_margin
> 0)
13469 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13470 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
13473 this_scroll_margin
= 0;
13475 top_scroll_margin
= this_scroll_margin
;
13476 if (WINDOW_WANTS_HEADER_LINE_P (w
))
13477 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
13479 /* Start with the row the cursor was displayed during the last
13480 not paused redisplay. Give up if that row is not valid. */
13481 if (w
->last_cursor
.vpos
< 0
13482 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
13483 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13486 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
13487 if (row
->mode_line_p
)
13489 if (!row
->enabled_p
)
13490 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13493 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
13495 int scroll_p
= 0, must_scroll
= 0;
13496 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
13498 if (PT
> XFASTINT (w
->last_point
))
13500 /* Point has moved forward. */
13501 while (MATRIX_ROW_END_CHARPOS (row
) < PT
13502 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
13504 xassert (row
->enabled_p
);
13508 /* If the end position of a row equals the start
13509 position of the next row, and PT is at that position,
13510 we would rather display cursor in the next line. */
13511 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
13512 && MATRIX_ROW_END_CHARPOS (row
) == PT
13513 && row
< w
->current_matrix
->rows
13514 + w
->current_matrix
->nrows
- 1
13515 && MATRIX_ROW_START_CHARPOS (row
+1) == PT
13516 && !cursor_row_p (w
, row
))
13519 /* If within the scroll margin, scroll. Note that
13520 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13521 the next line would be drawn, and that
13522 this_scroll_margin can be zero. */
13523 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
13524 || PT
> MATRIX_ROW_END_CHARPOS (row
)
13525 /* Line is completely visible last line in window
13526 and PT is to be set in the next line. */
13527 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
13528 && PT
== MATRIX_ROW_END_CHARPOS (row
)
13529 && !row
->ends_at_zv_p
13530 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
13533 else if (PT
< XFASTINT (w
->last_point
))
13535 /* Cursor has to be moved backward. Note that PT >=
13536 CHARPOS (startp) because of the outer if-statement. */
13537 while (!row
->mode_line_p
13538 && (MATRIX_ROW_START_CHARPOS (row
) > PT
13539 || (MATRIX_ROW_START_CHARPOS (row
) == PT
13540 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)
13541 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13542 row
> w
->current_matrix
->rows
13543 && (row
-1)->ends_in_newline_from_string_p
))))
13544 && (row
->y
> top_scroll_margin
13545 || CHARPOS (startp
) == BEGV
))
13547 xassert (row
->enabled_p
);
13551 /* Consider the following case: Window starts at BEGV,
13552 there is invisible, intangible text at BEGV, so that
13553 display starts at some point START > BEGV. It can
13554 happen that we are called with PT somewhere between
13555 BEGV and START. Try to handle that case. */
13556 if (row
< w
->current_matrix
->rows
13557 || row
->mode_line_p
)
13559 row
= w
->current_matrix
->rows
;
13560 if (row
->mode_line_p
)
13564 /* Due to newlines in overlay strings, we may have to
13565 skip forward over overlay strings. */
13566 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
13567 && MATRIX_ROW_END_CHARPOS (row
) == PT
13568 && !cursor_row_p (w
, row
))
13571 /* If within the scroll margin, scroll. */
13572 if (row
->y
< top_scroll_margin
13573 && CHARPOS (startp
) != BEGV
)
13578 /* Cursor did not move. So don't scroll even if cursor line
13579 is partially visible, as it was so before. */
13580 rc
= CURSOR_MOVEMENT_SUCCESS
;
13583 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
13584 || PT
> MATRIX_ROW_END_CHARPOS (row
))
13586 /* if PT is not in the glyph row, give up. */
13587 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13590 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
13591 && !NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
))
13593 /* If rows are bidi-reordered and point moved, back up
13594 until we find a row that does not belong to a
13595 continuation line. This is because we must consider
13596 all rows of a continued line as candidates for the
13597 new cursor positioning, since row start and end
13598 positions change non-linearly with vertical position
13600 /* FIXME: Revisit this when glyph ``spilling'' in
13601 continuation lines' rows is implemented for
13602 bidi-reordered rows. */
13603 while (MATRIX_ROW_CONTINUATION_LINE_P (row
))
13605 xassert (row
->enabled_p
);
13607 /* If we hit the beginning of the displayed portion
13608 without finding the first row of a continued
13610 if (row
<= w
->current_matrix
->rows
)
13612 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13620 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
13621 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
)
13622 && make_cursor_line_fully_visible_p
)
13624 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
13625 && !row
->ends_at_zv_p
13626 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
13627 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13628 else if (row
->height
> window_box_height (w
))
13630 /* If we end up in a partially visible line, let's
13631 make it fully visible, except when it's taller
13632 than the window, in which case we can't do much
13635 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13639 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13640 if (!cursor_row_fully_visible_p (w
, 0, 1))
13641 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13643 rc
= CURSOR_MOVEMENT_SUCCESS
;
13647 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13648 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
13649 && !NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
))
13651 /* With bidi-reordered rows, there could be more than
13652 one candidate row whose start and end positions
13653 occlude point. We need to let set_cursor_from_row
13654 find the best candidate. */
13655 /* FIXME: Revisit this when glyph ``spilling'' in
13656 continuation lines' rows is implemented for
13657 bidi-reordered rows. */
13662 if (MATRIX_ROW_START_CHARPOS (row
) <= PT
13663 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
13664 && cursor_row_p (w
, row
))
13665 rv
|= set_cursor_from_row (w
, row
, w
->current_matrix
,
13667 /* As soon as we've found the first suitable row
13668 whose ends_at_zv_p flag is set, we are done. */
13670 && MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
)->ends_at_zv_p
)
13672 rc
= CURSOR_MOVEMENT_SUCCESS
;
13677 while ((MATRIX_ROW_CONTINUATION_LINE_P (row
)
13678 && MATRIX_ROW_BOTTOM_Y (row
) <= last_y
)
13679 || (MATRIX_ROW_START_CHARPOS (row
) == PT
13680 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
));
13681 /* If we didn't find any candidate rows, or exited the
13682 loop before all the candidates were examined, signal
13683 to the caller that this method failed. */
13684 if (rc
!= CURSOR_MOVEMENT_SUCCESS
13685 && (!rv
|| MATRIX_ROW_CONTINUATION_LINE_P (row
)))
13686 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13688 rc
= CURSOR_MOVEMENT_SUCCESS
;
13694 if (set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0))
13696 rc
= CURSOR_MOVEMENT_SUCCESS
;
13701 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
13702 && MATRIX_ROW_START_CHARPOS (row
) == PT
13703 && cursor_row_p (w
, row
));
13712 set_vertical_scroll_bar (struct window
*w
)
13714 int start
, end
, whole
;
13716 /* Calculate the start and end positions for the current window.
13717 At some point, it would be nice to choose between scrollbars
13718 which reflect the whole buffer size, with special markers
13719 indicating narrowing, and scrollbars which reflect only the
13722 Note that mini-buffers sometimes aren't displaying any text. */
13723 if (!MINI_WINDOW_P (w
)
13724 || (w
== XWINDOW (minibuf_window
)
13725 && NILP (echo_area_buffer
[0])))
13727 struct buffer
*buf
= XBUFFER (w
->buffer
);
13728 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
13729 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
13730 /* I don't think this is guaranteed to be right. For the
13731 moment, we'll pretend it is. */
13732 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
13736 if (whole
< (end
- start
))
13737 whole
= end
- start
;
13740 start
= end
= whole
= 0;
13742 /* Indicate what this scroll bar ought to be displaying now. */
13743 if (FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
13744 (*FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
13745 (w
, end
- start
, whole
, start
);
13749 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13750 selected_window is redisplayed.
13752 We can return without actually redisplaying the window if
13753 fonts_changed_p is nonzero. In that case, redisplay_internal will
13757 redisplay_window (Lisp_Object window
, int just_this_one_p
)
13759 struct window
*w
= XWINDOW (window
);
13760 struct frame
*f
= XFRAME (w
->frame
);
13761 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13762 struct buffer
*old
= current_buffer
;
13763 struct text_pos lpoint
, opoint
, startp
;
13764 int update_mode_line
;
13767 /* Record it now because it's overwritten. */
13768 int current_matrix_up_to_date_p
= 0;
13769 int used_current_matrix_p
= 0;
13770 /* This is less strict than current_matrix_up_to_date_p.
13771 It indictes that the buffer contents and narrowing are unchanged. */
13772 int buffer_unchanged_p
= 0;
13773 int temp_scroll_step
= 0;
13774 int count
= SPECPDL_INDEX ();
13776 int centering_position
= -1;
13777 int last_line_misfit
= 0;
13778 int beg_unchanged
, end_unchanged
;
13780 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
13783 /* W must be a leaf window here. */
13784 xassert (!NILP (w
->buffer
));
13786 *w
->desired_matrix
->method
= 0;
13790 reconsider_clip_changes (w
, buffer
);
13792 /* Has the mode line to be updated? */
13793 update_mode_line
= (!NILP (w
->update_mode_line
)
13794 || update_mode_lines
13795 || buffer
->clip_changed
13796 || buffer
->prevent_redisplay_optimizations_p
);
13798 if (MINI_WINDOW_P (w
))
13800 if (w
== XWINDOW (echo_area_window
)
13801 && !NILP (echo_area_buffer
[0]))
13803 if (update_mode_line
)
13804 /* We may have to update a tty frame's menu bar or a
13805 tool-bar. Example `M-x C-h C-h C-g'. */
13806 goto finish_menu_bars
;
13808 /* We've already displayed the echo area glyphs in this window. */
13809 goto finish_scroll_bars
;
13811 else if ((w
!= XWINDOW (minibuf_window
)
13812 || minibuf_level
== 0)
13813 /* When buffer is nonempty, redisplay window normally. */
13814 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
13815 /* Quail displays non-mini buffers in minibuffer window.
13816 In that case, redisplay the window normally. */
13817 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
13819 /* W is a mini-buffer window, but it's not active, so clear
13821 int yb
= window_text_bottom_y (w
);
13822 struct glyph_row
*row
;
13825 for (y
= 0, row
= w
->desired_matrix
->rows
;
13827 y
+= row
->height
, ++row
)
13828 blank_row (w
, row
, y
);
13829 goto finish_scroll_bars
;
13832 clear_glyph_matrix (w
->desired_matrix
);
13835 /* Otherwise set up data on this window; select its buffer and point
13837 /* Really select the buffer, for the sake of buffer-local
13839 set_buffer_internal_1 (XBUFFER (w
->buffer
));
13841 current_matrix_up_to_date_p
13842 = (!NILP (w
->window_end_valid
)
13843 && !current_buffer
->clip_changed
13844 && !current_buffer
->prevent_redisplay_optimizations_p
13845 && XFASTINT (w
->last_modified
) >= MODIFF
13846 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
13848 /* Run the window-bottom-change-functions
13849 if it is possible that the text on the screen has changed
13850 (either due to modification of the text, or any other reason). */
13851 if (!current_matrix_up_to_date_p
13852 && !NILP (Vwindow_text_change_functions
))
13854 safe_run_hooks (Qwindow_text_change_functions
);
13858 beg_unchanged
= BEG_UNCHANGED
;
13859 end_unchanged
= END_UNCHANGED
;
13861 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
13863 specbind (Qinhibit_point_motion_hooks
, Qt
);
13866 = (!NILP (w
->window_end_valid
)
13867 && !current_buffer
->clip_changed
13868 && XFASTINT (w
->last_modified
) >= MODIFF
13869 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
13871 /* When windows_or_buffers_changed is non-zero, we can't rely on
13872 the window end being valid, so set it to nil there. */
13873 if (windows_or_buffers_changed
)
13875 /* If window starts on a continuation line, maybe adjust the
13876 window start in case the window's width changed. */
13877 if (XMARKER (w
->start
)->buffer
== current_buffer
)
13878 compute_window_start_on_continuation_line (w
);
13880 w
->window_end_valid
= Qnil
;
13883 /* Some sanity checks. */
13884 CHECK_WINDOW_END (w
);
13885 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
13887 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
13890 /* If %c is in mode line, update it if needed. */
13891 if (!NILP (w
->column_number_displayed
)
13892 /* This alternative quickly identifies a common case
13893 where no change is needed. */
13894 && !(PT
== XFASTINT (w
->last_point
)
13895 && XFASTINT (w
->last_modified
) >= MODIFF
13896 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
13897 && (XFASTINT (w
->column_number_displayed
)
13898 != (int) current_column ())) /* iftc */
13899 update_mode_line
= 1;
13901 /* Count number of windows showing the selected buffer. An indirect
13902 buffer counts as its base buffer. */
13903 if (!just_this_one_p
)
13905 struct buffer
*current_base
, *window_base
;
13906 current_base
= current_buffer
;
13907 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
13908 if (current_base
->base_buffer
)
13909 current_base
= current_base
->base_buffer
;
13910 if (window_base
->base_buffer
)
13911 window_base
= window_base
->base_buffer
;
13912 if (current_base
== window_base
)
13916 /* Point refers normally to the selected window. For any other
13917 window, set up appropriate value. */
13918 if (!EQ (window
, selected_window
))
13920 int new_pt
= XMARKER (w
->pointm
)->charpos
;
13921 int new_pt_byte
= marker_byte_position (w
->pointm
);
13925 new_pt_byte
= BEGV_BYTE
;
13926 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
13928 else if (new_pt
> (ZV
- 1))
13931 new_pt_byte
= ZV_BYTE
;
13932 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
13935 /* We don't use SET_PT so that the point-motion hooks don't run. */
13936 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
13939 /* If any of the character widths specified in the display table
13940 have changed, invalidate the width run cache. It's true that
13941 this may be a bit late to catch such changes, but the rest of
13942 redisplay goes (non-fatally) haywire when the display table is
13943 changed, so why should we worry about doing any better? */
13944 if (current_buffer
->width_run_cache
)
13946 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
13948 if (! disptab_matches_widthtab (disptab
,
13949 XVECTOR (current_buffer
->width_table
)))
13951 invalidate_region_cache (current_buffer
,
13952 current_buffer
->width_run_cache
,
13954 recompute_width_table (current_buffer
, disptab
);
13958 /* If window-start is screwed up, choose a new one. */
13959 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
13962 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
13964 /* If someone specified a new starting point but did not insist,
13965 check whether it can be used. */
13966 if (!NILP (w
->optional_new_start
)
13967 && CHARPOS (startp
) >= BEGV
13968 && CHARPOS (startp
) <= ZV
)
13970 w
->optional_new_start
= Qnil
;
13971 start_display (&it
, w
, startp
);
13972 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
13973 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
13974 if (IT_CHARPOS (it
) == PT
)
13975 w
->force_start
= Qt
;
13976 /* IT may overshoot PT if text at PT is invisible. */
13977 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
13978 w
->force_start
= Qt
;
13983 /* Handle case where place to start displaying has been specified,
13984 unless the specified location is outside the accessible range. */
13985 if (!NILP (w
->force_start
)
13986 || w
->frozen_window_start_p
)
13988 /* We set this later on if we have to adjust point. */
13991 w
->force_start
= Qnil
;
13993 w
->window_end_valid
= Qnil
;
13995 /* Forget any recorded base line for line number display. */
13996 if (!buffer_unchanged_p
)
13997 w
->base_line_number
= Qnil
;
13999 /* Redisplay the mode line. Select the buffer properly for that.
14000 Also, run the hook window-scroll-functions
14001 because we have scrolled. */
14002 /* Note, we do this after clearing force_start because
14003 if there's an error, it is better to forget about force_start
14004 than to get into an infinite loop calling the hook functions
14005 and having them get more errors. */
14006 if (!update_mode_line
14007 || ! NILP (Vwindow_scroll_functions
))
14009 update_mode_line
= 1;
14010 w
->update_mode_line
= Qt
;
14011 startp
= run_window_scroll_functions (window
, startp
);
14014 w
->last_modified
= make_number (0);
14015 w
->last_overlay_modified
= make_number (0);
14016 if (CHARPOS (startp
) < BEGV
)
14017 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
14018 else if (CHARPOS (startp
) > ZV
)
14019 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
14021 /* Redisplay, then check if cursor has been set during the
14022 redisplay. Give up if new fonts were loaded. */
14023 /* We used to issue a CHECK_MARGINS argument to try_window here,
14024 but this causes scrolling to fail when point begins inside
14025 the scroll margin (bug#148) -- cyd */
14026 if (!try_window (window
, startp
, 0))
14028 w
->force_start
= Qt
;
14029 clear_glyph_matrix (w
->desired_matrix
);
14030 goto need_larger_matrices
;
14033 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
14035 /* If point does not appear, try to move point so it does
14036 appear. The desired matrix has been built above, so we
14037 can use it here. */
14038 new_vpos
= window_box_height (w
) / 2;
14041 if (!cursor_row_fully_visible_p (w
, 0, 0))
14043 /* Point does appear, but on a line partly visible at end of window.
14044 Move it back to a fully-visible line. */
14045 new_vpos
= window_box_height (w
);
14048 /* If we need to move point for either of the above reasons,
14049 now actually do it. */
14052 struct glyph_row
*row
;
14054 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
14055 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
14058 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
14059 MATRIX_ROW_START_BYTEPOS (row
));
14061 if (w
!= XWINDOW (selected_window
))
14062 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
14063 else if (current_buffer
== old
)
14064 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
14066 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
14068 /* If we are highlighting the region, then we just changed
14069 the region, so redisplay to show it. */
14070 if (!NILP (Vtransient_mark_mode
)
14071 && !NILP (current_buffer
->mark_active
))
14073 clear_glyph_matrix (w
->desired_matrix
);
14074 if (!try_window (window
, startp
, 0))
14075 goto need_larger_matrices
;
14080 debug_method_add (w
, "forced window start");
14085 /* Handle case where text has not changed, only point, and it has
14086 not moved off the frame, and we are not retrying after hscroll.
14087 (current_matrix_up_to_date_p is nonzero when retrying.) */
14088 if (current_matrix_up_to_date_p
14089 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
14090 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
14094 case CURSOR_MOVEMENT_SUCCESS
:
14095 used_current_matrix_p
= 1;
14098 case CURSOR_MOVEMENT_MUST_SCROLL
:
14099 goto try_to_scroll
;
14105 /* If current starting point was originally the beginning of a line
14106 but no longer is, find a new starting point. */
14107 else if (!NILP (w
->start_at_line_beg
)
14108 && !(CHARPOS (startp
) <= BEGV
14109 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
14112 debug_method_add (w
, "recenter 1");
14117 /* Try scrolling with try_window_id. Value is > 0 if update has
14118 been done, it is -1 if we know that the same window start will
14119 not work. It is 0 if unsuccessful for some other reason. */
14120 else if ((tem
= try_window_id (w
)) != 0)
14123 debug_method_add (w
, "try_window_id %d", tem
);
14126 if (fonts_changed_p
)
14127 goto need_larger_matrices
;
14131 /* Otherwise try_window_id has returned -1 which means that we
14132 don't want the alternative below this comment to execute. */
14134 else if (CHARPOS (startp
) >= BEGV
14135 && CHARPOS (startp
) <= ZV
14136 && PT
>= CHARPOS (startp
)
14137 && (CHARPOS (startp
) < ZV
14138 /* Avoid starting at end of buffer. */
14139 || CHARPOS (startp
) == BEGV
14140 || (XFASTINT (w
->last_modified
) >= MODIFF
14141 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
14144 /* If first window line is a continuation line, and window start
14145 is inside the modified region, but the first change is before
14146 current window start, we must select a new window start.
14148 However, if this is the result of a down-mouse event (e.g. by
14149 extending the mouse-drag-overlay), we don't want to select a
14150 new window start, since that would change the position under
14151 the mouse, resulting in an unwanted mouse-movement rather
14152 than a simple mouse-click. */
14153 if (NILP (w
->start_at_line_beg
)
14154 && NILP (do_mouse_tracking
)
14155 && CHARPOS (startp
) > BEGV
14156 && CHARPOS (startp
) > BEG
+ beg_unchanged
14157 && CHARPOS (startp
) <= Z
- end_unchanged
14158 /* Even if w->start_at_line_beg is nil, a new window may
14159 start at a line_beg, since that's how set_buffer_window
14160 sets it. So, we need to check the return value of
14161 compute_window_start_on_continuation_line. (See also
14163 && XMARKER (w
->start
)->buffer
== current_buffer
14164 && compute_window_start_on_continuation_line (w
))
14166 w
->force_start
= Qt
;
14167 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14172 debug_method_add (w
, "same window start");
14175 /* Try to redisplay starting at same place as before.
14176 If point has not moved off frame, accept the results. */
14177 if (!current_matrix_up_to_date_p
14178 /* Don't use try_window_reusing_current_matrix in this case
14179 because a window scroll function can have changed the
14181 || !NILP (Vwindow_scroll_functions
)
14182 || MINI_WINDOW_P (w
)
14183 || !(used_current_matrix_p
14184 = try_window_reusing_current_matrix (w
)))
14186 IF_DEBUG (debug_method_add (w
, "1"));
14187 if (try_window (window
, startp
, TRY_WINDOW_CHECK_MARGINS
) < 0)
14188 /* -1 means we need to scroll.
14189 0 means we need new matrices, but fonts_changed_p
14190 is set in that case, so we will detect it below. */
14191 goto try_to_scroll
;
14194 if (fonts_changed_p
)
14195 goto need_larger_matrices
;
14197 if (w
->cursor
.vpos
>= 0)
14199 if (!just_this_one_p
14200 || current_buffer
->clip_changed
14201 || BEG_UNCHANGED
< CHARPOS (startp
))
14202 /* Forget any recorded base line for line number display. */
14203 w
->base_line_number
= Qnil
;
14205 if (!cursor_row_fully_visible_p (w
, 1, 0))
14207 clear_glyph_matrix (w
->desired_matrix
);
14208 last_line_misfit
= 1;
14210 /* Drop through and scroll. */
14215 clear_glyph_matrix (w
->desired_matrix
);
14220 w
->last_modified
= make_number (0);
14221 w
->last_overlay_modified
= make_number (0);
14223 /* Redisplay the mode line. Select the buffer properly for that. */
14224 if (!update_mode_line
)
14226 update_mode_line
= 1;
14227 w
->update_mode_line
= Qt
;
14230 /* Try to scroll by specified few lines. */
14231 if ((scroll_conservatively
14233 || temp_scroll_step
14234 || NUMBERP (current_buffer
->scroll_up_aggressively
)
14235 || NUMBERP (current_buffer
->scroll_down_aggressively
))
14236 && !current_buffer
->clip_changed
14237 && CHARPOS (startp
) >= BEGV
14238 && CHARPOS (startp
) <= ZV
)
14240 /* The function returns -1 if new fonts were loaded, 1 if
14241 successful, 0 if not successful. */
14242 int rc
= try_scrolling (window
, just_this_one_p
,
14243 scroll_conservatively
,
14245 temp_scroll_step
, last_line_misfit
);
14248 case SCROLLING_SUCCESS
:
14251 case SCROLLING_NEED_LARGER_MATRICES
:
14252 goto need_larger_matrices
;
14254 case SCROLLING_FAILED
:
14262 /* Finally, just choose place to start which centers point */
14265 if (centering_position
< 0)
14266 centering_position
= window_box_height (w
) / 2;
14269 debug_method_add (w
, "recenter");
14272 /* w->vscroll = 0; */
14274 /* Forget any previously recorded base line for line number display. */
14275 if (!buffer_unchanged_p
)
14276 w
->base_line_number
= Qnil
;
14278 /* Move backward half the height of the window. */
14279 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
14280 it
.current_y
= it
.last_visible_y
;
14281 move_it_vertically_backward (&it
, centering_position
);
14282 xassert (IT_CHARPOS (it
) >= BEGV
);
14284 /* The function move_it_vertically_backward may move over more
14285 than the specified y-distance. If it->w is small, e.g. a
14286 mini-buffer window, we may end up in front of the window's
14287 display area. Start displaying at the start of the line
14288 containing PT in this case. */
14289 if (it
.current_y
<= 0)
14291 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
14292 move_it_vertically_backward (&it
, 0);
14296 it
.current_x
= it
.hpos
= 0;
14298 /* Set startp here explicitly in case that helps avoid an infinite loop
14299 in case the window-scroll-functions functions get errors. */
14300 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
14302 /* Run scroll hooks. */
14303 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
14305 /* Redisplay the window. */
14306 if (!current_matrix_up_to_date_p
14307 || windows_or_buffers_changed
14308 || cursor_type_changed
14309 /* Don't use try_window_reusing_current_matrix in this case
14310 because it can have changed the buffer. */
14311 || !NILP (Vwindow_scroll_functions
)
14312 || !just_this_one_p
14313 || MINI_WINDOW_P (w
)
14314 || !(used_current_matrix_p
14315 = try_window_reusing_current_matrix (w
)))
14316 try_window (window
, startp
, 0);
14318 /* If new fonts have been loaded (due to fontsets), give up. We
14319 have to start a new redisplay since we need to re-adjust glyph
14321 if (fonts_changed_p
)
14322 goto need_larger_matrices
;
14324 /* If cursor did not appear assume that the middle of the window is
14325 in the first line of the window. Do it again with the next line.
14326 (Imagine a window of height 100, displaying two lines of height
14327 60. Moving back 50 from it->last_visible_y will end in the first
14329 if (w
->cursor
.vpos
< 0)
14331 if (!NILP (w
->window_end_valid
)
14332 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
14334 clear_glyph_matrix (w
->desired_matrix
);
14335 move_it_by_lines (&it
, 1, 0);
14336 try_window (window
, it
.current
.pos
, 0);
14338 else if (PT
< IT_CHARPOS (it
))
14340 clear_glyph_matrix (w
->desired_matrix
);
14341 move_it_by_lines (&it
, -1, 0);
14342 try_window (window
, it
.current
.pos
, 0);
14346 /* Not much we can do about it. */
14350 /* Consider the following case: Window starts at BEGV, there is
14351 invisible, intangible text at BEGV, so that display starts at
14352 some point START > BEGV. It can happen that we are called with
14353 PT somewhere between BEGV and START. Try to handle that case. */
14354 if (w
->cursor
.vpos
< 0)
14356 struct glyph_row
*row
= w
->current_matrix
->rows
;
14357 if (row
->mode_line_p
)
14359 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
14362 if (!cursor_row_fully_visible_p (w
, 0, 0))
14364 /* If vscroll is enabled, disable it and try again. */
14368 clear_glyph_matrix (w
->desired_matrix
);
14372 /* If centering point failed to make the whole line visible,
14373 put point at the top instead. That has to make the whole line
14374 visible, if it can be done. */
14375 if (centering_position
== 0)
14378 clear_glyph_matrix (w
->desired_matrix
);
14379 centering_position
= 0;
14385 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14386 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
14387 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
14390 /* Display the mode line, if we must. */
14391 if ((update_mode_line
14392 /* If window not full width, must redo its mode line
14393 if (a) the window to its side is being redone and
14394 (b) we do a frame-based redisplay. This is a consequence
14395 of how inverted lines are drawn in frame-based redisplay. */
14396 || (!just_this_one_p
14397 && !FRAME_WINDOW_P (f
)
14398 && !WINDOW_FULL_WIDTH_P (w
))
14399 /* Line number to display. */
14400 || INTEGERP (w
->base_line_pos
)
14401 /* Column number is displayed and different from the one displayed. */
14402 || (!NILP (w
->column_number_displayed
)
14403 && (XFASTINT (w
->column_number_displayed
)
14404 != (int) current_column ()))) /* iftc */
14405 /* This means that the window has a mode line. */
14406 && (WINDOW_WANTS_MODELINE_P (w
)
14407 || WINDOW_WANTS_HEADER_LINE_P (w
)))
14409 display_mode_lines (w
);
14411 /* If mode line height has changed, arrange for a thorough
14412 immediate redisplay using the correct mode line height. */
14413 if (WINDOW_WANTS_MODELINE_P (w
)
14414 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
14416 fonts_changed_p
= 1;
14417 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
14418 = DESIRED_MODE_LINE_HEIGHT (w
);
14421 /* If header line height has changed, arrange for a thorough
14422 immediate redisplay using the correct header line height. */
14423 if (WINDOW_WANTS_HEADER_LINE_P (w
)
14424 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
14426 fonts_changed_p
= 1;
14427 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
14428 = DESIRED_HEADER_LINE_HEIGHT (w
);
14431 if (fonts_changed_p
)
14432 goto need_larger_matrices
;
14435 if (!line_number_displayed
14436 && !BUFFERP (w
->base_line_pos
))
14438 w
->base_line_pos
= Qnil
;
14439 w
->base_line_number
= Qnil
;
14444 /* When we reach a frame's selected window, redo the frame's menu bar. */
14445 if (update_mode_line
14446 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
14448 int redisplay_menu_p
= 0;
14449 int redisplay_tool_bar_p
= 0;
14451 if (FRAME_WINDOW_P (f
))
14453 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14454 || defined (HAVE_NS) || defined (USE_GTK)
14455 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
14457 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
14461 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
14463 if (redisplay_menu_p
)
14464 display_menu_bar (w
);
14466 #ifdef HAVE_WINDOW_SYSTEM
14467 if (FRAME_WINDOW_P (f
))
14469 #if defined (USE_GTK) || defined (HAVE_NS)
14470 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
14472 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
14473 && (FRAME_TOOL_BAR_LINES (f
) > 0
14474 || !NILP (Vauto_resize_tool_bars
));
14477 if (redisplay_tool_bar_p
&& redisplay_tool_bar (f
))
14479 ignore_mouse_drag_p
= 1;
14485 #ifdef HAVE_WINDOW_SYSTEM
14486 if (FRAME_WINDOW_P (f
)
14487 && update_window_fringes (w
, (just_this_one_p
14488 || (!used_current_matrix_p
&& !overlay_arrow_seen
)
14489 || w
->pseudo_window_p
)))
14493 if (draw_window_fringes (w
, 1))
14494 x_draw_vertical_border (w
);
14498 #endif /* HAVE_WINDOW_SYSTEM */
14500 /* We go to this label, with fonts_changed_p nonzero,
14501 if it is necessary to try again using larger glyph matrices.
14502 We have to redeem the scroll bar even in this case,
14503 because the loop in redisplay_internal expects that. */
14504 need_larger_matrices
:
14506 finish_scroll_bars
:
14508 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
14510 /* Set the thumb's position and size. */
14511 set_vertical_scroll_bar (w
);
14513 /* Note that we actually used the scroll bar attached to this
14514 window, so it shouldn't be deleted at the end of redisplay. */
14515 if (FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
)
14516 (*FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
) (w
);
14519 /* Restore current_buffer and value of point in it. The window
14520 update may have changed the buffer, so first make sure `opoint'
14521 is still valid (Bug#6177). */
14522 if (CHARPOS (opoint
) < BEGV
)
14523 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
14524 else if (CHARPOS (opoint
) > ZV
)
14525 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
14527 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
14529 set_buffer_internal_1 (old
);
14530 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14531 shorter. This can be caused by log truncation in *Messages*. */
14532 if (CHARPOS (lpoint
) <= ZV
)
14533 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
14535 unbind_to (count
, Qnil
);
14539 /* Build the complete desired matrix of WINDOW with a window start
14540 buffer position POS.
14542 Value is 1 if successful. It is zero if fonts were loaded during
14543 redisplay which makes re-adjusting glyph matrices necessary, and -1
14544 if point would appear in the scroll margins.
14545 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14546 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14550 try_window (Lisp_Object window
, struct text_pos pos
, int flags
)
14552 struct window
*w
= XWINDOW (window
);
14554 struct glyph_row
*last_text_row
= NULL
;
14555 struct frame
*f
= XFRAME (w
->frame
);
14557 /* Make POS the new window start. */
14558 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
14560 /* Mark cursor position as unknown. No overlay arrow seen. */
14561 w
->cursor
.vpos
= -1;
14562 overlay_arrow_seen
= 0;
14564 /* Initialize iterator and info to start at POS. */
14565 start_display (&it
, w
, pos
);
14567 /* Display all lines of W. */
14568 while (it
.current_y
< it
.last_visible_y
)
14570 if (display_line (&it
))
14571 last_text_row
= it
.glyph_row
- 1;
14572 if (fonts_changed_p
&& !(flags
& TRY_WINDOW_IGNORE_FONTS_CHANGE
))
14576 /* Don't let the cursor end in the scroll margins. */
14577 if ((flags
& TRY_WINDOW_CHECK_MARGINS
)
14578 && !MINI_WINDOW_P (w
))
14580 int this_scroll_margin
;
14582 if (scroll_margin
> 0)
14584 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
14585 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
14588 this_scroll_margin
= 0;
14590 if ((w
->cursor
.y
>= 0 /* not vscrolled */
14591 && w
->cursor
.y
< this_scroll_margin
14592 && CHARPOS (pos
) > BEGV
14593 && IT_CHARPOS (it
) < ZV
)
14594 /* rms: considering make_cursor_line_fully_visible_p here
14595 seems to give wrong results. We don't want to recenter
14596 when the last line is partly visible, we want to allow
14597 that case to be handled in the usual way. */
14598 || w
->cursor
.y
> it
.last_visible_y
- this_scroll_margin
- 1)
14600 w
->cursor
.vpos
= -1;
14601 clear_glyph_matrix (w
->desired_matrix
);
14606 /* If bottom moved off end of frame, change mode line percentage. */
14607 if (XFASTINT (w
->window_end_pos
) <= 0
14608 && Z
!= IT_CHARPOS (it
))
14609 w
->update_mode_line
= Qt
;
14611 /* Set window_end_pos to the offset of the last character displayed
14612 on the window from the end of current_buffer. Set
14613 window_end_vpos to its row number. */
14616 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
14617 w
->window_end_bytepos
14618 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
14620 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
14622 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
14623 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
14624 ->displays_text_p
);
14628 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
14629 w
->window_end_pos
= make_number (Z
- ZV
);
14630 w
->window_end_vpos
= make_number (0);
14633 /* But that is not valid info until redisplay finishes. */
14634 w
->window_end_valid
= Qnil
;
14640 /************************************************************************
14641 Window redisplay reusing current matrix when buffer has not changed
14642 ************************************************************************/
14644 /* Try redisplay of window W showing an unchanged buffer with a
14645 different window start than the last time it was displayed by
14646 reusing its current matrix. Value is non-zero if successful.
14647 W->start is the new window start. */
14650 try_window_reusing_current_matrix (struct window
*w
)
14652 struct frame
*f
= XFRAME (w
->frame
);
14653 struct glyph_row
*row
, *bottom_row
;
14656 struct text_pos start
, new_start
;
14657 int nrows_scrolled
, i
;
14658 struct glyph_row
*last_text_row
;
14659 struct glyph_row
*last_reused_text_row
;
14660 struct glyph_row
*start_row
;
14661 int start_vpos
, min_y
, max_y
;
14664 if (inhibit_try_window_reusing
)
14668 if (/* This function doesn't handle terminal frames. */
14669 !FRAME_WINDOW_P (f
)
14670 /* Don't try to reuse the display if windows have been split
14672 || windows_or_buffers_changed
14673 || cursor_type_changed
)
14676 /* Can't do this if region may have changed. */
14677 if ((!NILP (Vtransient_mark_mode
)
14678 && !NILP (current_buffer
->mark_active
))
14679 || !NILP (w
->region_showing
)
14680 || !NILP (Vshow_trailing_whitespace
))
14683 /* If top-line visibility has changed, give up. */
14684 if (WINDOW_WANTS_HEADER_LINE_P (w
)
14685 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
14688 /* Give up if old or new display is scrolled vertically. We could
14689 make this function handle this, but right now it doesn't. */
14690 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
14691 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
))
14694 /* The variable new_start now holds the new window start. The old
14695 start `start' can be determined from the current matrix. */
14696 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
14697 start
= start_row
->minpos
;
14698 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
14700 /* Clear the desired matrix for the display below. */
14701 clear_glyph_matrix (w
->desired_matrix
);
14703 if (CHARPOS (new_start
) <= CHARPOS (start
))
14707 /* Don't use this method if the display starts with an ellipsis
14708 displayed for invisible text. It's not easy to handle that case
14709 below, and it's certainly not worth the effort since this is
14710 not a frequent case. */
14711 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
14714 IF_DEBUG (debug_method_add (w
, "twu1"));
14716 /* Display up to a row that can be reused. The variable
14717 last_text_row is set to the last row displayed that displays
14718 text. Note that it.vpos == 0 if or if not there is a
14719 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14720 start_display (&it
, w
, new_start
);
14721 first_row_y
= it
.current_y
;
14722 w
->cursor
.vpos
= -1;
14723 last_text_row
= last_reused_text_row
= NULL
;
14725 while (it
.current_y
< it
.last_visible_y
14726 && !fonts_changed_p
)
14728 /* If we have reached into the characters in the START row,
14729 that means the line boundaries have changed. So we
14730 can't start copying with the row START. Maybe it will
14731 work to start copying with the following row. */
14732 while (IT_CHARPOS (it
) > CHARPOS (start
))
14734 /* Advance to the next row as the "start". */
14736 start
= start_row
->minpos
;
14737 /* If there are no more rows to try, or just one, give up. */
14738 if (start_row
== MATRIX_MODE_LINE_ROW (w
->current_matrix
) - 1
14739 || w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
)
14740 || CHARPOS (start
) == ZV
)
14742 clear_glyph_matrix (w
->desired_matrix
);
14746 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
14748 /* If we have reached alignment,
14749 we can copy the rest of the rows. */
14750 if (IT_CHARPOS (it
) == CHARPOS (start
))
14753 if (display_line (&it
))
14754 last_text_row
= it
.glyph_row
- 1;
14757 /* A value of current_y < last_visible_y means that we stopped
14758 at the previous window start, which in turn means that we
14759 have at least one reusable row. */
14760 if (it
.current_y
< it
.last_visible_y
)
14762 /* IT.vpos always starts from 0; it counts text lines. */
14763 nrows_scrolled
= it
.vpos
- (start_row
- MATRIX_FIRST_TEXT_ROW (w
->current_matrix
));
14765 /* Find PT if not already found in the lines displayed. */
14766 if (w
->cursor
.vpos
< 0)
14768 int dy
= it
.current_y
- start_row
->y
;
14770 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
14771 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
14773 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
14774 dy
, nrows_scrolled
);
14777 clear_glyph_matrix (w
->desired_matrix
);
14782 /* Scroll the display. Do it before the current matrix is
14783 changed. The problem here is that update has not yet
14784 run, i.e. part of the current matrix is not up to date.
14785 scroll_run_hook will clear the cursor, and use the
14786 current matrix to get the height of the row the cursor is
14788 run
.current_y
= start_row
->y
;
14789 run
.desired_y
= it
.current_y
;
14790 run
.height
= it
.last_visible_y
- it
.current_y
;
14792 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
14795 FRAME_RIF (f
)->update_window_begin_hook (w
);
14796 FRAME_RIF (f
)->clear_window_mouse_face (w
);
14797 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
14798 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
14802 /* Shift current matrix down by nrows_scrolled lines. */
14803 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
14804 rotate_matrix (w
->current_matrix
,
14806 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
14809 /* Disable lines that must be updated. */
14810 for (i
= 0; i
< nrows_scrolled
; ++i
)
14811 (start_row
+ i
)->enabled_p
= 0;
14813 /* Re-compute Y positions. */
14814 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
14815 max_y
= it
.last_visible_y
;
14816 for (row
= start_row
+ nrows_scrolled
;
14820 row
->y
= it
.current_y
;
14821 row
->visible_height
= row
->height
;
14823 if (row
->y
< min_y
)
14824 row
->visible_height
-= min_y
- row
->y
;
14825 if (row
->y
+ row
->height
> max_y
)
14826 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
14827 row
->redraw_fringe_bitmaps_p
= 1;
14829 it
.current_y
+= row
->height
;
14831 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
14832 last_reused_text_row
= row
;
14833 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
14837 /* Disable lines in the current matrix which are now
14838 below the window. */
14839 for (++row
; row
< bottom_row
; ++row
)
14840 row
->enabled_p
= row
->mode_line_p
= 0;
14843 /* Update window_end_pos etc.; last_reused_text_row is the last
14844 reused row from the current matrix containing text, if any.
14845 The value of last_text_row is the last displayed line
14846 containing text. */
14847 if (last_reused_text_row
)
14849 w
->window_end_bytepos
14850 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
14852 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
14854 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
14855 w
->current_matrix
));
14857 else if (last_text_row
)
14859 w
->window_end_bytepos
14860 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
14862 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
14864 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
14868 /* This window must be completely empty. */
14869 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
14870 w
->window_end_pos
= make_number (Z
- ZV
);
14871 w
->window_end_vpos
= make_number (0);
14873 w
->window_end_valid
= Qnil
;
14875 /* Update hint: don't try scrolling again in update_window. */
14876 w
->desired_matrix
->no_scrolling_p
= 1;
14879 debug_method_add (w
, "try_window_reusing_current_matrix 1");
14883 else if (CHARPOS (new_start
) > CHARPOS (start
))
14885 struct glyph_row
*pt_row
, *row
;
14886 struct glyph_row
*first_reusable_row
;
14887 struct glyph_row
*first_row_to_display
;
14889 int yb
= window_text_bottom_y (w
);
14891 /* Find the row starting at new_start, if there is one. Don't
14892 reuse a partially visible line at the end. */
14893 first_reusable_row
= start_row
;
14894 while (first_reusable_row
->enabled_p
14895 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
14896 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
14897 < CHARPOS (new_start
)))
14898 ++first_reusable_row
;
14900 /* Give up if there is no row to reuse. */
14901 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
14902 || !first_reusable_row
->enabled_p
14903 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
14904 != CHARPOS (new_start
)))
14907 /* We can reuse fully visible rows beginning with
14908 first_reusable_row to the end of the window. Set
14909 first_row_to_display to the first row that cannot be reused.
14910 Set pt_row to the row containing point, if there is any. */
14912 for (first_row_to_display
= first_reusable_row
;
14913 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
14914 ++first_row_to_display
)
14916 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
14917 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
14918 pt_row
= first_row_to_display
;
14921 /* Start displaying at the start of first_row_to_display. */
14922 xassert (first_row_to_display
->y
< yb
);
14923 init_to_row_start (&it
, w
, first_row_to_display
);
14925 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
14927 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
14929 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
14930 + WINDOW_HEADER_LINE_HEIGHT (w
));
14932 /* Display lines beginning with first_row_to_display in the
14933 desired matrix. Set last_text_row to the last row displayed
14934 that displays text. */
14935 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
14936 if (pt_row
== NULL
)
14937 w
->cursor
.vpos
= -1;
14938 last_text_row
= NULL
;
14939 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
14940 if (display_line (&it
))
14941 last_text_row
= it
.glyph_row
- 1;
14943 /* If point is in a reused row, adjust y and vpos of the cursor
14947 w
->cursor
.vpos
-= nrows_scrolled
;
14948 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
14951 /* Give up if point isn't in a row displayed or reused. (This
14952 also handles the case where w->cursor.vpos < nrows_scrolled
14953 after the calls to display_line, which can happen with scroll
14954 margins. See bug#1295.) */
14955 if (w
->cursor
.vpos
< 0)
14957 clear_glyph_matrix (w
->desired_matrix
);
14961 /* Scroll the display. */
14962 run
.current_y
= first_reusable_row
->y
;
14963 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
14964 run
.height
= it
.last_visible_y
- run
.current_y
;
14965 dy
= run
.current_y
- run
.desired_y
;
14970 FRAME_RIF (f
)->update_window_begin_hook (w
);
14971 FRAME_RIF (f
)->clear_window_mouse_face (w
);
14972 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
14973 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
14977 /* Adjust Y positions of reused rows. */
14978 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
14979 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
14980 max_y
= it
.last_visible_y
;
14981 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
14984 row
->visible_height
= row
->height
;
14985 if (row
->y
< min_y
)
14986 row
->visible_height
-= min_y
- row
->y
;
14987 if (row
->y
+ row
->height
> max_y
)
14988 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
14989 row
->redraw_fringe_bitmaps_p
= 1;
14992 /* Scroll the current matrix. */
14993 xassert (nrows_scrolled
> 0);
14994 rotate_matrix (w
->current_matrix
,
14996 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
14999 /* Disable rows not reused. */
15000 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
15001 row
->enabled_p
= 0;
15003 /* Point may have moved to a different line, so we cannot assume that
15004 the previous cursor position is valid; locate the correct row. */
15007 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
15008 row
< bottom_row
&& PT
>= MATRIX_ROW_END_CHARPOS (row
);
15012 w
->cursor
.y
= row
->y
;
15014 if (row
< bottom_row
)
15016 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
15017 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
15019 /* Can't use this optimization with bidi-reordered glyph
15020 rows, unless cursor is already at point. */
15021 if (!NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
))
15023 if (!(w
->cursor
.hpos
>= 0
15024 && w
->cursor
.hpos
< row
->used
[TEXT_AREA
]
15025 && BUFFERP (glyph
->object
)
15026 && glyph
->charpos
== PT
))
15031 && (!BUFFERP (glyph
->object
)
15032 || glyph
->charpos
< PT
);
15036 w
->cursor
.x
+= glyph
->pixel_width
;
15041 /* Adjust window end. A null value of last_text_row means that
15042 the window end is in reused rows which in turn means that
15043 only its vpos can have changed. */
15046 w
->window_end_bytepos
15047 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
15049 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
15051 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
15056 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
15059 w
->window_end_valid
= Qnil
;
15060 w
->desired_matrix
->no_scrolling_p
= 1;
15063 debug_method_add (w
, "try_window_reusing_current_matrix 2");
15073 /************************************************************************
15074 Window redisplay reusing current matrix when buffer has changed
15075 ************************************************************************/
15077 static struct glyph_row
*find_last_unchanged_at_beg_row (struct window
*);
15078 static struct glyph_row
*find_first_unchanged_at_end_row (struct window
*,
15080 static struct glyph_row
*
15081 find_last_row_displaying_text (struct glyph_matrix
*, struct it
*,
15082 struct glyph_row
*);
15085 /* Return the last row in MATRIX displaying text. If row START is
15086 non-null, start searching with that row. IT gives the dimensions
15087 of the display. Value is null if matrix is empty; otherwise it is
15088 a pointer to the row found. */
15090 static struct glyph_row
*
15091 find_last_row_displaying_text (struct glyph_matrix
*matrix
, struct it
*it
,
15092 struct glyph_row
*start
)
15094 struct glyph_row
*row
, *row_found
;
15096 /* Set row_found to the last row in IT->w's current matrix
15097 displaying text. The loop looks funny but think of partially
15100 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
15101 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
15103 xassert (row
->enabled_p
);
15105 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
15114 /* Return the last row in the current matrix of W that is not affected
15115 by changes at the start of current_buffer that occurred since W's
15116 current matrix was built. Value is null if no such row exists.
15118 BEG_UNCHANGED us the number of characters unchanged at the start of
15119 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15120 first changed character in current_buffer. Characters at positions <
15121 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15122 when the current matrix was built. */
15124 static struct glyph_row
*
15125 find_last_unchanged_at_beg_row (struct window
*w
)
15127 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
15128 struct glyph_row
*row
;
15129 struct glyph_row
*row_found
= NULL
;
15130 int yb
= window_text_bottom_y (w
);
15132 /* Find the last row displaying unchanged text. */
15133 for (row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
15134 MATRIX_ROW_DISPLAYS_TEXT_P (row
)
15135 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
;
15138 if (/* If row ends before first_changed_pos, it is unchanged,
15139 except in some case. */
15140 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
15141 /* When row ends in ZV and we write at ZV it is not
15143 && !row
->ends_at_zv_p
15144 /* When first_changed_pos is the end of a continued line,
15145 row is not unchanged because it may be no longer
15147 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
15148 && (row
->continued_p
15149 || row
->exact_window_width_line_p
)))
15152 /* Stop if last visible row. */
15153 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
15161 /* Find the first glyph row in the current matrix of W that is not
15162 affected by changes at the end of current_buffer since the
15163 time W's current matrix was built.
15165 Return in *DELTA the number of chars by which buffer positions in
15166 unchanged text at the end of current_buffer must be adjusted.
15168 Return in *DELTA_BYTES the corresponding number of bytes.
15170 Value is null if no such row exists, i.e. all rows are affected by
15173 static struct glyph_row
*
15174 find_first_unchanged_at_end_row (struct window
*w
, int *delta
, int *delta_bytes
)
15176 struct glyph_row
*row
;
15177 struct glyph_row
*row_found
= NULL
;
15179 *delta
= *delta_bytes
= 0;
15181 /* Display must not have been paused, otherwise the current matrix
15182 is not up to date. */
15183 eassert (!NILP (w
->window_end_valid
));
15185 /* A value of window_end_pos >= END_UNCHANGED means that the window
15186 end is in the range of changed text. If so, there is no
15187 unchanged row at the end of W's current matrix. */
15188 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
15191 /* Set row to the last row in W's current matrix displaying text. */
15192 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
15194 /* If matrix is entirely empty, no unchanged row exists. */
15195 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
15197 /* The value of row is the last glyph row in the matrix having a
15198 meaningful buffer position in it. The end position of row
15199 corresponds to window_end_pos. This allows us to translate
15200 buffer positions in the current matrix to current buffer
15201 positions for characters not in changed text. */
15202 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
15203 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
15204 int last_unchanged_pos
, last_unchanged_pos_old
;
15205 struct glyph_row
*first_text_row
15206 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
15208 *delta
= Z
- Z_old
;
15209 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
15211 /* Set last_unchanged_pos to the buffer position of the last
15212 character in the buffer that has not been changed. Z is the
15213 index + 1 of the last character in current_buffer, i.e. by
15214 subtracting END_UNCHANGED we get the index of the last
15215 unchanged character, and we have to add BEG to get its buffer
15217 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
15218 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
15220 /* Search backward from ROW for a row displaying a line that
15221 starts at a minimum position >= last_unchanged_pos_old. */
15222 for (; row
> first_text_row
; --row
)
15224 /* This used to abort, but it can happen.
15225 It is ok to just stop the search instead here. KFS. */
15226 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
15229 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
15234 eassert (!row_found
|| MATRIX_ROW_DISPLAYS_TEXT_P (row_found
));
15240 /* Make sure that glyph rows in the current matrix of window W
15241 reference the same glyph memory as corresponding rows in the
15242 frame's frame matrix. This function is called after scrolling W's
15243 current matrix on a terminal frame in try_window_id and
15244 try_window_reusing_current_matrix. */
15247 sync_frame_with_window_matrix_rows (struct window
*w
)
15249 struct frame
*f
= XFRAME (w
->frame
);
15250 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
15252 /* Preconditions: W must be a leaf window and full-width. Its frame
15253 must have a frame matrix. */
15254 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
15255 xassert (WINDOW_FULL_WIDTH_P (w
));
15256 xassert (!FRAME_WINDOW_P (f
));
15258 /* If W is a full-width window, glyph pointers in W's current matrix
15259 have, by definition, to be the same as glyph pointers in the
15260 corresponding frame matrix. Note that frame matrices have no
15261 marginal areas (see build_frame_matrix). */
15262 window_row
= w
->current_matrix
->rows
;
15263 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
15264 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
15265 while (window_row
< window_row_end
)
15267 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
15268 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
15270 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
15271 frame_row
->glyphs
[TEXT_AREA
] = start
;
15272 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
15273 frame_row
->glyphs
[LAST_AREA
] = end
;
15275 /* Disable frame rows whose corresponding window rows have
15276 been disabled in try_window_id. */
15277 if (!window_row
->enabled_p
)
15278 frame_row
->enabled_p
= 0;
15280 ++window_row
, ++frame_row
;
15285 /* Find the glyph row in window W containing CHARPOS. Consider all
15286 rows between START and END (not inclusive). END null means search
15287 all rows to the end of the display area of W. Value is the row
15288 containing CHARPOS or null. */
15291 row_containing_pos (struct window
*w
, int charpos
, struct glyph_row
*start
,
15292 struct glyph_row
*end
, int dy
)
15294 struct glyph_row
*row
= start
;
15295 struct glyph_row
*best_row
= NULL
;
15296 EMACS_INT mindif
= BUF_ZV (XBUFFER (w
->buffer
)) + 1;
15299 /* If we happen to start on a header-line, skip that. */
15300 if (row
->mode_line_p
)
15303 if ((end
&& row
>= end
) || !row
->enabled_p
)
15306 last_y
= window_text_bottom_y (w
) - dy
;
15310 /* Give up if we have gone too far. */
15311 if (end
&& row
>= end
)
15313 /* This formerly returned if they were equal.
15314 I think that both quantities are of a "last plus one" type;
15315 if so, when they are equal, the row is within the screen. -- rms. */
15316 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
15319 /* If it is in this row, return this row. */
15320 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
15321 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
15322 /* The end position of a row equals the start
15323 position of the next row. If CHARPOS is there, we
15324 would rather display it in the next line, except
15325 when this line ends in ZV. */
15326 && !row
->ends_at_zv_p
15327 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
15328 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
15332 if (NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
)
15333 || (!best_row
&& !row
->continued_p
))
15335 /* In bidi-reordered rows, there could be several rows
15336 occluding point, all of them belonging to the same
15337 continued line. We need to find the row which fits
15338 CHARPOS the best. */
15339 for (g
= row
->glyphs
[TEXT_AREA
];
15340 g
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
15343 if (!STRINGP (g
->object
))
15345 if (g
->charpos
> 0 && eabs (g
->charpos
- charpos
) < mindif
)
15347 mindif
= eabs (g
->charpos
- charpos
);
15349 /* Exact match always wins. */
15356 else if (best_row
&& !row
->continued_p
)
15363 /* Try to redisplay window W by reusing its existing display. W's
15364 current matrix must be up to date when this function is called,
15365 i.e. window_end_valid must not be nil.
15369 1 if display has been updated
15370 0 if otherwise unsuccessful
15371 -1 if redisplay with same window start is known not to succeed
15373 The following steps are performed:
15375 1. Find the last row in the current matrix of W that is not
15376 affected by changes at the start of current_buffer. If no such row
15379 2. Find the first row in W's current matrix that is not affected by
15380 changes at the end of current_buffer. Maybe there is no such row.
15382 3. Display lines beginning with the row + 1 found in step 1 to the
15383 row found in step 2 or, if step 2 didn't find a row, to the end of
15386 4. If cursor is not known to appear on the window, give up.
15388 5. If display stopped at the row found in step 2, scroll the
15389 display and current matrix as needed.
15391 6. Maybe display some lines at the end of W, if we must. This can
15392 happen under various circumstances, like a partially visible line
15393 becoming fully visible, or because newly displayed lines are displayed
15394 in smaller font sizes.
15396 7. Update W's window end information. */
15399 try_window_id (struct window
*w
)
15401 struct frame
*f
= XFRAME (w
->frame
);
15402 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
15403 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
15404 struct glyph_row
*last_unchanged_at_beg_row
;
15405 struct glyph_row
*first_unchanged_at_end_row
;
15406 struct glyph_row
*row
;
15407 struct glyph_row
*bottom_row
;
15410 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
15411 struct text_pos start_pos
;
15413 int first_unchanged_at_end_vpos
= 0;
15414 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
15415 struct text_pos start
;
15416 int first_changed_charpos
, last_changed_charpos
;
15419 if (inhibit_try_window_id
)
15423 /* This is handy for debugging. */
15425 #define GIVE_UP(X) \
15427 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15431 #define GIVE_UP(X) return 0
15434 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
15436 /* Don't use this for mini-windows because these can show
15437 messages and mini-buffers, and we don't handle that here. */
15438 if (MINI_WINDOW_P (w
))
15441 /* This flag is used to prevent redisplay optimizations. */
15442 if (windows_or_buffers_changed
|| cursor_type_changed
)
15445 /* Verify that narrowing has not changed.
15446 Also verify that we were not told to prevent redisplay optimizations.
15447 It would be nice to further
15448 reduce the number of cases where this prevents try_window_id. */
15449 if (current_buffer
->clip_changed
15450 || current_buffer
->prevent_redisplay_optimizations_p
)
15453 /* Window must either use window-based redisplay or be full width. */
15454 if (!FRAME_WINDOW_P (f
)
15455 && (!FRAME_LINE_INS_DEL_OK (f
)
15456 || !WINDOW_FULL_WIDTH_P (w
)))
15459 /* Give up if point is known NOT to appear in W. */
15460 if (PT
< CHARPOS (start
))
15463 /* Another way to prevent redisplay optimizations. */
15464 if (XFASTINT (w
->last_modified
) == 0)
15467 /* Verify that window is not hscrolled. */
15468 if (XFASTINT (w
->hscroll
) != 0)
15471 /* Verify that display wasn't paused. */
15472 if (NILP (w
->window_end_valid
))
15475 /* Can't use this if highlighting a region because a cursor movement
15476 will do more than just set the cursor. */
15477 if (!NILP (Vtransient_mark_mode
)
15478 && !NILP (current_buffer
->mark_active
))
15481 /* Likewise if highlighting trailing whitespace. */
15482 if (!NILP (Vshow_trailing_whitespace
))
15485 /* Likewise if showing a region. */
15486 if (!NILP (w
->region_showing
))
15489 /* Can't use this if overlay arrow position and/or string have
15491 if (overlay_arrows_changed_p ())
15494 /* When word-wrap is on, adding a space to the first word of a
15495 wrapped line can change the wrap position, altering the line
15496 above it. It might be worthwhile to handle this more
15497 intelligently, but for now just redisplay from scratch. */
15498 if (!NILP (XBUFFER (w
->buffer
)->word_wrap
))
15501 /* Under bidi reordering, adding or deleting a character in the
15502 beginning of a paragraph, before the first strong directional
15503 character, can change the base direction of the paragraph (unless
15504 the buffer specifies a fixed paragraph direction), which will
15505 require to redisplay the whole paragraph. It might be worthwhile
15506 to find the paragraph limits and widen the range of redisplayed
15507 lines to that, but for now just give up this optimization and
15508 redisplay from scratch. */
15509 if (!NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
)
15510 && NILP (XBUFFER (w
->buffer
)->bidi_paragraph_direction
))
15513 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15514 only if buffer has really changed. The reason is that the gap is
15515 initially at Z for freshly visited files. The code below would
15516 set end_unchanged to 0 in that case. */
15517 if (MODIFF
> SAVE_MODIFF
15518 /* This seems to happen sometimes after saving a buffer. */
15519 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
15521 if (GPT
- BEG
< BEG_UNCHANGED
)
15522 BEG_UNCHANGED
= GPT
- BEG
;
15523 if (Z
- GPT
< END_UNCHANGED
)
15524 END_UNCHANGED
= Z
- GPT
;
15527 /* The position of the first and last character that has been changed. */
15528 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
15529 last_changed_charpos
= Z
- END_UNCHANGED
;
15531 /* If window starts after a line end, and the last change is in
15532 front of that newline, then changes don't affect the display.
15533 This case happens with stealth-fontification. Note that although
15534 the display is unchanged, glyph positions in the matrix have to
15535 be adjusted, of course. */
15536 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
15537 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
15538 && ((last_changed_charpos
< CHARPOS (start
)
15539 && CHARPOS (start
) == BEGV
)
15540 || (last_changed_charpos
< CHARPOS (start
) - 1
15541 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
15543 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
15544 struct glyph_row
*r0
;
15546 /* Compute how many chars/bytes have been added to or removed
15547 from the buffer. */
15548 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
15549 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
15551 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
15553 /* Give up if PT is not in the window. Note that it already has
15554 been checked at the start of try_window_id that PT is not in
15555 front of the window start. */
15556 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
15559 /* If window start is unchanged, we can reuse the whole matrix
15560 as is, after adjusting glyph positions. No need to compute
15561 the window end again, since its offset from Z hasn't changed. */
15562 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
15563 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
15564 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
15565 /* PT must not be in a partially visible line. */
15566 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
15567 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
15569 /* Adjust positions in the glyph matrix. */
15570 if (delta
|| delta_bytes
)
15572 struct glyph_row
*r1
15573 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
15574 increment_matrix_positions (w
->current_matrix
,
15575 MATRIX_ROW_VPOS (r0
, current_matrix
),
15576 MATRIX_ROW_VPOS (r1
, current_matrix
),
15577 delta
, delta_bytes
);
15580 /* Set the cursor. */
15581 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
15583 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
15590 /* Handle the case that changes are all below what is displayed in
15591 the window, and that PT is in the window. This shortcut cannot
15592 be taken if ZV is visible in the window, and text has been added
15593 there that is visible in the window. */
15594 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
15595 /* ZV is not visible in the window, or there are no
15596 changes at ZV, actually. */
15597 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
15598 || first_changed_charpos
== last_changed_charpos
))
15600 struct glyph_row
*r0
;
15602 /* Give up if PT is not in the window. Note that it already has
15603 been checked at the start of try_window_id that PT is not in
15604 front of the window start. */
15605 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
15608 /* If window start is unchanged, we can reuse the whole matrix
15609 as is, without changing glyph positions since no text has
15610 been added/removed in front of the window end. */
15611 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
15612 if (TEXT_POS_EQUAL_P (start
, r0
->minpos
)
15613 /* PT must not be in a partially visible line. */
15614 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
15615 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
15617 /* We have to compute the window end anew since text
15618 could have been added/removed after it. */
15620 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
15621 w
->window_end_bytepos
15622 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
15624 /* Set the cursor. */
15625 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
15627 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
15634 /* Give up if window start is in the changed area.
15636 The condition used to read
15638 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15640 but why that was tested escapes me at the moment. */
15641 if (CHARPOS (start
) >= first_changed_charpos
15642 && CHARPOS (start
) <= last_changed_charpos
)
15645 /* Check that window start agrees with the start of the first glyph
15646 row in its current matrix. Check this after we know the window
15647 start is not in changed text, otherwise positions would not be
15649 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
15650 if (!TEXT_POS_EQUAL_P (start
, row
->minpos
))
15653 /* Give up if the window ends in strings. Overlay strings
15654 at the end are difficult to handle, so don't try. */
15655 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
15656 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
15659 /* Compute the position at which we have to start displaying new
15660 lines. Some of the lines at the top of the window might be
15661 reusable because they are not displaying changed text. Find the
15662 last row in W's current matrix not affected by changes at the
15663 start of current_buffer. Value is null if changes start in the
15664 first line of window. */
15665 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
15666 if (last_unchanged_at_beg_row
)
15668 /* Avoid starting to display in the moddle of a character, a TAB
15669 for instance. This is easier than to set up the iterator
15670 exactly, and it's not a frequent case, so the additional
15671 effort wouldn't really pay off. */
15672 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
15673 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
15674 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
15675 --last_unchanged_at_beg_row
;
15677 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
15680 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
15682 start_pos
= it
.current
.pos
;
15684 /* Start displaying new lines in the desired matrix at the same
15685 vpos we would use in the current matrix, i.e. below
15686 last_unchanged_at_beg_row. */
15687 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
15689 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
15690 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
15692 xassert (it
.hpos
== 0 && it
.current_x
== 0);
15696 /* There are no reusable lines at the start of the window.
15697 Start displaying in the first text line. */
15698 start_display (&it
, w
, start
);
15699 it
.vpos
= it
.first_vpos
;
15700 start_pos
= it
.current
.pos
;
15703 /* Find the first row that is not affected by changes at the end of
15704 the buffer. Value will be null if there is no unchanged row, in
15705 which case we must redisplay to the end of the window. delta
15706 will be set to the value by which buffer positions beginning with
15707 first_unchanged_at_end_row have to be adjusted due to text
15709 first_unchanged_at_end_row
15710 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
15711 IF_DEBUG (debug_delta
= delta
);
15712 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
15714 /* Set stop_pos to the buffer position up to which we will have to
15715 display new lines. If first_unchanged_at_end_row != NULL, this
15716 is the buffer position of the start of the line displayed in that
15717 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15718 that we don't stop at a buffer position. */
15720 if (first_unchanged_at_end_row
)
15722 xassert (last_unchanged_at_beg_row
== NULL
15723 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
15725 /* If this is a continuation line, move forward to the next one
15726 that isn't. Changes in lines above affect this line.
15727 Caution: this may move first_unchanged_at_end_row to a row
15728 not displaying text. */
15729 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
15730 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
15731 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
15732 < it
.last_visible_y
))
15733 ++first_unchanged_at_end_row
;
15735 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
15736 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
15737 >= it
.last_visible_y
))
15738 first_unchanged_at_end_row
= NULL
;
15741 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
15743 first_unchanged_at_end_vpos
15744 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
15745 xassert (stop_pos
>= Z
- END_UNCHANGED
);
15748 else if (last_unchanged_at_beg_row
== NULL
)
15754 /* Either there is no unchanged row at the end, or the one we have
15755 now displays text. This is a necessary condition for the window
15756 end pos calculation at the end of this function. */
15757 xassert (first_unchanged_at_end_row
== NULL
15758 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
15760 debug_last_unchanged_at_beg_vpos
15761 = (last_unchanged_at_beg_row
15762 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
15764 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
15766 #endif /* GLYPH_DEBUG != 0 */
15769 /* Display new lines. Set last_text_row to the last new line
15770 displayed which has text on it, i.e. might end up as being the
15771 line where the window_end_vpos is. */
15772 w
->cursor
.vpos
= -1;
15773 last_text_row
= NULL
;
15774 overlay_arrow_seen
= 0;
15775 while (it
.current_y
< it
.last_visible_y
15776 && !fonts_changed_p
15777 && (first_unchanged_at_end_row
== NULL
15778 || IT_CHARPOS (it
) < stop_pos
))
15780 if (display_line (&it
))
15781 last_text_row
= it
.glyph_row
- 1;
15784 if (fonts_changed_p
)
15788 /* Compute differences in buffer positions, y-positions etc. for
15789 lines reused at the bottom of the window. Compute what we can
15791 if (first_unchanged_at_end_row
15792 /* No lines reused because we displayed everything up to the
15793 bottom of the window. */
15794 && it
.current_y
< it
.last_visible_y
)
15797 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
15799 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
15800 run
.current_y
= first_unchanged_at_end_row
->y
;
15801 run
.desired_y
= run
.current_y
+ dy
;
15802 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
15806 delta
= delta_bytes
= dvpos
= dy
15807 = run
.current_y
= run
.desired_y
= run
.height
= 0;
15808 first_unchanged_at_end_row
= NULL
;
15810 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
15813 /* Find the cursor if not already found. We have to decide whether
15814 PT will appear on this window (it sometimes doesn't, but this is
15815 not a very frequent case.) This decision has to be made before
15816 the current matrix is altered. A value of cursor.vpos < 0 means
15817 that PT is either in one of the lines beginning at
15818 first_unchanged_at_end_row or below the window. Don't care for
15819 lines that might be displayed later at the window end; as
15820 mentioned, this is not a frequent case. */
15821 if (w
->cursor
.vpos
< 0)
15823 /* Cursor in unchanged rows at the top? */
15824 if (PT
< CHARPOS (start_pos
)
15825 && last_unchanged_at_beg_row
)
15827 row
= row_containing_pos (w
, PT
,
15828 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
15829 last_unchanged_at_beg_row
+ 1, 0);
15831 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
15834 /* Start from first_unchanged_at_end_row looking for PT. */
15835 else if (first_unchanged_at_end_row
)
15837 row
= row_containing_pos (w
, PT
- delta
,
15838 first_unchanged_at_end_row
, NULL
, 0);
15840 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
15841 delta_bytes
, dy
, dvpos
);
15844 /* Give up if cursor was not found. */
15845 if (w
->cursor
.vpos
< 0)
15847 clear_glyph_matrix (w
->desired_matrix
);
15852 /* Don't let the cursor end in the scroll margins. */
15854 int this_scroll_margin
, cursor_height
;
15856 this_scroll_margin
= max (0, scroll_margin
);
15857 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
15858 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
15859 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
15861 if ((w
->cursor
.y
< this_scroll_margin
15862 && CHARPOS (start
) > BEGV
)
15863 /* Old redisplay didn't take scroll margin into account at the bottom,
15864 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15865 || (w
->cursor
.y
+ (make_cursor_line_fully_visible_p
15866 ? cursor_height
+ this_scroll_margin
15867 : 1)) > it
.last_visible_y
)
15869 w
->cursor
.vpos
= -1;
15870 clear_glyph_matrix (w
->desired_matrix
);
15875 /* Scroll the display. Do it before changing the current matrix so
15876 that xterm.c doesn't get confused about where the cursor glyph is
15878 if (dy
&& run
.height
)
15882 if (FRAME_WINDOW_P (f
))
15884 FRAME_RIF (f
)->update_window_begin_hook (w
);
15885 FRAME_RIF (f
)->clear_window_mouse_face (w
);
15886 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
15887 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
15891 /* Terminal frame. In this case, dvpos gives the number of
15892 lines to scroll by; dvpos < 0 means scroll up. */
15893 int first_unchanged_at_end_vpos
15894 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
15895 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
15896 int end
= (WINDOW_TOP_EDGE_LINE (w
)
15897 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
15898 + window_internal_height (w
));
15900 /* Perform the operation on the screen. */
15903 /* Scroll last_unchanged_at_beg_row to the end of the
15904 window down dvpos lines. */
15905 set_terminal_window (f
, end
);
15907 /* On dumb terminals delete dvpos lines at the end
15908 before inserting dvpos empty lines. */
15909 if (!FRAME_SCROLL_REGION_OK (f
))
15910 ins_del_lines (f
, end
- dvpos
, -dvpos
);
15912 /* Insert dvpos empty lines in front of
15913 last_unchanged_at_beg_row. */
15914 ins_del_lines (f
, from
, dvpos
);
15916 else if (dvpos
< 0)
15918 /* Scroll up last_unchanged_at_beg_vpos to the end of
15919 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15920 set_terminal_window (f
, end
);
15922 /* Delete dvpos lines in front of
15923 last_unchanged_at_beg_vpos. ins_del_lines will set
15924 the cursor to the given vpos and emit |dvpos| delete
15926 ins_del_lines (f
, from
+ dvpos
, dvpos
);
15928 /* On a dumb terminal insert dvpos empty lines at the
15930 if (!FRAME_SCROLL_REGION_OK (f
))
15931 ins_del_lines (f
, end
+ dvpos
, -dvpos
);
15934 set_terminal_window (f
, 0);
15940 /* Shift reused rows of the current matrix to the right position.
15941 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15943 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
15944 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
15947 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
15948 bottom_vpos
, dvpos
);
15949 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
15952 else if (dvpos
> 0)
15954 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
15955 bottom_vpos
, dvpos
);
15956 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
15957 first_unchanged_at_end_vpos
+ dvpos
, 0);
15960 /* For frame-based redisplay, make sure that current frame and window
15961 matrix are in sync with respect to glyph memory. */
15962 if (!FRAME_WINDOW_P (f
))
15963 sync_frame_with_window_matrix_rows (w
);
15965 /* Adjust buffer positions in reused rows. */
15966 if (delta
|| delta_bytes
)
15967 increment_matrix_positions (current_matrix
,
15968 first_unchanged_at_end_vpos
+ dvpos
,
15969 bottom_vpos
, delta
, delta_bytes
);
15971 /* Adjust Y positions. */
15973 shift_glyph_matrix (w
, current_matrix
,
15974 first_unchanged_at_end_vpos
+ dvpos
,
15977 if (first_unchanged_at_end_row
)
15979 first_unchanged_at_end_row
+= dvpos
;
15980 if (first_unchanged_at_end_row
->y
>= it
.last_visible_y
15981 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
))
15982 first_unchanged_at_end_row
= NULL
;
15985 /* If scrolling up, there may be some lines to display at the end of
15987 last_text_row_at_end
= NULL
;
15990 /* Scrolling up can leave for example a partially visible line
15991 at the end of the window to be redisplayed. */
15992 /* Set last_row to the glyph row in the current matrix where the
15993 window end line is found. It has been moved up or down in
15994 the matrix by dvpos. */
15995 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
15996 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
15998 /* If last_row is the window end line, it should display text. */
15999 xassert (last_row
->displays_text_p
);
16001 /* If window end line was partially visible before, begin
16002 displaying at that line. Otherwise begin displaying with the
16003 line following it. */
16004 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
16006 init_to_row_start (&it
, w
, last_row
);
16007 it
.vpos
= last_vpos
;
16008 it
.current_y
= last_row
->y
;
16012 init_to_row_end (&it
, w
, last_row
);
16013 it
.vpos
= 1 + last_vpos
;
16014 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
16018 /* We may start in a continuation line. If so, we have to
16019 get the right continuation_lines_width and current_x. */
16020 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
16021 it
.hpos
= it
.current_x
= 0;
16023 /* Display the rest of the lines at the window end. */
16024 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
16025 while (it
.current_y
< it
.last_visible_y
16026 && !fonts_changed_p
)
16028 /* Is it always sure that the display agrees with lines in
16029 the current matrix? I don't think so, so we mark rows
16030 displayed invalid in the current matrix by setting their
16031 enabled_p flag to zero. */
16032 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
16033 if (display_line (&it
))
16034 last_text_row_at_end
= it
.glyph_row
- 1;
16038 /* Update window_end_pos and window_end_vpos. */
16039 if (first_unchanged_at_end_row
16040 && !last_text_row_at_end
)
16042 /* Window end line if one of the preserved rows from the current
16043 matrix. Set row to the last row displaying text in current
16044 matrix starting at first_unchanged_at_end_row, after
16046 xassert (first_unchanged_at_end_row
->displays_text_p
);
16047 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
16048 first_unchanged_at_end_row
);
16049 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
16051 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
16052 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
16054 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
16055 xassert (w
->window_end_bytepos
>= 0);
16056 IF_DEBUG (debug_method_add (w
, "A"));
16058 else if (last_text_row_at_end
)
16061 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
16062 w
->window_end_bytepos
16063 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
16065 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
16066 xassert (w
->window_end_bytepos
>= 0);
16067 IF_DEBUG (debug_method_add (w
, "B"));
16069 else if (last_text_row
)
16071 /* We have displayed either to the end of the window or at the
16072 end of the window, i.e. the last row with text is to be found
16073 in the desired matrix. */
16075 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
16076 w
->window_end_bytepos
16077 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
16079 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
16080 xassert (w
->window_end_bytepos
>= 0);
16082 else if (first_unchanged_at_end_row
== NULL
16083 && last_text_row
== NULL
16084 && last_text_row_at_end
== NULL
)
16086 /* Displayed to end of window, but no line containing text was
16087 displayed. Lines were deleted at the end of the window. */
16088 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
16089 int vpos
= XFASTINT (w
->window_end_vpos
);
16090 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
16091 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
16094 row
== NULL
&& vpos
>= first_vpos
;
16095 --vpos
, --current_row
, --desired_row
)
16097 if (desired_row
->enabled_p
)
16099 if (desired_row
->displays_text_p
)
16102 else if (current_row
->displays_text_p
)
16106 xassert (row
!= NULL
);
16107 w
->window_end_vpos
= make_number (vpos
+ 1);
16108 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
16109 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
16110 xassert (w
->window_end_bytepos
>= 0);
16111 IF_DEBUG (debug_method_add (w
, "C"));
16116 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
16117 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
16119 /* Record that display has not been completed. */
16120 w
->window_end_valid
= Qnil
;
16121 w
->desired_matrix
->no_scrolling_p
= 1;
16129 /***********************************************************************
16130 More debugging support
16131 ***********************************************************************/
16135 void dump_glyph_row (struct glyph_row
*, int, int);
16136 void dump_glyph_matrix (struct glyph_matrix
*, int);
16137 void dump_glyph (struct glyph_row
*, struct glyph
*, int);
16140 /* Dump the contents of glyph matrix MATRIX on stderr.
16142 GLYPHS 0 means don't show glyph contents.
16143 GLYPHS 1 means show glyphs in short form
16144 GLYPHS > 1 means show glyphs in long form. */
16147 dump_glyph_matrix (matrix
, glyphs
)
16148 struct glyph_matrix
*matrix
;
16152 for (i
= 0; i
< matrix
->nrows
; ++i
)
16153 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
16157 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16158 the glyph row and area where the glyph comes from. */
16161 dump_glyph (row
, glyph
, area
)
16162 struct glyph_row
*row
;
16163 struct glyph
*glyph
;
16166 if (glyph
->type
== CHAR_GLYPH
)
16169 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16170 glyph
- row
->glyphs
[TEXT_AREA
],
16173 (BUFFERP (glyph
->object
)
16175 : (STRINGP (glyph
->object
)
16178 glyph
->pixel_width
,
16180 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
16184 glyph
->left_box_line_p
,
16185 glyph
->right_box_line_p
);
16187 else if (glyph
->type
== STRETCH_GLYPH
)
16190 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16191 glyph
- row
->glyphs
[TEXT_AREA
],
16194 (BUFFERP (glyph
->object
)
16196 : (STRINGP (glyph
->object
)
16199 glyph
->pixel_width
,
16203 glyph
->left_box_line_p
,
16204 glyph
->right_box_line_p
);
16206 else if (glyph
->type
== IMAGE_GLYPH
)
16209 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16210 glyph
- row
->glyphs
[TEXT_AREA
],
16213 (BUFFERP (glyph
->object
)
16215 : (STRINGP (glyph
->object
)
16218 glyph
->pixel_width
,
16222 glyph
->left_box_line_p
,
16223 glyph
->right_box_line_p
);
16225 else if (glyph
->type
== COMPOSITE_GLYPH
)
16228 " %5d %4c %6d %c %3d 0x%05x",
16229 glyph
- row
->glyphs
[TEXT_AREA
],
16232 (BUFFERP (glyph
->object
)
16234 : (STRINGP (glyph
->object
)
16237 glyph
->pixel_width
,
16239 if (glyph
->u
.cmp
.automatic
)
16242 glyph
->u
.cmp
.from
, glyph
->u
.cmp
.to
);
16243 fprintf (stderr
, " . %4d %1.1d%1.1d\n",
16245 glyph
->left_box_line_p
,
16246 glyph
->right_box_line_p
);
16251 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16252 GLYPHS 0 means don't show glyph contents.
16253 GLYPHS 1 means show glyphs in short form
16254 GLYPHS > 1 means show glyphs in long form. */
16257 dump_glyph_row (row
, vpos
, glyphs
)
16258 struct glyph_row
*row
;
16263 fprintf (stderr
, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16264 fprintf (stderr
, "======================================================================\n");
16266 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16267 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16269 MATRIX_ROW_START_CHARPOS (row
),
16270 MATRIX_ROW_END_CHARPOS (row
),
16271 row
->used
[TEXT_AREA
],
16272 row
->contains_overlapping_glyphs_p
,
16274 row
->truncated_on_left_p
,
16275 row
->truncated_on_right_p
,
16277 MATRIX_ROW_CONTINUATION_LINE_P (row
),
16278 row
->displays_text_p
,
16281 row
->ends_in_middle_of_char_p
,
16282 row
->starts_in_middle_of_char_p
,
16288 row
->visible_height
,
16291 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
16292 row
->end
.overlay_string_index
,
16293 row
->continuation_lines_width
);
16294 fprintf (stderr
, "%9d %5d\n",
16295 CHARPOS (row
->start
.string_pos
),
16296 CHARPOS (row
->end
.string_pos
));
16297 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
16298 row
->end
.dpvec_index
);
16305 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
16307 struct glyph
*glyph
= row
->glyphs
[area
];
16308 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
16310 /* Glyph for a line end in text. */
16311 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
16314 if (glyph
< glyph_end
)
16315 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
16317 for (; glyph
< glyph_end
; ++glyph
)
16318 dump_glyph (row
, glyph
, area
);
16321 else if (glyphs
== 1)
16325 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
16327 char *s
= (char *) alloca (row
->used
[area
] + 1);
16330 for (i
= 0; i
< row
->used
[area
]; ++i
)
16332 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
16333 if (glyph
->type
== CHAR_GLYPH
16334 && glyph
->u
.ch
< 0x80
16335 && glyph
->u
.ch
>= ' ')
16336 s
[i
] = glyph
->u
.ch
;
16342 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
16348 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
16349 Sdump_glyph_matrix
, 0, 1, "p",
16350 doc
: /* Dump the current matrix of the selected window to stderr.
16351 Shows contents of glyph row structures. With non-nil
16352 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16353 glyphs in short form, otherwise show glyphs in long form. */)
16354 (Lisp_Object glyphs
)
16356 struct window
*w
= XWINDOW (selected_window
);
16357 struct buffer
*buffer
= XBUFFER (w
->buffer
);
16359 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
16360 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
16361 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16362 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
16363 fprintf (stderr
, "=============================================\n");
16364 dump_glyph_matrix (w
->current_matrix
,
16365 NILP (glyphs
) ? 0 : XINT (glyphs
));
16370 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
16371 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
16374 struct frame
*f
= XFRAME (selected_frame
);
16375 dump_glyph_matrix (f
->current_matrix
, 1);
16380 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
16381 doc
: /* Dump glyph row ROW to stderr.
16382 GLYPH 0 means don't dump glyphs.
16383 GLYPH 1 means dump glyphs in short form.
16384 GLYPH > 1 or omitted means dump glyphs in long form. */)
16385 (Lisp_Object row
, Lisp_Object glyphs
)
16387 struct glyph_matrix
*matrix
;
16390 CHECK_NUMBER (row
);
16391 matrix
= XWINDOW (selected_window
)->current_matrix
;
16393 if (vpos
>= 0 && vpos
< matrix
->nrows
)
16394 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
16396 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
16401 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
16402 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16403 GLYPH 0 means don't dump glyphs.
16404 GLYPH 1 means dump glyphs in short form.
16405 GLYPH > 1 or omitted means dump glyphs in long form. */)
16406 (Lisp_Object row
, Lisp_Object glyphs
)
16408 struct frame
*sf
= SELECTED_FRAME ();
16409 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
16412 CHECK_NUMBER (row
);
16414 if (vpos
>= 0 && vpos
< m
->nrows
)
16415 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
16416 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
16421 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
16422 doc
: /* Toggle tracing of redisplay.
16423 With ARG, turn tracing on if and only if ARG is positive. */)
16427 trace_redisplay_p
= !trace_redisplay_p
;
16430 arg
= Fprefix_numeric_value (arg
);
16431 trace_redisplay_p
= XINT (arg
) > 0;
16438 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
16439 doc
: /* Like `format', but print result to stderr.
16440 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16441 (int nargs
, Lisp_Object
*args
)
16443 Lisp_Object s
= Fformat (nargs
, args
);
16444 fprintf (stderr
, "%s", SDATA (s
));
16448 #endif /* GLYPH_DEBUG */
16452 /***********************************************************************
16453 Building Desired Matrix Rows
16454 ***********************************************************************/
16456 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16457 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16459 static struct glyph_row
*
16460 get_overlay_arrow_glyph_row (struct window
*w
, Lisp_Object overlay_arrow_string
)
16462 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
16463 struct buffer
*buffer
= XBUFFER (w
->buffer
);
16464 struct buffer
*old
= current_buffer
;
16465 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
16466 int arrow_len
= SCHARS (overlay_arrow_string
);
16467 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
16468 const unsigned char *p
;
16471 int n_glyphs_before
;
16473 set_buffer_temp (buffer
);
16474 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
16475 it
.glyph_row
->used
[TEXT_AREA
] = 0;
16476 SET_TEXT_POS (it
.position
, 0, 0);
16478 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
16480 while (p
< arrow_end
)
16482 Lisp_Object face
, ilisp
;
16484 /* Get the next character. */
16486 it
.c
= string_char_and_length (p
, &it
.len
);
16488 it
.c
= *p
, it
.len
= 1;
16491 /* Get its face. */
16492 ilisp
= make_number (p
- arrow_string
);
16493 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
16494 it
.face_id
= compute_char_face (f
, it
.c
, face
);
16496 /* Compute its width, get its glyphs. */
16497 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
16498 SET_TEXT_POS (it
.position
, -1, -1);
16499 PRODUCE_GLYPHS (&it
);
16501 /* If this character doesn't fit any more in the line, we have
16502 to remove some glyphs. */
16503 if (it
.current_x
> it
.last_visible_x
)
16505 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
16510 set_buffer_temp (old
);
16511 return it
.glyph_row
;
16515 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16516 glyphs are only inserted for terminal frames since we can't really
16517 win with truncation glyphs when partially visible glyphs are
16518 involved. Which glyphs to insert is determined by
16519 produce_special_glyphs. */
16522 insert_left_trunc_glyphs (struct it
*it
)
16524 struct it truncate_it
;
16525 struct glyph
*from
, *end
, *to
, *toend
;
16527 xassert (!FRAME_WINDOW_P (it
->f
));
16529 /* Get the truncation glyphs. */
16531 truncate_it
.current_x
= 0;
16532 truncate_it
.face_id
= DEFAULT_FACE_ID
;
16533 truncate_it
.glyph_row
= &scratch_glyph_row
;
16534 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
16535 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
16536 truncate_it
.object
= make_number (0);
16537 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
16539 /* Overwrite glyphs from IT with truncation glyphs. */
16540 if (!it
->glyph_row
->reversed_p
)
16542 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
16543 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
16544 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
16545 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
16550 /* There may be padding glyphs left over. Overwrite them too. */
16551 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
16553 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
16559 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
16563 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16564 that back to front. */
16565 end
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
16566 from
= end
+ truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
16567 toend
= it
->glyph_row
->glyphs
[TEXT_AREA
];
16568 to
= toend
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
16570 while (from
>= end
&& to
>= toend
)
16572 while (to
>= toend
&& CHAR_GLYPH_PADDING_P (*to
))
16575 truncate_it
.glyph_row
->glyphs
[TEXT_AREA
]
16576 + truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
16577 while (from
>= end
&& to
>= toend
)
16582 /* Need to free some room before prepending additional
16584 int move_by
= from
- end
+ 1;
16585 struct glyph
*g0
= it
->glyph_row
->glyphs
[TEXT_AREA
];
16586 struct glyph
*g
= g0
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
16588 for ( ; g
>= g0
; g
--)
16590 while (from
>= end
)
16592 it
->glyph_row
->used
[TEXT_AREA
] += move_by
;
16598 /* Compute the pixel height and width of IT->glyph_row.
16600 Most of the time, ascent and height of a display line will be equal
16601 to the max_ascent and max_height values of the display iterator
16602 structure. This is not the case if
16604 1. We hit ZV without displaying anything. In this case, max_ascent
16605 and max_height will be zero.
16607 2. We have some glyphs that don't contribute to the line height.
16608 (The glyph row flag contributes_to_line_height_p is for future
16609 pixmap extensions).
16611 The first case is easily covered by using default values because in
16612 these cases, the line height does not really matter, except that it
16613 must not be zero. */
16616 compute_line_metrics (struct it
*it
)
16618 struct glyph_row
*row
= it
->glyph_row
;
16621 if (FRAME_WINDOW_P (it
->f
))
16623 int i
, min_y
, max_y
;
16625 /* The line may consist of one space only, that was added to
16626 place the cursor on it. If so, the row's height hasn't been
16628 if (row
->height
== 0)
16630 if (it
->max_ascent
+ it
->max_descent
== 0)
16631 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
16632 row
->ascent
= it
->max_ascent
;
16633 row
->height
= it
->max_ascent
+ it
->max_descent
;
16634 row
->phys_ascent
= it
->max_phys_ascent
;
16635 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
16636 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
16639 /* Compute the width of this line. */
16640 row
->pixel_width
= row
->x
;
16641 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
16642 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
16644 xassert (row
->pixel_width
>= 0);
16645 xassert (row
->ascent
>= 0 && row
->height
> 0);
16647 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
16648 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
16650 /* If first line's physical ascent is larger than its logical
16651 ascent, use the physical ascent, and make the row taller.
16652 This makes accented characters fully visible. */
16653 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
16654 && row
->phys_ascent
> row
->ascent
)
16656 row
->height
+= row
->phys_ascent
- row
->ascent
;
16657 row
->ascent
= row
->phys_ascent
;
16660 /* Compute how much of the line is visible. */
16661 row
->visible_height
= row
->height
;
16663 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
16664 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
16666 if (row
->y
< min_y
)
16667 row
->visible_height
-= min_y
- row
->y
;
16668 if (row
->y
+ row
->height
> max_y
)
16669 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
16673 row
->pixel_width
= row
->used
[TEXT_AREA
];
16674 if (row
->continued_p
)
16675 row
->pixel_width
-= it
->continuation_pixel_width
;
16676 else if (row
->truncated_on_right_p
)
16677 row
->pixel_width
-= it
->truncation_pixel_width
;
16678 row
->ascent
= row
->phys_ascent
= 0;
16679 row
->height
= row
->phys_height
= row
->visible_height
= 1;
16680 row
->extra_line_spacing
= 0;
16683 /* Compute a hash code for this row. */
16685 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
16686 for (i
= 0; i
< row
->used
[area
]; ++i
)
16687 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
16688 + row
->glyphs
[area
][i
].u
.val
16689 + row
->glyphs
[area
][i
].face_id
16690 + row
->glyphs
[area
][i
].padding_p
16691 + (row
->glyphs
[area
][i
].type
<< 2));
16693 it
->max_ascent
= it
->max_descent
= 0;
16694 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
16698 /* Append one space to the glyph row of iterator IT if doing a
16699 window-based redisplay. The space has the same face as
16700 IT->face_id. Value is non-zero if a space was added.
16702 This function is called to make sure that there is always one glyph
16703 at the end of a glyph row that the cursor can be set on under
16704 window-systems. (If there weren't such a glyph we would not know
16705 how wide and tall a box cursor should be displayed).
16707 At the same time this space let's a nicely handle clearing to the
16708 end of the line if the row ends in italic text. */
16711 append_space_for_newline (struct it
*it
, int default_face_p
)
16713 if (FRAME_WINDOW_P (it
->f
))
16715 int n
= it
->glyph_row
->used
[TEXT_AREA
];
16717 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
16718 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
16720 /* Save some values that must not be changed.
16721 Must save IT->c and IT->len because otherwise
16722 ITERATOR_AT_END_P wouldn't work anymore after
16723 append_space_for_newline has been called. */
16724 enum display_element_type saved_what
= it
->what
;
16725 int saved_c
= it
->c
, saved_len
= it
->len
;
16726 int saved_x
= it
->current_x
;
16727 int saved_face_id
= it
->face_id
;
16728 struct text_pos saved_pos
;
16729 Lisp_Object saved_object
;
16732 saved_object
= it
->object
;
16733 saved_pos
= it
->position
;
16735 it
->what
= IT_CHARACTER
;
16736 memset (&it
->position
, 0, sizeof it
->position
);
16737 it
->object
= make_number (0);
16741 if (default_face_p
)
16742 it
->face_id
= DEFAULT_FACE_ID
;
16743 else if (it
->face_before_selective_p
)
16744 it
->face_id
= it
->saved_face_id
;
16745 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
16746 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0, -1, Qnil
);
16748 PRODUCE_GLYPHS (it
);
16750 it
->override_ascent
= -1;
16751 it
->constrain_row_ascent_descent_p
= 0;
16752 it
->current_x
= saved_x
;
16753 it
->object
= saved_object
;
16754 it
->position
= saved_pos
;
16755 it
->what
= saved_what
;
16756 it
->face_id
= saved_face_id
;
16757 it
->len
= saved_len
;
16767 /* Extend the face of the last glyph in the text area of IT->glyph_row
16768 to the end of the display line. Called from display_line. If the
16769 glyph row is empty, add a space glyph to it so that we know the
16770 face to draw. Set the glyph row flag fill_line_p. If the glyph
16771 row is R2L, prepend a stretch glyph to cover the empty space to the
16772 left of the leftmost glyph. */
16775 extend_face_to_end_of_line (struct it
*it
)
16778 struct frame
*f
= it
->f
;
16780 /* If line is already filled, do nothing. Non window-system frames
16781 get a grace of one more ``pixel'' because their characters are
16782 1-``pixel'' wide, so they hit the equality too early. This grace
16783 is needed only for R2L rows that are not continued, to produce
16784 one extra blank where we could display the cursor. */
16785 if (it
->current_x
>= it
->last_visible_x
16786 + (!FRAME_WINDOW_P (f
)
16787 && it
->glyph_row
->reversed_p
16788 && !it
->glyph_row
->continued_p
))
16791 /* Face extension extends the background and box of IT->face_id
16792 to the end of the line. If the background equals the background
16793 of the frame, we don't have to do anything. */
16794 if (it
->face_before_selective_p
)
16795 face
= FACE_FROM_ID (f
, it
->saved_face_id
);
16797 face
= FACE_FROM_ID (f
, it
->face_id
);
16799 if (FRAME_WINDOW_P (f
)
16800 && it
->glyph_row
->displays_text_p
16801 && face
->box
== FACE_NO_BOX
16802 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
16804 && !it
->glyph_row
->reversed_p
)
16807 /* Set the glyph row flag indicating that the face of the last glyph
16808 in the text area has to be drawn to the end of the text area. */
16809 it
->glyph_row
->fill_line_p
= 1;
16811 /* If current character of IT is not ASCII, make sure we have the
16812 ASCII face. This will be automatically undone the next time
16813 get_next_display_element returns a multibyte character. Note
16814 that the character will always be single byte in unibyte
16816 if (!ASCII_CHAR_P (it
->c
))
16818 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0, -1, Qnil
);
16821 if (FRAME_WINDOW_P (f
))
16823 /* If the row is empty, add a space with the current face of IT,
16824 so that we know which face to draw. */
16825 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
16827 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
16828 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
16829 it
->glyph_row
->used
[TEXT_AREA
] = 1;
16831 #ifdef HAVE_WINDOW_SYSTEM
16832 if (it
->glyph_row
->reversed_p
)
16834 /* Prepend a stretch glyph to the row, such that the
16835 rightmost glyph will be drawn flushed all the way to the
16836 right margin of the window. The stretch glyph that will
16837 occupy the empty space, if any, to the left of the
16839 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (f
);
16840 struct glyph
*row_start
= it
->glyph_row
->glyphs
[TEXT_AREA
];
16841 struct glyph
*row_end
= row_start
+ it
->glyph_row
->used
[TEXT_AREA
];
16843 int row_width
, stretch_ascent
, stretch_width
;
16844 struct text_pos saved_pos
;
16845 int saved_face_id
, saved_avoid_cursor
;
16847 for (row_width
= 0, g
= row_start
; g
< row_end
; g
++)
16848 row_width
+= g
->pixel_width
;
16849 stretch_width
= window_box_width (it
->w
, TEXT_AREA
) - row_width
;
16850 if (stretch_width
> 0)
16853 (((it
->ascent
+ it
->descent
)
16854 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
16855 saved_pos
= it
->position
;
16856 memset (&it
->position
, 0, sizeof it
->position
);
16857 saved_avoid_cursor
= it
->avoid_cursor_p
;
16858 it
->avoid_cursor_p
= 1;
16859 saved_face_id
= it
->face_id
;
16860 /* The last row's stretch glyph should get the default
16861 face, to avoid painting the rest of the window with
16862 the region face, if the region ends at ZV. */
16863 if (it
->glyph_row
->ends_at_zv_p
)
16864 it
->face_id
= DEFAULT_FACE_ID
;
16866 it
->face_id
= face
->id
;
16867 append_stretch_glyph (it
, make_number (0), stretch_width
,
16868 it
->ascent
+ it
->descent
, stretch_ascent
);
16869 it
->position
= saved_pos
;
16870 it
->avoid_cursor_p
= saved_avoid_cursor
;
16871 it
->face_id
= saved_face_id
;
16874 #endif /* HAVE_WINDOW_SYSTEM */
16878 /* Save some values that must not be changed. */
16879 int saved_x
= it
->current_x
;
16880 struct text_pos saved_pos
;
16881 Lisp_Object saved_object
;
16882 enum display_element_type saved_what
= it
->what
;
16883 int saved_face_id
= it
->face_id
;
16885 saved_object
= it
->object
;
16886 saved_pos
= it
->position
;
16888 it
->what
= IT_CHARACTER
;
16889 memset (&it
->position
, 0, sizeof it
->position
);
16890 it
->object
= make_number (0);
16893 /* The last row's blank glyphs should get the default face, to
16894 avoid painting the rest of the window with the region face,
16895 if the region ends at ZV. */
16896 if (it
->glyph_row
->ends_at_zv_p
)
16897 it
->face_id
= DEFAULT_FACE_ID
;
16899 it
->face_id
= face
->id
;
16901 PRODUCE_GLYPHS (it
);
16903 while (it
->current_x
<= it
->last_visible_x
)
16904 PRODUCE_GLYPHS (it
);
16906 /* Don't count these blanks really. It would let us insert a left
16907 truncation glyph below and make us set the cursor on them, maybe. */
16908 it
->current_x
= saved_x
;
16909 it
->object
= saved_object
;
16910 it
->position
= saved_pos
;
16911 it
->what
= saved_what
;
16912 it
->face_id
= saved_face_id
;
16917 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16918 trailing whitespace. */
16921 trailing_whitespace_p (int charpos
)
16923 int bytepos
= CHAR_TO_BYTE (charpos
);
16926 while (bytepos
< ZV_BYTE
16927 && (c
= FETCH_CHAR (bytepos
),
16928 c
== ' ' || c
== '\t'))
16931 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
16933 if (bytepos
!= PT_BYTE
)
16940 /* Highlight trailing whitespace, if any, in ROW. */
16943 highlight_trailing_whitespace (struct frame
*f
, struct glyph_row
*row
)
16945 int used
= row
->used
[TEXT_AREA
];
16949 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
16950 struct glyph
*glyph
= start
+ used
- 1;
16952 if (row
->reversed_p
)
16954 /* Right-to-left rows need to be processed in the opposite
16955 direction, so swap the edge pointers. */
16957 start
= row
->glyphs
[TEXT_AREA
] + used
- 1;
16960 /* Skip over glyphs inserted to display the cursor at the
16961 end of a line, for extending the face of the last glyph
16962 to the end of the line on terminals, and for truncation
16963 and continuation glyphs. */
16964 if (!row
->reversed_p
)
16966 while (glyph
>= start
16967 && glyph
->type
== CHAR_GLYPH
16968 && INTEGERP (glyph
->object
))
16973 while (glyph
<= start
16974 && glyph
->type
== CHAR_GLYPH
16975 && INTEGERP (glyph
->object
))
16979 /* If last glyph is a space or stretch, and it's trailing
16980 whitespace, set the face of all trailing whitespace glyphs in
16981 IT->glyph_row to `trailing-whitespace'. */
16982 if ((row
->reversed_p
? glyph
<= start
: glyph
>= start
)
16983 && BUFFERP (glyph
->object
)
16984 && (glyph
->type
== STRETCH_GLYPH
16985 || (glyph
->type
== CHAR_GLYPH
16986 && glyph
->u
.ch
== ' '))
16987 && trailing_whitespace_p (glyph
->charpos
))
16989 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
16993 if (!row
->reversed_p
)
16995 while (glyph
>= start
16996 && BUFFERP (glyph
->object
)
16997 && (glyph
->type
== STRETCH_GLYPH
16998 || (glyph
->type
== CHAR_GLYPH
16999 && glyph
->u
.ch
== ' ')))
17000 (glyph
--)->face_id
= face_id
;
17004 while (glyph
<= start
17005 && BUFFERP (glyph
->object
)
17006 && (glyph
->type
== STRETCH_GLYPH
17007 || (glyph
->type
== CHAR_GLYPH
17008 && glyph
->u
.ch
== ' ')))
17009 (glyph
++)->face_id
= face_id
;
17016 /* Value is non-zero if glyph row ROW in window W should be
17017 used to hold the cursor. */
17020 cursor_row_p (struct window
*w
, struct glyph_row
*row
)
17022 int cursor_row_p
= 1;
17024 if (PT
== CHARPOS (row
->end
.pos
))
17026 /* Suppose the row ends on a string.
17027 Unless the row is continued, that means it ends on a newline
17028 in the string. If it's anything other than a display string
17029 (e.g. a before-string from an overlay), we don't want the
17030 cursor there. (This heuristic seems to give the optimal
17031 behavior for the various types of multi-line strings.) */
17032 if (CHARPOS (row
->end
.string_pos
) >= 0)
17034 if (row
->continued_p
)
17038 /* Check for `display' property. */
17039 struct glyph
*beg
= row
->glyphs
[TEXT_AREA
];
17040 struct glyph
*end
= beg
+ row
->used
[TEXT_AREA
] - 1;
17041 struct glyph
*glyph
;
17044 for (glyph
= end
; glyph
>= beg
; --glyph
)
17045 if (STRINGP (glyph
->object
))
17048 = Fget_char_property (make_number (PT
),
17052 && display_prop_string_p (prop
, glyph
->object
));
17057 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
17059 /* If the row ends in middle of a real character,
17060 and the line is continued, we want the cursor here.
17061 That's because CHARPOS (ROW->end.pos) would equal
17062 PT if PT is before the character. */
17063 if (!row
->ends_in_ellipsis_p
)
17064 cursor_row_p
= row
->continued_p
;
17066 /* If the row ends in an ellipsis, then
17067 CHARPOS (ROW->end.pos) will equal point after the
17068 invisible text. We want that position to be displayed
17069 after the ellipsis. */
17072 /* If the row ends at ZV, display the cursor at the end of that
17073 row instead of at the start of the row below. */
17074 else if (row
->ends_at_zv_p
)
17080 return cursor_row_p
;
17085 /* Push the display property PROP so that it will be rendered at the
17086 current position in IT. Return 1 if PROP was successfully pushed,
17090 push_display_prop (struct it
*it
, Lisp_Object prop
)
17094 if (STRINGP (prop
))
17096 if (SCHARS (prop
) == 0)
17103 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
17104 it
->current
.overlay_string_index
= -1;
17105 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
17106 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
17107 it
->method
= GET_FROM_STRING
;
17108 it
->stop_charpos
= 0;
17110 else if (CONSP (prop
) && EQ (XCAR (prop
), Qspace
))
17112 it
->method
= GET_FROM_STRETCH
;
17115 #ifdef HAVE_WINDOW_SYSTEM
17116 else if (IMAGEP (prop
))
17118 it
->what
= IT_IMAGE
;
17119 it
->image_id
= lookup_image (it
->f
, prop
);
17120 it
->method
= GET_FROM_IMAGE
;
17122 #endif /* HAVE_WINDOW_SYSTEM */
17125 pop_it (it
); /* bogus display property, give up */
17132 /* Return the character-property PROP at the current position in IT. */
17135 get_it_property (struct it
*it
, Lisp_Object prop
)
17137 Lisp_Object position
;
17139 if (STRINGP (it
->object
))
17140 position
= make_number (IT_STRING_CHARPOS (*it
));
17141 else if (BUFFERP (it
->object
))
17142 position
= make_number (IT_CHARPOS (*it
));
17146 return Fget_char_property (position
, prop
, it
->object
);
17149 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17152 handle_line_prefix (struct it
*it
)
17154 Lisp_Object prefix
;
17155 if (it
->continuation_lines_width
> 0)
17157 prefix
= get_it_property (it
, Qwrap_prefix
);
17159 prefix
= Vwrap_prefix
;
17163 prefix
= get_it_property (it
, Qline_prefix
);
17165 prefix
= Vline_prefix
;
17167 if (! NILP (prefix
) && push_display_prop (it
, prefix
))
17169 /* If the prefix is wider than the window, and we try to wrap
17170 it, it would acquire its own wrap prefix, and so on till the
17171 iterator stack overflows. So, don't wrap the prefix. */
17172 it
->line_wrap
= TRUNCATE
;
17173 it
->avoid_cursor_p
= 1;
17179 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17180 only for R2L lines from display_line, when it decides that too many
17181 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17184 unproduce_glyphs (struct it
*it
, int n
)
17186 struct glyph
*glyph
, *end
;
17188 xassert (it
->glyph_row
);
17189 xassert (it
->glyph_row
->reversed_p
);
17190 xassert (it
->area
== TEXT_AREA
);
17191 xassert (n
<= it
->glyph_row
->used
[TEXT_AREA
]);
17193 if (n
> it
->glyph_row
->used
[TEXT_AREA
])
17194 n
= it
->glyph_row
->used
[TEXT_AREA
];
17195 glyph
= it
->glyph_row
->glyphs
[TEXT_AREA
] + n
;
17196 end
= it
->glyph_row
->glyphs
[TEXT_AREA
] + it
->glyph_row
->used
[TEXT_AREA
];
17197 for ( ; glyph
< end
; glyph
++)
17198 glyph
[-n
] = *glyph
;
17201 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17202 and ROW->maxpos. */
17204 find_row_edges (struct it
*it
, struct glyph_row
*row
,
17205 EMACS_INT min_pos
, EMACS_INT min_bpos
,
17206 EMACS_INT max_pos
, EMACS_INT max_bpos
)
17208 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17209 lines' rows is implemented for bidi-reordered rows. */
17211 /* ROW->minpos is the value of min_pos, the minimal buffer position
17214 SET_TEXT_POS (row
->minpos
, min_pos
, min_bpos
);
17217 /* We didn't find _any_ valid buffer positions in any of the
17218 glyphs, so we must trust the iterator's computed
17220 row
->minpos
= row
->start
.pos
;
17221 max_pos
= CHARPOS (it
->current
.pos
);
17222 max_bpos
= BYTEPOS (it
->current
.pos
);
17228 /* Here are the various use-cases for ending the row, and the
17229 corresponding values for ROW->maxpos:
17231 Line ends in a newline from buffer eol_pos + 1
17232 Line is continued from buffer max_pos + 1
17233 Line is truncated on right it->current.pos
17234 Line ends in a newline from string max_pos
17235 Line is continued from string max_pos
17236 Line is continued from display vector max_pos
17237 Line is entirely from a string min_pos == max_pos
17238 Line is entirely from a display vector min_pos == max_pos
17239 Line that ends at ZV ZV
17241 If you discover other use-cases, please add them here as
17243 if (row
->ends_at_zv_p
)
17244 row
->maxpos
= it
->current
.pos
;
17245 else if (row
->used
[TEXT_AREA
])
17247 if (row
->ends_in_newline_from_string_p
)
17248 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
17249 else if (CHARPOS (it
->eol_pos
) > 0)
17250 SET_TEXT_POS (row
->maxpos
,
17251 CHARPOS (it
->eol_pos
) + 1, BYTEPOS (it
->eol_pos
) + 1);
17252 else if (row
->continued_p
)
17254 /* If max_pos is different from IT's current position, it
17255 means IT->method does not belong to the display element
17256 at max_pos. However, it also means that the display
17257 element at max_pos was displayed in its entirety on this
17258 line, which is equivalent to saying that the next line
17259 starts at the next buffer position. */
17260 if (IT_CHARPOS (*it
) == max_pos
&& it
->method
!= GET_FROM_BUFFER
)
17261 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
17264 INC_BOTH (max_pos
, max_bpos
);
17265 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
17268 else if (row
->truncated_on_right_p
)
17269 /* display_line already called reseat_at_next_visible_line_start,
17270 which puts the iterator at the beginning of the next line, in
17271 the logical order. */
17272 row
->maxpos
= it
->current
.pos
;
17273 else if (max_pos
== min_pos
&& it
->method
!= GET_FROM_BUFFER
)
17274 /* A line that is entirely from a string/image/stretch... */
17275 row
->maxpos
= row
->minpos
;
17280 row
->maxpos
= it
->current
.pos
;
17283 /* Construct the glyph row IT->glyph_row in the desired matrix of
17284 IT->w from text at the current position of IT. See dispextern.h
17285 for an overview of struct it. Value is non-zero if
17286 IT->glyph_row displays text, as opposed to a line displaying ZV
17290 display_line (struct it
*it
)
17292 struct glyph_row
*row
= it
->glyph_row
;
17293 Lisp_Object overlay_arrow_string
;
17295 int may_wrap
= 0, wrap_x
;
17296 int wrap_row_used
= -1, wrap_row_ascent
, wrap_row_height
;
17297 int wrap_row_phys_ascent
, wrap_row_phys_height
;
17298 int wrap_row_extra_line_spacing
;
17299 EMACS_INT wrap_row_min_pos
, wrap_row_min_bpos
;
17300 EMACS_INT wrap_row_max_pos
, wrap_row_max_bpos
;
17302 EMACS_INT min_pos
= ZV
+ 1, min_bpos
, max_pos
= 0, max_bpos
;
17304 /* We always start displaying at hpos zero even if hscrolled. */
17305 xassert (it
->hpos
== 0 && it
->current_x
== 0);
17307 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
17308 >= it
->w
->desired_matrix
->nrows
)
17310 it
->w
->nrows_scale_factor
++;
17311 fonts_changed_p
= 1;
17315 /* Is IT->w showing the region? */
17316 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
17318 /* Clear the result glyph row and enable it. */
17319 prepare_desired_row (row
);
17321 row
->y
= it
->current_y
;
17322 row
->start
= it
->start
;
17323 row
->continuation_lines_width
= it
->continuation_lines_width
;
17324 row
->displays_text_p
= 1;
17325 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
17326 it
->starts_in_middle_of_char_p
= 0;
17328 /* Arrange the overlays nicely for our purposes. Usually, we call
17329 display_line on only one line at a time, in which case this
17330 can't really hurt too much, or we call it on lines which appear
17331 one after another in the buffer, in which case all calls to
17332 recenter_overlay_lists but the first will be pretty cheap. */
17333 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
17335 /* Move over display elements that are not visible because we are
17336 hscrolled. This may stop at an x-position < IT->first_visible_x
17337 if the first glyph is partially visible or if we hit a line end. */
17338 if (it
->current_x
< it
->first_visible_x
)
17340 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
17341 MOVE_TO_POS
| MOVE_TO_X
);
17345 /* We only do this when not calling `move_it_in_display_line_to'
17346 above, because move_it_in_display_line_to calls
17347 handle_line_prefix itself. */
17348 handle_line_prefix (it
);
17351 /* Get the initial row height. This is either the height of the
17352 text hscrolled, if there is any, or zero. */
17353 row
->ascent
= it
->max_ascent
;
17354 row
->height
= it
->max_ascent
+ it
->max_descent
;
17355 row
->phys_ascent
= it
->max_phys_ascent
;
17356 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
17357 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
17359 /* Utility macro to record max and min buffer positions seen until now. */
17360 #define RECORD_MAX_MIN_POS(IT) \
17363 if (IT_CHARPOS (*(IT)) < min_pos) \
17365 min_pos = IT_CHARPOS (*(IT)); \
17366 min_bpos = IT_BYTEPOS (*(IT)); \
17368 if (IT_CHARPOS (*(IT)) > max_pos) \
17370 max_pos = IT_CHARPOS (*(IT)); \
17371 max_bpos = IT_BYTEPOS (*(IT)); \
17376 /* Loop generating characters. The loop is left with IT on the next
17377 character to display. */
17380 int n_glyphs_before
, hpos_before
, x_before
;
17382 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
17384 /* Retrieve the next thing to display. Value is zero if end of
17386 if (!get_next_display_element (it
))
17388 /* Maybe add a space at the end of this line that is used to
17389 display the cursor there under X. Set the charpos of the
17390 first glyph of blank lines not corresponding to any text
17392 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
17393 row
->exact_window_width_line_p
= 1;
17394 else if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
17395 || row
->used
[TEXT_AREA
] == 0)
17397 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
17398 row
->displays_text_p
= 0;
17400 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
17401 && (!MINI_WINDOW_P (it
->w
)
17402 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
17403 row
->indicate_empty_line_p
= 1;
17406 it
->continuation_lines_width
= 0;
17407 row
->ends_at_zv_p
= 1;
17408 /* A row that displays right-to-left text must always have
17409 its last face extended all the way to the end of line,
17410 even if this row ends in ZV, because we still write to
17411 the screen left to right. */
17412 if (row
->reversed_p
)
17413 extend_face_to_end_of_line (it
);
17417 /* Now, get the metrics of what we want to display. This also
17418 generates glyphs in `row' (which is IT->glyph_row). */
17419 n_glyphs_before
= row
->used
[TEXT_AREA
];
17422 /* Remember the line height so far in case the next element doesn't
17423 fit on the line. */
17424 if (it
->line_wrap
!= TRUNCATE
)
17426 ascent
= it
->max_ascent
;
17427 descent
= it
->max_descent
;
17428 phys_ascent
= it
->max_phys_ascent
;
17429 phys_descent
= it
->max_phys_descent
;
17431 if (it
->line_wrap
== WORD_WRAP
&& it
->area
== TEXT_AREA
)
17433 if (IT_DISPLAYING_WHITESPACE (it
))
17439 wrap_row_used
= row
->used
[TEXT_AREA
];
17440 wrap_row_ascent
= row
->ascent
;
17441 wrap_row_height
= row
->height
;
17442 wrap_row_phys_ascent
= row
->phys_ascent
;
17443 wrap_row_phys_height
= row
->phys_height
;
17444 wrap_row_extra_line_spacing
= row
->extra_line_spacing
;
17445 wrap_row_min_pos
= min_pos
;
17446 wrap_row_min_bpos
= min_bpos
;
17447 wrap_row_max_pos
= max_pos
;
17448 wrap_row_max_bpos
= max_bpos
;
17454 PRODUCE_GLYPHS (it
);
17456 /* If this display element was in marginal areas, continue with
17458 if (it
->area
!= TEXT_AREA
)
17460 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
17461 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
17462 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
17463 row
->phys_height
= max (row
->phys_height
,
17464 it
->max_phys_ascent
+ it
->max_phys_descent
);
17465 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
17466 it
->max_extra_line_spacing
);
17467 set_iterator_to_next (it
, 1);
17471 /* Does the display element fit on the line? If we truncate
17472 lines, we should draw past the right edge of the window. If
17473 we don't truncate, we want to stop so that we can display the
17474 continuation glyph before the right margin. If lines are
17475 continued, there are two possible strategies for characters
17476 resulting in more than 1 glyph (e.g. tabs): Display as many
17477 glyphs as possible in this line and leave the rest for the
17478 continuation line, or display the whole element in the next
17479 line. Original redisplay did the former, so we do it also. */
17480 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
17481 hpos_before
= it
->hpos
;
17484 if (/* Not a newline. */
17486 /* Glyphs produced fit entirely in the line. */
17487 && it
->current_x
< it
->last_visible_x
)
17489 it
->hpos
+= nglyphs
;
17490 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
17491 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
17492 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
17493 row
->phys_height
= max (row
->phys_height
,
17494 it
->max_phys_ascent
+ it
->max_phys_descent
);
17495 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
17496 it
->max_extra_line_spacing
);
17497 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
17498 row
->x
= x
- it
->first_visible_x
;
17499 /* Record the maximum and minimum buffer positions seen so
17500 far in glyphs that will be displayed by this row. */
17502 RECORD_MAX_MIN_POS (it
);
17507 struct glyph
*glyph
;
17509 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
17511 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
17512 new_x
= x
+ glyph
->pixel_width
;
17514 if (/* Lines are continued. */
17515 it
->line_wrap
!= TRUNCATE
17516 && (/* Glyph doesn't fit on the line. */
17517 new_x
> it
->last_visible_x
17518 /* Or it fits exactly on a window system frame. */
17519 || (new_x
== it
->last_visible_x
17520 && FRAME_WINDOW_P (it
->f
))))
17522 /* End of a continued line. */
17525 || (new_x
== it
->last_visible_x
17526 && FRAME_WINDOW_P (it
->f
)))
17528 /* Current glyph is the only one on the line or
17529 fits exactly on the line. We must continue
17530 the line because we can't draw the cursor
17531 after the glyph. */
17532 row
->continued_p
= 1;
17533 it
->current_x
= new_x
;
17534 it
->continuation_lines_width
+= new_x
;
17536 /* Record the maximum and minimum buffer
17537 positions seen so far in glyphs that will be
17538 displayed by this row. */
17540 RECORD_MAX_MIN_POS (it
);
17541 if (i
== nglyphs
- 1)
17543 /* If line-wrap is on, check if a previous
17544 wrap point was found. */
17545 if (wrap_row_used
> 0
17546 /* Even if there is a previous wrap
17547 point, continue the line here as
17548 usual, if (i) the previous character
17549 was a space or tab AND (ii) the
17550 current character is not. */
17552 || IT_DISPLAYING_WHITESPACE (it
)))
17555 set_iterator_to_next (it
, 1);
17556 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
17558 if (!get_next_display_element (it
))
17560 row
->exact_window_width_line_p
= 1;
17561 it
->continuation_lines_width
= 0;
17562 row
->continued_p
= 0;
17563 row
->ends_at_zv_p
= 1;
17565 else if (ITERATOR_AT_END_OF_LINE_P (it
))
17567 row
->continued_p
= 0;
17568 row
->exact_window_width_line_p
= 1;
17573 else if (CHAR_GLYPH_PADDING_P (*glyph
)
17574 && !FRAME_WINDOW_P (it
->f
))
17576 /* A padding glyph that doesn't fit on this line.
17577 This means the whole character doesn't fit
17579 if (row
->reversed_p
)
17580 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
17581 - n_glyphs_before
);
17582 row
->used
[TEXT_AREA
] = n_glyphs_before
;
17584 /* Fill the rest of the row with continuation
17585 glyphs like in 20.x. */
17586 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
17587 < row
->glyphs
[1 + TEXT_AREA
])
17588 produce_special_glyphs (it
, IT_CONTINUATION
);
17590 row
->continued_p
= 1;
17591 it
->current_x
= x_before
;
17592 it
->continuation_lines_width
+= x_before
;
17594 /* Restore the height to what it was before the
17595 element not fitting on the line. */
17596 it
->max_ascent
= ascent
;
17597 it
->max_descent
= descent
;
17598 it
->max_phys_ascent
= phys_ascent
;
17599 it
->max_phys_descent
= phys_descent
;
17601 else if (wrap_row_used
> 0)
17604 if (row
->reversed_p
)
17605 unproduce_glyphs (it
,
17606 row
->used
[TEXT_AREA
] - wrap_row_used
);
17608 it
->continuation_lines_width
+= wrap_x
;
17609 row
->used
[TEXT_AREA
] = wrap_row_used
;
17610 row
->ascent
= wrap_row_ascent
;
17611 row
->height
= wrap_row_height
;
17612 row
->phys_ascent
= wrap_row_phys_ascent
;
17613 row
->phys_height
= wrap_row_phys_height
;
17614 row
->extra_line_spacing
= wrap_row_extra_line_spacing
;
17615 min_pos
= wrap_row_min_pos
;
17616 min_bpos
= wrap_row_min_bpos
;
17617 max_pos
= wrap_row_max_pos
;
17618 max_bpos
= wrap_row_max_bpos
;
17619 row
->continued_p
= 1;
17620 row
->ends_at_zv_p
= 0;
17621 row
->exact_window_width_line_p
= 0;
17622 it
->continuation_lines_width
+= x
;
17624 /* Make sure that a non-default face is extended
17625 up to the right margin of the window. */
17626 extend_face_to_end_of_line (it
);
17628 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
17630 /* A TAB that extends past the right edge of the
17631 window. This produces a single glyph on
17632 window system frames. We leave the glyph in
17633 this row and let it fill the row, but don't
17634 consume the TAB. */
17635 it
->continuation_lines_width
+= it
->last_visible_x
;
17636 row
->ends_in_middle_of_char_p
= 1;
17637 row
->continued_p
= 1;
17638 glyph
->pixel_width
= it
->last_visible_x
- x
;
17639 it
->starts_in_middle_of_char_p
= 1;
17643 /* Something other than a TAB that draws past
17644 the right edge of the window. Restore
17645 positions to values before the element. */
17646 if (row
->reversed_p
)
17647 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
17648 - (n_glyphs_before
+ i
));
17649 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
17651 /* Display continuation glyphs. */
17652 if (!FRAME_WINDOW_P (it
->f
))
17653 produce_special_glyphs (it
, IT_CONTINUATION
);
17654 row
->continued_p
= 1;
17656 it
->current_x
= x_before
;
17657 it
->continuation_lines_width
+= x
;
17658 extend_face_to_end_of_line (it
);
17660 if (nglyphs
> 1 && i
> 0)
17662 row
->ends_in_middle_of_char_p
= 1;
17663 it
->starts_in_middle_of_char_p
= 1;
17666 /* Restore the height to what it was before the
17667 element not fitting on the line. */
17668 it
->max_ascent
= ascent
;
17669 it
->max_descent
= descent
;
17670 it
->max_phys_ascent
= phys_ascent
;
17671 it
->max_phys_descent
= phys_descent
;
17676 else if (new_x
> it
->first_visible_x
)
17678 /* Increment number of glyphs actually displayed. */
17681 /* Record the maximum and minimum buffer positions
17682 seen so far in glyphs that will be displayed by
17685 RECORD_MAX_MIN_POS (it
);
17687 if (x
< it
->first_visible_x
)
17688 /* Glyph is partially visible, i.e. row starts at
17689 negative X position. */
17690 row
->x
= x
- it
->first_visible_x
;
17694 /* Glyph is completely off the left margin of the
17695 window. This should not happen because of the
17696 move_it_in_display_line at the start of this
17697 function, unless the text display area of the
17698 window is empty. */
17699 xassert (it
->first_visible_x
<= it
->last_visible_x
);
17703 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
17704 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
17705 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
17706 row
->phys_height
= max (row
->phys_height
,
17707 it
->max_phys_ascent
+ it
->max_phys_descent
);
17708 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
17709 it
->max_extra_line_spacing
);
17711 /* End of this display line if row is continued. */
17712 if (row
->continued_p
|| row
->ends_at_zv_p
)
17717 /* Is this a line end? If yes, we're also done, after making
17718 sure that a non-default face is extended up to the right
17719 margin of the window. */
17720 if (ITERATOR_AT_END_OF_LINE_P (it
))
17722 int used_before
= row
->used
[TEXT_AREA
];
17724 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
17726 /* Add a space at the end of the line that is used to
17727 display the cursor there. */
17728 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
17729 append_space_for_newline (it
, 0);
17731 /* Extend the face to the end of the line. */
17732 extend_face_to_end_of_line (it
);
17734 /* Make sure we have the position. */
17735 if (used_before
== 0)
17736 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
17738 /* Record the position of the newline, for use in
17740 it
->eol_pos
= it
->current
.pos
;
17742 /* Consume the line end. This skips over invisible lines. */
17743 set_iterator_to_next (it
, 1);
17744 it
->continuation_lines_width
= 0;
17748 /* Proceed with next display element. Note that this skips
17749 over lines invisible because of selective display. */
17750 set_iterator_to_next (it
, 1);
17752 /* If we truncate lines, we are done when the last displayed
17753 glyphs reach past the right margin of the window. */
17754 if (it
->line_wrap
== TRUNCATE
17755 && (FRAME_WINDOW_P (it
->f
)
17756 ? (it
->current_x
>= it
->last_visible_x
)
17757 : (it
->current_x
> it
->last_visible_x
)))
17759 /* Maybe add truncation glyphs. */
17760 if (!FRAME_WINDOW_P (it
->f
))
17764 if (!row
->reversed_p
)
17766 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
17767 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
17772 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
17773 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
17775 /* Remove any padding glyphs at the front of ROW, to
17776 make room for the truncation glyphs we will be
17777 adding below. The loop below always inserts at
17778 least one truncation glyph, so also remove the
17779 last glyph added to ROW. */
17780 unproduce_glyphs (it
, i
+ 1);
17781 /* Adjust i for the loop below. */
17782 i
= row
->used
[TEXT_AREA
] - (i
+ 1);
17785 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
17787 row
->used
[TEXT_AREA
] = i
;
17788 produce_special_glyphs (it
, IT_TRUNCATION
);
17791 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
17793 /* Don't truncate if we can overflow newline into fringe. */
17794 if (!get_next_display_element (it
))
17796 it
->continuation_lines_width
= 0;
17797 row
->ends_at_zv_p
= 1;
17798 row
->exact_window_width_line_p
= 1;
17801 if (ITERATOR_AT_END_OF_LINE_P (it
))
17803 row
->exact_window_width_line_p
= 1;
17804 goto at_end_of_line
;
17808 row
->truncated_on_right_p
= 1;
17809 it
->continuation_lines_width
= 0;
17810 reseat_at_next_visible_line_start (it
, 0);
17811 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
17812 it
->hpos
= hpos_before
;
17813 it
->current_x
= x_before
;
17818 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17819 at the left window margin. */
17820 if (it
->first_visible_x
17821 && IT_CHARPOS (*it
) != CHARPOS (row
->start
.pos
))
17823 if (!FRAME_WINDOW_P (it
->f
))
17824 insert_left_trunc_glyphs (it
);
17825 row
->truncated_on_left_p
= 1;
17828 /* Remember the position at which this line ends.
17830 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
17831 cannot be before the call to find_row_edges below, since that is
17832 where these positions are determined. */
17833 row
->end
= it
->current
;
17836 row
->minpos
= row
->start
.pos
;
17837 row
->maxpos
= row
->end
.pos
;
17841 /* ROW->minpos and ROW->maxpos must be the smallest and
17842 `1 + the largest' buffer positions in ROW. But if ROW was
17843 bidi-reordered, these two positions can be anywhere in the
17844 row, so we must determine them now. */
17845 find_row_edges (it
, row
, min_pos
, min_bpos
, max_pos
, max_bpos
);
17848 /* If the start of this line is the overlay arrow-position, then
17849 mark this glyph row as the one containing the overlay arrow.
17850 This is clearly a mess with variable size fonts. It would be
17851 better to let it be displayed like cursors under X. */
17852 if ((row
->displays_text_p
|| !overlay_arrow_seen
)
17853 && (overlay_arrow_string
= overlay_arrow_at_row (it
, row
),
17854 !NILP (overlay_arrow_string
)))
17856 /* Overlay arrow in window redisplay is a fringe bitmap. */
17857 if (STRINGP (overlay_arrow_string
))
17859 struct glyph_row
*arrow_row
17860 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
17861 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
17862 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
17863 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
17864 struct glyph
*p2
, *end
;
17866 /* Copy the arrow glyphs. */
17867 while (glyph
< arrow_end
)
17870 /* Throw away padding glyphs. */
17872 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
17873 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
17879 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
17884 xassert (INTEGERP (overlay_arrow_string
));
17885 row
->overlay_arrow_bitmap
= XINT (overlay_arrow_string
);
17887 overlay_arrow_seen
= 1;
17890 /* Compute pixel dimensions of this line. */
17891 compute_line_metrics (it
);
17893 /* Record whether this row ends inside an ellipsis. */
17894 row
->ends_in_ellipsis_p
17895 = (it
->method
== GET_FROM_DISPLAY_VECTOR
17896 && it
->ellipsis_p
);
17898 /* Save fringe bitmaps in this row. */
17899 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
17900 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
17901 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
17902 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
17904 it
->left_user_fringe_bitmap
= 0;
17905 it
->left_user_fringe_face_id
= 0;
17906 it
->right_user_fringe_bitmap
= 0;
17907 it
->right_user_fringe_face_id
= 0;
17909 /* Maybe set the cursor. */
17910 cvpos
= it
->w
->cursor
.vpos
;
17912 /* In bidi-reordered rows, keep checking for proper cursor
17913 position even if one has been found already, because buffer
17914 positions in such rows change non-linearly with ROW->VPOS,
17915 when a line is continued. One exception: when we are at ZV,
17916 display cursor on the first suitable glyph row, since all
17917 the empty rows after that also have their position set to ZV. */
17918 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17919 lines' rows is implemented for bidi-reordered rows. */
17921 && !MATRIX_ROW (it
->w
->desired_matrix
, cvpos
)->ends_at_zv_p
))
17922 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
17923 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
17924 && cursor_row_p (it
->w
, row
))
17925 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
17927 /* Highlight trailing whitespace. */
17928 if (!NILP (Vshow_trailing_whitespace
))
17929 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
17931 /* Prepare for the next line. This line starts horizontally at (X
17932 HPOS) = (0 0). Vertical positions are incremented. As a
17933 convenience for the caller, IT->glyph_row is set to the next
17935 it
->current_x
= it
->hpos
= 0;
17936 it
->current_y
+= row
->height
;
17937 SET_TEXT_POS (it
->eol_pos
, 0, 0);
17940 /* The next row should by default use the same value of the
17941 reversed_p flag as this one. set_iterator_to_next decides when
17942 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
17943 the flag accordingly. */
17944 if (it
->glyph_row
< MATRIX_BOTTOM_TEXT_ROW (it
->w
->desired_matrix
, it
->w
))
17945 it
->glyph_row
->reversed_p
= row
->reversed_p
;
17946 it
->start
= row
->end
;
17947 return row
->displays_text_p
;
17949 #undef RECORD_MAX_MIN_POS
17952 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction
,
17953 Scurrent_bidi_paragraph_direction
, 0, 1, 0,
17954 doc
: /* Return paragraph direction at point in BUFFER.
17955 Value is either `left-to-right' or `right-to-left'.
17956 If BUFFER is omitted or nil, it defaults to the current buffer.
17958 Paragraph direction determines how the text in the paragraph is displayed.
17959 In left-to-right paragraphs, text begins at the left margin of the window
17960 and the reading direction is generally left to right. In right-to-left
17961 paragraphs, text begins at the right margin and is read from right to left.
17963 See also `bidi-paragraph-direction'. */)
17964 (Lisp_Object buffer
)
17966 struct buffer
*buf
;
17967 struct buffer
*old
;
17970 buf
= current_buffer
;
17973 CHECK_BUFFER (buffer
);
17974 buf
= XBUFFER (buffer
);
17975 old
= current_buffer
;
17978 if (NILP (buf
->bidi_display_reordering
))
17979 return Qleft_to_right
;
17980 else if (!NILP (buf
->bidi_paragraph_direction
))
17981 return buf
->bidi_paragraph_direction
;
17984 /* Determine the direction from buffer text. We could try to
17985 use current_matrix if it is up to date, but this seems fast
17986 enough as it is. */
17987 struct bidi_it itb
;
17988 EMACS_INT pos
= BUF_PT (buf
);
17989 EMACS_INT bytepos
= BUF_PT_BYTE (buf
);
17992 if (buf
!= current_buffer
)
17993 set_buffer_temp (buf
);
17994 /* bidi_paragraph_init finds the base direction of the paragraph
17995 by searching forward from paragraph start. We need the base
17996 direction of the current or _previous_ paragraph, so we need
17997 to make sure we are within that paragraph. To that end, find
17998 the previous non-empty line. */
17999 if (pos
>= ZV
&& pos
> BEGV
)
18002 bytepos
= CHAR_TO_BYTE (pos
);
18004 while ((c
= FETCH_BYTE (bytepos
)) == '\n'
18005 || c
== ' ' || c
== '\t' || c
== '\f')
18007 if (bytepos
<= BEGV_BYTE
)
18012 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos
)))
18015 itb
.bytepos
= bytepos
;
18017 itb
.separator_limit
= -1;
18019 bidi_paragraph_init (NEUTRAL_DIR
, &itb
);
18020 if (buf
!= current_buffer
)
18021 set_buffer_temp (old
);
18022 switch (itb
.paragraph_dir
)
18025 return Qleft_to_right
;
18028 return Qright_to_left
;
18038 /***********************************************************************
18040 ***********************************************************************/
18042 /* Redisplay the menu bar in the frame for window W.
18044 The menu bar of X frames that don't have X toolkit support is
18045 displayed in a special window W->frame->menu_bar_window.
18047 The menu bar of terminal frames is treated specially as far as
18048 glyph matrices are concerned. Menu bar lines are not part of
18049 windows, so the update is done directly on the frame matrix rows
18050 for the menu bar. */
18053 display_menu_bar (struct window
*w
)
18055 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
18060 /* Don't do all this for graphical frames. */
18062 if (FRAME_W32_P (f
))
18065 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18071 if (FRAME_NS_P (f
))
18073 #endif /* HAVE_NS */
18075 #ifdef USE_X_TOOLKIT
18076 xassert (!FRAME_WINDOW_P (f
));
18077 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
18078 it
.first_visible_x
= 0;
18079 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
18080 #else /* not USE_X_TOOLKIT */
18081 if (FRAME_WINDOW_P (f
))
18083 /* Menu bar lines are displayed in the desired matrix of the
18084 dummy window menu_bar_window. */
18085 struct window
*menu_w
;
18086 xassert (WINDOWP (f
->menu_bar_window
));
18087 menu_w
= XWINDOW (f
->menu_bar_window
);
18088 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
18090 it
.first_visible_x
= 0;
18091 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
18095 /* This is a TTY frame, i.e. character hpos/vpos are used as
18097 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
18099 it
.first_visible_x
= 0;
18100 it
.last_visible_x
= FRAME_COLS (f
);
18102 #endif /* not USE_X_TOOLKIT */
18104 if (! mode_line_inverse_video
)
18105 /* Force the menu-bar to be displayed in the default face. */
18106 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
18108 /* Clear all rows of the menu bar. */
18109 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
18111 struct glyph_row
*row
= it
.glyph_row
+ i
;
18112 clear_glyph_row (row
);
18113 row
->enabled_p
= 1;
18114 row
->full_width_p
= 1;
18117 /* Display all items of the menu bar. */
18118 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
18119 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
18121 Lisp_Object string
;
18123 /* Stop at nil string. */
18124 string
= AREF (items
, i
+ 1);
18128 /* Remember where item was displayed. */
18129 ASET (items
, i
+ 3, make_number (it
.hpos
));
18131 /* Display the item, pad with one space. */
18132 if (it
.current_x
< it
.last_visible_x
)
18133 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
18134 SCHARS (string
) + 1, 0, 0, -1);
18137 /* Fill out the line with spaces. */
18138 if (it
.current_x
< it
.last_visible_x
)
18139 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
18141 /* Compute the total height of the lines. */
18142 compute_line_metrics (&it
);
18147 /***********************************************************************
18149 ***********************************************************************/
18151 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18152 FORCE is non-zero, redisplay mode lines unconditionally.
18153 Otherwise, redisplay only mode lines that are garbaged. Value is
18154 the number of windows whose mode lines were redisplayed. */
18157 redisplay_mode_lines (Lisp_Object window
, int force
)
18161 while (!NILP (window
))
18163 struct window
*w
= XWINDOW (window
);
18165 if (WINDOWP (w
->hchild
))
18166 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
18167 else if (WINDOWP (w
->vchild
))
18168 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
18170 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
18171 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
18173 struct text_pos lpoint
;
18174 struct buffer
*old
= current_buffer
;
18176 /* Set the window's buffer for the mode line display. */
18177 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
18178 set_buffer_internal_1 (XBUFFER (w
->buffer
));
18180 /* Point refers normally to the selected window. For any
18181 other window, set up appropriate value. */
18182 if (!EQ (window
, selected_window
))
18184 struct text_pos pt
;
18186 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
18187 if (CHARPOS (pt
) < BEGV
)
18188 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
18189 else if (CHARPOS (pt
) > (ZV
- 1))
18190 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
18192 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
18195 /* Display mode lines. */
18196 clear_glyph_matrix (w
->desired_matrix
);
18197 if (display_mode_lines (w
))
18200 w
->must_be_updated_p
= 1;
18203 /* Restore old settings. */
18204 set_buffer_internal_1 (old
);
18205 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
18215 /* Display the mode and/or header line of window W. Value is the
18216 sum number of mode lines and header lines displayed. */
18219 display_mode_lines (struct window
*w
)
18221 Lisp_Object old_selected_window
, old_selected_frame
;
18224 old_selected_frame
= selected_frame
;
18225 selected_frame
= w
->frame
;
18226 old_selected_window
= selected_window
;
18227 XSETWINDOW (selected_window
, w
);
18229 /* These will be set while the mode line specs are processed. */
18230 line_number_displayed
= 0;
18231 w
->column_number_displayed
= Qnil
;
18233 if (WINDOW_WANTS_MODELINE_P (w
))
18235 struct window
*sel_w
= XWINDOW (old_selected_window
);
18237 /* Select mode line face based on the real selected window. */
18238 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
18239 current_buffer
->mode_line_format
);
18243 if (WINDOW_WANTS_HEADER_LINE_P (w
))
18245 display_mode_line (w
, HEADER_LINE_FACE_ID
,
18246 current_buffer
->header_line_format
);
18250 selected_frame
= old_selected_frame
;
18251 selected_window
= old_selected_window
;
18256 /* Display mode or header line of window W. FACE_ID specifies which
18257 line to display; it is either MODE_LINE_FACE_ID or
18258 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18259 display. Value is the pixel height of the mode/header line
18263 display_mode_line (struct window
*w
, enum face_id face_id
, Lisp_Object format
)
18267 int count
= SPECPDL_INDEX ();
18269 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
18270 /* Don't extend on a previously drawn mode-line.
18271 This may happen if called from pos_visible_p. */
18272 it
.glyph_row
->enabled_p
= 0;
18273 prepare_desired_row (it
.glyph_row
);
18275 it
.glyph_row
->mode_line_p
= 1;
18277 if (! mode_line_inverse_video
)
18278 /* Force the mode-line to be displayed in the default face. */
18279 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
18281 record_unwind_protect (unwind_format_mode_line
,
18282 format_mode_line_unwind_data (NULL
, Qnil
, 0));
18284 mode_line_target
= MODE_LINE_DISPLAY
;
18286 /* Temporarily make frame's keyboard the current kboard so that
18287 kboard-local variables in the mode_line_format will get the right
18289 push_kboard (FRAME_KBOARD (it
.f
));
18290 record_unwind_save_match_data ();
18291 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
18294 unbind_to (count
, Qnil
);
18296 /* Fill up with spaces. */
18297 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
18299 compute_line_metrics (&it
);
18300 it
.glyph_row
->full_width_p
= 1;
18301 it
.glyph_row
->continued_p
= 0;
18302 it
.glyph_row
->truncated_on_left_p
= 0;
18303 it
.glyph_row
->truncated_on_right_p
= 0;
18305 /* Make a 3D mode-line have a shadow at its right end. */
18306 face
= FACE_FROM_ID (it
.f
, face_id
);
18307 extend_face_to_end_of_line (&it
);
18308 if (face
->box
!= FACE_NO_BOX
)
18310 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
18311 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
18312 last
->right_box_line_p
= 1;
18315 return it
.glyph_row
->height
;
18318 /* Move element ELT in LIST to the front of LIST.
18319 Return the updated list. */
18322 move_elt_to_front (Lisp_Object elt
, Lisp_Object list
)
18324 register Lisp_Object tail
, prev
;
18325 register Lisp_Object tem
;
18329 while (CONSP (tail
))
18335 /* Splice out the link TAIL. */
18337 list
= XCDR (tail
);
18339 Fsetcdr (prev
, XCDR (tail
));
18341 /* Now make it the first. */
18342 Fsetcdr (tail
, list
);
18347 tail
= XCDR (tail
);
18351 /* Not found--return unchanged LIST. */
18355 /* Contribute ELT to the mode line for window IT->w. How it
18356 translates into text depends on its data type.
18358 IT describes the display environment in which we display, as usual.
18360 DEPTH is the depth in recursion. It is used to prevent
18361 infinite recursion here.
18363 FIELD_WIDTH is the number of characters the display of ELT should
18364 occupy in the mode line, and PRECISION is the maximum number of
18365 characters to display from ELT's representation. See
18366 display_string for details.
18368 Returns the hpos of the end of the text generated by ELT.
18370 PROPS is a property list to add to any string we encounter.
18372 If RISKY is nonzero, remove (disregard) any properties in any string
18373 we encounter, and ignore :eval and :propertize.
18375 The global variable `mode_line_target' determines whether the
18376 output is passed to `store_mode_line_noprop',
18377 `store_mode_line_string', or `display_string'. */
18380 display_mode_element (struct it
*it
, int depth
, int field_width
, int precision
,
18381 Lisp_Object elt
, Lisp_Object props
, int risky
)
18383 int n
= 0, field
, prec
;
18388 elt
= build_string ("*too-deep*");
18392 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
18396 /* A string: output it and check for %-constructs within it. */
18400 if (SCHARS (elt
) > 0
18401 && (!NILP (props
) || risky
))
18403 Lisp_Object oprops
, aelt
;
18404 oprops
= Ftext_properties_at (make_number (0), elt
);
18406 /* If the starting string's properties are not what
18407 we want, translate the string. Also, if the string
18408 is risky, do that anyway. */
18410 if (NILP (Fequal (props
, oprops
)) || risky
)
18412 /* If the starting string has properties,
18413 merge the specified ones onto the existing ones. */
18414 if (! NILP (oprops
) && !risky
)
18418 oprops
= Fcopy_sequence (oprops
);
18420 while (CONSP (tem
))
18422 oprops
= Fplist_put (oprops
, XCAR (tem
),
18423 XCAR (XCDR (tem
)));
18424 tem
= XCDR (XCDR (tem
));
18429 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
18430 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
18432 /* AELT is what we want. Move it to the front
18433 without consing. */
18435 mode_line_proptrans_alist
18436 = move_elt_to_front (aelt
, mode_line_proptrans_alist
);
18442 /* If AELT has the wrong props, it is useless.
18443 so get rid of it. */
18445 mode_line_proptrans_alist
18446 = Fdelq (aelt
, mode_line_proptrans_alist
);
18448 elt
= Fcopy_sequence (elt
);
18449 Fset_text_properties (make_number (0), Flength (elt
),
18451 /* Add this item to mode_line_proptrans_alist. */
18452 mode_line_proptrans_alist
18453 = Fcons (Fcons (elt
, props
),
18454 mode_line_proptrans_alist
);
18455 /* Truncate mode_line_proptrans_alist
18456 to at most 50 elements. */
18457 tem
= Fnthcdr (make_number (50),
18458 mode_line_proptrans_alist
);
18460 XSETCDR (tem
, Qnil
);
18469 prec
= precision
- n
;
18470 switch (mode_line_target
)
18472 case MODE_LINE_NOPROP
:
18473 case MODE_LINE_TITLE
:
18474 n
+= store_mode_line_noprop (SDATA (elt
), -1, prec
);
18476 case MODE_LINE_STRING
:
18477 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
18479 case MODE_LINE_DISPLAY
:
18480 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
18481 0, prec
, 0, STRING_MULTIBYTE (elt
));
18488 /* Handle the non-literal case. */
18490 while ((precision
<= 0 || n
< precision
)
18491 && SREF (elt
, offset
) != 0
18492 && (mode_line_target
!= MODE_LINE_DISPLAY
18493 || it
->current_x
< it
->last_visible_x
))
18495 int last_offset
= offset
;
18497 /* Advance to end of string or next format specifier. */
18498 while ((c
= SREF (elt
, offset
++)) != '\0' && c
!= '%')
18501 if (offset
- 1 != last_offset
)
18503 int nchars
, nbytes
;
18505 /* Output to end of string or up to '%'. Field width
18506 is length of string. Don't output more than
18507 PRECISION allows us. */
18510 prec
= c_string_width (SDATA (elt
) + last_offset
,
18511 offset
- last_offset
, precision
- n
,
18514 switch (mode_line_target
)
18516 case MODE_LINE_NOPROP
:
18517 case MODE_LINE_TITLE
:
18518 n
+= store_mode_line_noprop (SDATA (elt
) + last_offset
, 0, prec
);
18520 case MODE_LINE_STRING
:
18522 int bytepos
= last_offset
;
18523 int charpos
= string_byte_to_char (elt
, bytepos
);
18524 int endpos
= (precision
<= 0
18525 ? string_byte_to_char (elt
, offset
)
18526 : charpos
+ nchars
);
18528 n
+= store_mode_line_string (NULL
,
18529 Fsubstring (elt
, make_number (charpos
),
18530 make_number (endpos
)),
18534 case MODE_LINE_DISPLAY
:
18536 int bytepos
= last_offset
;
18537 int charpos
= string_byte_to_char (elt
, bytepos
);
18539 if (precision
<= 0)
18540 nchars
= string_byte_to_char (elt
, offset
) - charpos
;
18541 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
18543 STRING_MULTIBYTE (elt
));
18548 else /* c == '%' */
18550 int percent_position
= offset
;
18552 /* Get the specified minimum width. Zero means
18555 while ((c
= SREF (elt
, offset
++)) >= '0' && c
<= '9')
18556 field
= field
* 10 + c
- '0';
18558 /* Don't pad beyond the total padding allowed. */
18559 if (field_width
- n
> 0 && field
> field_width
- n
)
18560 field
= field_width
- n
;
18562 /* Note that either PRECISION <= 0 or N < PRECISION. */
18563 prec
= precision
- n
;
18566 n
+= display_mode_element (it
, depth
, field
, prec
,
18567 Vglobal_mode_string
, props
,
18572 int bytepos
, charpos
;
18573 const unsigned char *spec
;
18574 Lisp_Object string
;
18576 bytepos
= percent_position
;
18577 charpos
= (STRING_MULTIBYTE (elt
)
18578 ? string_byte_to_char (elt
, bytepos
)
18580 spec
= decode_mode_spec (it
->w
, c
, field
, prec
, &string
);
18581 multibyte
= STRINGP (string
) && STRING_MULTIBYTE (string
);
18583 switch (mode_line_target
)
18585 case MODE_LINE_NOPROP
:
18586 case MODE_LINE_TITLE
:
18587 n
+= store_mode_line_noprop (spec
, field
, prec
);
18589 case MODE_LINE_STRING
:
18591 int len
= strlen (spec
);
18592 Lisp_Object tem
= make_string (spec
, len
);
18593 props
= Ftext_properties_at (make_number (charpos
), elt
);
18594 /* Should only keep face property in props */
18595 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
18598 case MODE_LINE_DISPLAY
:
18600 int nglyphs_before
, nwritten
;
18602 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
18603 nwritten
= display_string (spec
, string
, elt
,
18608 /* Assign to the glyphs written above the
18609 string where the `%x' came from, position
18613 struct glyph
*glyph
18614 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
18618 for (i
= 0; i
< nwritten
; ++i
)
18620 glyph
[i
].object
= elt
;
18621 glyph
[i
].charpos
= charpos
;
18638 /* A symbol: process the value of the symbol recursively
18639 as if it appeared here directly. Avoid error if symbol void.
18640 Special case: if value of symbol is a string, output the string
18643 register Lisp_Object tem
;
18645 /* If the variable is not marked as risky to set
18646 then its contents are risky to use. */
18647 if (NILP (Fget (elt
, Qrisky_local_variable
)))
18650 tem
= Fboundp (elt
);
18653 tem
= Fsymbol_value (elt
);
18654 /* If value is a string, output that string literally:
18655 don't check for % within it. */
18659 if (!EQ (tem
, elt
))
18661 /* Give up right away for nil or t. */
18671 register Lisp_Object car
, tem
;
18673 /* A cons cell: five distinct cases.
18674 If first element is :eval or :propertize, do something special.
18675 If first element is a string or a cons, process all the elements
18676 and effectively concatenate them.
18677 If first element is a negative number, truncate displaying cdr to
18678 at most that many characters. If positive, pad (with spaces)
18679 to at least that many characters.
18680 If first element is a symbol, process the cadr or caddr recursively
18681 according to whether the symbol's value is non-nil or nil. */
18683 if (EQ (car
, QCeval
))
18685 /* An element of the form (:eval FORM) means evaluate FORM
18686 and use the result as mode line elements. */
18691 if (CONSP (XCDR (elt
)))
18694 spec
= safe_eval (XCAR (XCDR (elt
)));
18695 n
+= display_mode_element (it
, depth
, field_width
- n
,
18696 precision
- n
, spec
, props
,
18700 else if (EQ (car
, QCpropertize
))
18702 /* An element of the form (:propertize ELT PROPS...)
18703 means display ELT but applying properties PROPS. */
18708 if (CONSP (XCDR (elt
)))
18709 n
+= display_mode_element (it
, depth
, field_width
- n
,
18710 precision
- n
, XCAR (XCDR (elt
)),
18711 XCDR (XCDR (elt
)), risky
);
18713 else if (SYMBOLP (car
))
18715 tem
= Fboundp (car
);
18719 /* elt is now the cdr, and we know it is a cons cell.
18720 Use its car if CAR has a non-nil value. */
18723 tem
= Fsymbol_value (car
);
18730 /* Symbol's value is nil (or symbol is unbound)
18731 Get the cddr of the original list
18732 and if possible find the caddr and use that. */
18736 else if (!CONSP (elt
))
18741 else if (INTEGERP (car
))
18743 register int lim
= XINT (car
);
18747 /* Negative int means reduce maximum width. */
18748 if (precision
<= 0)
18751 precision
= min (precision
, -lim
);
18755 /* Padding specified. Don't let it be more than
18756 current maximum. */
18758 lim
= min (precision
, lim
);
18760 /* If that's more padding than already wanted, queue it.
18761 But don't reduce padding already specified even if
18762 that is beyond the current truncation point. */
18763 field_width
= max (lim
, field_width
);
18767 else if (STRINGP (car
) || CONSP (car
))
18769 Lisp_Object halftail
= elt
;
18773 && (precision
<= 0 || n
< precision
))
18775 n
+= display_mode_element (it
, depth
,
18776 /* Do padding only after the last
18777 element in the list. */
18778 (! CONSP (XCDR (elt
))
18781 precision
- n
, XCAR (elt
),
18785 if ((len
& 1) == 0)
18786 halftail
= XCDR (halftail
);
18787 /* Check for cycle. */
18788 if (EQ (halftail
, elt
))
18797 elt
= build_string ("*invalid*");
18801 /* Pad to FIELD_WIDTH. */
18802 if (field_width
> 0 && n
< field_width
)
18804 switch (mode_line_target
)
18806 case MODE_LINE_NOPROP
:
18807 case MODE_LINE_TITLE
:
18808 n
+= store_mode_line_noprop ("", field_width
- n
, 0);
18810 case MODE_LINE_STRING
:
18811 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
18813 case MODE_LINE_DISPLAY
:
18814 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
18823 /* Store a mode-line string element in mode_line_string_list.
18825 If STRING is non-null, display that C string. Otherwise, the Lisp
18826 string LISP_STRING is displayed.
18828 FIELD_WIDTH is the minimum number of output glyphs to produce.
18829 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18830 with spaces. FIELD_WIDTH <= 0 means don't pad.
18832 PRECISION is the maximum number of characters to output from
18833 STRING. PRECISION <= 0 means don't truncate the string.
18835 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18836 properties to the string.
18838 PROPS are the properties to add to the string.
18839 The mode_line_string_face face property is always added to the string.
18843 store_mode_line_string (const char *string
, Lisp_Object lisp_string
, int copy_string
,
18844 int field_width
, int precision
, Lisp_Object props
)
18849 if (string
!= NULL
)
18851 len
= strlen (string
);
18852 if (precision
> 0 && len
> precision
)
18854 lisp_string
= make_string (string
, len
);
18856 props
= mode_line_string_face_prop
;
18857 else if (!NILP (mode_line_string_face
))
18859 Lisp_Object face
= Fplist_get (props
, Qface
);
18860 props
= Fcopy_sequence (props
);
18862 face
= mode_line_string_face
;
18864 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
18865 props
= Fplist_put (props
, Qface
, face
);
18867 Fadd_text_properties (make_number (0), make_number (len
),
18868 props
, lisp_string
);
18872 len
= XFASTINT (Flength (lisp_string
));
18873 if (precision
> 0 && len
> precision
)
18876 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
18879 if (!NILP (mode_line_string_face
))
18883 props
= Ftext_properties_at (make_number (0), lisp_string
);
18884 face
= Fplist_get (props
, Qface
);
18886 face
= mode_line_string_face
;
18888 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
18889 props
= Fcons (Qface
, Fcons (face
, Qnil
));
18891 lisp_string
= Fcopy_sequence (lisp_string
);
18894 Fadd_text_properties (make_number (0), make_number (len
),
18895 props
, lisp_string
);
18900 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
18904 if (field_width
> len
)
18906 field_width
-= len
;
18907 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
18909 Fadd_text_properties (make_number (0), make_number (field_width
),
18910 props
, lisp_string
);
18911 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
18919 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
18921 doc
: /* Format a string out of a mode line format specification.
18922 First arg FORMAT specifies the mode line format (see `mode-line-format'
18923 for details) to use.
18925 Optional second arg FACE specifies the face property to put
18926 on all characters for which no face is specified.
18927 The value t means whatever face the window's mode line currently uses
18928 \(either `mode-line' or `mode-line-inactive', depending).
18929 A value of nil means the default is no face property.
18930 If FACE is an integer, the value string has no text properties.
18932 Optional third and fourth args WINDOW and BUFFER specify the window
18933 and buffer to use as the context for the formatting (defaults
18934 are the selected window and the window's buffer). */)
18935 (Lisp_Object format
, Lisp_Object face
, Lisp_Object window
, Lisp_Object buffer
)
18940 struct buffer
*old_buffer
= NULL
;
18942 int no_props
= INTEGERP (face
);
18943 int count
= SPECPDL_INDEX ();
18945 int string_start
= 0;
18948 window
= selected_window
;
18949 CHECK_WINDOW (window
);
18950 w
= XWINDOW (window
);
18953 buffer
= w
->buffer
;
18954 CHECK_BUFFER (buffer
);
18956 /* Make formatting the modeline a non-op when noninteractive, otherwise
18957 there will be problems later caused by a partially initialized frame. */
18958 if (NILP (format
) || noninteractive
)
18959 return empty_unibyte_string
;
18967 face
= (EQ (window
, selected_window
) ? Qmode_line
: Qmode_line_inactive
);
18968 face_id
= lookup_named_face (XFRAME (WINDOW_FRAME (w
)), face
, 0);
18972 face_id
= DEFAULT_FACE_ID
;
18974 if (XBUFFER (buffer
) != current_buffer
)
18975 old_buffer
= current_buffer
;
18977 /* Save things including mode_line_proptrans_alist,
18978 and set that to nil so that we don't alter the outer value. */
18979 record_unwind_protect (unwind_format_mode_line
,
18980 format_mode_line_unwind_data
18981 (old_buffer
, selected_window
, 1));
18982 mode_line_proptrans_alist
= Qnil
;
18984 Fselect_window (window
, Qt
);
18986 set_buffer_internal_1 (XBUFFER (buffer
));
18988 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
18992 mode_line_target
= MODE_LINE_NOPROP
;
18993 mode_line_string_face_prop
= Qnil
;
18994 mode_line_string_list
= Qnil
;
18995 string_start
= MODE_LINE_NOPROP_LEN (0);
18999 mode_line_target
= MODE_LINE_STRING
;
19000 mode_line_string_list
= Qnil
;
19001 mode_line_string_face
= face
;
19002 mode_line_string_face_prop
19003 = (NILP (face
) ? Qnil
: Fcons (Qface
, Fcons (face
, Qnil
)));
19006 push_kboard (FRAME_KBOARD (it
.f
));
19007 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
19012 len
= MODE_LINE_NOPROP_LEN (string_start
);
19013 str
= make_string (mode_line_noprop_buf
+ string_start
, len
);
19017 mode_line_string_list
= Fnreverse (mode_line_string_list
);
19018 str
= Fmapconcat (intern ("identity"), mode_line_string_list
,
19019 empty_unibyte_string
);
19022 unbind_to (count
, Qnil
);
19026 /* Write a null-terminated, right justified decimal representation of
19027 the positive integer D to BUF using a minimal field width WIDTH. */
19030 pint2str (register char *buf
, register int width
, register int d
)
19032 register char *p
= buf
;
19040 *p
++ = d
% 10 + '0';
19045 for (width
-= (int) (p
- buf
); width
> 0; --width
)
19056 /* Write a null-terminated, right justified decimal and "human
19057 readable" representation of the nonnegative integer D to BUF using
19058 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19060 static const char power_letter
[] =
19074 pint2hrstr (char *buf
, int width
, int d
)
19076 /* We aim to represent the nonnegative integer D as
19077 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19080 /* -1 means: do not use TENTHS. */
19084 /* Length of QUOTIENT.TENTHS as a string. */
19090 if (1000 <= quotient
)
19092 /* Scale to the appropriate EXPONENT. */
19095 remainder
= quotient
% 1000;
19099 while (1000 <= quotient
);
19101 /* Round to nearest and decide whether to use TENTHS or not. */
19104 tenths
= remainder
/ 100;
19105 if (50 <= remainder
% 100)
19112 if (quotient
== 10)
19120 if (500 <= remainder
)
19122 if (quotient
< 999)
19133 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19134 if (tenths
== -1 && quotient
<= 99)
19141 p
= psuffix
= buf
+ max (width
, length
);
19143 /* Print EXPONENT. */
19145 *psuffix
++ = power_letter
[exponent
];
19148 /* Print TENTHS. */
19151 *--p
= '0' + tenths
;
19155 /* Print QUOTIENT. */
19158 int digit
= quotient
% 10;
19159 *--p
= '0' + digit
;
19161 while ((quotient
/= 10) != 0);
19163 /* Print leading spaces. */
19168 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19169 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19170 type of CODING_SYSTEM. Return updated pointer into BUF. */
19172 static unsigned char invalid_eol_type
[] = "(*invalid*)";
19175 decode_mode_spec_coding (Lisp_Object coding_system
, register char *buf
, int eol_flag
)
19178 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
19179 const unsigned char *eol_str
;
19181 /* The EOL conversion we are using. */
19182 Lisp_Object eoltype
;
19184 val
= CODING_SYSTEM_SPEC (coding_system
);
19187 if (!VECTORP (val
)) /* Not yet decided. */
19192 eoltype
= eol_mnemonic_undecided
;
19193 /* Don't mention EOL conversion if it isn't decided. */
19198 Lisp_Object eolvalue
;
19200 attrs
= AREF (val
, 0);
19201 eolvalue
= AREF (val
, 2);
19204 *buf
++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs
));
19208 /* The EOL conversion that is normal on this system. */
19210 if (NILP (eolvalue
)) /* Not yet decided. */
19211 eoltype
= eol_mnemonic_undecided
;
19212 else if (VECTORP (eolvalue
)) /* Not yet decided. */
19213 eoltype
= eol_mnemonic_undecided
;
19214 else /* eolvalue is Qunix, Qdos, or Qmac. */
19215 eoltype
= (EQ (eolvalue
, Qunix
)
19216 ? eol_mnemonic_unix
19217 : (EQ (eolvalue
, Qdos
) == 1
19218 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
19224 /* Mention the EOL conversion if it is not the usual one. */
19225 if (STRINGP (eoltype
))
19227 eol_str
= SDATA (eoltype
);
19228 eol_str_len
= SBYTES (eoltype
);
19230 else if (CHARACTERP (eoltype
))
19232 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
19233 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
19238 eol_str
= invalid_eol_type
;
19239 eol_str_len
= sizeof (invalid_eol_type
) - 1;
19241 memcpy (buf
, eol_str
, eol_str_len
);
19242 buf
+= eol_str_len
;
19248 /* Return a string for the output of a mode line %-spec for window W,
19249 generated by character C. PRECISION >= 0 means don't return a
19250 string longer than that value. FIELD_WIDTH > 0 means pad the
19251 string returned with spaces to that value. Return a Lisp string in
19252 *STRING if the resulting string is taken from that Lisp string.
19254 Note we operate on the current buffer for most purposes,
19255 the exception being w->base_line_pos. */
19257 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19259 static const char *
19260 decode_mode_spec (struct window
*w
, register int c
, int field_width
,
19261 int precision
, Lisp_Object
*string
)
19264 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
19265 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
19266 struct buffer
*b
= current_buffer
;
19274 if (!NILP (b
->read_only
))
19276 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
19281 /* This differs from %* only for a modified read-only buffer. */
19282 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
19284 if (!NILP (b
->read_only
))
19289 /* This differs from %* in ignoring read-only-ness. */
19290 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
19302 if (command_loop_level
> 5)
19304 p
= decode_mode_spec_buf
;
19305 for (i
= 0; i
< command_loop_level
; i
++)
19308 return decode_mode_spec_buf
;
19316 if (command_loop_level
> 5)
19318 p
= decode_mode_spec_buf
;
19319 for (i
= 0; i
< command_loop_level
; i
++)
19322 return decode_mode_spec_buf
;
19329 /* Let lots_of_dashes be a string of infinite length. */
19330 if (mode_line_target
== MODE_LINE_NOPROP
||
19331 mode_line_target
== MODE_LINE_STRING
)
19333 if (field_width
<= 0
19334 || field_width
> sizeof (lots_of_dashes
))
19336 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
19337 decode_mode_spec_buf
[i
] = '-';
19338 decode_mode_spec_buf
[i
] = '\0';
19339 return decode_mode_spec_buf
;
19342 return lots_of_dashes
;
19350 /* %c and %l are ignored in `frame-title-format'.
19351 (In redisplay_internal, the frame title is drawn _before_ the
19352 windows are updated, so the stuff which depends on actual
19353 window contents (such as %l) may fail to render properly, or
19354 even crash emacs.) */
19355 if (mode_line_target
== MODE_LINE_TITLE
)
19359 int col
= (int) current_column (); /* iftc */
19360 w
->column_number_displayed
= make_number (col
);
19361 pint2str (decode_mode_spec_buf
, field_width
, col
);
19362 return decode_mode_spec_buf
;
19366 #ifndef SYSTEM_MALLOC
19368 if (NILP (Vmemory_full
))
19371 return "!MEM FULL! ";
19378 /* %F displays the frame name. */
19379 if (!NILP (f
->title
))
19380 return (char *) SDATA (f
->title
);
19381 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
19382 return (char *) SDATA (f
->name
);
19391 int size
= ZV
- BEGV
;
19392 pint2str (decode_mode_spec_buf
, field_width
, size
);
19393 return decode_mode_spec_buf
;
19398 int size
= ZV
- BEGV
;
19399 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
19400 return decode_mode_spec_buf
;
19405 int startpos
, startpos_byte
, line
, linepos
, linepos_byte
;
19406 int topline
, nlines
, junk
, height
;
19408 /* %c and %l are ignored in `frame-title-format'. */
19409 if (mode_line_target
== MODE_LINE_TITLE
)
19412 startpos
= XMARKER (w
->start
)->charpos
;
19413 startpos_byte
= marker_byte_position (w
->start
);
19414 height
= WINDOW_TOTAL_LINES (w
);
19416 /* If we decided that this buffer isn't suitable for line numbers,
19417 don't forget that too fast. */
19418 if (EQ (w
->base_line_pos
, w
->buffer
))
19420 /* But do forget it, if the window shows a different buffer now. */
19421 else if (BUFFERP (w
->base_line_pos
))
19422 w
->base_line_pos
= Qnil
;
19424 /* If the buffer is very big, don't waste time. */
19425 if (INTEGERP (Vline_number_display_limit
)
19426 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
19428 w
->base_line_pos
= Qnil
;
19429 w
->base_line_number
= Qnil
;
19433 if (INTEGERP (w
->base_line_number
)
19434 && INTEGERP (w
->base_line_pos
)
19435 && XFASTINT (w
->base_line_pos
) <= startpos
)
19437 line
= XFASTINT (w
->base_line_number
);
19438 linepos
= XFASTINT (w
->base_line_pos
);
19439 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
19444 linepos
= BUF_BEGV (b
);
19445 linepos_byte
= BUF_BEGV_BYTE (b
);
19448 /* Count lines from base line to window start position. */
19449 nlines
= display_count_lines (linepos
, linepos_byte
,
19453 topline
= nlines
+ line
;
19455 /* Determine a new base line, if the old one is too close
19456 or too far away, or if we did not have one.
19457 "Too close" means it's plausible a scroll-down would
19458 go back past it. */
19459 if (startpos
== BUF_BEGV (b
))
19461 w
->base_line_number
= make_number (topline
);
19462 w
->base_line_pos
= make_number (BUF_BEGV (b
));
19464 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
19465 || linepos
== BUF_BEGV (b
))
19467 int limit
= BUF_BEGV (b
);
19468 int limit_byte
= BUF_BEGV_BYTE (b
);
19470 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
19472 if (startpos
- distance
> limit
)
19474 limit
= startpos
- distance
;
19475 limit_byte
= CHAR_TO_BYTE (limit
);
19478 nlines
= display_count_lines (startpos
, startpos_byte
,
19480 - (height
* 2 + 30),
19482 /* If we couldn't find the lines we wanted within
19483 line_number_display_limit_width chars per line,
19484 give up on line numbers for this window. */
19485 if (position
== limit_byte
&& limit
== startpos
- distance
)
19487 w
->base_line_pos
= w
->buffer
;
19488 w
->base_line_number
= Qnil
;
19492 w
->base_line_number
= make_number (topline
- nlines
);
19493 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
19496 /* Now count lines from the start pos to point. */
19497 nlines
= display_count_lines (startpos
, startpos_byte
,
19498 PT_BYTE
, PT
, &junk
);
19500 /* Record that we did display the line number. */
19501 line_number_displayed
= 1;
19503 /* Make the string to show. */
19504 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
19505 return decode_mode_spec_buf
;
19508 char* p
= decode_mode_spec_buf
;
19509 int pad
= field_width
- 2;
19515 return decode_mode_spec_buf
;
19521 obj
= b
->mode_name
;
19525 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
19531 int pos
= marker_position (w
->start
);
19532 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
19534 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
19536 if (pos
<= BUF_BEGV (b
))
19541 else if (pos
<= BUF_BEGV (b
))
19545 if (total
> 1000000)
19546 /* Do it differently for a large value, to avoid overflow. */
19547 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
19549 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
19550 /* We can't normally display a 3-digit number,
19551 so get us a 2-digit number that is close. */
19554 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
19555 return decode_mode_spec_buf
;
19559 /* Display percentage of size above the bottom of the screen. */
19562 int toppos
= marker_position (w
->start
);
19563 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
19564 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
19566 if (botpos
>= BUF_ZV (b
))
19568 if (toppos
<= BUF_BEGV (b
))
19575 if (total
> 1000000)
19576 /* Do it differently for a large value, to avoid overflow. */
19577 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
19579 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
19580 /* We can't normally display a 3-digit number,
19581 so get us a 2-digit number that is close. */
19584 if (toppos
<= BUF_BEGV (b
))
19585 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
19587 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
19588 return decode_mode_spec_buf
;
19593 /* status of process */
19594 obj
= Fget_buffer_process (Fcurrent_buffer ());
19596 return "no process";
19598 obj
= Fsymbol_name (Fprocess_status (obj
));
19604 int count
= inhibit_garbage_collection ();
19605 Lisp_Object val
= call1 (intern ("file-remote-p"),
19606 current_buffer
->directory
);
19607 unbind_to (count
, Qnil
);
19615 case 't': /* indicate TEXT or BINARY */
19616 #ifdef MODE_LINE_BINARY_TEXT
19617 return MODE_LINE_BINARY_TEXT (b
);
19623 /* coding-system (not including end-of-line format) */
19625 /* coding-system (including end-of-line type) */
19627 int eol_flag
= (c
== 'Z');
19628 char *p
= decode_mode_spec_buf
;
19630 if (! FRAME_WINDOW_P (f
))
19632 /* No need to mention EOL here--the terminal never needs
19633 to do EOL conversion. */
19634 p
= decode_mode_spec_coding (CODING_ID_NAME
19635 (FRAME_KEYBOARD_CODING (f
)->id
),
19637 p
= decode_mode_spec_coding (CODING_ID_NAME
19638 (FRAME_TERMINAL_CODING (f
)->id
),
19641 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
19644 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19645 #ifdef subprocesses
19646 obj
= Fget_buffer_process (Fcurrent_buffer ());
19647 if (PROCESSP (obj
))
19649 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
19651 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
19654 #endif /* subprocesses */
19657 return decode_mode_spec_buf
;
19664 return (char *) SDATA (obj
);
19671 /* Count up to COUNT lines starting from START / START_BYTE.
19672 But don't go beyond LIMIT_BYTE.
19673 Return the number of lines thus found (always nonnegative).
19675 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19678 display_count_lines (int start
, int start_byte
, int limit_byte
, int count
,
19681 register unsigned char *cursor
;
19682 unsigned char *base
;
19684 register int ceiling
;
19685 register unsigned char *ceiling_addr
;
19686 int orig_count
= count
;
19688 /* If we are not in selective display mode,
19689 check only for newlines. */
19690 int selective_display
= (!NILP (current_buffer
->selective_display
)
19691 && !INTEGERP (current_buffer
->selective_display
));
19695 while (start_byte
< limit_byte
)
19697 ceiling
= BUFFER_CEILING_OF (start_byte
);
19698 ceiling
= min (limit_byte
- 1, ceiling
);
19699 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
19700 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
19703 if (selective_display
)
19704 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
19707 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
19710 if (cursor
!= ceiling_addr
)
19714 start_byte
+= cursor
- base
+ 1;
19715 *byte_pos_ptr
= start_byte
;
19719 if (++cursor
== ceiling_addr
)
19725 start_byte
+= cursor
- base
;
19730 while (start_byte
> limit_byte
)
19732 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
19733 ceiling
= max (limit_byte
, ceiling
);
19734 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
19735 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
19738 if (selective_display
)
19739 while (--cursor
!= ceiling_addr
19740 && *cursor
!= '\n' && *cursor
!= 015)
19743 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
19746 if (cursor
!= ceiling_addr
)
19750 start_byte
+= cursor
- base
+ 1;
19751 *byte_pos_ptr
= start_byte
;
19752 /* When scanning backwards, we should
19753 not count the newline posterior to which we stop. */
19754 return - orig_count
- 1;
19760 /* Here we add 1 to compensate for the last decrement
19761 of CURSOR, which took it past the valid range. */
19762 start_byte
+= cursor
- base
+ 1;
19766 *byte_pos_ptr
= limit_byte
;
19769 return - orig_count
+ count
;
19770 return orig_count
- count
;
19776 /***********************************************************************
19778 ***********************************************************************/
19780 /* Display a NUL-terminated string, starting with index START.
19782 If STRING is non-null, display that C string. Otherwise, the Lisp
19783 string LISP_STRING is displayed. There's a case that STRING is
19784 non-null and LISP_STRING is not nil. It means STRING is a string
19785 data of LISP_STRING. In that case, we display LISP_STRING while
19786 ignoring its text properties.
19788 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19789 FACE_STRING. Display STRING or LISP_STRING with the face at
19790 FACE_STRING_POS in FACE_STRING:
19792 Display the string in the environment given by IT, but use the
19793 standard display table, temporarily.
19795 FIELD_WIDTH is the minimum number of output glyphs to produce.
19796 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19797 with spaces. If STRING has more characters, more than FIELD_WIDTH
19798 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19800 PRECISION is the maximum number of characters to output from
19801 STRING. PRECISION < 0 means don't truncate the string.
19803 This is roughly equivalent to printf format specifiers:
19805 FIELD_WIDTH PRECISION PRINTF
19806 ----------------------------------------
19812 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19813 display them, and < 0 means obey the current buffer's value of
19814 enable_multibyte_characters.
19816 Value is the number of columns displayed. */
19819 display_string (const unsigned char *string
, Lisp_Object lisp_string
, Lisp_Object face_string
,
19820 EMACS_INT face_string_pos
, EMACS_INT start
, struct it
*it
,
19821 int field_width
, int precision
, int max_x
, int multibyte
)
19823 int hpos_at_start
= it
->hpos
;
19824 int saved_face_id
= it
->face_id
;
19825 struct glyph_row
*row
= it
->glyph_row
;
19827 /* Initialize the iterator IT for iteration over STRING beginning
19828 with index START. */
19829 reseat_to_string (it
, NILP (lisp_string
) ? string
: NULL
, lisp_string
, start
,
19830 precision
, field_width
, multibyte
);
19831 if (string
&& STRINGP (lisp_string
))
19832 /* LISP_STRING is the one returned by decode_mode_spec. We should
19833 ignore its text properties. */
19834 it
->stop_charpos
= -1;
19836 /* If displaying STRING, set up the face of the iterator
19837 from LISP_STRING, if that's given. */
19838 if (STRINGP (face_string
))
19844 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
19845 0, it
->region_beg_charpos
,
19846 it
->region_end_charpos
,
19847 &endptr
, it
->base_face_id
, 0);
19848 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19849 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
19852 /* Set max_x to the maximum allowed X position. Don't let it go
19853 beyond the right edge of the window. */
19855 max_x
= it
->last_visible_x
;
19857 max_x
= min (max_x
, it
->last_visible_x
);
19859 /* Skip over display elements that are not visible. because IT->w is
19861 if (it
->current_x
< it
->first_visible_x
)
19862 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
19863 MOVE_TO_POS
| MOVE_TO_X
);
19865 row
->ascent
= it
->max_ascent
;
19866 row
->height
= it
->max_ascent
+ it
->max_descent
;
19867 row
->phys_ascent
= it
->max_phys_ascent
;
19868 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
19869 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
19871 /* This condition is for the case that we are called with current_x
19872 past last_visible_x. */
19873 while (it
->current_x
< max_x
)
19875 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
19877 /* Get the next display element. */
19878 if (!get_next_display_element (it
))
19881 /* Produce glyphs. */
19882 x_before
= it
->current_x
;
19883 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
19884 PRODUCE_GLYPHS (it
);
19886 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
19889 while (i
< nglyphs
)
19891 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
19893 if (it
->line_wrap
!= TRUNCATE
19894 && x
+ glyph
->pixel_width
> max_x
)
19896 /* End of continued line or max_x reached. */
19897 if (CHAR_GLYPH_PADDING_P (*glyph
))
19899 /* A wide character is unbreakable. */
19900 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
19901 it
->current_x
= x_before
;
19905 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
19910 else if (x
+ glyph
->pixel_width
>= it
->first_visible_x
)
19912 /* Glyph is at least partially visible. */
19914 if (x
< it
->first_visible_x
)
19915 it
->glyph_row
->x
= x
- it
->first_visible_x
;
19919 /* Glyph is off the left margin of the display area.
19920 Should not happen. */
19924 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19925 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19926 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19927 row
->phys_height
= max (row
->phys_height
,
19928 it
->max_phys_ascent
+ it
->max_phys_descent
);
19929 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19930 it
->max_extra_line_spacing
);
19931 x
+= glyph
->pixel_width
;
19935 /* Stop if max_x reached. */
19939 /* Stop at line ends. */
19940 if (ITERATOR_AT_END_OF_LINE_P (it
))
19942 it
->continuation_lines_width
= 0;
19946 set_iterator_to_next (it
, 1);
19948 /* Stop if truncating at the right edge. */
19949 if (it
->line_wrap
== TRUNCATE
19950 && it
->current_x
>= it
->last_visible_x
)
19952 /* Add truncation mark, but don't do it if the line is
19953 truncated at a padding space. */
19954 if (IT_CHARPOS (*it
) < it
->string_nchars
)
19956 if (!FRAME_WINDOW_P (it
->f
))
19960 if (it
->current_x
> it
->last_visible_x
)
19962 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
19963 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
19965 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
19967 row
->used
[TEXT_AREA
] = i
;
19968 produce_special_glyphs (it
, IT_TRUNCATION
);
19971 produce_special_glyphs (it
, IT_TRUNCATION
);
19973 it
->glyph_row
->truncated_on_right_p
= 1;
19979 /* Maybe insert a truncation at the left. */
19980 if (it
->first_visible_x
19981 && IT_CHARPOS (*it
) > 0)
19983 if (!FRAME_WINDOW_P (it
->f
))
19984 insert_left_trunc_glyphs (it
);
19985 it
->glyph_row
->truncated_on_left_p
= 1;
19988 it
->face_id
= saved_face_id
;
19990 /* Value is number of columns displayed. */
19991 return it
->hpos
- hpos_at_start
;
19996 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
19997 appears as an element of LIST or as the car of an element of LIST.
19998 If PROPVAL is a list, compare each element against LIST in that
19999 way, and return 1/2 if any element of PROPVAL is found in LIST.
20000 Otherwise return 0. This function cannot quit.
20001 The return value is 2 if the text is invisible but with an ellipsis
20002 and 1 if it's invisible and without an ellipsis. */
20005 invisible_p (register Lisp_Object propval
, Lisp_Object list
)
20007 register Lisp_Object tail
, proptail
;
20009 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
20011 register Lisp_Object tem
;
20013 if (EQ (propval
, tem
))
20015 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
20016 return NILP (XCDR (tem
)) ? 1 : 2;
20019 if (CONSP (propval
))
20021 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
20023 Lisp_Object propelt
;
20024 propelt
= XCAR (proptail
);
20025 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
20027 register Lisp_Object tem
;
20029 if (EQ (propelt
, tem
))
20031 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
20032 return NILP (XCDR (tem
)) ? 1 : 2;
20040 DEFUN ("invisible-p", Finvisible_p
, Sinvisible_p
, 1, 1, 0,
20041 doc
: /* Non-nil if the property makes the text invisible.
20042 POS-OR-PROP can be a marker or number, in which case it is taken to be
20043 a position in the current buffer and the value of the `invisible' property
20044 is checked; or it can be some other value, which is then presumed to be the
20045 value of the `invisible' property of the text of interest.
20046 The non-nil value returned can be t for truly invisible text or something
20047 else if the text is replaced by an ellipsis. */)
20048 (Lisp_Object pos_or_prop
)
20051 = (NATNUMP (pos_or_prop
) || MARKERP (pos_or_prop
)
20052 ? Fget_char_property (pos_or_prop
, Qinvisible
, Qnil
)
20054 int invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
20055 return (invis
== 0 ? Qnil
20057 : make_number (invis
));
20060 /* Calculate a width or height in pixels from a specification using
20061 the following elements:
20064 NUM - a (fractional) multiple of the default font width/height
20065 (NUM) - specifies exactly NUM pixels
20066 UNIT - a fixed number of pixels, see below.
20067 ELEMENT - size of a display element in pixels, see below.
20068 (NUM . SPEC) - equals NUM * SPEC
20069 (+ SPEC SPEC ...) - add pixel values
20070 (- SPEC SPEC ...) - subtract pixel values
20071 (- SPEC) - negate pixel value
20074 INT or FLOAT - a number constant
20075 SYMBOL - use symbol's (buffer local) variable binding.
20078 in - pixels per inch *)
20079 mm - pixels per 1/1000 meter *)
20080 cm - pixels per 1/100 meter *)
20081 width - width of current font in pixels.
20082 height - height of current font in pixels.
20084 *) using the ratio(s) defined in display-pixels-per-inch.
20088 left-fringe - left fringe width in pixels
20089 right-fringe - right fringe width in pixels
20091 left-margin - left margin width in pixels
20092 right-margin - right margin width in pixels
20094 scroll-bar - scroll-bar area width in pixels
20098 Pixels corresponding to 5 inches:
20101 Total width of non-text areas on left side of window (if scroll-bar is on left):
20102 '(space :width (+ left-fringe left-margin scroll-bar))
20104 Align to first text column (in header line):
20105 '(space :align-to 0)
20107 Align to middle of text area minus half the width of variable `my-image'
20108 containing a loaded image:
20109 '(space :align-to (0.5 . (- text my-image)))
20111 Width of left margin minus width of 1 character in the default font:
20112 '(space :width (- left-margin 1))
20114 Width of left margin minus width of 2 characters in the current font:
20115 '(space :width (- left-margin (2 . width)))
20117 Center 1 character over left-margin (in header line):
20118 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20120 Different ways to express width of left fringe plus left margin minus one pixel:
20121 '(space :width (- (+ left-fringe left-margin) (1)))
20122 '(space :width (+ left-fringe left-margin (- (1))))
20123 '(space :width (+ left-fringe left-margin (-1)))
20127 #define NUMVAL(X) \
20128 ((INTEGERP (X) || FLOATP (X)) \
20133 calc_pixel_width_or_height (double *res
, struct it
*it
, Lisp_Object prop
,
20134 struct font
*font
, int width_p
, int *align_to
)
20138 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20139 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20142 return OK_PIXELS (0);
20144 xassert (FRAME_LIVE_P (it
->f
));
20146 if (SYMBOLP (prop
))
20148 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
20150 char *unit
= SDATA (SYMBOL_NAME (prop
));
20152 if (unit
[0] == 'i' && unit
[1] == 'n')
20154 else if (unit
[0] == 'm' && unit
[1] == 'm')
20156 else if (unit
[0] == 'c' && unit
[1] == 'm')
20163 #ifdef HAVE_WINDOW_SYSTEM
20164 if (FRAME_WINDOW_P (it
->f
)
20166 ? FRAME_X_DISPLAY_INFO (it
->f
)->resx
20167 : FRAME_X_DISPLAY_INFO (it
->f
)->resy
),
20169 return OK_PIXELS (ppi
/ pixels
);
20172 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
20173 || (CONSP (Vdisplay_pixels_per_inch
)
20175 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
20176 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
20178 return OK_PIXELS (ppi
/ pixels
);
20184 #ifdef HAVE_WINDOW_SYSTEM
20185 if (EQ (prop
, Qheight
))
20186 return OK_PIXELS (font
? FONT_HEIGHT (font
) : FRAME_LINE_HEIGHT (it
->f
));
20187 if (EQ (prop
, Qwidth
))
20188 return OK_PIXELS (font
? FONT_WIDTH (font
) : FRAME_COLUMN_WIDTH (it
->f
));
20190 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
20191 return OK_PIXELS (1);
20194 if (EQ (prop
, Qtext
))
20195 return OK_PIXELS (width_p
20196 ? window_box_width (it
->w
, TEXT_AREA
)
20197 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
20199 if (align_to
&& *align_to
< 0)
20202 if (EQ (prop
, Qleft
))
20203 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
20204 if (EQ (prop
, Qright
))
20205 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
20206 if (EQ (prop
, Qcenter
))
20207 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
20208 + window_box_width (it
->w
, TEXT_AREA
) / 2);
20209 if (EQ (prop
, Qleft_fringe
))
20210 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
20211 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
20212 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
20213 if (EQ (prop
, Qright_fringe
))
20214 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
20215 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
20216 : window_box_right_offset (it
->w
, TEXT_AREA
));
20217 if (EQ (prop
, Qleft_margin
))
20218 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
20219 if (EQ (prop
, Qright_margin
))
20220 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
20221 if (EQ (prop
, Qscroll_bar
))
20222 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
20224 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
20225 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
20226 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
20231 if (EQ (prop
, Qleft_fringe
))
20232 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
20233 if (EQ (prop
, Qright_fringe
))
20234 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
20235 if (EQ (prop
, Qleft_margin
))
20236 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
20237 if (EQ (prop
, Qright_margin
))
20238 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
20239 if (EQ (prop
, Qscroll_bar
))
20240 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
20243 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
20246 if (INTEGERP (prop
) || FLOATP (prop
))
20248 int base_unit
= (width_p
20249 ? FRAME_COLUMN_WIDTH (it
->f
)
20250 : FRAME_LINE_HEIGHT (it
->f
));
20251 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
20256 Lisp_Object car
= XCAR (prop
);
20257 Lisp_Object cdr
= XCDR (prop
);
20261 #ifdef HAVE_WINDOW_SYSTEM
20262 if (FRAME_WINDOW_P (it
->f
)
20263 && valid_image_p (prop
))
20265 int id
= lookup_image (it
->f
, prop
);
20266 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
20268 return OK_PIXELS (width_p
? img
->width
: img
->height
);
20271 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
20277 while (CONSP (cdr
))
20279 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
20280 font
, width_p
, align_to
))
20283 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
20288 if (EQ (car
, Qminus
))
20290 return OK_PIXELS (pixels
);
20293 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
20296 if (INTEGERP (car
) || FLOATP (car
))
20299 pixels
= XFLOATINT (car
);
20301 return OK_PIXELS (pixels
);
20302 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
20303 font
, width_p
, align_to
))
20304 return OK_PIXELS (pixels
* fact
);
20315 /***********************************************************************
20317 ***********************************************************************/
20319 #ifdef HAVE_WINDOW_SYSTEM
20324 dump_glyph_string (s
)
20325 struct glyph_string
*s
;
20327 fprintf (stderr
, "glyph string\n");
20328 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
20329 s
->x
, s
->y
, s
->width
, s
->height
);
20330 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
20331 fprintf (stderr
, " hl = %d\n", s
->hl
);
20332 fprintf (stderr
, " left overhang = %d, right = %d\n",
20333 s
->left_overhang
, s
->right_overhang
);
20334 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
20335 fprintf (stderr
, " extends to end of line = %d\n",
20336 s
->extends_to_end_of_line_p
);
20337 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
20338 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
20341 #endif /* GLYPH_DEBUG */
20343 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20344 of XChar2b structures for S; it can't be allocated in
20345 init_glyph_string because it must be allocated via `alloca'. W
20346 is the window on which S is drawn. ROW and AREA are the glyph row
20347 and area within the row from which S is constructed. START is the
20348 index of the first glyph structure covered by S. HL is a
20349 face-override for drawing S. */
20352 #define OPTIONAL_HDC(hdc) HDC hdc,
20353 #define DECLARE_HDC(hdc) HDC hdc;
20354 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20355 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20358 #ifndef OPTIONAL_HDC
20359 #define OPTIONAL_HDC(hdc)
20360 #define DECLARE_HDC(hdc)
20361 #define ALLOCATE_HDC(hdc, f)
20362 #define RELEASE_HDC(hdc, f)
20366 init_glyph_string (struct glyph_string
*s
,
20368 XChar2b
*char2b
, struct window
*w
, struct glyph_row
*row
,
20369 enum glyph_row_area area
, int start
, enum draw_glyphs_face hl
)
20371 memset (s
, 0, sizeof *s
);
20373 s
->f
= XFRAME (w
->frame
);
20377 s
->display
= FRAME_X_DISPLAY (s
->f
);
20378 s
->window
= FRAME_X_WINDOW (s
->f
);
20379 s
->char2b
= char2b
;
20383 s
->first_glyph
= row
->glyphs
[area
] + start
;
20384 s
->height
= row
->height
;
20385 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
20386 s
->ybase
= s
->y
+ row
->ascent
;
20390 /* Append the list of glyph strings with head H and tail T to the list
20391 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20394 append_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
20395 struct glyph_string
*h
, struct glyph_string
*t
)
20409 /* Prepend the list of glyph strings with head H and tail T to the
20410 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20414 prepend_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
20415 struct glyph_string
*h
, struct glyph_string
*t
)
20429 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20430 Set *HEAD and *TAIL to the resulting list. */
20433 append_glyph_string (struct glyph_string
**head
, struct glyph_string
**tail
,
20434 struct glyph_string
*s
)
20436 s
->next
= s
->prev
= NULL
;
20437 append_glyph_string_lists (head
, tail
, s
, s
);
20441 /* Get face and two-byte form of character C in face FACE_ID on frame
20442 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
20443 means we want to display multibyte text. DISPLAY_P non-zero means
20444 make sure that X resources for the face returned are allocated.
20445 Value is a pointer to a realized face that is ready for display if
20446 DISPLAY_P is non-zero. */
20448 static INLINE
struct face
*
20449 get_char_face_and_encoding (struct frame
*f
, int c
, int face_id
,
20450 XChar2b
*char2b
, int multibyte_p
, int display_p
)
20452 struct face
*face
= FACE_FROM_ID (f
, face_id
);
20456 unsigned code
= face
->font
->driver
->encode_char (face
->font
, c
);
20458 if (code
!= FONT_INVALID_CODE
)
20459 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
20461 STORE_XCHAR2B (char2b
, 0, 0);
20464 /* Make sure X resources of the face are allocated. */
20465 #ifdef HAVE_X_WINDOWS
20469 xassert (face
!= NULL
);
20470 PREPARE_FACE_FOR_DISPLAY (f
, face
);
20477 /* Get face and two-byte form of character glyph GLYPH on frame F.
20478 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20479 a pointer to a realized face that is ready for display. */
20481 static INLINE
struct face
*
20482 get_glyph_face_and_encoding (struct frame
*f
, struct glyph
*glyph
,
20483 XChar2b
*char2b
, int *two_byte_p
)
20487 xassert (glyph
->type
== CHAR_GLYPH
);
20488 face
= FACE_FROM_ID (f
, glyph
->face_id
);
20495 unsigned code
= face
->font
->driver
->encode_char (face
->font
, glyph
->u
.ch
);
20497 if (code
!= FONT_INVALID_CODE
)
20498 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
20500 STORE_XCHAR2B (char2b
, 0, 0);
20503 /* Make sure X resources of the face are allocated. */
20504 xassert (face
!= NULL
);
20505 PREPARE_FACE_FOR_DISPLAY (f
, face
);
20510 /* Fill glyph string S with composition components specified by S->cmp.
20512 BASE_FACE is the base face of the composition.
20513 S->cmp_from is the index of the first component for S.
20515 OVERLAPS non-zero means S should draw the foreground only, and use
20516 its physical height for clipping. See also draw_glyphs.
20518 Value is the index of a component not in S. */
20521 fill_composite_glyph_string (struct glyph_string
*s
, struct face
*base_face
,
20525 /* For all glyphs of this composition, starting at the offset
20526 S->cmp_from, until we reach the end of the definition or encounter a
20527 glyph that requires the different face, add it to S. */
20532 s
->for_overlaps
= overlaps
;
20535 for (i
= s
->cmp_from
; i
< s
->cmp
->glyph_len
; i
++)
20537 int c
= COMPOSITION_GLYPH (s
->cmp
, i
);
20541 int face_id
= FACE_FOR_CHAR (s
->f
, base_face
->ascii_face
, c
,
20544 face
= get_char_face_and_encoding (s
->f
, c
, face_id
,
20545 s
->char2b
+ i
, 1, 1);
20551 s
->font
= s
->face
->font
;
20553 else if (s
->face
!= face
)
20561 /* All glyph strings for the same composition has the same width,
20562 i.e. the width set for the first component of the composition. */
20563 s
->width
= s
->first_glyph
->pixel_width
;
20565 /* If the specified font could not be loaded, use the frame's
20566 default font, but record the fact that we couldn't load it in
20567 the glyph string so that we can draw rectangles for the
20568 characters of the glyph string. */
20569 if (s
->font
== NULL
)
20571 s
->font_not_found_p
= 1;
20572 s
->font
= FRAME_FONT (s
->f
);
20575 /* Adjust base line for subscript/superscript text. */
20576 s
->ybase
+= s
->first_glyph
->voffset
;
20578 /* This glyph string must always be drawn with 16-bit functions. */
20585 fill_gstring_glyph_string (struct glyph_string
*s
, int face_id
,
20586 int start
, int end
, int overlaps
)
20588 struct glyph
*glyph
, *last
;
20589 Lisp_Object lgstring
;
20592 s
->for_overlaps
= overlaps
;
20593 glyph
= s
->row
->glyphs
[s
->area
] + start
;
20594 last
= s
->row
->glyphs
[s
->area
] + end
;
20595 s
->cmp_id
= glyph
->u
.cmp
.id
;
20596 s
->cmp_from
= glyph
->u
.cmp
.from
;
20597 s
->cmp_to
= glyph
->u
.cmp
.to
+ 1;
20598 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
20599 lgstring
= composition_gstring_from_id (s
->cmp_id
);
20600 s
->font
= XFONT_OBJECT (LGSTRING_FONT (lgstring
));
20602 while (glyph
< last
20603 && glyph
->u
.cmp
.automatic
20604 && glyph
->u
.cmp
.id
== s
->cmp_id
20605 && s
->cmp_to
== glyph
->u
.cmp
.from
)
20606 s
->cmp_to
= (glyph
++)->u
.cmp
.to
+ 1;
20608 for (i
= s
->cmp_from
; i
< s
->cmp_to
; i
++)
20610 Lisp_Object lglyph
= LGSTRING_GLYPH (lgstring
, i
);
20611 unsigned code
= LGLYPH_CODE (lglyph
);
20613 STORE_XCHAR2B ((s
->char2b
+ i
), code
>> 8, code
& 0xFF);
20615 s
->width
= composition_gstring_width (lgstring
, s
->cmp_from
, s
->cmp_to
, NULL
);
20616 return glyph
- s
->row
->glyphs
[s
->area
];
20620 /* Fill glyph string S from a sequence of character glyphs.
20622 FACE_ID is the face id of the string. START is the index of the
20623 first glyph to consider, END is the index of the last + 1.
20624 OVERLAPS non-zero means S should draw the foreground only, and use
20625 its physical height for clipping. See also draw_glyphs.
20627 Value is the index of the first glyph not in S. */
20630 fill_glyph_string (struct glyph_string
*s
, int face_id
,
20631 int start
, int end
, int overlaps
)
20633 struct glyph
*glyph
, *last
;
20635 int glyph_not_available_p
;
20637 xassert (s
->f
== XFRAME (s
->w
->frame
));
20638 xassert (s
->nchars
== 0);
20639 xassert (start
>= 0 && end
> start
);
20641 s
->for_overlaps
= overlaps
;
20642 glyph
= s
->row
->glyphs
[s
->area
] + start
;
20643 last
= s
->row
->glyphs
[s
->area
] + end
;
20644 voffset
= glyph
->voffset
;
20645 s
->padding_p
= glyph
->padding_p
;
20646 glyph_not_available_p
= glyph
->glyph_not_available_p
;
20648 while (glyph
< last
20649 && glyph
->type
== CHAR_GLYPH
20650 && glyph
->voffset
== voffset
20651 /* Same face id implies same font, nowadays. */
20652 && glyph
->face_id
== face_id
20653 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
20657 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
20658 s
->char2b
+ s
->nchars
,
20660 s
->two_byte_p
= two_byte_p
;
20662 xassert (s
->nchars
<= end
- start
);
20663 s
->width
+= glyph
->pixel_width
;
20664 if (glyph
++->padding_p
!= s
->padding_p
)
20668 s
->font
= s
->face
->font
;
20670 /* If the specified font could not be loaded, use the frame's font,
20671 but record the fact that we couldn't load it in
20672 S->font_not_found_p so that we can draw rectangles for the
20673 characters of the glyph string. */
20674 if (s
->font
== NULL
|| glyph_not_available_p
)
20676 s
->font_not_found_p
= 1;
20677 s
->font
= FRAME_FONT (s
->f
);
20680 /* Adjust base line for subscript/superscript text. */
20681 s
->ybase
+= voffset
;
20683 xassert (s
->face
&& s
->face
->gc
);
20684 return glyph
- s
->row
->glyphs
[s
->area
];
20688 /* Fill glyph string S from image glyph S->first_glyph. */
20691 fill_image_glyph_string (struct glyph_string
*s
)
20693 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
20694 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
20696 s
->slice
= s
->first_glyph
->slice
;
20697 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
20698 s
->font
= s
->face
->font
;
20699 s
->width
= s
->first_glyph
->pixel_width
;
20701 /* Adjust base line for subscript/superscript text. */
20702 s
->ybase
+= s
->first_glyph
->voffset
;
20706 /* Fill glyph string S from a sequence of stretch glyphs.
20708 ROW is the glyph row in which the glyphs are found, AREA is the
20709 area within the row. START is the index of the first glyph to
20710 consider, END is the index of the last + 1.
20712 Value is the index of the first glyph not in S. */
20715 fill_stretch_glyph_string (struct glyph_string
*s
, struct glyph_row
*row
,
20716 enum glyph_row_area area
, int start
, int end
)
20718 struct glyph
*glyph
, *last
;
20719 int voffset
, face_id
;
20721 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
20723 glyph
= s
->row
->glyphs
[s
->area
] + start
;
20724 last
= s
->row
->glyphs
[s
->area
] + end
;
20725 face_id
= glyph
->face_id
;
20726 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
20727 s
->font
= s
->face
->font
;
20728 s
->width
= glyph
->pixel_width
;
20730 voffset
= glyph
->voffset
;
20734 && glyph
->type
== STRETCH_GLYPH
20735 && glyph
->voffset
== voffset
20736 && glyph
->face_id
== face_id
);
20738 s
->width
+= glyph
->pixel_width
;
20740 /* Adjust base line for subscript/superscript text. */
20741 s
->ybase
+= voffset
;
20743 /* The case that face->gc == 0 is handled when drawing the glyph
20744 string by calling PREPARE_FACE_FOR_DISPLAY. */
20746 return glyph
- s
->row
->glyphs
[s
->area
];
20749 static struct font_metrics
*
20750 get_per_char_metric (struct frame
*f
, struct font
*font
, XChar2b
*char2b
)
20752 static struct font_metrics metrics
;
20753 unsigned code
= (XCHAR2B_BYTE1 (char2b
) << 8) | XCHAR2B_BYTE2 (char2b
);
20755 if (! font
|| code
== FONT_INVALID_CODE
)
20757 font
->driver
->text_extents (font
, &code
, 1, &metrics
);
20762 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20763 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20764 assumed to be zero. */
20767 x_get_glyph_overhangs (struct glyph
*glyph
, struct frame
*f
, int *left
, int *right
)
20769 *left
= *right
= 0;
20771 if (glyph
->type
== CHAR_GLYPH
)
20775 struct font_metrics
*pcm
;
20777 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
20778 if (face
->font
&& (pcm
= get_per_char_metric (f
, face
->font
, &char2b
)))
20780 if (pcm
->rbearing
> pcm
->width
)
20781 *right
= pcm
->rbearing
- pcm
->width
;
20782 if (pcm
->lbearing
< 0)
20783 *left
= -pcm
->lbearing
;
20786 else if (glyph
->type
== COMPOSITE_GLYPH
)
20788 if (! glyph
->u
.cmp
.automatic
)
20790 struct composition
*cmp
= composition_table
[glyph
->u
.cmp
.id
];
20792 if (cmp
->rbearing
> cmp
->pixel_width
)
20793 *right
= cmp
->rbearing
- cmp
->pixel_width
;
20794 if (cmp
->lbearing
< 0)
20795 *left
= - cmp
->lbearing
;
20799 Lisp_Object gstring
= composition_gstring_from_id (glyph
->u
.cmp
.id
);
20800 struct font_metrics metrics
;
20802 composition_gstring_width (gstring
, glyph
->u
.cmp
.from
,
20803 glyph
->u
.cmp
.to
+ 1, &metrics
);
20804 if (metrics
.rbearing
> metrics
.width
)
20805 *right
= metrics
.rbearing
- metrics
.width
;
20806 if (metrics
.lbearing
< 0)
20807 *left
= - metrics
.lbearing
;
20813 /* Return the index of the first glyph preceding glyph string S that
20814 is overwritten by S because of S's left overhang. Value is -1
20815 if no glyphs are overwritten. */
20818 left_overwritten (struct glyph_string
*s
)
20822 if (s
->left_overhang
)
20825 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
20826 int first
= s
->first_glyph
- glyphs
;
20828 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
20829 x
-= glyphs
[i
].pixel_width
;
20840 /* Return the index of the first glyph preceding glyph string S that
20841 is overwriting S because of its right overhang. Value is -1 if no
20842 glyph in front of S overwrites S. */
20845 left_overwriting (struct glyph_string
*s
)
20848 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
20849 int first
= s
->first_glyph
- glyphs
;
20853 for (i
= first
- 1; i
>= 0; --i
)
20856 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
20859 x
-= glyphs
[i
].pixel_width
;
20866 /* Return the index of the last glyph following glyph string S that is
20867 overwritten by S because of S's right overhang. Value is -1 if
20868 no such glyph is found. */
20871 right_overwritten (struct glyph_string
*s
)
20875 if (s
->right_overhang
)
20878 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
20879 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
20880 int end
= s
->row
->used
[s
->area
];
20882 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
20883 x
+= glyphs
[i
].pixel_width
;
20892 /* Return the index of the last glyph following glyph string S that
20893 overwrites S because of its left overhang. Value is negative
20894 if no such glyph is found. */
20897 right_overwriting (struct glyph_string
*s
)
20900 int end
= s
->row
->used
[s
->area
];
20901 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
20902 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
20906 for (i
= first
; i
< end
; ++i
)
20909 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
20912 x
+= glyphs
[i
].pixel_width
;
20919 /* Set background width of glyph string S. START is the index of the
20920 first glyph following S. LAST_X is the right-most x-position + 1
20921 in the drawing area. */
20924 set_glyph_string_background_width (struct glyph_string
*s
, int start
, int last_x
)
20926 /* If the face of this glyph string has to be drawn to the end of
20927 the drawing area, set S->extends_to_end_of_line_p. */
20929 if (start
== s
->row
->used
[s
->area
]
20930 && s
->area
== TEXT_AREA
20931 && ((s
->row
->fill_line_p
20932 && (s
->hl
== DRAW_NORMAL_TEXT
20933 || s
->hl
== DRAW_IMAGE_RAISED
20934 || s
->hl
== DRAW_IMAGE_SUNKEN
))
20935 || s
->hl
== DRAW_MOUSE_FACE
))
20936 s
->extends_to_end_of_line_p
= 1;
20938 /* If S extends its face to the end of the line, set its
20939 background_width to the distance to the right edge of the drawing
20941 if (s
->extends_to_end_of_line_p
)
20942 s
->background_width
= last_x
- s
->x
+ 1;
20944 s
->background_width
= s
->width
;
20948 /* Compute overhangs and x-positions for glyph string S and its
20949 predecessors, or successors. X is the starting x-position for S.
20950 BACKWARD_P non-zero means process predecessors. */
20953 compute_overhangs_and_x (struct glyph_string
*s
, int x
, int backward_p
)
20959 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
20960 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
20970 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
20971 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
20981 /* The following macros are only called from draw_glyphs below.
20982 They reference the following parameters of that function directly:
20983 `w', `row', `area', and `overlap_p'
20984 as well as the following local variables:
20985 `s', `f', and `hdc' (in W32) */
20988 /* On W32, silently add local `hdc' variable to argument list of
20989 init_glyph_string. */
20990 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20991 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
20993 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20994 init_glyph_string (s, char2b, w, row, area, start, hl)
20997 /* Add a glyph string for a stretch glyph to the list of strings
20998 between HEAD and TAIL. START is the index of the stretch glyph in
20999 row area AREA of glyph row ROW. END is the index of the last glyph
21000 in that glyph row area. X is the current output position assigned
21001 to the new glyph string constructed. HL overrides that face of the
21002 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21003 is the right-most x-position of the drawing area. */
21005 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21006 and below -- keep them on one line. */
21007 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21010 s = (struct glyph_string *) alloca (sizeof *s); \
21011 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21012 START = fill_stretch_glyph_string (s, row, area, START, END); \
21013 append_glyph_string (&HEAD, &TAIL, s); \
21019 /* Add a glyph string for an image glyph to the list of strings
21020 between HEAD and TAIL. START is the index of the image glyph in
21021 row area AREA of glyph row ROW. END is the index of the last glyph
21022 in that glyph row area. X is the current output position assigned
21023 to the new glyph string constructed. HL overrides that face of the
21024 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21025 is the right-most x-position of the drawing area. */
21027 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21030 s = (struct glyph_string *) alloca (sizeof *s); \
21031 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21032 fill_image_glyph_string (s); \
21033 append_glyph_string (&HEAD, &TAIL, s); \
21040 /* Add a glyph string for a sequence of character glyphs to the list
21041 of strings between HEAD and TAIL. START is the index of the first
21042 glyph in row area AREA of glyph row ROW that is part of the new
21043 glyph string. END is the index of the last glyph in that glyph row
21044 area. X is the current output position assigned to the new glyph
21045 string constructed. HL overrides that face of the glyph; e.g. it
21046 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21047 right-most x-position of the drawing area. */
21049 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21055 face_id = (row)->glyphs[area][START].face_id; \
21057 s = (struct glyph_string *) alloca (sizeof *s); \
21058 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21059 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21060 append_glyph_string (&HEAD, &TAIL, s); \
21062 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21067 /* Add a glyph string for a composite sequence to the list of strings
21068 between HEAD and TAIL. START is the index of the first glyph in
21069 row area AREA of glyph row ROW that is part of the new glyph
21070 string. END is the index of the last glyph in that glyph row area.
21071 X is the current output position assigned to the new glyph string
21072 constructed. HL overrides that face of the glyph; e.g. it is
21073 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21074 x-position of the drawing area. */
21076 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21078 int face_id = (row)->glyphs[area][START].face_id; \
21079 struct face *base_face = FACE_FROM_ID (f, face_id); \
21080 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21081 struct composition *cmp = composition_table[cmp_id]; \
21083 struct glyph_string *first_s; \
21086 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21088 /* Make glyph_strings for each glyph sequence that is drawable by \
21089 the same face, and append them to HEAD/TAIL. */ \
21090 for (n = 0; n < cmp->glyph_len;) \
21092 s = (struct glyph_string *) alloca (sizeof *s); \
21093 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21094 append_glyph_string (&(HEAD), &(TAIL), s); \
21100 n = fill_composite_glyph_string (s, base_face, overlaps); \
21108 /* Add a glyph string for a glyph-string sequence to the list of strings
21109 between HEAD and TAIL. */
21111 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21115 Lisp_Object gstring; \
21117 face_id = (row)->glyphs[area][START].face_id; \
21118 gstring = (composition_gstring_from_id \
21119 ((row)->glyphs[area][START].u.cmp.id)); \
21120 s = (struct glyph_string *) alloca (sizeof *s); \
21121 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21122 * LGSTRING_GLYPH_LEN (gstring)); \
21123 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21124 append_glyph_string (&(HEAD), &(TAIL), s); \
21126 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21130 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21131 of AREA of glyph row ROW on window W between indices START and END.
21132 HL overrides the face for drawing glyph strings, e.g. it is
21133 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21134 x-positions of the drawing area.
21136 This is an ugly monster macro construct because we must use alloca
21137 to allocate glyph strings (because draw_glyphs can be called
21138 asynchronously). */
21140 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21143 HEAD = TAIL = NULL; \
21144 while (START < END) \
21146 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21147 switch (first_glyph->type) \
21150 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21154 case COMPOSITE_GLYPH: \
21155 if (first_glyph->u.cmp.automatic) \
21156 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21159 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21163 case STRETCH_GLYPH: \
21164 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21168 case IMAGE_GLYPH: \
21169 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21179 set_glyph_string_background_width (s, START, LAST_X); \
21186 /* Draw glyphs between START and END in AREA of ROW on window W,
21187 starting at x-position X. X is relative to AREA in W. HL is a
21188 face-override with the following meaning:
21190 DRAW_NORMAL_TEXT draw normally
21191 DRAW_CURSOR draw in cursor face
21192 DRAW_MOUSE_FACE draw in mouse face.
21193 DRAW_INVERSE_VIDEO draw in mode line face
21194 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21195 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21197 If OVERLAPS is non-zero, draw only the foreground of characters and
21198 clip to the physical height of ROW. Non-zero value also defines
21199 the overlapping part to be drawn:
21201 OVERLAPS_PRED overlap with preceding rows
21202 OVERLAPS_SUCC overlap with succeeding rows
21203 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21204 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21206 Value is the x-position reached, relative to AREA of W. */
21209 draw_glyphs (struct window
*w
, int x
, struct glyph_row
*row
,
21210 enum glyph_row_area area
, EMACS_INT start
, EMACS_INT end
,
21211 enum draw_glyphs_face hl
, int overlaps
)
21213 struct glyph_string
*head
, *tail
;
21214 struct glyph_string
*s
;
21215 struct glyph_string
*clip_head
= NULL
, *clip_tail
= NULL
;
21216 int i
, j
, x_reached
, last_x
, area_left
= 0;
21217 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
21220 ALLOCATE_HDC (hdc
, f
);
21222 /* Let's rather be paranoid than getting a SEGV. */
21223 end
= min (end
, row
->used
[area
]);
21224 start
= max (0, start
);
21225 start
= min (end
, start
);
21227 /* Translate X to frame coordinates. Set last_x to the right
21228 end of the drawing area. */
21229 if (row
->full_width_p
)
21231 /* X is relative to the left edge of W, without scroll bars
21233 area_left
= WINDOW_LEFT_EDGE_X (w
);
21234 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
21238 area_left
= window_box_left (w
, area
);
21239 last_x
= area_left
+ window_box_width (w
, area
);
21243 /* Build a doubly-linked list of glyph_string structures between
21244 head and tail from what we have to draw. Note that the macro
21245 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21246 the reason we use a separate variable `i'. */
21248 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
21250 x_reached
= tail
->x
+ tail
->background_width
;
21254 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21255 the row, redraw some glyphs in front or following the glyph
21256 strings built above. */
21257 if (head
&& !overlaps
&& row
->contains_overlapping_glyphs_p
)
21259 struct glyph_string
*h
, *t
;
21260 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21261 int mouse_beg_col
, mouse_end_col
, check_mouse_face
= 0;
21264 /* If mouse highlighting is on, we may need to draw adjacent
21265 glyphs using mouse-face highlighting. */
21266 if (area
== TEXT_AREA
&& row
->mouse_face_p
)
21268 struct glyph_row
*mouse_beg_row
, *mouse_end_row
;
21270 mouse_beg_row
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
21271 mouse_end_row
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
21273 if (row
>= mouse_beg_row
&& row
<= mouse_end_row
)
21275 check_mouse_face
= 1;
21276 mouse_beg_col
= (row
== mouse_beg_row
)
21277 ? dpyinfo
->mouse_face_beg_col
: 0;
21278 mouse_end_col
= (row
== mouse_end_row
)
21279 ? dpyinfo
->mouse_face_end_col
21280 : row
->used
[TEXT_AREA
];
21284 /* Compute overhangs for all glyph strings. */
21285 if (FRAME_RIF (f
)->compute_glyph_string_overhangs
)
21286 for (s
= head
; s
; s
= s
->next
)
21287 FRAME_RIF (f
)->compute_glyph_string_overhangs (s
);
21289 /* Prepend glyph strings for glyphs in front of the first glyph
21290 string that are overwritten because of the first glyph
21291 string's left overhang. The background of all strings
21292 prepended must be drawn because the first glyph string
21294 i
= left_overwritten (head
);
21297 enum draw_glyphs_face overlap_hl
;
21299 /* If this row contains mouse highlighting, attempt to draw
21300 the overlapped glyphs with the correct highlight. This
21301 code fails if the overlap encompasses more than one glyph
21302 and mouse-highlight spans only some of these glyphs.
21303 However, making it work perfectly involves a lot more
21304 code, and I don't know if the pathological case occurs in
21305 practice, so we'll stick to this for now. --- cyd */
21306 if (check_mouse_face
21307 && mouse_beg_col
< start
&& mouse_end_col
> i
)
21308 overlap_hl
= DRAW_MOUSE_FACE
;
21310 overlap_hl
= DRAW_NORMAL_TEXT
;
21313 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
21314 overlap_hl
, dummy_x
, last_x
);
21316 compute_overhangs_and_x (t
, head
->x
, 1);
21317 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
21321 /* Prepend glyph strings for glyphs in front of the first glyph
21322 string that overwrite that glyph string because of their
21323 right overhang. For these strings, only the foreground must
21324 be drawn, because it draws over the glyph string at `head'.
21325 The background must not be drawn because this would overwrite
21326 right overhangs of preceding glyphs for which no glyph
21328 i
= left_overwriting (head
);
21331 enum draw_glyphs_face overlap_hl
;
21333 if (check_mouse_face
21334 && mouse_beg_col
< start
&& mouse_end_col
> i
)
21335 overlap_hl
= DRAW_MOUSE_FACE
;
21337 overlap_hl
= DRAW_NORMAL_TEXT
;
21340 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
21341 overlap_hl
, dummy_x
, last_x
);
21342 for (s
= h
; s
; s
= s
->next
)
21343 s
->background_filled_p
= 1;
21344 compute_overhangs_and_x (t
, head
->x
, 1);
21345 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
21348 /* Append glyphs strings for glyphs following the last glyph
21349 string tail that are overwritten by tail. The background of
21350 these strings has to be drawn because tail's foreground draws
21352 i
= right_overwritten (tail
);
21355 enum draw_glyphs_face overlap_hl
;
21357 if (check_mouse_face
21358 && mouse_beg_col
< i
&& mouse_end_col
> end
)
21359 overlap_hl
= DRAW_MOUSE_FACE
;
21361 overlap_hl
= DRAW_NORMAL_TEXT
;
21363 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
21364 overlap_hl
, x
, last_x
);
21365 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21366 we don't have `end = i;' here. */
21367 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
21368 append_glyph_string_lists (&head
, &tail
, h
, t
);
21372 /* Append glyph strings for glyphs following the last glyph
21373 string tail that overwrite tail. The foreground of such
21374 glyphs has to be drawn because it writes into the background
21375 of tail. The background must not be drawn because it could
21376 paint over the foreground of following glyphs. */
21377 i
= right_overwriting (tail
);
21380 enum draw_glyphs_face overlap_hl
;
21381 if (check_mouse_face
21382 && mouse_beg_col
< i
&& mouse_end_col
> end
)
21383 overlap_hl
= DRAW_MOUSE_FACE
;
21385 overlap_hl
= DRAW_NORMAL_TEXT
;
21388 i
++; /* We must include the Ith glyph. */
21389 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
21390 overlap_hl
, x
, last_x
);
21391 for (s
= h
; s
; s
= s
->next
)
21392 s
->background_filled_p
= 1;
21393 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
21394 append_glyph_string_lists (&head
, &tail
, h
, t
);
21396 if (clip_head
|| clip_tail
)
21397 for (s
= head
; s
; s
= s
->next
)
21399 s
->clip_head
= clip_head
;
21400 s
->clip_tail
= clip_tail
;
21404 /* Draw all strings. */
21405 for (s
= head
; s
; s
= s
->next
)
21406 FRAME_RIF (f
)->draw_glyph_string (s
);
21409 /* When focus a sole frame and move horizontally, this sets on_p to 0
21410 causing a failure to erase prev cursor position. */
21411 if (area
== TEXT_AREA
21412 && !row
->full_width_p
21413 /* When drawing overlapping rows, only the glyph strings'
21414 foreground is drawn, which doesn't erase a cursor
21418 int x0
= clip_head
? clip_head
->x
: (head
? head
->x
: x
);
21419 int x1
= (clip_tail
? clip_tail
->x
+ clip_tail
->background_width
21420 : (tail
? tail
->x
+ tail
->background_width
: x
));
21424 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
21425 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
21429 /* Value is the x-position up to which drawn, relative to AREA of W.
21430 This doesn't include parts drawn because of overhangs. */
21431 if (row
->full_width_p
)
21432 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
21434 x_reached
-= area_left
;
21436 RELEASE_HDC (hdc
, f
);
21441 /* Expand row matrix if too narrow. Don't expand if area
21444 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21446 if (!fonts_changed_p \
21447 && (it->glyph_row->glyphs[area] \
21448 < it->glyph_row->glyphs[area + 1])) \
21450 it->w->ncols_scale_factor++; \
21451 fonts_changed_p = 1; \
21455 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21456 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21459 append_glyph (struct it
*it
)
21461 struct glyph
*glyph
;
21462 enum glyph_row_area area
= it
->area
;
21464 xassert (it
->glyph_row
);
21465 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
21467 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
21468 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
21470 /* If the glyph row is reversed, we need to prepend the glyph
21471 rather than append it. */
21472 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
21476 /* Make room for the additional glyph. */
21477 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
21479 glyph
= it
->glyph_row
->glyphs
[area
];
21481 glyph
->charpos
= CHARPOS (it
->position
);
21482 glyph
->object
= it
->object
;
21483 if (it
->pixel_width
> 0)
21485 glyph
->pixel_width
= it
->pixel_width
;
21486 glyph
->padding_p
= 0;
21490 /* Assure at least 1-pixel width. Otherwise, cursor can't
21491 be displayed correctly. */
21492 glyph
->pixel_width
= 1;
21493 glyph
->padding_p
= 1;
21495 glyph
->ascent
= it
->ascent
;
21496 glyph
->descent
= it
->descent
;
21497 glyph
->voffset
= it
->voffset
;
21498 glyph
->type
= CHAR_GLYPH
;
21499 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
21500 glyph
->multibyte_p
= it
->multibyte_p
;
21501 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
21502 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
21503 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
21504 || it
->phys_descent
> it
->descent
);
21505 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
21506 glyph
->face_id
= it
->face_id
;
21507 glyph
->u
.ch
= it
->char_to_display
;
21508 glyph
->slice
= null_glyph_slice
;
21509 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
21512 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
21513 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
21515 glyph
->bidi_type
= it
->bidi_it
.type
;
21519 glyph
->resolved_level
= 0;
21520 glyph
->bidi_type
= UNKNOWN_BT
;
21522 ++it
->glyph_row
->used
[area
];
21525 IT_EXPAND_MATRIX_WIDTH (it
, area
);
21528 /* Store one glyph for the composition IT->cmp_it.id in
21529 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21533 append_composite_glyph (struct it
*it
)
21535 struct glyph
*glyph
;
21536 enum glyph_row_area area
= it
->area
;
21538 xassert (it
->glyph_row
);
21540 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
21541 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
21543 /* If the glyph row is reversed, we need to prepend the glyph
21544 rather than append it. */
21545 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
21549 /* Make room for the new glyph. */
21550 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
21552 glyph
= it
->glyph_row
->glyphs
[it
->area
];
21554 glyph
->charpos
= it
->cmp_it
.charpos
;
21555 glyph
->object
= it
->object
;
21556 glyph
->pixel_width
= it
->pixel_width
;
21557 glyph
->ascent
= it
->ascent
;
21558 glyph
->descent
= it
->descent
;
21559 glyph
->voffset
= it
->voffset
;
21560 glyph
->type
= COMPOSITE_GLYPH
;
21561 if (it
->cmp_it
.ch
< 0)
21563 glyph
->u
.cmp
.automatic
= 0;
21564 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
21568 glyph
->u
.cmp
.automatic
= 1;
21569 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
21570 glyph
->u
.cmp
.from
= it
->cmp_it
.from
;
21571 glyph
->u
.cmp
.to
= it
->cmp_it
.to
- 1;
21573 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
21574 glyph
->multibyte_p
= it
->multibyte_p
;
21575 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
21576 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
21577 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
21578 || it
->phys_descent
> it
->descent
);
21579 glyph
->padding_p
= 0;
21580 glyph
->glyph_not_available_p
= 0;
21581 glyph
->face_id
= it
->face_id
;
21582 glyph
->slice
= null_glyph_slice
;
21583 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
21586 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
21587 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
21589 glyph
->bidi_type
= it
->bidi_it
.type
;
21591 ++it
->glyph_row
->used
[area
];
21594 IT_EXPAND_MATRIX_WIDTH (it
, area
);
21598 /* Change IT->ascent and IT->height according to the setting of
21602 take_vertical_position_into_account (struct it
*it
)
21606 if (it
->voffset
< 0)
21607 /* Increase the ascent so that we can display the text higher
21609 it
->ascent
-= it
->voffset
;
21611 /* Increase the descent so that we can display the text lower
21613 it
->descent
+= it
->voffset
;
21618 /* Produce glyphs/get display metrics for the image IT is loaded with.
21619 See the description of struct display_iterator in dispextern.h for
21620 an overview of struct display_iterator. */
21623 produce_image_glyph (struct it
*it
)
21627 int glyph_ascent
, crop
;
21628 struct glyph_slice slice
;
21630 xassert (it
->what
== IT_IMAGE
);
21632 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
21634 /* Make sure X resources of the face is loaded. */
21635 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
21637 if (it
->image_id
< 0)
21639 /* Fringe bitmap. */
21640 it
->ascent
= it
->phys_ascent
= 0;
21641 it
->descent
= it
->phys_descent
= 0;
21642 it
->pixel_width
= 0;
21647 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
21649 /* Make sure X resources of the image is loaded. */
21650 prepare_image_for_display (it
->f
, img
);
21652 slice
.x
= slice
.y
= 0;
21653 slice
.width
= img
->width
;
21654 slice
.height
= img
->height
;
21656 if (INTEGERP (it
->slice
.x
))
21657 slice
.x
= XINT (it
->slice
.x
);
21658 else if (FLOATP (it
->slice
.x
))
21659 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
21661 if (INTEGERP (it
->slice
.y
))
21662 slice
.y
= XINT (it
->slice
.y
);
21663 else if (FLOATP (it
->slice
.y
))
21664 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
21666 if (INTEGERP (it
->slice
.width
))
21667 slice
.width
= XINT (it
->slice
.width
);
21668 else if (FLOATP (it
->slice
.width
))
21669 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
21671 if (INTEGERP (it
->slice
.height
))
21672 slice
.height
= XINT (it
->slice
.height
);
21673 else if (FLOATP (it
->slice
.height
))
21674 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
21676 if (slice
.x
>= img
->width
)
21677 slice
.x
= img
->width
;
21678 if (slice
.y
>= img
->height
)
21679 slice
.y
= img
->height
;
21680 if (slice
.x
+ slice
.width
>= img
->width
)
21681 slice
.width
= img
->width
- slice
.x
;
21682 if (slice
.y
+ slice
.height
> img
->height
)
21683 slice
.height
= img
->height
- slice
.y
;
21685 if (slice
.width
== 0 || slice
.height
== 0)
21688 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
21690 it
->descent
= slice
.height
- glyph_ascent
;
21692 it
->descent
+= img
->vmargin
;
21693 if (slice
.y
+ slice
.height
== img
->height
)
21694 it
->descent
+= img
->vmargin
;
21695 it
->phys_descent
= it
->descent
;
21697 it
->pixel_width
= slice
.width
;
21699 it
->pixel_width
+= img
->hmargin
;
21700 if (slice
.x
+ slice
.width
== img
->width
)
21701 it
->pixel_width
+= img
->hmargin
;
21703 /* It's quite possible for images to have an ascent greater than
21704 their height, so don't get confused in that case. */
21705 if (it
->descent
< 0)
21710 if (face
->box
!= FACE_NO_BOX
)
21712 if (face
->box_line_width
> 0)
21715 it
->ascent
+= face
->box_line_width
;
21716 if (slice
.y
+ slice
.height
== img
->height
)
21717 it
->descent
+= face
->box_line_width
;
21720 if (it
->start_of_box_run_p
&& slice
.x
== 0)
21721 it
->pixel_width
+= eabs (face
->box_line_width
);
21722 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
21723 it
->pixel_width
+= eabs (face
->box_line_width
);
21726 take_vertical_position_into_account (it
);
21728 /* Automatically crop wide image glyphs at right edge so we can
21729 draw the cursor on same display row. */
21730 if ((crop
= it
->pixel_width
- (it
->last_visible_x
- it
->current_x
), crop
> 0)
21731 && (it
->hpos
== 0 || it
->pixel_width
> it
->last_visible_x
/ 4))
21733 it
->pixel_width
-= crop
;
21734 slice
.width
-= crop
;
21739 struct glyph
*glyph
;
21740 enum glyph_row_area area
= it
->area
;
21742 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
21743 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
21745 glyph
->charpos
= CHARPOS (it
->position
);
21746 glyph
->object
= it
->object
;
21747 glyph
->pixel_width
= it
->pixel_width
;
21748 glyph
->ascent
= glyph_ascent
;
21749 glyph
->descent
= it
->descent
;
21750 glyph
->voffset
= it
->voffset
;
21751 glyph
->type
= IMAGE_GLYPH
;
21752 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
21753 glyph
->multibyte_p
= it
->multibyte_p
;
21754 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
21755 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
21756 glyph
->overlaps_vertically_p
= 0;
21757 glyph
->padding_p
= 0;
21758 glyph
->glyph_not_available_p
= 0;
21759 glyph
->face_id
= it
->face_id
;
21760 glyph
->u
.img_id
= img
->id
;
21761 glyph
->slice
= slice
;
21762 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
21765 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
21766 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
21768 glyph
->bidi_type
= it
->bidi_it
.type
;
21770 ++it
->glyph_row
->used
[area
];
21773 IT_EXPAND_MATRIX_WIDTH (it
, area
);
21778 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
21779 of the glyph, WIDTH and HEIGHT are the width and height of the
21780 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
21783 append_stretch_glyph (struct it
*it
, Lisp_Object object
,
21784 int width
, int height
, int ascent
)
21786 struct glyph
*glyph
;
21787 enum glyph_row_area area
= it
->area
;
21789 xassert (ascent
>= 0 && ascent
<= height
);
21791 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
21792 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
21794 /* If the glyph row is reversed, we need to prepend the glyph
21795 rather than append it. */
21796 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
21800 /* Make room for the additional glyph. */
21801 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
21803 glyph
= it
->glyph_row
->glyphs
[area
];
21805 glyph
->charpos
= CHARPOS (it
->position
);
21806 glyph
->object
= object
;
21807 glyph
->pixel_width
= width
;
21808 glyph
->ascent
= ascent
;
21809 glyph
->descent
= height
- ascent
;
21810 glyph
->voffset
= it
->voffset
;
21811 glyph
->type
= STRETCH_GLYPH
;
21812 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
21813 glyph
->multibyte_p
= it
->multibyte_p
;
21814 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
21815 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
21816 glyph
->overlaps_vertically_p
= 0;
21817 glyph
->padding_p
= 0;
21818 glyph
->glyph_not_available_p
= 0;
21819 glyph
->face_id
= it
->face_id
;
21820 glyph
->u
.stretch
.ascent
= ascent
;
21821 glyph
->u
.stretch
.height
= height
;
21822 glyph
->slice
= null_glyph_slice
;
21823 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
21826 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
21827 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
21829 glyph
->bidi_type
= it
->bidi_it
.type
;
21833 glyph
->resolved_level
= 0;
21834 glyph
->bidi_type
= UNKNOWN_BT
;
21836 ++it
->glyph_row
->used
[area
];
21839 IT_EXPAND_MATRIX_WIDTH (it
, area
);
21843 /* Produce a stretch glyph for iterator IT. IT->object is the value
21844 of the glyph property displayed. The value must be a list
21845 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
21848 1. `:width WIDTH' specifies that the space should be WIDTH *
21849 canonical char width wide. WIDTH may be an integer or floating
21852 2. `:relative-width FACTOR' specifies that the width of the stretch
21853 should be computed from the width of the first character having the
21854 `glyph' property, and should be FACTOR times that width.
21856 3. `:align-to HPOS' specifies that the space should be wide enough
21857 to reach HPOS, a value in canonical character units.
21859 Exactly one of the above pairs must be present.
21861 4. `:height HEIGHT' specifies that the height of the stretch produced
21862 should be HEIGHT, measured in canonical character units.
21864 5. `:relative-height FACTOR' specifies that the height of the
21865 stretch should be FACTOR times the height of the characters having
21866 the glyph property.
21868 Either none or exactly one of 4 or 5 must be present.
21870 6. `:ascent ASCENT' specifies that ASCENT percent of the height
21871 of the stretch should be used for the ascent of the stretch.
21872 ASCENT must be in the range 0 <= ASCENT <= 100. */
21875 produce_stretch_glyph (struct it
*it
)
21877 /* (space :width WIDTH :height HEIGHT ...) */
21878 Lisp_Object prop
, plist
;
21879 int width
= 0, height
= 0, align_to
= -1;
21880 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
21883 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
21884 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
21886 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
21888 /* List should start with `space'. */
21889 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
21890 plist
= XCDR (it
->object
);
21892 /* Compute the width of the stretch. */
21893 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
21894 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
21896 /* Absolute width `:width WIDTH' specified and valid. */
21897 zero_width_ok_p
= 1;
21900 else if (prop
= Fplist_get (plist
, QCrelative_width
),
21903 /* Relative width `:relative-width FACTOR' specified and valid.
21904 Compute the width of the characters having the `glyph'
21907 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
21910 if (it
->multibyte_p
)
21912 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
21913 - IT_BYTEPOS (*it
));
21914 it2
.c
= STRING_CHAR_AND_LENGTH (p
, it2
.len
);
21917 it2
.c
= *p
, it2
.len
= 1;
21919 it2
.glyph_row
= NULL
;
21920 it2
.what
= IT_CHARACTER
;
21921 x_produce_glyphs (&it2
);
21922 width
= NUMVAL (prop
) * it2
.pixel_width
;
21924 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
21925 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
21927 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
21928 align_to
= (align_to
< 0
21930 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
21931 else if (align_to
< 0)
21932 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
21933 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
21934 zero_width_ok_p
= 1;
21937 /* Nothing specified -> width defaults to canonical char width. */
21938 width
= FRAME_COLUMN_WIDTH (it
->f
);
21940 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
21943 /* Compute height. */
21944 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
21945 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
21948 zero_height_ok_p
= 1;
21950 else if (prop
= Fplist_get (plist
, QCrelative_height
),
21952 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
21954 height
= FONT_HEIGHT (font
);
21956 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
21959 /* Compute percentage of height used for ascent. If
21960 `:ascent ASCENT' is present and valid, use that. Otherwise,
21961 derive the ascent from the font in use. */
21962 if (prop
= Fplist_get (plist
, QCascent
),
21963 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
21964 ascent
= height
* NUMVAL (prop
) / 100.0;
21965 else if (!NILP (prop
)
21966 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
21967 ascent
= min (max (0, (int)tem
), height
);
21969 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
21971 if (width
> 0 && it
->line_wrap
!= TRUNCATE
21972 && it
->current_x
+ width
> it
->last_visible_x
)
21973 width
= it
->last_visible_x
- it
->current_x
- 1;
21975 if (width
> 0 && height
> 0 && it
->glyph_row
)
21977 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
21978 if (!STRINGP (object
))
21979 object
= it
->w
->buffer
;
21980 append_stretch_glyph (it
, object
, width
, height
, ascent
);
21983 it
->pixel_width
= width
;
21984 it
->ascent
= it
->phys_ascent
= ascent
;
21985 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
21986 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
21988 take_vertical_position_into_account (it
);
21991 /* Calculate line-height and line-spacing properties.
21992 An integer value specifies explicit pixel value.
21993 A float value specifies relative value to current face height.
21994 A cons (float . face-name) specifies relative value to
21995 height of specified face font.
21997 Returns height in pixels, or nil. */
22001 calc_line_height_property (struct it
*it
, Lisp_Object val
, struct font
*font
,
22002 int boff
, int override
)
22004 Lisp_Object face_name
= Qnil
;
22005 int ascent
, descent
, height
;
22007 if (NILP (val
) || INTEGERP (val
) || (override
&& EQ (val
, Qt
)))
22012 face_name
= XCAR (val
);
22014 if (!NUMBERP (val
))
22015 val
= make_number (1);
22016 if (NILP (face_name
))
22018 height
= it
->ascent
+ it
->descent
;
22023 if (NILP (face_name
))
22025 font
= FRAME_FONT (it
->f
);
22026 boff
= FRAME_BASELINE_OFFSET (it
->f
);
22028 else if (EQ (face_name
, Qt
))
22037 face_id
= lookup_named_face (it
->f
, face_name
, 0);
22039 return make_number (-1);
22041 face
= FACE_FROM_ID (it
->f
, face_id
);
22044 return make_number (-1);
22045 boff
= font
->baseline_offset
;
22046 if (font
->vertical_centering
)
22047 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
22050 ascent
= FONT_BASE (font
) + boff
;
22051 descent
= FONT_DESCENT (font
) - boff
;
22055 it
->override_ascent
= ascent
;
22056 it
->override_descent
= descent
;
22057 it
->override_boff
= boff
;
22060 height
= ascent
+ descent
;
22064 height
= (int)(XFLOAT_DATA (val
) * height
);
22065 else if (INTEGERP (val
))
22066 height
*= XINT (val
);
22068 return make_number (height
);
22073 Produce glyphs/get display metrics for the display element IT is
22074 loaded with. See the description of struct it in dispextern.h
22075 for an overview of struct it. */
22078 x_produce_glyphs (struct it
*it
)
22080 int extra_line_spacing
= it
->extra_line_spacing
;
22082 it
->glyph_not_available_p
= 0;
22084 if (it
->what
== IT_CHARACTER
)
22088 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22089 struct font_metrics
*pcm
;
22090 int font_not_found_p
;
22091 int boff
; /* baseline offset */
22092 /* We may change it->multibyte_p upon unibyte<->multibyte
22093 conversion. So, save the current value now and restore it
22096 Note: It seems that we don't have to record multibyte_p in
22097 struct glyph because the character code itself tells whether
22098 or not the character is multibyte. Thus, in the future, we
22099 must consider eliminating the field `multibyte_p' in the
22101 int saved_multibyte_p
= it
->multibyte_p
;
22103 /* Maybe translate single-byte characters to multibyte, or the
22105 it
->char_to_display
= it
->c
;
22106 if (!ASCII_BYTE_P (it
->c
)
22107 && ! it
->multibyte_p
)
22109 if (SINGLE_BYTE_CHAR_P (it
->c
)
22110 && unibyte_display_via_language_environment
)
22112 struct charset
*unibyte
= CHARSET_FROM_ID (charset_unibyte
);
22114 /* get_next_display_element assures that this decoding
22116 it
->char_to_display
= DECODE_CHAR (unibyte
, it
->c
);
22117 it
->multibyte_p
= 1;
22118 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
,
22120 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22124 /* Get font to use. Encode IT->char_to_display. */
22125 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
22126 &char2b
, it
->multibyte_p
, 0);
22129 font_not_found_p
= font
== NULL
;
22130 if (font_not_found_p
)
22132 /* When no suitable font found, display an empty box based
22133 on the metrics of the font of the default face (or what
22135 struct face
*no_font_face
22136 = FACE_FROM_ID (it
->f
,
22137 NILP (Vface_remapping_alist
) ? DEFAULT_FACE_ID
22138 : lookup_basic_face (it
->f
, DEFAULT_FACE_ID
));
22139 font
= no_font_face
->font
;
22140 boff
= font
->baseline_offset
;
22144 boff
= font
->baseline_offset
;
22145 if (font
->vertical_centering
)
22146 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
22149 if (it
->char_to_display
>= ' '
22150 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
22152 /* Either unibyte or ASCII. */
22157 pcm
= get_per_char_metric (it
->f
, font
, &char2b
);
22159 if (it
->override_ascent
>= 0)
22161 it
->ascent
= it
->override_ascent
;
22162 it
->descent
= it
->override_descent
;
22163 boff
= it
->override_boff
;
22167 it
->ascent
= FONT_BASE (font
) + boff
;
22168 it
->descent
= FONT_DESCENT (font
) - boff
;
22173 it
->phys_ascent
= pcm
->ascent
+ boff
;
22174 it
->phys_descent
= pcm
->descent
- boff
;
22175 it
->pixel_width
= pcm
->width
;
22179 it
->glyph_not_available_p
= 1;
22180 it
->phys_ascent
= it
->ascent
;
22181 it
->phys_descent
= it
->descent
;
22182 it
->pixel_width
= FONT_WIDTH (font
);
22185 if (it
->constrain_row_ascent_descent_p
)
22187 if (it
->descent
> it
->max_descent
)
22189 it
->ascent
+= it
->descent
- it
->max_descent
;
22190 it
->descent
= it
->max_descent
;
22192 if (it
->ascent
> it
->max_ascent
)
22194 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
22195 it
->ascent
= it
->max_ascent
;
22197 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
22198 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
22199 extra_line_spacing
= 0;
22202 /* If this is a space inside a region of text with
22203 `space-width' property, change its width. */
22204 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
22206 it
->pixel_width
*= XFLOATINT (it
->space_width
);
22208 /* If face has a box, add the box thickness to the character
22209 height. If character has a box line to the left and/or
22210 right, add the box line width to the character's width. */
22211 if (face
->box
!= FACE_NO_BOX
)
22213 int thick
= face
->box_line_width
;
22217 it
->ascent
+= thick
;
22218 it
->descent
+= thick
;
22223 if (it
->start_of_box_run_p
)
22224 it
->pixel_width
+= thick
;
22225 if (it
->end_of_box_run_p
)
22226 it
->pixel_width
+= thick
;
22229 /* If face has an overline, add the height of the overline
22230 (1 pixel) and a 1 pixel margin to the character height. */
22231 if (face
->overline_p
)
22232 it
->ascent
+= overline_margin
;
22234 if (it
->constrain_row_ascent_descent_p
)
22236 if (it
->ascent
> it
->max_ascent
)
22237 it
->ascent
= it
->max_ascent
;
22238 if (it
->descent
> it
->max_descent
)
22239 it
->descent
= it
->max_descent
;
22242 take_vertical_position_into_account (it
);
22244 /* If we have to actually produce glyphs, do it. */
22249 /* Translate a space with a `space-width' property
22250 into a stretch glyph. */
22251 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
22252 / FONT_HEIGHT (font
));
22253 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
22254 it
->ascent
+ it
->descent
, ascent
);
22259 /* If characters with lbearing or rbearing are displayed
22260 in this line, record that fact in a flag of the
22261 glyph row. This is used to optimize X output code. */
22262 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
22263 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
22265 if (! stretched_p
&& it
->pixel_width
== 0)
22266 /* We assure that all visible glyphs have at least 1-pixel
22268 it
->pixel_width
= 1;
22270 else if (it
->char_to_display
== '\n')
22272 /* A newline has no width, but we need the height of the
22273 line. But if previous part of the line sets a height,
22274 don't increase that height */
22276 Lisp_Object height
;
22277 Lisp_Object total_height
= Qnil
;
22279 it
->override_ascent
= -1;
22280 it
->pixel_width
= 0;
22283 height
= get_it_property (it
, Qline_height
);
22284 /* Split (line-height total-height) list */
22286 && CONSP (XCDR (height
))
22287 && NILP (XCDR (XCDR (height
))))
22289 total_height
= XCAR (XCDR (height
));
22290 height
= XCAR (height
);
22292 height
= calc_line_height_property (it
, height
, font
, boff
, 1);
22294 if (it
->override_ascent
>= 0)
22296 it
->ascent
= it
->override_ascent
;
22297 it
->descent
= it
->override_descent
;
22298 boff
= it
->override_boff
;
22302 it
->ascent
= FONT_BASE (font
) + boff
;
22303 it
->descent
= FONT_DESCENT (font
) - boff
;
22306 if (EQ (height
, Qt
))
22308 if (it
->descent
> it
->max_descent
)
22310 it
->ascent
+= it
->descent
- it
->max_descent
;
22311 it
->descent
= it
->max_descent
;
22313 if (it
->ascent
> it
->max_ascent
)
22315 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
22316 it
->ascent
= it
->max_ascent
;
22318 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
22319 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
22320 it
->constrain_row_ascent_descent_p
= 1;
22321 extra_line_spacing
= 0;
22325 Lisp_Object spacing
;
22327 it
->phys_ascent
= it
->ascent
;
22328 it
->phys_descent
= it
->descent
;
22330 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
22331 && face
->box
!= FACE_NO_BOX
22332 && face
->box_line_width
> 0)
22334 it
->ascent
+= face
->box_line_width
;
22335 it
->descent
+= face
->box_line_width
;
22338 && XINT (height
) > it
->ascent
+ it
->descent
)
22339 it
->ascent
= XINT (height
) - it
->descent
;
22341 if (!NILP (total_height
))
22342 spacing
= calc_line_height_property (it
, total_height
, font
, boff
, 0);
22345 spacing
= get_it_property (it
, Qline_spacing
);
22346 spacing
= calc_line_height_property (it
, spacing
, font
, boff
, 0);
22348 if (INTEGERP (spacing
))
22350 extra_line_spacing
= XINT (spacing
);
22351 if (!NILP (total_height
))
22352 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
22356 else if (it
->char_to_display
== '\t')
22358 if (font
->space_width
> 0)
22360 int tab_width
= it
->tab_width
* font
->space_width
;
22361 int x
= it
->current_x
+ it
->continuation_lines_width
;
22362 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
22364 /* If the distance from the current position to the next tab
22365 stop is less than a space character width, use the
22366 tab stop after that. */
22367 if (next_tab_x
- x
< font
->space_width
)
22368 next_tab_x
+= tab_width
;
22370 it
->pixel_width
= next_tab_x
- x
;
22372 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
22373 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
22377 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
22378 it
->ascent
+ it
->descent
, it
->ascent
);
22383 it
->pixel_width
= 0;
22389 /* A multi-byte character. Assume that the display width of the
22390 character is the width of the character multiplied by the
22391 width of the font. */
22393 /* If we found a font, this font should give us the right
22394 metrics. If we didn't find a font, use the frame's
22395 default font and calculate the width of the character by
22396 multiplying the width of font by the width of the
22399 pcm
= get_per_char_metric (it
->f
, font
, &char2b
);
22401 if (font_not_found_p
|| !pcm
)
22403 int char_width
= CHAR_WIDTH (it
->char_to_display
);
22405 if (char_width
== 0)
22406 /* This is a non spacing character. But, as we are
22407 going to display an empty box, the box must occupy
22408 at least one column. */
22410 it
->glyph_not_available_p
= 1;
22411 it
->pixel_width
= font
->space_width
* char_width
;
22412 it
->phys_ascent
= FONT_BASE (font
) + boff
;
22413 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
22417 it
->pixel_width
= pcm
->width
;
22418 it
->phys_ascent
= pcm
->ascent
+ boff
;
22419 it
->phys_descent
= pcm
->descent
- boff
;
22421 && (pcm
->lbearing
< 0
22422 || pcm
->rbearing
> pcm
->width
))
22423 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
22426 it
->ascent
= FONT_BASE (font
) + boff
;
22427 it
->descent
= FONT_DESCENT (font
) - boff
;
22428 if (face
->box
!= FACE_NO_BOX
)
22430 int thick
= face
->box_line_width
;
22434 it
->ascent
+= thick
;
22435 it
->descent
+= thick
;
22440 if (it
->start_of_box_run_p
)
22441 it
->pixel_width
+= thick
;
22442 if (it
->end_of_box_run_p
)
22443 it
->pixel_width
+= thick
;
22446 /* If face has an overline, add the height of the overline
22447 (1 pixel) and a 1 pixel margin to the character height. */
22448 if (face
->overline_p
)
22449 it
->ascent
+= overline_margin
;
22451 take_vertical_position_into_account (it
);
22453 if (it
->ascent
< 0)
22455 if (it
->descent
< 0)
22460 if (it
->pixel_width
== 0)
22461 /* We assure that all visible glyphs have at least 1-pixel
22463 it
->pixel_width
= 1;
22465 it
->multibyte_p
= saved_multibyte_p
;
22467 else if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
< 0)
22469 /* A static composition.
22471 Note: A composition is represented as one glyph in the
22472 glyph matrix. There are no padding glyphs.
22474 Important note: pixel_width, ascent, and descent are the
22475 values of what is drawn by draw_glyphs (i.e. the values of
22476 the overall glyphs composed). */
22477 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22478 int boff
; /* baseline offset */
22479 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
22480 int glyph_len
= cmp
->glyph_len
;
22481 struct font
*font
= face
->font
;
22485 /* If we have not yet calculated pixel size data of glyphs of
22486 the composition for the current face font, calculate them
22487 now. Theoretically, we have to check all fonts for the
22488 glyphs, but that requires much time and memory space. So,
22489 here we check only the font of the first glyph. This may
22490 lead to incorrect display, but it's very rare, and C-l
22491 (recenter-top-bottom) can correct the display anyway. */
22492 if (! cmp
->font
|| cmp
->font
!= font
)
22494 /* Ascent and descent of the font of the first character
22495 of this composition (adjusted by baseline offset).
22496 Ascent and descent of overall glyphs should not be less
22497 than these, respectively. */
22498 int font_ascent
, font_descent
, font_height
;
22499 /* Bounding box of the overall glyphs. */
22500 int leftmost
, rightmost
, lowest
, highest
;
22501 int lbearing
, rbearing
;
22502 int i
, width
, ascent
, descent
;
22503 int left_padded
= 0, right_padded
= 0;
22506 struct font_metrics
*pcm
;
22507 int font_not_found_p
;
22510 for (glyph_len
= cmp
->glyph_len
; glyph_len
> 0; glyph_len
--)
22511 if ((c
= COMPOSITION_GLYPH (cmp
, glyph_len
- 1)) != '\t')
22513 if (glyph_len
< cmp
->glyph_len
)
22515 for (i
= 0; i
< glyph_len
; i
++)
22517 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
22519 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
22524 pos
= (STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
22525 : IT_CHARPOS (*it
));
22526 /* If no suitable font is found, use the default font. */
22527 font_not_found_p
= font
== NULL
;
22528 if (font_not_found_p
)
22530 face
= face
->ascii_face
;
22533 boff
= font
->baseline_offset
;
22534 if (font
->vertical_centering
)
22535 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
22536 font_ascent
= FONT_BASE (font
) + boff
;
22537 font_descent
= FONT_DESCENT (font
) - boff
;
22538 font_height
= FONT_HEIGHT (font
);
22540 cmp
->font
= (void *) font
;
22543 if (! font_not_found_p
)
22545 get_char_face_and_encoding (it
->f
, c
, it
->face_id
,
22546 &char2b
, it
->multibyte_p
, 0);
22547 pcm
= get_per_char_metric (it
->f
, font
, &char2b
);
22550 /* Initialize the bounding box. */
22553 width
= pcm
->width
;
22554 ascent
= pcm
->ascent
;
22555 descent
= pcm
->descent
;
22556 lbearing
= pcm
->lbearing
;
22557 rbearing
= pcm
->rbearing
;
22561 width
= FONT_WIDTH (font
);
22562 ascent
= FONT_BASE (font
);
22563 descent
= FONT_DESCENT (font
);
22570 lowest
= - descent
+ boff
;
22571 highest
= ascent
+ boff
;
22573 if (! font_not_found_p
22574 && font
->default_ascent
22575 && CHAR_TABLE_P (Vuse_default_ascent
)
22576 && !NILP (Faref (Vuse_default_ascent
,
22577 make_number (it
->char_to_display
))))
22578 highest
= font
->default_ascent
+ boff
;
22580 /* Draw the first glyph at the normal position. It may be
22581 shifted to right later if some other glyphs are drawn
22583 cmp
->offsets
[i
* 2] = 0;
22584 cmp
->offsets
[i
* 2 + 1] = boff
;
22585 cmp
->lbearing
= lbearing
;
22586 cmp
->rbearing
= rbearing
;
22588 /* Set cmp->offsets for the remaining glyphs. */
22589 for (i
++; i
< glyph_len
; i
++)
22591 int left
, right
, btm
, top
;
22592 int ch
= COMPOSITION_GLYPH (cmp
, i
);
22594 struct face
*this_face
;
22599 face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
, pos
, it
->string
);
22600 this_face
= FACE_FROM_ID (it
->f
, face_id
);
22601 font
= this_face
->font
;
22607 this_boff
= font
->baseline_offset
;
22608 if (font
->vertical_centering
)
22609 this_boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
22610 get_char_face_and_encoding (it
->f
, ch
, face_id
,
22611 &char2b
, it
->multibyte_p
, 0);
22612 pcm
= get_per_char_metric (it
->f
, font
, &char2b
);
22615 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
22618 width
= pcm
->width
;
22619 ascent
= pcm
->ascent
;
22620 descent
= pcm
->descent
;
22621 lbearing
= pcm
->lbearing
;
22622 rbearing
= pcm
->rbearing
;
22623 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
22625 /* Relative composition with or without
22626 alternate chars. */
22627 left
= (leftmost
+ rightmost
- width
) / 2;
22628 btm
= - descent
+ boff
;
22629 if (font
->relative_compose
22630 && (! CHAR_TABLE_P (Vignore_relative_composition
)
22631 || NILP (Faref (Vignore_relative_composition
,
22632 make_number (ch
)))))
22635 if (- descent
>= font
->relative_compose
)
22636 /* One extra pixel between two glyphs. */
22638 else if (ascent
<= 0)
22639 /* One extra pixel between two glyphs. */
22640 btm
= lowest
- 1 - ascent
- descent
;
22645 /* A composition rule is specified by an integer
22646 value that encodes global and new reference
22647 points (GREF and NREF). GREF and NREF are
22648 specified by numbers as below:
22650 0---1---2 -- ascent
22654 9--10--11 -- center
22656 ---3---4---5--- baseline
22658 6---7---8 -- descent
22660 int rule
= COMPOSITION_RULE (cmp
, i
);
22661 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
, xoff
, yoff
;
22663 COMPOSITION_DECODE_RULE (rule
, gref
, nref
, xoff
, yoff
);
22664 grefx
= gref
% 3, nrefx
= nref
% 3;
22665 grefy
= gref
/ 3, nrefy
= nref
/ 3;
22667 xoff
= font_height
* (xoff
- 128) / 256;
22669 yoff
= font_height
* (yoff
- 128) / 256;
22672 + grefx
* (rightmost
- leftmost
) / 2
22673 - nrefx
* width
/ 2
22676 btm
= ((grefy
== 0 ? highest
22678 : grefy
== 2 ? lowest
22679 : (highest
+ lowest
) / 2)
22680 - (nrefy
== 0 ? ascent
+ descent
22681 : nrefy
== 1 ? descent
- boff
22683 : (ascent
+ descent
) / 2)
22687 cmp
->offsets
[i
* 2] = left
;
22688 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
22690 /* Update the bounding box of the overall glyphs. */
22693 right
= left
+ width
;
22694 if (left
< leftmost
)
22696 if (right
> rightmost
)
22699 top
= btm
+ descent
+ ascent
;
22705 if (cmp
->lbearing
> left
+ lbearing
)
22706 cmp
->lbearing
= left
+ lbearing
;
22707 if (cmp
->rbearing
< left
+ rbearing
)
22708 cmp
->rbearing
= left
+ rbearing
;
22712 /* If there are glyphs whose x-offsets are negative,
22713 shift all glyphs to the right and make all x-offsets
22717 for (i
= 0; i
< cmp
->glyph_len
; i
++)
22718 cmp
->offsets
[i
* 2] -= leftmost
;
22719 rightmost
-= leftmost
;
22720 cmp
->lbearing
-= leftmost
;
22721 cmp
->rbearing
-= leftmost
;
22724 if (left_padded
&& cmp
->lbearing
< 0)
22726 for (i
= 0; i
< cmp
->glyph_len
; i
++)
22727 cmp
->offsets
[i
* 2] -= cmp
->lbearing
;
22728 rightmost
-= cmp
->lbearing
;
22729 cmp
->rbearing
-= cmp
->lbearing
;
22732 if (right_padded
&& rightmost
< cmp
->rbearing
)
22734 rightmost
= cmp
->rbearing
;
22737 cmp
->pixel_width
= rightmost
;
22738 cmp
->ascent
= highest
;
22739 cmp
->descent
= - lowest
;
22740 if (cmp
->ascent
< font_ascent
)
22741 cmp
->ascent
= font_ascent
;
22742 if (cmp
->descent
< font_descent
)
22743 cmp
->descent
= font_descent
;
22747 && (cmp
->lbearing
< 0
22748 || cmp
->rbearing
> cmp
->pixel_width
))
22749 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
22751 it
->pixel_width
= cmp
->pixel_width
;
22752 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
22753 it
->descent
= it
->phys_descent
= cmp
->descent
;
22754 if (face
->box
!= FACE_NO_BOX
)
22756 int thick
= face
->box_line_width
;
22760 it
->ascent
+= thick
;
22761 it
->descent
+= thick
;
22766 if (it
->start_of_box_run_p
)
22767 it
->pixel_width
+= thick
;
22768 if (it
->end_of_box_run_p
)
22769 it
->pixel_width
+= thick
;
22772 /* If face has an overline, add the height of the overline
22773 (1 pixel) and a 1 pixel margin to the character height. */
22774 if (face
->overline_p
)
22775 it
->ascent
+= overline_margin
;
22777 take_vertical_position_into_account (it
);
22778 if (it
->ascent
< 0)
22780 if (it
->descent
< 0)
22784 append_composite_glyph (it
);
22786 else if (it
->what
== IT_COMPOSITION
)
22788 /* A dynamic (automatic) composition. */
22789 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22790 Lisp_Object gstring
;
22791 struct font_metrics metrics
;
22793 gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
22795 = composition_gstring_width (gstring
, it
->cmp_it
.from
, it
->cmp_it
.to
,
22798 && (metrics
.lbearing
< 0 || metrics
.rbearing
> metrics
.width
))
22799 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
22800 it
->ascent
= it
->phys_ascent
= metrics
.ascent
;
22801 it
->descent
= it
->phys_descent
= metrics
.descent
;
22802 if (face
->box
!= FACE_NO_BOX
)
22804 int thick
= face
->box_line_width
;
22808 it
->ascent
+= thick
;
22809 it
->descent
+= thick
;
22814 if (it
->start_of_box_run_p
)
22815 it
->pixel_width
+= thick
;
22816 if (it
->end_of_box_run_p
)
22817 it
->pixel_width
+= thick
;
22819 /* If face has an overline, add the height of the overline
22820 (1 pixel) and a 1 pixel margin to the character height. */
22821 if (face
->overline_p
)
22822 it
->ascent
+= overline_margin
;
22823 take_vertical_position_into_account (it
);
22824 if (it
->ascent
< 0)
22826 if (it
->descent
< 0)
22830 append_composite_glyph (it
);
22832 else if (it
->what
== IT_IMAGE
)
22833 produce_image_glyph (it
);
22834 else if (it
->what
== IT_STRETCH
)
22835 produce_stretch_glyph (it
);
22837 /* Accumulate dimensions. Note: can't assume that it->descent > 0
22838 because this isn't true for images with `:ascent 100'. */
22839 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
22840 if (it
->area
== TEXT_AREA
)
22841 it
->current_x
+= it
->pixel_width
;
22843 if (extra_line_spacing
> 0)
22845 it
->descent
+= extra_line_spacing
;
22846 if (extra_line_spacing
> it
->max_extra_line_spacing
)
22847 it
->max_extra_line_spacing
= extra_line_spacing
;
22850 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
22851 it
->max_descent
= max (it
->max_descent
, it
->descent
);
22852 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
22853 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
22857 Output LEN glyphs starting at START at the nominal cursor position.
22858 Advance the nominal cursor over the text. The global variable
22859 updated_window contains the window being updated, updated_row is
22860 the glyph row being updated, and updated_area is the area of that
22861 row being updated. */
22864 x_write_glyphs (struct glyph
*start
, int len
)
22868 xassert (updated_window
&& updated_row
);
22871 /* Write glyphs. */
22873 hpos
= start
- updated_row
->glyphs
[updated_area
];
22874 x
= draw_glyphs (updated_window
, output_cursor
.x
,
22875 updated_row
, updated_area
,
22877 DRAW_NORMAL_TEXT
, 0);
22879 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
22880 if (updated_area
== TEXT_AREA
22881 && updated_window
->phys_cursor_on_p
22882 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
22883 && updated_window
->phys_cursor
.hpos
>= hpos
22884 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
22885 updated_window
->phys_cursor_on_p
= 0;
22889 /* Advance the output cursor. */
22890 output_cursor
.hpos
+= len
;
22891 output_cursor
.x
= x
;
22896 Insert LEN glyphs from START at the nominal cursor position. */
22899 x_insert_glyphs (struct glyph
*start
, int len
)
22903 int line_height
, shift_by_width
, shifted_region_width
;
22904 struct glyph_row
*row
;
22905 struct glyph
*glyph
;
22906 int frame_x
, frame_y
;
22909 xassert (updated_window
&& updated_row
);
22911 w
= updated_window
;
22912 f
= XFRAME (WINDOW_FRAME (w
));
22914 /* Get the height of the line we are in. */
22916 line_height
= row
->height
;
22918 /* Get the width of the glyphs to insert. */
22919 shift_by_width
= 0;
22920 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
22921 shift_by_width
+= glyph
->pixel_width
;
22923 /* Get the width of the region to shift right. */
22924 shifted_region_width
= (window_box_width (w
, updated_area
)
22929 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
22930 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
22932 FRAME_RIF (f
)->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
22933 line_height
, shift_by_width
);
22935 /* Write the glyphs. */
22936 hpos
= start
- row
->glyphs
[updated_area
];
22937 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
22939 DRAW_NORMAL_TEXT
, 0);
22941 /* Advance the output cursor. */
22942 output_cursor
.hpos
+= len
;
22943 output_cursor
.x
+= shift_by_width
;
22949 Erase the current text line from the nominal cursor position
22950 (inclusive) to pixel column TO_X (exclusive). The idea is that
22951 everything from TO_X onward is already erased.
22953 TO_X is a pixel position relative to updated_area of
22954 updated_window. TO_X == -1 means clear to the end of this area. */
22957 x_clear_end_of_line (int to_x
)
22960 struct window
*w
= updated_window
;
22961 int max_x
, min_y
, max_y
;
22962 int from_x
, from_y
, to_y
;
22964 xassert (updated_window
&& updated_row
);
22965 f
= XFRAME (w
->frame
);
22967 if (updated_row
->full_width_p
)
22968 max_x
= WINDOW_TOTAL_WIDTH (w
);
22970 max_x
= window_box_width (w
, updated_area
);
22971 max_y
= window_text_bottom_y (w
);
22973 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
22974 of window. For TO_X > 0, truncate to end of drawing area. */
22980 to_x
= min (to_x
, max_x
);
22982 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
22984 /* Notice if the cursor will be cleared by this operation. */
22985 if (!updated_row
->full_width_p
)
22986 notice_overwritten_cursor (w
, updated_area
,
22987 output_cursor
.x
, -1,
22989 MATRIX_ROW_BOTTOM_Y (updated_row
));
22991 from_x
= output_cursor
.x
;
22993 /* Translate to frame coordinates. */
22994 if (updated_row
->full_width_p
)
22996 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
22997 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
23001 int area_left
= window_box_left (w
, updated_area
);
23002 from_x
+= area_left
;
23006 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
23007 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
23008 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
23010 /* Prevent inadvertently clearing to end of the X window. */
23011 if (to_x
> from_x
&& to_y
> from_y
)
23014 FRAME_RIF (f
)->clear_frame_area (f
, from_x
, from_y
,
23015 to_x
- from_x
, to_y
- from_y
);
23020 #endif /* HAVE_WINDOW_SYSTEM */
23024 /***********************************************************************
23026 ***********************************************************************/
23028 /* Value is the internal representation of the specified cursor type
23029 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23030 of the bar cursor. */
23032 static enum text_cursor_kinds
23033 get_specified_cursor_type (Lisp_Object arg
, int *width
)
23035 enum text_cursor_kinds type
;
23040 if (EQ (arg
, Qbox
))
23041 return FILLED_BOX_CURSOR
;
23043 if (EQ (arg
, Qhollow
))
23044 return HOLLOW_BOX_CURSOR
;
23046 if (EQ (arg
, Qbar
))
23053 && EQ (XCAR (arg
), Qbar
)
23054 && INTEGERP (XCDR (arg
))
23055 && XINT (XCDR (arg
)) >= 0)
23057 *width
= XINT (XCDR (arg
));
23061 if (EQ (arg
, Qhbar
))
23064 return HBAR_CURSOR
;
23068 && EQ (XCAR (arg
), Qhbar
)
23069 && INTEGERP (XCDR (arg
))
23070 && XINT (XCDR (arg
)) >= 0)
23072 *width
= XINT (XCDR (arg
));
23073 return HBAR_CURSOR
;
23076 /* Treat anything unknown as "hollow box cursor".
23077 It was bad to signal an error; people have trouble fixing
23078 .Xdefaults with Emacs, when it has something bad in it. */
23079 type
= HOLLOW_BOX_CURSOR
;
23084 /* Set the default cursor types for specified frame. */
23086 set_frame_cursor_types (struct frame
*f
, Lisp_Object arg
)
23091 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
23092 FRAME_CURSOR_WIDTH (f
) = width
;
23094 /* By default, set up the blink-off state depending on the on-state. */
23096 tem
= Fassoc (arg
, Vblink_cursor_alist
);
23099 FRAME_BLINK_OFF_CURSOR (f
)
23100 = get_specified_cursor_type (XCDR (tem
), &width
);
23101 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
23104 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
23108 /* Return the cursor we want to be displayed in window W. Return
23109 width of bar/hbar cursor through WIDTH arg. Return with
23110 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23111 (i.e. if the `system caret' should track this cursor).
23113 In a mini-buffer window, we want the cursor only to appear if we
23114 are reading input from this window. For the selected window, we
23115 want the cursor type given by the frame parameter or buffer local
23116 setting of cursor-type. If explicitly marked off, draw no cursor.
23117 In all other cases, we want a hollow box cursor. */
23119 static enum text_cursor_kinds
23120 get_window_cursor_type (struct window
*w
, struct glyph
*glyph
, int *width
,
23121 int *active_cursor
)
23123 struct frame
*f
= XFRAME (w
->frame
);
23124 struct buffer
*b
= XBUFFER (w
->buffer
);
23125 int cursor_type
= DEFAULT_CURSOR
;
23126 Lisp_Object alt_cursor
;
23127 int non_selected
= 0;
23129 *active_cursor
= 1;
23132 if (cursor_in_echo_area
23133 && FRAME_HAS_MINIBUF_P (f
)
23134 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
23136 if (w
== XWINDOW (echo_area_window
))
23138 if (EQ (b
->cursor_type
, Qt
) || NILP (b
->cursor_type
))
23140 *width
= FRAME_CURSOR_WIDTH (f
);
23141 return FRAME_DESIRED_CURSOR (f
);
23144 return get_specified_cursor_type (b
->cursor_type
, width
);
23147 *active_cursor
= 0;
23151 /* Detect a nonselected window or nonselected frame. */
23152 else if (w
!= XWINDOW (f
->selected_window
)
23153 #ifdef HAVE_WINDOW_SYSTEM
23154 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
23158 *active_cursor
= 0;
23160 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
23166 /* Never display a cursor in a window in which cursor-type is nil. */
23167 if (NILP (b
->cursor_type
))
23170 /* Get the normal cursor type for this window. */
23171 if (EQ (b
->cursor_type
, Qt
))
23173 cursor_type
= FRAME_DESIRED_CURSOR (f
);
23174 *width
= FRAME_CURSOR_WIDTH (f
);
23177 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
23179 /* Use cursor-in-non-selected-windows instead
23180 for non-selected window or frame. */
23183 alt_cursor
= b
->cursor_in_non_selected_windows
;
23184 if (!EQ (Qt
, alt_cursor
))
23185 return get_specified_cursor_type (alt_cursor
, width
);
23186 /* t means modify the normal cursor type. */
23187 if (cursor_type
== FILLED_BOX_CURSOR
)
23188 cursor_type
= HOLLOW_BOX_CURSOR
;
23189 else if (cursor_type
== BAR_CURSOR
&& *width
> 1)
23191 return cursor_type
;
23194 /* Use normal cursor if not blinked off. */
23195 if (!w
->cursor_off_p
)
23197 #ifdef HAVE_WINDOW_SYSTEM
23198 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
23200 if (cursor_type
== FILLED_BOX_CURSOR
)
23202 /* Using a block cursor on large images can be very annoying.
23203 So use a hollow cursor for "large" images.
23204 If image is not transparent (no mask), also use hollow cursor. */
23205 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
23206 if (img
!= NULL
&& IMAGEP (img
->spec
))
23208 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23209 where N = size of default frame font size.
23210 This should cover most of the "tiny" icons people may use. */
23212 || img
->width
> max (32, WINDOW_FRAME_COLUMN_WIDTH (w
))
23213 || img
->height
> max (32, WINDOW_FRAME_LINE_HEIGHT (w
)))
23214 cursor_type
= HOLLOW_BOX_CURSOR
;
23217 else if (cursor_type
!= NO_CURSOR
)
23219 /* Display current only supports BOX and HOLLOW cursors for images.
23220 So for now, unconditionally use a HOLLOW cursor when cursor is
23221 not a solid box cursor. */
23222 cursor_type
= HOLLOW_BOX_CURSOR
;
23226 return cursor_type
;
23229 /* Cursor is blinked off, so determine how to "toggle" it. */
23231 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23232 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
23233 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
23235 /* Then see if frame has specified a specific blink off cursor type. */
23236 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
23238 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
23239 return FRAME_BLINK_OFF_CURSOR (f
);
23243 /* Some people liked having a permanently visible blinking cursor,
23244 while others had very strong opinions against it. So it was
23245 decided to remove it. KFS 2003-09-03 */
23247 /* Finally perform built-in cursor blinking:
23248 filled box <-> hollow box
23249 wide [h]bar <-> narrow [h]bar
23250 narrow [h]bar <-> no cursor
23251 other type <-> no cursor */
23253 if (cursor_type
== FILLED_BOX_CURSOR
)
23254 return HOLLOW_BOX_CURSOR
;
23256 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
23259 return cursor_type
;
23267 #ifdef HAVE_WINDOW_SYSTEM
23269 /* Notice when the text cursor of window W has been completely
23270 overwritten by a drawing operation that outputs glyphs in AREA
23271 starting at X0 and ending at X1 in the line starting at Y0 and
23272 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23273 the rest of the line after X0 has been written. Y coordinates
23274 are window-relative. */
23277 notice_overwritten_cursor (struct window
*w
, enum glyph_row_area area
,
23278 int x0
, int x1
, int y0
, int y1
)
23280 int cx0
, cx1
, cy0
, cy1
;
23281 struct glyph_row
*row
;
23283 if (!w
->phys_cursor_on_p
)
23285 if (area
!= TEXT_AREA
)
23288 if (w
->phys_cursor
.vpos
< 0
23289 || w
->phys_cursor
.vpos
>= w
->current_matrix
->nrows
23290 || (row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
,
23291 !(row
->enabled_p
&& row
->displays_text_p
)))
23294 if (row
->cursor_in_fringe_p
)
23296 row
->cursor_in_fringe_p
= 0;
23297 draw_fringe_bitmap (w
, row
, row
->reversed_p
);
23298 w
->phys_cursor_on_p
= 0;
23302 cx0
= w
->phys_cursor
.x
;
23303 cx1
= cx0
+ w
->phys_cursor_width
;
23304 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
23307 /* The cursor image will be completely removed from the
23308 screen if the output area intersects the cursor area in
23309 y-direction. When we draw in [y0 y1[, and some part of
23310 the cursor is at y < y0, that part must have been drawn
23311 before. When scrolling, the cursor is erased before
23312 actually scrolling, so we don't come here. When not
23313 scrolling, the rows above the old cursor row must have
23314 changed, and in this case these rows must have written
23315 over the cursor image.
23317 Likewise if part of the cursor is below y1, with the
23318 exception of the cursor being in the first blank row at
23319 the buffer and window end because update_text_area
23320 doesn't draw that row. (Except when it does, but
23321 that's handled in update_text_area.) */
23323 cy0
= w
->phys_cursor
.y
;
23324 cy1
= cy0
+ w
->phys_cursor_height
;
23325 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
23328 w
->phys_cursor_on_p
= 0;
23331 #endif /* HAVE_WINDOW_SYSTEM */
23334 /************************************************************************
23336 ************************************************************************/
23338 #ifdef HAVE_WINDOW_SYSTEM
23341 Fix the display of area AREA of overlapping row ROW in window W
23342 with respect to the overlapping part OVERLAPS. */
23345 x_fix_overlapping_area (struct window
*w
, struct glyph_row
*row
,
23346 enum glyph_row_area area
, int overlaps
)
23353 for (i
= 0; i
< row
->used
[area
];)
23355 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
23357 int start
= i
, start_x
= x
;
23361 x
+= row
->glyphs
[area
][i
].pixel_width
;
23364 while (i
< row
->used
[area
]
23365 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
23367 draw_glyphs (w
, start_x
, row
, area
,
23369 DRAW_NORMAL_TEXT
, overlaps
);
23373 x
+= row
->glyphs
[area
][i
].pixel_width
;
23383 Draw the cursor glyph of window W in glyph row ROW. See the
23384 comment of draw_glyphs for the meaning of HL. */
23387 draw_phys_cursor_glyph (struct window
*w
, struct glyph_row
*row
,
23388 enum draw_glyphs_face hl
)
23390 /* If cursor hpos is out of bounds, don't draw garbage. This can
23391 happen in mini-buffer windows when switching between echo area
23392 glyphs and mini-buffer. */
23393 if ((row
->reversed_p
23394 ? (w
->phys_cursor
.hpos
>= 0)
23395 : (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])))
23397 int on_p
= w
->phys_cursor_on_p
;
23399 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
23400 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
23402 w
->phys_cursor_on_p
= on_p
;
23404 if (hl
== DRAW_CURSOR
)
23405 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
23406 /* When we erase the cursor, and ROW is overlapped by other
23407 rows, make sure that these overlapping parts of other rows
23409 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
23411 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
23413 if (row
> w
->current_matrix
->rows
23414 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
23415 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
,
23416 OVERLAPS_ERASED_CURSOR
);
23418 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
23419 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
23420 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
,
23421 OVERLAPS_ERASED_CURSOR
);
23428 Erase the image of a cursor of window W from the screen. */
23431 erase_phys_cursor (struct window
*w
)
23433 struct frame
*f
= XFRAME (w
->frame
);
23434 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
23435 int hpos
= w
->phys_cursor
.hpos
;
23436 int vpos
= w
->phys_cursor
.vpos
;
23437 int mouse_face_here_p
= 0;
23438 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
23439 struct glyph_row
*cursor_row
;
23440 struct glyph
*cursor_glyph
;
23441 enum draw_glyphs_face hl
;
23443 /* No cursor displayed or row invalidated => nothing to do on the
23445 if (w
->phys_cursor_type
== NO_CURSOR
)
23446 goto mark_cursor_off
;
23448 /* VPOS >= active_glyphs->nrows means that window has been resized.
23449 Don't bother to erase the cursor. */
23450 if (vpos
>= active_glyphs
->nrows
)
23451 goto mark_cursor_off
;
23453 /* If row containing cursor is marked invalid, there is nothing we
23455 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
23456 if (!cursor_row
->enabled_p
)
23457 goto mark_cursor_off
;
23459 /* If line spacing is > 0, old cursor may only be partially visible in
23460 window after split-window. So adjust visible height. */
23461 cursor_row
->visible_height
= min (cursor_row
->visible_height
,
23462 window_text_bottom_y (w
) - cursor_row
->y
);
23464 /* If row is completely invisible, don't attempt to delete a cursor which
23465 isn't there. This can happen if cursor is at top of a window, and
23466 we switch to a buffer with a header line in that window. */
23467 if (cursor_row
->visible_height
<= 0)
23468 goto mark_cursor_off
;
23470 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23471 if (cursor_row
->cursor_in_fringe_p
)
23473 cursor_row
->cursor_in_fringe_p
= 0;
23474 draw_fringe_bitmap (w
, cursor_row
, cursor_row
->reversed_p
);
23475 goto mark_cursor_off
;
23478 /* This can happen when the new row is shorter than the old one.
23479 In this case, either draw_glyphs or clear_end_of_line
23480 should have cleared the cursor. Note that we wouldn't be
23481 able to erase the cursor in this case because we don't have a
23482 cursor glyph at hand. */
23483 if ((cursor_row
->reversed_p
23484 ? (w
->phys_cursor
.hpos
< 0)
23485 : (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])))
23486 goto mark_cursor_off
;
23488 /* If the cursor is in the mouse face area, redisplay that when
23489 we clear the cursor. */
23490 if (! NILP (dpyinfo
->mouse_face_window
)
23491 && coords_in_mouse_face_p (w
, hpos
, vpos
)
23492 /* Don't redraw the cursor's spot in mouse face if it is at the
23493 end of a line (on a newline). The cursor appears there, but
23494 mouse highlighting does not. */
23495 && cursor_row
->used
[TEXT_AREA
] > hpos
&& hpos
>= 0)
23496 mouse_face_here_p
= 1;
23498 /* Maybe clear the display under the cursor. */
23499 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
23502 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
23505 cursor_glyph
= get_phys_cursor_glyph (w
);
23506 if (cursor_glyph
== NULL
)
23507 goto mark_cursor_off
;
23509 width
= cursor_glyph
->pixel_width
;
23510 left_x
= window_box_left_offset (w
, TEXT_AREA
);
23511 x
= w
->phys_cursor
.x
;
23513 width
-= left_x
- x
;
23514 width
= min (width
, window_box_width (w
, TEXT_AREA
) - x
);
23515 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
23516 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, max (x
, left_x
));
23519 FRAME_RIF (f
)->clear_frame_area (f
, x
, y
, width
, cursor_row
->visible_height
);
23522 /* Erase the cursor by redrawing the character underneath it. */
23523 if (mouse_face_here_p
)
23524 hl
= DRAW_MOUSE_FACE
;
23526 hl
= DRAW_NORMAL_TEXT
;
23527 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
23530 w
->phys_cursor_on_p
= 0;
23531 w
->phys_cursor_type
= NO_CURSOR
;
23536 Display or clear cursor of window W. If ON is zero, clear the
23537 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23538 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23541 display_and_set_cursor (struct window
*w
, int on
,
23542 int hpos
, int vpos
, int x
, int y
)
23544 struct frame
*f
= XFRAME (w
->frame
);
23545 int new_cursor_type
;
23546 int new_cursor_width
;
23548 struct glyph_row
*glyph_row
;
23549 struct glyph
*glyph
;
23551 /* This is pointless on invisible frames, and dangerous on garbaged
23552 windows and frames; in the latter case, the frame or window may
23553 be in the midst of changing its size, and x and y may be off the
23555 if (! FRAME_VISIBLE_P (f
)
23556 || FRAME_GARBAGED_P (f
)
23557 || vpos
>= w
->current_matrix
->nrows
23558 || hpos
>= w
->current_matrix
->matrix_w
)
23561 /* If cursor is off and we want it off, return quickly. */
23562 if (!on
&& !w
->phys_cursor_on_p
)
23565 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
23566 /* If cursor row is not enabled, we don't really know where to
23567 display the cursor. */
23568 if (!glyph_row
->enabled_p
)
23570 w
->phys_cursor_on_p
= 0;
23575 if (!glyph_row
->exact_window_width_line_p
23576 || (0 <= hpos
&& hpos
< glyph_row
->used
[TEXT_AREA
]))
23577 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
23579 xassert (interrupt_input_blocked
);
23581 /* Set new_cursor_type to the cursor we want to be displayed. */
23582 new_cursor_type
= get_window_cursor_type (w
, glyph
,
23583 &new_cursor_width
, &active_cursor
);
23585 /* If cursor is currently being shown and we don't want it to be or
23586 it is in the wrong place, or the cursor type is not what we want,
23588 if (w
->phys_cursor_on_p
23590 || w
->phys_cursor
.x
!= x
23591 || w
->phys_cursor
.y
!= y
23592 || new_cursor_type
!= w
->phys_cursor_type
23593 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
23594 && new_cursor_width
!= w
->phys_cursor_width
)))
23595 erase_phys_cursor (w
);
23597 /* Don't check phys_cursor_on_p here because that flag is only set
23598 to zero in some cases where we know that the cursor has been
23599 completely erased, to avoid the extra work of erasing the cursor
23600 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23601 still not be visible, or it has only been partly erased. */
23604 w
->phys_cursor_ascent
= glyph_row
->ascent
;
23605 w
->phys_cursor_height
= glyph_row
->height
;
23607 /* Set phys_cursor_.* before x_draw_.* is called because some
23608 of them may need the information. */
23609 w
->phys_cursor
.x
= x
;
23610 w
->phys_cursor
.y
= glyph_row
->y
;
23611 w
->phys_cursor
.hpos
= hpos
;
23612 w
->phys_cursor
.vpos
= vpos
;
23615 FRAME_RIF (f
)->draw_window_cursor (w
, glyph_row
, x
, y
,
23616 new_cursor_type
, new_cursor_width
,
23617 on
, active_cursor
);
23621 /* Switch the display of W's cursor on or off, according to the value
23625 update_window_cursor (struct window
*w
, int on
)
23627 /* Don't update cursor in windows whose frame is in the process
23628 of being deleted. */
23629 if (w
->current_matrix
)
23632 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
23633 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
23639 /* Call update_window_cursor with parameter ON_P on all leaf windows
23640 in the window tree rooted at W. */
23643 update_cursor_in_window_tree (struct window
*w
, int on_p
)
23647 if (!NILP (w
->hchild
))
23648 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
23649 else if (!NILP (w
->vchild
))
23650 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
23652 update_window_cursor (w
, on_p
);
23654 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
23660 Display the cursor on window W, or clear it, according to ON_P.
23661 Don't change the cursor's position. */
23664 x_update_cursor (struct frame
*f
, int on_p
)
23666 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
23671 Clear the cursor of window W to background color, and mark the
23672 cursor as not shown. This is used when the text where the cursor
23673 is about to be rewritten. */
23676 x_clear_cursor (struct window
*w
)
23678 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
23679 update_window_cursor (w
, 0);
23684 Display the active region described by mouse_face_* according to DRAW. */
23687 show_mouse_face (Display_Info
*dpyinfo
, enum draw_glyphs_face draw
)
23689 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
23690 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
23692 if (/* If window is in the process of being destroyed, don't bother
23694 w
->current_matrix
!= NULL
23695 /* Don't update mouse highlight if hidden */
23696 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
23697 /* Recognize when we are called to operate on rows that don't exist
23698 anymore. This can happen when a window is split. */
23699 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
23701 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
23702 struct glyph_row
*row
, *first
, *last
;
23704 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
23705 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
23707 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
23709 int start_hpos
, end_hpos
, start_x
;
23711 /* For all but the first row, the highlight starts at column 0. */
23714 /* R2L rows have BEG and END in reversed order, but the
23715 screen drawing geometry is always left to right. So
23716 we need to mirror the beginning and end of the
23717 highlighted area in R2L rows. */
23718 if (!row
->reversed_p
)
23720 start_hpos
= dpyinfo
->mouse_face_beg_col
;
23721 start_x
= dpyinfo
->mouse_face_beg_x
;
23723 else if (row
== last
)
23725 start_hpos
= dpyinfo
->mouse_face_end_col
;
23726 start_x
= dpyinfo
->mouse_face_end_x
;
23734 else if (row
->reversed_p
&& row
== last
)
23736 start_hpos
= dpyinfo
->mouse_face_end_col
;
23737 start_x
= dpyinfo
->mouse_face_end_x
;
23747 if (!row
->reversed_p
)
23748 end_hpos
= dpyinfo
->mouse_face_end_col
;
23749 else if (row
== first
)
23750 end_hpos
= dpyinfo
->mouse_face_beg_col
;
23753 end_hpos
= row
->used
[TEXT_AREA
];
23754 if (draw
== DRAW_NORMAL_TEXT
)
23755 row
->fill_line_p
= 1; /* Clear to end of line */
23758 else if (row
->reversed_p
&& row
== first
)
23759 end_hpos
= dpyinfo
->mouse_face_beg_col
;
23762 end_hpos
= row
->used
[TEXT_AREA
];
23763 if (draw
== DRAW_NORMAL_TEXT
)
23764 row
->fill_line_p
= 1; /* Clear to end of line */
23767 if (end_hpos
> start_hpos
)
23769 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
23770 start_hpos
, end_hpos
,
23774 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
23778 /* When we've written over the cursor, arrange for it to
23779 be displayed again. */
23780 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
23783 display_and_set_cursor (w
, 1,
23784 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
23785 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
23790 /* Change the mouse cursor. */
23791 if (draw
== DRAW_NORMAL_TEXT
&& !EQ (dpyinfo
->mouse_face_window
, f
->tool_bar_window
))
23792 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
23793 else if (draw
== DRAW_MOUSE_FACE
)
23794 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
23796 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
23800 Clear out the mouse-highlighted active region.
23801 Redraw it un-highlighted first. Value is non-zero if mouse
23802 face was actually drawn unhighlighted. */
23805 clear_mouse_face (Display_Info
*dpyinfo
)
23809 if (!dpyinfo
->mouse_face_hidden
&& !NILP (dpyinfo
->mouse_face_window
))
23811 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
23815 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
23816 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
23817 dpyinfo
->mouse_face_window
= Qnil
;
23818 dpyinfo
->mouse_face_overlay
= Qnil
;
23822 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
23823 within the mouse face on that window. */
23825 coords_in_mouse_face_p (struct window
*w
, int hpos
, int vpos
)
23827 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
23829 /* Quickly resolve the easy cases. */
23830 if (!(WINDOWP (dpyinfo
->mouse_face_window
)
23831 && XWINDOW (dpyinfo
->mouse_face_window
) == w
))
23833 if (vpos
< dpyinfo
->mouse_face_beg_row
23834 || vpos
> dpyinfo
->mouse_face_end_row
)
23836 if (vpos
> dpyinfo
->mouse_face_beg_row
23837 && vpos
< dpyinfo
->mouse_face_end_row
)
23840 if (!MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
)
23842 if (dpyinfo
->mouse_face_beg_row
== dpyinfo
->mouse_face_end_row
)
23844 if (dpyinfo
->mouse_face_beg_col
<= hpos
&& hpos
< dpyinfo
->mouse_face_end_col
)
23847 else if ((vpos
== dpyinfo
->mouse_face_beg_row
23848 && hpos
>= dpyinfo
->mouse_face_beg_col
)
23849 || (vpos
== dpyinfo
->mouse_face_end_row
23850 && hpos
< dpyinfo
->mouse_face_end_col
))
23855 if (dpyinfo
->mouse_face_beg_row
== dpyinfo
->mouse_face_end_row
)
23857 if (dpyinfo
->mouse_face_end_col
< hpos
&& hpos
<= dpyinfo
->mouse_face_beg_col
)
23860 else if ((vpos
== dpyinfo
->mouse_face_beg_row
23861 && hpos
<= dpyinfo
->mouse_face_beg_col
)
23862 || (vpos
== dpyinfo
->mouse_face_end_row
23863 && hpos
> dpyinfo
->mouse_face_end_col
))
23871 Non-zero if physical cursor of window W is within mouse face. */
23874 cursor_in_mouse_face_p (struct window
*w
)
23876 return coords_in_mouse_face_p (w
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
);
23881 /* This function sets the mouse_face_* elements of DPYINFO, assuming
23882 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
23883 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
23884 for the overlay or run of text properties specifying the mouse
23885 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
23886 before-string and after-string that must also be highlighted.
23887 DISPLAY_STRING, if non-nil, is a display string that may cover some
23888 or all of the highlighted text. */
23891 mouse_face_from_buffer_pos (Lisp_Object window
,
23892 Display_Info
*dpyinfo
,
23893 EMACS_INT mouse_charpos
,
23894 EMACS_INT start_charpos
,
23895 EMACS_INT end_charpos
,
23896 Lisp_Object before_string
,
23897 Lisp_Object after_string
,
23898 Lisp_Object display_string
)
23900 struct window
*w
= XWINDOW (window
);
23901 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
23902 struct glyph_row
*r1
, *r2
;
23903 struct glyph
*glyph
, *end
;
23904 EMACS_INT ignore
, pos
;
23908 xassert (NILP (display_string
) || STRINGP (display_string
));
23909 xassert (NILP (before_string
) || STRINGP (before_string
));
23910 xassert (NILP (after_string
) || STRINGP (after_string
));
23912 /* Find the row with START_CHARPOS. */
23913 /* FIXME: Sometimes the caller gets "wise" and gives us the window
23914 start position instead of the real start of the mouse face
23915 property. This completely messes up the logic of finding the
23916 beg_row and end_row. */
23917 if (start_charpos
< MATRIX_ROW_START_CHARPOS (first
)
23918 && (NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
)
23919 || row_containing_pos (w
, start_charpos
, first
, NULL
, 0) == NULL
))
23921 dpyinfo
->mouse_face_beg_col
= 0;
23922 dpyinfo
->mouse_face_beg_row
= MATRIX_ROW_VPOS (first
, w
->current_matrix
);
23923 dpyinfo
->mouse_face_beg_x
= first
->x
;
23924 dpyinfo
->mouse_face_beg_y
= first
->y
;
23929 r1
= row_containing_pos (w
, start_charpos
, first
, NULL
, 0);
23931 r1
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
23933 /* If the before-string or display-string contains newlines,
23934 row_containing_pos skips to its last row. Move back. */
23935 if (!NILP (before_string
) || !NILP (display_string
))
23937 struct glyph_row
*prev
;
23938 while ((prev
= r1
- 1, prev
>= first
)
23939 && MATRIX_ROW_END_CHARPOS (prev
) == start_charpos
23940 && prev
->used
[TEXT_AREA
] > 0)
23942 struct glyph
*beg
= prev
->glyphs
[TEXT_AREA
];
23943 glyph
= beg
+ prev
->used
[TEXT_AREA
];
23944 while (--glyph
>= beg
&& INTEGERP (glyph
->object
));
23946 || !(EQ (glyph
->object
, before_string
)
23947 || EQ (glyph
->object
, display_string
)))
23954 /* Find the row with END_CHARPOS. */
23955 r2
= row_containing_pos (w
, end_charpos
, first
, NULL
, 0);
23958 r2
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
23959 dpyinfo
->mouse_face_past_end
= 1;
23961 else if (!NILP (after_string
))
23963 /* If the after-string has newlines, advance to its last row. */
23964 struct glyph_row
*next
;
23965 struct glyph_row
*last
23966 = MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
23968 for (next
= r2
+ 1;
23970 && next
->used
[TEXT_AREA
] > 0
23971 && EQ (next
->glyphs
[TEXT_AREA
]->object
, after_string
);
23976 /* The rest of the display engine assumes that mouse_face_beg_row is
23977 either above below mouse_face_end_row or identical to it. But
23978 with bidi-reordered continued lines, the row for START_CHARPOS
23979 could be below the row for END_CHARPOS. If so, swap the rows and
23980 store them in correct order. */
23983 struct glyph_row
*tem
= r2
;
23988 dpyinfo
->mouse_face_beg_y
= r1
->y
;
23989 dpyinfo
->mouse_face_beg_row
= MATRIX_ROW_VPOS (r1
, w
->current_matrix
);
23990 dpyinfo
->mouse_face_end_y
= r2
->y
;
23991 dpyinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r2
, w
->current_matrix
);
23993 /* For a bidi-reordered row, the positions of BEFORE_STRING,
23994 AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
23995 could be anywhere in the row and in any order. The strategy
23996 below is to find the leftmost and the rightmost glyph that
23997 belongs to either of these 3 strings, or whose position is
23998 between START_CHARPOS and END_CHARPOS, and highlight all the
23999 glyphs between those two. This may cover more than just the text
24000 between START_CHARPOS and END_CHARPOS if the range of characters
24001 strides the bidi level boundary, e.g. if the beginning is in R2L
24002 text while the end is in L2R text or vice versa. */
24005 else if (!r1
->reversed_p
)
24007 /* This row is in a left to right paragraph. Scan it left to
24009 glyph
= r1
->glyphs
[TEXT_AREA
];
24010 end
= glyph
+ r1
->used
[TEXT_AREA
];
24013 /* Skip truncation glyphs at the start of the glyph row. */
24014 if (r1
->displays_text_p
)
24016 && INTEGERP (glyph
->object
)
24017 && glyph
->charpos
< 0;
24019 x
+= glyph
->pixel_width
;
24021 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24022 or DISPLAY_STRING, and the first glyph from buffer whose
24023 position is between START_CHARPOS and END_CHARPOS. */
24025 && !INTEGERP (glyph
->object
)
24026 && !EQ (glyph
->object
, display_string
)
24027 && !(BUFFERP (glyph
->object
)
24028 && (glyph
->charpos
>= start_charpos
24029 && glyph
->charpos
< end_charpos
));
24032 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24033 are present at buffer positions between START_CHARPOS and
24034 END_CHARPOS, or if they come from an overlay. */
24035 if (EQ (glyph
->object
, before_string
))
24037 pos
= string_buffer_position (w
, before_string
,
24039 /* If pos == 0, it means before_string came from an
24040 overlay, not from a buffer position. */
24041 if (!pos
|| pos
>= start_charpos
&& pos
< end_charpos
)
24044 else if (EQ (glyph
->object
, after_string
))
24046 pos
= string_buffer_position (w
, after_string
, end_charpos
);
24047 if (!pos
|| pos
>= start_charpos
&& pos
< end_charpos
)
24050 x
+= glyph
->pixel_width
;
24052 dpyinfo
->mouse_face_beg_x
= x
;
24053 dpyinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
24057 /* This row is in a right to left paragraph. Scan it right to
24061 end
= r1
->glyphs
[TEXT_AREA
] - 1;
24062 glyph
= end
+ r1
->used
[TEXT_AREA
];
24064 /* Skip truncation glyphs at the start of the glyph row. */
24065 if (r1
->displays_text_p
)
24067 && INTEGERP (glyph
->object
)
24068 && glyph
->charpos
< 0;
24072 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24073 or DISPLAY_STRING, and the first glyph from buffer whose
24074 position is between START_CHARPOS and END_CHARPOS. */
24076 && !INTEGERP (glyph
->object
)
24077 && !EQ (glyph
->object
, display_string
)
24078 && !(BUFFERP (glyph
->object
)
24079 && (glyph
->charpos
>= start_charpos
24080 && glyph
->charpos
< end_charpos
));
24083 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24084 are present at buffer positions between START_CHARPOS and
24085 END_CHARPOS, or if they come from an overlay. */
24086 if (EQ (glyph
->object
, before_string
))
24088 pos
= string_buffer_position (w
, before_string
, start_charpos
);
24089 /* If pos == 0, it means before_string came from an
24090 overlay, not from a buffer position. */
24091 if (!pos
|| pos
>= start_charpos
&& pos
< end_charpos
)
24094 else if (EQ (glyph
->object
, after_string
))
24096 pos
= string_buffer_position (w
, after_string
, end_charpos
);
24097 if (!pos
|| pos
>= start_charpos
&& pos
< end_charpos
)
24102 glyph
++; /* first glyph to the right of the highlighted area */
24103 for (g
= r1
->glyphs
[TEXT_AREA
], x
= r1
->x
; g
< glyph
; g
++)
24104 x
+= g
->pixel_width
;
24105 dpyinfo
->mouse_face_beg_x
= x
;
24106 dpyinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
24109 /* If the highlight ends in a different row, compute GLYPH and END
24110 for the end row. Otherwise, reuse the values computed above for
24111 the row where the highlight begins. */
24114 if (!r2
->reversed_p
)
24116 glyph
= r2
->glyphs
[TEXT_AREA
];
24117 end
= glyph
+ r2
->used
[TEXT_AREA
];
24122 end
= r2
->glyphs
[TEXT_AREA
] - 1;
24123 glyph
= end
+ r2
->used
[TEXT_AREA
];
24127 if (!r2
->reversed_p
)
24129 /* Skip truncation and continuation glyphs near the end of the
24130 row, and also blanks and stretch glyphs inserted by
24131 extend_face_to_end_of_line. */
24133 && INTEGERP ((end
- 1)->object
)
24134 && (end
- 1)->charpos
<= 0)
24136 /* Scan the rest of the glyph row from the end, looking for the
24137 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24138 DISPLAY_STRING, or whose position is between START_CHARPOS
24142 && !INTEGERP (end
->object
)
24143 && !EQ (end
->object
, display_string
)
24144 && !(BUFFERP (end
->object
)
24145 && (end
->charpos
>= start_charpos
24146 && end
->charpos
< end_charpos
));
24149 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24150 are present at buffer positions between START_CHARPOS and
24151 END_CHARPOS, or if they come from an overlay. */
24152 if (EQ (end
->object
, before_string
))
24154 pos
= string_buffer_position (w
, before_string
, start_charpos
);
24155 if (!pos
|| pos
>= start_charpos
&& pos
< end_charpos
)
24158 else if (EQ (end
->object
, after_string
))
24160 pos
= string_buffer_position (w
, after_string
, end_charpos
);
24161 if (!pos
|| pos
>= start_charpos
&& pos
< end_charpos
)
24165 /* Find the X coordinate of the last glyph to be highlighted. */
24166 for (; glyph
<= end
; ++glyph
)
24167 x
+= glyph
->pixel_width
;
24169 dpyinfo
->mouse_face_end_x
= x
;
24170 dpyinfo
->mouse_face_end_col
= glyph
- r2
->glyphs
[TEXT_AREA
];
24174 /* Skip truncation and continuation glyphs near the end of the
24175 row, and also blanks and stretch glyphs inserted by
24176 extend_face_to_end_of_line. */
24180 && INTEGERP (end
->object
)
24181 && end
->charpos
<= 0)
24183 x
+= end
->pixel_width
;
24186 /* Scan the rest of the glyph row from the end, looking for the
24187 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24188 DISPLAY_STRING, or whose position is between START_CHARPOS
24192 && !INTEGERP (end
->object
)
24193 && !EQ (end
->object
, display_string
)
24194 && !(BUFFERP (end
->object
)
24195 && (end
->charpos
>= start_charpos
24196 && end
->charpos
< end_charpos
));
24199 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24200 are present at buffer positions between START_CHARPOS and
24201 END_CHARPOS, or if they come from an overlay. */
24202 if (EQ (end
->object
, before_string
))
24204 pos
= string_buffer_position (w
, before_string
, start_charpos
);
24205 if (!pos
|| pos
>= start_charpos
&& pos
< end_charpos
)
24208 else if (EQ (end
->object
, after_string
))
24210 pos
= string_buffer_position (w
, after_string
, end_charpos
);
24211 if (!pos
|| pos
>= start_charpos
&& pos
< end_charpos
)
24214 x
+= end
->pixel_width
;
24216 dpyinfo
->mouse_face_end_x
= x
;
24217 dpyinfo
->mouse_face_end_col
= end
- r2
->glyphs
[TEXT_AREA
];
24220 dpyinfo
->mouse_face_window
= window
;
24221 dpyinfo
->mouse_face_face_id
24222 = face_at_buffer_position (w
, mouse_charpos
, 0, 0, &ignore
,
24224 !dpyinfo
->mouse_face_hidden
, -1);
24225 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
24229 /* Find the position of the glyph for position POS in OBJECT in
24230 window W's current matrix, and return in *X, *Y the pixel
24231 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24233 RIGHT_P non-zero means return the position of the right edge of the
24234 glyph, RIGHT_P zero means return the left edge position.
24236 If no glyph for POS exists in the matrix, return the position of
24237 the glyph with the next smaller position that is in the matrix, if
24238 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24239 exists in the matrix, return the position of the glyph with the
24240 next larger position in OBJECT.
24242 Value is non-zero if a glyph was found. */
24245 fast_find_string_pos (struct window
*w
, EMACS_INT pos
, Lisp_Object object
,
24246 int *hpos
, int *vpos
, int *x
, int *y
, int right_p
)
24248 int yb
= window_text_bottom_y (w
);
24249 struct glyph_row
*r
;
24250 struct glyph
*best_glyph
= NULL
;
24251 struct glyph_row
*best_row
= NULL
;
24254 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
24255 r
->enabled_p
&& r
->y
< yb
;
24258 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
24259 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
24262 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
24263 if (EQ (g
->object
, object
))
24265 if (g
->charpos
== pos
)
24272 else if (best_glyph
== NULL
24273 || ((eabs (g
->charpos
- pos
)
24274 < eabs (best_glyph
->charpos
- pos
))
24277 : g
->charpos
> pos
)))
24291 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
24295 *x
+= best_glyph
->pixel_width
;
24300 *vpos
= best_row
- w
->current_matrix
->rows
;
24303 return best_glyph
!= NULL
;
24307 /* See if position X, Y is within a hot-spot of an image. */
24310 on_hot_spot_p (Lisp_Object hot_spot
, int x
, int y
)
24312 if (!CONSP (hot_spot
))
24315 if (EQ (XCAR (hot_spot
), Qrect
))
24317 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24318 Lisp_Object rect
= XCDR (hot_spot
);
24322 if (!CONSP (XCAR (rect
)))
24324 if (!CONSP (XCDR (rect
)))
24326 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
24328 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
24330 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
24332 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
24336 else if (EQ (XCAR (hot_spot
), Qcircle
))
24338 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24339 Lisp_Object circ
= XCDR (hot_spot
);
24340 Lisp_Object lr
, lx0
, ly0
;
24342 && CONSP (XCAR (circ
))
24343 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
24344 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
24345 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
24347 double r
= XFLOATINT (lr
);
24348 double dx
= XINT (lx0
) - x
;
24349 double dy
= XINT (ly0
) - y
;
24350 return (dx
* dx
+ dy
* dy
<= r
* r
);
24353 else if (EQ (XCAR (hot_spot
), Qpoly
))
24355 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24356 if (VECTORP (XCDR (hot_spot
)))
24358 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
24359 Lisp_Object
*poly
= v
->contents
;
24363 Lisp_Object lx
, ly
;
24366 /* Need an even number of coordinates, and at least 3 edges. */
24367 if (n
< 6 || n
& 1)
24370 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24371 If count is odd, we are inside polygon. Pixels on edges
24372 may or may not be included depending on actual geometry of the
24374 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
24375 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
24377 x0
= XINT (lx
), y0
= XINT (ly
);
24378 for (i
= 0; i
< n
; i
+= 2)
24380 int x1
= x0
, y1
= y0
;
24381 if ((lx
= poly
[i
], !INTEGERP (lx
))
24382 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
24384 x0
= XINT (lx
), y0
= XINT (ly
);
24386 /* Does this segment cross the X line? */
24394 if (y
> y0
&& y
> y1
)
24396 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
24406 find_hot_spot (Lisp_Object map
, int x
, int y
)
24408 while (CONSP (map
))
24410 if (CONSP (XCAR (map
))
24411 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
24419 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
24421 doc
: /* Lookup in image map MAP coordinates X and Y.
24422 An image map is an alist where each element has the format (AREA ID PLIST).
24423 An AREA is specified as either a rectangle, a circle, or a polygon:
24424 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
24425 pixel coordinates of the upper left and bottom right corners.
24426 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
24427 and the radius of the circle; r may be a float or integer.
24428 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
24429 vector describes one corner in the polygon.
24430 Returns the alist element for the first matching AREA in MAP. */)
24431 (Lisp_Object map
, Lisp_Object x
, Lisp_Object y
)
24439 return find_hot_spot (map
, XINT (x
), XINT (y
));
24443 /* Display frame CURSOR, optionally using shape defined by POINTER. */
24445 define_frame_cursor1 (struct frame
*f
, Cursor cursor
, Lisp_Object pointer
)
24447 /* Do not change cursor shape while dragging mouse. */
24448 if (!NILP (do_mouse_tracking
))
24451 if (!NILP (pointer
))
24453 if (EQ (pointer
, Qarrow
))
24454 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24455 else if (EQ (pointer
, Qhand
))
24456 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
24457 else if (EQ (pointer
, Qtext
))
24458 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
24459 else if (EQ (pointer
, intern ("hdrag")))
24460 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
24461 #ifdef HAVE_X_WINDOWS
24462 else if (EQ (pointer
, intern ("vdrag")))
24463 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
24465 else if (EQ (pointer
, intern ("hourglass")))
24466 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
24467 else if (EQ (pointer
, Qmodeline
))
24468 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
24470 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24473 if (cursor
!= No_Cursor
)
24474 FRAME_RIF (f
)->define_frame_cursor (f
, cursor
);
24477 /* Take proper action when mouse has moved to the mode or header line
24478 or marginal area AREA of window W, x-position X and y-position Y.
24479 X is relative to the start of the text display area of W, so the
24480 width of bitmap areas and scroll bars must be subtracted to get a
24481 position relative to the start of the mode line. */
24484 note_mode_line_or_margin_highlight (Lisp_Object window
, int x
, int y
,
24485 enum window_part area
)
24487 struct window
*w
= XWINDOW (window
);
24488 struct frame
*f
= XFRAME (w
->frame
);
24489 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
24490 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24491 Lisp_Object pointer
= Qnil
;
24492 int charpos
, dx
, dy
, width
, height
;
24493 Lisp_Object string
, object
= Qnil
;
24494 Lisp_Object pos
, help
;
24496 Lisp_Object mouse_face
;
24497 int original_x_pixel
= x
;
24498 struct glyph
* glyph
= NULL
, * row_start_glyph
= NULL
;
24499 struct glyph_row
*row
;
24501 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
24506 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
24507 &object
, &dx
, &dy
, &width
, &height
);
24509 row
= (area
== ON_MODE_LINE
24510 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
24511 : MATRIX_HEADER_LINE_ROW (w
->current_matrix
));
24514 if (row
->mode_line_p
&& row
->enabled_p
)
24516 glyph
= row_start_glyph
= row
->glyphs
[TEXT_AREA
];
24517 end
= glyph
+ row
->used
[TEXT_AREA
];
24519 for (x0
= original_x_pixel
;
24520 glyph
< end
&& x0
>= glyph
->pixel_width
;
24522 x0
-= glyph
->pixel_width
;
24530 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
24531 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
24532 &object
, &dx
, &dy
, &width
, &height
);
24537 if (IMAGEP (object
))
24539 Lisp_Object image_map
, hotspot
;
24540 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
24542 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
24544 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
24546 Lisp_Object area_id
, plist
;
24548 area_id
= XCAR (hotspot
);
24549 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24550 If so, we could look for mouse-enter, mouse-leave
24551 properties in PLIST (and do something...). */
24552 hotspot
= XCDR (hotspot
);
24553 if (CONSP (hotspot
)
24554 && (plist
= XCAR (hotspot
), CONSP (plist
)))
24556 pointer
= Fplist_get (plist
, Qpointer
);
24557 if (NILP (pointer
))
24559 help
= Fplist_get (plist
, Qhelp_echo
);
24562 help_echo_string
= help
;
24563 /* Is this correct? ++kfs */
24564 XSETWINDOW (help_echo_window
, w
);
24565 help_echo_object
= w
->buffer
;
24566 help_echo_pos
= charpos
;
24570 if (NILP (pointer
))
24571 pointer
= Fplist_get (XCDR (object
), QCpointer
);
24574 if (STRINGP (string
))
24576 pos
= make_number (charpos
);
24577 /* If we're on a string with `help-echo' text property, arrange
24578 for the help to be displayed. This is done by setting the
24579 global variable help_echo_string to the help string. */
24582 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
24585 help_echo_string
= help
;
24586 XSETWINDOW (help_echo_window
, w
);
24587 help_echo_object
= string
;
24588 help_echo_pos
= charpos
;
24592 if (NILP (pointer
))
24593 pointer
= Fget_text_property (pos
, Qpointer
, string
);
24595 /* Change the mouse pointer according to what is under X/Y. */
24596 if (NILP (pointer
) && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
24599 map
= Fget_text_property (pos
, Qlocal_map
, string
);
24600 if (!KEYMAPP (map
))
24601 map
= Fget_text_property (pos
, Qkeymap
, string
);
24602 if (!KEYMAPP (map
))
24603 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
24606 /* Change the mouse face according to what is under X/Y. */
24607 mouse_face
= Fget_text_property (pos
, Qmouse_face
, string
);
24608 if (!NILP (mouse_face
)
24609 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
24614 struct glyph
* tmp_glyph
;
24618 int total_pixel_width
;
24623 b
= Fprevious_single_property_change (make_number (charpos
+ 1),
24624 Qmouse_face
, string
, Qnil
);
24626 b
= make_number (0);
24628 e
= Fnext_single_property_change (pos
, Qmouse_face
, string
, Qnil
);
24630 e
= make_number (SCHARS (string
));
24632 /* Calculate the position(glyph position: GPOS) of GLYPH in
24633 displayed string. GPOS is different from CHARPOS.
24635 CHARPOS is the position of glyph in internal string
24636 object. A mode line string format has structures which
24637 is converted to a flatten by emacs lisp interpreter.
24638 The internal string is an element of the structures.
24639 The displayed string is the flatten string. */
24641 if (glyph
> row_start_glyph
)
24643 tmp_glyph
= glyph
- 1;
24644 while (tmp_glyph
>= row_start_glyph
24645 && tmp_glyph
->charpos
>= XINT (b
)
24646 && EQ (tmp_glyph
->object
, glyph
->object
))
24653 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
24654 displayed string holding GLYPH.
24656 GSEQ_LENGTH is different from SCHARS (STRING).
24657 SCHARS (STRING) returns the length of the internal string. */
24658 for (tmp_glyph
= glyph
, gseq_length
= gpos
;
24659 tmp_glyph
->charpos
< XINT (e
);
24660 tmp_glyph
++, gseq_length
++)
24662 if (!EQ (tmp_glyph
->object
, glyph
->object
))
24666 total_pixel_width
= 0;
24667 for (tmp_glyph
= glyph
- gpos
; tmp_glyph
!= glyph
; tmp_glyph
++)
24668 total_pixel_width
+= tmp_glyph
->pixel_width
;
24670 /* Pre calculation of re-rendering position */
24672 vpos
= (area
== ON_MODE_LINE
24673 ? (w
->current_matrix
)->nrows
- 1
24676 /* If the re-rendering position is included in the last
24677 re-rendering area, we should do nothing. */
24678 if ( EQ (window
, dpyinfo
->mouse_face_window
)
24679 && dpyinfo
->mouse_face_beg_col
<= hpos
24680 && hpos
< dpyinfo
->mouse_face_end_col
24681 && dpyinfo
->mouse_face_beg_row
== vpos
)
24684 if (clear_mouse_face (dpyinfo
))
24685 cursor
= No_Cursor
;
24687 dpyinfo
->mouse_face_beg_col
= hpos
;
24688 dpyinfo
->mouse_face_beg_row
= vpos
;
24690 dpyinfo
->mouse_face_beg_x
= original_x_pixel
- (total_pixel_width
+ dx
);
24691 dpyinfo
->mouse_face_beg_y
= 0;
24693 dpyinfo
->mouse_face_end_col
= hpos
+ gseq_length
;
24694 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_beg_row
;
24696 dpyinfo
->mouse_face_end_x
= 0;
24697 dpyinfo
->mouse_face_end_y
= 0;
24699 dpyinfo
->mouse_face_past_end
= 0;
24700 dpyinfo
->mouse_face_window
= window
;
24702 dpyinfo
->mouse_face_face_id
= face_at_string_position (w
, string
,
24705 glyph
->face_id
, 1);
24706 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
24708 if (NILP (pointer
))
24711 else if ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
24712 clear_mouse_face (dpyinfo
);
24714 define_frame_cursor1 (f
, cursor
, pointer
);
24719 Take proper action when the mouse has moved to position X, Y on
24720 frame F as regards highlighting characters that have mouse-face
24721 properties. Also de-highlighting chars where the mouse was before.
24722 X and Y can be negative or out of range. */
24725 note_mouse_highlight (struct frame
*f
, int x
, int y
)
24727 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
24728 enum window_part part
;
24729 Lisp_Object window
;
24731 Cursor cursor
= No_Cursor
;
24732 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
24735 /* When a menu is active, don't highlight because this looks odd. */
24736 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
24737 if (popup_activated ())
24741 if (NILP (Vmouse_highlight
)
24742 || !f
->glyphs_initialized_p
24743 || f
->pointer_invisible
)
24746 dpyinfo
->mouse_face_mouse_x
= x
;
24747 dpyinfo
->mouse_face_mouse_y
= y
;
24748 dpyinfo
->mouse_face_mouse_frame
= f
;
24750 if (dpyinfo
->mouse_face_defer
)
24753 if (gc_in_progress
)
24755 dpyinfo
->mouse_face_deferred_gc
= 1;
24759 /* Which window is that in? */
24760 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
24762 /* If we were displaying active text in another window, clear that.
24763 Also clear if we move out of text area in same window. */
24764 if (! EQ (window
, dpyinfo
->mouse_face_window
)
24765 || (part
!= ON_TEXT
&& part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
24766 && !NILP (dpyinfo
->mouse_face_window
)))
24767 clear_mouse_face (dpyinfo
);
24769 /* Not on a window -> return. */
24770 if (!WINDOWP (window
))
24773 /* Reset help_echo_string. It will get recomputed below. */
24774 help_echo_string
= Qnil
;
24776 /* Convert to window-relative pixel coordinates. */
24777 w
= XWINDOW (window
);
24778 frame_to_window_pixel_xy (w
, &x
, &y
);
24780 /* Handle tool-bar window differently since it doesn't display a
24782 if (EQ (window
, f
->tool_bar_window
))
24784 note_tool_bar_highlight (f
, x
, y
);
24788 /* Mouse is on the mode, header line or margin? */
24789 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
24790 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
24792 note_mode_line_or_margin_highlight (window
, x
, y
, part
);
24796 if (part
== ON_VERTICAL_BORDER
)
24798 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
24799 help_echo_string
= build_string ("drag-mouse-1: resize");
24801 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
24802 || part
== ON_SCROLL_BAR
)
24803 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24805 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
24807 /* Are we in a window whose display is up to date?
24808 And verify the buffer's text has not changed. */
24809 b
= XBUFFER (w
->buffer
);
24810 if (part
== ON_TEXT
24811 && EQ (w
->window_end_valid
, w
->buffer
)
24812 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
24813 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
24815 int hpos
, vpos
, i
, dx
, dy
, area
;
24817 struct glyph
*glyph
;
24818 Lisp_Object object
;
24819 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
24820 Lisp_Object
*overlay_vec
= NULL
;
24822 struct buffer
*obuf
;
24823 int obegv
, ozv
, same_region
;
24825 /* Find the glyph under X/Y. */
24826 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
24828 /* Look for :pointer property on image. */
24829 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
24831 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
24832 if (img
!= NULL
&& IMAGEP (img
->spec
))
24834 Lisp_Object image_map
, hotspot
;
24835 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
24837 && (hotspot
= find_hot_spot (image_map
,
24838 glyph
->slice
.x
+ dx
,
24839 glyph
->slice
.y
+ dy
),
24841 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
24843 Lisp_Object area_id
, plist
;
24845 area_id
= XCAR (hotspot
);
24846 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24847 If so, we could look for mouse-enter, mouse-leave
24848 properties in PLIST (and do something...). */
24849 hotspot
= XCDR (hotspot
);
24850 if (CONSP (hotspot
)
24851 && (plist
= XCAR (hotspot
), CONSP (plist
)))
24853 pointer
= Fplist_get (plist
, Qpointer
);
24854 if (NILP (pointer
))
24856 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
24857 if (!NILP (help_echo_string
))
24859 help_echo_window
= window
;
24860 help_echo_object
= glyph
->object
;
24861 help_echo_pos
= glyph
->charpos
;
24865 if (NILP (pointer
))
24866 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
24870 /* Clear mouse face if X/Y not over text. */
24872 || area
!= TEXT_AREA
24873 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
24874 /* R2L rows have a stretch glyph at their front, which
24875 stands for no text, whereas L2R rows have no glyphs at
24876 all beyond the end of text. Treat such stretch glyphs
24877 like we do with NULL glyphs in L2R rows. */
24878 || (MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
24879 && glyph
== MATRIX_ROW (w
->current_matrix
, vpos
)->glyphs
[TEXT_AREA
]
24880 && glyph
->type
== STRETCH_GLYPH
24881 && glyph
->avoid_cursor_p
))
24883 if (clear_mouse_face (dpyinfo
))
24884 cursor
= No_Cursor
;
24885 if (NILP (pointer
))
24887 if (area
!= TEXT_AREA
)
24888 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24890 pointer
= Vvoid_text_area_pointer
;
24895 pos
= glyph
->charpos
;
24896 object
= glyph
->object
;
24897 if (!STRINGP (object
) && !BUFFERP (object
))
24900 /* If we get an out-of-range value, return now; avoid an error. */
24901 if (BUFFERP (object
) && pos
> BUF_Z (b
))
24904 /* Make the window's buffer temporarily current for
24905 overlays_at and compute_char_face. */
24906 obuf
= current_buffer
;
24907 current_buffer
= b
;
24913 /* Is this char mouse-active or does it have help-echo? */
24914 position
= make_number (pos
);
24916 if (BUFFERP (object
))
24918 /* Put all the overlays we want in a vector in overlay_vec. */
24919 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
24920 /* Sort overlays into increasing priority order. */
24921 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
24926 same_region
= coords_in_mouse_face_p (w
, hpos
, vpos
);
24929 cursor
= No_Cursor
;
24931 /* Check mouse-face highlighting. */
24933 /* If there exists an overlay with mouse-face overlapping
24934 the one we are currently highlighting, we have to
24935 check if we enter the overlapping overlay, and then
24936 highlight only that. */
24937 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
24938 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
24940 /* Find the highest priority overlay with a mouse-face. */
24942 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
24944 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
24945 if (!NILP (mouse_face
))
24946 overlay
= overlay_vec
[i
];
24949 /* If we're highlighting the same overlay as before, there's
24950 no need to do that again. */
24951 if (!NILP (overlay
) && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
24952 goto check_help_echo
;
24953 dpyinfo
->mouse_face_overlay
= overlay
;
24955 /* Clear the display of the old active region, if any. */
24956 if (clear_mouse_face (dpyinfo
))
24957 cursor
= No_Cursor
;
24959 /* If no overlay applies, get a text property. */
24960 if (NILP (overlay
))
24961 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
24963 /* Next, compute the bounds of the mouse highlighting and
24965 if (!NILP (mouse_face
) && STRINGP (object
))
24967 /* The mouse-highlighting comes from a display string
24968 with a mouse-face. */
24972 b
= Fprevious_single_property_change
24973 (make_number (pos
+ 1), Qmouse_face
, object
, Qnil
);
24974 e
= Fnext_single_property_change
24975 (position
, Qmouse_face
, object
, Qnil
);
24977 b
= make_number (0);
24979 e
= make_number (SCHARS (object
) - 1);
24981 fast_find_string_pos (w
, XINT (b
), object
,
24982 &dpyinfo
->mouse_face_beg_col
,
24983 &dpyinfo
->mouse_face_beg_row
,
24984 &dpyinfo
->mouse_face_beg_x
,
24985 &dpyinfo
->mouse_face_beg_y
, 0);
24986 fast_find_string_pos (w
, XINT (e
), object
,
24987 &dpyinfo
->mouse_face_end_col
,
24988 &dpyinfo
->mouse_face_end_row
,
24989 &dpyinfo
->mouse_face_end_x
,
24990 &dpyinfo
->mouse_face_end_y
, 1);
24991 dpyinfo
->mouse_face_past_end
= 0;
24992 dpyinfo
->mouse_face_window
= window
;
24993 dpyinfo
->mouse_face_face_id
24994 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
24995 glyph
->face_id
, 1);
24996 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
24997 cursor
= No_Cursor
;
25001 /* The mouse-highlighting, if any, comes from an overlay
25002 or text property in the buffer. */
25003 Lisp_Object buffer
, display_string
;
25005 if (STRINGP (object
))
25007 /* If we are on a display string with no mouse-face,
25008 check if the text under it has one. */
25009 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
25010 int start
= MATRIX_ROW_START_CHARPOS (r
);
25011 pos
= string_buffer_position (w
, object
, start
);
25014 mouse_face
= get_char_property_and_overlay
25015 (make_number (pos
), Qmouse_face
, w
->buffer
, &overlay
);
25016 buffer
= w
->buffer
;
25017 display_string
= object
;
25023 display_string
= Qnil
;
25026 if (!NILP (mouse_face
))
25028 Lisp_Object before
, after
;
25029 Lisp_Object before_string
, after_string
;
25031 if (NILP (overlay
))
25033 /* Handle the text property case. */
25034 before
= Fprevious_single_property_change
25035 (make_number (pos
+ 1), Qmouse_face
, buffer
,
25036 Fmarker_position (w
->start
));
25037 after
= Fnext_single_property_change
25038 (make_number (pos
), Qmouse_face
, buffer
,
25039 make_number (BUF_Z (XBUFFER (buffer
))
25040 - XFASTINT (w
->window_end_pos
)));
25041 before_string
= after_string
= Qnil
;
25045 /* Handle the overlay case. */
25046 before
= Foverlay_start (overlay
);
25047 after
= Foverlay_end (overlay
);
25048 before_string
= Foverlay_get (overlay
, Qbefore_string
);
25049 after_string
= Foverlay_get (overlay
, Qafter_string
);
25051 if (!STRINGP (before_string
)) before_string
= Qnil
;
25052 if (!STRINGP (after_string
)) after_string
= Qnil
;
25055 mouse_face_from_buffer_pos (window
, dpyinfo
, pos
,
25058 before_string
, after_string
,
25060 cursor
= No_Cursor
;
25067 /* Look for a `help-echo' property. */
25068 if (NILP (help_echo_string
)) {
25069 Lisp_Object help
, overlay
;
25071 /* Check overlays first. */
25072 help
= overlay
= Qnil
;
25073 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
25075 overlay
= overlay_vec
[i
];
25076 help
= Foverlay_get (overlay
, Qhelp_echo
);
25081 help_echo_string
= help
;
25082 help_echo_window
= window
;
25083 help_echo_object
= overlay
;
25084 help_echo_pos
= pos
;
25088 Lisp_Object object
= glyph
->object
;
25089 int charpos
= glyph
->charpos
;
25091 /* Try text properties. */
25092 if (STRINGP (object
)
25094 && charpos
< SCHARS (object
))
25096 help
= Fget_text_property (make_number (charpos
),
25097 Qhelp_echo
, object
);
25100 /* If the string itself doesn't specify a help-echo,
25101 see if the buffer text ``under'' it does. */
25102 struct glyph_row
*r
25103 = MATRIX_ROW (w
->current_matrix
, vpos
);
25104 int start
= MATRIX_ROW_START_CHARPOS (r
);
25105 EMACS_INT pos
= string_buffer_position (w
, object
, start
);
25108 help
= Fget_char_property (make_number (pos
),
25109 Qhelp_echo
, w
->buffer
);
25113 object
= w
->buffer
;
25118 else if (BUFFERP (object
)
25121 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
25126 help_echo_string
= help
;
25127 help_echo_window
= window
;
25128 help_echo_object
= object
;
25129 help_echo_pos
= charpos
;
25134 /* Look for a `pointer' property. */
25135 if (NILP (pointer
))
25137 /* Check overlays first. */
25138 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
25139 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
25141 if (NILP (pointer
))
25143 Lisp_Object object
= glyph
->object
;
25144 int charpos
= glyph
->charpos
;
25146 /* Try text properties. */
25147 if (STRINGP (object
)
25149 && charpos
< SCHARS (object
))
25151 pointer
= Fget_text_property (make_number (charpos
),
25153 if (NILP (pointer
))
25155 /* If the string itself doesn't specify a pointer,
25156 see if the buffer text ``under'' it does. */
25157 struct glyph_row
*r
25158 = MATRIX_ROW (w
->current_matrix
, vpos
);
25159 int start
= MATRIX_ROW_START_CHARPOS (r
);
25160 EMACS_INT pos
= string_buffer_position (w
, object
,
25163 pointer
= Fget_char_property (make_number (pos
),
25164 Qpointer
, w
->buffer
);
25167 else if (BUFFERP (object
)
25170 pointer
= Fget_text_property (make_number (charpos
),
25177 current_buffer
= obuf
;
25182 define_frame_cursor1 (f
, cursor
, pointer
);
25187 Clear any mouse-face on window W. This function is part of the
25188 redisplay interface, and is called from try_window_id and similar
25189 functions to ensure the mouse-highlight is off. */
25192 x_clear_window_mouse_face (struct window
*w
)
25194 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
25195 Lisp_Object window
;
25198 XSETWINDOW (window
, w
);
25199 if (EQ (window
, dpyinfo
->mouse_face_window
))
25200 clear_mouse_face (dpyinfo
);
25206 Just discard the mouse face information for frame F, if any.
25207 This is used when the size of F is changed. */
25210 cancel_mouse_face (struct frame
*f
)
25212 Lisp_Object window
;
25213 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
25215 window
= dpyinfo
->mouse_face_window
;
25216 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
25218 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
25219 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
25220 dpyinfo
->mouse_face_window
= Qnil
;
25225 #endif /* HAVE_WINDOW_SYSTEM */
25228 /***********************************************************************
25230 ***********************************************************************/
25232 #ifdef HAVE_WINDOW_SYSTEM
25234 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25235 which intersects rectangle R. R is in window-relative coordinates. */
25238 expose_area (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
,
25239 enum glyph_row_area area
)
25241 struct glyph
*first
= row
->glyphs
[area
];
25242 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
25243 struct glyph
*last
;
25244 int first_x
, start_x
, x
;
25246 if (area
== TEXT_AREA
&& row
->fill_line_p
)
25247 /* If row extends face to end of line write the whole line. */
25248 draw_glyphs (w
, 0, row
, area
,
25249 0, row
->used
[area
],
25250 DRAW_NORMAL_TEXT
, 0);
25253 /* Set START_X to the window-relative start position for drawing glyphs of
25254 AREA. The first glyph of the text area can be partially visible.
25255 The first glyphs of other areas cannot. */
25256 start_x
= window_box_left_offset (w
, area
);
25258 if (area
== TEXT_AREA
)
25261 /* Find the first glyph that must be redrawn. */
25263 && x
+ first
->pixel_width
< r
->x
)
25265 x
+= first
->pixel_width
;
25269 /* Find the last one. */
25273 && x
< r
->x
+ r
->width
)
25275 x
+= last
->pixel_width
;
25281 draw_glyphs (w
, first_x
- start_x
, row
, area
,
25282 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
25283 DRAW_NORMAL_TEXT
, 0);
25288 /* Redraw the parts of the glyph row ROW on window W intersecting
25289 rectangle R. R is in window-relative coordinates. Value is
25290 non-zero if mouse-face was overwritten. */
25293 expose_line (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
)
25295 xassert (row
->enabled_p
);
25297 if (row
->mode_line_p
|| w
->pseudo_window_p
)
25298 draw_glyphs (w
, 0, row
, TEXT_AREA
,
25299 0, row
->used
[TEXT_AREA
],
25300 DRAW_NORMAL_TEXT
, 0);
25303 if (row
->used
[LEFT_MARGIN_AREA
])
25304 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
25305 if (row
->used
[TEXT_AREA
])
25306 expose_area (w
, row
, r
, TEXT_AREA
);
25307 if (row
->used
[RIGHT_MARGIN_AREA
])
25308 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
25309 draw_row_fringe_bitmaps (w
, row
);
25312 return row
->mouse_face_p
;
25316 /* Redraw those parts of glyphs rows during expose event handling that
25317 overlap other rows. Redrawing of an exposed line writes over parts
25318 of lines overlapping that exposed line; this function fixes that.
25320 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25321 row in W's current matrix that is exposed and overlaps other rows.
25322 LAST_OVERLAPPING_ROW is the last such row. */
25325 expose_overlaps (struct window
*w
,
25326 struct glyph_row
*first_overlapping_row
,
25327 struct glyph_row
*last_overlapping_row
,
25330 struct glyph_row
*row
;
25332 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
25333 if (row
->overlapping_p
)
25335 xassert (row
->enabled_p
&& !row
->mode_line_p
);
25338 if (row
->used
[LEFT_MARGIN_AREA
])
25339 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
, OVERLAPS_BOTH
);
25341 if (row
->used
[TEXT_AREA
])
25342 x_fix_overlapping_area (w
, row
, TEXT_AREA
, OVERLAPS_BOTH
);
25344 if (row
->used
[RIGHT_MARGIN_AREA
])
25345 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
, OVERLAPS_BOTH
);
25351 /* Return non-zero if W's cursor intersects rectangle R. */
25354 phys_cursor_in_rect_p (struct window
*w
, XRectangle
*r
)
25356 XRectangle cr
, result
;
25357 struct glyph
*cursor_glyph
;
25358 struct glyph_row
*row
;
25360 if (w
->phys_cursor
.vpos
>= 0
25361 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
25362 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
25364 && row
->cursor_in_fringe_p
)
25366 /* Cursor is in the fringe. */
25367 cr
.x
= window_box_right_offset (w
,
25368 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
25369 ? RIGHT_MARGIN_AREA
25372 cr
.width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
25373 cr
.height
= row
->height
;
25374 return x_intersect_rectangles (&cr
, r
, &result
);
25377 cursor_glyph
= get_phys_cursor_glyph (w
);
25380 /* r is relative to W's box, but w->phys_cursor.x is relative
25381 to left edge of W's TEXT area. Adjust it. */
25382 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
25383 cr
.y
= w
->phys_cursor
.y
;
25384 cr
.width
= cursor_glyph
->pixel_width
;
25385 cr
.height
= w
->phys_cursor_height
;
25386 /* ++KFS: W32 version used W32-specific IntersectRect here, but
25387 I assume the effect is the same -- and this is portable. */
25388 return x_intersect_rectangles (&cr
, r
, &result
);
25390 /* If we don't understand the format, pretend we're not in the hot-spot. */
25396 Draw a vertical window border to the right of window W if W doesn't
25397 have vertical scroll bars. */
25400 x_draw_vertical_border (struct window
*w
)
25402 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
25404 /* We could do better, if we knew what type of scroll-bar the adjacent
25405 windows (on either side) have... But we don't :-(
25406 However, I think this works ok. ++KFS 2003-04-25 */
25408 /* Redraw borders between horizontally adjacent windows. Don't
25409 do it for frames with vertical scroll bars because either the
25410 right scroll bar of a window, or the left scroll bar of its
25411 neighbor will suffice as a border. */
25412 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w
->frame
)))
25415 if (!WINDOW_RIGHTMOST_P (w
)
25416 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
25418 int x0
, x1
, y0
, y1
;
25420 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
25423 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
25426 FRAME_RIF (f
)->draw_vertical_window_border (w
, x1
, y0
, y1
);
25428 else if (!WINDOW_LEFTMOST_P (w
)
25429 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
25431 int x0
, x1
, y0
, y1
;
25433 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
25436 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
25439 FRAME_RIF (f
)->draw_vertical_window_border (w
, x0
, y0
, y1
);
25444 /* Redraw the part of window W intersection rectangle FR. Pixel
25445 coordinates in FR are frame-relative. Call this function with
25446 input blocked. Value is non-zero if the exposure overwrites
25450 expose_window (struct window
*w
, XRectangle
*fr
)
25452 struct frame
*f
= XFRAME (w
->frame
);
25454 int mouse_face_overwritten_p
= 0;
25456 /* If window is not yet fully initialized, do nothing. This can
25457 happen when toolkit scroll bars are used and a window is split.
25458 Reconfiguring the scroll bar will generate an expose for a newly
25460 if (w
->current_matrix
== NULL
)
25463 /* When we're currently updating the window, display and current
25464 matrix usually don't agree. Arrange for a thorough display
25466 if (w
== updated_window
)
25468 SET_FRAME_GARBAGED (f
);
25472 /* Frame-relative pixel rectangle of W. */
25473 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
25474 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
25475 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
25476 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
25478 if (x_intersect_rectangles (fr
, &wr
, &r
))
25480 int yb
= window_text_bottom_y (w
);
25481 struct glyph_row
*row
;
25482 int cursor_cleared_p
;
25483 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
25485 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
25486 r
.x
, r
.y
, r
.width
, r
.height
));
25488 /* Convert to window coordinates. */
25489 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
25490 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
25492 /* Turn off the cursor. */
25493 if (!w
->pseudo_window_p
25494 && phys_cursor_in_rect_p (w
, &r
))
25496 x_clear_cursor (w
);
25497 cursor_cleared_p
= 1;
25500 cursor_cleared_p
= 0;
25502 /* Update lines intersecting rectangle R. */
25503 first_overlapping_row
= last_overlapping_row
= NULL
;
25504 for (row
= w
->current_matrix
->rows
;
25509 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
25511 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
25512 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
25513 || (r
.y
>= y0
&& r
.y
< y1
)
25514 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
25516 /* A header line may be overlapping, but there is no need
25517 to fix overlapping areas for them. KFS 2005-02-12 */
25518 if (row
->overlapping_p
&& !row
->mode_line_p
)
25520 if (first_overlapping_row
== NULL
)
25521 first_overlapping_row
= row
;
25522 last_overlapping_row
= row
;
25526 if (expose_line (w
, row
, &r
))
25527 mouse_face_overwritten_p
= 1;
25530 else if (row
->overlapping_p
)
25532 /* We must redraw a row overlapping the exposed area. */
25534 ? y0
+ row
->phys_height
> r
.y
25535 : y0
+ row
->ascent
- row
->phys_ascent
< r
.y
+r
.height
)
25537 if (first_overlapping_row
== NULL
)
25538 first_overlapping_row
= row
;
25539 last_overlapping_row
= row
;
25547 /* Display the mode line if there is one. */
25548 if (WINDOW_WANTS_MODELINE_P (w
)
25549 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
25551 && row
->y
< r
.y
+ r
.height
)
25553 if (expose_line (w
, row
, &r
))
25554 mouse_face_overwritten_p
= 1;
25557 if (!w
->pseudo_window_p
)
25559 /* Fix the display of overlapping rows. */
25560 if (first_overlapping_row
)
25561 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
,
25564 /* Draw border between windows. */
25565 x_draw_vertical_border (w
);
25567 /* Turn the cursor on again. */
25568 if (cursor_cleared_p
)
25569 update_window_cursor (w
, 1);
25573 return mouse_face_overwritten_p
;
25578 /* Redraw (parts) of all windows in the window tree rooted at W that
25579 intersect R. R contains frame pixel coordinates. Value is
25580 non-zero if the exposure overwrites mouse-face. */
25583 expose_window_tree (struct window
*w
, XRectangle
*r
)
25585 struct frame
*f
= XFRAME (w
->frame
);
25586 int mouse_face_overwritten_p
= 0;
25588 while (w
&& !FRAME_GARBAGED_P (f
))
25590 if (!NILP (w
->hchild
))
25591 mouse_face_overwritten_p
25592 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
25593 else if (!NILP (w
->vchild
))
25594 mouse_face_overwritten_p
25595 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
25597 mouse_face_overwritten_p
|= expose_window (w
, r
);
25599 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
25602 return mouse_face_overwritten_p
;
25607 Redisplay an exposed area of frame F. X and Y are the upper-left
25608 corner of the exposed rectangle. W and H are width and height of
25609 the exposed area. All are pixel values. W or H zero means redraw
25610 the entire frame. */
25613 expose_frame (struct frame
*f
, int x
, int y
, int w
, int h
)
25616 int mouse_face_overwritten_p
= 0;
25618 TRACE ((stderr
, "expose_frame "));
25620 /* No need to redraw if frame will be redrawn soon. */
25621 if (FRAME_GARBAGED_P (f
))
25623 TRACE ((stderr
, " garbaged\n"));
25627 /* If basic faces haven't been realized yet, there is no point in
25628 trying to redraw anything. This can happen when we get an expose
25629 event while Emacs is starting, e.g. by moving another window. */
25630 if (FRAME_FACE_CACHE (f
) == NULL
25631 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
25633 TRACE ((stderr
, " no faces\n"));
25637 if (w
== 0 || h
== 0)
25640 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
25641 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
25651 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
25652 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
25654 if (WINDOWP (f
->tool_bar_window
))
25655 mouse_face_overwritten_p
25656 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
25658 #ifdef HAVE_X_WINDOWS
25660 #ifndef USE_X_TOOLKIT
25661 if (WINDOWP (f
->menu_bar_window
))
25662 mouse_face_overwritten_p
25663 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
25664 #endif /* not USE_X_TOOLKIT */
25668 /* Some window managers support a focus-follows-mouse style with
25669 delayed raising of frames. Imagine a partially obscured frame,
25670 and moving the mouse into partially obscured mouse-face on that
25671 frame. The visible part of the mouse-face will be highlighted,
25672 then the WM raises the obscured frame. With at least one WM, KDE
25673 2.1, Emacs is not getting any event for the raising of the frame
25674 (even tried with SubstructureRedirectMask), only Expose events.
25675 These expose events will draw text normally, i.e. not
25676 highlighted. Which means we must redo the highlight here.
25677 Subsume it under ``we love X''. --gerd 2001-08-15 */
25678 /* Included in Windows version because Windows most likely does not
25679 do the right thing if any third party tool offers
25680 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
25681 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
25683 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
25684 if (f
== dpyinfo
->mouse_face_mouse_frame
)
25686 int x
= dpyinfo
->mouse_face_mouse_x
;
25687 int y
= dpyinfo
->mouse_face_mouse_y
;
25688 clear_mouse_face (dpyinfo
);
25689 note_mouse_highlight (f
, x
, y
);
25696 Determine the intersection of two rectangles R1 and R2. Return
25697 the intersection in *RESULT. Value is non-zero if RESULT is not
25701 x_intersect_rectangles (XRectangle
*r1
, XRectangle
*r2
, XRectangle
*result
)
25703 XRectangle
*left
, *right
;
25704 XRectangle
*upper
, *lower
;
25705 int intersection_p
= 0;
25707 /* Rearrange so that R1 is the left-most rectangle. */
25709 left
= r1
, right
= r2
;
25711 left
= r2
, right
= r1
;
25713 /* X0 of the intersection is right.x0, if this is inside R1,
25714 otherwise there is no intersection. */
25715 if (right
->x
<= left
->x
+ left
->width
)
25717 result
->x
= right
->x
;
25719 /* The right end of the intersection is the minimum of the
25720 the right ends of left and right. */
25721 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
25724 /* Same game for Y. */
25726 upper
= r1
, lower
= r2
;
25728 upper
= r2
, lower
= r1
;
25730 /* The upper end of the intersection is lower.y0, if this is inside
25731 of upper. Otherwise, there is no intersection. */
25732 if (lower
->y
<= upper
->y
+ upper
->height
)
25734 result
->y
= lower
->y
;
25736 /* The lower end of the intersection is the minimum of the lower
25737 ends of upper and lower. */
25738 result
->height
= (min (lower
->y
+ lower
->height
,
25739 upper
->y
+ upper
->height
)
25741 intersection_p
= 1;
25745 return intersection_p
;
25748 #endif /* HAVE_WINDOW_SYSTEM */
25751 /***********************************************************************
25753 ***********************************************************************/
25756 syms_of_xdisp (void)
25758 Vwith_echo_area_save_vector
= Qnil
;
25759 staticpro (&Vwith_echo_area_save_vector
);
25761 Vmessage_stack
= Qnil
;
25762 staticpro (&Vmessage_stack
);
25764 Qinhibit_redisplay
= intern_c_string ("inhibit-redisplay");
25765 staticpro (&Qinhibit_redisplay
);
25767 message_dolog_marker1
= Fmake_marker ();
25768 staticpro (&message_dolog_marker1
);
25769 message_dolog_marker2
= Fmake_marker ();
25770 staticpro (&message_dolog_marker2
);
25771 message_dolog_marker3
= Fmake_marker ();
25772 staticpro (&message_dolog_marker3
);
25775 defsubr (&Sdump_frame_glyph_matrix
);
25776 defsubr (&Sdump_glyph_matrix
);
25777 defsubr (&Sdump_glyph_row
);
25778 defsubr (&Sdump_tool_bar_row
);
25779 defsubr (&Strace_redisplay
);
25780 defsubr (&Strace_to_stderr
);
25782 #ifdef HAVE_WINDOW_SYSTEM
25783 defsubr (&Stool_bar_lines_needed
);
25784 defsubr (&Slookup_image_map
);
25786 defsubr (&Sformat_mode_line
);
25787 defsubr (&Sinvisible_p
);
25788 defsubr (&Scurrent_bidi_paragraph_direction
);
25790 staticpro (&Qmenu_bar_update_hook
);
25791 Qmenu_bar_update_hook
= intern_c_string ("menu-bar-update-hook");
25793 staticpro (&Qoverriding_terminal_local_map
);
25794 Qoverriding_terminal_local_map
= intern_c_string ("overriding-terminal-local-map");
25796 staticpro (&Qoverriding_local_map
);
25797 Qoverriding_local_map
= intern_c_string ("overriding-local-map");
25799 staticpro (&Qwindow_scroll_functions
);
25800 Qwindow_scroll_functions
= intern_c_string ("window-scroll-functions");
25802 staticpro (&Qwindow_text_change_functions
);
25803 Qwindow_text_change_functions
= intern_c_string ("window-text-change-functions");
25805 staticpro (&Qredisplay_end_trigger_functions
);
25806 Qredisplay_end_trigger_functions
= intern_c_string ("redisplay-end-trigger-functions");
25808 staticpro (&Qinhibit_point_motion_hooks
);
25809 Qinhibit_point_motion_hooks
= intern_c_string ("inhibit-point-motion-hooks");
25811 Qeval
= intern_c_string ("eval");
25812 staticpro (&Qeval
);
25814 QCdata
= intern_c_string (":data");
25815 staticpro (&QCdata
);
25816 Qdisplay
= intern_c_string ("display");
25817 staticpro (&Qdisplay
);
25818 Qspace_width
= intern_c_string ("space-width");
25819 staticpro (&Qspace_width
);
25820 Qraise
= intern_c_string ("raise");
25821 staticpro (&Qraise
);
25822 Qslice
= intern_c_string ("slice");
25823 staticpro (&Qslice
);
25824 Qspace
= intern_c_string ("space");
25825 staticpro (&Qspace
);
25826 Qmargin
= intern_c_string ("margin");
25827 staticpro (&Qmargin
);
25828 Qpointer
= intern_c_string ("pointer");
25829 staticpro (&Qpointer
);
25830 Qleft_margin
= intern_c_string ("left-margin");
25831 staticpro (&Qleft_margin
);
25832 Qright_margin
= intern_c_string ("right-margin");
25833 staticpro (&Qright_margin
);
25834 Qcenter
= intern_c_string ("center");
25835 staticpro (&Qcenter
);
25836 Qline_height
= intern_c_string ("line-height");
25837 staticpro (&Qline_height
);
25838 QCalign_to
= intern_c_string (":align-to");
25839 staticpro (&QCalign_to
);
25840 QCrelative_width
= intern_c_string (":relative-width");
25841 staticpro (&QCrelative_width
);
25842 QCrelative_height
= intern_c_string (":relative-height");
25843 staticpro (&QCrelative_height
);
25844 QCeval
= intern_c_string (":eval");
25845 staticpro (&QCeval
);
25846 QCpropertize
= intern_c_string (":propertize");
25847 staticpro (&QCpropertize
);
25848 QCfile
= intern_c_string (":file");
25849 staticpro (&QCfile
);
25850 Qfontified
= intern_c_string ("fontified");
25851 staticpro (&Qfontified
);
25852 Qfontification_functions
= intern_c_string ("fontification-functions");
25853 staticpro (&Qfontification_functions
);
25854 Qtrailing_whitespace
= intern_c_string ("trailing-whitespace");
25855 staticpro (&Qtrailing_whitespace
);
25856 Qescape_glyph
= intern_c_string ("escape-glyph");
25857 staticpro (&Qescape_glyph
);
25858 Qnobreak_space
= intern_c_string ("nobreak-space");
25859 staticpro (&Qnobreak_space
);
25860 Qimage
= intern_c_string ("image");
25861 staticpro (&Qimage
);
25862 Qtext
= intern_c_string ("text");
25863 staticpro (&Qtext
);
25864 Qboth
= intern_c_string ("both");
25865 staticpro (&Qboth
);
25866 Qboth_horiz
= intern_c_string ("both-horiz");
25867 staticpro (&Qboth_horiz
);
25868 Qtext_image_horiz
= intern_c_string ("text-image-horiz");
25869 staticpro (&Qtext_image_horiz
);
25870 QCmap
= intern_c_string (":map");
25871 staticpro (&QCmap
);
25872 QCpointer
= intern_c_string (":pointer");
25873 staticpro (&QCpointer
);
25874 Qrect
= intern_c_string ("rect");
25875 staticpro (&Qrect
);
25876 Qcircle
= intern_c_string ("circle");
25877 staticpro (&Qcircle
);
25878 Qpoly
= intern_c_string ("poly");
25879 staticpro (&Qpoly
);
25880 Qmessage_truncate_lines
= intern_c_string ("message-truncate-lines");
25881 staticpro (&Qmessage_truncate_lines
);
25882 Qgrow_only
= intern_c_string ("grow-only");
25883 staticpro (&Qgrow_only
);
25884 Qinhibit_menubar_update
= intern_c_string ("inhibit-menubar-update");
25885 staticpro (&Qinhibit_menubar_update
);
25886 Qinhibit_eval_during_redisplay
= intern_c_string ("inhibit-eval-during-redisplay");
25887 staticpro (&Qinhibit_eval_during_redisplay
);
25888 Qposition
= intern_c_string ("position");
25889 staticpro (&Qposition
);
25890 Qbuffer_position
= intern_c_string ("buffer-position");
25891 staticpro (&Qbuffer_position
);
25892 Qobject
= intern_c_string ("object");
25893 staticpro (&Qobject
);
25894 Qbar
= intern_c_string ("bar");
25896 Qhbar
= intern_c_string ("hbar");
25897 staticpro (&Qhbar
);
25898 Qbox
= intern_c_string ("box");
25900 Qhollow
= intern_c_string ("hollow");
25901 staticpro (&Qhollow
);
25902 Qhand
= intern_c_string ("hand");
25903 staticpro (&Qhand
);
25904 Qarrow
= intern_c_string ("arrow");
25905 staticpro (&Qarrow
);
25906 Qtext
= intern_c_string ("text");
25907 staticpro (&Qtext
);
25908 Qrisky_local_variable
= intern_c_string ("risky-local-variable");
25909 staticpro (&Qrisky_local_variable
);
25910 Qinhibit_free_realized_faces
= intern_c_string ("inhibit-free-realized-faces");
25911 staticpro (&Qinhibit_free_realized_faces
);
25913 list_of_error
= Fcons (Fcons (intern_c_string ("error"),
25914 Fcons (intern_c_string ("void-variable"), Qnil
)),
25916 staticpro (&list_of_error
);
25918 Qlast_arrow_position
= intern_c_string ("last-arrow-position");
25919 staticpro (&Qlast_arrow_position
);
25920 Qlast_arrow_string
= intern_c_string ("last-arrow-string");
25921 staticpro (&Qlast_arrow_string
);
25923 Qoverlay_arrow_string
= intern_c_string ("overlay-arrow-string");
25924 staticpro (&Qoverlay_arrow_string
);
25925 Qoverlay_arrow_bitmap
= intern_c_string ("overlay-arrow-bitmap");
25926 staticpro (&Qoverlay_arrow_bitmap
);
25928 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
25929 staticpro (&echo_buffer
[0]);
25930 staticpro (&echo_buffer
[1]);
25932 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
25933 staticpro (&echo_area_buffer
[0]);
25934 staticpro (&echo_area_buffer
[1]);
25936 Vmessages_buffer_name
= make_pure_c_string ("*Messages*");
25937 staticpro (&Vmessages_buffer_name
);
25939 mode_line_proptrans_alist
= Qnil
;
25940 staticpro (&mode_line_proptrans_alist
);
25941 mode_line_string_list
= Qnil
;
25942 staticpro (&mode_line_string_list
);
25943 mode_line_string_face
= Qnil
;
25944 staticpro (&mode_line_string_face
);
25945 mode_line_string_face_prop
= Qnil
;
25946 staticpro (&mode_line_string_face_prop
);
25947 Vmode_line_unwind_vector
= Qnil
;
25948 staticpro (&Vmode_line_unwind_vector
);
25950 help_echo_string
= Qnil
;
25951 staticpro (&help_echo_string
);
25952 help_echo_object
= Qnil
;
25953 staticpro (&help_echo_object
);
25954 help_echo_window
= Qnil
;
25955 staticpro (&help_echo_window
);
25956 previous_help_echo_string
= Qnil
;
25957 staticpro (&previous_help_echo_string
);
25958 help_echo_pos
= -1;
25960 Qright_to_left
= intern_c_string ("right-to-left");
25961 staticpro (&Qright_to_left
);
25962 Qleft_to_right
= intern_c_string ("left-to-right");
25963 staticpro (&Qleft_to_right
);
25965 #ifdef HAVE_WINDOW_SYSTEM
25966 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
25967 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
25968 For example, if a block cursor is over a tab, it will be drawn as
25969 wide as that tab on the display. */);
25970 x_stretch_cursor_p
= 0;
25973 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
25974 doc
: /* *Non-nil means highlight trailing whitespace.
25975 The face used for trailing whitespace is `trailing-whitespace'. */);
25976 Vshow_trailing_whitespace
= Qnil
;
25978 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display
,
25979 doc
: /* *Control highlighting of nobreak space and soft hyphen.
25980 A value of t means highlight the character itself (for nobreak space,
25981 use face `nobreak-space').
25982 A value of nil means no highlighting.
25983 Other values mean display the escape glyph followed by an ordinary
25984 space or ordinary hyphen. */);
25985 Vnobreak_char_display
= Qt
;
25987 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer
,
25988 doc
: /* *The pointer shape to show in void text areas.
25989 A value of nil means to show the text pointer. Other options are `arrow',
25990 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
25991 Vvoid_text_area_pointer
= Qarrow
;
25993 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
25994 doc
: /* Non-nil means don't actually do any redisplay.
25995 This is used for internal purposes. */);
25996 Vinhibit_redisplay
= Qnil
;
25998 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
25999 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
26000 Vglobal_mode_string
= Qnil
;
26002 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
26003 doc
: /* Marker for where to display an arrow on top of the buffer text.
26004 This must be the beginning of a line in order to work.
26005 See also `overlay-arrow-string'. */);
26006 Voverlay_arrow_position
= Qnil
;
26008 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
26009 doc
: /* String to display as an arrow in non-window frames.
26010 See also `overlay-arrow-position'. */);
26011 Voverlay_arrow_string
= make_pure_c_string ("=>");
26013 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list
,
26014 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
26015 The symbols on this list are examined during redisplay to determine
26016 where to display overlay arrows. */);
26017 Voverlay_arrow_variable_list
26018 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil
);
26020 DEFVAR_INT ("scroll-step", &scroll_step
,
26021 doc
: /* *The number of lines to try scrolling a window by when point moves out.
26022 If that fails to bring point back on frame, point is centered instead.
26023 If this is zero, point is always centered after it moves off frame.
26024 If you want scrolling to always be a line at a time, you should set
26025 `scroll-conservatively' to a large value rather than set this to 1. */);
26027 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
26028 doc
: /* *Scroll up to this many lines, to bring point back on screen.
26029 If point moves off-screen, redisplay will scroll by up to
26030 `scroll-conservatively' lines in order to bring point just barely
26031 onto the screen again. If that cannot be done, then redisplay
26032 recenters point as usual.
26034 A value of zero means always recenter point if it moves off screen. */);
26035 scroll_conservatively
= 0;
26037 DEFVAR_INT ("scroll-margin", &scroll_margin
,
26038 doc
: /* *Number of lines of margin at the top and bottom of a window.
26039 Recenter the window whenever point gets within this many lines
26040 of the top or bottom of the window. */);
26043 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch
,
26044 doc
: /* Pixels per inch value for non-window system displays.
26045 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
26046 Vdisplay_pixels_per_inch
= make_float (72.0);
26049 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, doc
: /* Don't ask. */);
26052 DEFVAR_LISP ("truncate-partial-width-windows",
26053 &Vtruncate_partial_width_windows
,
26054 doc
: /* Non-nil means truncate lines in windows narrower than the frame.
26055 For an integer value, truncate lines in each window narrower than the
26056 full frame width, provided the window width is less than that integer;
26057 otherwise, respect the value of `truncate-lines'.
26059 For any other non-nil value, truncate lines in all windows that do
26060 not span the full frame width.
26062 A value of nil means to respect the value of `truncate-lines'.
26064 If `word-wrap' is enabled, you might want to reduce this. */);
26065 Vtruncate_partial_width_windows
= make_number (50);
26067 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
26068 doc
: /* When nil, display the mode-line/header-line/menu-bar in the default face.
26069 Any other value means to use the appropriate face, `mode-line',
26070 `header-line', or `menu' respectively. */);
26071 mode_line_inverse_video
= 1;
26073 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
26074 doc
: /* *Maximum buffer size for which line number should be displayed.
26075 If the buffer is bigger than this, the line number does not appear
26076 in the mode line. A value of nil means no limit. */);
26077 Vline_number_display_limit
= Qnil
;
26079 DEFVAR_INT ("line-number-display-limit-width",
26080 &line_number_display_limit_width
,
26081 doc
: /* *Maximum line width (in characters) for line number display.
26082 If the average length of the lines near point is bigger than this, then the
26083 line number may be omitted from the mode line. */);
26084 line_number_display_limit_width
= 200;
26086 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
26087 doc
: /* *Non-nil means highlight region even in nonselected windows. */);
26088 highlight_nonselected_windows
= 0;
26090 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
26091 doc
: /* Non-nil if more than one frame is visible on this display.
26092 Minibuffer-only frames don't count, but iconified frames do.
26093 This variable is not guaranteed to be accurate except while processing
26094 `frame-title-format' and `icon-title-format'. */);
26096 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
26097 doc
: /* Template for displaying the title bar of visible frames.
26098 \(Assuming the window manager supports this feature.)
26100 This variable has the same structure as `mode-line-format', except that
26101 the %c and %l constructs are ignored. It is used only on frames for
26102 which no explicit name has been set \(see `modify-frame-parameters'). */);
26104 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
26105 doc
: /* Template for displaying the title bar of an iconified frame.
26106 \(Assuming the window manager supports this feature.)
26107 This variable has the same structure as `mode-line-format' (which see),
26108 and is used only on frames for which no explicit name has been set
26109 \(see `modify-frame-parameters'). */);
26111 = Vframe_title_format
26112 = pure_cons (intern_c_string ("multiple-frames"),
26113 pure_cons (make_pure_c_string ("%b"),
26114 pure_cons (pure_cons (empty_unibyte_string
,
26115 pure_cons (intern_c_string ("invocation-name"),
26116 pure_cons (make_pure_c_string ("@"),
26117 pure_cons (intern_c_string ("system-name"),
26121 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
26122 doc
: /* Maximum number of lines to keep in the message log buffer.
26123 If nil, disable message logging. If t, log messages but don't truncate
26124 the buffer when it becomes large. */);
26125 Vmessage_log_max
= make_number (100);
26127 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
26128 doc
: /* Functions called before redisplay, if window sizes have changed.
26129 The value should be a list of functions that take one argument.
26130 Just before redisplay, for each frame, if any of its windows have changed
26131 size since the last redisplay, or have been split or deleted,
26132 all the functions in the list are called, with the frame as argument. */);
26133 Vwindow_size_change_functions
= Qnil
;
26135 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
26136 doc
: /* List of functions to call before redisplaying a window with scrolling.
26137 Each function is called with two arguments, the window and its new
26138 display-start position. Note that these functions are also called by
26139 `set-window-buffer'. Also note that the value of `window-end' is not
26140 valid when these functions are called. */);
26141 Vwindow_scroll_functions
= Qnil
;
26143 DEFVAR_LISP ("window-text-change-functions",
26144 &Vwindow_text_change_functions
,
26145 doc
: /* Functions to call in redisplay when text in the window might change. */);
26146 Vwindow_text_change_functions
= Qnil
;
26148 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions
,
26149 doc
: /* Functions called when redisplay of a window reaches the end trigger.
26150 Each function is called with two arguments, the window and the end trigger value.
26151 See `set-window-redisplay-end-trigger'. */);
26152 Vredisplay_end_trigger_functions
= Qnil
;
26154 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window
,
26155 doc
: /* *Non-nil means autoselect window with mouse pointer.
26156 If nil, do not autoselect windows.
26157 A positive number means delay autoselection by that many seconds: a
26158 window is autoselected only after the mouse has remained in that
26159 window for the duration of the delay.
26160 A negative number has a similar effect, but causes windows to be
26161 autoselected only after the mouse has stopped moving. \(Because of
26162 the way Emacs compares mouse events, you will occasionally wait twice
26163 that time before the window gets selected.\)
26164 Any other value means to autoselect window instantaneously when the
26165 mouse pointer enters it.
26167 Autoselection selects the minibuffer only if it is active, and never
26168 unselects the minibuffer if it is active.
26170 When customizing this variable make sure that the actual value of
26171 `focus-follows-mouse' matches the behavior of your window manager. */);
26172 Vmouse_autoselect_window
= Qnil
;
26174 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars
,
26175 doc
: /* *Non-nil means automatically resize tool-bars.
26176 This dynamically changes the tool-bar's height to the minimum height
26177 that is needed to make all tool-bar items visible.
26178 If value is `grow-only', the tool-bar's height is only increased
26179 automatically; to decrease the tool-bar height, use \\[recenter]. */);
26180 Vauto_resize_tool_bars
= Qt
;
26182 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
26183 doc
: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
26184 auto_raise_tool_bar_buttons_p
= 1;
26186 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p
,
26187 doc
: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
26188 make_cursor_line_fully_visible_p
= 1;
26190 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border
,
26191 doc
: /* *Border below tool-bar in pixels.
26192 If an integer, use it as the height of the border.
26193 If it is one of `internal-border-width' or `border-width', use the
26194 value of the corresponding frame parameter.
26195 Otherwise, no border is added below the tool-bar. */);
26196 Vtool_bar_border
= Qinternal_border_width
;
26198 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin
,
26199 doc
: /* *Margin around tool-bar buttons in pixels.
26200 If an integer, use that for both horizontal and vertical margins.
26201 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
26202 HORZ specifying the horizontal margin, and VERT specifying the
26203 vertical margin. */);
26204 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
26206 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
26207 doc
: /* *Relief thickness of tool-bar buttons. */);
26208 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
26210 DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style
,
26211 doc
: /* *Tool bar style to use.
26213 image - show images only
26214 text - show text only
26215 both - show both, text below image
26216 both-horiz - show text to the right of the image
26217 text-image-horiz - show text to the left of the image
26218 any other - use system default or image if no system default. */);
26219 Vtool_bar_style
= Qnil
;
26221 DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size
,
26222 doc
: /* *Maximum number of characters a label can have to be shown.
26223 The tool bar style must also show labels for this to have any effect, see
26224 `tool-bar-style'. */);
26225 tool_bar_max_label_size
= DEFAULT_TOOL_BAR_LABEL_SIZE
;
26227 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
26228 doc
: /* List of functions to call to fontify regions of text.
26229 Each function is called with one argument POS. Functions must
26230 fontify a region starting at POS in the current buffer, and give
26231 fontified regions the property `fontified'. */);
26232 Vfontification_functions
= Qnil
;
26233 Fmake_variable_buffer_local (Qfontification_functions
);
26235 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26236 &unibyte_display_via_language_environment
,
26237 doc
: /* *Non-nil means display unibyte text according to language environment.
26238 Specifically, this means that raw bytes in the range 160-255 decimal
26239 are displayed by converting them to the equivalent multibyte characters
26240 according to the current language environment. As a result, they are
26241 displayed according to the current fontset.
26243 Note that this variable affects only how these bytes are displayed,
26244 but does not change the fact they are interpreted as raw bytes. */);
26245 unibyte_display_via_language_environment
= 0;
26247 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
26248 doc
: /* *Maximum height for resizing mini-windows.
26249 If a float, it specifies a fraction of the mini-window frame's height.
26250 If an integer, it specifies a number of lines. */);
26251 Vmax_mini_window_height
= make_float (0.25);
26253 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
26254 doc
: /* *How to resize mini-windows.
26255 A value of nil means don't automatically resize mini-windows.
26256 A value of t means resize them to fit the text displayed in them.
26257 A value of `grow-only', the default, means let mini-windows grow
26258 only, until their display becomes empty, at which point the windows
26259 go back to their normal size. */);
26260 Vresize_mini_windows
= Qgrow_only
;
26262 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist
,
26263 doc
: /* Alist specifying how to blink the cursor off.
26264 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26265 `cursor-type' frame-parameter or variable equals ON-STATE,
26266 comparing using `equal', Emacs uses OFF-STATE to specify
26267 how to blink it off. ON-STATE and OFF-STATE are values for
26268 the `cursor-type' frame parameter.
26270 If a frame's ON-STATE has no entry in this list,
26271 the frame's other specifications determine how to blink the cursor off. */);
26272 Vblink_cursor_alist
= Qnil
;
26274 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p
,
26275 doc
: /* *Non-nil means scroll the display automatically to make point visible. */);
26276 automatic_hscrolling_p
= 1;
26277 Qauto_hscroll_mode
= intern_c_string ("auto-hscroll-mode");
26278 staticpro (&Qauto_hscroll_mode
);
26280 DEFVAR_INT ("hscroll-margin", &hscroll_margin
,
26281 doc
: /* *How many columns away from the window edge point is allowed to get
26282 before automatic hscrolling will horizontally scroll the window. */);
26283 hscroll_margin
= 5;
26285 DEFVAR_LISP ("hscroll-step", &Vhscroll_step
,
26286 doc
: /* *How many columns to scroll the window when point gets too close to the edge.
26287 When point is less than `hscroll-margin' columns from the window
26288 edge, automatic hscrolling will scroll the window by the amount of columns
26289 determined by this variable. If its value is a positive integer, scroll that
26290 many columns. If it's a positive floating-point number, it specifies the
26291 fraction of the window's width to scroll. If it's nil or zero, point will be
26292 centered horizontally after the scroll. Any other value, including negative
26293 numbers, are treated as if the value were zero.
26295 Automatic hscrolling always moves point outside the scroll margin, so if
26296 point was more than scroll step columns inside the margin, the window will
26297 scroll more than the value given by the scroll step.
26299 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26300 and `scroll-right' overrides this variable's effect. */);
26301 Vhscroll_step
= make_number (0);
26303 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
26304 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
26305 Bind this around calls to `message' to let it take effect. */);
26306 message_truncate_lines
= 0;
26308 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
26309 doc
: /* Normal hook run to update the menu bar definitions.
26310 Redisplay runs this hook before it redisplays the menu bar.
26311 This is used to update submenus such as Buffers,
26312 whose contents depend on various data. */);
26313 Vmenu_bar_update_hook
= Qnil
;
26315 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame
,
26316 doc
: /* Frame for which we are updating a menu.
26317 The enable predicate for a menu binding should check this variable. */);
26318 Vmenu_updating_frame
= Qnil
;
26320 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update
,
26321 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
26322 inhibit_menubar_update
= 0;
26324 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix
,
26325 doc
: /* Prefix prepended to all continuation lines at display time.
26326 The value may be a string, an image, or a stretch-glyph; it is
26327 interpreted in the same way as the value of a `display' text property.
26329 This variable is overridden by any `wrap-prefix' text or overlay
26332 To add a prefix to non-continuation lines, use `line-prefix'. */);
26333 Vwrap_prefix
= Qnil
;
26334 staticpro (&Qwrap_prefix
);
26335 Qwrap_prefix
= intern_c_string ("wrap-prefix");
26336 Fmake_variable_buffer_local (Qwrap_prefix
);
26338 DEFVAR_LISP ("line-prefix", &Vline_prefix
,
26339 doc
: /* Prefix prepended to all non-continuation lines at display time.
26340 The value may be a string, an image, or a stretch-glyph; it is
26341 interpreted in the same way as the value of a `display' text property.
26343 This variable is overridden by any `line-prefix' text or overlay
26346 To add a prefix to continuation lines, use `wrap-prefix'. */);
26347 Vline_prefix
= Qnil
;
26348 staticpro (&Qline_prefix
);
26349 Qline_prefix
= intern_c_string ("line-prefix");
26350 Fmake_variable_buffer_local (Qline_prefix
);
26352 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay
,
26353 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
26354 inhibit_eval_during_redisplay
= 0;
26356 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces
,
26357 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
26358 inhibit_free_realized_faces
= 0;
26361 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id
,
26362 doc
: /* Inhibit try_window_id display optimization. */);
26363 inhibit_try_window_id
= 0;
26365 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing
,
26366 doc
: /* Inhibit try_window_reusing display optimization. */);
26367 inhibit_try_window_reusing
= 0;
26369 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement
,
26370 doc
: /* Inhibit try_cursor_movement display optimization. */);
26371 inhibit_try_cursor_movement
= 0;
26372 #endif /* GLYPH_DEBUG */
26374 DEFVAR_INT ("overline-margin", &overline_margin
,
26375 doc
: /* *Space between overline and text, in pixels.
26376 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
26377 margin to the caracter height. */);
26378 overline_margin
= 2;
26380 DEFVAR_INT ("underline-minimum-offset",
26381 &underline_minimum_offset
,
26382 doc
: /* Minimum distance between baseline and underline.
26383 This can improve legibility of underlined text at small font sizes,
26384 particularly when using variable `x-use-underline-position-properties'
26385 with fonts that specify an UNDERLINE_POSITION relatively close to the
26386 baseline. The default value is 1. */);
26387 underline_minimum_offset
= 1;
26389 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
26390 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
26391 display_hourglass_p
= 1;
26393 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
26394 doc
: /* *Seconds to wait before displaying an hourglass pointer.
26395 Value must be an integer or float. */);
26396 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
26398 hourglass_atimer
= NULL
;
26399 hourglass_shown_p
= 0;
26403 /* Initialize this module when Emacs starts. */
26408 Lisp_Object root_window
;
26409 struct window
*mini_w
;
26411 current_header_line_height
= current_mode_line_height
= -1;
26413 CHARPOS (this_line_start_pos
) = 0;
26415 mini_w
= XWINDOW (minibuf_window
);
26416 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
26418 if (!noninteractive
)
26420 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
26423 XWINDOW (root_window
)->top_line
= make_number (FRAME_TOP_MARGIN (f
));
26424 set_window_height (root_window
,
26425 FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
),
26427 mini_w
->top_line
= make_number (FRAME_LINES (f
) - 1);
26428 set_window_height (minibuf_window
, 1, 0);
26430 XWINDOW (root_window
)->total_cols
= make_number (FRAME_COLS (f
));
26431 mini_w
->total_cols
= make_number (FRAME_COLS (f
));
26433 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
26434 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
26435 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
26437 /* The default ellipsis glyphs `...'. */
26438 for (i
= 0; i
< 3; ++i
)
26439 default_invis_vector
[i
] = make_number ('.');
26443 /* Allocate the buffer for frame titles.
26444 Also used for `format-mode-line'. */
26446 mode_line_noprop_buf
= (char *) xmalloc (size
);
26447 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
26448 mode_line_noprop_ptr
= mode_line_noprop_buf
;
26449 mode_line_target
= MODE_LINE_DISPLAY
;
26452 help_echo_showing_p
= 0;
26455 /* Since w32 does not support atimers, it defines its own implementation of
26456 the following three functions in w32fns.c. */
26459 /* Platform-independent portion of hourglass implementation. */
26461 /* Return non-zero if houglass timer has been started or hourglass is shown. */
26463 hourglass_started (void)
26465 return hourglass_shown_p
|| hourglass_atimer
!= NULL
;
26468 /* Cancel a currently active hourglass timer, and start a new one. */
26470 start_hourglass (void)
26472 #if defined (HAVE_WINDOW_SYSTEM)
26474 int secs
, usecs
= 0;
26476 cancel_hourglass ();
26478 if (INTEGERP (Vhourglass_delay
)
26479 && XINT (Vhourglass_delay
) > 0)
26480 secs
= XFASTINT (Vhourglass_delay
);
26481 else if (FLOATP (Vhourglass_delay
)
26482 && XFLOAT_DATA (Vhourglass_delay
) > 0)
26485 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
26486 secs
= XFASTINT (tem
);
26487 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
26490 secs
= DEFAULT_HOURGLASS_DELAY
;
26492 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
26493 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
26494 show_hourglass
, NULL
);
26499 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
26502 cancel_hourglass (void)
26504 #if defined (HAVE_WINDOW_SYSTEM)
26505 if (hourglass_atimer
)
26507 cancel_atimer (hourglass_atimer
);
26508 hourglass_atimer
= NULL
;
26511 if (hourglass_shown_p
)
26515 #endif /* ! WINDOWSNT */
26517 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
26518 (do not change this comment) */