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. */
228 #include "keyboard.h"
231 #include "termchar.h"
232 #include "dispextern.h"
234 #include "character.h"
237 #include "commands.h"
241 #include "termhooks.h"
242 #include "intervals.h"
245 #include "region-cache.h"
248 #include "blockinput.h"
250 #ifdef HAVE_X_WINDOWS
265 #ifndef FRAME_X_OUTPUT
266 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
269 #define INFINITY 10000000
271 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
272 || defined(HAVE_NS) || defined (USE_GTK)
273 extern void set_frame_menubar (struct frame
*f
, int, int);
276 extern int interrupt_input
;
277 extern int command_loop_level
;
279 extern Lisp_Object do_mouse_tracking
;
281 extern int minibuffer_auto_raise
;
282 extern Lisp_Object Vminibuffer_list
;
284 extern Lisp_Object Qface
;
285 extern Lisp_Object Qmode_line
, Qmode_line_inactive
, Qheader_line
;
287 extern Lisp_Object Voverriding_local_map
;
288 extern Lisp_Object Voverriding_local_map_menu_flag
;
289 extern Lisp_Object Qmenu_item
;
290 extern Lisp_Object Qwhen
;
291 extern Lisp_Object Qhelp_echo
;
292 extern Lisp_Object Qbefore_string
, Qafter_string
;
294 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
295 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
296 Lisp_Object Qwindow_text_change_functions
, Vwindow_text_change_functions
;
297 Lisp_Object Qredisplay_end_trigger_functions
, Vredisplay_end_trigger_functions
;
298 Lisp_Object Qinhibit_point_motion_hooks
;
299 Lisp_Object QCeval
, QCfile
, QCdata
, QCpropertize
;
300 Lisp_Object Qfontified
;
301 Lisp_Object Qgrow_only
;
302 Lisp_Object Qinhibit_eval_during_redisplay
;
303 Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
304 Lisp_Object Qright_to_left
, Qleft_to_right
;
307 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
310 Lisp_Object Qarrow
, Qhand
, Qtext
;
312 Lisp_Object Qrisky_local_variable
;
314 /* Holds the list (error). */
315 Lisp_Object list_of_error
;
317 /* Functions called to fontify regions of text. */
319 Lisp_Object Vfontification_functions
;
320 Lisp_Object Qfontification_functions
;
322 /* Non-nil means automatically select any window when the mouse
323 cursor moves into it. */
324 Lisp_Object Vmouse_autoselect_window
;
326 Lisp_Object Vwrap_prefix
, Qwrap_prefix
;
327 Lisp_Object Vline_prefix
, Qline_prefix
;
329 /* Non-zero means draw tool bar buttons raised when the mouse moves
332 int auto_raise_tool_bar_buttons_p
;
334 /* Non-zero means to reposition window if cursor line is only partially visible. */
336 int make_cursor_line_fully_visible_p
;
338 /* Margin below tool bar in pixels. 0 or nil means no margin.
339 If value is `internal-border-width' or `border-width',
340 the corresponding frame parameter is used. */
342 Lisp_Object Vtool_bar_border
;
344 /* Margin around tool bar buttons in pixels. */
346 Lisp_Object Vtool_bar_button_margin
;
348 /* Thickness of shadow to draw around tool bar buttons. */
350 EMACS_INT tool_bar_button_relief
;
352 /* Non-nil means automatically resize tool-bars so that all tool-bar
353 items are visible, and no blank lines remain.
355 If value is `grow-only', only make tool-bar bigger. */
357 Lisp_Object Vauto_resize_tool_bars
;
359 /* Type of tool bar. Can be symbols image, text, both or both-hroiz. */
361 Lisp_Object Vtool_bar_style
;
363 /* Maximum number of characters a label can have to be shown. */
365 EMACS_INT tool_bar_max_label_size
;
367 /* Non-zero means draw block and hollow cursor as wide as the glyph
368 under it. For example, if a block cursor is over a tab, it will be
369 drawn as wide as that tab on the display. */
371 int x_stretch_cursor_p
;
373 /* Non-nil means don't actually do any redisplay. */
375 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
377 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
379 int inhibit_eval_during_redisplay
;
381 /* Names of text properties relevant for redisplay. */
383 Lisp_Object Qdisplay
;
384 extern Lisp_Object Qface
, Qinvisible
, Qwidth
;
386 /* Symbols used in text property values. */
388 Lisp_Object Vdisplay_pixels_per_inch
;
389 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
390 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qraise
;
393 Lisp_Object Qmargin
, Qpointer
;
394 Lisp_Object Qline_height
;
395 extern Lisp_Object Qheight
;
396 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
397 extern Lisp_Object Qscroll_bar
;
398 extern Lisp_Object Qcursor
;
400 /* Non-nil means highlight trailing whitespace. */
402 Lisp_Object Vshow_trailing_whitespace
;
404 /* Non-nil means escape non-break space and hyphens. */
406 Lisp_Object Vnobreak_char_display
;
408 #ifdef HAVE_WINDOW_SYSTEM
409 extern Lisp_Object Voverflow_newline_into_fringe
;
411 /* Test if overflow newline into fringe. Called with iterator IT
412 at or past right window margin, and with IT->current_x set. */
414 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
415 (!NILP (Voverflow_newline_into_fringe) \
416 && FRAME_WINDOW_P ((IT)->f) \
417 && ((IT)->bidi_it.paragraph_dir == R2L \
418 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
419 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
420 && (IT)->current_x == (IT)->last_visible_x \
421 && (IT)->line_wrap != WORD_WRAP)
423 #else /* !HAVE_WINDOW_SYSTEM */
424 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
425 #endif /* HAVE_WINDOW_SYSTEM */
427 /* Test if the display element loaded in IT is a space or tab
428 character. This is used to determine word wrapping. */
430 #define IT_DISPLAYING_WHITESPACE(it) \
431 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
433 /* Non-nil means show the text cursor in void text areas
434 i.e. in blank areas after eol and eob. This used to be
435 the default in 21.3. */
437 Lisp_Object Vvoid_text_area_pointer
;
439 /* Name of the face used to highlight trailing whitespace. */
441 Lisp_Object Qtrailing_whitespace
;
443 /* Name and number of the face used to highlight escape glyphs. */
445 Lisp_Object Qescape_glyph
;
447 /* Name and number of the face used to highlight non-breaking spaces. */
449 Lisp_Object Qnobreak_space
;
451 /* The symbol `image' which is the car of the lists used to represent
452 images in Lisp. Also a tool bar style. */
456 /* The image map types. */
457 Lisp_Object QCmap
, QCpointer
;
458 Lisp_Object Qrect
, Qcircle
, Qpoly
;
460 /* Tool bar styles */
461 Lisp_Object Qtext
, Qboth
, Qboth_horiz
;
463 /* Non-zero means print newline to stdout before next mini-buffer
466 int noninteractive_need_newline
;
468 /* Non-zero means print newline to message log before next message. */
470 static int message_log_need_newline
;
472 /* Three markers that message_dolog uses.
473 It could allocate them itself, but that causes trouble
474 in handling memory-full errors. */
475 static Lisp_Object message_dolog_marker1
;
476 static Lisp_Object message_dolog_marker2
;
477 static Lisp_Object message_dolog_marker3
;
479 /* The buffer position of the first character appearing entirely or
480 partially on the line of the selected window which contains the
481 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
482 redisplay optimization in redisplay_internal. */
484 static struct text_pos this_line_start_pos
;
486 /* Number of characters past the end of the line above, including the
487 terminating newline. */
489 static struct text_pos this_line_end_pos
;
491 /* The vertical positions and the height of this line. */
493 static int this_line_vpos
;
494 static int this_line_y
;
495 static int this_line_pixel_height
;
497 /* X position at which this display line starts. Usually zero;
498 negative if first character is partially visible. */
500 static int this_line_start_x
;
502 /* Buffer that this_line_.* variables are referring to. */
504 static struct buffer
*this_line_buffer
;
506 /* Nonzero means truncate lines in all windows less wide than the
509 Lisp_Object Vtruncate_partial_width_windows
;
511 /* A flag to control how to display unibyte 8-bit character. */
513 int unibyte_display_via_language_environment
;
515 /* Nonzero means we have more than one non-mini-buffer-only frame.
516 Not guaranteed to be accurate except while parsing
517 frame-title-format. */
521 Lisp_Object Vglobal_mode_string
;
524 /* List of variables (symbols) which hold markers for overlay arrows.
525 The symbols on this list are examined during redisplay to determine
526 where to display overlay arrows. */
528 Lisp_Object Voverlay_arrow_variable_list
;
530 /* Marker for where to display an arrow on top of the buffer text. */
532 Lisp_Object Voverlay_arrow_position
;
534 /* String to display for the arrow. Only used on terminal frames. */
536 Lisp_Object Voverlay_arrow_string
;
538 /* Values of those variables at last redisplay are stored as
539 properties on `overlay-arrow-position' symbol. However, if
540 Voverlay_arrow_position is a marker, last-arrow-position is its
541 numerical position. */
543 Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
545 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
546 properties on a symbol in overlay-arrow-variable-list. */
548 Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
550 /* Like mode-line-format, but for the title bar on a visible frame. */
552 Lisp_Object Vframe_title_format
;
554 /* Like mode-line-format, but for the title bar on an iconified frame. */
556 Lisp_Object Vicon_title_format
;
558 /* List of functions to call when a window's size changes. These
559 functions get one arg, a frame on which one or more windows' sizes
562 static Lisp_Object Vwindow_size_change_functions
;
564 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
566 /* Nonzero if an overlay arrow has been displayed in this window. */
568 static int overlay_arrow_seen
;
570 /* Nonzero means highlight the region even in nonselected windows. */
572 int highlight_nonselected_windows
;
574 /* If cursor motion alone moves point off frame, try scrolling this
575 many lines up or down if that will bring it back. */
577 static EMACS_INT scroll_step
;
579 /* Nonzero means scroll just far enough to bring point back on the
580 screen, when appropriate. */
582 static EMACS_INT scroll_conservatively
;
584 /* Recenter the window whenever point gets within this many lines of
585 the top or bottom of the window. This value is translated into a
586 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
587 that there is really a fixed pixel height scroll margin. */
589 EMACS_INT scroll_margin
;
591 /* Number of windows showing the buffer of the selected window (or
592 another buffer with the same base buffer). keyboard.c refers to
597 /* Vector containing glyphs for an ellipsis `...'. */
599 static Lisp_Object default_invis_vector
[3];
601 /* Zero means display the mode-line/header-line/menu-bar in the default face
602 (this slightly odd definition is for compatibility with previous versions
603 of emacs), non-zero means display them using their respective faces.
605 This variable is deprecated. */
607 int mode_line_inverse_video
;
609 /* Prompt to display in front of the mini-buffer contents. */
611 Lisp_Object minibuf_prompt
;
613 /* Width of current mini-buffer prompt. Only set after display_line
614 of the line that contains the prompt. */
616 int minibuf_prompt_width
;
618 /* This is the window where the echo area message was displayed. It
619 is always a mini-buffer window, but it may not be the same window
620 currently active as a mini-buffer. */
622 Lisp_Object echo_area_window
;
624 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
625 pushes the current message and the value of
626 message_enable_multibyte on the stack, the function restore_message
627 pops the stack and displays MESSAGE again. */
629 Lisp_Object Vmessage_stack
;
631 /* Nonzero means multibyte characters were enabled when the echo area
632 message was specified. */
634 int message_enable_multibyte
;
636 /* Nonzero if we should redraw the mode lines on the next redisplay. */
638 int update_mode_lines
;
640 /* Nonzero if window sizes or contents have changed since last
641 redisplay that finished. */
643 int windows_or_buffers_changed
;
645 /* Nonzero means a frame's cursor type has been changed. */
647 int cursor_type_changed
;
649 /* Nonzero after display_mode_line if %l was used and it displayed a
652 int line_number_displayed
;
654 /* Maximum buffer size for which to display line numbers. */
656 Lisp_Object Vline_number_display_limit
;
658 /* Line width to consider when repositioning for line number display. */
660 static EMACS_INT line_number_display_limit_width
;
662 /* Number of lines to keep in the message log buffer. t means
663 infinite. nil means don't log at all. */
665 Lisp_Object Vmessage_log_max
;
667 /* The name of the *Messages* buffer, a string. */
669 static Lisp_Object Vmessages_buffer_name
;
671 /* Current, index 0, and last displayed echo area message. Either
672 buffers from echo_buffers, or nil to indicate no message. */
674 Lisp_Object echo_area_buffer
[2];
676 /* The buffers referenced from echo_area_buffer. */
678 static Lisp_Object echo_buffer
[2];
680 /* A vector saved used in with_area_buffer to reduce consing. */
682 static Lisp_Object Vwith_echo_area_save_vector
;
684 /* Non-zero means display_echo_area should display the last echo area
685 message again. Set by redisplay_preserve_echo_area. */
687 static int display_last_displayed_message_p
;
689 /* Nonzero if echo area is being used by print; zero if being used by
692 int message_buf_print
;
694 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
696 Lisp_Object Qinhibit_menubar_update
;
697 int inhibit_menubar_update
;
699 /* When evaluating expressions from menu bar items (enable conditions,
700 for instance), this is the frame they are being processed for. */
702 Lisp_Object Vmenu_updating_frame
;
704 /* Maximum height for resizing mini-windows. Either a float
705 specifying a fraction of the available height, or an integer
706 specifying a number of lines. */
708 Lisp_Object Vmax_mini_window_height
;
710 /* Non-zero means messages should be displayed with truncated
711 lines instead of being continued. */
713 int message_truncate_lines
;
714 Lisp_Object Qmessage_truncate_lines
;
716 /* Set to 1 in clear_message to make redisplay_internal aware
717 of an emptied echo area. */
719 static int message_cleared_p
;
721 /* How to blink the default frame cursor off. */
722 Lisp_Object Vblink_cursor_alist
;
724 /* A scratch glyph row with contents used for generating truncation
725 glyphs. Also used in direct_output_for_insert. */
727 #define MAX_SCRATCH_GLYPHS 100
728 struct glyph_row scratch_glyph_row
;
729 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
731 /* Ascent and height of the last line processed by move_it_to. */
733 static int last_max_ascent
, last_height
;
735 /* Non-zero if there's a help-echo in the echo area. */
737 int help_echo_showing_p
;
739 /* If >= 0, computed, exact values of mode-line and header-line height
740 to use in the macros CURRENT_MODE_LINE_HEIGHT and
741 CURRENT_HEADER_LINE_HEIGHT. */
743 int current_mode_line_height
, current_header_line_height
;
745 /* The maximum distance to look ahead for text properties. Values
746 that are too small let us call compute_char_face and similar
747 functions too often which is expensive. Values that are too large
748 let us call compute_char_face and alike too often because we
749 might not be interested in text properties that far away. */
751 #define TEXT_PROP_DISTANCE_LIMIT 100
755 /* Variables to turn off display optimizations from Lisp. */
757 int inhibit_try_window_id
, inhibit_try_window_reusing
;
758 int inhibit_try_cursor_movement
;
760 /* Non-zero means print traces of redisplay if compiled with
763 int trace_redisplay_p
;
765 #endif /* GLYPH_DEBUG */
767 #ifdef DEBUG_TRACE_MOVE
768 /* Non-zero means trace with TRACE_MOVE to stderr. */
771 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
773 #define TRACE_MOVE(x) (void) 0
776 /* Non-zero means automatically scroll windows horizontally to make
779 int automatic_hscrolling_p
;
780 Lisp_Object Qauto_hscroll_mode
;
782 /* How close to the margin can point get before the window is scrolled
784 EMACS_INT hscroll_margin
;
786 /* How much to scroll horizontally when point is inside the above margin. */
787 Lisp_Object Vhscroll_step
;
789 /* The variable `resize-mini-windows'. If nil, don't resize
790 mini-windows. If t, always resize them to fit the text they
791 display. If `grow-only', let mini-windows grow only until they
794 Lisp_Object Vresize_mini_windows
;
796 /* Buffer being redisplayed -- for redisplay_window_error. */
798 struct buffer
*displayed_buffer
;
800 /* Space between overline and text. */
802 EMACS_INT overline_margin
;
804 /* Require underline to be at least this many screen pixels below baseline
805 This to avoid underline "merging" with the base of letters at small
806 font sizes, particularly when x_use_underline_position_properties is on. */
808 EMACS_INT underline_minimum_offset
;
810 /* Value returned from text property handlers (see below). */
815 HANDLED_RECOMPUTE_PROPS
,
816 HANDLED_OVERLAY_STRING_CONSUMED
,
820 /* A description of text properties that redisplay is interested
825 /* The name of the property. */
828 /* A unique index for the property. */
831 /* A handler function called to set up iterator IT from the property
832 at IT's current position. Value is used to steer handle_stop. */
833 enum prop_handled (*handler
) (struct it
*it
);
836 static enum prop_handled
handle_face_prop (struct it
*);
837 static enum prop_handled
handle_invisible_prop (struct it
*);
838 static enum prop_handled
handle_display_prop (struct it
*);
839 static enum prop_handled
handle_composition_prop (struct it
*);
840 static enum prop_handled
handle_overlay_change (struct it
*);
841 static enum prop_handled
handle_fontified_prop (struct it
*);
843 /* Properties handled by iterators. */
845 static struct props it_props
[] =
847 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
848 /* Handle `face' before `display' because some sub-properties of
849 `display' need to know the face. */
850 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
851 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
852 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
853 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
857 /* Value is the position described by X. If X is a marker, value is
858 the marker_position of X. Otherwise, value is X. */
860 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
862 /* Enumeration returned by some move_it_.* functions internally. */
866 /* Not used. Undefined value. */
869 /* Move ended at the requested buffer position or ZV. */
870 MOVE_POS_MATCH_OR_ZV
,
872 /* Move ended at the requested X pixel position. */
875 /* Move within a line ended at the end of a line that must be
879 /* Move within a line ended at the end of a line that would
880 be displayed truncated. */
883 /* Move within a line ended at a line end. */
887 /* This counter is used to clear the face cache every once in a while
888 in redisplay_internal. It is incremented for each redisplay.
889 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
892 #define CLEAR_FACE_CACHE_COUNT 500
893 static int clear_face_cache_count
;
895 /* Similarly for the image cache. */
897 #ifdef HAVE_WINDOW_SYSTEM
898 #define CLEAR_IMAGE_CACHE_COUNT 101
899 static int clear_image_cache_count
;
902 /* Non-zero while redisplay_internal is in progress. */
906 /* Non-zero means don't free realized faces. Bound while freeing
907 realized faces is dangerous because glyph matrices might still
910 int inhibit_free_realized_faces
;
911 Lisp_Object Qinhibit_free_realized_faces
;
913 /* If a string, XTread_socket generates an event to display that string.
914 (The display is done in read_char.) */
916 Lisp_Object help_echo_string
;
917 Lisp_Object help_echo_window
;
918 Lisp_Object help_echo_object
;
921 /* Temporary variable for XTread_socket. */
923 Lisp_Object previous_help_echo_string
;
925 /* Null glyph slice */
927 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
929 /* Platform-independent portion of hourglass implementation. */
931 /* Non-zero means we're allowed to display a hourglass pointer. */
932 int display_hourglass_p
;
934 /* Non-zero means an hourglass cursor is currently shown. */
935 int hourglass_shown_p
;
937 /* If non-null, an asynchronous timer that, when it expires, displays
938 an hourglass cursor on all frames. */
939 struct atimer
*hourglass_atimer
;
941 /* Number of seconds to wait before displaying an hourglass cursor. */
942 Lisp_Object Vhourglass_delay
;
944 /* Default number of seconds to wait before displaying an hourglass
946 #define DEFAULT_HOURGLASS_DELAY 1
949 /* Function prototypes. */
951 static void setup_for_ellipsis (struct it
*, int);
952 static void mark_window_display_accurate_1 (struct window
*, int);
953 static int single_display_spec_string_p (Lisp_Object
, Lisp_Object
);
954 static int display_prop_string_p (Lisp_Object
, Lisp_Object
);
955 static int cursor_row_p (struct window
*, struct glyph_row
*);
956 static int redisplay_mode_lines (Lisp_Object
, int);
957 static char *decode_mode_spec_coding (Lisp_Object
, char *, int);
959 static Lisp_Object
get_it_property (struct it
*it
, Lisp_Object prop
);
961 static void handle_line_prefix (struct it
*);
963 static void pint2str (char *, int, int);
964 static void pint2hrstr (char *, int, int);
965 static struct text_pos
run_window_scroll_functions (Lisp_Object
,
967 static void reconsider_clip_changes (struct window
*, struct buffer
*);
968 static int text_outside_line_unchanged_p (struct window
*, int, int);
969 static void store_mode_line_noprop_char (char);
970 static int store_mode_line_noprop (const unsigned char *, int, int);
971 static void x_consider_frame_title (Lisp_Object
);
972 static void handle_stop (struct it
*);
973 static void handle_stop_backwards (struct it
*, EMACS_INT
);
974 static int tool_bar_lines_needed (struct frame
*, int *);
975 static int single_display_spec_intangible_p (Lisp_Object
);
976 static void ensure_echo_area_buffers (void);
977 static Lisp_Object
unwind_with_echo_area_buffer (Lisp_Object
);
978 static Lisp_Object
with_echo_area_buffer_unwind_data (struct window
*);
979 static int with_echo_area_buffer (struct window
*, int,
980 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
981 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
982 static void clear_garbaged_frames (void);
983 static int current_message_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
984 static int truncate_message_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
985 static int set_message_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
986 static int display_echo_area (struct window
*);
987 static int display_echo_area_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
988 static int resize_mini_window_1 (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
);
989 static Lisp_Object
unwind_redisplay (Lisp_Object
);
990 static int string_char_and_length (const unsigned char *, int *);
991 static struct text_pos
display_prop_end (struct it
*, Lisp_Object
,
993 static int compute_window_start_on_continuation_line (struct window
*);
994 static Lisp_Object
safe_eval_handler (Lisp_Object
);
995 static void insert_left_trunc_glyphs (struct it
*);
996 static struct glyph_row
*get_overlay_arrow_glyph_row (struct window
*,
998 static void extend_face_to_end_of_line (struct it
*);
999 static int append_space_for_newline (struct it
*, int);
1000 static int cursor_row_fully_visible_p (struct window
*, int, int);
1001 static int try_scrolling (Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int);
1002 static int try_cursor_movement (Lisp_Object
, struct text_pos
, int *);
1003 static int trailing_whitespace_p (int);
1004 static int message_log_check_duplicate (int, int, int, int);
1005 static void push_it (struct it
*);
1006 static void pop_it (struct it
*);
1007 static void sync_frame_with_window_matrix_rows (struct window
*);
1008 static void select_frame_for_redisplay (Lisp_Object
);
1009 static void redisplay_internal (int);
1010 static int echo_area_display (int);
1011 static void redisplay_windows (Lisp_Object
);
1012 static void redisplay_window (Lisp_Object
, int);
1013 static Lisp_Object
redisplay_window_error (Lisp_Object
);
1014 static Lisp_Object
redisplay_window_0 (Lisp_Object
);
1015 static Lisp_Object
redisplay_window_1 (Lisp_Object
);
1016 static int update_menu_bar (struct frame
*, int, int);
1017 static int try_window_reusing_current_matrix (struct window
*);
1018 static int try_window_id (struct window
*);
1019 static int display_line (struct it
*);
1020 static int display_mode_lines (struct window
*);
1021 static int display_mode_line (struct window
*, enum face_id
, Lisp_Object
);
1022 static int display_mode_element (struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int);
1023 static int store_mode_line_string (char *, Lisp_Object
, int, int, int, Lisp_Object
);
1024 static char *decode_mode_spec (struct window
*, int, int, int,
1026 static void display_menu_bar (struct window
*);
1027 static int display_count_lines (int, int, int, int, int *);
1028 static int display_string (unsigned char *, Lisp_Object
, Lisp_Object
,
1029 EMACS_INT
, EMACS_INT
, struct it
*, int, int, int, int);
1030 static void compute_line_metrics (struct it
*);
1031 static void run_redisplay_end_trigger_hook (struct it
*);
1032 static int get_overlay_strings (struct it
*, int);
1033 static int get_overlay_strings_1 (struct it
*, int, int);
1034 static void next_overlay_string (struct it
*);
1035 static void reseat (struct it
*, struct text_pos
, int);
1036 static void reseat_1 (struct it
*, struct text_pos
, int);
1037 static void back_to_previous_visible_line_start (struct it
*);
1038 void reseat_at_previous_visible_line_start (struct it
*);
1039 static void reseat_at_next_visible_line_start (struct it
*, int);
1040 static int next_element_from_ellipsis (struct it
*);
1041 static int next_element_from_display_vector (struct it
*);
1042 static int next_element_from_string (struct it
*);
1043 static int next_element_from_c_string (struct it
*);
1044 static int next_element_from_buffer (struct it
*);
1045 static int next_element_from_composition (struct it
*);
1046 static int next_element_from_image (struct it
*);
1047 static int next_element_from_stretch (struct it
*);
1048 static void load_overlay_strings (struct it
*, int);
1049 static int init_from_display_pos (struct it
*, struct window
*,
1050 struct display_pos
*);
1051 static void reseat_to_string (struct it
*, unsigned char *,
1052 Lisp_Object
, int, int, int, int);
1053 static enum move_it_result
1054 move_it_in_display_line_to (struct it
*, EMACS_INT
, int,
1055 enum move_operation_enum
);
1056 void move_it_vertically_backward (struct it
*, int);
1057 static void init_to_row_start (struct it
*, struct window
*,
1058 struct glyph_row
*);
1059 static int init_to_row_end (struct it
*, struct window
*,
1060 struct glyph_row
*);
1061 static void back_to_previous_line_start (struct it
*);
1062 static int forward_to_next_line_start (struct it
*, int *);
1063 static struct text_pos
string_pos_nchars_ahead (struct text_pos
,
1065 static struct text_pos
string_pos (int, Lisp_Object
);
1066 static struct text_pos
c_string_pos (int, unsigned char *, int);
1067 static int number_of_chars (unsigned char *, int);
1068 static void compute_stop_pos (struct it
*);
1069 static void compute_string_pos (struct text_pos
*, struct text_pos
,
1071 static int face_before_or_after_it_pos (struct it
*, int);
1072 static EMACS_INT
next_overlay_change (EMACS_INT
);
1073 static int handle_single_display_spec (struct it
*, Lisp_Object
,
1074 Lisp_Object
, Lisp_Object
,
1075 struct text_pos
*, int);
1076 static int underlying_face_id (struct it
*);
1077 static int in_ellipses_for_invisible_text_p (struct display_pos
*,
1080 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1081 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1083 #ifdef HAVE_WINDOW_SYSTEM
1085 static void update_tool_bar (struct frame
*, int);
1086 static void build_desired_tool_bar_string (struct frame
*f
);
1087 static int redisplay_tool_bar (struct frame
*);
1088 static void display_tool_bar_line (struct it
*, int);
1089 static void notice_overwritten_cursor (struct window
*,
1090 enum glyph_row_area
,
1091 int, int, int, int);
1092 static void append_stretch_glyph (struct it
*, Lisp_Object
,
1097 #endif /* HAVE_WINDOW_SYSTEM */
1100 /***********************************************************************
1101 Window display dimensions
1102 ***********************************************************************/
1104 /* Return the bottom boundary y-position for text lines in window W.
1105 This is the first y position at which a line cannot start.
1106 It is relative to the top of the window.
1108 This is the height of W minus the height of a mode line, if any. */
1111 window_text_bottom_y (struct window
*w
)
1113 int height
= WINDOW_TOTAL_HEIGHT (w
);
1115 if (WINDOW_WANTS_MODELINE_P (w
))
1116 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
1120 /* Return the pixel width of display area AREA of window W. AREA < 0
1121 means return the total width of W, not including fringes to
1122 the left and right of the window. */
1125 window_box_width (struct window
*w
, int area
)
1127 int cols
= XFASTINT (w
->total_cols
);
1130 if (!w
->pseudo_window_p
)
1132 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
1134 if (area
== TEXT_AREA
)
1136 if (INTEGERP (w
->left_margin_cols
))
1137 cols
-= XFASTINT (w
->left_margin_cols
);
1138 if (INTEGERP (w
->right_margin_cols
))
1139 cols
-= XFASTINT (w
->right_margin_cols
);
1140 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
1142 else if (area
== LEFT_MARGIN_AREA
)
1144 cols
= (INTEGERP (w
->left_margin_cols
)
1145 ? XFASTINT (w
->left_margin_cols
) : 0);
1148 else if (area
== RIGHT_MARGIN_AREA
)
1150 cols
= (INTEGERP (w
->right_margin_cols
)
1151 ? XFASTINT (w
->right_margin_cols
) : 0);
1156 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1160 /* Return the pixel height of the display area of window W, not
1161 including mode lines of W, if any. */
1164 window_box_height (struct window
*w
)
1166 struct frame
*f
= XFRAME (w
->frame
);
1167 int height
= WINDOW_TOTAL_HEIGHT (w
);
1169 xassert (height
>= 0);
1171 /* Note: the code below that determines the mode-line/header-line
1172 height is essentially the same as that contained in the macro
1173 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1174 the appropriate glyph row has its `mode_line_p' flag set,
1175 and if it doesn't, uses estimate_mode_line_height instead. */
1177 if (WINDOW_WANTS_MODELINE_P (w
))
1179 struct glyph_row
*ml_row
1180 = (w
->current_matrix
&& w
->current_matrix
->rows
1181 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1183 if (ml_row
&& ml_row
->mode_line_p
)
1184 height
-= ml_row
->height
;
1186 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1189 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1191 struct glyph_row
*hl_row
1192 = (w
->current_matrix
&& w
->current_matrix
->rows
1193 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1195 if (hl_row
&& hl_row
->mode_line_p
)
1196 height
-= hl_row
->height
;
1198 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1201 /* With a very small font and a mode-line that's taller than
1202 default, we might end up with a negative height. */
1203 return max (0, height
);
1206 /* Return the window-relative coordinate of the left edge of display
1207 area AREA of window W. AREA < 0 means return the left edge of the
1208 whole window, to the right of the left fringe of W. */
1211 window_box_left_offset (struct window
*w
, int area
)
1215 if (w
->pseudo_window_p
)
1218 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1220 if (area
== TEXT_AREA
)
1221 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1222 + window_box_width (w
, LEFT_MARGIN_AREA
));
1223 else if (area
== RIGHT_MARGIN_AREA
)
1224 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1225 + window_box_width (w
, LEFT_MARGIN_AREA
)
1226 + window_box_width (w
, TEXT_AREA
)
1227 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1229 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1230 else if (area
== LEFT_MARGIN_AREA
1231 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1232 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1238 /* Return the window-relative coordinate of the right edge of display
1239 area AREA of window W. AREA < 0 means return the left edge of the
1240 whole window, to the left of the right fringe of W. */
1243 window_box_right_offset (struct window
*w
, int area
)
1245 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1248 /* Return the frame-relative coordinate of the left edge of display
1249 area AREA of window W. AREA < 0 means return the left edge of the
1250 whole window, to the right of the left fringe of W. */
1253 window_box_left (struct window
*w
, int area
)
1255 struct frame
*f
= XFRAME (w
->frame
);
1258 if (w
->pseudo_window_p
)
1259 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1261 x
= (WINDOW_LEFT_EDGE_X (w
)
1262 + window_box_left_offset (w
, area
));
1268 /* Return the frame-relative coordinate of the right edge of display
1269 area AREA of window W. AREA < 0 means return the left edge of the
1270 whole window, to the left of the right fringe of W. */
1273 window_box_right (struct window
*w
, int area
)
1275 return window_box_left (w
, area
) + window_box_width (w
, area
);
1278 /* Get the bounding box of the display area AREA of window W, without
1279 mode lines, in frame-relative coordinates. AREA < 0 means the
1280 whole window, not including the left and right fringes of
1281 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1282 coordinates of the upper-left corner of the box. Return in
1283 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1286 window_box (struct window
*w
, int area
, int *box_x
, int *box_y
,
1287 int *box_width
, int *box_height
)
1290 *box_width
= window_box_width (w
, area
);
1292 *box_height
= window_box_height (w
);
1294 *box_x
= window_box_left (w
, area
);
1297 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1298 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1299 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1304 /* Get the bounding box of the display area AREA of window W, without
1305 mode lines. AREA < 0 means the whole window, not including the
1306 left and right fringe of the window. Return in *TOP_LEFT_X
1307 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1308 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1309 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1313 window_box_edges (struct window
*w
, int area
, int *top_left_x
, int *top_left_y
,
1314 int *bottom_right_x
, int *bottom_right_y
)
1316 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1318 *bottom_right_x
+= *top_left_x
;
1319 *bottom_right_y
+= *top_left_y
;
1324 /***********************************************************************
1326 ***********************************************************************/
1328 /* Return the bottom y-position of the line the iterator IT is in.
1329 This can modify IT's settings. */
1332 line_bottom_y (struct it
*it
)
1334 int line_height
= it
->max_ascent
+ it
->max_descent
;
1335 int line_top_y
= it
->current_y
;
1337 if (line_height
== 0)
1340 line_height
= last_height
;
1341 else if (IT_CHARPOS (*it
) < ZV
)
1343 move_it_by_lines (it
, 1, 1);
1344 line_height
= (it
->max_ascent
|| it
->max_descent
1345 ? it
->max_ascent
+ it
->max_descent
1350 struct glyph_row
*row
= it
->glyph_row
;
1352 /* Use the default character height. */
1353 it
->glyph_row
= NULL
;
1354 it
->what
= IT_CHARACTER
;
1357 PRODUCE_GLYPHS (it
);
1358 line_height
= it
->ascent
+ it
->descent
;
1359 it
->glyph_row
= row
;
1363 return line_top_y
+ line_height
;
1367 /* Return 1 if position CHARPOS is visible in window W.
1368 CHARPOS < 0 means return info about WINDOW_END position.
1369 If visible, set *X and *Y to pixel coordinates of top left corner.
1370 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1371 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1374 pos_visible_p (struct window
*w
, int charpos
, int *x
, int *y
,
1375 int *rtop
, int *rbot
, int *rowh
, int *vpos
)
1378 struct text_pos top
;
1380 struct buffer
*old_buffer
= NULL
;
1382 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w
))))
1385 if (XBUFFER (w
->buffer
) != current_buffer
)
1387 old_buffer
= current_buffer
;
1388 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1391 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1393 /* Compute exact mode line heights. */
1394 if (WINDOW_WANTS_MODELINE_P (w
))
1395 current_mode_line_height
1396 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1397 current_buffer
->mode_line_format
);
1399 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1400 current_header_line_height
1401 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1402 current_buffer
->header_line_format
);
1404 start_display (&it
, w
, top
);
1405 move_it_to (&it
, charpos
, -1, it
.last_visible_y
-1, -1,
1406 (charpos
>= 0 ? MOVE_TO_POS
: 0) | MOVE_TO_Y
);
1408 if (charpos
>= 0 && IT_CHARPOS (it
) >= charpos
)
1410 /* We have reached CHARPOS, or passed it. How the call to
1411 move_it_to can overshoot: (i) If CHARPOS is on invisible
1412 text, move_it_to stops at the end of the invisible text,
1413 after CHARPOS. (ii) If CHARPOS is in a display vector,
1414 move_it_to stops on its last glyph. */
1415 int top_x
= it
.current_x
;
1416 int top_y
= it
.current_y
;
1417 enum it_method it_method
= it
.method
;
1418 /* Calling line_bottom_y may change it.method, it.position, etc. */
1419 int bottom_y
= (last_height
= 0, line_bottom_y (&it
));
1420 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1422 if (top_y
< window_top_y
)
1423 visible_p
= bottom_y
> window_top_y
;
1424 else if (top_y
< it
.last_visible_y
)
1428 if (it_method
== GET_FROM_DISPLAY_VECTOR
)
1430 /* We stopped on the last glyph of a display vector.
1431 Try and recompute. Hack alert! */
1432 if (charpos
< 2 || top
.charpos
>= charpos
)
1433 top_x
= it
.glyph_row
->x
;
1437 start_display (&it2
, w
, top
);
1438 move_it_to (&it2
, charpos
- 1, -1, -1, -1, MOVE_TO_POS
);
1439 get_next_display_element (&it2
);
1440 PRODUCE_GLYPHS (&it2
);
1441 if (ITERATOR_AT_END_OF_LINE_P (&it2
)
1442 || it2
.current_x
> it2
.last_visible_x
)
1443 top_x
= it
.glyph_row
->x
;
1446 top_x
= it2
.current_x
;
1447 top_y
= it2
.current_y
;
1453 *y
= max (top_y
+ max (0, it
.max_ascent
- it
.ascent
), window_top_y
);
1454 *rtop
= max (0, window_top_y
- top_y
);
1455 *rbot
= max (0, bottom_y
- it
.last_visible_y
);
1456 *rowh
= max (0, (min (bottom_y
, it
.last_visible_y
)
1457 - max (top_y
, window_top_y
)));
1466 if (IT_CHARPOS (it
) < ZV
&& FETCH_BYTE (IT_BYTEPOS (it
)) != '\n')
1467 move_it_by_lines (&it
, 1, 0);
1468 if (charpos
< IT_CHARPOS (it
)
1469 || (it
.what
== IT_EOB
&& charpos
== IT_CHARPOS (it
)))
1472 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1474 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1475 *rtop
= max (0, -it2
.current_y
);
1476 *rbot
= max (0, ((it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
)
1477 - it
.last_visible_y
));
1478 *rowh
= max (0, (min (it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
,
1480 - max (it2
.current_y
,
1481 WINDOW_HEADER_LINE_HEIGHT (w
))));
1487 set_buffer_internal_1 (old_buffer
);
1489 current_header_line_height
= current_mode_line_height
= -1;
1491 if (visible_p
&& XFASTINT (w
->hscroll
) > 0)
1492 *x
-= XFASTINT (w
->hscroll
) * WINDOW_FRAME_COLUMN_WIDTH (w
);
1495 /* Debugging code. */
1497 fprintf (stderr
, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1498 charpos
, w
->vscroll
, *x
, *y
, *rtop
, *rbot
, *rowh
, *vpos
);
1500 fprintf (stderr
, "-pv pt=%d vs=%d\n", charpos
, w
->vscroll
);
1507 /* Return the next character from STR which is MAXLEN bytes long.
1508 Return in *LEN the length of the character. This is like
1509 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1510 we find one, we return a `?', but with the length of the invalid
1514 string_char_and_length (const unsigned char *str
, int *len
)
1518 c
= STRING_CHAR_AND_LENGTH (str
, *len
);
1519 if (!CHAR_VALID_P (c
, 1))
1520 /* We may not change the length here because other places in Emacs
1521 don't use this function, i.e. they silently accept invalid
1530 /* Given a position POS containing a valid character and byte position
1531 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1533 static struct text_pos
1534 string_pos_nchars_ahead (struct text_pos pos
, Lisp_Object string
, int nchars
)
1536 xassert (STRINGP (string
) && nchars
>= 0);
1538 if (STRING_MULTIBYTE (string
))
1540 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1541 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1546 string_char_and_length (p
, &len
);
1547 p
+= len
, rest
-= len
;
1548 xassert (rest
>= 0);
1550 BYTEPOS (pos
) += len
;
1554 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1560 /* Value is the text position, i.e. character and byte position,
1561 for character position CHARPOS in STRING. */
1563 static INLINE
struct text_pos
1564 string_pos (int charpos
, Lisp_Object string
)
1566 struct text_pos pos
;
1567 xassert (STRINGP (string
));
1568 xassert (charpos
>= 0);
1569 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1574 /* Value is a text position, i.e. character and byte position, for
1575 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1576 means recognize multibyte characters. */
1578 static struct text_pos
1579 c_string_pos (int charpos
, unsigned char *s
, int multibyte_p
)
1581 struct text_pos pos
;
1583 xassert (s
!= NULL
);
1584 xassert (charpos
>= 0);
1588 int rest
= strlen (s
), len
;
1590 SET_TEXT_POS (pos
, 0, 0);
1593 string_char_and_length (s
, &len
);
1594 s
+= len
, rest
-= len
;
1595 xassert (rest
>= 0);
1597 BYTEPOS (pos
) += len
;
1601 SET_TEXT_POS (pos
, charpos
, charpos
);
1607 /* Value is the number of characters in C string S. MULTIBYTE_P
1608 non-zero means recognize multibyte characters. */
1611 number_of_chars (unsigned char *s
, int multibyte_p
)
1617 int rest
= strlen (s
), len
;
1618 unsigned char *p
= (unsigned char *) s
;
1620 for (nchars
= 0; rest
> 0; ++nchars
)
1622 string_char_and_length (p
, &len
);
1623 rest
-= len
, p
+= len
;
1627 nchars
= strlen (s
);
1633 /* Compute byte position NEWPOS->bytepos corresponding to
1634 NEWPOS->charpos. POS is a known position in string STRING.
1635 NEWPOS->charpos must be >= POS.charpos. */
1638 compute_string_pos (struct text_pos
*newpos
, struct text_pos pos
, Lisp_Object string
)
1640 xassert (STRINGP (string
));
1641 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1643 if (STRING_MULTIBYTE (string
))
1644 *newpos
= string_pos_nchars_ahead (pos
, string
,
1645 CHARPOS (*newpos
) - CHARPOS (pos
));
1647 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1651 Return an estimation of the pixel height of mode or header lines on
1652 frame F. FACE_ID specifies what line's height to estimate. */
1655 estimate_mode_line_height (struct frame
*f
, enum face_id face_id
)
1657 #ifdef HAVE_WINDOW_SYSTEM
1658 if (FRAME_WINDOW_P (f
))
1660 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1662 /* This function is called so early when Emacs starts that the face
1663 cache and mode line face are not yet initialized. */
1664 if (FRAME_FACE_CACHE (f
))
1666 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1670 height
= FONT_HEIGHT (face
->font
);
1671 if (face
->box_line_width
> 0)
1672 height
+= 2 * face
->box_line_width
;
1683 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1684 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1685 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1686 not force the value into range. */
1689 pixel_to_glyph_coords (FRAME_PTR f
, register int pix_x
, register int pix_y
,
1690 int *x
, int *y
, NativeRectangle
*bounds
, int noclip
)
1693 #ifdef HAVE_WINDOW_SYSTEM
1694 if (FRAME_WINDOW_P (f
))
1696 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1697 even for negative values. */
1699 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1701 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1703 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1704 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1707 STORE_NATIVE_RECT (*bounds
,
1708 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1709 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1710 FRAME_COLUMN_WIDTH (f
) - 1,
1711 FRAME_LINE_HEIGHT (f
) - 1);
1717 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1718 pix_x
= FRAME_TOTAL_COLS (f
);
1722 else if (pix_y
> FRAME_LINES (f
))
1723 pix_y
= FRAME_LINES (f
);
1733 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1734 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1735 can't tell the positions because W's display is not up to date,
1739 glyph_to_pixel_coords (struct window
*w
, int hpos
, int vpos
,
1740 int *frame_x
, int *frame_y
)
1742 #ifdef HAVE_WINDOW_SYSTEM
1743 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1747 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1748 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1750 if (display_completed
)
1752 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1753 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1754 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1760 hpos
+= glyph
->pixel_width
;
1764 /* If first glyph is partially visible, its first visible position is still 0. */
1776 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1777 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1788 #ifdef HAVE_WINDOW_SYSTEM
1790 /* Find the glyph under window-relative coordinates X/Y in window W.
1791 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1792 strings. Return in *HPOS and *VPOS the row and column number of
1793 the glyph found. Return in *AREA the glyph area containing X.
1794 Value is a pointer to the glyph found or null if X/Y is not on
1795 text, or we can't tell because W's current matrix is not up to
1800 x_y_to_hpos_vpos (struct window
*w
, int x
, int y
, int *hpos
, int *vpos
,
1801 int *dx
, int *dy
, int *area
)
1803 struct glyph
*glyph
, *end
;
1804 struct glyph_row
*row
= NULL
;
1807 /* Find row containing Y. Give up if some row is not enabled. */
1808 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1810 row
= MATRIX_ROW (w
->current_matrix
, i
);
1811 if (!row
->enabled_p
)
1813 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1820 /* Give up if Y is not in the window. */
1821 if (i
== w
->current_matrix
->nrows
)
1824 /* Get the glyph area containing X. */
1825 if (w
->pseudo_window_p
)
1832 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1834 *area
= LEFT_MARGIN_AREA
;
1835 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1837 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1840 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1844 *area
= RIGHT_MARGIN_AREA
;
1845 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1849 /* Find glyph containing X. */
1850 glyph
= row
->glyphs
[*area
];
1851 end
= glyph
+ row
->used
[*area
];
1853 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1855 x
-= glyph
->pixel_width
;
1865 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1868 *hpos
= glyph
- row
->glyphs
[*area
];
1874 Convert frame-relative x/y to coordinates relative to window W.
1875 Takes pseudo-windows into account. */
1878 frame_to_window_pixel_xy (struct window
*w
, int *x
, int *y
)
1880 if (w
->pseudo_window_p
)
1882 /* A pseudo-window is always full-width, and starts at the
1883 left edge of the frame, plus a frame border. */
1884 struct frame
*f
= XFRAME (w
->frame
);
1885 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1886 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1890 *x
-= WINDOW_LEFT_EDGE_X (w
);
1891 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1896 Return in RECTS[] at most N clipping rectangles for glyph string S.
1897 Return the number of stored rectangles. */
1900 get_glyph_string_clip_rects (struct glyph_string
*s
, NativeRectangle
*rects
, int n
)
1907 if (s
->row
->full_width_p
)
1909 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1910 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1911 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1913 /* Unless displaying a mode or menu bar line, which are always
1914 fully visible, clip to the visible part of the row. */
1915 if (s
->w
->pseudo_window_p
)
1916 r
.height
= s
->row
->visible_height
;
1918 r
.height
= s
->height
;
1922 /* This is a text line that may be partially visible. */
1923 r
.x
= window_box_left (s
->w
, s
->area
);
1924 r
.width
= window_box_width (s
->w
, s
->area
);
1925 r
.height
= s
->row
->visible_height
;
1929 if (r
.x
< s
->clip_head
->x
)
1931 if (r
.width
>= s
->clip_head
->x
- r
.x
)
1932 r
.width
-= s
->clip_head
->x
- r
.x
;
1935 r
.x
= s
->clip_head
->x
;
1938 if (r
.x
+ r
.width
> s
->clip_tail
->x
+ s
->clip_tail
->background_width
)
1940 if (s
->clip_tail
->x
+ s
->clip_tail
->background_width
>= r
.x
)
1941 r
.width
= s
->clip_tail
->x
+ s
->clip_tail
->background_width
- r
.x
;
1946 /* If S draws overlapping rows, it's sufficient to use the top and
1947 bottom of the window for clipping because this glyph string
1948 intentionally draws over other lines. */
1949 if (s
->for_overlaps
)
1951 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1952 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1954 /* Alas, the above simple strategy does not work for the
1955 environments with anti-aliased text: if the same text is
1956 drawn onto the same place multiple times, it gets thicker.
1957 If the overlap we are processing is for the erased cursor, we
1958 take the intersection with the rectagle of the cursor. */
1959 if (s
->for_overlaps
& OVERLAPS_ERASED_CURSOR
)
1961 XRectangle rc
, r_save
= r
;
1963 rc
.x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (s
->w
, s
->w
->phys_cursor
.x
);
1964 rc
.y
= s
->w
->phys_cursor
.y
;
1965 rc
.width
= s
->w
->phys_cursor_width
;
1966 rc
.height
= s
->w
->phys_cursor_height
;
1968 x_intersect_rectangles (&r_save
, &rc
, &r
);
1973 /* Don't use S->y for clipping because it doesn't take partially
1974 visible lines into account. For example, it can be negative for
1975 partially visible lines at the top of a window. */
1976 if (!s
->row
->full_width_p
1977 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1978 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1980 r
.y
= max (0, s
->row
->y
);
1983 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1985 /* If drawing the cursor, don't let glyph draw outside its
1986 advertised boundaries. Cleartype does this under some circumstances. */
1987 if (s
->hl
== DRAW_CURSOR
)
1989 struct glyph
*glyph
= s
->first_glyph
;
1994 r
.width
-= s
->x
- r
.x
;
1997 r
.width
= min (r
.width
, glyph
->pixel_width
);
1999 /* If r.y is below window bottom, ensure that we still see a cursor. */
2000 height
= min (glyph
->ascent
+ glyph
->descent
,
2001 min (FRAME_LINE_HEIGHT (s
->f
), s
->row
->visible_height
));
2002 max_y
= window_text_bottom_y (s
->w
) - height
;
2003 max_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, max_y
);
2004 if (s
->ybase
- glyph
->ascent
> max_y
)
2011 /* Don't draw cursor glyph taller than our actual glyph. */
2012 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
2013 if (height
< r
.height
)
2015 max_y
= r
.y
+ r
.height
;
2016 r
.y
= min (max_y
, max (r
.y
, s
->ybase
+ glyph
->descent
- height
));
2017 r
.height
= min (max_y
- r
.y
, height
);
2024 XRectangle r_save
= r
;
2026 if (! x_intersect_rectangles (&r_save
, s
->row
->clip
, &r
))
2030 if ((s
->for_overlaps
& OVERLAPS_BOTH
) == 0
2031 || ((s
->for_overlaps
& OVERLAPS_BOTH
) == OVERLAPS_BOTH
&& n
== 1))
2033 #ifdef CONVERT_FROM_XRECT
2034 CONVERT_FROM_XRECT (r
, *rects
);
2042 /* If we are processing overlapping and allowed to return
2043 multiple clipping rectangles, we exclude the row of the glyph
2044 string from the clipping rectangle. This is to avoid drawing
2045 the same text on the environment with anti-aliasing. */
2046 #ifdef CONVERT_FROM_XRECT
2049 XRectangle
*rs
= rects
;
2051 int i
= 0, row_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, s
->row
->y
);
2053 if (s
->for_overlaps
& OVERLAPS_PRED
)
2056 if (r
.y
+ r
.height
> row_y
)
2059 rs
[i
].height
= row_y
- r
.y
;
2065 if (s
->for_overlaps
& OVERLAPS_SUCC
)
2068 if (r
.y
< row_y
+ s
->row
->visible_height
)
2070 if (r
.y
+ r
.height
> row_y
+ s
->row
->visible_height
)
2072 rs
[i
].y
= row_y
+ s
->row
->visible_height
;
2073 rs
[i
].height
= r
.y
+ r
.height
- rs
[i
].y
;
2082 #ifdef CONVERT_FROM_XRECT
2083 for (i
= 0; i
< n
; i
++)
2084 CONVERT_FROM_XRECT (rs
[i
], rects
[i
]);
2091 Return in *NR the clipping rectangle for glyph string S. */
2094 get_glyph_string_clip_rect (struct glyph_string
*s
, NativeRectangle
*nr
)
2096 get_glyph_string_clip_rects (s
, nr
, 1);
2101 Return the position and height of the phys cursor in window W.
2102 Set w->phys_cursor_width to width of phys cursor.
2106 get_phys_cursor_geometry (struct window
*w
, struct glyph_row
*row
,
2107 struct glyph
*glyph
, int *xp
, int *yp
, int *heightp
)
2109 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2110 int x
, y
, wd
, h
, h0
, y0
;
2112 /* Compute the width of the rectangle to draw. If on a stretch
2113 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2114 rectangle as wide as the glyph, but use a canonical character
2116 wd
= glyph
->pixel_width
- 1;
2117 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2121 x
= w
->phys_cursor
.x
;
2128 if (glyph
->type
== STRETCH_GLYPH
2129 && !x_stretch_cursor_p
)
2130 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
2131 w
->phys_cursor_width
= wd
;
2133 y
= w
->phys_cursor
.y
+ row
->ascent
- glyph
->ascent
;
2135 /* If y is below window bottom, ensure that we still see a cursor. */
2136 h0
= min (FRAME_LINE_HEIGHT (f
), row
->visible_height
);
2138 h
= max (h0
, glyph
->ascent
+ glyph
->descent
);
2139 h0
= min (h0
, glyph
->ascent
+ glyph
->descent
);
2141 y0
= WINDOW_HEADER_LINE_HEIGHT (w
);
2144 h
= max (h
- (y0
- y
) + 1, h0
);
2149 y0
= window_text_bottom_y (w
) - h0
;
2157 *xp
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, x
);
2158 *yp
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
);
2163 * Remember which glyph the mouse is over.
2167 remember_mouse_glyph (struct frame
*f
, int gx
, int gy
, NativeRectangle
*rect
)
2171 struct glyph_row
*r
, *gr
, *end_row
;
2172 enum window_part part
;
2173 enum glyph_row_area area
;
2174 int x
, y
, width
, height
;
2176 /* Try to determine frame pixel position and size of the glyph under
2177 frame pixel coordinates X/Y on frame F. */
2179 if (!f
->glyphs_initialized_p
2180 || (window
= window_from_coordinates (f
, gx
, gy
, &part
, &x
, &y
, 0),
2183 width
= FRAME_SMALLEST_CHAR_WIDTH (f
);
2184 height
= FRAME_SMALLEST_FONT_HEIGHT (f
);
2188 w
= XWINDOW (window
);
2189 width
= WINDOW_FRAME_COLUMN_WIDTH (w
);
2190 height
= WINDOW_FRAME_LINE_HEIGHT (w
);
2192 r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
2193 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
2195 if (w
->pseudo_window_p
)
2198 part
= ON_MODE_LINE
; /* Don't adjust margin. */
2204 case ON_LEFT_MARGIN
:
2205 area
= LEFT_MARGIN_AREA
;
2208 case ON_RIGHT_MARGIN
:
2209 area
= RIGHT_MARGIN_AREA
;
2212 case ON_HEADER_LINE
:
2214 gr
= (part
== ON_HEADER_LINE
2215 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
2216 : MATRIX_MODE_LINE_ROW (w
->current_matrix
));
2219 goto text_glyph_row_found
;
2226 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2227 if (r
->y
+ r
->height
> y
)
2233 text_glyph_row_found
:
2236 struct glyph
*g
= gr
->glyphs
[area
];
2237 struct glyph
*end
= g
+ gr
->used
[area
];
2239 height
= gr
->height
;
2240 for (gx
= gr
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
2241 if (gx
+ g
->pixel_width
> x
)
2246 if (g
->type
== IMAGE_GLYPH
)
2248 /* Don't remember when mouse is over image, as
2249 image may have hot-spots. */
2250 STORE_NATIVE_RECT (*rect
, 0, 0, 0, 0);
2253 width
= g
->pixel_width
;
2257 /* Use nominal char spacing at end of line. */
2259 gx
+= (x
/ width
) * width
;
2262 if (part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
)
2263 gx
+= window_box_left_offset (w
, area
);
2267 /* Use nominal line height at end of window. */
2268 gx
= (x
/ width
) * width
;
2270 gy
+= (y
/ height
) * height
;
2274 case ON_LEFT_FRINGE
:
2275 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2276 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
)
2277 : window_box_right_offset (w
, LEFT_MARGIN_AREA
));
2278 width
= WINDOW_LEFT_FRINGE_WIDTH (w
);
2281 case ON_RIGHT_FRINGE
:
2282 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2283 ? window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2284 : window_box_right_offset (w
, TEXT_AREA
));
2285 width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
2289 gx
= (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
2291 : (window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2292 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2293 ? WINDOW_RIGHT_FRINGE_WIDTH (w
)
2295 width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
2299 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2300 if (r
->y
+ r
->height
> y
)
2307 height
= gr
->height
;
2310 /* Use nominal line height at end of window. */
2312 gy
+= (y
/ height
) * height
;
2319 /* If there is no glyph under the mouse, then we divide the screen
2320 into a grid of the smallest glyph in the frame, and use that
2323 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2324 round down even for negative values. */
2330 gx
= (gx
/ width
) * width
;
2331 gy
= (gy
/ height
) * height
;
2336 gx
+= WINDOW_LEFT_EDGE_X (w
);
2337 gy
+= WINDOW_TOP_EDGE_Y (w
);
2340 STORE_NATIVE_RECT (*rect
, gx
, gy
, width
, height
);
2342 /* Visible feedback for debugging. */
2345 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2346 f
->output_data
.x
->normal_gc
,
2347 gx
, gy
, width
, height
);
2353 #endif /* HAVE_WINDOW_SYSTEM */
2356 /***********************************************************************
2357 Lisp form evaluation
2358 ***********************************************************************/
2360 /* Error handler for safe_eval and safe_call. */
2363 safe_eval_handler (Lisp_Object arg
)
2365 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
2370 /* Evaluate SEXPR and return the result, or nil if something went
2371 wrong. Prevent redisplay during the evaluation. */
2373 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2374 Return the result, or nil if something went wrong. Prevent
2375 redisplay during the evaluation. */
2378 safe_call (int nargs
, Lisp_Object
*args
)
2382 if (inhibit_eval_during_redisplay
)
2386 int count
= SPECPDL_INDEX ();
2387 struct gcpro gcpro1
;
2390 gcpro1
.nvars
= nargs
;
2391 specbind (Qinhibit_redisplay
, Qt
);
2392 /* Use Qt to ensure debugger does not run,
2393 so there is no possibility of wanting to redisplay. */
2394 val
= internal_condition_case_n (Ffuncall
, nargs
, args
, Qt
,
2397 val
= unbind_to (count
, val
);
2404 /* Call function FN with one argument ARG.
2405 Return the result, or nil if something went wrong. */
2408 safe_call1 (Lisp_Object fn
, Lisp_Object arg
)
2410 Lisp_Object args
[2];
2413 return safe_call (2, args
);
2416 static Lisp_Object Qeval
;
2419 safe_eval (Lisp_Object sexpr
)
2421 return safe_call1 (Qeval
, sexpr
);
2424 /* Call function FN with one argument ARG.
2425 Return the result, or nil if something went wrong. */
2428 safe_call2 (Lisp_Object fn
, Lisp_Object arg1
, Lisp_Object arg2
)
2430 Lisp_Object args
[3];
2434 return safe_call (3, args
);
2439 /***********************************************************************
2441 ***********************************************************************/
2445 /* Define CHECK_IT to perform sanity checks on iterators.
2446 This is for debugging. It is too slow to do unconditionally. */
2452 if (it
->method
== GET_FROM_STRING
)
2454 xassert (STRINGP (it
->string
));
2455 xassert (IT_STRING_CHARPOS (*it
) >= 0);
2459 xassert (IT_STRING_CHARPOS (*it
) < 0);
2460 if (it
->method
== GET_FROM_BUFFER
)
2462 /* Check that character and byte positions agree. */
2463 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
2468 xassert (it
->current
.dpvec_index
>= 0);
2470 xassert (it
->current
.dpvec_index
< 0);
2473 #define CHECK_IT(IT) check_it ((IT))
2477 #define CHECK_IT(IT) (void) 0
2484 /* Check that the window end of window W is what we expect it
2485 to be---the last row in the current matrix displaying text. */
2488 check_window_end (w
)
2491 if (!MINI_WINDOW_P (w
)
2492 && !NILP (w
->window_end_valid
))
2494 struct glyph_row
*row
;
2495 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
2496 XFASTINT (w
->window_end_vpos
)),
2498 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
2499 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
2503 #define CHECK_WINDOW_END(W) check_window_end ((W))
2505 #else /* not GLYPH_DEBUG */
2507 #define CHECK_WINDOW_END(W) (void) 0
2509 #endif /* not GLYPH_DEBUG */
2513 /***********************************************************************
2514 Iterator initialization
2515 ***********************************************************************/
2517 /* Initialize IT for displaying current_buffer in window W, starting
2518 at character position CHARPOS. CHARPOS < 0 means that no buffer
2519 position is specified which is useful when the iterator is assigned
2520 a position later. BYTEPOS is the byte position corresponding to
2521 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2523 If ROW is not null, calls to produce_glyphs with IT as parameter
2524 will produce glyphs in that row.
2526 BASE_FACE_ID is the id of a base face to use. It must be one of
2527 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2528 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2529 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2531 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2532 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2533 will be initialized to use the corresponding mode line glyph row of
2534 the desired matrix of W. */
2537 init_iterator (struct it
*it
, struct window
*w
,
2538 EMACS_INT charpos
, EMACS_INT bytepos
,
2539 struct glyph_row
*row
, enum face_id base_face_id
)
2541 int highlight_region_p
;
2542 enum face_id remapped_base_face_id
= base_face_id
;
2544 /* Some precondition checks. */
2545 xassert (w
!= NULL
&& it
!= NULL
);
2546 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2549 /* If face attributes have been changed since the last redisplay,
2550 free realized faces now because they depend on face definitions
2551 that might have changed. Don't free faces while there might be
2552 desired matrices pending which reference these faces. */
2553 if (face_change_count
&& !inhibit_free_realized_faces
)
2555 face_change_count
= 0;
2556 free_all_realized_faces (Qnil
);
2559 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2560 if (! NILP (Vface_remapping_alist
))
2561 remapped_base_face_id
= lookup_basic_face (XFRAME (w
->frame
), base_face_id
);
2563 /* Use one of the mode line rows of W's desired matrix if
2567 if (base_face_id
== MODE_LINE_FACE_ID
2568 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2569 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2570 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2571 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2575 memset (it
, 0, sizeof *it
);
2576 it
->current
.overlay_string_index
= -1;
2577 it
->current
.dpvec_index
= -1;
2578 it
->base_face_id
= remapped_base_face_id
;
2580 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2582 /* The window in which we iterate over current_buffer: */
2583 XSETWINDOW (it
->window
, w
);
2585 it
->f
= XFRAME (w
->frame
);
2589 /* Extra space between lines (on window systems only). */
2590 if (base_face_id
== DEFAULT_FACE_ID
2591 && FRAME_WINDOW_P (it
->f
))
2593 if (NATNUMP (current_buffer
->extra_line_spacing
))
2594 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2595 else if (FLOATP (current_buffer
->extra_line_spacing
))
2596 it
->extra_line_spacing
= (XFLOAT_DATA (current_buffer
->extra_line_spacing
)
2597 * FRAME_LINE_HEIGHT (it
->f
));
2598 else if (it
->f
->extra_line_spacing
> 0)
2599 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2600 it
->max_extra_line_spacing
= 0;
2603 /* If realized faces have been removed, e.g. because of face
2604 attribute changes of named faces, recompute them. When running
2605 in batch mode, the face cache of the initial frame is null. If
2606 we happen to get called, make a dummy face cache. */
2607 if (FRAME_FACE_CACHE (it
->f
) == NULL
)
2608 init_frame_faces (it
->f
);
2609 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2610 recompute_basic_faces (it
->f
);
2612 /* Current value of the `slice', `space-width', and 'height' properties. */
2613 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2614 it
->space_width
= Qnil
;
2615 it
->font_height
= Qnil
;
2616 it
->override_ascent
= -1;
2618 /* Are control characters displayed as `^C'? */
2619 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2621 /* -1 means everything between a CR and the following line end
2622 is invisible. >0 means lines indented more than this value are
2624 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2625 ? XFASTINT (current_buffer
->selective_display
)
2626 : (!NILP (current_buffer
->selective_display
)
2628 it
->selective_display_ellipsis_p
2629 = !NILP (current_buffer
->selective_display_ellipses
);
2631 /* Display table to use. */
2632 it
->dp
= window_display_table (w
);
2634 /* Are multibyte characters enabled in current_buffer? */
2635 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2637 /* Do we need to reorder bidirectional text? Not if this is a
2638 unibyte buffer: by definition, none of the single-byte characters
2639 are strong R2L, so no reordering is needed. And bidi.c doesn't
2640 support unibyte buffers anyway. */
2642 = !NILP (current_buffer
->bidi_display_reordering
) && it
->multibyte_p
;
2644 /* Non-zero if we should highlight the region. */
2646 = (!NILP (Vtransient_mark_mode
)
2647 && !NILP (current_buffer
->mark_active
)
2648 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2650 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2651 start and end of a visible region in window IT->w. Set both to
2652 -1 to indicate no region. */
2653 if (highlight_region_p
2654 /* Maybe highlight only in selected window. */
2655 && (/* Either show region everywhere. */
2656 highlight_nonselected_windows
2657 /* Or show region in the selected window. */
2658 || w
== XWINDOW (selected_window
)
2659 /* Or show the region if we are in the mini-buffer and W is
2660 the window the mini-buffer refers to. */
2661 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2662 && WINDOWP (minibuf_selected_window
)
2663 && w
== XWINDOW (minibuf_selected_window
))))
2665 int charpos
= marker_position (current_buffer
->mark
);
2666 it
->region_beg_charpos
= min (PT
, charpos
);
2667 it
->region_end_charpos
= max (PT
, charpos
);
2670 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2672 /* Get the position at which the redisplay_end_trigger hook should
2673 be run, if it is to be run at all. */
2674 if (MARKERP (w
->redisplay_end_trigger
)
2675 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2676 it
->redisplay_end_trigger_charpos
2677 = marker_position (w
->redisplay_end_trigger
);
2678 else if (INTEGERP (w
->redisplay_end_trigger
))
2679 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2681 /* Correct bogus values of tab_width. */
2682 it
->tab_width
= XINT (current_buffer
->tab_width
);
2683 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2686 /* Are lines in the display truncated? */
2687 if (base_face_id
!= DEFAULT_FACE_ID
2688 || XINT (it
->w
->hscroll
)
2689 || (! WINDOW_FULL_WIDTH_P (it
->w
)
2690 && ((!NILP (Vtruncate_partial_width_windows
)
2691 && !INTEGERP (Vtruncate_partial_width_windows
))
2692 || (INTEGERP (Vtruncate_partial_width_windows
)
2693 && (WINDOW_TOTAL_COLS (it
->w
)
2694 < XINT (Vtruncate_partial_width_windows
))))))
2695 it
->line_wrap
= TRUNCATE
;
2696 else if (NILP (current_buffer
->truncate_lines
))
2697 it
->line_wrap
= NILP (current_buffer
->word_wrap
)
2698 ? WINDOW_WRAP
: WORD_WRAP
;
2700 it
->line_wrap
= TRUNCATE
;
2702 /* Get dimensions of truncation and continuation glyphs. These are
2703 displayed as fringe bitmaps under X, so we don't need them for such
2705 if (!FRAME_WINDOW_P (it
->f
))
2707 if (it
->line_wrap
== TRUNCATE
)
2709 /* We will need the truncation glyph. */
2710 xassert (it
->glyph_row
== NULL
);
2711 produce_special_glyphs (it
, IT_TRUNCATION
);
2712 it
->truncation_pixel_width
= it
->pixel_width
;
2716 /* We will need the continuation glyph. */
2717 xassert (it
->glyph_row
== NULL
);
2718 produce_special_glyphs (it
, IT_CONTINUATION
);
2719 it
->continuation_pixel_width
= it
->pixel_width
;
2722 /* Reset these values to zero because the produce_special_glyphs
2723 above has changed them. */
2724 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2725 it
->phys_ascent
= it
->phys_descent
= 0;
2728 /* Set this after getting the dimensions of truncation and
2729 continuation glyphs, so that we don't produce glyphs when calling
2730 produce_special_glyphs, above. */
2731 it
->glyph_row
= row
;
2732 it
->area
= TEXT_AREA
;
2734 /* Forget any previous info about this row being reversed. */
2736 it
->glyph_row
->reversed_p
= 0;
2738 /* Get the dimensions of the display area. The display area
2739 consists of the visible window area plus a horizontally scrolled
2740 part to the left of the window. All x-values are relative to the
2741 start of this total display area. */
2742 if (base_face_id
!= DEFAULT_FACE_ID
)
2744 /* Mode lines, menu bar in terminal frames. */
2745 it
->first_visible_x
= 0;
2746 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2751 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2752 it
->last_visible_x
= (it
->first_visible_x
2753 + window_box_width (w
, TEXT_AREA
));
2755 /* If we truncate lines, leave room for the truncator glyph(s) at
2756 the right margin. Otherwise, leave room for the continuation
2757 glyph(s). Truncation and continuation glyphs are not inserted
2758 for window-based redisplay. */
2759 if (!FRAME_WINDOW_P (it
->f
))
2761 if (it
->line_wrap
== TRUNCATE
)
2762 it
->last_visible_x
-= it
->truncation_pixel_width
;
2764 it
->last_visible_x
-= it
->continuation_pixel_width
;
2767 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2768 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2771 /* Leave room for a border glyph. */
2772 if (!FRAME_WINDOW_P (it
->f
)
2773 && !WINDOW_RIGHTMOST_P (it
->w
))
2774 it
->last_visible_x
-= 1;
2776 it
->last_visible_y
= window_text_bottom_y (w
);
2778 /* For mode lines and alike, arrange for the first glyph having a
2779 left box line if the face specifies a box. */
2780 if (base_face_id
!= DEFAULT_FACE_ID
)
2784 it
->face_id
= remapped_base_face_id
;
2786 /* If we have a boxed mode line, make the first character appear
2787 with a left box line. */
2788 face
= FACE_FROM_ID (it
->f
, remapped_base_face_id
);
2789 if (face
->box
!= FACE_NO_BOX
)
2790 it
->start_of_box_run_p
= 1;
2793 /* If we are to reorder bidirectional text, init the bidi
2797 /* Note the paragraph direction that this buffer wants to
2799 if (EQ (current_buffer
->bidi_paragraph_direction
, Qleft_to_right
))
2800 it
->paragraph_embedding
= L2R
;
2801 else if (EQ (current_buffer
->bidi_paragraph_direction
, Qright_to_left
))
2802 it
->paragraph_embedding
= R2L
;
2804 it
->paragraph_embedding
= NEUTRAL_DIR
;
2805 bidi_init_it (charpos
, bytepos
, &it
->bidi_it
);
2808 /* If a buffer position was specified, set the iterator there,
2809 getting overlays and face properties from that position. */
2810 if (charpos
>= BUF_BEG (current_buffer
))
2812 it
->end_charpos
= ZV
;
2814 IT_CHARPOS (*it
) = charpos
;
2816 /* Compute byte position if not specified. */
2817 if (bytepos
< charpos
)
2818 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2820 IT_BYTEPOS (*it
) = bytepos
;
2822 it
->start
= it
->current
;
2824 /* Compute faces etc. */
2825 reseat (it
, it
->current
.pos
, 1);
2832 /* Initialize IT for the display of window W with window start POS. */
2835 start_display (struct it
*it
, struct window
*w
, struct text_pos pos
)
2837 struct glyph_row
*row
;
2838 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2840 row
= w
->desired_matrix
->rows
+ first_vpos
;
2841 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2842 it
->first_vpos
= first_vpos
;
2844 /* Don't reseat to previous visible line start if current start
2845 position is in a string or image. */
2846 if (it
->method
== GET_FROM_BUFFER
&& it
->line_wrap
!= TRUNCATE
)
2848 int start_at_line_beg_p
;
2849 int first_y
= it
->current_y
;
2851 /* If window start is not at a line start, skip forward to POS to
2852 get the correct continuation lines width. */
2853 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2854 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2855 if (!start_at_line_beg_p
)
2859 reseat_at_previous_visible_line_start (it
);
2860 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2862 new_x
= it
->current_x
+ it
->pixel_width
;
2864 /* If lines are continued, this line may end in the middle
2865 of a multi-glyph character (e.g. a control character
2866 displayed as \003, or in the middle of an overlay
2867 string). In this case move_it_to above will not have
2868 taken us to the start of the continuation line but to the
2869 end of the continued line. */
2870 if (it
->current_x
> 0
2871 && it
->line_wrap
!= TRUNCATE
/* Lines are continued. */
2872 && (/* And glyph doesn't fit on the line. */
2873 new_x
> it
->last_visible_x
2874 /* Or it fits exactly and we're on a window
2876 || (new_x
== it
->last_visible_x
2877 && FRAME_WINDOW_P (it
->f
))))
2879 if (it
->current
.dpvec_index
>= 0
2880 || it
->current
.overlay_string_index
>= 0)
2882 set_iterator_to_next (it
, 1);
2883 move_it_in_display_line_to (it
, -1, -1, 0);
2886 it
->continuation_lines_width
+= it
->current_x
;
2889 /* We're starting a new display line, not affected by the
2890 height of the continued line, so clear the appropriate
2891 fields in the iterator structure. */
2892 it
->max_ascent
= it
->max_descent
= 0;
2893 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2895 it
->current_y
= first_y
;
2897 it
->current_x
= it
->hpos
= 0;
2903 /* Return 1 if POS is a position in ellipses displayed for invisible
2904 text. W is the window we display, for text property lookup. */
2907 in_ellipses_for_invisible_text_p (struct display_pos
*pos
, struct window
*w
)
2909 Lisp_Object prop
, window
;
2911 int charpos
= CHARPOS (pos
->pos
);
2913 /* If POS specifies a position in a display vector, this might
2914 be for an ellipsis displayed for invisible text. We won't
2915 get the iterator set up for delivering that ellipsis unless
2916 we make sure that it gets aware of the invisible text. */
2917 if (pos
->dpvec_index
>= 0
2918 && pos
->overlay_string_index
< 0
2919 && CHARPOS (pos
->string_pos
) < 0
2921 && (XSETWINDOW (window
, w
),
2922 prop
= Fget_char_property (make_number (charpos
),
2923 Qinvisible
, window
),
2924 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2926 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2928 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2935 /* Initialize IT for stepping through current_buffer in window W,
2936 starting at position POS that includes overlay string and display
2937 vector/ control character translation position information. Value
2938 is zero if there are overlay strings with newlines at POS. */
2941 init_from_display_pos (struct it
*it
, struct window
*w
, struct display_pos
*pos
)
2943 EMACS_INT charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2944 int i
, overlay_strings_with_newlines
= 0;
2946 /* If POS specifies a position in a display vector, this might
2947 be for an ellipsis displayed for invisible text. We won't
2948 get the iterator set up for delivering that ellipsis unless
2949 we make sure that it gets aware of the invisible text. */
2950 if (in_ellipses_for_invisible_text_p (pos
, w
))
2956 /* Keep in mind: the call to reseat in init_iterator skips invisible
2957 text, so we might end up at a position different from POS. This
2958 is only a problem when POS is a row start after a newline and an
2959 overlay starts there with an after-string, and the overlay has an
2960 invisible property. Since we don't skip invisible text in
2961 display_line and elsewhere immediately after consuming the
2962 newline before the row start, such a POS will not be in a string,
2963 but the call to init_iterator below will move us to the
2965 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2967 /* This only scans the current chunk -- it should scan all chunks.
2968 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2969 to 16 in 22.1 to make this a lesser problem. */
2970 for (i
= 0; i
< it
->n_overlay_strings
&& i
< OVERLAY_STRING_CHUNK_SIZE
; ++i
)
2972 const char *s
= SDATA (it
->overlay_strings
[i
]);
2973 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2975 while (s
< e
&& *s
!= '\n')
2980 overlay_strings_with_newlines
= 1;
2985 /* If position is within an overlay string, set up IT to the right
2987 if (pos
->overlay_string_index
>= 0)
2991 /* If the first overlay string happens to have a `display'
2992 property for an image, the iterator will be set up for that
2993 image, and we have to undo that setup first before we can
2994 correct the overlay string index. */
2995 if (it
->method
== GET_FROM_IMAGE
)
2998 /* We already have the first chunk of overlay strings in
2999 IT->overlay_strings. Load more until the one for
3000 pos->overlay_string_index is in IT->overlay_strings. */
3001 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
3003 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
3004 it
->current
.overlay_string_index
= 0;
3007 load_overlay_strings (it
, 0);
3008 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
3012 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
3013 relative_index
= (it
->current
.overlay_string_index
3014 % OVERLAY_STRING_CHUNK_SIZE
);
3015 it
->string
= it
->overlay_strings
[relative_index
];
3016 xassert (STRINGP (it
->string
));
3017 it
->current
.string_pos
= pos
->string_pos
;
3018 it
->method
= GET_FROM_STRING
;
3021 if (CHARPOS (pos
->string_pos
) >= 0)
3023 /* Recorded position is not in an overlay string, but in another
3024 string. This can only be a string from a `display' property.
3025 IT should already be filled with that string. */
3026 it
->current
.string_pos
= pos
->string_pos
;
3027 xassert (STRINGP (it
->string
));
3030 /* Restore position in display vector translations, control
3031 character translations or ellipses. */
3032 if (pos
->dpvec_index
>= 0)
3034 if (it
->dpvec
== NULL
)
3035 get_next_display_element (it
);
3036 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
3037 it
->current
.dpvec_index
= pos
->dpvec_index
;
3041 return !overlay_strings_with_newlines
;
3045 /* Initialize IT for stepping through current_buffer in window W
3046 starting at ROW->start. */
3049 init_to_row_start (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3051 init_from_display_pos (it
, w
, &row
->start
);
3052 it
->start
= row
->start
;
3053 it
->continuation_lines_width
= row
->continuation_lines_width
;
3058 /* Initialize IT for stepping through current_buffer in window W
3059 starting in the line following ROW, i.e. starting at ROW->end.
3060 Value is zero if there are overlay strings with newlines at ROW's
3064 init_to_row_end (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3068 if (init_from_display_pos (it
, w
, &row
->end
))
3070 if (row
->continued_p
)
3071 it
->continuation_lines_width
3072 = row
->continuation_lines_width
+ row
->pixel_width
;
3083 /***********************************************************************
3085 ***********************************************************************/
3087 /* Called when IT reaches IT->stop_charpos. Handle text property and
3088 overlay changes. Set IT->stop_charpos to the next position where
3092 handle_stop (struct it
*it
)
3094 enum prop_handled handled
;
3095 int handle_overlay_change_p
;
3099 it
->current
.dpvec_index
= -1;
3100 handle_overlay_change_p
= !it
->ignore_overlay_strings_at_pos_p
;
3101 it
->ignore_overlay_strings_at_pos_p
= 0;
3104 /* Use face of preceding text for ellipsis (if invisible) */
3105 if (it
->selective_display_ellipsis_p
)
3106 it
->saved_face_id
= it
->face_id
;
3110 handled
= HANDLED_NORMALLY
;
3112 /* Call text property handlers. */
3113 for (p
= it_props
; p
->handler
; ++p
)
3115 handled
= p
->handler (it
);
3117 if (handled
== HANDLED_RECOMPUTE_PROPS
)
3119 else if (handled
== HANDLED_RETURN
)
3121 /* We still want to show before and after strings from
3122 overlays even if the actual buffer text is replaced. */
3123 if (!handle_overlay_change_p
3125 || !get_overlay_strings_1 (it
, 0, 0))
3128 setup_for_ellipsis (it
, 0);
3129 /* When handling a display spec, we might load an
3130 empty string. In that case, discard it here. We
3131 used to discard it in handle_single_display_spec,
3132 but that causes get_overlay_strings_1, above, to
3133 ignore overlay strings that we must check. */
3134 if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3138 else if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3142 it
->ignore_overlay_strings_at_pos_p
= 1;
3143 it
->string_from_display_prop_p
= 0;
3144 handle_overlay_change_p
= 0;
3146 handled
= HANDLED_RECOMPUTE_PROPS
;
3149 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
3150 handle_overlay_change_p
= 0;
3153 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
3155 /* Don't check for overlay strings below when set to deliver
3156 characters from a display vector. */
3157 if (it
->method
== GET_FROM_DISPLAY_VECTOR
)
3158 handle_overlay_change_p
= 0;
3160 /* Handle overlay changes.
3161 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3162 if it finds overlays. */
3163 if (handle_overlay_change_p
)
3164 handled
= handle_overlay_change (it
);
3169 setup_for_ellipsis (it
, 0);
3173 while (handled
== HANDLED_RECOMPUTE_PROPS
);
3175 /* Determine where to stop next. */
3176 if (handled
== HANDLED_NORMALLY
)
3177 compute_stop_pos (it
);
3181 /* Compute IT->stop_charpos from text property and overlay change
3182 information for IT's current position. */
3185 compute_stop_pos (struct it
*it
)
3187 register INTERVAL iv
, next_iv
;
3188 Lisp_Object object
, limit
, position
;
3189 EMACS_INT charpos
, bytepos
;
3191 /* If nowhere else, stop at the end. */
3192 it
->stop_charpos
= it
->end_charpos
;
3194 if (STRINGP (it
->string
))
3196 /* Strings are usually short, so don't limit the search for
3198 object
= it
->string
;
3200 charpos
= IT_STRING_CHARPOS (*it
);
3201 bytepos
= IT_STRING_BYTEPOS (*it
);
3207 /* If next overlay change is in front of the current stop pos
3208 (which is IT->end_charpos), stop there. Note: value of
3209 next_overlay_change is point-max if no overlay change
3211 charpos
= IT_CHARPOS (*it
);
3212 bytepos
= IT_BYTEPOS (*it
);
3213 pos
= next_overlay_change (charpos
);
3214 if (pos
< it
->stop_charpos
)
3215 it
->stop_charpos
= pos
;
3217 /* If showing the region, we have to stop at the region
3218 start or end because the face might change there. */
3219 if (it
->region_beg_charpos
> 0)
3221 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
3222 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
3223 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
3224 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
3227 /* Set up variables for computing the stop position from text
3228 property changes. */
3229 XSETBUFFER (object
, current_buffer
);
3230 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
3233 /* Get the interval containing IT's position. Value is a null
3234 interval if there isn't such an interval. */
3235 position
= make_number (charpos
);
3236 iv
= validate_interval_range (object
, &position
, &position
, 0);
3237 if (!NULL_INTERVAL_P (iv
))
3239 Lisp_Object values_here
[LAST_PROP_IDX
];
3242 /* Get properties here. */
3243 for (p
= it_props
; p
->handler
; ++p
)
3244 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
3246 /* Look for an interval following iv that has different
3248 for (next_iv
= next_interval (iv
);
3249 (!NULL_INTERVAL_P (next_iv
)
3251 || XFASTINT (limit
) > next_iv
->position
));
3252 next_iv
= next_interval (next_iv
))
3254 for (p
= it_props
; p
->handler
; ++p
)
3256 Lisp_Object new_value
;
3258 new_value
= textget (next_iv
->plist
, *p
->name
);
3259 if (!EQ (values_here
[p
->idx
], new_value
))
3267 if (!NULL_INTERVAL_P (next_iv
))
3269 if (INTEGERP (limit
)
3270 && next_iv
->position
>= XFASTINT (limit
))
3271 /* No text property change up to limit. */
3272 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
3274 /* Text properties change in next_iv. */
3275 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
3279 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
,
3280 it
->stop_charpos
, it
->string
);
3282 xassert (STRINGP (it
->string
)
3283 || (it
->stop_charpos
>= BEGV
3284 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
3288 /* Return the position of the next overlay change after POS in
3289 current_buffer. Value is point-max if no overlay change
3290 follows. This is like `next-overlay-change' but doesn't use
3294 next_overlay_change (EMACS_INT pos
)
3298 Lisp_Object
*overlays
;
3301 /* Get all overlays at the given position. */
3302 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
3304 /* If any of these overlays ends before endpos,
3305 use its ending point instead. */
3306 for (i
= 0; i
< noverlays
; ++i
)
3311 oend
= OVERLAY_END (overlays
[i
]);
3312 oendpos
= OVERLAY_POSITION (oend
);
3313 endpos
= min (endpos
, oendpos
);
3321 /***********************************************************************
3323 ***********************************************************************/
3325 /* Handle changes in the `fontified' property of the current buffer by
3326 calling hook functions from Qfontification_functions to fontify
3329 static enum prop_handled
3330 handle_fontified_prop (struct it
*it
)
3332 Lisp_Object prop
, pos
;
3333 enum prop_handled handled
= HANDLED_NORMALLY
;
3335 if (!NILP (Vmemory_full
))
3338 /* Get the value of the `fontified' property at IT's current buffer
3339 position. (The `fontified' property doesn't have a special
3340 meaning in strings.) If the value is nil, call functions from
3341 Qfontification_functions. */
3342 if (!STRINGP (it
->string
)
3344 && !NILP (Vfontification_functions
)
3345 && !NILP (Vrun_hooks
)
3346 && (pos
= make_number (IT_CHARPOS (*it
)),
3347 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
3348 /* Ignore the special cased nil value always present at EOB since
3349 no amount of fontifying will be able to change it. */
3350 NILP (prop
) && IT_CHARPOS (*it
) < Z
))
3352 int count
= SPECPDL_INDEX ();
3355 val
= Vfontification_functions
;
3356 specbind (Qfontification_functions
, Qnil
);
3358 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
3359 safe_call1 (val
, pos
);
3362 Lisp_Object globals
, fn
;
3363 struct gcpro gcpro1
, gcpro2
;
3366 GCPRO2 (val
, globals
);
3368 for (; CONSP (val
); val
= XCDR (val
))
3374 /* A value of t indicates this hook has a local
3375 binding; it means to run the global binding too.
3376 In a global value, t should not occur. If it
3377 does, we must ignore it to avoid an endless
3379 for (globals
= Fdefault_value (Qfontification_functions
);
3381 globals
= XCDR (globals
))
3383 fn
= XCAR (globals
);
3385 safe_call1 (fn
, pos
);
3389 safe_call1 (fn
, pos
);
3395 unbind_to (count
, Qnil
);
3397 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3398 something. This avoids an endless loop if they failed to
3399 fontify the text for which reason ever. */
3400 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
3401 handled
= HANDLED_RECOMPUTE_PROPS
;
3409 /***********************************************************************
3411 ***********************************************************************/
3413 /* Set up iterator IT from face properties at its current position.
3414 Called from handle_stop. */
3416 static enum prop_handled
3417 handle_face_prop (struct it
*it
)
3420 EMACS_INT next_stop
;
3422 if (!STRINGP (it
->string
))
3425 = face_at_buffer_position (it
->w
,
3427 it
->region_beg_charpos
,
3428 it
->region_end_charpos
,
3431 + TEXT_PROP_DISTANCE_LIMIT
),
3432 0, it
->base_face_id
);
3434 /* Is this a start of a run of characters with box face?
3435 Caveat: this can be called for a freshly initialized
3436 iterator; face_id is -1 in this case. We know that the new
3437 face will not change until limit, i.e. if the new face has a
3438 box, all characters up to limit will have one. But, as
3439 usual, we don't know whether limit is really the end. */
3440 if (new_face_id
!= it
->face_id
)
3442 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3444 /* If new face has a box but old face has not, this is
3445 the start of a run of characters with box, i.e. it has
3446 a shadow on the left side. The value of face_id of the
3447 iterator will be -1 if this is the initial call that gets
3448 the face. In this case, we have to look in front of IT's
3449 position and see whether there is a face != new_face_id. */
3450 it
->start_of_box_run_p
3451 = (new_face
->box
!= FACE_NO_BOX
3452 && (it
->face_id
>= 0
3453 || IT_CHARPOS (*it
) == BEG
3454 || new_face_id
!= face_before_it_pos (it
)));
3455 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3460 int base_face_id
, bufpos
;
3462 Lisp_Object from_overlay
3463 = (it
->current
.overlay_string_index
>= 0
3464 ? it
->string_overlays
[it
->current
.overlay_string_index
]
3467 /* See if we got to this string directly or indirectly from
3468 an overlay property. That includes the before-string or
3469 after-string of an overlay, strings in display properties
3470 provided by an overlay, their text properties, etc.
3472 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3473 if (! NILP (from_overlay
))
3474 for (i
= it
->sp
- 1; i
>= 0; i
--)
3476 if (it
->stack
[i
].current
.overlay_string_index
>= 0)
3478 = it
->string_overlays
[it
->stack
[i
].current
.overlay_string_index
];
3479 else if (! NILP (it
->stack
[i
].from_overlay
))
3480 from_overlay
= it
->stack
[i
].from_overlay
;
3482 if (!NILP (from_overlay
))
3486 if (! NILP (from_overlay
))
3488 bufpos
= IT_CHARPOS (*it
);
3489 /* For a string from an overlay, the base face depends
3490 only on text properties and ignores overlays. */
3492 = face_for_overlay_string (it
->w
,
3494 it
->region_beg_charpos
,
3495 it
->region_end_charpos
,
3498 + TEXT_PROP_DISTANCE_LIMIT
),
3506 /* For strings from a `display' property, use the face at
3507 IT's current buffer position as the base face to merge
3508 with, so that overlay strings appear in the same face as
3509 surrounding text, unless they specify their own
3511 base_face_id
= underlying_face_id (it
);
3514 new_face_id
= face_at_string_position (it
->w
,
3516 IT_STRING_CHARPOS (*it
),
3518 it
->region_beg_charpos
,
3519 it
->region_end_charpos
,
3523 /* Is this a start of a run of characters with box? Caveat:
3524 this can be called for a freshly allocated iterator; face_id
3525 is -1 is this case. We know that the new face will not
3526 change until the next check pos, i.e. if the new face has a
3527 box, all characters up to that position will have a
3528 box. But, as usual, we don't know whether that position
3529 is really the end. */
3530 if (new_face_id
!= it
->face_id
)
3532 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3533 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3535 /* If new face has a box but old face hasn't, this is the
3536 start of a run of characters with box, i.e. it has a
3537 shadow on the left side. */
3538 it
->start_of_box_run_p
3539 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
3540 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3544 it
->face_id
= new_face_id
;
3545 return HANDLED_NORMALLY
;
3549 /* Return the ID of the face ``underlying'' IT's current position,
3550 which is in a string. If the iterator is associated with a
3551 buffer, return the face at IT's current buffer position.
3552 Otherwise, use the iterator's base_face_id. */
3555 underlying_face_id (struct it
*it
)
3557 int face_id
= it
->base_face_id
, i
;
3559 xassert (STRINGP (it
->string
));
3561 for (i
= it
->sp
- 1; i
>= 0; --i
)
3562 if (NILP (it
->stack
[i
].string
))
3563 face_id
= it
->stack
[i
].face_id
;
3569 /* Compute the face one character before or after the current position
3570 of IT. BEFORE_P non-zero means get the face in front of IT's
3571 position. Value is the id of the face. */
3574 face_before_or_after_it_pos (struct it
*it
, int before_p
)
3577 EMACS_INT next_check_charpos
;
3578 struct text_pos pos
;
3580 xassert (it
->s
== NULL
);
3582 if (STRINGP (it
->string
))
3584 int bufpos
, base_face_id
;
3586 /* No face change past the end of the string (for the case
3587 we are padding with spaces). No face change before the
3589 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
3590 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
3593 /* Set pos to the position before or after IT's current position. */
3595 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
3597 /* For composition, we must check the character after the
3599 pos
= (it
->what
== IT_COMPOSITION
3600 ? string_pos (IT_STRING_CHARPOS (*it
)
3601 + it
->cmp_it
.nchars
, it
->string
)
3602 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
3604 if (it
->current
.overlay_string_index
>= 0)
3605 bufpos
= IT_CHARPOS (*it
);
3609 base_face_id
= underlying_face_id (it
);
3611 /* Get the face for ASCII, or unibyte. */
3612 face_id
= face_at_string_position (it
->w
,
3616 it
->region_beg_charpos
,
3617 it
->region_end_charpos
,
3618 &next_check_charpos
,
3621 /* Correct the face for charsets different from ASCII. Do it
3622 for the multibyte case only. The face returned above is
3623 suitable for unibyte text if IT->string is unibyte. */
3624 if (STRING_MULTIBYTE (it
->string
))
3626 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
3627 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
3629 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3631 c
= string_char_and_length (p
, &len
);
3632 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, CHARPOS (pos
), it
->string
);
3637 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3638 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3641 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3642 pos
= it
->current
.pos
;
3645 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3648 if (it
->what
== IT_COMPOSITION
)
3649 /* For composition, we must check the position after the
3651 pos
.charpos
+= it
->cmp_it
.nchars
, pos
.bytepos
+= it
->len
;
3653 INC_TEXT_POS (pos
, it
->multibyte_p
);
3656 /* Determine face for CHARSET_ASCII, or unibyte. */
3657 face_id
= face_at_buffer_position (it
->w
,
3659 it
->region_beg_charpos
,
3660 it
->region_end_charpos
,
3661 &next_check_charpos
,
3664 /* Correct the face for charsets different from ASCII. Do it
3665 for the multibyte case only. The face returned above is
3666 suitable for unibyte text if current_buffer is unibyte. */
3667 if (it
->multibyte_p
)
3669 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3670 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3671 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, CHARPOS (pos
), Qnil
);
3680 /***********************************************************************
3682 ***********************************************************************/
3684 /* Set up iterator IT from invisible properties at its current
3685 position. Called from handle_stop. */
3687 static enum prop_handled
3688 handle_invisible_prop (struct it
*it
)
3690 enum prop_handled handled
= HANDLED_NORMALLY
;
3692 if (STRINGP (it
->string
))
3694 extern Lisp_Object Qinvisible
;
3695 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3697 /* Get the value of the invisible text property at the
3698 current position. Value will be nil if there is no such
3700 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3701 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3704 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3706 handled
= HANDLED_RECOMPUTE_PROPS
;
3708 /* Get the position at which the next change of the
3709 invisible text property can be found in IT->string.
3710 Value will be nil if the property value is the same for
3711 all the rest of IT->string. */
3712 XSETINT (limit
, SCHARS (it
->string
));
3713 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3716 /* Text at current position is invisible. The next
3717 change in the property is at position end_charpos.
3718 Move IT's current position to that position. */
3719 if (INTEGERP (end_charpos
)
3720 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3722 struct text_pos old
;
3723 old
= it
->current
.string_pos
;
3724 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3725 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3729 /* The rest of the string is invisible. If this is an
3730 overlay string, proceed with the next overlay string
3731 or whatever comes and return a character from there. */
3732 if (it
->current
.overlay_string_index
>= 0)
3734 next_overlay_string (it
);
3735 /* Don't check for overlay strings when we just
3736 finished processing them. */
3737 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3741 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3742 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3750 EMACS_INT newpos
, next_stop
, start_charpos
, tem
;
3751 Lisp_Object pos
, prop
, overlay
;
3753 /* First of all, is there invisible text at this position? */
3754 tem
= start_charpos
= IT_CHARPOS (*it
);
3755 pos
= make_number (tem
);
3756 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3758 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3760 /* If we are on invisible text, skip over it. */
3761 if (invis_p
&& start_charpos
< it
->end_charpos
)
3763 /* Record whether we have to display an ellipsis for the
3765 int display_ellipsis_p
= invis_p
== 2;
3767 handled
= HANDLED_RECOMPUTE_PROPS
;
3769 /* Loop skipping over invisible text. The loop is left at
3770 ZV or with IT on the first char being visible again. */
3773 /* Try to skip some invisible text. Return value is the
3774 position reached which can be equal to where we start
3775 if there is nothing invisible there. This skips both
3776 over invisible text properties and overlays with
3777 invisible property. */
3778 newpos
= skip_invisible (tem
, &next_stop
, ZV
, it
->window
);
3780 /* If we skipped nothing at all we weren't at invisible
3781 text in the first place. If everything to the end of
3782 the buffer was skipped, end the loop. */
3783 if (newpos
== tem
|| newpos
>= ZV
)
3787 /* We skipped some characters but not necessarily
3788 all there are. Check if we ended up on visible
3789 text. Fget_char_property returns the property of
3790 the char before the given position, i.e. if we
3791 get invis_p = 0, this means that the char at
3792 newpos is visible. */
3793 pos
= make_number (newpos
);
3794 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3795 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3798 /* If we ended up on invisible text, proceed to
3799 skip starting with next_stop. */
3803 /* If there are adjacent invisible texts, don't lose the
3804 second one's ellipsis. */
3806 display_ellipsis_p
= 1;
3810 /* The position newpos is now either ZV or on visible text. */
3811 if (it
->bidi_p
&& newpos
< ZV
)
3813 /* With bidi iteration, the region of invisible text
3814 could start and/or end in the middle of a non-base
3815 embedding level. Therefore, we need to skip
3816 invisible text using the bidi iterator, starting at
3817 IT's current position, until we find ourselves
3818 outside the invisible text. Skipping invisible text
3819 _after_ bidi iteration avoids affecting the visual
3820 order of the displayed text when invisible properties
3821 are added or removed. */
3822 if (it
->bidi_it
.first_elt
)
3824 /* If we were `reseat'ed to a new paragraph,
3825 determine the paragraph base direction. We need
3826 to do it now because next_element_from_buffer may
3827 not have a chance to do it, if we are going to
3828 skip any text at the beginning, which resets the
3830 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
3834 bidi_move_to_visually_next (&it
->bidi_it
);
3836 while (it
->stop_charpos
<= it
->bidi_it
.charpos
3837 && it
->bidi_it
.charpos
< newpos
);
3838 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
3839 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
3840 /* If we overstepped NEWPOS, record its position in the
3841 iterator, so that we skip invisible text if later the
3842 bidi iteration lands us in the invisible region
3844 if (IT_CHARPOS (*it
) >= newpos
)
3845 it
->prev_stop
= newpos
;
3849 IT_CHARPOS (*it
) = newpos
;
3850 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3853 /* If there are before-strings at the start of invisible
3854 text, and the text is invisible because of a text
3855 property, arrange to show before-strings because 20.x did
3856 it that way. (If the text is invisible because of an
3857 overlay property instead of a text property, this is
3858 already handled in the overlay code.) */
3860 && get_overlay_strings (it
, it
->stop_charpos
))
3862 handled
= HANDLED_RECOMPUTE_PROPS
;
3863 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3865 else if (display_ellipsis_p
)
3867 /* Make sure that the glyphs of the ellipsis will get
3868 correct `charpos' values. If we would not update
3869 it->position here, the glyphs would belong to the
3870 last visible character _before_ the invisible
3871 text, which confuses `set_cursor_from_row'.
3873 We use the last invisible position instead of the
3874 first because this way the cursor is always drawn on
3875 the first "." of the ellipsis, whenever PT is inside
3876 the invisible text. Otherwise the cursor would be
3877 placed _after_ the ellipsis when the point is after the
3878 first invisible character. */
3879 if (!STRINGP (it
->object
))
3881 it
->position
.charpos
= newpos
- 1;
3882 it
->position
.bytepos
= CHAR_TO_BYTE (it
->position
.charpos
);
3885 /* Let the ellipsis display before
3886 considering any properties of the following char.
3887 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3888 handled
= HANDLED_RETURN
;
3897 /* Make iterator IT return `...' next.
3898 Replaces LEN characters from buffer. */
3901 setup_for_ellipsis (struct it
*it
, int len
)
3903 /* Use the display table definition for `...'. Invalid glyphs
3904 will be handled by the method returning elements from dpvec. */
3905 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3907 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3908 it
->dpvec
= v
->contents
;
3909 it
->dpend
= v
->contents
+ v
->size
;
3913 /* Default `...'. */
3914 it
->dpvec
= default_invis_vector
;
3915 it
->dpend
= default_invis_vector
+ 3;
3918 it
->dpvec_char_len
= len
;
3919 it
->current
.dpvec_index
= 0;
3920 it
->dpvec_face_id
= -1;
3922 /* Remember the current face id in case glyphs specify faces.
3923 IT's face is restored in set_iterator_to_next.
3924 saved_face_id was set to preceding char's face in handle_stop. */
3925 if (it
->saved_face_id
< 0 || it
->saved_face_id
!= it
->face_id
)
3926 it
->saved_face_id
= it
->face_id
= DEFAULT_FACE_ID
;
3928 it
->method
= GET_FROM_DISPLAY_VECTOR
;
3934 /***********************************************************************
3936 ***********************************************************************/
3938 /* Set up iterator IT from `display' property at its current position.
3939 Called from handle_stop.
3940 We return HANDLED_RETURN if some part of the display property
3941 overrides the display of the buffer text itself.
3942 Otherwise we return HANDLED_NORMALLY. */
3944 static enum prop_handled
3945 handle_display_prop (struct it
*it
)
3947 Lisp_Object prop
, object
, overlay
;
3948 struct text_pos
*position
;
3949 /* Nonzero if some property replaces the display of the text itself. */
3950 int display_replaced_p
= 0;
3952 if (STRINGP (it
->string
))
3954 object
= it
->string
;
3955 position
= &it
->current
.string_pos
;
3959 XSETWINDOW (object
, it
->w
);
3960 position
= &it
->current
.pos
;
3963 /* Reset those iterator values set from display property values. */
3964 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
3965 it
->space_width
= Qnil
;
3966 it
->font_height
= Qnil
;
3969 /* We don't support recursive `display' properties, i.e. string
3970 values that have a string `display' property, that have a string
3971 `display' property etc. */
3972 if (!it
->string_from_display_prop_p
)
3973 it
->area
= TEXT_AREA
;
3975 prop
= get_char_property_and_overlay (make_number (position
->charpos
),
3976 Qdisplay
, object
, &overlay
);
3978 return HANDLED_NORMALLY
;
3979 /* Now OVERLAY is the overlay that gave us this property, or nil
3980 if it was a text property. */
3982 if (!STRINGP (it
->string
))
3983 object
= it
->w
->buffer
;
3986 /* Simple properties. */
3987 && !EQ (XCAR (prop
), Qimage
)
3988 && !EQ (XCAR (prop
), Qspace
)
3989 && !EQ (XCAR (prop
), Qwhen
)
3990 && !EQ (XCAR (prop
), Qslice
)
3991 && !EQ (XCAR (prop
), Qspace_width
)
3992 && !EQ (XCAR (prop
), Qheight
)
3993 && !EQ (XCAR (prop
), Qraise
)
3994 /* Marginal area specifications. */
3995 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3996 && !EQ (XCAR (prop
), Qleft_fringe
)
3997 && !EQ (XCAR (prop
), Qright_fringe
)
3998 && !NILP (XCAR (prop
)))
4000 for (; CONSP (prop
); prop
= XCDR (prop
))
4002 if (handle_single_display_spec (it
, XCAR (prop
), object
, overlay
,
4003 position
, display_replaced_p
))
4005 display_replaced_p
= 1;
4006 /* If some text in a string is replaced, `position' no
4007 longer points to the position of `object'. */
4008 if (STRINGP (object
))
4013 else if (VECTORP (prop
))
4016 for (i
= 0; i
< ASIZE (prop
); ++i
)
4017 if (handle_single_display_spec (it
, AREF (prop
, i
), object
, overlay
,
4018 position
, display_replaced_p
))
4020 display_replaced_p
= 1;
4021 /* If some text in a string is replaced, `position' no
4022 longer points to the position of `object'. */
4023 if (STRINGP (object
))
4029 if (handle_single_display_spec (it
, prop
, object
, overlay
,
4031 display_replaced_p
= 1;
4034 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
4038 /* Value is the position of the end of the `display' property starting
4039 at START_POS in OBJECT. */
4041 static struct text_pos
4042 display_prop_end (struct it
*it
, Lisp_Object object
, struct text_pos start_pos
)
4045 struct text_pos end_pos
;
4047 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
4048 Qdisplay
, object
, Qnil
);
4049 CHARPOS (end_pos
) = XFASTINT (end
);
4050 if (STRINGP (object
))
4051 compute_string_pos (&end_pos
, start_pos
, it
->string
);
4053 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
4059 /* Set up IT from a single `display' specification PROP. OBJECT
4060 is the object in which the `display' property was found. *POSITION
4061 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4062 means that we previously saw a display specification which already
4063 replaced text display with something else, for example an image;
4064 we ignore such properties after the first one has been processed.
4066 OVERLAY is the overlay this `display' property came from,
4067 or nil if it was a text property.
4069 If PROP is a `space' or `image' specification, and in some other
4070 cases too, set *POSITION to the position where the `display'
4073 Value is non-zero if something was found which replaces the display
4074 of buffer or string text. */
4077 handle_single_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4078 Lisp_Object overlay
, struct text_pos
*position
,
4079 int display_replaced_before_p
)
4082 Lisp_Object location
, value
;
4083 struct text_pos start_pos
, save_pos
;
4086 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4087 If the result is non-nil, use VALUE instead of SPEC. */
4089 if (CONSP (spec
) && EQ (XCAR (spec
), Qwhen
))
4098 if (!NILP (form
) && !EQ (form
, Qt
))
4100 int count
= SPECPDL_INDEX ();
4101 struct gcpro gcpro1
;
4103 /* Bind `object' to the object having the `display' property, a
4104 buffer or string. Bind `position' to the position in the
4105 object where the property was found, and `buffer-position'
4106 to the current position in the buffer. */
4107 specbind (Qobject
, object
);
4108 specbind (Qposition
, make_number (CHARPOS (*position
)));
4109 specbind (Qbuffer_position
,
4110 make_number (STRINGP (object
)
4111 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
4113 form
= safe_eval (form
);
4115 unbind_to (count
, Qnil
);
4121 /* Handle `(height HEIGHT)' specifications. */
4123 && EQ (XCAR (spec
), Qheight
)
4124 && CONSP (XCDR (spec
)))
4126 if (!FRAME_WINDOW_P (it
->f
))
4129 it
->font_height
= XCAR (XCDR (spec
));
4130 if (!NILP (it
->font_height
))
4132 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4133 int new_height
= -1;
4135 if (CONSP (it
->font_height
)
4136 && (EQ (XCAR (it
->font_height
), Qplus
)
4137 || EQ (XCAR (it
->font_height
), Qminus
))
4138 && CONSP (XCDR (it
->font_height
))
4139 && INTEGERP (XCAR (XCDR (it
->font_height
))))
4141 /* `(+ N)' or `(- N)' where N is an integer. */
4142 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
4143 if (EQ (XCAR (it
->font_height
), Qplus
))
4145 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
4147 else if (FUNCTIONP (it
->font_height
))
4149 /* Call function with current height as argument.
4150 Value is the new height. */
4152 height
= safe_call1 (it
->font_height
,
4153 face
->lface
[LFACE_HEIGHT_INDEX
]);
4154 if (NUMBERP (height
))
4155 new_height
= XFLOATINT (height
);
4157 else if (NUMBERP (it
->font_height
))
4159 /* Value is a multiple of the canonical char height. */
4162 face
= FACE_FROM_ID (it
->f
,
4163 lookup_basic_face (it
->f
, DEFAULT_FACE_ID
));
4164 new_height
= (XFLOATINT (it
->font_height
)
4165 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
4169 /* Evaluate IT->font_height with `height' bound to the
4170 current specified height to get the new height. */
4171 int count
= SPECPDL_INDEX ();
4173 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
4174 value
= safe_eval (it
->font_height
);
4175 unbind_to (count
, Qnil
);
4177 if (NUMBERP (value
))
4178 new_height
= XFLOATINT (value
);
4182 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
4188 /* Handle `(space-width WIDTH)'. */
4190 && EQ (XCAR (spec
), Qspace_width
)
4191 && CONSP (XCDR (spec
)))
4193 if (!FRAME_WINDOW_P (it
->f
))
4196 value
= XCAR (XCDR (spec
));
4197 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
4198 it
->space_width
= value
;
4203 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4205 && EQ (XCAR (spec
), Qslice
))
4209 if (!FRAME_WINDOW_P (it
->f
))
4212 if (tem
= XCDR (spec
), CONSP (tem
))
4214 it
->slice
.x
= XCAR (tem
);
4215 if (tem
= XCDR (tem
), CONSP (tem
))
4217 it
->slice
.y
= XCAR (tem
);
4218 if (tem
= XCDR (tem
), CONSP (tem
))
4220 it
->slice
.width
= XCAR (tem
);
4221 if (tem
= XCDR (tem
), CONSP (tem
))
4222 it
->slice
.height
= XCAR (tem
);
4230 /* Handle `(raise FACTOR)'. */
4232 && EQ (XCAR (spec
), Qraise
)
4233 && CONSP (XCDR (spec
)))
4235 if (!FRAME_WINDOW_P (it
->f
))
4238 #ifdef HAVE_WINDOW_SYSTEM
4239 value
= XCAR (XCDR (spec
));
4240 if (NUMBERP (value
))
4242 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4243 it
->voffset
= - (XFLOATINT (value
)
4244 * (FONT_HEIGHT (face
->font
)));
4246 #endif /* HAVE_WINDOW_SYSTEM */
4251 /* Don't handle the other kinds of display specifications
4252 inside a string that we got from a `display' property. */
4253 if (it
->string_from_display_prop_p
)
4256 /* Characters having this form of property are not displayed, so
4257 we have to find the end of the property. */
4258 start_pos
= *position
;
4259 *position
= display_prop_end (it
, object
, start_pos
);
4262 /* Stop the scan at that end position--we assume that all
4263 text properties change there. */
4264 it
->stop_charpos
= position
->charpos
;
4266 /* Handle `(left-fringe BITMAP [FACE])'
4267 and `(right-fringe BITMAP [FACE])'. */
4269 && (EQ (XCAR (spec
), Qleft_fringe
)
4270 || EQ (XCAR (spec
), Qright_fringe
))
4271 && CONSP (XCDR (spec
)))
4273 int face_id
= lookup_basic_face (it
->f
, DEFAULT_FACE_ID
);
4276 if (!FRAME_WINDOW_P (it
->f
))
4277 /* If we return here, POSITION has been advanced
4278 across the text with this property. */
4281 #ifdef HAVE_WINDOW_SYSTEM
4282 value
= XCAR (XCDR (spec
));
4283 if (!SYMBOLP (value
)
4284 || !(fringe_bitmap
= lookup_fringe_bitmap (value
)))
4285 /* If we return here, POSITION has been advanced
4286 across the text with this property. */
4289 if (CONSP (XCDR (XCDR (spec
))))
4291 Lisp_Object face_name
= XCAR (XCDR (XCDR (spec
)));
4292 int face_id2
= lookup_derived_face (it
->f
, face_name
,
4298 /* Save current settings of IT so that we can restore them
4299 when we are finished with the glyph property value. */
4301 save_pos
= it
->position
;
4302 it
->position
= *position
;
4304 it
->position
= save_pos
;
4306 it
->area
= TEXT_AREA
;
4307 it
->what
= IT_IMAGE
;
4308 it
->image_id
= -1; /* no image */
4309 it
->position
= start_pos
;
4310 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
4311 it
->method
= GET_FROM_IMAGE
;
4312 it
->from_overlay
= Qnil
;
4313 it
->face_id
= face_id
;
4315 /* Say that we haven't consumed the characters with
4316 `display' property yet. The call to pop_it in
4317 set_iterator_to_next will clean this up. */
4318 *position
= start_pos
;
4320 if (EQ (XCAR (spec
), Qleft_fringe
))
4322 it
->left_user_fringe_bitmap
= fringe_bitmap
;
4323 it
->left_user_fringe_face_id
= face_id
;
4327 it
->right_user_fringe_bitmap
= fringe_bitmap
;
4328 it
->right_user_fringe_face_id
= face_id
;
4330 #endif /* HAVE_WINDOW_SYSTEM */
4334 /* Prepare to handle `((margin left-margin) ...)',
4335 `((margin right-margin) ...)' and `((margin nil) ...)'
4336 prefixes for display specifications. */
4337 location
= Qunbound
;
4338 if (CONSP (spec
) && CONSP (XCAR (spec
)))
4342 value
= XCDR (spec
);
4344 value
= XCAR (value
);
4347 if (EQ (XCAR (tem
), Qmargin
)
4348 && (tem
= XCDR (tem
),
4349 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
4351 || EQ (tem
, Qleft_margin
)
4352 || EQ (tem
, Qright_margin
))))
4356 if (EQ (location
, Qunbound
))
4362 /* After this point, VALUE is the property after any
4363 margin prefix has been stripped. It must be a string,
4364 an image specification, or `(space ...)'.
4366 LOCATION specifies where to display: `left-margin',
4367 `right-margin' or nil. */
4369 valid_p
= (STRINGP (value
)
4370 #ifdef HAVE_WINDOW_SYSTEM
4371 || (FRAME_WINDOW_P (it
->f
) && valid_image_p (value
))
4372 #endif /* not HAVE_WINDOW_SYSTEM */
4373 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
4375 if (valid_p
&& !display_replaced_before_p
)
4377 /* Save current settings of IT so that we can restore them
4378 when we are finished with the glyph property value. */
4379 save_pos
= it
->position
;
4380 it
->position
= *position
;
4382 it
->position
= save_pos
;
4383 it
->from_overlay
= overlay
;
4385 if (NILP (location
))
4386 it
->area
= TEXT_AREA
;
4387 else if (EQ (location
, Qleft_margin
))
4388 it
->area
= LEFT_MARGIN_AREA
;
4390 it
->area
= RIGHT_MARGIN_AREA
;
4392 if (STRINGP (value
))
4395 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4396 it
->current
.overlay_string_index
= -1;
4397 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4398 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
4399 it
->method
= GET_FROM_STRING
;
4400 it
->stop_charpos
= 0;
4401 it
->string_from_display_prop_p
= 1;
4402 /* Say that we haven't consumed the characters with
4403 `display' property yet. The call to pop_it in
4404 set_iterator_to_next will clean this up. */
4405 if (BUFFERP (object
))
4406 *position
= start_pos
;
4408 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
4410 it
->method
= GET_FROM_STRETCH
;
4412 *position
= it
->position
= start_pos
;
4414 #ifdef HAVE_WINDOW_SYSTEM
4417 it
->what
= IT_IMAGE
;
4418 it
->image_id
= lookup_image (it
->f
, value
);
4419 it
->position
= start_pos
;
4420 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
4421 it
->method
= GET_FROM_IMAGE
;
4423 /* Say that we haven't consumed the characters with
4424 `display' property yet. The call to pop_it in
4425 set_iterator_to_next will clean this up. */
4426 *position
= start_pos
;
4428 #endif /* HAVE_WINDOW_SYSTEM */
4433 /* Invalid property or property not supported. Restore
4434 POSITION to what it was before. */
4435 *position
= start_pos
;
4440 /* Check if SPEC is a display sub-property value whose text should be
4441 treated as intangible. */
4444 single_display_spec_intangible_p (Lisp_Object prop
)
4446 /* Skip over `when FORM'. */
4447 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
4461 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4462 we don't need to treat text as intangible. */
4463 if (EQ (XCAR (prop
), Qmargin
))
4471 || EQ (XCAR (prop
), Qleft_margin
)
4472 || EQ (XCAR (prop
), Qright_margin
))
4476 return (CONSP (prop
)
4477 && (EQ (XCAR (prop
), Qimage
)
4478 || EQ (XCAR (prop
), Qspace
)));
4482 /* Check if PROP is a display property value whose text should be
4483 treated as intangible. */
4486 display_prop_intangible_p (Lisp_Object prop
)
4489 && CONSP (XCAR (prop
))
4490 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
4492 /* A list of sub-properties. */
4493 while (CONSP (prop
))
4495 if (single_display_spec_intangible_p (XCAR (prop
)))
4500 else if (VECTORP (prop
))
4502 /* A vector of sub-properties. */
4504 for (i
= 0; i
< ASIZE (prop
); ++i
)
4505 if (single_display_spec_intangible_p (AREF (prop
, i
)))
4509 return single_display_spec_intangible_p (prop
);
4515 /* Return 1 if PROP is a display sub-property value containing STRING. */
4518 single_display_spec_string_p (Lisp_Object prop
, Lisp_Object string
)
4520 if (EQ (string
, prop
))
4523 /* Skip over `when FORM'. */
4524 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
4533 /* Skip over `margin LOCATION'. */
4534 if (EQ (XCAR (prop
), Qmargin
))
4545 return CONSP (prop
) && EQ (XCAR (prop
), string
);
4549 /* Return 1 if STRING appears in the `display' property PROP. */
4552 display_prop_string_p (Lisp_Object prop
, Lisp_Object string
)
4555 && CONSP (XCAR (prop
))
4556 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
4558 /* A list of sub-properties. */
4559 while (CONSP (prop
))
4561 if (single_display_spec_string_p (XCAR (prop
), string
))
4566 else if (VECTORP (prop
))
4568 /* A vector of sub-properties. */
4570 for (i
= 0; i
< ASIZE (prop
); ++i
)
4571 if (single_display_spec_string_p (AREF (prop
, i
), string
))
4575 return single_display_spec_string_p (prop
, string
);
4580 /* Look for STRING in overlays and text properties in W's buffer,
4581 between character positions FROM and TO (excluding TO).
4582 BACK_P non-zero means look back (in this case, TO is supposed to be
4584 Value is the first character position where STRING was found, or
4585 zero if it wasn't found before hitting TO.
4587 W's buffer must be current.
4589 This function may only use code that doesn't eval because it is
4590 called asynchronously from note_mouse_highlight. */
4593 string_buffer_position_lim (struct window
*w
, Lisp_Object string
,
4594 EMACS_INT from
, EMACS_INT to
, int back_p
)
4596 Lisp_Object limit
, prop
, pos
;
4599 pos
= make_number (from
);
4601 if (!back_p
) /* looking forward */
4603 limit
= make_number (min (to
, ZV
));
4604 while (!found
&& !EQ (pos
, limit
))
4606 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
4607 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
4610 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
,
4614 else /* looking back */
4616 limit
= make_number (max (to
, BEGV
));
4617 while (!found
&& !EQ (pos
, limit
))
4619 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
4620 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
4623 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
4628 return found
? XINT (pos
) : 0;
4631 /* Determine which buffer position in W's buffer STRING comes from.
4632 AROUND_CHARPOS is an approximate position where it could come from.
4633 Value is the buffer position or 0 if it couldn't be determined.
4635 W's buffer must be current.
4637 This function is necessary because we don't record buffer positions
4638 in glyphs generated from strings (to keep struct glyph small).
4639 This function may only use code that doesn't eval because it is
4640 called asynchronously from note_mouse_highlight. */
4643 string_buffer_position (struct window
*w
, Lisp_Object string
, EMACS_INT around_charpos
)
4645 Lisp_Object limit
, prop
, pos
;
4646 const int MAX_DISTANCE
= 1000;
4647 EMACS_INT found
= string_buffer_position_lim (w
, string
, around_charpos
,
4648 around_charpos
+ MAX_DISTANCE
,
4652 found
= string_buffer_position_lim (w
, string
, around_charpos
,
4653 around_charpos
- MAX_DISTANCE
, 1);
4659 /***********************************************************************
4660 `composition' property
4661 ***********************************************************************/
4663 /* Set up iterator IT from `composition' property at its current
4664 position. Called from handle_stop. */
4666 static enum prop_handled
4667 handle_composition_prop (struct it
*it
)
4669 Lisp_Object prop
, string
;
4670 EMACS_INT pos
, pos_byte
, start
, end
;
4672 if (STRINGP (it
->string
))
4676 pos
= IT_STRING_CHARPOS (*it
);
4677 pos_byte
= IT_STRING_BYTEPOS (*it
);
4678 string
= it
->string
;
4679 s
= SDATA (string
) + pos_byte
;
4680 it
->c
= STRING_CHAR (s
);
4684 pos
= IT_CHARPOS (*it
);
4685 pos_byte
= IT_BYTEPOS (*it
);
4687 it
->c
= FETCH_CHAR (pos_byte
);
4690 /* If there's a valid composition and point is not inside of the
4691 composition (in the case that the composition is from the current
4692 buffer), draw a glyph composed from the composition components. */
4693 if (find_composition (pos
, -1, &start
, &end
, &prop
, string
)
4694 && COMPOSITION_VALID_P (start
, end
, prop
)
4695 && (STRINGP (it
->string
) || (PT
<= start
|| PT
>= end
)))
4699 if (STRINGP (it
->string
))
4700 pos_byte
= string_char_to_byte (it
->string
, start
);
4702 pos_byte
= CHAR_TO_BYTE (start
);
4704 it
->cmp_it
.id
= get_composition_id (start
, pos_byte
, end
- start
,
4707 if (it
->cmp_it
.id
>= 0)
4710 it
->cmp_it
.nchars
= COMPOSITION_LENGTH (prop
);
4711 it
->cmp_it
.nglyphs
= -1;
4715 return HANDLED_NORMALLY
;
4720 /***********************************************************************
4722 ***********************************************************************/
4724 /* The following structure is used to record overlay strings for
4725 later sorting in load_overlay_strings. */
4727 struct overlay_entry
4729 Lisp_Object overlay
;
4736 /* Set up iterator IT from overlay strings at its current position.
4737 Called from handle_stop. */
4739 static enum prop_handled
4740 handle_overlay_change (struct it
*it
)
4742 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
4743 return HANDLED_RECOMPUTE_PROPS
;
4745 return HANDLED_NORMALLY
;
4749 /* Set up the next overlay string for delivery by IT, if there is an
4750 overlay string to deliver. Called by set_iterator_to_next when the
4751 end of the current overlay string is reached. If there are more
4752 overlay strings to display, IT->string and
4753 IT->current.overlay_string_index are set appropriately here.
4754 Otherwise IT->string is set to nil. */
4757 next_overlay_string (struct it
*it
)
4759 ++it
->current
.overlay_string_index
;
4760 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
4762 /* No more overlay strings. Restore IT's settings to what
4763 they were before overlay strings were processed, and
4764 continue to deliver from current_buffer. */
4766 it
->ellipsis_p
= (it
->stack
[it
->sp
- 1].display_ellipsis_p
!= 0);
4769 || (NILP (it
->string
)
4770 && it
->method
== GET_FROM_BUFFER
4771 && it
->stop_charpos
>= BEGV
4772 && it
->stop_charpos
<= it
->end_charpos
));
4773 it
->current
.overlay_string_index
= -1;
4774 it
->n_overlay_strings
= 0;
4776 /* If we're at the end of the buffer, record that we have
4777 processed the overlay strings there already, so that
4778 next_element_from_buffer doesn't try it again. */
4779 if (NILP (it
->string
) && IT_CHARPOS (*it
) >= it
->end_charpos
)
4780 it
->overlay_strings_at_end_processed_p
= 1;
4784 /* There are more overlay strings to process. If
4785 IT->current.overlay_string_index has advanced to a position
4786 where we must load IT->overlay_strings with more strings, do
4788 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
4790 if (it
->current
.overlay_string_index
&& i
== 0)
4791 load_overlay_strings (it
, 0);
4793 /* Initialize IT to deliver display elements from the overlay
4795 it
->string
= it
->overlay_strings
[i
];
4796 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4797 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
4798 it
->method
= GET_FROM_STRING
;
4799 it
->stop_charpos
= 0;
4800 if (it
->cmp_it
.stop_pos
>= 0)
4801 it
->cmp_it
.stop_pos
= 0;
4808 /* Compare two overlay_entry structures E1 and E2. Used as a
4809 comparison function for qsort in load_overlay_strings. Overlay
4810 strings for the same position are sorted so that
4812 1. All after-strings come in front of before-strings, except
4813 when they come from the same overlay.
4815 2. Within after-strings, strings are sorted so that overlay strings
4816 from overlays with higher priorities come first.
4818 2. Within before-strings, strings are sorted so that overlay
4819 strings from overlays with higher priorities come last.
4821 Value is analogous to strcmp. */
4825 compare_overlay_entries (const void *e1
, const void *e2
)
4827 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4828 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4831 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4833 /* Let after-strings appear in front of before-strings if
4834 they come from different overlays. */
4835 if (EQ (entry1
->overlay
, entry2
->overlay
))
4836 result
= entry1
->after_string_p
? 1 : -1;
4838 result
= entry1
->after_string_p
? -1 : 1;
4840 else if (entry1
->after_string_p
)
4841 /* After-strings sorted in order of decreasing priority. */
4842 result
= entry2
->priority
- entry1
->priority
;
4844 /* Before-strings sorted in order of increasing priority. */
4845 result
= entry1
->priority
- entry2
->priority
;
4851 /* Load the vector IT->overlay_strings with overlay strings from IT's
4852 current buffer position, or from CHARPOS if that is > 0. Set
4853 IT->n_overlays to the total number of overlay strings found.
4855 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4856 a time. On entry into load_overlay_strings,
4857 IT->current.overlay_string_index gives the number of overlay
4858 strings that have already been loaded by previous calls to this
4861 IT->add_overlay_start contains an additional overlay start
4862 position to consider for taking overlay strings from, if non-zero.
4863 This position comes into play when the overlay has an `invisible'
4864 property, and both before and after-strings. When we've skipped to
4865 the end of the overlay, because of its `invisible' property, we
4866 nevertheless want its before-string to appear.
4867 IT->add_overlay_start will contain the overlay start position
4870 Overlay strings are sorted so that after-string strings come in
4871 front of before-string strings. Within before and after-strings,
4872 strings are sorted by overlay priority. See also function
4873 compare_overlay_entries. */
4876 load_overlay_strings (struct it
*it
, int charpos
)
4878 extern Lisp_Object Qwindow
, Qpriority
;
4879 Lisp_Object overlay
, window
, str
, invisible
;
4880 struct Lisp_Overlay
*ov
;
4883 int n
= 0, i
, j
, invis_p
;
4884 struct overlay_entry
*entries
4885 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4888 charpos
= IT_CHARPOS (*it
);
4890 /* Append the overlay string STRING of overlay OVERLAY to vector
4891 `entries' which has size `size' and currently contains `n'
4892 elements. AFTER_P non-zero means STRING is an after-string of
4894 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4897 Lisp_Object priority; \
4901 int new_size = 2 * size; \
4902 struct overlay_entry *old = entries; \
4904 (struct overlay_entry *) alloca (new_size \
4905 * sizeof *entries); \
4906 memcpy (entries, old, size * sizeof *entries); \
4910 entries[n].string = (STRING); \
4911 entries[n].overlay = (OVERLAY); \
4912 priority = Foverlay_get ((OVERLAY), Qpriority); \
4913 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4914 entries[n].after_string_p = (AFTER_P); \
4919 /* Process overlay before the overlay center. */
4920 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4922 XSETMISC (overlay
, ov
);
4923 xassert (OVERLAYP (overlay
));
4924 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4925 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4930 /* Skip this overlay if it doesn't start or end at IT's current
4932 if (end
!= charpos
&& start
!= charpos
)
4935 /* Skip this overlay if it doesn't apply to IT->w. */
4936 window
= Foverlay_get (overlay
, Qwindow
);
4937 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4940 /* If the text ``under'' the overlay is invisible, both before-
4941 and after-strings from this overlay are visible; start and
4942 end position are indistinguishable. */
4943 invisible
= Foverlay_get (overlay
, Qinvisible
);
4944 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4946 /* If overlay has a non-empty before-string, record it. */
4947 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4948 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4950 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4952 /* If overlay has a non-empty after-string, record it. */
4953 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4954 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4956 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4959 /* Process overlays after the overlay center. */
4960 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4962 XSETMISC (overlay
, ov
);
4963 xassert (OVERLAYP (overlay
));
4964 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4965 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4967 if (start
> charpos
)
4970 /* Skip this overlay if it doesn't start or end at IT's current
4972 if (end
!= charpos
&& start
!= charpos
)
4975 /* Skip this overlay if it doesn't apply to IT->w. */
4976 window
= Foverlay_get (overlay
, Qwindow
);
4977 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4980 /* If the text ``under'' the overlay is invisible, it has a zero
4981 dimension, and both before- and after-strings apply. */
4982 invisible
= Foverlay_get (overlay
, Qinvisible
);
4983 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4985 /* If overlay has a non-empty before-string, record it. */
4986 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4987 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4989 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4991 /* If overlay has a non-empty after-string, record it. */
4992 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4993 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4995 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4998 #undef RECORD_OVERLAY_STRING
5002 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
5004 /* Record the total number of strings to process. */
5005 it
->n_overlay_strings
= n
;
5007 /* IT->current.overlay_string_index is the number of overlay strings
5008 that have already been consumed by IT. Copy some of the
5009 remaining overlay strings to IT->overlay_strings. */
5011 j
= it
->current
.overlay_string_index
;
5012 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
5014 it
->overlay_strings
[i
] = entries
[j
].string
;
5015 it
->string_overlays
[i
++] = entries
[j
++].overlay
;
5022 /* Get the first chunk of overlay strings at IT's current buffer
5023 position, or at CHARPOS if that is > 0. Value is non-zero if at
5024 least one overlay string was found. */
5027 get_overlay_strings_1 (struct it
*it
, int charpos
, int compute_stop_p
)
5029 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5030 process. This fills IT->overlay_strings with strings, and sets
5031 IT->n_overlay_strings to the total number of strings to process.
5032 IT->pos.overlay_string_index has to be set temporarily to zero
5033 because load_overlay_strings needs this; it must be set to -1
5034 when no overlay strings are found because a zero value would
5035 indicate a position in the first overlay string. */
5036 it
->current
.overlay_string_index
= 0;
5037 load_overlay_strings (it
, charpos
);
5039 /* If we found overlay strings, set up IT to deliver display
5040 elements from the first one. Otherwise set up IT to deliver
5041 from current_buffer. */
5042 if (it
->n_overlay_strings
)
5044 /* Make sure we know settings in current_buffer, so that we can
5045 restore meaningful values when we're done with the overlay
5048 compute_stop_pos (it
);
5049 xassert (it
->face_id
>= 0);
5051 /* Save IT's settings. They are restored after all overlay
5052 strings have been processed. */
5053 xassert (!compute_stop_p
|| it
->sp
== 0);
5055 /* When called from handle_stop, there might be an empty display
5056 string loaded. In that case, don't bother saving it. */
5057 if (!STRINGP (it
->string
) || SCHARS (it
->string
))
5060 /* Set up IT to deliver display elements from the first overlay
5062 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5063 it
->string
= it
->overlay_strings
[0];
5064 it
->from_overlay
= Qnil
;
5065 it
->stop_charpos
= 0;
5066 xassert (STRINGP (it
->string
));
5067 it
->end_charpos
= SCHARS (it
->string
);
5068 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5069 it
->method
= GET_FROM_STRING
;
5073 it
->current
.overlay_string_index
= -1;
5078 get_overlay_strings (struct it
*it
, int charpos
)
5081 it
->method
= GET_FROM_BUFFER
;
5083 (void) get_overlay_strings_1 (it
, charpos
, 1);
5087 /* Value is non-zero if we found at least one overlay string. */
5088 return STRINGP (it
->string
);
5093 /***********************************************************************
5094 Saving and restoring state
5095 ***********************************************************************/
5097 /* Save current settings of IT on IT->stack. Called, for example,
5098 before setting up IT for an overlay string, to be able to restore
5099 IT's settings to what they were after the overlay string has been
5103 push_it (struct it
*it
)
5105 struct iterator_stack_entry
*p
;
5107 xassert (it
->sp
< IT_STACK_SIZE
);
5108 p
= it
->stack
+ it
->sp
;
5110 p
->stop_charpos
= it
->stop_charpos
;
5111 p
->prev_stop
= it
->prev_stop
;
5112 p
->base_level_stop
= it
->base_level_stop
;
5113 p
->cmp_it
= it
->cmp_it
;
5114 xassert (it
->face_id
>= 0);
5115 p
->face_id
= it
->face_id
;
5116 p
->string
= it
->string
;
5117 p
->method
= it
->method
;
5118 p
->from_overlay
= it
->from_overlay
;
5121 case GET_FROM_IMAGE
:
5122 p
->u
.image
.object
= it
->object
;
5123 p
->u
.image
.image_id
= it
->image_id
;
5124 p
->u
.image
.slice
= it
->slice
;
5126 case GET_FROM_STRETCH
:
5127 p
->u
.stretch
.object
= it
->object
;
5130 p
->position
= it
->position
;
5131 p
->current
= it
->current
;
5132 p
->end_charpos
= it
->end_charpos
;
5133 p
->string_nchars
= it
->string_nchars
;
5135 p
->multibyte_p
= it
->multibyte_p
;
5136 p
->avoid_cursor_p
= it
->avoid_cursor_p
;
5137 p
->space_width
= it
->space_width
;
5138 p
->font_height
= it
->font_height
;
5139 p
->voffset
= it
->voffset
;
5140 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
5141 p
->display_ellipsis_p
= 0;
5142 p
->line_wrap
= it
->line_wrap
;
5147 iterate_out_of_display_property (struct it
*it
)
5149 /* Maybe initialize paragraph direction. If we are at the beginning
5150 of a new paragraph, next_element_from_buffer may not have a
5151 chance to do that. */
5152 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< ZV
)
5153 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
5154 /* prev_stop can be zero, so check against BEGV as well. */
5155 while (it
->bidi_it
.charpos
>= BEGV
5156 && it
->prev_stop
<= it
->bidi_it
.charpos
5157 && it
->bidi_it
.charpos
< CHARPOS (it
->position
))
5158 bidi_move_to_visually_next (&it
->bidi_it
);
5159 /* Record the stop_pos we just crossed, for when we cross it
5161 if (it
->bidi_it
.charpos
> CHARPOS (it
->position
))
5162 it
->prev_stop
= CHARPOS (it
->position
);
5163 /* If we ended up not where pop_it put us, resync IT's
5164 positional members with the bidi iterator. */
5165 if (it
->bidi_it
.charpos
!= CHARPOS (it
->position
))
5167 SET_TEXT_POS (it
->position
,
5168 it
->bidi_it
.charpos
, it
->bidi_it
.bytepos
);
5169 it
->current
.pos
= it
->position
;
5173 /* Restore IT's settings from IT->stack. Called, for example, when no
5174 more overlay strings must be processed, and we return to delivering
5175 display elements from a buffer, or when the end of a string from a
5176 `display' property is reached and we return to delivering display
5177 elements from an overlay string, or from a buffer. */
5180 pop_it (struct it
*it
)
5182 struct iterator_stack_entry
*p
;
5184 xassert (it
->sp
> 0);
5186 p
= it
->stack
+ it
->sp
;
5187 it
->stop_charpos
= p
->stop_charpos
;
5188 it
->prev_stop
= p
->prev_stop
;
5189 it
->base_level_stop
= p
->base_level_stop
;
5190 it
->cmp_it
= p
->cmp_it
;
5191 it
->face_id
= p
->face_id
;
5192 it
->current
= p
->current
;
5193 it
->position
= p
->position
;
5194 it
->string
= p
->string
;
5195 it
->from_overlay
= p
->from_overlay
;
5196 if (NILP (it
->string
))
5197 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
5198 it
->method
= p
->method
;
5201 case GET_FROM_IMAGE
:
5202 it
->image_id
= p
->u
.image
.image_id
;
5203 it
->object
= p
->u
.image
.object
;
5204 it
->slice
= p
->u
.image
.slice
;
5206 case GET_FROM_STRETCH
:
5207 it
->object
= p
->u
.comp
.object
;
5209 case GET_FROM_BUFFER
:
5210 it
->object
= it
->w
->buffer
;
5213 /* Bidi-iterate until we get out of the portion of text, if
5214 any, covered by a `display' text property or an overlay
5215 with `display' property. (We cannot just jump there,
5216 because the internal coherency of the bidi iterator state
5217 can not be preserved across such jumps.) We also must
5218 determine the paragraph base direction if the overlay we
5219 just processed is at the beginning of a new
5221 iterate_out_of_display_property (it
);
5224 case GET_FROM_STRING
:
5225 it
->object
= it
->string
;
5227 case GET_FROM_DISPLAY_VECTOR
:
5229 it
->method
= GET_FROM_C_STRING
;
5230 else if (STRINGP (it
->string
))
5231 it
->method
= GET_FROM_STRING
;
5234 it
->method
= GET_FROM_BUFFER
;
5235 it
->object
= it
->w
->buffer
;
5238 it
->end_charpos
= p
->end_charpos
;
5239 it
->string_nchars
= p
->string_nchars
;
5241 it
->multibyte_p
= p
->multibyte_p
;
5242 it
->avoid_cursor_p
= p
->avoid_cursor_p
;
5243 it
->space_width
= p
->space_width
;
5244 it
->font_height
= p
->font_height
;
5245 it
->voffset
= p
->voffset
;
5246 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
5247 it
->line_wrap
= p
->line_wrap
;
5252 /***********************************************************************
5254 ***********************************************************************/
5256 /* Set IT's current position to the previous line start. */
5259 back_to_previous_line_start (struct it
*it
)
5261 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
5262 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
5266 /* Move IT to the next line start.
5268 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5269 we skipped over part of the text (as opposed to moving the iterator
5270 continuously over the text). Otherwise, don't change the value
5273 Newlines may come from buffer text, overlay strings, or strings
5274 displayed via the `display' property. That's the reason we can't
5275 simply use find_next_newline_no_quit.
5277 Note that this function may not skip over invisible text that is so
5278 because of text properties and immediately follows a newline. If
5279 it would, function reseat_at_next_visible_line_start, when called
5280 from set_iterator_to_next, would effectively make invisible
5281 characters following a newline part of the wrong glyph row, which
5282 leads to wrong cursor motion. */
5285 forward_to_next_line_start (struct it
*it
, int *skipped_p
)
5287 int old_selective
, newline_found_p
, n
;
5288 const int MAX_NEWLINE_DISTANCE
= 500;
5290 /* If already on a newline, just consume it to avoid unintended
5291 skipping over invisible text below. */
5292 if (it
->what
== IT_CHARACTER
5294 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
5296 set_iterator_to_next (it
, 0);
5301 /* Don't handle selective display in the following. It's (a)
5302 unnecessary because it's done by the caller, and (b) leads to an
5303 infinite recursion because next_element_from_ellipsis indirectly
5304 calls this function. */
5305 old_selective
= it
->selective
;
5308 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5309 from buffer text. */
5310 for (n
= newline_found_p
= 0;
5311 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
5312 n
+= STRINGP (it
->string
) ? 0 : 1)
5314 if (!get_next_display_element (it
))
5316 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
5317 set_iterator_to_next (it
, 0);
5320 /* If we didn't find a newline near enough, see if we can use a
5322 if (!newline_found_p
)
5324 int start
= IT_CHARPOS (*it
);
5325 int limit
= find_next_newline_no_quit (start
, 1);
5328 xassert (!STRINGP (it
->string
));
5330 /* If there isn't any `display' property in sight, and no
5331 overlays, we can just use the position of the newline in
5333 if (it
->stop_charpos
>= limit
5334 || ((pos
= Fnext_single_property_change (make_number (start
),
5336 Qnil
, make_number (limit
)),
5338 && next_overlay_change (start
) == ZV
))
5340 IT_CHARPOS (*it
) = limit
;
5341 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
5342 *skipped_p
= newline_found_p
= 1;
5346 while (get_next_display_element (it
)
5347 && !newline_found_p
)
5349 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
5350 set_iterator_to_next (it
, 0);
5355 it
->selective
= old_selective
;
5356 return newline_found_p
;
5360 /* Set IT's current position to the previous visible line start. Skip
5361 invisible text that is so either due to text properties or due to
5362 selective display. Caution: this does not change IT->current_x and
5366 back_to_previous_visible_line_start (struct it
*it
)
5368 while (IT_CHARPOS (*it
) > BEGV
)
5370 back_to_previous_line_start (it
);
5372 if (IT_CHARPOS (*it
) <= BEGV
)
5375 /* If selective > 0, then lines indented more than its value are
5377 if (it
->selective
> 0
5378 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
5379 (double) it
->selective
)) /* iftc */
5382 /* Check the newline before point for invisibility. */
5385 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
) - 1),
5386 Qinvisible
, it
->window
);
5387 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
5391 if (IT_CHARPOS (*it
) <= BEGV
)
5398 Lisp_Object val
, overlay
;
5400 /* If newline is part of a composition, continue from start of composition */
5401 if (find_composition (IT_CHARPOS (*it
), -1, &beg
, &end
, &val
, Qnil
)
5402 && beg
< IT_CHARPOS (*it
))
5405 /* If newline is replaced by a display property, find start of overlay
5406 or interval and continue search from that point. */
5408 pos
= --IT_CHARPOS (it2
);
5411 it2
.string_from_display_prop_p
= 0;
5412 if (handle_display_prop (&it2
) == HANDLED_RETURN
5413 && !NILP (val
= get_char_property_and_overlay
5414 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
5415 && (OVERLAYP (overlay
)
5416 ? (beg
= OVERLAY_POSITION (OVERLAY_START (overlay
)))
5417 : get_property_and_range (pos
, Qdisplay
, &val
, &beg
, &end
, Qnil
)))
5420 /* Newline is not replaced by anything -- so we are done. */
5426 IT_CHARPOS (*it
) = beg
;
5427 IT_BYTEPOS (*it
) = buf_charpos_to_bytepos (current_buffer
, beg
);
5431 it
->continuation_lines_width
= 0;
5433 xassert (IT_CHARPOS (*it
) >= BEGV
);
5434 xassert (IT_CHARPOS (*it
) == BEGV
5435 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
5440 /* Reseat iterator IT at the previous visible line start. Skip
5441 invisible text that is so either due to text properties or due to
5442 selective display. At the end, update IT's overlay information,
5443 face information etc. */
5446 reseat_at_previous_visible_line_start (struct it
*it
)
5448 back_to_previous_visible_line_start (it
);
5449 reseat (it
, it
->current
.pos
, 1);
5454 /* Reseat iterator IT on the next visible line start in the current
5455 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5456 preceding the line start. Skip over invisible text that is so
5457 because of selective display. Compute faces, overlays etc at the
5458 new position. Note that this function does not skip over text that
5459 is invisible because of text properties. */
5462 reseat_at_next_visible_line_start (struct it
*it
, int on_newline_p
)
5464 int newline_found_p
, skipped_p
= 0;
5466 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
5468 /* Skip over lines that are invisible because they are indented
5469 more than the value of IT->selective. */
5470 if (it
->selective
> 0)
5471 while (IT_CHARPOS (*it
) < ZV
5472 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
5473 (double) it
->selective
)) /* iftc */
5475 xassert (IT_BYTEPOS (*it
) == BEGV
5476 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
5477 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
5480 /* Position on the newline if that's what's requested. */
5481 if (on_newline_p
&& newline_found_p
)
5483 if (STRINGP (it
->string
))
5485 if (IT_STRING_CHARPOS (*it
) > 0)
5487 --IT_STRING_CHARPOS (*it
);
5488 --IT_STRING_BYTEPOS (*it
);
5491 else if (IT_CHARPOS (*it
) > BEGV
)
5495 reseat (it
, it
->current
.pos
, 0);
5499 reseat (it
, it
->current
.pos
, 0);
5506 /***********************************************************************
5507 Changing an iterator's position
5508 ***********************************************************************/
5510 /* Change IT's current position to POS in current_buffer. If FORCE_P
5511 is non-zero, always check for text properties at the new position.
5512 Otherwise, text properties are only looked up if POS >=
5513 IT->check_charpos of a property. */
5516 reseat (struct it
*it
, struct text_pos pos
, int force_p
)
5518 int original_pos
= IT_CHARPOS (*it
);
5520 reseat_1 (it
, pos
, 0);
5522 /* Determine where to check text properties. Avoid doing it
5523 where possible because text property lookup is very expensive. */
5525 || CHARPOS (pos
) > it
->stop_charpos
5526 || CHARPOS (pos
) < original_pos
)
5530 /* For bidi iteration, we need to prime prev_stop and
5531 base_level_stop with our best estimations. */
5532 if (CHARPOS (pos
) < it
->prev_stop
)
5534 handle_stop_backwards (it
, BEGV
);
5535 if (CHARPOS (pos
) < it
->base_level_stop
)
5536 it
->base_level_stop
= 0;
5538 else if (CHARPOS (pos
) > it
->stop_charpos
5539 && it
->stop_charpos
>= BEGV
)
5540 handle_stop_backwards (it
, it
->stop_charpos
);
5547 it
->prev_stop
= it
->base_level_stop
= 0;
5556 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5557 IT->stop_pos to POS, also. */
5560 reseat_1 (struct it
*it
, struct text_pos pos
, int set_stop_p
)
5562 /* Don't call this function when scanning a C string. */
5563 xassert (it
->s
== NULL
);
5565 /* POS must be a reasonable value. */
5566 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
5568 it
->current
.pos
= it
->position
= pos
;
5569 it
->end_charpos
= ZV
;
5571 it
->current
.dpvec_index
= -1;
5572 it
->current
.overlay_string_index
= -1;
5573 IT_STRING_CHARPOS (*it
) = -1;
5574 IT_STRING_BYTEPOS (*it
) = -1;
5576 it
->string_from_display_prop_p
= 0;
5577 it
->method
= GET_FROM_BUFFER
;
5578 it
->object
= it
->w
->buffer
;
5579 it
->area
= TEXT_AREA
;
5580 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
5582 it
->string_from_display_prop_p
= 0;
5583 it
->face_before_selective_p
= 0;
5585 it
->bidi_it
.first_elt
= 1;
5589 it
->stop_charpos
= CHARPOS (pos
);
5590 it
->base_level_stop
= CHARPOS (pos
);
5595 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5596 If S is non-null, it is a C string to iterate over. Otherwise,
5597 STRING gives a Lisp string to iterate over.
5599 If PRECISION > 0, don't return more then PRECISION number of
5600 characters from the string.
5602 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5603 characters have been returned. FIELD_WIDTH < 0 means an infinite
5606 MULTIBYTE = 0 means disable processing of multibyte characters,
5607 MULTIBYTE > 0 means enable it,
5608 MULTIBYTE < 0 means use IT->multibyte_p.
5610 IT must be initialized via a prior call to init_iterator before
5611 calling this function. */
5614 reseat_to_string (struct it
*it
, unsigned char *s
, Lisp_Object string
,
5615 int charpos
, int precision
, int field_width
, int multibyte
)
5617 /* No region in strings. */
5618 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
5620 /* No text property checks performed by default, but see below. */
5621 it
->stop_charpos
= -1;
5623 /* Set iterator position and end position. */
5624 memset (&it
->current
, 0, sizeof it
->current
);
5625 it
->current
.overlay_string_index
= -1;
5626 it
->current
.dpvec_index
= -1;
5627 xassert (charpos
>= 0);
5629 /* If STRING is specified, use its multibyteness, otherwise use the
5630 setting of MULTIBYTE, if specified. */
5632 it
->multibyte_p
= multibyte
> 0;
5636 xassert (STRINGP (string
));
5637 it
->string
= string
;
5639 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
5640 it
->method
= GET_FROM_STRING
;
5641 it
->current
.string_pos
= string_pos (charpos
, string
);
5648 /* Note that we use IT->current.pos, not it->current.string_pos,
5649 for displaying C strings. */
5650 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
5651 if (it
->multibyte_p
)
5653 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
5654 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
5658 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
5659 it
->end_charpos
= it
->string_nchars
= strlen (s
);
5662 it
->method
= GET_FROM_C_STRING
;
5665 /* PRECISION > 0 means don't return more than PRECISION characters
5667 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
5668 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
5670 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5671 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5672 FIELD_WIDTH < 0 means infinite field width. This is useful for
5673 padding with `-' at the end of a mode line. */
5674 if (field_width
< 0)
5675 field_width
= INFINITY
;
5676 if (field_width
> it
->end_charpos
- charpos
)
5677 it
->end_charpos
= charpos
+ field_width
;
5679 /* Use the standard display table for displaying strings. */
5680 if (DISP_TABLE_P (Vstandard_display_table
))
5681 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
5683 it
->stop_charpos
= charpos
;
5684 if (s
== NULL
&& it
->multibyte_p
)
5686 EMACS_INT endpos
= SCHARS (it
->string
);
5687 if (endpos
> it
->end_charpos
)
5688 endpos
= it
->end_charpos
;
5689 composition_compute_stop_pos (&it
->cmp_it
, charpos
, -1, endpos
,
5697 /***********************************************************************
5699 ***********************************************************************/
5701 /* Map enum it_method value to corresponding next_element_from_* function. */
5703 static int (* get_next_element
[NUM_IT_METHODS
]) (struct it
*it
) =
5705 next_element_from_buffer
,
5706 next_element_from_display_vector
,
5707 next_element_from_string
,
5708 next_element_from_c_string
,
5709 next_element_from_image
,
5710 next_element_from_stretch
5713 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5716 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5717 (possibly with the following characters). */
5719 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5720 ((IT)->cmp_it.id >= 0 \
5721 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5722 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5723 END_CHARPOS, (IT)->w, \
5724 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5728 /* Load IT's display element fields with information about the next
5729 display element from the current position of IT. Value is zero if
5730 end of buffer (or C string) is reached. */
5732 static struct frame
*last_escape_glyph_frame
= NULL
;
5733 static unsigned last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
5734 static int last_escape_glyph_merged_face_id
= 0;
5737 get_next_display_element (struct it
*it
)
5739 /* Non-zero means that we found a display element. Zero means that
5740 we hit the end of what we iterate over. Performance note: the
5741 function pointer `method' used here turns out to be faster than
5742 using a sequence of if-statements. */
5746 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
5748 if (it
->what
== IT_CHARACTER
)
5750 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5751 and only if (a) the resolved directionality of that character
5753 /* FIXME: Do we need an exception for characters from display
5755 if (it
->bidi_p
&& it
->bidi_it
.type
== STRONG_R
)
5756 it
->c
= bidi_mirror_char (it
->c
);
5757 /* Map via display table or translate control characters.
5758 IT->c, IT->len etc. have been set to the next character by
5759 the function call above. If we have a display table, and it
5760 contains an entry for IT->c, translate it. Don't do this if
5761 IT->c itself comes from a display table, otherwise we could
5762 end up in an infinite recursion. (An alternative could be to
5763 count the recursion depth of this function and signal an
5764 error when a certain maximum depth is reached.) Is it worth
5766 if (success_p
&& it
->dpvec
== NULL
)
5769 struct charset
*unibyte
= CHARSET_FROM_ID (charset_unibyte
);
5770 enum { char_is_other
= 0, char_is_nbsp
, char_is_soft_hyphen
}
5771 nbsp_or_shy
= char_is_other
;
5772 int decoded
= it
->c
;
5775 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
5778 struct Lisp_Vector
*v
= XVECTOR (dv
);
5780 /* Return the first character from the display table
5781 entry, if not empty. If empty, don't display the
5782 current character. */
5785 it
->dpvec_char_len
= it
->len
;
5786 it
->dpvec
= v
->contents
;
5787 it
->dpend
= v
->contents
+ v
->size
;
5788 it
->current
.dpvec_index
= 0;
5789 it
->dpvec_face_id
= -1;
5790 it
->saved_face_id
= it
->face_id
;
5791 it
->method
= GET_FROM_DISPLAY_VECTOR
;
5796 set_iterator_to_next (it
, 0);
5801 if (unibyte_display_via_language_environment
5802 && !ASCII_CHAR_P (it
->c
))
5803 decoded
= DECODE_CHAR (unibyte
, it
->c
);
5805 if (it
->c
>= 0x80 && ! NILP (Vnobreak_char_display
))
5807 if (it
->multibyte_p
)
5808 nbsp_or_shy
= (it
->c
== 0xA0 ? char_is_nbsp
5809 : it
->c
== 0xAD ? char_is_soft_hyphen
5811 else if (unibyte_display_via_language_environment
)
5812 nbsp_or_shy
= (decoded
== 0xA0 ? char_is_nbsp
5813 : decoded
== 0xAD ? char_is_soft_hyphen
5817 /* Translate control characters into `\003' or `^C' form.
5818 Control characters coming from a display table entry are
5819 currently not translated because we use IT->dpvec to hold
5820 the translation. This could easily be changed but I
5821 don't believe that it is worth doing.
5823 If it->multibyte_p is nonzero, non-printable non-ASCII
5824 characters are also translated to octal form.
5826 If it->multibyte_p is zero, eight-bit characters that
5827 don't have corresponding multibyte char code are also
5828 translated to octal form. */
5830 ? (it
->area
!= TEXT_AREA
5831 /* In mode line, treat \n, \t like other crl chars. */
5834 && (it
->glyph_row
->mode_line_p
|| it
->avoid_cursor_p
))
5835 || (it
->c
!= '\n' && it
->c
!= '\t'))
5838 ? ! CHAR_PRINTABLE_P (it
->c
)
5839 : (! unibyte_display_via_language_environment
5841 : (decoded
>= 0x80 && decoded
< 0xA0))))))
5843 /* IT->c is a control character which must be displayed
5844 either as '\003' or as `^C' where the '\\' and '^'
5845 can be defined in the display table. Fill
5846 IT->ctl_chars with glyphs for what we have to
5847 display. Then, set IT->dpvec to these glyphs. */
5850 int face_id
, lface_id
= 0 ;
5853 /* Handle control characters with ^. */
5855 if (it
->c
< 128 && it
->ctl_arrow_p
)
5859 g
= '^'; /* default glyph for Control */
5860 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5862 && (gc
= DISP_CTRL_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
5863 && GLYPH_CODE_CHAR_VALID_P (gc
))
5865 g
= GLYPH_CODE_CHAR (gc
);
5866 lface_id
= GLYPH_CODE_FACE (gc
);
5870 face_id
= merge_faces (it
->f
, Qt
, lface_id
, it
->face_id
);
5872 else if (it
->f
== last_escape_glyph_frame
5873 && it
->face_id
== last_escape_glyph_face_id
)
5875 face_id
= last_escape_glyph_merged_face_id
;
5879 /* Merge the escape-glyph face into the current face. */
5880 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
5882 last_escape_glyph_frame
= it
->f
;
5883 last_escape_glyph_face_id
= it
->face_id
;
5884 last_escape_glyph_merged_face_id
= face_id
;
5887 XSETINT (it
->ctl_chars
[0], g
);
5888 XSETINT (it
->ctl_chars
[1], it
->c
^ 0100);
5890 goto display_control
;
5893 /* Handle non-break space in the mode where it only gets
5896 if (EQ (Vnobreak_char_display
, Qt
)
5897 && nbsp_or_shy
== char_is_nbsp
)
5899 /* Merge the no-break-space face into the current face. */
5900 face_id
= merge_faces (it
->f
, Qnobreak_space
, 0,
5904 XSETINT (it
->ctl_chars
[0], ' ');
5906 goto display_control
;
5909 /* Handle sequences that start with the "escape glyph". */
5911 /* the default escape glyph is \. */
5912 escape_glyph
= '\\';
5915 && (gc
= DISP_ESCAPE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
5916 && GLYPH_CODE_CHAR_VALID_P (gc
))
5918 escape_glyph
= GLYPH_CODE_CHAR (gc
);
5919 lface_id
= GLYPH_CODE_FACE (gc
);
5923 /* The display table specified a face.
5924 Merge it into face_id and also into escape_glyph. */
5925 face_id
= merge_faces (it
->f
, Qt
, lface_id
,
5928 else if (it
->f
== last_escape_glyph_frame
5929 && it
->face_id
== last_escape_glyph_face_id
)
5931 face_id
= last_escape_glyph_merged_face_id
;
5935 /* Merge the escape-glyph face into the current face. */
5936 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
5938 last_escape_glyph_frame
= it
->f
;
5939 last_escape_glyph_face_id
= it
->face_id
;
5940 last_escape_glyph_merged_face_id
= face_id
;
5943 /* Handle soft hyphens in the mode where they only get
5946 if (EQ (Vnobreak_char_display
, Qt
)
5947 && nbsp_or_shy
== char_is_soft_hyphen
)
5950 XSETINT (it
->ctl_chars
[0], '-');
5952 goto display_control
;
5955 /* Handle non-break space and soft hyphen
5956 with the escape glyph. */
5960 XSETINT (it
->ctl_chars
[0], escape_glyph
);
5961 it
->c
= (nbsp_or_shy
== char_is_nbsp
? ' ' : '-');
5962 XSETINT (it
->ctl_chars
[1], it
->c
);
5964 goto display_control
;
5968 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
5972 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5973 if (CHAR_BYTE8_P (it
->c
))
5975 str
[0] = CHAR_TO_BYTE8 (it
->c
);
5978 else if (it
->c
< 256)
5985 /* It's an invalid character, which shouldn't
5986 happen actually, but due to bugs it may
5987 happen. Let's print the char as is, there's
5988 not much meaningful we can do with it. */
5990 str
[1] = it
->c
>> 8;
5991 str
[2] = it
->c
>> 16;
5992 str
[3] = it
->c
>> 24;
5996 for (i
= 0; i
< len
; i
++)
5999 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
6000 /* Insert three more glyphs into IT->ctl_chars for
6001 the octal display of the character. */
6002 g
= ((str
[i
] >> 6) & 7) + '0';
6003 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
6004 g
= ((str
[i
] >> 3) & 7) + '0';
6005 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
6006 g
= (str
[i
] & 7) + '0';
6007 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
6013 /* Set up IT->dpvec and return first character from it. */
6014 it
->dpvec_char_len
= it
->len
;
6015 it
->dpvec
= it
->ctl_chars
;
6016 it
->dpend
= it
->dpvec
+ ctl_len
;
6017 it
->current
.dpvec_index
= 0;
6018 it
->dpvec_face_id
= face_id
;
6019 it
->saved_face_id
= it
->face_id
;
6020 it
->method
= GET_FROM_DISPLAY_VECTOR
;
6027 #ifdef HAVE_WINDOW_SYSTEM
6028 /* Adjust face id for a multibyte character. There are no multibyte
6029 character in unibyte text. */
6030 if ((it
->what
== IT_CHARACTER
|| it
->what
== IT_COMPOSITION
)
6033 && FRAME_WINDOW_P (it
->f
))
6035 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
6037 if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
>= 0)
6039 /* Automatic composition with glyph-string. */
6040 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
6042 it
->face_id
= face_for_font (it
->f
, LGSTRING_FONT (gstring
), face
);
6046 int pos
= (it
->s
? -1
6047 : STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
6048 : IT_CHARPOS (*it
));
6050 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
, pos
, it
->string
);
6055 /* Is this character the last one of a run of characters with
6056 box? If yes, set IT->end_of_box_run_p to 1. */
6060 if (it
->method
== GET_FROM_STRING
&& it
->sp
)
6062 int face_id
= underlying_face_id (it
);
6063 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
6067 if (face
->box
== FACE_NO_BOX
)
6069 /* If the box comes from face properties in a
6070 display string, check faces in that string. */
6071 int string_face_id
= face_after_it_pos (it
);
6072 it
->end_of_box_run_p
6073 = (FACE_FROM_ID (it
->f
, string_face_id
)->box
6076 /* Otherwise, the box comes from the underlying face.
6077 If this is the last string character displayed, check
6078 the next buffer location. */
6079 else if ((IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
) - 1)
6080 && (it
->current
.overlay_string_index
6081 == it
->n_overlay_strings
- 1))
6085 struct text_pos pos
= it
->current
.pos
;
6086 INC_TEXT_POS (pos
, it
->multibyte_p
);
6088 next_face_id
= face_at_buffer_position
6089 (it
->w
, CHARPOS (pos
), it
->region_beg_charpos
,
6090 it
->region_end_charpos
, &ignore
,
6091 (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
), 0,
6093 it
->end_of_box_run_p
6094 = (FACE_FROM_ID (it
->f
, next_face_id
)->box
6101 int face_id
= face_after_it_pos (it
);
6102 it
->end_of_box_run_p
6103 = (face_id
!= it
->face_id
6104 && FACE_FROM_ID (it
->f
, face_id
)->box
== FACE_NO_BOX
);
6108 /* Value is 0 if end of buffer or string reached. */
6113 /* Move IT to the next display element.
6115 RESEAT_P non-zero means if called on a newline in buffer text,
6116 skip to the next visible line start.
6118 Functions get_next_display_element and set_iterator_to_next are
6119 separate because I find this arrangement easier to handle than a
6120 get_next_display_element function that also increments IT's
6121 position. The way it is we can first look at an iterator's current
6122 display element, decide whether it fits on a line, and if it does,
6123 increment the iterator position. The other way around we probably
6124 would either need a flag indicating whether the iterator has to be
6125 incremented the next time, or we would have to implement a
6126 decrement position function which would not be easy to write. */
6129 set_iterator_to_next (struct it
*it
, int reseat_p
)
6131 /* Reset flags indicating start and end of a sequence of characters
6132 with box. Reset them at the start of this function because
6133 moving the iterator to a new position might set them. */
6134 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
6138 case GET_FROM_BUFFER
:
6139 /* The current display element of IT is a character from
6140 current_buffer. Advance in the buffer, and maybe skip over
6141 invisible lines that are so because of selective display. */
6142 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
6143 reseat_at_next_visible_line_start (it
, 0);
6144 else if (it
->cmp_it
.id
>= 0)
6146 /* We are currently getting glyphs from a composition. */
6151 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
6152 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
6153 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
6155 it
->cmp_it
.from
= it
->cmp_it
.to
;
6160 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6162 it
->stop_charpos
, Qnil
);
6165 else if (! it
->cmp_it
.reversed_p
)
6167 /* Composition created while scanning forward. */
6168 /* Update IT's char/byte positions to point to the first
6169 character of the next grapheme cluster, or to the
6170 character visually after the current composition. */
6171 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
6172 bidi_move_to_visually_next (&it
->bidi_it
);
6173 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6174 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6176 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
6178 /* Proceed to the next grapheme cluster. */
6179 it
->cmp_it
.from
= it
->cmp_it
.to
;
6183 /* No more grapheme clusters in this composition.
6184 Find the next stop position. */
6185 EMACS_INT stop
= it
->stop_charpos
;
6186 if (it
->bidi_it
.scan_dir
< 0)
6187 /* Now we are scanning backward and don't know
6190 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6191 IT_BYTEPOS (*it
), stop
, Qnil
);
6196 /* Composition created while scanning backward. */
6197 /* Update IT's char/byte positions to point to the last
6198 character of the previous grapheme cluster, or the
6199 character visually after the current composition. */
6200 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
6201 bidi_move_to_visually_next (&it
->bidi_it
);
6202 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6203 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6204 if (it
->cmp_it
.from
> 0)
6206 /* Proceed to the previous grapheme cluster. */
6207 it
->cmp_it
.to
= it
->cmp_it
.from
;
6211 /* No more grapheme clusters in this composition.
6212 Find the next stop position. */
6213 EMACS_INT stop
= it
->stop_charpos
;
6214 if (it
->bidi_it
.scan_dir
< 0)
6215 /* Now we are scanning backward and don't know
6218 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6219 IT_BYTEPOS (*it
), stop
, Qnil
);
6225 xassert (it
->len
!= 0);
6229 IT_BYTEPOS (*it
) += it
->len
;
6230 IT_CHARPOS (*it
) += 1;
6234 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
6235 /* If this is a new paragraph, determine its base
6236 direction (a.k.a. its base embedding level). */
6237 if (it
->bidi_it
.new_paragraph
)
6238 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
6239 bidi_move_to_visually_next (&it
->bidi_it
);
6240 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6241 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6242 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
6244 /* As the scan direction was changed, we must
6245 re-compute the stop position for composition. */
6246 EMACS_INT stop
= it
->stop_charpos
;
6247 if (it
->bidi_it
.scan_dir
< 0)
6249 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6250 IT_BYTEPOS (*it
), stop
, Qnil
);
6253 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
6257 case GET_FROM_C_STRING
:
6258 /* Current display element of IT is from a C string. */
6259 IT_BYTEPOS (*it
) += it
->len
;
6260 IT_CHARPOS (*it
) += 1;
6263 case GET_FROM_DISPLAY_VECTOR
:
6264 /* Current display element of IT is from a display table entry.
6265 Advance in the display table definition. Reset it to null if
6266 end reached, and continue with characters from buffers/
6268 ++it
->current
.dpvec_index
;
6270 /* Restore face of the iterator to what they were before the
6271 display vector entry (these entries may contain faces). */
6272 it
->face_id
= it
->saved_face_id
;
6274 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
6276 int recheck_faces
= it
->ellipsis_p
;
6279 it
->method
= GET_FROM_C_STRING
;
6280 else if (STRINGP (it
->string
))
6281 it
->method
= GET_FROM_STRING
;
6284 it
->method
= GET_FROM_BUFFER
;
6285 it
->object
= it
->w
->buffer
;
6289 it
->current
.dpvec_index
= -1;
6291 /* Skip over characters which were displayed via IT->dpvec. */
6292 if (it
->dpvec_char_len
< 0)
6293 reseat_at_next_visible_line_start (it
, 1);
6294 else if (it
->dpvec_char_len
> 0)
6296 if (it
->method
== GET_FROM_STRING
6297 && it
->n_overlay_strings
> 0)
6298 it
->ignore_overlay_strings_at_pos_p
= 1;
6299 it
->len
= it
->dpvec_char_len
;
6300 set_iterator_to_next (it
, reseat_p
);
6303 /* Maybe recheck faces after display vector */
6305 it
->stop_charpos
= IT_CHARPOS (*it
);
6309 case GET_FROM_STRING
:
6310 /* Current display element is a character from a Lisp string. */
6311 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
6312 if (it
->cmp_it
.id
>= 0)
6314 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
6315 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
6316 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
6317 it
->cmp_it
.from
= it
->cmp_it
.to
;
6321 composition_compute_stop_pos (&it
->cmp_it
,
6322 IT_STRING_CHARPOS (*it
),
6323 IT_STRING_BYTEPOS (*it
),
6324 it
->stop_charpos
, it
->string
);
6329 IT_STRING_BYTEPOS (*it
) += it
->len
;
6330 IT_STRING_CHARPOS (*it
) += 1;
6333 consider_string_end
:
6335 if (it
->current
.overlay_string_index
>= 0)
6337 /* IT->string is an overlay string. Advance to the
6338 next, if there is one. */
6339 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
6342 next_overlay_string (it
);
6344 setup_for_ellipsis (it
, 0);
6349 /* IT->string is not an overlay string. If we reached
6350 its end, and there is something on IT->stack, proceed
6351 with what is on the stack. This can be either another
6352 string, this time an overlay string, or a buffer. */
6353 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
6357 if (it
->method
== GET_FROM_STRING
)
6358 goto consider_string_end
;
6363 case GET_FROM_IMAGE
:
6364 case GET_FROM_STRETCH
:
6365 /* The position etc with which we have to proceed are on
6366 the stack. The position may be at the end of a string,
6367 if the `display' property takes up the whole string. */
6368 xassert (it
->sp
> 0);
6370 if (it
->method
== GET_FROM_STRING
)
6371 goto consider_string_end
;
6375 /* There are no other methods defined, so this should be a bug. */
6379 xassert (it
->method
!= GET_FROM_STRING
6380 || (STRINGP (it
->string
)
6381 && IT_STRING_CHARPOS (*it
) >= 0));
6384 /* Load IT's display element fields with information about the next
6385 display element which comes from a display table entry or from the
6386 result of translating a control character to one of the forms `^C'
6389 IT->dpvec holds the glyphs to return as characters.
6390 IT->saved_face_id holds the face id before the display vector--it
6391 is restored into IT->face_id in set_iterator_to_next. */
6394 next_element_from_display_vector (struct it
*it
)
6399 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
6401 it
->face_id
= it
->saved_face_id
;
6403 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6404 That seemed totally bogus - so I changed it... */
6405 gc
= it
->dpvec
[it
->current
.dpvec_index
];
6407 if (GLYPH_CODE_P (gc
) && GLYPH_CODE_CHAR_VALID_P (gc
))
6409 it
->c
= GLYPH_CODE_CHAR (gc
);
6410 it
->len
= CHAR_BYTES (it
->c
);
6412 /* The entry may contain a face id to use. Such a face id is
6413 the id of a Lisp face, not a realized face. A face id of
6414 zero means no face is specified. */
6415 if (it
->dpvec_face_id
>= 0)
6416 it
->face_id
= it
->dpvec_face_id
;
6419 int lface_id
= GLYPH_CODE_FACE (gc
);
6421 it
->face_id
= merge_faces (it
->f
, Qt
, lface_id
,
6426 /* Display table entry is invalid. Return a space. */
6427 it
->c
= ' ', it
->len
= 1;
6429 /* Don't change position and object of the iterator here. They are
6430 still the values of the character that had this display table
6431 entry or was translated, and that's what we want. */
6432 it
->what
= IT_CHARACTER
;
6437 /* Load IT with the next display element from Lisp string IT->string.
6438 IT->current.string_pos is the current position within the string.
6439 If IT->current.overlay_string_index >= 0, the Lisp string is an
6443 next_element_from_string (struct it
*it
)
6445 struct text_pos position
;
6447 xassert (STRINGP (it
->string
));
6448 xassert (IT_STRING_CHARPOS (*it
) >= 0);
6449 position
= it
->current
.string_pos
;
6451 /* Time to check for invisible text? */
6452 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
6453 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
6457 /* Since a handler may have changed IT->method, we must
6459 return GET_NEXT_DISPLAY_ELEMENT (it
);
6462 if (it
->current
.overlay_string_index
>= 0)
6464 /* Get the next character from an overlay string. In overlay
6465 strings, There is no field width or padding with spaces to
6467 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
6472 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
6473 IT_STRING_BYTEPOS (*it
), SCHARS (it
->string
))
6474 && next_element_from_composition (it
))
6478 else if (STRING_MULTIBYTE (it
->string
))
6480 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
6481 const unsigned char *s
= (SDATA (it
->string
)
6482 + IT_STRING_BYTEPOS (*it
));
6483 it
->c
= string_char_and_length (s
, &it
->len
);
6487 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
6493 /* Get the next character from a Lisp string that is not an
6494 overlay string. Such strings come from the mode line, for
6495 example. We may have to pad with spaces, or truncate the
6496 string. See also next_element_from_c_string. */
6497 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
6502 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
6504 /* Pad with spaces. */
6505 it
->c
= ' ', it
->len
= 1;
6506 CHARPOS (position
) = BYTEPOS (position
) = -1;
6508 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
6509 IT_STRING_BYTEPOS (*it
), it
->string_nchars
)
6510 && next_element_from_composition (it
))
6514 else if (STRING_MULTIBYTE (it
->string
))
6516 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
6517 const unsigned char *s
= (SDATA (it
->string
)
6518 + IT_STRING_BYTEPOS (*it
));
6519 it
->c
= string_char_and_length (s
, &it
->len
);
6523 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
6528 /* Record what we have and where it came from. */
6529 it
->what
= IT_CHARACTER
;
6530 it
->object
= it
->string
;
6531 it
->position
= position
;
6536 /* Load IT with next display element from C string IT->s.
6537 IT->string_nchars is the maximum number of characters to return
6538 from the string. IT->end_charpos may be greater than
6539 IT->string_nchars when this function is called, in which case we
6540 may have to return padding spaces. Value is zero if end of string
6541 reached, including padding spaces. */
6544 next_element_from_c_string (struct it
*it
)
6549 it
->what
= IT_CHARACTER
;
6550 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
6553 /* IT's position can be greater IT->string_nchars in case a field
6554 width or precision has been specified when the iterator was
6556 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
6558 /* End of the game. */
6562 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
6564 /* Pad with spaces. */
6565 it
->c
= ' ', it
->len
= 1;
6566 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
6568 else if (it
->multibyte_p
)
6570 /* Implementation note: The calls to strlen apparently aren't a
6571 performance problem because there is no noticeable performance
6572 difference between Emacs running in unibyte or multibyte mode. */
6573 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
6574 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
), &it
->len
);
6577 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
6583 /* Set up IT to return characters from an ellipsis, if appropriate.
6584 The definition of the ellipsis glyphs may come from a display table
6585 entry. This function fills IT with the first glyph from the
6586 ellipsis if an ellipsis is to be displayed. */
6589 next_element_from_ellipsis (struct it
*it
)
6591 if (it
->selective_display_ellipsis_p
)
6592 setup_for_ellipsis (it
, it
->len
);
6595 /* The face at the current position may be different from the
6596 face we find after the invisible text. Remember what it
6597 was in IT->saved_face_id, and signal that it's there by
6598 setting face_before_selective_p. */
6599 it
->saved_face_id
= it
->face_id
;
6600 it
->method
= GET_FROM_BUFFER
;
6601 it
->object
= it
->w
->buffer
;
6602 reseat_at_next_visible_line_start (it
, 1);
6603 it
->face_before_selective_p
= 1;
6606 return GET_NEXT_DISPLAY_ELEMENT (it
);
6610 /* Deliver an image display element. The iterator IT is already
6611 filled with image information (done in handle_display_prop). Value
6616 next_element_from_image (struct it
*it
)
6618 it
->what
= IT_IMAGE
;
6619 it
->ignore_overlay_strings_at_pos_p
= 0;
6624 /* Fill iterator IT with next display element from a stretch glyph
6625 property. IT->object is the value of the text property. Value is
6629 next_element_from_stretch (struct it
*it
)
6631 it
->what
= IT_STRETCH
;
6635 /* Scan forward from CHARPOS in the current buffer, until we find a
6636 stop position > current IT's position. Then handle the stop
6637 position before that. This is called when we bump into a stop
6638 position while reordering bidirectional text. CHARPOS should be
6639 the last previously processed stop_pos (or BEGV, if none were
6640 processed yet) whose position is less that IT's current
6644 handle_stop_backwards (struct it
*it
, EMACS_INT charpos
)
6646 EMACS_INT where_we_are
= IT_CHARPOS (*it
);
6647 struct display_pos save_current
= it
->current
;
6648 struct text_pos save_position
= it
->position
;
6649 struct text_pos pos1
;
6650 EMACS_INT next_stop
;
6652 /* Scan in strict logical order. */
6656 it
->prev_stop
= charpos
;
6657 SET_TEXT_POS (pos1
, charpos
, CHAR_TO_BYTE (charpos
));
6658 reseat_1 (it
, pos1
, 0);
6659 compute_stop_pos (it
);
6660 /* We must advance forward, right? */
6661 if (it
->stop_charpos
<= it
->prev_stop
)
6663 charpos
= it
->stop_charpos
;
6665 while (charpos
<= where_we_are
);
6667 next_stop
= it
->stop_charpos
;
6668 it
->stop_charpos
= it
->prev_stop
;
6670 it
->current
= save_current
;
6671 it
->position
= save_position
;
6673 it
->stop_charpos
= next_stop
;
6676 /* Load IT with the next display element from current_buffer. Value
6677 is zero if end of buffer reached. IT->stop_charpos is the next
6678 position at which to stop and check for text properties or buffer
6682 next_element_from_buffer (struct it
*it
)
6686 xassert (IT_CHARPOS (*it
) >= BEGV
);
6688 /* With bidi reordering, the character to display might not be the
6689 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6690 we were reseat()ed to a new buffer position, which is potentially
6691 a different paragraph. */
6692 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
6694 it
->bidi_it
.charpos
= IT_CHARPOS (*it
);
6695 it
->bidi_it
.bytepos
= IT_BYTEPOS (*it
);
6696 if (it
->bidi_it
.bytepos
== ZV_BYTE
)
6698 /* Nothing to do, but reset the FIRST_ELT flag, like
6699 bidi_paragraph_init does, because we are not going to
6701 it
->bidi_it
.first_elt
= 0;
6703 else if (it
->bidi_it
.bytepos
== BEGV_BYTE
6704 /* FIXME: Should support all Unicode line separators. */
6705 || FETCH_CHAR (it
->bidi_it
.bytepos
- 1) == '\n'
6706 || FETCH_CHAR (it
->bidi_it
.bytepos
) == '\n')
6708 /* If we are at the beginning of a line, we can produce the
6709 next element right away. */
6710 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
6711 bidi_move_to_visually_next (&it
->bidi_it
);
6715 int orig_bytepos
= IT_BYTEPOS (*it
);
6717 /* We need to prime the bidi iterator starting at the line's
6718 beginning, before we will be able to produce the next
6720 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
), -1);
6721 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
6722 it
->bidi_it
.charpos
= IT_CHARPOS (*it
);
6723 it
->bidi_it
.bytepos
= IT_BYTEPOS (*it
);
6724 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
6727 /* Now return to buffer position where we were asked to
6728 get the next display element, and produce that. */
6729 bidi_move_to_visually_next (&it
->bidi_it
);
6731 while (it
->bidi_it
.bytepos
!= orig_bytepos
6732 && it
->bidi_it
.bytepos
< ZV_BYTE
);
6735 it
->bidi_it
.first_elt
= 0; /* paranoia: bidi.c does this */
6736 /* Adjust IT's position information to where we ended up. */
6737 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6738 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6739 SET_TEXT_POS (it
->position
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
6741 EMACS_INT stop
= it
->stop_charpos
;
6742 if (it
->bidi_it
.scan_dir
< 0)
6744 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
6745 IT_BYTEPOS (*it
), stop
, Qnil
);
6749 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
6751 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
6753 int overlay_strings_follow_p
;
6755 /* End of the game, except when overlay strings follow that
6756 haven't been returned yet. */
6757 if (it
->overlay_strings_at_end_processed_p
)
6758 overlay_strings_follow_p
= 0;
6761 it
->overlay_strings_at_end_processed_p
= 1;
6762 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
6765 if (overlay_strings_follow_p
)
6766 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
6770 it
->position
= it
->current
.pos
;
6774 else if (!(!it
->bidi_p
6775 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
6776 || IT_CHARPOS (*it
) == it
->stop_charpos
))
6778 /* With bidi non-linear iteration, we could find ourselves
6779 far beyond the last computed stop_charpos, with several
6780 other stop positions in between that we missed. Scan
6781 them all now, in buffer's logical order, until we find
6782 and handle the last stop_charpos that precedes our
6783 current position. */
6784 handle_stop_backwards (it
, it
->stop_charpos
);
6785 return GET_NEXT_DISPLAY_ELEMENT (it
);
6791 /* Take note of the stop position we just moved across,
6792 for when we will move back across it. */
6793 it
->prev_stop
= it
->stop_charpos
;
6794 /* If we are at base paragraph embedding level, take
6795 note of the last stop position seen at this
6797 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
6798 it
->base_level_stop
= it
->stop_charpos
;
6801 return GET_NEXT_DISPLAY_ELEMENT (it
);
6805 /* We can sometimes back up for reasons that have nothing
6806 to do with bidi reordering. E.g., compositions. The
6807 code below is only needed when we are above the base
6808 embedding level, so test for that explicitly. */
6809 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
)
6810 && IT_CHARPOS (*it
) < it
->prev_stop
)
6812 if (it
->base_level_stop
<= 0)
6813 it
->base_level_stop
= BEGV
;
6814 if (IT_CHARPOS (*it
) < it
->base_level_stop
)
6816 handle_stop_backwards (it
, it
->base_level_stop
);
6817 return GET_NEXT_DISPLAY_ELEMENT (it
);
6821 /* No face changes, overlays etc. in sight, so just return a
6822 character from current_buffer. */
6826 /* Maybe run the redisplay end trigger hook. Performance note:
6827 This doesn't seem to cost measurable time. */
6828 if (it
->redisplay_end_trigger_charpos
6830 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
6831 run_redisplay_end_trigger_hook (it
);
6833 stop
= it
->bidi_it
.scan_dir
< 0 ? -1 : it
->end_charpos
;
6834 if (CHAR_COMPOSED_P (it
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6836 && next_element_from_composition (it
))
6841 /* Get the next character, maybe multibyte. */
6842 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
6843 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
6844 it
->c
= STRING_CHAR_AND_LENGTH (p
, it
->len
);
6846 it
->c
= *p
, it
->len
= 1;
6848 /* Record what we have and where it came from. */
6849 it
->what
= IT_CHARACTER
;
6850 it
->object
= it
->w
->buffer
;
6851 it
->position
= it
->current
.pos
;
6853 /* Normally we return the character found above, except when we
6854 really want to return an ellipsis for selective display. */
6859 /* A value of selective > 0 means hide lines indented more
6860 than that number of columns. */
6861 if (it
->selective
> 0
6862 && IT_CHARPOS (*it
) + 1 < ZV
6863 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
6864 IT_BYTEPOS (*it
) + 1,
6865 (double) it
->selective
)) /* iftc */
6867 success_p
= next_element_from_ellipsis (it
);
6868 it
->dpvec_char_len
= -1;
6871 else if (it
->c
== '\r' && it
->selective
== -1)
6873 /* A value of selective == -1 means that everything from the
6874 CR to the end of the line is invisible, with maybe an
6875 ellipsis displayed for it. */
6876 success_p
= next_element_from_ellipsis (it
);
6877 it
->dpvec_char_len
= -1;
6882 /* Value is zero if end of buffer reached. */
6883 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
6888 /* Run the redisplay end trigger hook for IT. */
6891 run_redisplay_end_trigger_hook (struct it
*it
)
6893 Lisp_Object args
[3];
6895 /* IT->glyph_row should be non-null, i.e. we should be actually
6896 displaying something, or otherwise we should not run the hook. */
6897 xassert (it
->glyph_row
);
6899 /* Set up hook arguments. */
6900 args
[0] = Qredisplay_end_trigger_functions
;
6901 args
[1] = it
->window
;
6902 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
6903 it
->redisplay_end_trigger_charpos
= 0;
6905 /* Since we are *trying* to run these functions, don't try to run
6906 them again, even if they get an error. */
6907 it
->w
->redisplay_end_trigger
= Qnil
;
6908 Frun_hook_with_args (3, args
);
6910 /* Notice if it changed the face of the character we are on. */
6911 handle_face_prop (it
);
6915 /* Deliver a composition display element. Unlike the other
6916 next_element_from_XXX, this function is not registered in the array
6917 get_next_element[]. It is called from next_element_from_buffer and
6918 next_element_from_string when necessary. */
6921 next_element_from_composition (struct it
*it
)
6923 it
->what
= IT_COMPOSITION
;
6924 it
->len
= it
->cmp_it
.nbytes
;
6925 if (STRINGP (it
->string
))
6929 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
6930 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
6933 it
->position
= it
->current
.string_pos
;
6934 it
->object
= it
->string
;
6935 it
->c
= composition_update_it (&it
->cmp_it
, IT_STRING_CHARPOS (*it
),
6936 IT_STRING_BYTEPOS (*it
), it
->string
);
6942 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
6943 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
6946 if (it
->bidi_it
.new_paragraph
)
6947 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
);
6948 /* Resync the bidi iterator with IT's new position.
6949 FIXME: this doesn't support bidirectional text. */
6950 while (it
->bidi_it
.charpos
< IT_CHARPOS (*it
))
6951 bidi_move_to_visually_next (&it
->bidi_it
);
6955 it
->position
= it
->current
.pos
;
6956 it
->object
= it
->w
->buffer
;
6957 it
->c
= composition_update_it (&it
->cmp_it
, IT_CHARPOS (*it
),
6958 IT_BYTEPOS (*it
), Qnil
);
6965 /***********************************************************************
6966 Moving an iterator without producing glyphs
6967 ***********************************************************************/
6969 /* Check if iterator is at a position corresponding to a valid buffer
6970 position after some move_it_ call. */
6972 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6973 ((it)->method == GET_FROM_STRING \
6974 ? IT_STRING_CHARPOS (*it) == 0 \
6978 /* Move iterator IT to a specified buffer or X position within one
6979 line on the display without producing glyphs.
6981 OP should be a bit mask including some or all of these bits:
6982 MOVE_TO_X: Stop upon reaching x-position TO_X.
6983 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6984 Regardless of OP's value, stop upon reaching the end of the display line.
6986 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6987 This means, in particular, that TO_X includes window's horizontal
6990 The return value has several possible values that
6991 say what condition caused the scan to stop:
6993 MOVE_POS_MATCH_OR_ZV
6994 - when TO_POS or ZV was reached.
6997 -when TO_X was reached before TO_POS or ZV were reached.
7000 - when we reached the end of the display area and the line must
7004 - when we reached the end of the display area and the line is
7008 - when we stopped at a line end, i.e. a newline or a CR and selective
7011 static enum move_it_result
7012 move_it_in_display_line_to (struct it
*it
,
7013 EMACS_INT to_charpos
, int to_x
,
7014 enum move_operation_enum op
)
7016 enum move_it_result result
= MOVE_UNDEFINED
;
7017 struct glyph_row
*saved_glyph_row
;
7018 struct it wrap_it
, atpos_it
, atx_it
;
7020 enum it_method prev_method
= it
->method
;
7021 EMACS_INT prev_pos
= IT_CHARPOS (*it
);
7023 /* Don't produce glyphs in produce_glyphs. */
7024 saved_glyph_row
= it
->glyph_row
;
7025 it
->glyph_row
= NULL
;
7027 /* Use wrap_it to save a copy of IT wherever a word wrap could
7028 occur. Use atpos_it to save a copy of IT at the desired buffer
7029 position, if found, so that we can scan ahead and check if the
7030 word later overshoots the window edge. Use atx_it similarly, for
7036 #define BUFFER_POS_REACHED_P() \
7037 ((op & MOVE_TO_POS) != 0 \
7038 && BUFFERP (it->object) \
7039 && (IT_CHARPOS (*it) == to_charpos \
7040 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7041 && (it->method == GET_FROM_BUFFER \
7042 || (it->method == GET_FROM_DISPLAY_VECTOR \
7043 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7045 /* If there's a line-/wrap-prefix, handle it. */
7046 if (it
->hpos
== 0 && it
->method
== GET_FROM_BUFFER
7047 && it
->current_y
< it
->last_visible_y
)
7048 handle_line_prefix (it
);
7052 int x
, i
, ascent
= 0, descent
= 0;
7054 /* Utility macro to reset an iterator with x, ascent, and descent. */
7055 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7056 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7057 (IT)->max_descent = descent)
7059 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7061 if ((op
& MOVE_TO_POS
) != 0
7062 && BUFFERP (it
->object
)
7063 && it
->method
== GET_FROM_BUFFER
7064 && ((!it
->bidi_p
&& IT_CHARPOS (*it
) > to_charpos
)
7066 && (prev_method
== GET_FROM_IMAGE
7067 || prev_method
== GET_FROM_STRETCH
)
7068 /* Passed TO_CHARPOS from left to right. */
7069 && ((prev_pos
< to_charpos
7070 && IT_CHARPOS (*it
) > to_charpos
)
7071 /* Passed TO_CHARPOS from right to left. */
7072 || (prev_pos
> to_charpos
7073 && IT_CHARPOS (*it
) < to_charpos
)))))
7075 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
7077 result
= MOVE_POS_MATCH_OR_ZV
;
7080 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
7081 /* If wrap_it is valid, the current position might be in a
7082 word that is wrapped. So, save the iterator in
7083 atpos_it and continue to see if wrapping happens. */
7087 prev_method
= it
->method
;
7088 if (it
->method
== GET_FROM_BUFFER
)
7089 prev_pos
= IT_CHARPOS (*it
);
7090 /* Stop when ZV reached.
7091 We used to stop here when TO_CHARPOS reached as well, but that is
7092 too soon if this glyph does not fit on this line. So we handle it
7093 explicitly below. */
7094 if (!get_next_display_element (it
))
7096 result
= MOVE_POS_MATCH_OR_ZV
;
7100 if (it
->line_wrap
== TRUNCATE
)
7102 if (BUFFER_POS_REACHED_P ())
7104 result
= MOVE_POS_MATCH_OR_ZV
;
7110 if (it
->line_wrap
== WORD_WRAP
)
7112 if (IT_DISPLAYING_WHITESPACE (it
))
7116 /* We have reached a glyph that follows one or more
7117 whitespace characters. If the position is
7118 already found, we are done. */
7119 if (atpos_it
.sp
>= 0)
7122 result
= MOVE_POS_MATCH_OR_ZV
;
7128 result
= MOVE_X_REACHED
;
7131 /* Otherwise, we can wrap here. */
7138 /* Remember the line height for the current line, in case
7139 the next element doesn't fit on the line. */
7140 ascent
= it
->max_ascent
;
7141 descent
= it
->max_descent
;
7143 /* The call to produce_glyphs will get the metrics of the
7144 display element IT is loaded with. Record the x-position
7145 before this display element, in case it doesn't fit on the
7149 PRODUCE_GLYPHS (it
);
7151 if (it
->area
!= TEXT_AREA
)
7153 set_iterator_to_next (it
, 1);
7157 /* The number of glyphs we get back in IT->nglyphs will normally
7158 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7159 character on a terminal frame, or (iii) a line end. For the
7160 second case, IT->nglyphs - 1 padding glyphs will be present.
7161 (On X frames, there is only one glyph produced for a
7162 composite character.)
7164 The behavior implemented below means, for continuation lines,
7165 that as many spaces of a TAB as fit on the current line are
7166 displayed there. For terminal frames, as many glyphs of a
7167 multi-glyph character are displayed in the current line, too.
7168 This is what the old redisplay code did, and we keep it that
7169 way. Under X, the whole shape of a complex character must
7170 fit on the line or it will be completely displayed in the
7173 Note that both for tabs and padding glyphs, all glyphs have
7177 /* More than one glyph or glyph doesn't fit on line. All
7178 glyphs have the same width. */
7179 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
7181 int x_before_this_char
= x
;
7182 int hpos_before_this_char
= it
->hpos
;
7184 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
7186 new_x
= x
+ single_glyph_width
;
7188 /* We want to leave anything reaching TO_X to the caller. */
7189 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
7191 if (BUFFER_POS_REACHED_P ())
7193 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
7194 goto buffer_pos_reached
;
7195 if (atpos_it
.sp
< 0)
7198 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
7203 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
7206 result
= MOVE_X_REACHED
;
7212 IT_RESET_X_ASCENT_DESCENT (&atx_it
);
7217 if (/* Lines are continued. */
7218 it
->line_wrap
!= TRUNCATE
7219 && (/* And glyph doesn't fit on the line. */
7220 new_x
> it
->last_visible_x
7221 /* Or it fits exactly and we're on a window
7223 || (new_x
== it
->last_visible_x
7224 && FRAME_WINDOW_P (it
->f
))))
7226 if (/* IT->hpos == 0 means the very first glyph
7227 doesn't fit on the line, e.g. a wide image. */
7229 || (new_x
== it
->last_visible_x
7230 && FRAME_WINDOW_P (it
->f
)))
7233 it
->current_x
= new_x
;
7235 /* The character's last glyph just barely fits
7237 if (i
== it
->nglyphs
- 1)
7239 /* If this is the destination position,
7240 return a position *before* it in this row,
7241 now that we know it fits in this row. */
7242 if (BUFFER_POS_REACHED_P ())
7244 if (it
->line_wrap
!= WORD_WRAP
7247 it
->hpos
= hpos_before_this_char
;
7248 it
->current_x
= x_before_this_char
;
7249 result
= MOVE_POS_MATCH_OR_ZV
;
7252 if (it
->line_wrap
== WORD_WRAP
7256 atpos_it
.current_x
= x_before_this_char
;
7257 atpos_it
.hpos
= hpos_before_this_char
;
7261 set_iterator_to_next (it
, 1);
7262 /* On graphical terminals, newlines may
7263 "overflow" into the fringe if
7264 overflow-newline-into-fringe is non-nil.
7265 On text-only terminals, newlines may
7266 overflow into the last glyph on the
7268 if (!FRAME_WINDOW_P (it
->f
)
7269 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
7271 if (!get_next_display_element (it
))
7273 result
= MOVE_POS_MATCH_OR_ZV
;
7276 if (BUFFER_POS_REACHED_P ())
7278 if (ITERATOR_AT_END_OF_LINE_P (it
))
7279 result
= MOVE_POS_MATCH_OR_ZV
;
7281 result
= MOVE_LINE_CONTINUED
;
7284 if (ITERATOR_AT_END_OF_LINE_P (it
))
7286 result
= MOVE_NEWLINE_OR_CR
;
7293 IT_RESET_X_ASCENT_DESCENT (it
);
7295 if (wrap_it
.sp
>= 0)
7302 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
7304 result
= MOVE_LINE_CONTINUED
;
7308 if (BUFFER_POS_REACHED_P ())
7310 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
7311 goto buffer_pos_reached
;
7312 if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
7315 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
7319 if (new_x
> it
->first_visible_x
)
7321 /* Glyph is visible. Increment number of glyphs that
7322 would be displayed. */
7327 if (result
!= MOVE_UNDEFINED
)
7330 else if (BUFFER_POS_REACHED_P ())
7333 IT_RESET_X_ASCENT_DESCENT (it
);
7334 result
= MOVE_POS_MATCH_OR_ZV
;
7337 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
7339 /* Stop when TO_X specified and reached. This check is
7340 necessary here because of lines consisting of a line end,
7341 only. The line end will not produce any glyphs and we
7342 would never get MOVE_X_REACHED. */
7343 xassert (it
->nglyphs
== 0);
7344 result
= MOVE_X_REACHED
;
7348 /* Is this a line end? If yes, we're done. */
7349 if (ITERATOR_AT_END_OF_LINE_P (it
))
7351 result
= MOVE_NEWLINE_OR_CR
;
7355 if (it
->method
== GET_FROM_BUFFER
)
7356 prev_pos
= IT_CHARPOS (*it
);
7357 /* The current display element has been consumed. Advance
7359 set_iterator_to_next (it
, 1);
7361 /* Stop if lines are truncated and IT's current x-position is
7362 past the right edge of the window now. */
7363 if (it
->line_wrap
== TRUNCATE
7364 && it
->current_x
>= it
->last_visible_x
)
7366 if (!FRAME_WINDOW_P (it
->f
)
7367 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
7369 if (!get_next_display_element (it
)
7370 || BUFFER_POS_REACHED_P ())
7372 result
= MOVE_POS_MATCH_OR_ZV
;
7375 if (ITERATOR_AT_END_OF_LINE_P (it
))
7377 result
= MOVE_NEWLINE_OR_CR
;
7381 result
= MOVE_LINE_TRUNCATED
;
7384 #undef IT_RESET_X_ASCENT_DESCENT
7387 #undef BUFFER_POS_REACHED_P
7389 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7390 restore the saved iterator. */
7391 if (atpos_it
.sp
>= 0)
7393 else if (atx_it
.sp
>= 0)
7398 /* Restore the iterator settings altered at the beginning of this
7400 it
->glyph_row
= saved_glyph_row
;
7404 /* For external use. */
7406 move_it_in_display_line (struct it
*it
,
7407 EMACS_INT to_charpos
, int to_x
,
7408 enum move_operation_enum op
)
7410 if (it
->line_wrap
== WORD_WRAP
7411 && (op
& MOVE_TO_X
))
7413 struct it save_it
= *it
;
7414 int skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
7415 /* When word-wrap is on, TO_X may lie past the end
7416 of a wrapped line. Then it->current is the
7417 character on the next line, so backtrack to the
7418 space before the wrap point. */
7419 if (skip
== MOVE_LINE_CONTINUED
)
7421 int prev_x
= max (it
->current_x
- 1, 0);
7423 move_it_in_display_line_to
7424 (it
, -1, prev_x
, MOVE_TO_X
);
7428 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
7432 /* Move IT forward until it satisfies one or more of the criteria in
7433 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7435 OP is a bit-mask that specifies where to stop, and in particular,
7436 which of those four position arguments makes a difference. See the
7437 description of enum move_operation_enum.
7439 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7440 screen line, this function will set IT to the next position >
7444 move_it_to (struct it
*it
, int to_charpos
, int to_x
, int to_y
, int to_vpos
, int op
)
7446 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
7447 int line_height
, line_start_x
= 0, reached
= 0;
7451 if (op
& MOVE_TO_VPOS
)
7453 /* If no TO_CHARPOS and no TO_X specified, stop at the
7454 start of the line TO_VPOS. */
7455 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
7457 if (it
->vpos
== to_vpos
)
7463 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
7467 /* TO_VPOS >= 0 means stop at TO_X in the line at
7468 TO_VPOS, or at TO_POS, whichever comes first. */
7469 if (it
->vpos
== to_vpos
)
7475 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
7477 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
7482 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
7484 /* We have reached TO_X but not in the line we want. */
7485 skip
= move_it_in_display_line_to (it
, to_charpos
,
7487 if (skip
== MOVE_POS_MATCH_OR_ZV
)
7495 else if (op
& MOVE_TO_Y
)
7497 struct it it_backup
;
7499 if (it
->line_wrap
== WORD_WRAP
)
7502 /* TO_Y specified means stop at TO_X in the line containing
7503 TO_Y---or at TO_CHARPOS if this is reached first. The
7504 problem is that we can't really tell whether the line
7505 contains TO_Y before we have completely scanned it, and
7506 this may skip past TO_X. What we do is to first scan to
7509 If TO_X is not specified, use a TO_X of zero. The reason
7510 is to make the outcome of this function more predictable.
7511 If we didn't use TO_X == 0, we would stop at the end of
7512 the line which is probably not what a caller would expect
7514 skip
= move_it_in_display_line_to
7515 (it
, to_charpos
, ((op
& MOVE_TO_X
) ? to_x
: 0),
7516 (MOVE_TO_X
| (op
& MOVE_TO_POS
)));
7518 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7519 if (skip
== MOVE_POS_MATCH_OR_ZV
)
7521 else if (skip
== MOVE_X_REACHED
)
7523 /* If TO_X was reached, we want to know whether TO_Y is
7524 in the line. We know this is the case if the already
7525 scanned glyphs make the line tall enough. Otherwise,
7526 we must check by scanning the rest of the line. */
7527 line_height
= it
->max_ascent
+ it
->max_descent
;
7528 if (to_y
>= it
->current_y
7529 && to_y
< it
->current_y
+ line_height
)
7535 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
7536 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
7538 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
7539 line_height
= it
->max_ascent
+ it
->max_descent
;
7540 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
7542 if (to_y
>= it
->current_y
7543 && to_y
< it
->current_y
+ line_height
)
7545 /* If TO_Y is in this line and TO_X was reached
7546 above, we scanned too far. We have to restore
7547 IT's settings to the ones before skipping. */
7554 if (skip
== MOVE_POS_MATCH_OR_ZV
)
7560 /* Check whether TO_Y is in this line. */
7561 line_height
= it
->max_ascent
+ it
->max_descent
;
7562 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
7564 if (to_y
>= it
->current_y
7565 && to_y
< it
->current_y
+ line_height
)
7567 /* When word-wrap is on, TO_X may lie past the end
7568 of a wrapped line. Then it->current is the
7569 character on the next line, so backtrack to the
7570 space before the wrap point. */
7571 if (skip
== MOVE_LINE_CONTINUED
7572 && it
->line_wrap
== WORD_WRAP
)
7574 int prev_x
= max (it
->current_x
- 1, 0);
7576 skip
= move_it_in_display_line_to
7577 (it
, -1, prev_x
, MOVE_TO_X
);
7586 else if (BUFFERP (it
->object
)
7587 && (it
->method
== GET_FROM_BUFFER
7588 || it
->method
== GET_FROM_STRETCH
)
7589 && IT_CHARPOS (*it
) >= to_charpos
)
7590 skip
= MOVE_POS_MATCH_OR_ZV
;
7592 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
7596 case MOVE_POS_MATCH_OR_ZV
:
7600 case MOVE_NEWLINE_OR_CR
:
7601 set_iterator_to_next (it
, 1);
7602 it
->continuation_lines_width
= 0;
7605 case MOVE_LINE_TRUNCATED
:
7606 it
->continuation_lines_width
= 0;
7607 reseat_at_next_visible_line_start (it
, 0);
7608 if ((op
& MOVE_TO_POS
) != 0
7609 && IT_CHARPOS (*it
) > to_charpos
)
7616 case MOVE_LINE_CONTINUED
:
7617 /* For continued lines ending in a tab, some of the glyphs
7618 associated with the tab are displayed on the current
7619 line. Since it->current_x does not include these glyphs,
7620 we use it->last_visible_x instead. */
7623 it
->continuation_lines_width
+= it
->last_visible_x
;
7624 /* When moving by vpos, ensure that the iterator really
7625 advances to the next line (bug#847, bug#969). Fixme:
7626 do we need to do this in other circumstances? */
7627 if (it
->current_x
!= it
->last_visible_x
7628 && (op
& MOVE_TO_VPOS
)
7629 && !(op
& (MOVE_TO_X
| MOVE_TO_POS
)))
7631 line_start_x
= it
->current_x
+ it
->pixel_width
7632 - it
->last_visible_x
;
7633 set_iterator_to_next (it
, 0);
7637 it
->continuation_lines_width
+= it
->current_x
;
7644 /* Reset/increment for the next run. */
7645 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
7646 it
->current_x
= line_start_x
;
7649 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
7651 last_height
= it
->max_ascent
+ it
->max_descent
;
7652 last_max_ascent
= it
->max_ascent
;
7653 it
->max_ascent
= it
->max_descent
= 0;
7658 /* On text terminals, we may stop at the end of a line in the middle
7659 of a multi-character glyph. If the glyph itself is continued,
7660 i.e. it is actually displayed on the next line, don't treat this
7661 stopping point as valid; move to the next line instead (unless
7662 that brings us offscreen). */
7663 if (!FRAME_WINDOW_P (it
->f
)
7665 && IT_CHARPOS (*it
) == to_charpos
7666 && it
->what
== IT_CHARACTER
7668 && it
->line_wrap
== WINDOW_WRAP
7669 && it
->current_x
== it
->last_visible_x
- 1
7672 && it
->vpos
< XFASTINT (it
->w
->window_end_vpos
))
7674 it
->continuation_lines_width
+= it
->current_x
;
7675 it
->current_x
= it
->hpos
= it
->max_ascent
= it
->max_descent
= 0;
7676 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
7678 last_height
= it
->max_ascent
+ it
->max_descent
;
7679 last_max_ascent
= it
->max_ascent
;
7682 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
7686 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7688 If DY > 0, move IT backward at least that many pixels. DY = 0
7689 means move IT backward to the preceding line start or BEGV. This
7690 function may move over more than DY pixels if IT->current_y - DY
7691 ends up in the middle of a line; in this case IT->current_y will be
7692 set to the top of the line moved to. */
7695 move_it_vertically_backward (struct it
*it
, int dy
)
7704 start_pos
= IT_CHARPOS (*it
);
7706 /* Estimate how many newlines we must move back. */
7707 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
7709 /* Set the iterator's position that many lines back. */
7710 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
7711 back_to_previous_visible_line_start (it
);
7713 /* Reseat the iterator here. When moving backward, we don't want
7714 reseat to skip forward over invisible text, set up the iterator
7715 to deliver from overlay strings at the new position etc. So,
7716 use reseat_1 here. */
7717 reseat_1 (it
, it
->current
.pos
, 1);
7719 /* We are now surely at a line start. */
7720 it
->current_x
= it
->hpos
= 0;
7721 it
->continuation_lines_width
= 0;
7723 /* Move forward and see what y-distance we moved. First move to the
7724 start of the next line so that we get its height. We need this
7725 height to be able to tell whether we reached the specified
7728 it2
.max_ascent
= it2
.max_descent
= 0;
7731 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
7732 MOVE_TO_POS
| MOVE_TO_VPOS
);
7734 while (!IT_POS_VALID_AFTER_MOVE_P (&it2
));
7735 xassert (IT_CHARPOS (*it
) >= BEGV
);
7738 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
7739 xassert (IT_CHARPOS (*it
) >= BEGV
);
7740 /* H is the actual vertical distance from the position in *IT
7741 and the starting position. */
7742 h
= it2
.current_y
- it
->current_y
;
7743 /* NLINES is the distance in number of lines. */
7744 nlines
= it2
.vpos
- it
->vpos
;
7746 /* Correct IT's y and vpos position
7747 so that they are relative to the starting point. */
7753 /* DY == 0 means move to the start of the screen line. The
7754 value of nlines is > 0 if continuation lines were involved. */
7756 move_it_by_lines (it
, nlines
, 1);
7760 /* The y-position we try to reach, relative to *IT.
7761 Note that H has been subtracted in front of the if-statement. */
7762 int target_y
= it
->current_y
+ h
- dy
;
7763 int y0
= it3
.current_y
;
7764 int y1
= line_bottom_y (&it3
);
7765 int line_height
= y1
- y0
;
7767 /* If we did not reach target_y, try to move further backward if
7768 we can. If we moved too far backward, try to move forward. */
7769 if (target_y
< it
->current_y
7770 /* This is heuristic. In a window that's 3 lines high, with
7771 a line height of 13 pixels each, recentering with point
7772 on the bottom line will try to move -39/2 = 19 pixels
7773 backward. Try to avoid moving into the first line. */
7774 && (it
->current_y
- target_y
7775 > min (window_box_height (it
->w
), line_height
* 2 / 3))
7776 && IT_CHARPOS (*it
) > BEGV
)
7778 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
7779 target_y
- it
->current_y
));
7780 dy
= it
->current_y
- target_y
;
7781 goto move_further_back
;
7783 else if (target_y
>= it
->current_y
+ line_height
7784 && IT_CHARPOS (*it
) < ZV
)
7786 /* Should move forward by at least one line, maybe more.
7788 Note: Calling move_it_by_lines can be expensive on
7789 terminal frames, where compute_motion is used (via
7790 vmotion) to do the job, when there are very long lines
7791 and truncate-lines is nil. That's the reason for
7792 treating terminal frames specially here. */
7794 if (!FRAME_WINDOW_P (it
->f
))
7795 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
7800 move_it_by_lines (it
, 1, 1);
7802 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
7809 /* Move IT by a specified amount of pixel lines DY. DY negative means
7810 move backwards. DY = 0 means move to start of screen line. At the
7811 end, IT will be on the start of a screen line. */
7814 move_it_vertically (struct it
*it
, int dy
)
7817 move_it_vertically_backward (it
, -dy
);
7820 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
7821 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
7822 MOVE_TO_POS
| MOVE_TO_Y
);
7823 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
7825 /* If buffer ends in ZV without a newline, move to the start of
7826 the line to satisfy the post-condition. */
7827 if (IT_CHARPOS (*it
) == ZV
7829 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
7830 move_it_by_lines (it
, 0, 0);
7835 /* Move iterator IT past the end of the text line it is in. */
7838 move_it_past_eol (struct it
*it
)
7840 enum move_it_result rc
;
7842 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
7843 if (rc
== MOVE_NEWLINE_OR_CR
)
7844 set_iterator_to_next (it
, 0);
7848 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7849 negative means move up. DVPOS == 0 means move to the start of the
7850 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7851 NEED_Y_P is zero, IT->current_y will be left unchanged.
7853 Further optimization ideas: If we would know that IT->f doesn't use
7854 a face with proportional font, we could be faster for
7855 truncate-lines nil. */
7858 move_it_by_lines (struct it
*it
, int dvpos
, int need_y_p
)
7860 struct position pos
;
7862 /* The commented-out optimization uses vmotion on terminals. This
7863 gives bad results, because elements like it->what, on which
7864 callers such as pos_visible_p rely, aren't updated. */
7865 /* if (!FRAME_WINDOW_P (it->f))
7867 struct text_pos textpos;
7869 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7870 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7871 reseat (it, textpos, 1);
7872 it->vpos += pos.vpos;
7873 it->current_y += pos.vpos;
7879 /* DVPOS == 0 means move to the start of the screen line. */
7880 move_it_vertically_backward (it
, 0);
7881 xassert (it
->current_x
== 0 && it
->hpos
== 0);
7882 /* Let next call to line_bottom_y calculate real line height */
7887 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
7888 if (!IT_POS_VALID_AFTER_MOVE_P (it
))
7889 move_it_to (it
, IT_CHARPOS (*it
) + 1, -1, -1, -1, MOVE_TO_POS
);
7894 int start_charpos
, i
;
7896 /* Start at the beginning of the screen line containing IT's
7897 position. This may actually move vertically backwards,
7898 in case of overlays, so adjust dvpos accordingly. */
7900 move_it_vertically_backward (it
, 0);
7903 /* Go back -DVPOS visible lines and reseat the iterator there. */
7904 start_charpos
= IT_CHARPOS (*it
);
7905 for (i
= -dvpos
; i
> 0 && IT_CHARPOS (*it
) > BEGV
; --i
)
7906 back_to_previous_visible_line_start (it
);
7907 reseat (it
, it
->current
.pos
, 1);
7909 /* Move further back if we end up in a string or an image. */
7910 while (!IT_POS_VALID_AFTER_MOVE_P (it
))
7912 /* First try to move to start of display line. */
7914 move_it_vertically_backward (it
, 0);
7916 if (IT_POS_VALID_AFTER_MOVE_P (it
))
7918 /* If start of line is still in string or image,
7919 move further back. */
7920 back_to_previous_visible_line_start (it
);
7921 reseat (it
, it
->current
.pos
, 1);
7925 it
->current_x
= it
->hpos
= 0;
7927 /* Above call may have moved too far if continuation lines
7928 are involved. Scan forward and see if it did. */
7930 it2
.vpos
= it2
.current_y
= 0;
7931 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
7932 it
->vpos
-= it2
.vpos
;
7933 it
->current_y
-= it2
.current_y
;
7934 it
->current_x
= it
->hpos
= 0;
7936 /* If we moved too far back, move IT some lines forward. */
7937 if (it2
.vpos
> -dvpos
)
7939 int delta
= it2
.vpos
+ dvpos
;
7941 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
7942 /* Move back again if we got too far ahead. */
7943 if (IT_CHARPOS (*it
) >= start_charpos
)
7949 /* Return 1 if IT points into the middle of a display vector. */
7952 in_display_vector_p (struct it
*it
)
7954 return (it
->method
== GET_FROM_DISPLAY_VECTOR
7955 && it
->current
.dpvec_index
> 0
7956 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
7960 /***********************************************************************
7962 ***********************************************************************/
7965 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7969 add_to_log (char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
7971 Lisp_Object args
[3];
7972 Lisp_Object msg
, fmt
;
7975 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
7978 /* Do nothing if called asynchronously. Inserting text into
7979 a buffer may call after-change-functions and alike and
7980 that would means running Lisp asynchronously. */
7981 if (handling_signal
)
7985 GCPRO4 (fmt
, msg
, arg1
, arg2
);
7987 args
[0] = fmt
= build_string (format
);
7990 msg
= Fformat (3, args
);
7992 len
= SBYTES (msg
) + 1;
7993 SAFE_ALLOCA (buffer
, char *, len
);
7994 memcpy (buffer
, SDATA (msg
), len
);
7996 message_dolog (buffer
, len
- 1, 1, 0);
8003 /* Output a newline in the *Messages* buffer if "needs" one. */
8006 message_log_maybe_newline (void)
8008 if (message_log_need_newline
)
8009 message_dolog ("", 0, 1, 0);
8013 /* Add a string M of length NBYTES to the message log, optionally
8014 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8015 nonzero, means interpret the contents of M as multibyte. This
8016 function calls low-level routines in order to bypass text property
8017 hooks, etc. which might not be safe to run.
8019 This may GC (insert may run before/after change hooks),
8020 so the buffer M must NOT point to a Lisp string. */
8023 message_dolog (const char *m
, int nbytes
, int nlflag
, int multibyte
)
8025 if (!NILP (Vmemory_full
))
8028 if (!NILP (Vmessage_log_max
))
8030 struct buffer
*oldbuf
;
8031 Lisp_Object oldpoint
, oldbegv
, oldzv
;
8032 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
8033 int point_at_end
= 0;
8035 Lisp_Object old_deactivate_mark
, tem
;
8036 struct gcpro gcpro1
;
8038 old_deactivate_mark
= Vdeactivate_mark
;
8039 oldbuf
= current_buffer
;
8040 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
8041 current_buffer
->undo_list
= Qt
;
8043 oldpoint
= message_dolog_marker1
;
8044 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
8045 oldbegv
= message_dolog_marker2
;
8046 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
8047 oldzv
= message_dolog_marker3
;
8048 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
8049 GCPRO1 (old_deactivate_mark
);
8057 BEGV_BYTE
= BEG_BYTE
;
8060 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
8062 /* Insert the string--maybe converting multibyte to single byte
8063 or vice versa, so that all the text fits the buffer. */
8065 && NILP (current_buffer
->enable_multibyte_characters
))
8067 int i
, c
, char_bytes
;
8068 unsigned char work
[1];
8070 /* Convert a multibyte string to single-byte
8071 for the *Message* buffer. */
8072 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
8074 c
= string_char_and_length (m
+ i
, &char_bytes
);
8075 work
[0] = (ASCII_CHAR_P (c
)
8077 : multibyte_char_to_unibyte (c
, Qnil
));
8078 insert_1_both (work
, 1, 1, 1, 0, 0);
8081 else if (! multibyte
8082 && ! NILP (current_buffer
->enable_multibyte_characters
))
8084 int i
, c
, char_bytes
;
8085 unsigned char *msg
= (unsigned char *) m
;
8086 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
8087 /* Convert a single-byte string to multibyte
8088 for the *Message* buffer. */
8089 for (i
= 0; i
< nbytes
; i
++)
8092 MAKE_CHAR_MULTIBYTE (c
);
8093 char_bytes
= CHAR_STRING (c
, str
);
8094 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
8098 insert_1 (m
, nbytes
, 1, 0, 0);
8102 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
8103 insert_1 ("\n", 1, 1, 0, 0);
8105 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
8107 this_bol_byte
= PT_BYTE
;
8109 /* See if this line duplicates the previous one.
8110 If so, combine duplicates. */
8113 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
8115 prev_bol_byte
= PT_BYTE
;
8117 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
8118 this_bol
, this_bol_byte
);
8121 del_range_both (prev_bol
, prev_bol_byte
,
8122 this_bol
, this_bol_byte
, 0);
8128 /* If you change this format, don't forget to also
8129 change message_log_check_duplicate. */
8130 sprintf (dupstr
, " [%d times]", dup
);
8131 duplen
= strlen (dupstr
);
8132 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
8133 insert_1 (dupstr
, duplen
, 1, 0, 1);
8138 /* If we have more than the desired maximum number of lines
8139 in the *Messages* buffer now, delete the oldest ones.
8140 This is safe because we don't have undo in this buffer. */
8142 if (NATNUMP (Vmessage_log_max
))
8144 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
8145 -XFASTINT (Vmessage_log_max
) - 1, 0);
8146 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
8149 BEGV
= XMARKER (oldbegv
)->charpos
;
8150 BEGV_BYTE
= marker_byte_position (oldbegv
);
8159 ZV
= XMARKER (oldzv
)->charpos
;
8160 ZV_BYTE
= marker_byte_position (oldzv
);
8164 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
8166 /* We can't do Fgoto_char (oldpoint) because it will run some
8168 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
8169 XMARKER (oldpoint
)->bytepos
);
8172 unchain_marker (XMARKER (oldpoint
));
8173 unchain_marker (XMARKER (oldbegv
));
8174 unchain_marker (XMARKER (oldzv
));
8176 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
8177 set_buffer_internal (oldbuf
);
8179 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
8180 message_log_need_newline
= !nlflag
;
8181 Vdeactivate_mark
= old_deactivate_mark
;
8186 /* We are at the end of the buffer after just having inserted a newline.
8187 (Note: We depend on the fact we won't be crossing the gap.)
8188 Check to see if the most recent message looks a lot like the previous one.
8189 Return 0 if different, 1 if the new one should just replace it, or a
8190 value N > 1 if we should also append " [N times]". */
8193 message_log_check_duplicate (int prev_bol
, int prev_bol_byte
,
8194 int this_bol
, int this_bol_byte
)
8197 int len
= Z_BYTE
- 1 - this_bol_byte
;
8199 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
8200 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
8202 for (i
= 0; i
< len
; i
++)
8204 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
8212 if (*p1
++ == ' ' && *p1
++ == '[')
8215 while (*p1
>= '0' && *p1
<= '9')
8216 n
= n
* 10 + *p1
++ - '0';
8217 if (strncmp (p1
, " times]\n", 8) == 0)
8224 /* Display an echo area message M with a specified length of NBYTES
8225 bytes. The string may include null characters. If M is 0, clear
8226 out any existing message, and let the mini-buffer text show
8229 This may GC, so the buffer M must NOT point to a Lisp string. */
8232 message2 (const char *m
, int nbytes
, int multibyte
)
8234 /* First flush out any partial line written with print. */
8235 message_log_maybe_newline ();
8237 message_dolog (m
, nbytes
, 1, multibyte
);
8238 message2_nolog (m
, nbytes
, multibyte
);
8242 /* The non-logging counterpart of message2. */
8245 message2_nolog (const char *m
, int nbytes
, int multibyte
)
8247 struct frame
*sf
= SELECTED_FRAME ();
8248 message_enable_multibyte
= multibyte
;
8250 if (FRAME_INITIAL_P (sf
))
8252 if (noninteractive_need_newline
)
8253 putc ('\n', stderr
);
8254 noninteractive_need_newline
= 0;
8256 fwrite (m
, nbytes
, 1, stderr
);
8257 if (cursor_in_echo_area
== 0)
8258 fprintf (stderr
, "\n");
8261 /* A null message buffer means that the frame hasn't really been
8262 initialized yet. Error messages get reported properly by
8263 cmd_error, so this must be just an informative message; toss it. */
8264 else if (INTERACTIVE
8265 && sf
->glyphs_initialized_p
8266 && FRAME_MESSAGE_BUF (sf
))
8268 Lisp_Object mini_window
;
8271 /* Get the frame containing the mini-buffer
8272 that the selected frame is using. */
8273 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8274 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
8276 FRAME_SAMPLE_VISIBILITY (f
);
8277 if (FRAME_VISIBLE_P (sf
)
8278 && ! FRAME_VISIBLE_P (f
))
8279 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
8283 set_message (m
, Qnil
, nbytes
, multibyte
);
8284 if (minibuffer_auto_raise
)
8285 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
8288 clear_message (1, 1);
8290 do_pending_window_change (0);
8291 echo_area_display (1);
8292 do_pending_window_change (0);
8293 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
8294 (*FRAME_TERMINAL (f
)->frame_up_to_date_hook
) (f
);
8299 /* Display an echo area message M with a specified length of NBYTES
8300 bytes. The string may include null characters. If M is not a
8301 string, clear out any existing message, and let the mini-buffer
8304 This function cancels echoing. */
8307 message3 (Lisp_Object m
, int nbytes
, int multibyte
)
8309 struct gcpro gcpro1
;
8312 clear_message (1,1);
8315 /* First flush out any partial line written with print. */
8316 message_log_maybe_newline ();
8322 SAFE_ALLOCA (buffer
, char *, nbytes
);
8323 memcpy (buffer
, SDATA (m
), nbytes
);
8324 message_dolog (buffer
, nbytes
, 1, multibyte
);
8327 message3_nolog (m
, nbytes
, multibyte
);
8333 /* The non-logging version of message3.
8334 This does not cancel echoing, because it is used for echoing.
8335 Perhaps we need to make a separate function for echoing
8336 and make this cancel echoing. */
8339 message3_nolog (Lisp_Object m
, int nbytes
, int multibyte
)
8341 struct frame
*sf
= SELECTED_FRAME ();
8342 message_enable_multibyte
= multibyte
;
8344 if (FRAME_INITIAL_P (sf
))
8346 if (noninteractive_need_newline
)
8347 putc ('\n', stderr
);
8348 noninteractive_need_newline
= 0;
8350 fwrite (SDATA (m
), nbytes
, 1, stderr
);
8351 if (cursor_in_echo_area
== 0)
8352 fprintf (stderr
, "\n");
8355 /* A null message buffer means that the frame hasn't really been
8356 initialized yet. Error messages get reported properly by
8357 cmd_error, so this must be just an informative message; toss it. */
8358 else if (INTERACTIVE
8359 && sf
->glyphs_initialized_p
8360 && FRAME_MESSAGE_BUF (sf
))
8362 Lisp_Object mini_window
;
8366 /* Get the frame containing the mini-buffer
8367 that the selected frame is using. */
8368 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8369 frame
= XWINDOW (mini_window
)->frame
;
8372 FRAME_SAMPLE_VISIBILITY (f
);
8373 if (FRAME_VISIBLE_P (sf
)
8374 && !FRAME_VISIBLE_P (f
))
8375 Fmake_frame_visible (frame
);
8377 if (STRINGP (m
) && SCHARS (m
) > 0)
8379 set_message (NULL
, m
, nbytes
, multibyte
);
8380 if (minibuffer_auto_raise
)
8381 Fraise_frame (frame
);
8382 /* Assume we are not echoing.
8383 (If we are, echo_now will override this.) */
8384 echo_message_buffer
= Qnil
;
8387 clear_message (1, 1);
8389 do_pending_window_change (0);
8390 echo_area_display (1);
8391 do_pending_window_change (0);
8392 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
8393 (*FRAME_TERMINAL (f
)->frame_up_to_date_hook
) (f
);
8398 /* Display a null-terminated echo area message M. If M is 0, clear
8399 out any existing message, and let the mini-buffer text show through.
8401 The buffer M must continue to exist until after the echo area gets
8402 cleared or some other message gets displayed there. Do not pass
8403 text that is stored in a Lisp string. Do not pass text in a buffer
8404 that was alloca'd. */
8407 message1 (const char *m
)
8409 message2 (m
, (m
? strlen (m
) : 0), 0);
8413 /* The non-logging counterpart of message1. */
8416 message1_nolog (const char *m
)
8418 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
8421 /* Display a message M which contains a single %s
8422 which gets replaced with STRING. */
8425 message_with_string (const char *m
, Lisp_Object string
, int log
)
8427 CHECK_STRING (string
);
8433 if (noninteractive_need_newline
)
8434 putc ('\n', stderr
);
8435 noninteractive_need_newline
= 0;
8436 fprintf (stderr
, m
, SDATA (string
));
8437 if (!cursor_in_echo_area
)
8438 fprintf (stderr
, "\n");
8442 else if (INTERACTIVE
)
8444 /* The frame whose minibuffer we're going to display the message on.
8445 It may be larger than the selected frame, so we need
8446 to use its buffer, not the selected frame's buffer. */
8447 Lisp_Object mini_window
;
8448 struct frame
*f
, *sf
= SELECTED_FRAME ();
8450 /* Get the frame containing the minibuffer
8451 that the selected frame is using. */
8452 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8453 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
8455 /* A null message buffer means that the frame hasn't really been
8456 initialized yet. Error messages get reported properly by
8457 cmd_error, so this must be just an informative message; toss it. */
8458 if (FRAME_MESSAGE_BUF (f
))
8460 Lisp_Object args
[2], message
;
8461 struct gcpro gcpro1
, gcpro2
;
8463 args
[0] = build_string (m
);
8464 args
[1] = message
= string
;
8465 GCPRO2 (args
[0], message
);
8468 message
= Fformat (2, args
);
8471 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
8473 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
8477 /* Print should start at the beginning of the message
8478 buffer next time. */
8479 message_buf_print
= 0;
8485 /* Dump an informative message to the minibuf. If M is 0, clear out
8486 any existing message, and let the mini-buffer text show through. */
8489 vmessage (const char *m
, va_list ap
)
8495 if (noninteractive_need_newline
)
8496 putc ('\n', stderr
);
8497 noninteractive_need_newline
= 0;
8498 vfprintf (stderr
, m
, ap
);
8499 if (cursor_in_echo_area
== 0)
8500 fprintf (stderr
, "\n");
8504 else if (INTERACTIVE
)
8506 /* The frame whose mini-buffer we're going to display the message
8507 on. It may be larger than the selected frame, so we need to
8508 use its buffer, not the selected frame's buffer. */
8509 Lisp_Object mini_window
;
8510 struct frame
*f
, *sf
= SELECTED_FRAME ();
8512 /* Get the frame containing the mini-buffer
8513 that the selected frame is using. */
8514 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8515 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
8517 /* A null message buffer means that the frame hasn't really been
8518 initialized yet. Error messages get reported properly by
8519 cmd_error, so this must be just an informative message; toss
8521 if (FRAME_MESSAGE_BUF (f
))
8527 len
= doprnt (FRAME_MESSAGE_BUF (f
),
8528 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, ap
);
8530 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
8535 /* Print should start at the beginning of the message
8536 buffer next time. */
8537 message_buf_print
= 0;
8543 message (const char *m
, ...)
8552 /* The non-logging version of message. */
8555 message_nolog (const char *m
, ...)
8557 Lisp_Object old_log_max
;
8560 old_log_max
= Vmessage_log_max
;
8561 Vmessage_log_max
= Qnil
;
8563 Vmessage_log_max
= old_log_max
;
8568 /* Display the current message in the current mini-buffer. This is
8569 only called from error handlers in process.c, and is not time
8573 update_echo_area (void)
8575 if (!NILP (echo_area_buffer
[0]))
8578 string
= Fcurrent_message ();
8579 message3 (string
, SBYTES (string
),
8580 !NILP (current_buffer
->enable_multibyte_characters
));
8585 /* Make sure echo area buffers in `echo_buffers' are live.
8586 If they aren't, make new ones. */
8589 ensure_echo_area_buffers (void)
8593 for (i
= 0; i
< 2; ++i
)
8594 if (!BUFFERP (echo_buffer
[i
])
8595 || NILP (XBUFFER (echo_buffer
[i
])->name
))
8598 Lisp_Object old_buffer
;
8601 old_buffer
= echo_buffer
[i
];
8602 sprintf (name
, " *Echo Area %d*", i
);
8603 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
8604 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
8605 /* to force word wrap in echo area -
8606 it was decided to postpone this*/
8607 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8609 for (j
= 0; j
< 2; ++j
)
8610 if (EQ (old_buffer
, echo_area_buffer
[j
]))
8611 echo_area_buffer
[j
] = echo_buffer
[i
];
8616 /* Call FN with args A1..A4 with either the current or last displayed
8617 echo_area_buffer as current buffer.
8619 WHICH zero means use the current message buffer
8620 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8621 from echo_buffer[] and clear it.
8623 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8624 suitable buffer from echo_buffer[] and clear it.
8626 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8627 that the current message becomes the last displayed one, make
8628 choose a suitable buffer for echo_area_buffer[0], and clear it.
8630 Value is what FN returns. */
8633 with_echo_area_buffer (struct window
*w
, int which
,
8634 int (*fn
) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
8635 EMACS_INT a1
, Lisp_Object a2
, EMACS_INT a3
, EMACS_INT a4
)
8638 int this_one
, the_other
, clear_buffer_p
, rc
;
8639 int count
= SPECPDL_INDEX ();
8641 /* If buffers aren't live, make new ones. */
8642 ensure_echo_area_buffers ();
8647 this_one
= 0, the_other
= 1;
8649 this_one
= 1, the_other
= 0;
8652 this_one
= 0, the_other
= 1;
8655 /* We need a fresh one in case the current echo buffer equals
8656 the one containing the last displayed echo area message. */
8657 if (!NILP (echo_area_buffer
[this_one
])
8658 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
8659 echo_area_buffer
[this_one
] = Qnil
;
8662 /* Choose a suitable buffer from echo_buffer[] is we don't
8664 if (NILP (echo_area_buffer
[this_one
]))
8666 echo_area_buffer
[this_one
]
8667 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
8668 ? echo_buffer
[the_other
]
8669 : echo_buffer
[this_one
]);
8673 buffer
= echo_area_buffer
[this_one
];
8675 /* Don't get confused by reusing the buffer used for echoing
8676 for a different purpose. */
8677 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
8680 record_unwind_protect (unwind_with_echo_area_buffer
,
8681 with_echo_area_buffer_unwind_data (w
));
8683 /* Make the echo area buffer current. Note that for display
8684 purposes, it is not necessary that the displayed window's buffer
8685 == current_buffer, except for text property lookup. So, let's
8686 only set that buffer temporarily here without doing a full
8687 Fset_window_buffer. We must also change w->pointm, though,
8688 because otherwise an assertions in unshow_buffer fails, and Emacs
8690 set_buffer_internal_1 (XBUFFER (buffer
));
8694 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
8697 current_buffer
->undo_list
= Qt
;
8698 current_buffer
->read_only
= Qnil
;
8699 specbind (Qinhibit_read_only
, Qt
);
8700 specbind (Qinhibit_modification_hooks
, Qt
);
8702 if (clear_buffer_p
&& Z
> BEG
)
8705 xassert (BEGV
>= BEG
);
8706 xassert (ZV
<= Z
&& ZV
>= BEGV
);
8708 rc
= fn (a1
, a2
, a3
, a4
);
8710 xassert (BEGV
>= BEG
);
8711 xassert (ZV
<= Z
&& ZV
>= BEGV
);
8713 unbind_to (count
, Qnil
);
8718 /* Save state that should be preserved around the call to the function
8719 FN called in with_echo_area_buffer. */
8722 with_echo_area_buffer_unwind_data (struct window
*w
)
8725 Lisp_Object vector
, tmp
;
8727 /* Reduce consing by keeping one vector in
8728 Vwith_echo_area_save_vector. */
8729 vector
= Vwith_echo_area_save_vector
;
8730 Vwith_echo_area_save_vector
= Qnil
;
8733 vector
= Fmake_vector (make_number (7), Qnil
);
8735 XSETBUFFER (tmp
, current_buffer
); ASET (vector
, i
, tmp
); ++i
;
8736 ASET (vector
, i
, Vdeactivate_mark
); ++i
;
8737 ASET (vector
, i
, make_number (windows_or_buffers_changed
)); ++i
;
8741 XSETWINDOW (tmp
, w
); ASET (vector
, i
, tmp
); ++i
;
8742 ASET (vector
, i
, w
->buffer
); ++i
;
8743 ASET (vector
, i
, make_number (XMARKER (w
->pointm
)->charpos
)); ++i
;
8744 ASET (vector
, i
, make_number (XMARKER (w
->pointm
)->bytepos
)); ++i
;
8749 for (; i
< end
; ++i
)
8750 ASET (vector
, i
, Qnil
);
8753 xassert (i
== ASIZE (vector
));
8758 /* Restore global state from VECTOR which was created by
8759 with_echo_area_buffer_unwind_data. */
8762 unwind_with_echo_area_buffer (Lisp_Object vector
)
8764 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
8765 Vdeactivate_mark
= AREF (vector
, 1);
8766 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
8768 if (WINDOWP (AREF (vector
, 3)))
8771 Lisp_Object buffer
, charpos
, bytepos
;
8773 w
= XWINDOW (AREF (vector
, 3));
8774 buffer
= AREF (vector
, 4);
8775 charpos
= AREF (vector
, 5);
8776 bytepos
= AREF (vector
, 6);
8779 set_marker_both (w
->pointm
, buffer
,
8780 XFASTINT (charpos
), XFASTINT (bytepos
));
8783 Vwith_echo_area_save_vector
= vector
;
8788 /* Set up the echo area for use by print functions. MULTIBYTE_P
8789 non-zero means we will print multibyte. */
8792 setup_echo_area_for_printing (int multibyte_p
)
8794 /* If we can't find an echo area any more, exit. */
8795 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
8798 ensure_echo_area_buffers ();
8800 if (!message_buf_print
)
8802 /* A message has been output since the last time we printed.
8803 Choose a fresh echo area buffer. */
8804 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
8805 echo_area_buffer
[0] = echo_buffer
[1];
8807 echo_area_buffer
[0] = echo_buffer
[0];
8809 /* Switch to that buffer and clear it. */
8810 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
8811 current_buffer
->truncate_lines
= Qnil
;
8815 int count
= SPECPDL_INDEX ();
8816 specbind (Qinhibit_read_only
, Qt
);
8817 /* Note that undo recording is always disabled. */
8819 unbind_to (count
, Qnil
);
8821 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
8823 /* Set up the buffer for the multibyteness we need. */
8825 != !NILP (current_buffer
->enable_multibyte_characters
))
8826 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
8828 /* Raise the frame containing the echo area. */
8829 if (minibuffer_auto_raise
)
8831 struct frame
*sf
= SELECTED_FRAME ();
8832 Lisp_Object mini_window
;
8833 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8834 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
8837 message_log_maybe_newline ();
8838 message_buf_print
= 1;
8842 if (NILP (echo_area_buffer
[0]))
8844 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
8845 echo_area_buffer
[0] = echo_buffer
[1];
8847 echo_area_buffer
[0] = echo_buffer
[0];
8850 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
8852 /* Someone switched buffers between print requests. */
8853 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
8854 current_buffer
->truncate_lines
= Qnil
;
8860 /* Display an echo area message in window W. Value is non-zero if W's
8861 height is changed. If display_last_displayed_message_p is
8862 non-zero, display the message that was last displayed, otherwise
8863 display the current message. */
8866 display_echo_area (struct window
*w
)
8868 int i
, no_message_p
, window_height_changed_p
, count
;
8870 /* Temporarily disable garbage collections while displaying the echo
8871 area. This is done because a GC can print a message itself.
8872 That message would modify the echo area buffer's contents while a
8873 redisplay of the buffer is going on, and seriously confuse
8875 count
= inhibit_garbage_collection ();
8877 /* If there is no message, we must call display_echo_area_1
8878 nevertheless because it resizes the window. But we will have to
8879 reset the echo_area_buffer in question to nil at the end because
8880 with_echo_area_buffer will sets it to an empty buffer. */
8881 i
= display_last_displayed_message_p
? 1 : 0;
8882 no_message_p
= NILP (echo_area_buffer
[i
]);
8884 window_height_changed_p
8885 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
8886 display_echo_area_1
,
8887 (EMACS_INT
) w
, Qnil
, 0, 0);
8890 echo_area_buffer
[i
] = Qnil
;
8892 unbind_to (count
, Qnil
);
8893 return window_height_changed_p
;
8897 /* Helper for display_echo_area. Display the current buffer which
8898 contains the current echo area message in window W, a mini-window,
8899 a pointer to which is passed in A1. A2..A4 are currently not used.
8900 Change the height of W so that all of the message is displayed.
8901 Value is non-zero if height of W was changed. */
8904 display_echo_area_1 (EMACS_INT a1
, Lisp_Object a2
, EMACS_INT a3
, EMACS_INT a4
)
8906 struct window
*w
= (struct window
*) a1
;
8908 struct text_pos start
;
8909 int window_height_changed_p
= 0;
8911 /* Do this before displaying, so that we have a large enough glyph
8912 matrix for the display. If we can't get enough space for the
8913 whole text, display the last N lines. That works by setting w->start. */
8914 window_height_changed_p
= resize_mini_window (w
, 0);
8916 /* Use the starting position chosen by resize_mini_window. */
8917 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
8920 clear_glyph_matrix (w
->desired_matrix
);
8921 XSETWINDOW (window
, w
);
8922 try_window (window
, start
, 0);
8924 return window_height_changed_p
;
8928 /* Resize the echo area window to exactly the size needed for the
8929 currently displayed message, if there is one. If a mini-buffer
8930 is active, don't shrink it. */
8933 resize_echo_area_exactly (void)
8935 if (BUFFERP (echo_area_buffer
[0])
8936 && WINDOWP (echo_area_window
))
8938 struct window
*w
= XWINDOW (echo_area_window
);
8940 Lisp_Object resize_exactly
;
8942 if (minibuf_level
== 0)
8943 resize_exactly
= Qt
;
8945 resize_exactly
= Qnil
;
8947 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
8948 (EMACS_INT
) w
, resize_exactly
, 0, 0);
8951 ++windows_or_buffers_changed
;
8952 ++update_mode_lines
;
8953 redisplay_internal (0);
8959 /* Callback function for with_echo_area_buffer, when used from
8960 resize_echo_area_exactly. A1 contains a pointer to the window to
8961 resize, EXACTLY non-nil means resize the mini-window exactly to the
8962 size of the text displayed. A3 and A4 are not used. Value is what
8963 resize_mini_window returns. */
8966 resize_mini_window_1 (EMACS_INT a1
, Lisp_Object exactly
, EMACS_INT a3
, EMACS_INT a4
)
8968 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
8972 /* Resize mini-window W to fit the size of its contents. EXACT_P
8973 means size the window exactly to the size needed. Otherwise, it's
8974 only enlarged until W's buffer is empty.
8976 Set W->start to the right place to begin display. If the whole
8977 contents fit, start at the beginning. Otherwise, start so as
8978 to make the end of the contents appear. This is particularly
8979 important for y-or-n-p, but seems desirable generally.
8981 Value is non-zero if the window height has been changed. */
8984 resize_mini_window (struct window
*w
, int exact_p
)
8986 struct frame
*f
= XFRAME (w
->frame
);
8987 int window_height_changed_p
= 0;
8989 xassert (MINI_WINDOW_P (w
));
8991 /* By default, start display at the beginning. */
8992 set_marker_both (w
->start
, w
->buffer
,
8993 BUF_BEGV (XBUFFER (w
->buffer
)),
8994 BUF_BEGV_BYTE (XBUFFER (w
->buffer
)));
8996 /* Don't resize windows while redisplaying a window; it would
8997 confuse redisplay functions when the size of the window they are
8998 displaying changes from under them. Such a resizing can happen,
8999 for instance, when which-func prints a long message while
9000 we are running fontification-functions. We're running these
9001 functions with safe_call which binds inhibit-redisplay to t. */
9002 if (!NILP (Vinhibit_redisplay
))
9005 /* Nil means don't try to resize. */
9006 if (NILP (Vresize_mini_windows
)
9007 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
9010 if (!FRAME_MINIBUF_ONLY_P (f
))
9013 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
9014 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
9015 int height
, max_height
;
9016 int unit
= FRAME_LINE_HEIGHT (f
);
9017 struct text_pos start
;
9018 struct buffer
*old_current_buffer
= NULL
;
9020 if (current_buffer
!= XBUFFER (w
->buffer
))
9022 old_current_buffer
= current_buffer
;
9023 set_buffer_internal (XBUFFER (w
->buffer
));
9026 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
9028 /* Compute the max. number of lines specified by the user. */
9029 if (FLOATP (Vmax_mini_window_height
))
9030 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
9031 else if (INTEGERP (Vmax_mini_window_height
))
9032 max_height
= XINT (Vmax_mini_window_height
);
9034 max_height
= total_height
/ 4;
9036 /* Correct that max. height if it's bogus. */
9037 max_height
= max (1, max_height
);
9038 max_height
= min (total_height
, max_height
);
9040 /* Find out the height of the text in the window. */
9041 if (it
.line_wrap
== TRUNCATE
)
9046 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
9047 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
9048 height
= it
.current_y
+ last_height
;
9050 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
9051 height
-= min (it
.extra_line_spacing
, it
.max_extra_line_spacing
);
9052 height
= (height
+ unit
- 1) / unit
;
9055 /* Compute a suitable window start. */
9056 if (height
> max_height
)
9058 height
= max_height
;
9059 init_iterator (&it
, w
, ZV
, ZV_BYTE
, NULL
, DEFAULT_FACE_ID
);
9060 move_it_vertically_backward (&it
, (height
- 1) * unit
);
9061 start
= it
.current
.pos
;
9064 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
9065 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
9067 if (EQ (Vresize_mini_windows
, Qgrow_only
))
9069 /* Let it grow only, until we display an empty message, in which
9070 case the window shrinks again. */
9071 if (height
> WINDOW_TOTAL_LINES (w
))
9073 int old_height
= WINDOW_TOTAL_LINES (w
);
9074 freeze_window_starts (f
, 1);
9075 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
9076 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
9078 else if (height
< WINDOW_TOTAL_LINES (w
)
9079 && (exact_p
|| BEGV
== ZV
))
9081 int old_height
= WINDOW_TOTAL_LINES (w
);
9082 freeze_window_starts (f
, 0);
9083 shrink_mini_window (w
);
9084 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
9089 /* Always resize to exact size needed. */
9090 if (height
> WINDOW_TOTAL_LINES (w
))
9092 int old_height
= WINDOW_TOTAL_LINES (w
);
9093 freeze_window_starts (f
, 1);
9094 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
9095 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
9097 else if (height
< WINDOW_TOTAL_LINES (w
))
9099 int old_height
= WINDOW_TOTAL_LINES (w
);
9100 freeze_window_starts (f
, 0);
9101 shrink_mini_window (w
);
9105 freeze_window_starts (f
, 1);
9106 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
9109 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
9113 if (old_current_buffer
)
9114 set_buffer_internal (old_current_buffer
);
9117 return window_height_changed_p
;
9121 /* Value is the current message, a string, or nil if there is no
9125 current_message (void)
9129 if (!BUFFERP (echo_area_buffer
[0]))
9133 with_echo_area_buffer (0, 0, current_message_1
,
9134 (EMACS_INT
) &msg
, Qnil
, 0, 0);
9136 echo_area_buffer
[0] = Qnil
;
9144 current_message_1 (EMACS_INT a1
, Lisp_Object a2
, EMACS_INT a3
, EMACS_INT a4
)
9146 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
9149 *msg
= make_buffer_string (BEG
, Z
, 1);
9156 /* Push the current message on Vmessage_stack for later restauration
9157 by restore_message. Value is non-zero if the current message isn't
9158 empty. This is a relatively infrequent operation, so it's not
9159 worth optimizing. */
9165 msg
= current_message ();
9166 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
9167 return STRINGP (msg
);
9171 /* Restore message display from the top of Vmessage_stack. */
9174 restore_message (void)
9178 xassert (CONSP (Vmessage_stack
));
9179 msg
= XCAR (Vmessage_stack
);
9181 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
9183 message3_nolog (msg
, 0, 0);
9187 /* Handler for record_unwind_protect calling pop_message. */
9190 pop_message_unwind (Lisp_Object dummy
)
9196 /* Pop the top-most entry off Vmessage_stack. */
9201 xassert (CONSP (Vmessage_stack
));
9202 Vmessage_stack
= XCDR (Vmessage_stack
);
9206 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9207 exits. If the stack is not empty, we have a missing pop_message
9211 check_message_stack (void)
9213 if (!NILP (Vmessage_stack
))
9218 /* Truncate to NCHARS what will be displayed in the echo area the next
9219 time we display it---but don't redisplay it now. */
9222 truncate_echo_area (int nchars
)
9225 echo_area_buffer
[0] = Qnil
;
9226 /* A null message buffer means that the frame hasn't really been
9227 initialized yet. Error messages get reported properly by
9228 cmd_error, so this must be just an informative message; toss it. */
9229 else if (!noninteractive
9231 && !NILP (echo_area_buffer
[0]))
9233 struct frame
*sf
= SELECTED_FRAME ();
9234 if (FRAME_MESSAGE_BUF (sf
))
9235 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
9240 /* Helper function for truncate_echo_area. Truncate the current
9241 message to at most NCHARS characters. */
9244 truncate_message_1 (EMACS_INT nchars
, Lisp_Object a2
, EMACS_INT a3
, EMACS_INT a4
)
9246 if (BEG
+ nchars
< Z
)
9247 del_range (BEG
+ nchars
, Z
);
9249 echo_area_buffer
[0] = Qnil
;
9254 /* Set the current message to a substring of S or STRING.
9256 If STRING is a Lisp string, set the message to the first NBYTES
9257 bytes from STRING. NBYTES zero means use the whole string. If
9258 STRING is multibyte, the message will be displayed multibyte.
9260 If S is not null, set the message to the first LEN bytes of S. LEN
9261 zero means use the whole string. MULTIBYTE_P non-zero means S is
9262 multibyte. Display the message multibyte in that case.
9264 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9265 to t before calling set_message_1 (which calls insert).
9269 set_message (const char *s
, Lisp_Object string
, int nbytes
, int multibyte_p
)
9271 message_enable_multibyte
9272 = ((s
&& multibyte_p
)
9273 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
9275 with_echo_area_buffer (0, -1, set_message_1
,
9276 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
9277 message_buf_print
= 0;
9278 help_echo_showing_p
= 0;
9282 /* Helper function for set_message. Arguments have the same meaning
9283 as there, with A1 corresponding to S and A2 corresponding to STRING
9284 This function is called with the echo area buffer being
9288 set_message_1 (EMACS_INT a1
, Lisp_Object a2
, EMACS_INT nbytes
, EMACS_INT multibyte_p
)
9290 const char *s
= (const char *) a1
;
9291 Lisp_Object string
= a2
;
9293 /* Change multibyteness of the echo buffer appropriately. */
9294 if (message_enable_multibyte
9295 != !NILP (current_buffer
->enable_multibyte_characters
))
9296 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
9298 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
9300 /* Insert new message at BEG. */
9301 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
9303 if (STRINGP (string
))
9308 nbytes
= SBYTES (string
);
9309 nchars
= string_byte_to_char (string
, nbytes
);
9311 /* This function takes care of single/multibyte conversion. We
9312 just have to ensure that the echo area buffer has the right
9313 setting of enable_multibyte_characters. */
9314 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
9319 nbytes
= strlen (s
);
9321 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
9323 /* Convert from multi-byte to single-byte. */
9325 unsigned char work
[1];
9327 /* Convert a multibyte string to single-byte. */
9328 for (i
= 0; i
< nbytes
; i
+= n
)
9330 c
= string_char_and_length (s
+ i
, &n
);
9331 work
[0] = (ASCII_CHAR_P (c
)
9333 : multibyte_char_to_unibyte (c
, Qnil
));
9334 insert_1_both (work
, 1, 1, 1, 0, 0);
9337 else if (!multibyte_p
9338 && !NILP (current_buffer
->enable_multibyte_characters
))
9340 /* Convert from single-byte to multi-byte. */
9342 const unsigned char *msg
= (const unsigned char *) s
;
9343 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
9345 /* Convert a single-byte string to multibyte. */
9346 for (i
= 0; i
< nbytes
; i
++)
9349 MAKE_CHAR_MULTIBYTE (c
);
9350 n
= CHAR_STRING (c
, str
);
9351 insert_1_both (str
, 1, n
, 1, 0, 0);
9355 insert_1 (s
, nbytes
, 1, 0, 0);
9362 /* Clear messages. CURRENT_P non-zero means clear the current
9363 message. LAST_DISPLAYED_P non-zero means clear the message
9367 clear_message (int current_p
, int last_displayed_p
)
9371 echo_area_buffer
[0] = Qnil
;
9372 message_cleared_p
= 1;
9375 if (last_displayed_p
)
9376 echo_area_buffer
[1] = Qnil
;
9378 message_buf_print
= 0;
9381 /* Clear garbaged frames.
9383 This function is used where the old redisplay called
9384 redraw_garbaged_frames which in turn called redraw_frame which in
9385 turn called clear_frame. The call to clear_frame was a source of
9386 flickering. I believe a clear_frame is not necessary. It should
9387 suffice in the new redisplay to invalidate all current matrices,
9388 and ensure a complete redisplay of all windows. */
9391 clear_garbaged_frames (void)
9395 Lisp_Object tail
, frame
;
9396 int changed_count
= 0;
9398 FOR_EACH_FRAME (tail
, frame
)
9400 struct frame
*f
= XFRAME (frame
);
9402 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
9406 Fredraw_frame (frame
);
9407 f
->force_flush_display_p
= 1;
9409 clear_current_matrices (f
);
9418 ++windows_or_buffers_changed
;
9423 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9424 is non-zero update selected_frame. Value is non-zero if the
9425 mini-windows height has been changed. */
9428 echo_area_display (int update_frame_p
)
9430 Lisp_Object mini_window
;
9433 int window_height_changed_p
= 0;
9434 struct frame
*sf
= SELECTED_FRAME ();
9436 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9437 w
= XWINDOW (mini_window
);
9438 f
= XFRAME (WINDOW_FRAME (w
));
9440 /* Don't display if frame is invisible or not yet initialized. */
9441 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
9444 #ifdef HAVE_WINDOW_SYSTEM
9445 /* When Emacs starts, selected_frame may be the initial terminal
9446 frame. If we let this through, a message would be displayed on
9448 if (FRAME_INITIAL_P (XFRAME (selected_frame
)))
9450 #endif /* HAVE_WINDOW_SYSTEM */
9452 /* Redraw garbaged frames. */
9454 clear_garbaged_frames ();
9456 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
9458 echo_area_window
= mini_window
;
9459 window_height_changed_p
= display_echo_area (w
);
9460 w
->must_be_updated_p
= 1;
9462 /* Update the display, unless called from redisplay_internal.
9463 Also don't update the screen during redisplay itself. The
9464 update will happen at the end of redisplay, and an update
9465 here could cause confusion. */
9466 if (update_frame_p
&& !redisplaying_p
)
9470 /* If the display update has been interrupted by pending
9471 input, update mode lines in the frame. Due to the
9472 pending input, it might have been that redisplay hasn't
9473 been called, so that mode lines above the echo area are
9474 garbaged. This looks odd, so we prevent it here. */
9475 if (!display_completed
)
9476 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
9478 if (window_height_changed_p
9479 /* Don't do this if Emacs is shutting down. Redisplay
9480 needs to run hooks. */
9481 && !NILP (Vrun_hooks
))
9483 /* Must update other windows. Likewise as in other
9484 cases, don't let this update be interrupted by
9486 int count
= SPECPDL_INDEX ();
9487 specbind (Qredisplay_dont_pause
, Qt
);
9488 windows_or_buffers_changed
= 1;
9489 redisplay_internal (0);
9490 unbind_to (count
, Qnil
);
9492 else if (FRAME_WINDOW_P (f
) && n
== 0)
9494 /* Window configuration is the same as before.
9495 Can do with a display update of the echo area,
9496 unless we displayed some mode lines. */
9497 update_single_window (w
, 1);
9498 FRAME_RIF (f
)->flush_display (f
);
9501 update_frame (f
, 1, 1);
9503 /* If cursor is in the echo area, make sure that the next
9504 redisplay displays the minibuffer, so that the cursor will
9505 be replaced with what the minibuffer wants. */
9506 if (cursor_in_echo_area
)
9507 ++windows_or_buffers_changed
;
9510 else if (!EQ (mini_window
, selected_window
))
9511 windows_or_buffers_changed
++;
9513 /* Last displayed message is now the current message. */
9514 echo_area_buffer
[1] = echo_area_buffer
[0];
9515 /* Inform read_char that we're not echoing. */
9516 echo_message_buffer
= Qnil
;
9518 /* Prevent redisplay optimization in redisplay_internal by resetting
9519 this_line_start_pos. This is done because the mini-buffer now
9520 displays the message instead of its buffer text. */
9521 if (EQ (mini_window
, selected_window
))
9522 CHARPOS (this_line_start_pos
) = 0;
9524 return window_height_changed_p
;
9529 /***********************************************************************
9530 Mode Lines and Frame Titles
9531 ***********************************************************************/
9533 /* A buffer for constructing non-propertized mode-line strings and
9534 frame titles in it; allocated from the heap in init_xdisp and
9535 resized as needed in store_mode_line_noprop_char. */
9537 static char *mode_line_noprop_buf
;
9539 /* The buffer's end, and a current output position in it. */
9541 static char *mode_line_noprop_buf_end
;
9542 static char *mode_line_noprop_ptr
;
9544 #define MODE_LINE_NOPROP_LEN(start) \
9545 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9548 MODE_LINE_DISPLAY
= 0,
9554 /* Alist that caches the results of :propertize.
9555 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9556 static Lisp_Object mode_line_proptrans_alist
;
9558 /* List of strings making up the mode-line. */
9559 static Lisp_Object mode_line_string_list
;
9561 /* Base face property when building propertized mode line string. */
9562 static Lisp_Object mode_line_string_face
;
9563 static Lisp_Object mode_line_string_face_prop
;
9566 /* Unwind data for mode line strings */
9568 static Lisp_Object Vmode_line_unwind_vector
;
9571 format_mode_line_unwind_data (struct buffer
*obuf
,
9575 Lisp_Object vector
, tmp
;
9577 /* Reduce consing by keeping one vector in
9578 Vwith_echo_area_save_vector. */
9579 vector
= Vmode_line_unwind_vector
;
9580 Vmode_line_unwind_vector
= Qnil
;
9583 vector
= Fmake_vector (make_number (8), Qnil
);
9585 ASET (vector
, 0, make_number (mode_line_target
));
9586 ASET (vector
, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9587 ASET (vector
, 2, mode_line_string_list
);
9588 ASET (vector
, 3, save_proptrans
? mode_line_proptrans_alist
: Qt
);
9589 ASET (vector
, 4, mode_line_string_face
);
9590 ASET (vector
, 5, mode_line_string_face_prop
);
9593 XSETBUFFER (tmp
, obuf
);
9596 ASET (vector
, 6, tmp
);
9597 ASET (vector
, 7, owin
);
9603 unwind_format_mode_line (Lisp_Object vector
)
9605 mode_line_target
= XINT (AREF (vector
, 0));
9606 mode_line_noprop_ptr
= mode_line_noprop_buf
+ XINT (AREF (vector
, 1));
9607 mode_line_string_list
= AREF (vector
, 2);
9608 if (! EQ (AREF (vector
, 3), Qt
))
9609 mode_line_proptrans_alist
= AREF (vector
, 3);
9610 mode_line_string_face
= AREF (vector
, 4);
9611 mode_line_string_face_prop
= AREF (vector
, 5);
9613 if (!NILP (AREF (vector
, 7)))
9614 /* Select window before buffer, since it may change the buffer. */
9615 Fselect_window (AREF (vector
, 7), Qt
);
9617 if (!NILP (AREF (vector
, 6)))
9619 set_buffer_internal_1 (XBUFFER (AREF (vector
, 6)));
9620 ASET (vector
, 6, Qnil
);
9623 Vmode_line_unwind_vector
= vector
;
9628 /* Store a single character C for the frame title in mode_line_noprop_buf.
9629 Re-allocate mode_line_noprop_buf if necessary. */
9632 store_mode_line_noprop_char (char c
)
9634 /* If output position has reached the end of the allocated buffer,
9635 double the buffer's size. */
9636 if (mode_line_noprop_ptr
== mode_line_noprop_buf_end
)
9638 int len
= MODE_LINE_NOPROP_LEN (0);
9639 int new_size
= 2 * len
* sizeof *mode_line_noprop_buf
;
9640 mode_line_noprop_buf
= (char *) xrealloc (mode_line_noprop_buf
, new_size
);
9641 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ new_size
;
9642 mode_line_noprop_ptr
= mode_line_noprop_buf
+ len
;
9645 *mode_line_noprop_ptr
++ = c
;
9649 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9650 mode_line_noprop_ptr. STR is the string to store. Do not copy
9651 characters that yield more columns than PRECISION; PRECISION <= 0
9652 means copy the whole string. Pad with spaces until FIELD_WIDTH
9653 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9654 pad. Called from display_mode_element when it is used to build a
9658 store_mode_line_noprop (const unsigned char *str
, int field_width
, int precision
)
9663 /* Copy at most PRECISION chars from STR. */
9664 nbytes
= strlen (str
);
9665 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
9667 store_mode_line_noprop_char (*str
++);
9669 /* Fill up with spaces until FIELD_WIDTH reached. */
9670 while (field_width
> 0
9673 store_mode_line_noprop_char (' ');
9680 /***********************************************************************
9682 ***********************************************************************/
9684 #ifdef HAVE_WINDOW_SYSTEM
9686 /* Set the title of FRAME, if it has changed. The title format is
9687 Vicon_title_format if FRAME is iconified, otherwise it is
9688 frame_title_format. */
9691 x_consider_frame_title (Lisp_Object frame
)
9693 struct frame
*f
= XFRAME (frame
);
9695 if (FRAME_WINDOW_P (f
)
9696 || FRAME_MINIBUF_ONLY_P (f
)
9697 || f
->explicit_name
)
9699 /* Do we have more than one visible frame on this X display? */
9706 int count
= SPECPDL_INDEX ();
9708 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
9710 Lisp_Object other_frame
= XCAR (tail
);
9711 struct frame
*tf
= XFRAME (other_frame
);
9714 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
9715 && !FRAME_MINIBUF_ONLY_P (tf
)
9716 && !EQ (other_frame
, tip_frame
)
9717 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
9721 /* Set global variable indicating that multiple frames exist. */
9722 multiple_frames
= CONSP (tail
);
9724 /* Switch to the buffer of selected window of the frame. Set up
9725 mode_line_target so that display_mode_element will output into
9726 mode_line_noprop_buf; then display the title. */
9727 record_unwind_protect (unwind_format_mode_line
,
9728 format_mode_line_unwind_data
9729 (current_buffer
, selected_window
, 0));
9731 Fselect_window (f
->selected_window
, Qt
);
9732 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
9733 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
9735 mode_line_target
= MODE_LINE_TITLE
;
9736 title_start
= MODE_LINE_NOPROP_LEN (0);
9737 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
9738 NULL
, DEFAULT_FACE_ID
);
9739 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
9740 len
= MODE_LINE_NOPROP_LEN (title_start
);
9741 title
= mode_line_noprop_buf
+ title_start
;
9742 unbind_to (count
, Qnil
);
9744 /* Set the title only if it's changed. This avoids consing in
9745 the common case where it hasn't. (If it turns out that we've
9746 already wasted too much time by walking through the list with
9747 display_mode_element, then we might need to optimize at a
9748 higher level than this.) */
9749 if (! STRINGP (f
->name
)
9750 || SBYTES (f
->name
) != len
9751 || memcmp (title
, SDATA (f
->name
), len
) != 0)
9752 x_implicitly_set_name (f
, make_string (title
, len
), Qnil
);
9756 #endif /* not HAVE_WINDOW_SYSTEM */
9761 /***********************************************************************
9763 ***********************************************************************/
9766 /* Prepare for redisplay by updating menu-bar item lists when
9767 appropriate. This can call eval. */
9770 prepare_menu_bars (void)
9773 struct gcpro gcpro1
, gcpro2
;
9775 Lisp_Object tooltip_frame
;
9777 #ifdef HAVE_WINDOW_SYSTEM
9778 tooltip_frame
= tip_frame
;
9780 tooltip_frame
= Qnil
;
9783 /* Update all frame titles based on their buffer names, etc. We do
9784 this before the menu bars so that the buffer-menu will show the
9785 up-to-date frame titles. */
9786 #ifdef HAVE_WINDOW_SYSTEM
9787 if (windows_or_buffers_changed
|| update_mode_lines
)
9789 Lisp_Object tail
, frame
;
9791 FOR_EACH_FRAME (tail
, frame
)
9794 if (!EQ (frame
, tooltip_frame
)
9795 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
9796 x_consider_frame_title (frame
);
9799 #endif /* HAVE_WINDOW_SYSTEM */
9801 /* Update the menu bar item lists, if appropriate. This has to be
9802 done before any actual redisplay or generation of display lines. */
9803 all_windows
= (update_mode_lines
9804 || buffer_shared
> 1
9805 || windows_or_buffers_changed
);
9808 Lisp_Object tail
, frame
;
9809 int count
= SPECPDL_INDEX ();
9810 /* 1 means that update_menu_bar has run its hooks
9811 so any further calls to update_menu_bar shouldn't do so again. */
9812 int menu_bar_hooks_run
= 0;
9814 record_unwind_save_match_data ();
9816 FOR_EACH_FRAME (tail
, frame
)
9820 /* Ignore tooltip frame. */
9821 if (EQ (frame
, tooltip_frame
))
9824 /* If a window on this frame changed size, report that to
9825 the user and clear the size-change flag. */
9826 if (FRAME_WINDOW_SIZES_CHANGED (f
))
9828 Lisp_Object functions
;
9830 /* Clear flag first in case we get an error below. */
9831 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
9832 functions
= Vwindow_size_change_functions
;
9833 GCPRO2 (tail
, functions
);
9835 while (CONSP (functions
))
9837 if (!EQ (XCAR (functions
), Qt
))
9838 call1 (XCAR (functions
), frame
);
9839 functions
= XCDR (functions
);
9845 menu_bar_hooks_run
= update_menu_bar (f
, 0, menu_bar_hooks_run
);
9846 #ifdef HAVE_WINDOW_SYSTEM
9847 update_tool_bar (f
, 0);
9850 if (windows_or_buffers_changed
9852 ns_set_doc_edited (f
, Fbuffer_modified_p
9853 (XWINDOW (f
->selected_window
)->buffer
));
9858 unbind_to (count
, Qnil
);
9862 struct frame
*sf
= SELECTED_FRAME ();
9863 update_menu_bar (sf
, 1, 0);
9864 #ifdef HAVE_WINDOW_SYSTEM
9865 update_tool_bar (sf
, 1);
9871 /* Update the menu bar item list for frame F. This has to be done
9872 before we start to fill in any display lines, because it can call
9875 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9877 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9878 already ran the menu bar hooks for this redisplay, so there
9879 is no need to run them again. The return value is the
9880 updated value of this flag, to pass to the next call. */
9883 update_menu_bar (struct frame
*f
, int save_match_data
, int hooks_run
)
9886 register struct window
*w
;
9888 /* If called recursively during a menu update, do nothing. This can
9889 happen when, for instance, an activate-menubar-hook causes a
9891 if (inhibit_menubar_update
)
9894 window
= FRAME_SELECTED_WINDOW (f
);
9895 w
= XWINDOW (window
);
9897 if (FRAME_WINDOW_P (f
)
9899 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9900 || defined (HAVE_NS) || defined (USE_GTK)
9901 FRAME_EXTERNAL_MENU_BAR (f
)
9903 FRAME_MENU_BAR_LINES (f
) > 0
9905 : FRAME_MENU_BAR_LINES (f
) > 0)
9907 /* If the user has switched buffers or windows, we need to
9908 recompute to reflect the new bindings. But we'll
9909 recompute when update_mode_lines is set too; that means
9910 that people can use force-mode-line-update to request
9911 that the menu bar be recomputed. The adverse effect on
9912 the rest of the redisplay algorithm is about the same as
9913 windows_or_buffers_changed anyway. */
9914 if (windows_or_buffers_changed
9915 /* This used to test w->update_mode_line, but we believe
9916 there is no need to recompute the menu in that case. */
9917 || update_mode_lines
9918 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
9919 < BUF_MODIFF (XBUFFER (w
->buffer
)))
9920 != !NILP (w
->last_had_star
))
9921 || ((!NILP (Vtransient_mark_mode
)
9922 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9923 != !NILP (w
->region_showing
)))
9925 struct buffer
*prev
= current_buffer
;
9926 int count
= SPECPDL_INDEX ();
9928 specbind (Qinhibit_menubar_update
, Qt
);
9930 set_buffer_internal_1 (XBUFFER (w
->buffer
));
9931 if (save_match_data
)
9932 record_unwind_save_match_data ();
9933 if (NILP (Voverriding_local_map_menu_flag
))
9935 specbind (Qoverriding_terminal_local_map
, Qnil
);
9936 specbind (Qoverriding_local_map
, Qnil
);
9941 /* Run the Lucid hook. */
9942 safe_run_hooks (Qactivate_menubar_hook
);
9944 /* If it has changed current-menubar from previous value,
9945 really recompute the menu-bar from the value. */
9946 if (! NILP (Vlucid_menu_bar_dirty_flag
))
9947 call0 (Qrecompute_lucid_menubar
);
9949 safe_run_hooks (Qmenu_bar_update_hook
);
9954 XSETFRAME (Vmenu_updating_frame
, f
);
9955 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
9957 /* Redisplay the menu bar in case we changed it. */
9958 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9959 || defined (HAVE_NS) || defined (USE_GTK)
9960 if (FRAME_WINDOW_P (f
))
9962 #if defined (HAVE_NS)
9963 /* All frames on Mac OS share the same menubar. So only
9964 the selected frame should be allowed to set it. */
9965 if (f
== SELECTED_FRAME ())
9967 set_frame_menubar (f
, 0, 0);
9970 /* On a terminal screen, the menu bar is an ordinary screen
9971 line, and this makes it get updated. */
9972 w
->update_mode_line
= Qt
;
9973 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9974 /* In the non-toolkit version, the menu bar is an ordinary screen
9975 line, and this makes it get updated. */
9976 w
->update_mode_line
= Qt
;
9977 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9979 unbind_to (count
, Qnil
);
9980 set_buffer_internal_1 (prev
);
9989 /***********************************************************************
9991 ***********************************************************************/
9993 #ifdef HAVE_WINDOW_SYSTEM
9996 Nominal cursor position -- where to draw output.
9997 HPOS and VPOS are window relative glyph matrix coordinates.
9998 X and Y are window relative pixel coordinates. */
10000 struct cursor_pos output_cursor
;
10004 Set the global variable output_cursor to CURSOR. All cursor
10005 positions are relative to updated_window. */
10008 set_output_cursor (struct cursor_pos
*cursor
)
10010 output_cursor
.hpos
= cursor
->hpos
;
10011 output_cursor
.vpos
= cursor
->vpos
;
10012 output_cursor
.x
= cursor
->x
;
10013 output_cursor
.y
= cursor
->y
;
10018 Set a nominal cursor position.
10020 HPOS and VPOS are column/row positions in a window glyph matrix. X
10021 and Y are window text area relative pixel positions.
10023 If this is done during an update, updated_window will contain the
10024 window that is being updated and the position is the future output
10025 cursor position for that window. If updated_window is null, use
10026 selected_window and display the cursor at the given position. */
10029 x_cursor_to (int vpos
, int hpos
, int y
, int x
)
10033 /* If updated_window is not set, work on selected_window. */
10034 if (updated_window
)
10035 w
= updated_window
;
10037 w
= XWINDOW (selected_window
);
10039 /* Set the output cursor. */
10040 output_cursor
.hpos
= hpos
;
10041 output_cursor
.vpos
= vpos
;
10042 output_cursor
.x
= x
;
10043 output_cursor
.y
= y
;
10045 /* If not called as part of an update, really display the cursor.
10046 This will also set the cursor position of W. */
10047 if (updated_window
== NULL
)
10050 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
10051 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional
)
10052 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10057 #endif /* HAVE_WINDOW_SYSTEM */
10060 /***********************************************************************
10062 ***********************************************************************/
10064 #ifdef HAVE_WINDOW_SYSTEM
10066 /* Where the mouse was last time we reported a mouse event. */
10068 FRAME_PTR last_mouse_frame
;
10070 /* Tool-bar item index of the item on which a mouse button was pressed
10073 int last_tool_bar_item
;
10077 update_tool_bar_unwind (Lisp_Object frame
)
10079 selected_frame
= frame
;
10083 /* Update the tool-bar item list for frame F. This has to be done
10084 before we start to fill in any display lines. Called from
10085 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10086 and restore it here. */
10089 update_tool_bar (struct frame
*f
, int save_match_data
)
10091 #if defined (USE_GTK) || defined (HAVE_NS)
10092 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
10094 int do_update
= WINDOWP (f
->tool_bar_window
)
10095 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
10100 Lisp_Object window
;
10103 window
= FRAME_SELECTED_WINDOW (f
);
10104 w
= XWINDOW (window
);
10106 /* If the user has switched buffers or windows, we need to
10107 recompute to reflect the new bindings. But we'll
10108 recompute when update_mode_lines is set too; that means
10109 that people can use force-mode-line-update to request
10110 that the menu bar be recomputed. The adverse effect on
10111 the rest of the redisplay algorithm is about the same as
10112 windows_or_buffers_changed anyway. */
10113 if (windows_or_buffers_changed
10114 || !NILP (w
->update_mode_line
)
10115 || update_mode_lines
10116 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
10117 < BUF_MODIFF (XBUFFER (w
->buffer
)))
10118 != !NILP (w
->last_had_star
))
10119 || ((!NILP (Vtransient_mark_mode
)
10120 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
10121 != !NILP (w
->region_showing
)))
10123 struct buffer
*prev
= current_buffer
;
10124 int count
= SPECPDL_INDEX ();
10125 Lisp_Object frame
, new_tool_bar
;
10126 int new_n_tool_bar
;
10127 struct gcpro gcpro1
;
10129 /* Set current_buffer to the buffer of the selected
10130 window of the frame, so that we get the right local
10132 set_buffer_internal_1 (XBUFFER (w
->buffer
));
10134 /* Save match data, if we must. */
10135 if (save_match_data
)
10136 record_unwind_save_match_data ();
10138 /* Make sure that we don't accidentally use bogus keymaps. */
10139 if (NILP (Voverriding_local_map_menu_flag
))
10141 specbind (Qoverriding_terminal_local_map
, Qnil
);
10142 specbind (Qoverriding_local_map
, Qnil
);
10145 GCPRO1 (new_tool_bar
);
10147 /* We must temporarily set the selected frame to this frame
10148 before calling tool_bar_items, because the calculation of
10149 the tool-bar keymap uses the selected frame (see
10150 `tool-bar-make-keymap' in tool-bar.el). */
10151 record_unwind_protect (update_tool_bar_unwind
, selected_frame
);
10152 XSETFRAME (frame
, f
);
10153 selected_frame
= frame
;
10155 /* Build desired tool-bar items from keymaps. */
10156 new_tool_bar
= tool_bar_items (Fcopy_sequence (f
->tool_bar_items
),
10159 /* Redisplay the tool-bar if we changed it. */
10160 if (new_n_tool_bar
!= f
->n_tool_bar_items
10161 || NILP (Fequal (new_tool_bar
, f
->tool_bar_items
)))
10163 /* Redisplay that happens asynchronously due to an expose event
10164 may access f->tool_bar_items. Make sure we update both
10165 variables within BLOCK_INPUT so no such event interrupts. */
10167 f
->tool_bar_items
= new_tool_bar
;
10168 f
->n_tool_bar_items
= new_n_tool_bar
;
10169 w
->update_mode_line
= Qt
;
10175 unbind_to (count
, Qnil
);
10176 set_buffer_internal_1 (prev
);
10182 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10183 F's desired tool-bar contents. F->tool_bar_items must have
10184 been set up previously by calling prepare_menu_bars. */
10187 build_desired_tool_bar_string (struct frame
*f
)
10189 int i
, size
, size_needed
;
10190 struct gcpro gcpro1
, gcpro2
, gcpro3
;
10191 Lisp_Object image
, plist
, props
;
10193 image
= plist
= props
= Qnil
;
10194 GCPRO3 (image
, plist
, props
);
10196 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10197 Otherwise, make a new string. */
10199 /* The size of the string we might be able to reuse. */
10200 size
= (STRINGP (f
->desired_tool_bar_string
)
10201 ? SCHARS (f
->desired_tool_bar_string
)
10204 /* We need one space in the string for each image. */
10205 size_needed
= f
->n_tool_bar_items
;
10207 /* Reuse f->desired_tool_bar_string, if possible. */
10208 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
10209 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
10210 make_number (' '));
10213 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
10214 Fremove_text_properties (make_number (0), make_number (size
),
10215 props
, f
->desired_tool_bar_string
);
10218 /* Put a `display' property on the string for the images to display,
10219 put a `menu_item' property on tool-bar items with a value that
10220 is the index of the item in F's tool-bar item vector. */
10221 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
10223 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10225 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
10226 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
10227 int hmargin
, vmargin
, relief
, idx
, end
;
10228 extern Lisp_Object QCrelief
, QCmargin
, QCconversion
;
10230 /* If image is a vector, choose the image according to the
10232 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
10233 if (VECTORP (image
))
10237 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10238 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
10241 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10242 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
10244 xassert (ASIZE (image
) >= idx
);
10245 image
= AREF (image
, idx
);
10250 /* Ignore invalid image specifications. */
10251 if (!valid_image_p (image
))
10254 /* Display the tool-bar button pressed, or depressed. */
10255 plist
= Fcopy_sequence (XCDR (image
));
10257 /* Compute margin and relief to draw. */
10258 relief
= (tool_bar_button_relief
>= 0
10259 ? tool_bar_button_relief
10260 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
10261 hmargin
= vmargin
= relief
;
10263 if (INTEGERP (Vtool_bar_button_margin
)
10264 && XINT (Vtool_bar_button_margin
) > 0)
10266 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
10267 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
10269 else if (CONSP (Vtool_bar_button_margin
))
10271 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
10272 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
10273 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
10275 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
10276 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
10277 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
10280 if (auto_raise_tool_bar_buttons_p
)
10282 /* Add a `:relief' property to the image spec if the item is
10286 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
10293 /* If image is selected, display it pressed, i.e. with a
10294 negative relief. If it's not selected, display it with a
10296 plist
= Fplist_put (plist
, QCrelief
,
10298 ? make_number (-relief
)
10299 : make_number (relief
)));
10304 /* Put a margin around the image. */
10305 if (hmargin
|| vmargin
)
10307 if (hmargin
== vmargin
)
10308 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
10310 plist
= Fplist_put (plist
, QCmargin
,
10311 Fcons (make_number (hmargin
),
10312 make_number (vmargin
)));
10315 /* If button is not enabled, and we don't have special images
10316 for the disabled state, make the image appear disabled by
10317 applying an appropriate algorithm to it. */
10318 if (!enabled_p
&& idx
< 0)
10319 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
10321 /* Put a `display' text property on the string for the image to
10322 display. Put a `menu-item' property on the string that gives
10323 the start of this item's properties in the tool-bar items
10325 image
= Fcons (Qimage
, plist
);
10326 props
= list4 (Qdisplay
, image
,
10327 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
10329 /* Let the last image hide all remaining spaces in the tool bar
10330 string. The string can be longer than needed when we reuse a
10331 previous string. */
10332 if (i
+ 1 == f
->n_tool_bar_items
)
10333 end
= SCHARS (f
->desired_tool_bar_string
);
10336 Fadd_text_properties (make_number (i
), make_number (end
),
10337 props
, f
->desired_tool_bar_string
);
10345 /* Display one line of the tool-bar of frame IT->f.
10347 HEIGHT specifies the desired height of the tool-bar line.
10348 If the actual height of the glyph row is less than HEIGHT, the
10349 row's height is increased to HEIGHT, and the icons are centered
10350 vertically in the new height.
10352 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10353 count a final empty row in case the tool-bar width exactly matches
10358 display_tool_bar_line (struct it
*it
, int height
)
10360 struct glyph_row
*row
= it
->glyph_row
;
10361 int max_x
= it
->last_visible_x
;
10362 struct glyph
*last
;
10364 prepare_desired_row (row
);
10365 row
->y
= it
->current_y
;
10367 /* Note that this isn't made use of if the face hasn't a box,
10368 so there's no need to check the face here. */
10369 it
->start_of_box_run_p
= 1;
10371 while (it
->current_x
< max_x
)
10373 int x
, n_glyphs_before
, i
, nglyphs
;
10374 struct it it_before
;
10376 /* Get the next display element. */
10377 if (!get_next_display_element (it
))
10379 /* Don't count empty row if we are counting needed tool-bar lines. */
10380 if (height
< 0 && !it
->hpos
)
10385 /* Produce glyphs. */
10386 n_glyphs_before
= row
->used
[TEXT_AREA
];
10389 PRODUCE_GLYPHS (it
);
10391 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
10393 x
= it_before
.current_x
;
10394 while (i
< nglyphs
)
10396 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
10398 if (x
+ glyph
->pixel_width
> max_x
)
10400 /* Glyph doesn't fit on line. Backtrack. */
10401 row
->used
[TEXT_AREA
] = n_glyphs_before
;
10403 /* If this is the only glyph on this line, it will never fit on the
10404 toolbar, so skip it. But ensure there is at least one glyph,
10405 so we don't accidentally disable the tool-bar. */
10406 if (n_glyphs_before
== 0
10407 && (it
->vpos
> 0 || IT_STRING_CHARPOS (*it
) < it
->end_charpos
-1))
10413 x
+= glyph
->pixel_width
;
10417 /* Stop at line ends. */
10418 if (ITERATOR_AT_END_OF_LINE_P (it
))
10421 set_iterator_to_next (it
, 1);
10426 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
10428 /* Use default face for the border below the tool bar.
10430 FIXME: When auto-resize-tool-bars is grow-only, there is
10431 no additional border below the possibly empty tool-bar lines.
10432 So to make the extra empty lines look "normal", we have to
10433 use the tool-bar face for the border too. */
10434 if (!row
->displays_text_p
&& !EQ (Vauto_resize_tool_bars
, Qgrow_only
))
10435 it
->face_id
= DEFAULT_FACE_ID
;
10437 extend_face_to_end_of_line (it
);
10438 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
10439 last
->right_box_line_p
= 1;
10440 if (last
== row
->glyphs
[TEXT_AREA
])
10441 last
->left_box_line_p
= 1;
10443 /* Make line the desired height and center it vertically. */
10444 if ((height
-= it
->max_ascent
+ it
->max_descent
) > 0)
10446 /* Don't add more than one line height. */
10447 height
%= FRAME_LINE_HEIGHT (it
->f
);
10448 it
->max_ascent
+= height
/ 2;
10449 it
->max_descent
+= (height
+ 1) / 2;
10452 compute_line_metrics (it
);
10454 /* If line is empty, make it occupy the rest of the tool-bar. */
10455 if (!row
->displays_text_p
)
10457 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
10458 row
->visible_height
= row
->height
;
10459 row
->ascent
= row
->phys_ascent
= 0;
10460 row
->extra_line_spacing
= 0;
10463 row
->full_width_p
= 1;
10464 row
->continued_p
= 0;
10465 row
->truncated_on_left_p
= 0;
10466 row
->truncated_on_right_p
= 0;
10468 it
->current_x
= it
->hpos
= 0;
10469 it
->current_y
+= row
->height
;
10475 /* Max tool-bar height. */
10477 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10478 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10480 /* Value is the number of screen lines needed to make all tool-bar
10481 items of frame F visible. The number of actual rows needed is
10482 returned in *N_ROWS if non-NULL. */
10485 tool_bar_lines_needed (struct frame
*f
, int *n_rows
)
10487 struct window
*w
= XWINDOW (f
->tool_bar_window
);
10489 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10490 the desired matrix, so use (unused) mode-line row as temporary row to
10491 avoid destroying the first tool-bar row. */
10492 struct glyph_row
*temp_row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
10494 /* Initialize an iterator for iteration over
10495 F->desired_tool_bar_string in the tool-bar window of frame F. */
10496 init_iterator (&it
, w
, -1, -1, temp_row
, TOOL_BAR_FACE_ID
);
10497 it
.first_visible_x
= 0;
10498 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
10499 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
10501 while (!ITERATOR_AT_END_P (&it
))
10503 clear_glyph_row (temp_row
);
10504 it
.glyph_row
= temp_row
;
10505 display_tool_bar_line (&it
, -1);
10507 clear_glyph_row (temp_row
);
10509 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10511 *n_rows
= it
.vpos
> 0 ? it
.vpos
: -1;
10513 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
10517 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
10519 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
10520 (Lisp_Object frame
)
10527 frame
= selected_frame
;
10529 CHECK_FRAME (frame
);
10530 f
= XFRAME (frame
);
10532 if (WINDOWP (f
->tool_bar_window
)
10533 || (w
= XWINDOW (f
->tool_bar_window
),
10534 WINDOW_TOTAL_LINES (w
) > 0))
10536 update_tool_bar (f
, 1);
10537 if (f
->n_tool_bar_items
)
10539 build_desired_tool_bar_string (f
);
10540 nlines
= tool_bar_lines_needed (f
, NULL
);
10544 return make_number (nlines
);
10548 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10549 height should be changed. */
10552 redisplay_tool_bar (struct frame
*f
)
10556 struct glyph_row
*row
;
10558 #if defined (USE_GTK) || defined (HAVE_NS)
10559 if (FRAME_EXTERNAL_TOOL_BAR (f
))
10560 update_frame_tool_bar (f
);
10564 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10565 do anything. This means you must start with tool-bar-lines
10566 non-zero to get the auto-sizing effect. Or in other words, you
10567 can turn off tool-bars by specifying tool-bar-lines zero. */
10568 if (!WINDOWP (f
->tool_bar_window
)
10569 || (w
= XWINDOW (f
->tool_bar_window
),
10570 WINDOW_TOTAL_LINES (w
) == 0))
10573 /* Set up an iterator for the tool-bar window. */
10574 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
10575 it
.first_visible_x
= 0;
10576 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
10577 row
= it
.glyph_row
;
10579 /* Build a string that represents the contents of the tool-bar. */
10580 build_desired_tool_bar_string (f
);
10581 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
10583 if (f
->n_tool_bar_rows
== 0)
10587 if ((nlines
= tool_bar_lines_needed (f
, &f
->n_tool_bar_rows
),
10588 nlines
!= WINDOW_TOTAL_LINES (w
)))
10590 extern Lisp_Object Qtool_bar_lines
;
10592 int old_height
= WINDOW_TOTAL_LINES (w
);
10594 XSETFRAME (frame
, f
);
10595 Fmodify_frame_parameters (frame
,
10596 Fcons (Fcons (Qtool_bar_lines
,
10597 make_number (nlines
)),
10599 if (WINDOW_TOTAL_LINES (w
) != old_height
)
10601 clear_glyph_matrix (w
->desired_matrix
);
10602 fonts_changed_p
= 1;
10608 /* Display as many lines as needed to display all tool-bar items. */
10610 if (f
->n_tool_bar_rows
> 0)
10612 int border
, rows
, height
, extra
;
10614 if (INTEGERP (Vtool_bar_border
))
10615 border
= XINT (Vtool_bar_border
);
10616 else if (EQ (Vtool_bar_border
, Qinternal_border_width
))
10617 border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
10618 else if (EQ (Vtool_bar_border
, Qborder_width
))
10619 border
= f
->border_width
;
10625 rows
= f
->n_tool_bar_rows
;
10626 height
= max (1, (it
.last_visible_y
- border
) / rows
);
10627 extra
= it
.last_visible_y
- border
- height
* rows
;
10629 while (it
.current_y
< it
.last_visible_y
)
10632 if (extra
> 0 && rows
-- > 0)
10634 h
= (extra
+ rows
- 1) / rows
;
10637 display_tool_bar_line (&it
, height
+ h
);
10642 while (it
.current_y
< it
.last_visible_y
)
10643 display_tool_bar_line (&it
, 0);
10646 /* It doesn't make much sense to try scrolling in the tool-bar
10647 window, so don't do it. */
10648 w
->desired_matrix
->no_scrolling_p
= 1;
10649 w
->must_be_updated_p
= 1;
10651 if (!NILP (Vauto_resize_tool_bars
))
10653 int max_tool_bar_height
= MAX_FRAME_TOOL_BAR_HEIGHT (f
);
10654 int change_height_p
= 0;
10656 /* If we couldn't display everything, change the tool-bar's
10657 height if there is room for more. */
10658 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
10659 && it
.current_y
< max_tool_bar_height
)
10660 change_height_p
= 1;
10662 row
= it
.glyph_row
- 1;
10664 /* If there are blank lines at the end, except for a partially
10665 visible blank line at the end that is smaller than
10666 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10667 if (!row
->displays_text_p
10668 && row
->height
>= FRAME_LINE_HEIGHT (f
))
10669 change_height_p
= 1;
10671 /* If row displays tool-bar items, but is partially visible,
10672 change the tool-bar's height. */
10673 if (row
->displays_text_p
10674 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
10675 && MATRIX_ROW_BOTTOM_Y (row
) < max_tool_bar_height
)
10676 change_height_p
= 1;
10678 /* Resize windows as needed by changing the `tool-bar-lines'
10679 frame parameter. */
10680 if (change_height_p
)
10682 extern Lisp_Object Qtool_bar_lines
;
10684 int old_height
= WINDOW_TOTAL_LINES (w
);
10686 int nlines
= tool_bar_lines_needed (f
, &nrows
);
10688 change_height_p
= ((EQ (Vauto_resize_tool_bars
, Qgrow_only
)
10689 && !f
->minimize_tool_bar_window_p
)
10690 ? (nlines
> old_height
)
10691 : (nlines
!= old_height
));
10692 f
->minimize_tool_bar_window_p
= 0;
10694 if (change_height_p
)
10696 XSETFRAME (frame
, f
);
10697 Fmodify_frame_parameters (frame
,
10698 Fcons (Fcons (Qtool_bar_lines
,
10699 make_number (nlines
)),
10701 if (WINDOW_TOTAL_LINES (w
) != old_height
)
10703 clear_glyph_matrix (w
->desired_matrix
);
10704 f
->n_tool_bar_rows
= nrows
;
10705 fonts_changed_p
= 1;
10712 f
->minimize_tool_bar_window_p
= 0;
10717 /* Get information about the tool-bar item which is displayed in GLYPH
10718 on frame F. Return in *PROP_IDX the index where tool-bar item
10719 properties start in F->tool_bar_items. Value is zero if
10720 GLYPH doesn't display a tool-bar item. */
10723 tool_bar_item_info (struct frame
*f
, struct glyph
*glyph
, int *prop_idx
)
10729 /* This function can be called asynchronously, which means we must
10730 exclude any possibility that Fget_text_property signals an
10732 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
10733 charpos
= max (0, charpos
);
10735 /* Get the text property `menu-item' at pos. The value of that
10736 property is the start index of this item's properties in
10737 F->tool_bar_items. */
10738 prop
= Fget_text_property (make_number (charpos
),
10739 Qmenu_item
, f
->current_tool_bar_string
);
10740 if (INTEGERP (prop
))
10742 *prop_idx
= XINT (prop
);
10752 /* Get information about the tool-bar item at position X/Y on frame F.
10753 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10754 the current matrix of the tool-bar window of F, or NULL if not
10755 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10756 item in F->tool_bar_items. Value is
10758 -1 if X/Y is not on a tool-bar item
10759 0 if X/Y is on the same item that was highlighted before.
10763 get_tool_bar_item (struct frame
*f
, int x
, int y
, struct glyph
**glyph
,
10764 int *hpos
, int *vpos
, int *prop_idx
)
10766 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10767 struct window
*w
= XWINDOW (f
->tool_bar_window
);
10770 /* Find the glyph under X/Y. */
10771 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
10772 if (*glyph
== NULL
)
10775 /* Get the start of this tool-bar item's properties in
10776 f->tool_bar_items. */
10777 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
10780 /* Is mouse on the highlighted item? */
10781 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
10782 && *vpos
>= dpyinfo
->mouse_face_beg_row
10783 && *vpos
<= dpyinfo
->mouse_face_end_row
10784 && (*vpos
> dpyinfo
->mouse_face_beg_row
10785 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
10786 && (*vpos
< dpyinfo
->mouse_face_end_row
10787 || *hpos
< dpyinfo
->mouse_face_end_col
10788 || dpyinfo
->mouse_face_past_end
))
10796 Handle mouse button event on the tool-bar of frame F, at
10797 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10798 0 for button release. MODIFIERS is event modifiers for button
10802 handle_tool_bar_click (struct frame
*f
, int x
, int y
, int down_p
,
10803 unsigned int modifiers
)
10805 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10806 struct window
*w
= XWINDOW (f
->tool_bar_window
);
10807 int hpos
, vpos
, prop_idx
;
10808 struct glyph
*glyph
;
10809 Lisp_Object enabled_p
;
10811 /* If not on the highlighted tool-bar item, return. */
10812 frame_to_window_pixel_xy (w
, &x
, &y
);
10813 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
10816 /* If item is disabled, do nothing. */
10817 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
10818 if (NILP (enabled_p
))
10823 /* Show item in pressed state. */
10824 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
10825 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
10826 last_tool_bar_item
= prop_idx
;
10830 Lisp_Object key
, frame
;
10831 struct input_event event
;
10832 EVENT_INIT (event
);
10834 /* Show item in released state. */
10835 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
10836 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
10838 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
10840 XSETFRAME (frame
, f
);
10841 event
.kind
= TOOL_BAR_EVENT
;
10842 event
.frame_or_window
= frame
;
10844 kbd_buffer_store_event (&event
);
10846 event
.kind
= TOOL_BAR_EVENT
;
10847 event
.frame_or_window
= frame
;
10849 event
.modifiers
= modifiers
;
10850 kbd_buffer_store_event (&event
);
10851 last_tool_bar_item
= -1;
10856 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10857 tool-bar window-relative coordinates X/Y. Called from
10858 note_mouse_highlight. */
10861 note_tool_bar_highlight (struct frame
*f
, int x
, int y
)
10863 Lisp_Object window
= f
->tool_bar_window
;
10864 struct window
*w
= XWINDOW (window
);
10865 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10867 struct glyph
*glyph
;
10868 struct glyph_row
*row
;
10870 Lisp_Object enabled_p
;
10872 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
10873 int mouse_down_p
, rc
;
10875 /* Function note_mouse_highlight is called with negative x(y
10876 values when mouse moves outside of the frame. */
10877 if (x
<= 0 || y
<= 0)
10879 clear_mouse_face (dpyinfo
);
10883 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
10886 /* Not on tool-bar item. */
10887 clear_mouse_face (dpyinfo
);
10891 /* On same tool-bar item as before. */
10892 goto set_help_echo
;
10894 clear_mouse_face (dpyinfo
);
10896 /* Mouse is down, but on different tool-bar item? */
10897 mouse_down_p
= (dpyinfo
->grabbed
10898 && f
== last_mouse_frame
10899 && FRAME_LIVE_P (f
));
10901 && last_tool_bar_item
!= prop_idx
)
10904 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
10905 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
10907 /* If tool-bar item is not enabled, don't highlight it. */
10908 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
10909 if (!NILP (enabled_p
))
10911 /* Compute the x-position of the glyph. In front and past the
10912 image is a space. We include this in the highlighted area. */
10913 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
10914 for (i
= x
= 0; i
< hpos
; ++i
)
10915 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
10917 /* Record this as the current active region. */
10918 dpyinfo
->mouse_face_beg_col
= hpos
;
10919 dpyinfo
->mouse_face_beg_row
= vpos
;
10920 dpyinfo
->mouse_face_beg_x
= x
;
10921 dpyinfo
->mouse_face_beg_y
= row
->y
;
10922 dpyinfo
->mouse_face_past_end
= 0;
10924 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
10925 dpyinfo
->mouse_face_end_row
= vpos
;
10926 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
10927 dpyinfo
->mouse_face_end_y
= row
->y
;
10928 dpyinfo
->mouse_face_window
= window
;
10929 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
10931 /* Display it as active. */
10932 show_mouse_face (dpyinfo
, draw
);
10933 dpyinfo
->mouse_face_image_state
= draw
;
10938 /* Set help_echo_string to a help string to display for this tool-bar item.
10939 XTread_socket does the rest. */
10940 help_echo_object
= help_echo_window
= Qnil
;
10941 help_echo_pos
= -1;
10942 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
10943 if (NILP (help_echo_string
))
10944 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
10947 #endif /* HAVE_WINDOW_SYSTEM */
10951 /************************************************************************
10952 Horizontal scrolling
10953 ************************************************************************/
10955 static int hscroll_window_tree (Lisp_Object
);
10956 static int hscroll_windows (Lisp_Object
);
10958 /* For all leaf windows in the window tree rooted at WINDOW, set their
10959 hscroll value so that PT is (i) visible in the window, and (ii) so
10960 that it is not within a certain margin at the window's left and
10961 right border. Value is non-zero if any window's hscroll has been
10965 hscroll_window_tree (Lisp_Object window
)
10967 int hscrolled_p
= 0;
10968 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
10969 int hscroll_step_abs
= 0;
10970 double hscroll_step_rel
= 0;
10972 if (hscroll_relative_p
)
10974 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
10975 if (hscroll_step_rel
< 0)
10977 hscroll_relative_p
= 0;
10978 hscroll_step_abs
= 0;
10981 else if (INTEGERP (Vhscroll_step
))
10983 hscroll_step_abs
= XINT (Vhscroll_step
);
10984 if (hscroll_step_abs
< 0)
10985 hscroll_step_abs
= 0;
10988 hscroll_step_abs
= 0;
10990 while (WINDOWP (window
))
10992 struct window
*w
= XWINDOW (window
);
10994 if (WINDOWP (w
->hchild
))
10995 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
10996 else if (WINDOWP (w
->vchild
))
10997 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
10998 else if (w
->cursor
.vpos
>= 0)
11001 int text_area_width
;
11002 struct glyph_row
*current_cursor_row
11003 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
11004 struct glyph_row
*desired_cursor_row
11005 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
11006 struct glyph_row
*cursor_row
11007 = (desired_cursor_row
->enabled_p
11008 ? desired_cursor_row
11009 : current_cursor_row
);
11011 text_area_width
= window_box_width (w
, TEXT_AREA
);
11013 /* Scroll when cursor is inside this scroll margin. */
11014 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
11016 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode
, w
->buffer
))
11017 && ((XFASTINT (w
->hscroll
)
11018 && w
->cursor
.x
<= h_margin
)
11019 || (cursor_row
->enabled_p
11020 && cursor_row
->truncated_on_right_p
11021 && (w
->cursor
.x
>= text_area_width
- h_margin
))))
11025 struct buffer
*saved_current_buffer
;
11029 /* Find point in a display of infinite width. */
11030 saved_current_buffer
= current_buffer
;
11031 current_buffer
= XBUFFER (w
->buffer
);
11033 if (w
== XWINDOW (selected_window
))
11034 pt
= BUF_PT (current_buffer
);
11037 pt
= marker_position (w
->pointm
);
11038 pt
= max (BEGV
, pt
);
11042 /* Move iterator to pt starting at cursor_row->start in
11043 a line with infinite width. */
11044 init_to_row_start (&it
, w
, cursor_row
);
11045 it
.last_visible_x
= INFINITY
;
11046 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
11047 current_buffer
= saved_current_buffer
;
11049 /* Position cursor in window. */
11050 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
11051 hscroll
= max (0, (it
.current_x
11052 - (ITERATOR_AT_END_OF_LINE_P (&it
)
11053 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
11054 : (text_area_width
/ 2))))
11055 / FRAME_COLUMN_WIDTH (it
.f
);
11056 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
11058 if (hscroll_relative_p
)
11059 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
11062 wanted_x
= text_area_width
11063 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
11066 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
11070 if (hscroll_relative_p
)
11071 wanted_x
= text_area_width
* hscroll_step_rel
11074 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
11077 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
11079 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
11081 /* Don't call Fset_window_hscroll if value hasn't
11082 changed because it will prevent redisplay
11084 if (XFASTINT (w
->hscroll
) != hscroll
)
11086 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
11087 w
->hscroll
= make_number (hscroll
);
11096 /* Value is non-zero if hscroll of any leaf window has been changed. */
11097 return hscrolled_p
;
11101 /* Set hscroll so that cursor is visible and not inside horizontal
11102 scroll margins for all windows in the tree rooted at WINDOW. See
11103 also hscroll_window_tree above. Value is non-zero if any window's
11104 hscroll has been changed. If it has, desired matrices on the frame
11105 of WINDOW are cleared. */
11108 hscroll_windows (Lisp_Object window
)
11110 int hscrolled_p
= hscroll_window_tree (window
);
11112 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
11113 return hscrolled_p
;
11118 /************************************************************************
11120 ************************************************************************/
11122 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11123 to a non-zero value. This is sometimes handy to have in a debugger
11128 /* First and last unchanged row for try_window_id. */
11130 int debug_first_unchanged_at_end_vpos
;
11131 int debug_last_unchanged_at_beg_vpos
;
11133 /* Delta vpos and y. */
11135 int debug_dvpos
, debug_dy
;
11137 /* Delta in characters and bytes for try_window_id. */
11139 int debug_delta
, debug_delta_bytes
;
11141 /* Values of window_end_pos and window_end_vpos at the end of
11144 EMACS_INT debug_end_pos
, debug_end_vpos
;
11146 /* Append a string to W->desired_matrix->method. FMT is a printf
11147 format string. A1...A9 are a supplement for a variable-length
11148 argument list. If trace_redisplay_p is non-zero also printf the
11149 resulting string to stderr. */
11152 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
11155 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
11158 char *method
= w
->desired_matrix
->method
;
11159 int len
= strlen (method
);
11160 int size
= sizeof w
->desired_matrix
->method
;
11161 int remaining
= size
- len
- 1;
11163 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
11164 if (len
&& remaining
)
11167 --remaining
, ++len
;
11170 strncpy (method
+ len
, buffer
, remaining
);
11172 if (trace_redisplay_p
)
11173 fprintf (stderr
, "%p (%s): %s\n",
11175 ((BUFFERP (w
->buffer
)
11176 && STRINGP (XBUFFER (w
->buffer
)->name
))
11177 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
11182 #endif /* GLYPH_DEBUG */
11185 /* Value is non-zero if all changes in window W, which displays
11186 current_buffer, are in the text between START and END. START is a
11187 buffer position, END is given as a distance from Z. Used in
11188 redisplay_internal for display optimization. */
11191 text_outside_line_unchanged_p (struct window
*w
, int start
, int end
)
11193 int unchanged_p
= 1;
11195 /* If text or overlays have changed, see where. */
11196 if (XFASTINT (w
->last_modified
) < MODIFF
11197 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
11199 /* Gap in the line? */
11200 if (GPT
< start
|| Z
- GPT
< end
)
11203 /* Changes start in front of the line, or end after it? */
11205 && (BEG_UNCHANGED
< start
- 1
11206 || END_UNCHANGED
< end
))
11209 /* If selective display, can't optimize if changes start at the
11210 beginning of the line. */
11212 && INTEGERP (current_buffer
->selective_display
)
11213 && XINT (current_buffer
->selective_display
) > 0
11214 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
11217 /* If there are overlays at the start or end of the line, these
11218 may have overlay strings with newlines in them. A change at
11219 START, for instance, may actually concern the display of such
11220 overlay strings as well, and they are displayed on different
11221 lines. So, quickly rule out this case. (For the future, it
11222 might be desirable to implement something more telling than
11223 just BEG/END_UNCHANGED.) */
11226 if (BEG
+ BEG_UNCHANGED
== start
11227 && overlay_touches_p (start
))
11229 if (END_UNCHANGED
== end
11230 && overlay_touches_p (Z
- end
))
11234 /* Under bidi reordering, adding or deleting a character in the
11235 beginning of a paragraph, before the first strong directional
11236 character, can change the base direction of the paragraph (unless
11237 the buffer specifies a fixed paragraph direction), which will
11238 require to redisplay the whole paragraph. It might be worthwhile
11239 to find the paragraph limits and widen the range of redisplayed
11240 lines to that, but for now just give up this optimization. */
11241 if (!NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
)
11242 && NILP (XBUFFER (w
->buffer
)->bidi_paragraph_direction
))
11246 return unchanged_p
;
11250 /* Do a frame update, taking possible shortcuts into account. This is
11251 the main external entry point for redisplay.
11253 If the last redisplay displayed an echo area message and that message
11254 is no longer requested, we clear the echo area or bring back the
11255 mini-buffer if that is in use. */
11260 redisplay_internal (0);
11265 overlay_arrow_string_or_property (Lisp_Object var
)
11269 if (val
= Fget (var
, Qoverlay_arrow_string
), STRINGP (val
))
11272 return Voverlay_arrow_string
;
11275 /* Return 1 if there are any overlay-arrows in current_buffer. */
11277 overlay_arrow_in_current_buffer_p (void)
11281 for (vlist
= Voverlay_arrow_variable_list
;
11283 vlist
= XCDR (vlist
))
11285 Lisp_Object var
= XCAR (vlist
);
11288 if (!SYMBOLP (var
))
11290 val
= find_symbol_value (var
);
11292 && current_buffer
== XMARKER (val
)->buffer
)
11299 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11303 overlay_arrows_changed_p (void)
11307 for (vlist
= Voverlay_arrow_variable_list
;
11309 vlist
= XCDR (vlist
))
11311 Lisp_Object var
= XCAR (vlist
);
11312 Lisp_Object val
, pstr
;
11314 if (!SYMBOLP (var
))
11316 val
= find_symbol_value (var
);
11317 if (!MARKERP (val
))
11319 if (! EQ (COERCE_MARKER (val
),
11320 Fget (var
, Qlast_arrow_position
))
11321 || ! (pstr
= overlay_arrow_string_or_property (var
),
11322 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
11328 /* Mark overlay arrows to be updated on next redisplay. */
11331 update_overlay_arrows (int up_to_date
)
11335 for (vlist
= Voverlay_arrow_variable_list
;
11337 vlist
= XCDR (vlist
))
11339 Lisp_Object var
= XCAR (vlist
);
11341 if (!SYMBOLP (var
))
11344 if (up_to_date
> 0)
11346 Lisp_Object val
= find_symbol_value (var
);
11347 Fput (var
, Qlast_arrow_position
,
11348 COERCE_MARKER (val
));
11349 Fput (var
, Qlast_arrow_string
,
11350 overlay_arrow_string_or_property (var
));
11352 else if (up_to_date
< 0
11353 || !NILP (Fget (var
, Qlast_arrow_position
)))
11355 Fput (var
, Qlast_arrow_position
, Qt
);
11356 Fput (var
, Qlast_arrow_string
, Qt
);
11362 /* Return overlay arrow string to display at row.
11363 Return integer (bitmap number) for arrow bitmap in left fringe.
11364 Return nil if no overlay arrow. */
11367 overlay_arrow_at_row (struct it
*it
, struct glyph_row
*row
)
11371 for (vlist
= Voverlay_arrow_variable_list
;
11373 vlist
= XCDR (vlist
))
11375 Lisp_Object var
= XCAR (vlist
);
11378 if (!SYMBOLP (var
))
11381 val
= find_symbol_value (var
);
11384 && current_buffer
== XMARKER (val
)->buffer
11385 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
11387 if (FRAME_WINDOW_P (it
->f
)
11388 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) > 0)
11390 #ifdef HAVE_WINDOW_SYSTEM
11391 if (val
= Fget (var
, Qoverlay_arrow_bitmap
), SYMBOLP (val
))
11394 if ((fringe_bitmap
= lookup_fringe_bitmap (val
)) != 0)
11395 return make_number (fringe_bitmap
);
11398 return make_number (-1); /* Use default arrow bitmap */
11400 return overlay_arrow_string_or_property (var
);
11407 /* Return 1 if point moved out of or into a composition. Otherwise
11408 return 0. PREV_BUF and PREV_PT are the last point buffer and
11409 position. BUF and PT are the current point buffer and position. */
11412 check_point_in_composition (struct buffer
*prev_buf
, int prev_pt
,
11413 struct buffer
*buf
, int pt
)
11415 EMACS_INT start
, end
;
11417 Lisp_Object buffer
;
11419 XSETBUFFER (buffer
, buf
);
11420 /* Check a composition at the last point if point moved within the
11422 if (prev_buf
== buf
)
11425 /* Point didn't move. */
11428 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
11429 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
11430 && COMPOSITION_VALID_P (start
, end
, prop
)
11431 && start
< prev_pt
&& end
> prev_pt
)
11432 /* The last point was within the composition. Return 1 iff
11433 point moved out of the composition. */
11434 return (pt
<= start
|| pt
>= end
);
11437 /* Check a composition at the current point. */
11438 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
11439 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
11440 && COMPOSITION_VALID_P (start
, end
, prop
)
11441 && start
< pt
&& end
> pt
);
11445 /* Reconsider the setting of B->clip_changed which is displayed
11449 reconsider_clip_changes (struct window
*w
, struct buffer
*b
)
11451 if (b
->clip_changed
11452 && !NILP (w
->window_end_valid
)
11453 && w
->current_matrix
->buffer
== b
11454 && w
->current_matrix
->zv
== BUF_ZV (b
)
11455 && w
->current_matrix
->begv
== BUF_BEGV (b
))
11456 b
->clip_changed
= 0;
11458 /* If display wasn't paused, and W is not a tool bar window, see if
11459 point has been moved into or out of a composition. In that case,
11460 we set b->clip_changed to 1 to force updating the screen. If
11461 b->clip_changed has already been set to 1, we can skip this
11463 if (!b
->clip_changed
11464 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
11468 if (w
== XWINDOW (selected_window
))
11469 pt
= BUF_PT (current_buffer
);
11471 pt
= marker_position (w
->pointm
);
11473 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
11474 || pt
!= XINT (w
->last_point
))
11475 && check_point_in_composition (w
->current_matrix
->buffer
,
11476 XINT (w
->last_point
),
11477 XBUFFER (w
->buffer
), pt
))
11478 b
->clip_changed
= 1;
11483 /* Select FRAME to forward the values of frame-local variables into C
11484 variables so that the redisplay routines can access those values
11488 select_frame_for_redisplay (Lisp_Object frame
)
11490 Lisp_Object tail
, tem
;
11491 Lisp_Object old
= selected_frame
;
11492 struct Lisp_Symbol
*sym
;
11494 xassert (FRAMEP (frame
) && FRAME_LIVE_P (XFRAME (frame
)));
11496 selected_frame
= frame
;
11499 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
11500 if (CONSP (XCAR (tail
))
11501 && (tem
= XCAR (XCAR (tail
)),
11503 && (sym
= indirect_variable (XSYMBOL (tem
)),
11504 sym
->redirect
== SYMBOL_LOCALIZED
)
11505 && sym
->val
.blv
->frame_local
)
11506 /* Use find_symbol_value rather than Fsymbol_value
11507 to avoid an error if it is void. */
11508 find_symbol_value (tem
);
11509 } while (!EQ (frame
, old
) && (frame
= old
, 1));
11513 #define STOP_POLLING \
11514 do { if (! polling_stopped_here) stop_polling (); \
11515 polling_stopped_here = 1; } while (0)
11517 #define RESUME_POLLING \
11518 do { if (polling_stopped_here) start_polling (); \
11519 polling_stopped_here = 0; } while (0)
11522 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11523 response to any user action; therefore, we should preserve the echo
11524 area. (Actually, our caller does that job.) Perhaps in the future
11525 avoid recentering windows if it is not necessary; currently that
11526 causes some problems. */
11529 redisplay_internal (int preserve_echo_area
)
11531 struct window
*w
= XWINDOW (selected_window
);
11534 int must_finish
= 0;
11535 struct text_pos tlbufpos
, tlendpos
;
11536 int number_of_visible_frames
;
11539 int polling_stopped_here
= 0;
11540 Lisp_Object old_frame
= selected_frame
;
11542 /* Non-zero means redisplay has to consider all windows on all
11543 frames. Zero means, only selected_window is considered. */
11544 int consider_all_windows_p
;
11546 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
11548 /* No redisplay if running in batch mode or frame is not yet fully
11549 initialized, or redisplay is explicitly turned off by setting
11550 Vinhibit_redisplay. */
11551 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11552 || !NILP (Vinhibit_redisplay
))
11555 /* Don't examine these until after testing Vinhibit_redisplay.
11556 When Emacs is shutting down, perhaps because its connection to
11557 X has dropped, we should not look at them at all. */
11558 f
= XFRAME (w
->frame
);
11559 sf
= SELECTED_FRAME ();
11561 if (!f
->glyphs_initialized_p
)
11564 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11565 if (popup_activated ())
11569 /* I don't think this happens but let's be paranoid. */
11570 if (redisplaying_p
)
11573 /* Record a function that resets redisplaying_p to its old value
11574 when we leave this function. */
11575 count
= SPECPDL_INDEX ();
11576 record_unwind_protect (unwind_redisplay
,
11577 Fcons (make_number (redisplaying_p
), selected_frame
));
11579 specbind (Qinhibit_free_realized_faces
, Qnil
);
11582 Lisp_Object tail
, frame
;
11584 FOR_EACH_FRAME (tail
, frame
)
11586 struct frame
*f
= XFRAME (frame
);
11587 f
->already_hscrolled_p
= 0;
11592 if (!EQ (old_frame
, selected_frame
)
11593 && FRAME_LIVE_P (XFRAME (old_frame
)))
11594 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11595 selected_frame and selected_window to be temporarily out-of-sync so
11596 when we come back here via `goto retry', we need to resync because we
11597 may need to run Elisp code (via prepare_menu_bars). */
11598 select_frame_for_redisplay (old_frame
);
11601 reconsider_clip_changes (w
, current_buffer
);
11602 last_escape_glyph_frame
= NULL
;
11603 last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
11605 /* If new fonts have been loaded that make a glyph matrix adjustment
11606 necessary, do it. */
11607 if (fonts_changed_p
)
11609 adjust_glyphs (NULL
);
11610 ++windows_or_buffers_changed
;
11611 fonts_changed_p
= 0;
11614 /* If face_change_count is non-zero, init_iterator will free all
11615 realized faces, which includes the faces referenced from current
11616 matrices. So, we can't reuse current matrices in this case. */
11617 if (face_change_count
)
11618 ++windows_or_buffers_changed
;
11620 if ((FRAME_TERMCAP_P (sf
) || FRAME_MSDOS_P (sf
))
11621 && FRAME_TTY (sf
)->previous_frame
!= sf
)
11623 /* Since frames on a single ASCII terminal share the same
11624 display area, displaying a different frame means redisplay
11625 the whole thing. */
11626 windows_or_buffers_changed
++;
11627 SET_FRAME_GARBAGED (sf
);
11629 set_tty_color_mode (FRAME_TTY (sf
), sf
);
11631 FRAME_TTY (sf
)->previous_frame
= sf
;
11634 /* Set the visible flags for all frames. Do this before checking
11635 for resized or garbaged frames; they want to know if their frames
11636 are visible. See the comment in frame.h for
11637 FRAME_SAMPLE_VISIBILITY. */
11639 Lisp_Object tail
, frame
;
11641 number_of_visible_frames
= 0;
11643 FOR_EACH_FRAME (tail
, frame
)
11645 struct frame
*f
= XFRAME (frame
);
11647 FRAME_SAMPLE_VISIBILITY (f
);
11648 if (FRAME_VISIBLE_P (f
))
11649 ++number_of_visible_frames
;
11650 clear_desired_matrices (f
);
11654 /* Notice any pending interrupt request to change frame size. */
11655 do_pending_window_change (1);
11657 /* Clear frames marked as garbaged. */
11658 if (frame_garbaged
)
11659 clear_garbaged_frames ();
11661 /* Build menubar and tool-bar items. */
11662 if (NILP (Vmemory_full
))
11663 prepare_menu_bars ();
11665 if (windows_or_buffers_changed
)
11666 update_mode_lines
++;
11668 /* Detect case that we need to write or remove a star in the mode line. */
11669 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
11671 w
->update_mode_line
= Qt
;
11672 if (buffer_shared
> 1)
11673 update_mode_lines
++;
11676 /* Avoid invocation of point motion hooks by `current_column' below. */
11677 count1
= SPECPDL_INDEX ();
11678 specbind (Qinhibit_point_motion_hooks
, Qt
);
11680 /* If %c is in the mode line, update it if needed. */
11681 if (!NILP (w
->column_number_displayed
)
11682 /* This alternative quickly identifies a common case
11683 where no change is needed. */
11684 && !(PT
== XFASTINT (w
->last_point
)
11685 && XFASTINT (w
->last_modified
) >= MODIFF
11686 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
11687 && (XFASTINT (w
->column_number_displayed
)
11688 != (int) current_column ())) /* iftc */
11689 w
->update_mode_line
= Qt
;
11691 unbind_to (count1
, Qnil
);
11693 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
11695 /* The variable buffer_shared is set in redisplay_window and
11696 indicates that we redisplay a buffer in different windows. See
11698 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
11699 || cursor_type_changed
);
11701 /* If specs for an arrow have changed, do thorough redisplay
11702 to ensure we remove any arrow that should no longer exist. */
11703 if (overlay_arrows_changed_p ())
11704 consider_all_windows_p
= windows_or_buffers_changed
= 1;
11706 /* Normally the message* functions will have already displayed and
11707 updated the echo area, but the frame may have been trashed, or
11708 the update may have been preempted, so display the echo area
11709 again here. Checking message_cleared_p captures the case that
11710 the echo area should be cleared. */
11711 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
11712 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
11713 || (message_cleared_p
11714 && minibuf_level
== 0
11715 /* If the mini-window is currently selected, this means the
11716 echo-area doesn't show through. */
11717 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
11719 int window_height_changed_p
= echo_area_display (0);
11722 /* If we don't display the current message, don't clear the
11723 message_cleared_p flag, because, if we did, we wouldn't clear
11724 the echo area in the next redisplay which doesn't preserve
11726 if (!display_last_displayed_message_p
)
11727 message_cleared_p
= 0;
11729 if (fonts_changed_p
)
11731 else if (window_height_changed_p
)
11733 consider_all_windows_p
= 1;
11734 ++update_mode_lines
;
11735 ++windows_or_buffers_changed
;
11737 /* If window configuration was changed, frames may have been
11738 marked garbaged. Clear them or we will experience
11739 surprises wrt scrolling. */
11740 if (frame_garbaged
)
11741 clear_garbaged_frames ();
11744 else if (EQ (selected_window
, minibuf_window
)
11745 && (current_buffer
->clip_changed
11746 || XFASTINT (w
->last_modified
) < MODIFF
11747 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
11748 && resize_mini_window (w
, 0))
11750 /* Resized active mini-window to fit the size of what it is
11751 showing if its contents might have changed. */
11753 /* FIXME: this causes all frames to be updated, which seems unnecessary
11754 since only the current frame needs to be considered. This function needs
11755 to be rewritten with two variables, consider_all_windows and
11756 consider_all_frames. */
11757 consider_all_windows_p
= 1;
11758 ++windows_or_buffers_changed
;
11759 ++update_mode_lines
;
11761 /* If window configuration was changed, frames may have been
11762 marked garbaged. Clear them or we will experience
11763 surprises wrt scrolling. */
11764 if (frame_garbaged
)
11765 clear_garbaged_frames ();
11769 /* If showing the region, and mark has changed, we must redisplay
11770 the whole window. The assignment to this_line_start_pos prevents
11771 the optimization directly below this if-statement. */
11772 if (((!NILP (Vtransient_mark_mode
)
11773 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
11774 != !NILP (w
->region_showing
))
11775 || (!NILP (w
->region_showing
)
11776 && !EQ (w
->region_showing
,
11777 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
11778 CHARPOS (this_line_start_pos
) = 0;
11780 /* Optimize the case that only the line containing the cursor in the
11781 selected window has changed. Variables starting with this_ are
11782 set in display_line and record information about the line
11783 containing the cursor. */
11784 tlbufpos
= this_line_start_pos
;
11785 tlendpos
= this_line_end_pos
;
11786 if (!consider_all_windows_p
11787 && CHARPOS (tlbufpos
) > 0
11788 && NILP (w
->update_mode_line
)
11789 && !current_buffer
->clip_changed
11790 && !current_buffer
->prevent_redisplay_optimizations_p
11791 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
11792 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
11793 /* Make sure recorded data applies to current buffer, etc. */
11794 && this_line_buffer
== current_buffer
11795 && current_buffer
== XBUFFER (w
->buffer
)
11796 && NILP (w
->force_start
)
11797 && NILP (w
->optional_new_start
)
11798 /* Point must be on the line that we have info recorded about. */
11799 && PT
>= CHARPOS (tlbufpos
)
11800 && PT
<= Z
- CHARPOS (tlendpos
)
11801 /* All text outside that line, including its final newline,
11802 must be unchanged. */
11803 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
11804 CHARPOS (tlendpos
)))
11806 if (CHARPOS (tlbufpos
) > BEGV
11807 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
11808 && (CHARPOS (tlbufpos
) == ZV
11809 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
11810 /* Former continuation line has disappeared by becoming empty. */
11812 else if (XFASTINT (w
->last_modified
) < MODIFF
11813 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
11814 || MINI_WINDOW_P (w
))
11816 /* We have to handle the case of continuation around a
11817 wide-column character (see the comment in indent.c around
11820 For instance, in the following case:
11822 -------- Insert --------
11823 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11824 J_I_ ==> J_I_ `^^' are cursors.
11828 As we have to redraw the line above, we cannot use this
11832 int line_height_before
= this_line_pixel_height
;
11834 /* Note that start_display will handle the case that the
11835 line starting at tlbufpos is a continuation line. */
11836 start_display (&it
, w
, tlbufpos
);
11838 /* Implementation note: It this still necessary? */
11839 if (it
.current_x
!= this_line_start_x
)
11842 TRACE ((stderr
, "trying display optimization 1\n"));
11843 w
->cursor
.vpos
= -1;
11844 overlay_arrow_seen
= 0;
11845 it
.vpos
= this_line_vpos
;
11846 it
.current_y
= this_line_y
;
11847 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
11848 display_line (&it
);
11850 /* If line contains point, is not continued,
11851 and ends at same distance from eob as before, we win. */
11852 if (w
->cursor
.vpos
>= 0
11853 /* Line is not continued, otherwise this_line_start_pos
11854 would have been set to 0 in display_line. */
11855 && CHARPOS (this_line_start_pos
)
11856 /* Line ends as before. */
11857 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
11858 /* Line has same height as before. Otherwise other lines
11859 would have to be shifted up or down. */
11860 && this_line_pixel_height
== line_height_before
)
11862 /* If this is not the window's last line, we must adjust
11863 the charstarts of the lines below. */
11864 if (it
.current_y
< it
.last_visible_y
)
11866 struct glyph_row
*row
11867 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
11868 int delta
, delta_bytes
;
11870 /* We used to distinguish between two cases here,
11871 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11872 when the line ends in a newline or the end of the
11873 buffer's accessible portion. But both cases did
11874 the same, so they were collapsed. */
11876 - CHARPOS (tlendpos
)
11877 - MATRIX_ROW_START_CHARPOS (row
));
11878 delta_bytes
= (Z_BYTE
11879 - BYTEPOS (tlendpos
)
11880 - MATRIX_ROW_START_BYTEPOS (row
));
11882 increment_matrix_positions (w
->current_matrix
,
11883 this_line_vpos
+ 1,
11884 w
->current_matrix
->nrows
,
11885 delta
, delta_bytes
);
11888 /* If this row displays text now but previously didn't,
11889 or vice versa, w->window_end_vpos may have to be
11891 if ((it
.glyph_row
- 1)->displays_text_p
)
11893 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
11894 XSETINT (w
->window_end_vpos
, this_line_vpos
);
11896 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
11897 && this_line_vpos
> 0)
11898 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
11899 w
->window_end_valid
= Qnil
;
11901 /* Update hint: No need to try to scroll in update_window. */
11902 w
->desired_matrix
->no_scrolling_p
= 1;
11905 *w
->desired_matrix
->method
= 0;
11906 debug_method_add (w
, "optimization 1");
11908 #ifdef HAVE_WINDOW_SYSTEM
11909 update_window_fringes (w
, 0);
11916 else if (/* Cursor position hasn't changed. */
11917 PT
== XFASTINT (w
->last_point
)
11918 /* Make sure the cursor was last displayed
11919 in this window. Otherwise we have to reposition it. */
11920 && 0 <= w
->cursor
.vpos
11921 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
11925 do_pending_window_change (1);
11927 /* We used to always goto end_of_redisplay here, but this
11928 isn't enough if we have a blinking cursor. */
11929 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
11930 goto end_of_redisplay
;
11934 /* If highlighting the region, or if the cursor is in the echo area,
11935 then we can't just move the cursor. */
11936 else if (! (!NILP (Vtransient_mark_mode
)
11937 && !NILP (current_buffer
->mark_active
))
11938 && (EQ (selected_window
, current_buffer
->last_selected_window
)
11939 || highlight_nonselected_windows
)
11940 && NILP (w
->region_showing
)
11941 && NILP (Vshow_trailing_whitespace
)
11942 && !cursor_in_echo_area
)
11945 struct glyph_row
*row
;
11947 /* Skip from tlbufpos to PT and see where it is. Note that
11948 PT may be in invisible text. If so, we will end at the
11949 next visible position. */
11950 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
11951 NULL
, DEFAULT_FACE_ID
);
11952 it
.current_x
= this_line_start_x
;
11953 it
.current_y
= this_line_y
;
11954 it
.vpos
= this_line_vpos
;
11956 /* The call to move_it_to stops in front of PT, but
11957 moves over before-strings. */
11958 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
11960 if (it
.vpos
== this_line_vpos
11961 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
11964 xassert (this_line_vpos
== it
.vpos
);
11965 xassert (this_line_y
== it
.current_y
);
11966 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11968 *w
->desired_matrix
->method
= 0;
11969 debug_method_add (w
, "optimization 3");
11978 /* Text changed drastically or point moved off of line. */
11979 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
11982 CHARPOS (this_line_start_pos
) = 0;
11983 consider_all_windows_p
|= buffer_shared
> 1;
11984 ++clear_face_cache_count
;
11985 #ifdef HAVE_WINDOW_SYSTEM
11986 ++clear_image_cache_count
;
11989 /* Build desired matrices, and update the display. If
11990 consider_all_windows_p is non-zero, do it for all windows on all
11991 frames. Otherwise do it for selected_window, only. */
11993 if (consider_all_windows_p
)
11995 Lisp_Object tail
, frame
;
11997 FOR_EACH_FRAME (tail
, frame
)
11998 XFRAME (frame
)->updated_p
= 0;
12000 /* Recompute # windows showing selected buffer. This will be
12001 incremented each time such a window is displayed. */
12004 FOR_EACH_FRAME (tail
, frame
)
12006 struct frame
*f
= XFRAME (frame
);
12008 if (FRAME_WINDOW_P (f
) || FRAME_TERMCAP_P (f
) || f
== sf
)
12010 if (! EQ (frame
, selected_frame
))
12011 /* Select the frame, for the sake of frame-local
12013 select_frame_for_redisplay (frame
);
12015 /* Mark all the scroll bars to be removed; we'll redeem
12016 the ones we want when we redisplay their windows. */
12017 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
12018 FRAME_TERMINAL (f
)->condemn_scroll_bars_hook (f
);
12020 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
12021 redisplay_windows (FRAME_ROOT_WINDOW (f
));
12023 /* The X error handler may have deleted that frame. */
12024 if (!FRAME_LIVE_P (f
))
12027 /* Any scroll bars which redisplay_windows should have
12028 nuked should now go away. */
12029 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
12030 FRAME_TERMINAL (f
)->judge_scroll_bars_hook (f
);
12032 /* If fonts changed, display again. */
12033 /* ??? rms: I suspect it is a mistake to jump all the way
12034 back to retry here. It should just retry this frame. */
12035 if (fonts_changed_p
)
12038 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
12040 /* See if we have to hscroll. */
12041 if (!f
->already_hscrolled_p
)
12043 f
->already_hscrolled_p
= 1;
12044 if (hscroll_windows (f
->root_window
))
12048 /* Prevent various kinds of signals during display
12049 update. stdio is not robust about handling
12050 signals, which can cause an apparent I/O
12052 if (interrupt_input
)
12053 unrequest_sigio ();
12056 /* Update the display. */
12057 set_window_update_flags (XWINDOW (f
->root_window
), 1);
12058 pause
|= update_frame (f
, 0, 0);
12064 if (!EQ (old_frame
, selected_frame
)
12065 && FRAME_LIVE_P (XFRAME (old_frame
)))
12066 /* We played a bit fast-and-loose above and allowed selected_frame
12067 and selected_window to be temporarily out-of-sync but let's make
12068 sure this stays contained. */
12069 select_frame_for_redisplay (old_frame
);
12070 eassert (EQ (XFRAME (selected_frame
)->selected_window
, selected_window
));
12074 /* Do the mark_window_display_accurate after all windows have
12075 been redisplayed because this call resets flags in buffers
12076 which are needed for proper redisplay. */
12077 FOR_EACH_FRAME (tail
, frame
)
12079 struct frame
*f
= XFRAME (frame
);
12082 mark_window_display_accurate (f
->root_window
, 1);
12083 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
12084 FRAME_TERMINAL (f
)->frame_up_to_date_hook (f
);
12089 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
12091 Lisp_Object mini_window
;
12092 struct frame
*mini_frame
;
12094 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
12095 /* Use list_of_error, not Qerror, so that
12096 we catch only errors and don't run the debugger. */
12097 internal_condition_case_1 (redisplay_window_1
, selected_window
,
12099 redisplay_window_error
);
12101 /* Compare desired and current matrices, perform output. */
12104 /* If fonts changed, display again. */
12105 if (fonts_changed_p
)
12108 /* Prevent various kinds of signals during display update.
12109 stdio is not robust about handling signals,
12110 which can cause an apparent I/O error. */
12111 if (interrupt_input
)
12112 unrequest_sigio ();
12115 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
12117 if (hscroll_windows (selected_window
))
12120 XWINDOW (selected_window
)->must_be_updated_p
= 1;
12121 pause
= update_frame (sf
, 0, 0);
12124 /* We may have called echo_area_display at the top of this
12125 function. If the echo area is on another frame, that may
12126 have put text on a frame other than the selected one, so the
12127 above call to update_frame would not have caught it. Catch
12129 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
12130 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
12132 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
12134 XWINDOW (mini_window
)->must_be_updated_p
= 1;
12135 pause
|= update_frame (mini_frame
, 0, 0);
12136 if (!pause
&& hscroll_windows (mini_window
))
12141 /* If display was paused because of pending input, make sure we do a
12142 thorough update the next time. */
12145 /* Prevent the optimization at the beginning of
12146 redisplay_internal that tries a single-line update of the
12147 line containing the cursor in the selected window. */
12148 CHARPOS (this_line_start_pos
) = 0;
12150 /* Let the overlay arrow be updated the next time. */
12151 update_overlay_arrows (0);
12153 /* If we pause after scrolling, some rows in the current
12154 matrices of some windows are not valid. */
12155 if (!WINDOW_FULL_WIDTH_P (w
)
12156 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
12157 update_mode_lines
= 1;
12161 if (!consider_all_windows_p
)
12163 /* This has already been done above if
12164 consider_all_windows_p is set. */
12165 mark_window_display_accurate_1 (w
, 1);
12167 /* Say overlay arrows are up to date. */
12168 update_overlay_arrows (1);
12170 if (FRAME_TERMINAL (sf
)->frame_up_to_date_hook
!= 0)
12171 FRAME_TERMINAL (sf
)->frame_up_to_date_hook (sf
);
12174 update_mode_lines
= 0;
12175 windows_or_buffers_changed
= 0;
12176 cursor_type_changed
= 0;
12179 /* Start SIGIO interrupts coming again. Having them off during the
12180 code above makes it less likely one will discard output, but not
12181 impossible, since there might be stuff in the system buffer here.
12182 But it is much hairier to try to do anything about that. */
12183 if (interrupt_input
)
12187 /* If a frame has become visible which was not before, redisplay
12188 again, so that we display it. Expose events for such a frame
12189 (which it gets when becoming visible) don't call the parts of
12190 redisplay constructing glyphs, so simply exposing a frame won't
12191 display anything in this case. So, we have to display these
12192 frames here explicitly. */
12195 Lisp_Object tail
, frame
;
12198 FOR_EACH_FRAME (tail
, frame
)
12200 int this_is_visible
= 0;
12202 if (XFRAME (frame
)->visible
)
12203 this_is_visible
= 1;
12204 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
12205 if (XFRAME (frame
)->visible
)
12206 this_is_visible
= 1;
12208 if (this_is_visible
)
12212 if (new_count
!= number_of_visible_frames
)
12213 windows_or_buffers_changed
++;
12216 /* Change frame size now if a change is pending. */
12217 do_pending_window_change (1);
12219 /* If we just did a pending size change, or have additional
12220 visible frames, redisplay again. */
12221 if (windows_or_buffers_changed
&& !pause
)
12224 /* Clear the face and image caches.
12226 We used to do this only if consider_all_windows_p. But the cache
12227 needs to be cleared if a timer creates images in the current
12228 buffer (e.g. the test case in Bug#6230). */
12230 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
12232 clear_face_cache (0);
12233 clear_face_cache_count
= 0;
12236 #ifdef HAVE_WINDOW_SYSTEM
12237 if (clear_image_cache_count
> CLEAR_IMAGE_CACHE_COUNT
)
12239 clear_image_caches (Qnil
);
12240 clear_image_cache_count
= 0;
12242 #endif /* HAVE_WINDOW_SYSTEM */
12245 unbind_to (count
, Qnil
);
12250 /* Redisplay, but leave alone any recent echo area message unless
12251 another message has been requested in its place.
12253 This is useful in situations where you need to redisplay but no
12254 user action has occurred, making it inappropriate for the message
12255 area to be cleared. See tracking_off and
12256 wait_reading_process_output for examples of these situations.
12258 FROM_WHERE is an integer saying from where this function was
12259 called. This is useful for debugging. */
12262 redisplay_preserve_echo_area (int from_where
)
12264 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
12266 if (!NILP (echo_area_buffer
[1]))
12268 /* We have a previously displayed message, but no current
12269 message. Redisplay the previous message. */
12270 display_last_displayed_message_p
= 1;
12271 redisplay_internal (1);
12272 display_last_displayed_message_p
= 0;
12275 redisplay_internal (1);
12277 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12278 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional
)
12279 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL
);
12283 /* Function registered with record_unwind_protect in
12284 redisplay_internal. Reset redisplaying_p to the value it had
12285 before redisplay_internal was called, and clear
12286 prevent_freeing_realized_faces_p. It also selects the previously
12287 selected frame, unless it has been deleted (by an X connection
12288 failure during redisplay, for example). */
12291 unwind_redisplay (Lisp_Object val
)
12293 Lisp_Object old_redisplaying_p
, old_frame
;
12295 old_redisplaying_p
= XCAR (val
);
12296 redisplaying_p
= XFASTINT (old_redisplaying_p
);
12297 old_frame
= XCDR (val
);
12298 if (! EQ (old_frame
, selected_frame
)
12299 && FRAME_LIVE_P (XFRAME (old_frame
)))
12300 select_frame_for_redisplay (old_frame
);
12305 /* Mark the display of window W as accurate or inaccurate. If
12306 ACCURATE_P is non-zero mark display of W as accurate. If
12307 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12308 redisplay_internal is called. */
12311 mark_window_display_accurate_1 (struct window
*w
, int accurate_p
)
12313 if (BUFFERP (w
->buffer
))
12315 struct buffer
*b
= XBUFFER (w
->buffer
);
12318 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
12319 w
->last_overlay_modified
12320 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
12322 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
12326 b
->clip_changed
= 0;
12327 b
->prevent_redisplay_optimizations_p
= 0;
12329 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
12330 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
12331 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
12332 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
12334 w
->current_matrix
->buffer
= b
;
12335 w
->current_matrix
->begv
= BUF_BEGV (b
);
12336 w
->current_matrix
->zv
= BUF_ZV (b
);
12338 w
->last_cursor
= w
->cursor
;
12339 w
->last_cursor_off_p
= w
->cursor_off_p
;
12341 if (w
== XWINDOW (selected_window
))
12342 w
->last_point
= make_number (BUF_PT (b
));
12344 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
12350 w
->window_end_valid
= w
->buffer
;
12351 w
->update_mode_line
= Qnil
;
12356 /* Mark the display of windows in the window tree rooted at WINDOW as
12357 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12358 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12359 be redisplayed the next time redisplay_internal is called. */
12362 mark_window_display_accurate (Lisp_Object window
, int accurate_p
)
12366 for (; !NILP (window
); window
= w
->next
)
12368 w
= XWINDOW (window
);
12369 mark_window_display_accurate_1 (w
, accurate_p
);
12371 if (!NILP (w
->vchild
))
12372 mark_window_display_accurate (w
->vchild
, accurate_p
);
12373 if (!NILP (w
->hchild
))
12374 mark_window_display_accurate (w
->hchild
, accurate_p
);
12379 update_overlay_arrows (1);
12383 /* Force a thorough redisplay the next time by setting
12384 last_arrow_position and last_arrow_string to t, which is
12385 unequal to any useful value of Voverlay_arrow_... */
12386 update_overlay_arrows (-1);
12391 /* Return value in display table DP (Lisp_Char_Table *) for character
12392 C. Since a display table doesn't have any parent, we don't have to
12393 follow parent. Do not call this function directly but use the
12394 macro DISP_CHAR_VECTOR. */
12397 disp_char_vector (struct Lisp_Char_Table
*dp
, int c
)
12401 if (ASCII_CHAR_P (c
))
12404 if (SUB_CHAR_TABLE_P (val
))
12405 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
12411 XSETCHAR_TABLE (table
, dp
);
12412 val
= char_table_ref (table
, c
);
12421 /***********************************************************************
12423 ***********************************************************************/
12425 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12428 redisplay_windows (Lisp_Object window
)
12430 while (!NILP (window
))
12432 struct window
*w
= XWINDOW (window
);
12434 if (!NILP (w
->hchild
))
12435 redisplay_windows (w
->hchild
);
12436 else if (!NILP (w
->vchild
))
12437 redisplay_windows (w
->vchild
);
12438 else if (!NILP (w
->buffer
))
12440 displayed_buffer
= XBUFFER (w
->buffer
);
12441 /* Use list_of_error, not Qerror, so that
12442 we catch only errors and don't run the debugger. */
12443 internal_condition_case_1 (redisplay_window_0
, window
,
12445 redisplay_window_error
);
12453 redisplay_window_error (Lisp_Object ignore
)
12455 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
12460 redisplay_window_0 (Lisp_Object window
)
12462 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
12463 redisplay_window (window
, 0);
12468 redisplay_window_1 (Lisp_Object window
)
12470 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
12471 redisplay_window (window
, 1);
12476 /* Increment GLYPH until it reaches END or CONDITION fails while
12477 adding (GLYPH)->pixel_width to X. */
12479 #define SKIP_GLYPHS(glyph, end, x, condition) \
12482 (x) += (glyph)->pixel_width; \
12485 while ((glyph) < (end) && (condition))
12488 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12489 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12490 which positions recorded in ROW differ from current buffer
12493 Return 0 if cursor is not on this row, 1 otherwise. */
12496 set_cursor_from_row (struct window
*w
, struct glyph_row
*row
,
12497 struct glyph_matrix
*matrix
, int delta
, int delta_bytes
,
12500 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
12501 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
12502 struct glyph
*cursor
= NULL
;
12503 /* The last known character position in row. */
12504 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
12506 EMACS_INT pt_old
= PT
- delta
;
12507 EMACS_INT pos_before
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
12508 EMACS_INT pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
12509 struct glyph
*glyph_before
= glyph
- 1, *glyph_after
= end
;
12510 /* A glyph beyond the edge of TEXT_AREA which we should never
12512 struct glyph
*glyphs_end
= end
;
12513 /* Non-zero means we've found a match for cursor position, but that
12514 glyph has the avoid_cursor_p flag set. */
12515 int match_with_avoid_cursor
= 0;
12516 /* Non-zero means we've seen at least one glyph that came from a
12518 int string_seen
= 0;
12519 /* Largest buffer position seen so far during scan of glyph row. */
12520 EMACS_INT bpos_max
= last_pos
;
12521 /* Last buffer position covered by an overlay string with an integer
12522 `cursor' property. */
12523 EMACS_INT bpos_covered
= 0;
12525 /* Skip over glyphs not having an object at the start and the end of
12526 the row. These are special glyphs like truncation marks on
12527 terminal frames. */
12528 if (row
->displays_text_p
)
12530 if (!row
->reversed_p
)
12533 && INTEGERP (glyph
->object
)
12534 && glyph
->charpos
< 0)
12536 x
+= glyph
->pixel_width
;
12540 && INTEGERP ((end
- 1)->object
)
12541 /* CHARPOS is zero for blanks and stretch glyphs
12542 inserted by extend_face_to_end_of_line. */
12543 && (end
- 1)->charpos
<= 0)
12545 glyph_before
= glyph
- 1;
12552 /* If the glyph row is reversed, we need to process it from back
12553 to front, so swap the edge pointers. */
12554 glyphs_end
= end
= glyph
- 1;
12555 glyph
+= row
->used
[TEXT_AREA
] - 1;
12557 while (glyph
> end
+ 1
12558 && INTEGERP (glyph
->object
)
12559 && glyph
->charpos
< 0)
12562 x
-= glyph
->pixel_width
;
12564 if (INTEGERP (glyph
->object
) && glyph
->charpos
< 0)
12566 /* By default, in reversed rows we put the cursor on the
12567 rightmost (first in the reading order) glyph. */
12568 for (g
= end
+ 1; g
< glyph
; g
++)
12569 x
+= g
->pixel_width
;
12571 && INTEGERP ((end
+ 1)->object
)
12572 && (end
+ 1)->charpos
<= 0)
12574 glyph_before
= glyph
+ 1;
12578 else if (row
->reversed_p
)
12580 /* In R2L rows that don't display text, put the cursor on the
12581 rightmost glyph. Case in point: an empty last line that is
12582 part of an R2L paragraph. */
12584 /* Avoid placing the cursor on the last glyph of the row, where
12585 on terminal frames we hold the vertical border between
12586 adjacent windows. */
12587 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w
))
12588 && !WINDOW_RIGHTMOST_P (w
)
12589 && cursor
== row
->glyphs
[LAST_AREA
] - 1)
12591 x
= -1; /* will be computed below, at label compute_x */
12594 /* Step 1: Try to find the glyph whose character position
12595 corresponds to point. If that's not possible, find 2 glyphs
12596 whose character positions are the closest to point, one before
12597 point, the other after it. */
12598 if (!row
->reversed_p
)
12599 while (/* not marched to end of glyph row */
12601 /* glyph was not inserted by redisplay for internal purposes */
12602 && !INTEGERP (glyph
->object
))
12604 if (BUFFERP (glyph
->object
))
12606 EMACS_INT dpos
= glyph
->charpos
- pt_old
;
12608 if (glyph
->charpos
> bpos_max
)
12609 bpos_max
= glyph
->charpos
;
12610 if (!glyph
->avoid_cursor_p
)
12612 /* If we hit point, we've found the glyph on which to
12613 display the cursor. */
12616 match_with_avoid_cursor
= 0;
12619 /* See if we've found a better approximation to
12620 POS_BEFORE or to POS_AFTER. Note that we want the
12621 first (leftmost) glyph of all those that are the
12622 closest from below, and the last (rightmost) of all
12623 those from above. */
12624 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
12626 pos_before
= glyph
->charpos
;
12627 glyph_before
= glyph
;
12629 else if (0 < dpos
&& dpos
<= pos_after
- pt_old
)
12631 pos_after
= glyph
->charpos
;
12632 glyph_after
= glyph
;
12635 else if (dpos
== 0)
12636 match_with_avoid_cursor
= 1;
12638 else if (STRINGP (glyph
->object
))
12640 Lisp_Object chprop
;
12641 int glyph_pos
= glyph
->charpos
;
12643 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
12645 if (INTEGERP (chprop
))
12647 bpos_covered
= bpos_max
+ XINT (chprop
);
12648 /* If the `cursor' property covers buffer positions up
12649 to and including point, we should display cursor on
12650 this glyph. Note that overlays and text properties
12651 with string values stop bidi reordering, so every
12652 buffer position to the left of the string is always
12653 smaller than any position to the right of the
12654 string. Therefore, if a `cursor' property on one
12655 of the string's characters has an integer value, we
12656 will break out of the loop below _before_ we get to
12657 the position match above. IOW, integer values of
12658 the `cursor' property override the "exact match for
12659 point" strategy of positioning the cursor. */
12660 /* Implementation note: bpos_max == pt_old when, e.g.,
12661 we are in an empty line, where bpos_max is set to
12662 MATRIX_ROW_START_CHARPOS, see above. */
12663 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
12672 x
+= glyph
->pixel_width
;
12675 else if (glyph
> end
) /* row is reversed */
12676 while (!INTEGERP (glyph
->object
))
12678 if (BUFFERP (glyph
->object
))
12680 EMACS_INT dpos
= glyph
->charpos
- pt_old
;
12682 if (glyph
->charpos
> bpos_max
)
12683 bpos_max
= glyph
->charpos
;
12684 if (!glyph
->avoid_cursor_p
)
12688 match_with_avoid_cursor
= 0;
12691 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
12693 pos_before
= glyph
->charpos
;
12694 glyph_before
= glyph
;
12696 else if (0 < dpos
&& dpos
<= pos_after
- pt_old
)
12698 pos_after
= glyph
->charpos
;
12699 glyph_after
= glyph
;
12702 else if (dpos
== 0)
12703 match_with_avoid_cursor
= 1;
12705 else if (STRINGP (glyph
->object
))
12707 Lisp_Object chprop
;
12708 int glyph_pos
= glyph
->charpos
;
12710 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
12712 if (INTEGERP (chprop
))
12714 bpos_covered
= bpos_max
+ XINT (chprop
);
12715 /* If the `cursor' property covers buffer positions up
12716 to and including point, we should display cursor on
12718 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
12727 if (glyph
== glyphs_end
) /* don't dereference outside TEXT_AREA */
12729 x
--; /* can't use any pixel_width */
12732 x
-= glyph
->pixel_width
;
12735 /* Step 2: If we didn't find an exact match for point, we need to
12736 look for a proper place to put the cursor among glyphs between
12737 GLYPH_BEFORE and GLYPH_AFTER. */
12738 if (!((row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
12739 && BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
12740 && bpos_covered
< pt_old
)
12742 if (row
->ends_in_ellipsis_p
&& pos_after
== last_pos
)
12744 EMACS_INT ellipsis_pos
;
12746 /* Scan back over the ellipsis glyphs. */
12747 if (!row
->reversed_p
)
12749 ellipsis_pos
= (glyph
- 1)->charpos
;
12750 while (glyph
> row
->glyphs
[TEXT_AREA
]
12751 && (glyph
- 1)->charpos
== ellipsis_pos
)
12752 glyph
--, x
-= glyph
->pixel_width
;
12753 /* That loop always goes one position too far, including
12754 the glyph before the ellipsis. So scan forward over
12756 x
+= glyph
->pixel_width
;
12759 else /* row is reversed */
12761 ellipsis_pos
= (glyph
+ 1)->charpos
;
12762 while (glyph
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
12763 && (glyph
+ 1)->charpos
== ellipsis_pos
)
12764 glyph
++, x
+= glyph
->pixel_width
;
12765 x
-= glyph
->pixel_width
;
12769 else if (match_with_avoid_cursor
12770 /* zero-width characters produce no glyphs */
12771 || ((row
->reversed_p
12772 ? glyph_after
> glyphs_end
12773 : glyph_after
< glyphs_end
)
12774 && eabs (glyph_after
- glyph_before
) == 1))
12776 cursor
= glyph_after
;
12779 else if (string_seen
)
12781 int incr
= row
->reversed_p
? -1 : +1;
12783 /* Need to find the glyph that came out of a string which is
12784 present at point. That glyph is somewhere between
12785 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12786 positioned between POS_BEFORE and POS_AFTER in the
12788 struct glyph
*stop
= glyph_after
;
12789 EMACS_INT pos
= pos_before
;
12792 for (glyph
= glyph_before
+ incr
;
12793 row
->reversed_p
? glyph
> stop
: glyph
< stop
; )
12796 /* Any glyphs that come from the buffer are here because
12797 of bidi reordering. Skip them, and only pay
12798 attention to glyphs that came from some string. */
12799 if (STRINGP (glyph
->object
))
12804 str
= glyph
->object
;
12805 tem
= string_buffer_position_lim (w
, str
, pos
, pos_after
, 0);
12806 if (tem
== 0 /* from overlay */
12809 /* If the string from which this glyph came is
12810 found in the buffer at point, then we've
12811 found the glyph we've been looking for. If
12812 it comes from an overlay (tem == 0), and it
12813 has the `cursor' property on one of its
12814 glyphs, record that glyph as a candidate for
12815 displaying the cursor. (As in the
12816 unidirectional version, we will display the
12817 cursor on the last candidate we find.) */
12818 if (tem
== 0 || tem
== pt_old
)
12820 /* The glyphs from this string could have
12821 been reordered. Find the one with the
12822 smallest string position. Or there could
12823 be a character in the string with the
12824 `cursor' property, which means display
12825 cursor on that character's glyph. */
12826 int strpos
= glyph
->charpos
;
12829 for (glyph
+= incr
;
12830 (row
->reversed_p
? glyph
> stop
: glyph
< stop
)
12831 && EQ (glyph
->object
, str
);
12835 int gpos
= glyph
->charpos
;
12837 cprop
= Fget_char_property (make_number (gpos
),
12845 if (glyph
->charpos
< strpos
)
12847 strpos
= glyph
->charpos
;
12856 pos
= tem
+ 1; /* don't find previous instances */
12858 /* This string is not what we want; skip all of the
12859 glyphs that came from it. */
12862 while ((row
->reversed_p
? glyph
> stop
: glyph
< stop
)
12863 && EQ (glyph
->object
, str
));
12869 /* If we reached the end of the line, and END was from a string,
12870 the cursor is not on this line. */
12872 && (row
->reversed_p
? glyph
<= end
: glyph
>= end
)
12873 && STRINGP (end
->object
)
12874 && row
->continued_p
)
12880 if (cursor
!= NULL
)
12886 /* Need to compute x that corresponds to GLYPH. */
12887 for (g
= row
->glyphs
[TEXT_AREA
], x
= row
->x
; g
< glyph
; g
++)
12889 if (g
>= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
])
12891 x
+= g
->pixel_width
;
12895 /* ROW could be part of a continued line, which, under bidi
12896 reordering, might have other rows whose start and end charpos
12897 occlude point. Only set w->cursor if we found a better
12898 approximation to the cursor position than we have from previously
12899 examined candidate rows belonging to the same continued line. */
12900 if (/* we already have a candidate row */
12901 w
->cursor
.vpos
>= 0
12902 /* that candidate is not the row we are processing */
12903 && MATRIX_ROW (matrix
, w
->cursor
.vpos
) != row
12904 /* the row we are processing is part of a continued line */
12905 && (row
->continued_p
|| MATRIX_ROW_CONTINUATION_LINE_P (row
))
12906 /* Make sure cursor.vpos specifies a row whose start and end
12907 charpos occlude point. This is because some callers of this
12908 function leave cursor.vpos at the row where the cursor was
12909 displayed during the last redisplay cycle. */
12910 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
)) <= pt_old
12911 && pt_old
< MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
)))
12914 MATRIX_ROW_GLYPH_START (matrix
, w
->cursor
.vpos
) + w
->cursor
.hpos
;
12916 /* Don't consider glyphs that are outside TEXT_AREA. */
12917 if (!(row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
))
12919 /* Keep the candidate whose buffer position is the closest to
12921 if (/* previous candidate is a glyph in TEXT_AREA of that row */
12922 w
->cursor
.hpos
>= 0
12923 && w
->cursor
.hpos
< MATRIX_ROW_USED (matrix
, w
->cursor
.vpos
)
12924 && BUFFERP (g1
->object
)
12925 && (g1
->charpos
== pt_old
/* an exact match always wins */
12926 || (BUFFERP (glyph
->object
)
12927 && eabs (g1
->charpos
- pt_old
)
12928 < eabs (glyph
->charpos
- pt_old
))))
12930 /* If this candidate gives an exact match, use that. */
12931 if (!(BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
12932 /* Otherwise, keep the candidate that comes from a row
12933 spanning less buffer positions. This may win when one or
12934 both candidate positions are on glyphs that came from
12935 display strings, for which we cannot compare buffer
12937 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
12938 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
12939 < MATRIX_ROW_END_CHARPOS (row
) - MATRIX_ROW_START_CHARPOS (row
))
12942 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
12944 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
12945 w
->cursor
.y
= row
->y
+ dy
;
12947 if (w
== XWINDOW (selected_window
))
12949 if (!row
->continued_p
12950 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
12953 this_line_buffer
= XBUFFER (w
->buffer
);
12955 CHARPOS (this_line_start_pos
)
12956 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
12957 BYTEPOS (this_line_start_pos
)
12958 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
12960 CHARPOS (this_line_end_pos
)
12961 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
12962 BYTEPOS (this_line_end_pos
)
12963 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
12965 this_line_y
= w
->cursor
.y
;
12966 this_line_pixel_height
= row
->height
;
12967 this_line_vpos
= w
->cursor
.vpos
;
12968 this_line_start_x
= row
->x
;
12971 CHARPOS (this_line_start_pos
) = 0;
12978 /* Run window scroll functions, if any, for WINDOW with new window
12979 start STARTP. Sets the window start of WINDOW to that position.
12981 We assume that the window's buffer is really current. */
12983 static INLINE
struct text_pos
12984 run_window_scroll_functions (Lisp_Object window
, struct text_pos startp
)
12986 struct window
*w
= XWINDOW (window
);
12987 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
12989 if (current_buffer
!= XBUFFER (w
->buffer
))
12992 if (!NILP (Vwindow_scroll_functions
))
12994 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
12995 make_number (CHARPOS (startp
)));
12996 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12997 /* In case the hook functions switch buffers. */
12998 if (current_buffer
!= XBUFFER (w
->buffer
))
12999 set_buffer_internal_1 (XBUFFER (w
->buffer
));
13006 /* Make sure the line containing the cursor is fully visible.
13007 A value of 1 means there is nothing to be done.
13008 (Either the line is fully visible, or it cannot be made so,
13009 or we cannot tell.)
13011 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13012 is higher than window.
13014 A value of 0 means the caller should do scrolling
13015 as if point had gone off the screen. */
13018 cursor_row_fully_visible_p (struct window
*w
, int force_p
, int current_matrix_p
)
13020 struct glyph_matrix
*matrix
;
13021 struct glyph_row
*row
;
13024 if (!make_cursor_line_fully_visible_p
)
13027 /* It's not always possible to find the cursor, e.g, when a window
13028 is full of overlay strings. Don't do anything in that case. */
13029 if (w
->cursor
.vpos
< 0)
13032 matrix
= current_matrix_p
? w
->current_matrix
: w
->desired_matrix
;
13033 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
13035 /* If the cursor row is not partially visible, there's nothing to do. */
13036 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
))
13039 /* If the row the cursor is in is taller than the window's height,
13040 it's not clear what to do, so do nothing. */
13041 window_height
= window_box_height (w
);
13042 if (row
->height
>= window_height
)
13044 if (!force_p
|| MINI_WINDOW_P (w
)
13045 || w
->vscroll
|| w
->cursor
.vpos
== 0)
13052 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13053 non-zero means only WINDOW is redisplayed in redisplay_internal.
13054 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
13055 in redisplay_window to bring a partially visible line into view in
13056 the case that only the cursor has moved.
13058 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13059 last screen line's vertical height extends past the end of the screen.
13063 1 if scrolling succeeded
13065 0 if scrolling didn't find point.
13067 -1 if new fonts have been loaded so that we must interrupt
13068 redisplay, adjust glyph matrices, and try again. */
13074 SCROLLING_NEED_LARGER_MATRICES
13078 try_scrolling (Lisp_Object window
, int just_this_one_p
,
13079 EMACS_INT scroll_conservatively
, EMACS_INT scroll_step
,
13080 int temp_scroll_step
, int last_line_misfit
)
13082 struct window
*w
= XWINDOW (window
);
13083 struct frame
*f
= XFRAME (w
->frame
);
13084 struct text_pos pos
, startp
;
13086 int this_scroll_margin
, scroll_max
, rc
, height
;
13087 int dy
= 0, amount_to_scroll
= 0, scroll_down_p
= 0;
13088 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
13089 Lisp_Object aggressive
;
13090 int scroll_limit
= INT_MAX
/ FRAME_LINE_HEIGHT (f
);
13093 debug_method_add (w
, "try_scrolling");
13096 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
13098 /* Compute scroll margin height in pixels. We scroll when point is
13099 within this distance from the top or bottom of the window. */
13100 if (scroll_margin
> 0)
13101 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4)
13102 * FRAME_LINE_HEIGHT (f
);
13104 this_scroll_margin
= 0;
13106 /* Force scroll_conservatively to have a reasonable value, to avoid
13107 overflow while computing how much to scroll. Note that the user
13108 can supply scroll-conservatively equal to `most-positive-fixnum',
13109 which can be larger than INT_MAX. */
13110 if (scroll_conservatively
> scroll_limit
)
13112 scroll_conservatively
= scroll_limit
;
13113 scroll_max
= INT_MAX
;
13115 else if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
13116 /* Compute how much we should try to scroll maximally to bring
13117 point into view. */
13118 scroll_max
= (max (scroll_step
,
13119 max (scroll_conservatively
, temp_scroll_step
))
13120 * FRAME_LINE_HEIGHT (f
));
13121 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
13122 || NUMBERP (current_buffer
->scroll_up_aggressively
))
13123 /* We're trying to scroll because of aggressive scrolling but no
13124 scroll_step is set. Choose an arbitrary one. */
13125 scroll_max
= 10 * FRAME_LINE_HEIGHT (f
);
13131 /* Decide whether to scroll down. */
13132 if (PT
> CHARPOS (startp
))
13134 int scroll_margin_y
;
13136 /* Compute the pixel ypos of the scroll margin, then move it to
13137 either that ypos or PT, whichever comes first. */
13138 start_display (&it
, w
, startp
);
13139 scroll_margin_y
= it
.last_visible_y
- this_scroll_margin
13140 - FRAME_LINE_HEIGHT (f
) * extra_scroll_margin_lines
;
13141 move_it_to (&it
, PT
, -1, scroll_margin_y
- 1, -1,
13142 (MOVE_TO_POS
| MOVE_TO_Y
));
13144 if (PT
> CHARPOS (it
.current
.pos
))
13146 int y0
= line_bottom_y (&it
);
13147 /* Compute how many pixels below window bottom to stop searching
13148 for PT. This avoids costly search for PT that is far away if
13149 the user limited scrolling by a small number of lines, but
13150 always finds PT if scroll_conservatively is set to a large
13151 number, such as most-positive-fixnum. */
13152 int slack
= max (scroll_max
, 10 * FRAME_LINE_HEIGHT (f
));
13154 slack
>= INT_MAX
- it
.last_visible_y
13156 : it
.last_visible_y
+ slack
;
13158 /* Compute the distance from the scroll margin to PT or to
13159 the scroll limit, whichever comes first. This should
13160 include the height of the cursor line, to make that line
13162 move_it_to (&it
, PT
, -1, y_to_move
,
13163 -1, MOVE_TO_POS
| MOVE_TO_Y
);
13164 dy
= line_bottom_y (&it
) - y0
;
13166 if (dy
> scroll_max
)
13167 return SCROLLING_FAILED
;
13175 /* Point is in or below the bottom scroll margin, so move the
13176 window start down. If scrolling conservatively, move it just
13177 enough down to make point visible. If scroll_step is set,
13178 move it down by scroll_step. */
13179 if (scroll_conservatively
)
13181 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
13182 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
13183 else if (scroll_step
|| temp_scroll_step
)
13184 amount_to_scroll
= scroll_max
;
13187 aggressive
= current_buffer
->scroll_up_aggressively
;
13188 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
13189 if (NUMBERP (aggressive
))
13191 double float_amount
= XFLOATINT (aggressive
) * height
;
13192 amount_to_scroll
= float_amount
;
13193 if (amount_to_scroll
== 0 && float_amount
> 0)
13194 amount_to_scroll
= 1;
13198 if (amount_to_scroll
<= 0)
13199 return SCROLLING_FAILED
;
13201 start_display (&it
, w
, startp
);
13202 if (scroll_max
< INT_MAX
)
13203 move_it_vertically (&it
, amount_to_scroll
);
13206 /* Extra precision for users who set scroll-conservatively
13207 to most-positive-fixnum: make sure the amount we scroll
13208 the window start is never less than amount_to_scroll,
13209 which was computed as distance from window bottom to
13210 point. This matters when lines at window top and lines
13211 below window bottom have different height. */
13212 struct it it1
= it
;
13213 /* We use a temporary it1 because line_bottom_y can modify
13214 its argument, if it moves one line down; see there. */
13215 int start_y
= line_bottom_y (&it1
);
13218 move_it_by_lines (&it
, 1, 1);
13220 } while (line_bottom_y (&it1
) - start_y
< amount_to_scroll
);
13223 /* If STARTP is unchanged, move it down another screen line. */
13224 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
13225 move_it_by_lines (&it
, 1, 1);
13226 startp
= it
.current
.pos
;
13230 struct text_pos scroll_margin_pos
= startp
;
13232 /* See if point is inside the scroll margin at the top of the
13234 if (this_scroll_margin
)
13236 start_display (&it
, w
, startp
);
13237 move_it_vertically (&it
, this_scroll_margin
);
13238 scroll_margin_pos
= it
.current
.pos
;
13241 if (PT
< CHARPOS (scroll_margin_pos
))
13243 /* Point is in the scroll margin at the top of the window or
13244 above what is displayed in the window. */
13247 /* Compute the vertical distance from PT to the scroll
13248 margin position. Give up if distance is greater than
13250 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
13251 start_display (&it
, w
, pos
);
13253 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
13254 it
.last_visible_y
, -1,
13255 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
13256 dy
= it
.current_y
- y0
;
13257 if (dy
> scroll_max
)
13258 return SCROLLING_FAILED
;
13260 /* Compute new window start. */
13261 start_display (&it
, w
, startp
);
13263 if (scroll_conservatively
)
13265 = max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
13266 else if (scroll_step
|| temp_scroll_step
)
13267 amount_to_scroll
= scroll_max
;
13270 aggressive
= current_buffer
->scroll_down_aggressively
;
13271 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
13272 if (NUMBERP (aggressive
))
13274 double float_amount
= XFLOATINT (aggressive
) * height
;
13275 amount_to_scroll
= float_amount
;
13276 if (amount_to_scroll
== 0 && float_amount
> 0)
13277 amount_to_scroll
= 1;
13281 if (amount_to_scroll
<= 0)
13282 return SCROLLING_FAILED
;
13284 move_it_vertically_backward (&it
, amount_to_scroll
);
13285 startp
= it
.current
.pos
;
13289 /* Run window scroll functions. */
13290 startp
= run_window_scroll_functions (window
, startp
);
13292 /* Display the window. Give up if new fonts are loaded, or if point
13294 if (!try_window (window
, startp
, 0))
13295 rc
= SCROLLING_NEED_LARGER_MATRICES
;
13296 else if (w
->cursor
.vpos
< 0)
13298 clear_glyph_matrix (w
->desired_matrix
);
13299 rc
= SCROLLING_FAILED
;
13303 /* Maybe forget recorded base line for line number display. */
13304 if (!just_this_one_p
13305 || current_buffer
->clip_changed
13306 || BEG_UNCHANGED
< CHARPOS (startp
))
13307 w
->base_line_number
= Qnil
;
13309 /* If cursor ends up on a partially visible line,
13310 treat that as being off the bottom of the screen. */
13311 if (! cursor_row_fully_visible_p (w
, extra_scroll_margin_lines
<= 1, 0))
13313 clear_glyph_matrix (w
->desired_matrix
);
13314 ++extra_scroll_margin_lines
;
13317 rc
= SCROLLING_SUCCESS
;
13324 /* Compute a suitable window start for window W if display of W starts
13325 on a continuation line. Value is non-zero if a new window start
13328 The new window start will be computed, based on W's width, starting
13329 from the start of the continued line. It is the start of the
13330 screen line with the minimum distance from the old start W->start. */
13333 compute_window_start_on_continuation_line (struct window
*w
)
13335 struct text_pos pos
, start_pos
;
13336 int window_start_changed_p
= 0;
13338 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
13340 /* If window start is on a continuation line... Window start may be
13341 < BEGV in case there's invisible text at the start of the
13342 buffer (M-x rmail, for example). */
13343 if (CHARPOS (start_pos
) > BEGV
13344 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
13347 struct glyph_row
*row
;
13349 /* Handle the case that the window start is out of range. */
13350 if (CHARPOS (start_pos
) < BEGV
)
13351 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
13352 else if (CHARPOS (start_pos
) > ZV
)
13353 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
13355 /* Find the start of the continued line. This should be fast
13356 because scan_buffer is fast (newline cache). */
13357 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
13358 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
13359 row
, DEFAULT_FACE_ID
);
13360 reseat_at_previous_visible_line_start (&it
);
13362 /* If the line start is "too far" away from the window start,
13363 say it takes too much time to compute a new window start. */
13364 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
13365 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
13367 int min_distance
, distance
;
13369 /* Move forward by display lines to find the new window
13370 start. If window width was enlarged, the new start can
13371 be expected to be > the old start. If window width was
13372 decreased, the new window start will be < the old start.
13373 So, we're looking for the display line start with the
13374 minimum distance from the old window start. */
13375 pos
= it
.current
.pos
;
13376 min_distance
= INFINITY
;
13377 while ((distance
= eabs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
13378 distance
< min_distance
)
13380 min_distance
= distance
;
13381 pos
= it
.current
.pos
;
13382 move_it_by_lines (&it
, 1, 0);
13385 /* Set the window start there. */
13386 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
13387 window_start_changed_p
= 1;
13391 return window_start_changed_p
;
13395 /* Try cursor movement in case text has not changed in window WINDOW,
13396 with window start STARTP. Value is
13398 CURSOR_MOVEMENT_SUCCESS if successful
13400 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13402 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13403 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13404 we want to scroll as if scroll-step were set to 1. See the code.
13406 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13407 which case we have to abort this redisplay, and adjust matrices
13412 CURSOR_MOVEMENT_SUCCESS
,
13413 CURSOR_MOVEMENT_CANNOT_BE_USED
,
13414 CURSOR_MOVEMENT_MUST_SCROLL
,
13415 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13419 try_cursor_movement (Lisp_Object window
, struct text_pos startp
, int *scroll_step
)
13421 struct window
*w
= XWINDOW (window
);
13422 struct frame
*f
= XFRAME (w
->frame
);
13423 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
13426 if (inhibit_try_cursor_movement
)
13430 /* Handle case where text has not changed, only point, and it has
13431 not moved off the frame. */
13432 if (/* Point may be in this window. */
13433 PT
>= CHARPOS (startp
)
13434 /* Selective display hasn't changed. */
13435 && !current_buffer
->clip_changed
13436 /* Function force-mode-line-update is used to force a thorough
13437 redisplay. It sets either windows_or_buffers_changed or
13438 update_mode_lines. So don't take a shortcut here for these
13440 && !update_mode_lines
13441 && !windows_or_buffers_changed
13442 && !cursor_type_changed
13443 /* Can't use this case if highlighting a region. When a
13444 region exists, cursor movement has to do more than just
13446 && !(!NILP (Vtransient_mark_mode
)
13447 && !NILP (current_buffer
->mark_active
))
13448 && NILP (w
->region_showing
)
13449 && NILP (Vshow_trailing_whitespace
)
13450 /* Right after splitting windows, last_point may be nil. */
13451 && INTEGERP (w
->last_point
)
13452 /* This code is not used for mini-buffer for the sake of the case
13453 of redisplaying to replace an echo area message; since in
13454 that case the mini-buffer contents per se are usually
13455 unchanged. This code is of no real use in the mini-buffer
13456 since the handling of this_line_start_pos, etc., in redisplay
13457 handles the same cases. */
13458 && !EQ (window
, minibuf_window
)
13459 /* When splitting windows or for new windows, it happens that
13460 redisplay is called with a nil window_end_vpos or one being
13461 larger than the window. This should really be fixed in
13462 window.c. I don't have this on my list, now, so we do
13463 approximately the same as the old redisplay code. --gerd. */
13464 && INTEGERP (w
->window_end_vpos
)
13465 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
13466 && (FRAME_WINDOW_P (f
)
13467 || !overlay_arrow_in_current_buffer_p ()))
13469 int this_scroll_margin
, top_scroll_margin
;
13470 struct glyph_row
*row
= NULL
;
13473 debug_method_add (w
, "cursor movement");
13476 /* Scroll if point within this distance from the top or bottom
13477 of the window. This is a pixel value. */
13478 if (scroll_margin
> 0)
13480 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13481 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
13484 this_scroll_margin
= 0;
13486 top_scroll_margin
= this_scroll_margin
;
13487 if (WINDOW_WANTS_HEADER_LINE_P (w
))
13488 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
13490 /* Start with the row the cursor was displayed during the last
13491 not paused redisplay. Give up if that row is not valid. */
13492 if (w
->last_cursor
.vpos
< 0
13493 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
13494 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13497 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
13498 if (row
->mode_line_p
)
13500 if (!row
->enabled_p
)
13501 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13504 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
13506 int scroll_p
= 0, must_scroll
= 0;
13507 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
13509 if (PT
> XFASTINT (w
->last_point
))
13511 /* Point has moved forward. */
13512 while (MATRIX_ROW_END_CHARPOS (row
) < PT
13513 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
13515 xassert (row
->enabled_p
);
13519 /* If the end position of a row equals the start
13520 position of the next row, and PT is at that position,
13521 we would rather display cursor in the next line. */
13522 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
13523 && MATRIX_ROW_END_CHARPOS (row
) == PT
13524 && row
< w
->current_matrix
->rows
13525 + w
->current_matrix
->nrows
- 1
13526 && MATRIX_ROW_START_CHARPOS (row
+1) == PT
13527 && !cursor_row_p (w
, row
))
13530 /* If within the scroll margin, scroll. Note that
13531 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13532 the next line would be drawn, and that
13533 this_scroll_margin can be zero. */
13534 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
13535 || PT
> MATRIX_ROW_END_CHARPOS (row
)
13536 /* Line is completely visible last line in window
13537 and PT is to be set in the next line. */
13538 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
13539 && PT
== MATRIX_ROW_END_CHARPOS (row
)
13540 && !row
->ends_at_zv_p
13541 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
13544 else if (PT
< XFASTINT (w
->last_point
))
13546 /* Cursor has to be moved backward. Note that PT >=
13547 CHARPOS (startp) because of the outer if-statement. */
13548 while (!row
->mode_line_p
13549 && (MATRIX_ROW_START_CHARPOS (row
) > PT
13550 || (MATRIX_ROW_START_CHARPOS (row
) == PT
13551 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)
13552 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13553 row
> w
->current_matrix
->rows
13554 && (row
-1)->ends_in_newline_from_string_p
))))
13555 && (row
->y
> top_scroll_margin
13556 || CHARPOS (startp
) == BEGV
))
13558 xassert (row
->enabled_p
);
13562 /* Consider the following case: Window starts at BEGV,
13563 there is invisible, intangible text at BEGV, so that
13564 display starts at some point START > BEGV. It can
13565 happen that we are called with PT somewhere between
13566 BEGV and START. Try to handle that case. */
13567 if (row
< w
->current_matrix
->rows
13568 || row
->mode_line_p
)
13570 row
= w
->current_matrix
->rows
;
13571 if (row
->mode_line_p
)
13575 /* Due to newlines in overlay strings, we may have to
13576 skip forward over overlay strings. */
13577 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
13578 && MATRIX_ROW_END_CHARPOS (row
) == PT
13579 && !cursor_row_p (w
, row
))
13582 /* If within the scroll margin, scroll. */
13583 if (row
->y
< top_scroll_margin
13584 && CHARPOS (startp
) != BEGV
)
13589 /* Cursor did not move. So don't scroll even if cursor line
13590 is partially visible, as it was so before. */
13591 rc
= CURSOR_MOVEMENT_SUCCESS
;
13594 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
13595 || PT
> MATRIX_ROW_END_CHARPOS (row
))
13597 /* if PT is not in the glyph row, give up. */
13598 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13601 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
13602 && !NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
))
13604 /* If rows are bidi-reordered and point moved, back up
13605 until we find a row that does not belong to a
13606 continuation line. This is because we must consider
13607 all rows of a continued line as candidates for the
13608 new cursor positioning, since row start and end
13609 positions change non-linearly with vertical position
13611 /* FIXME: Revisit this when glyph ``spilling'' in
13612 continuation lines' rows is implemented for
13613 bidi-reordered rows. */
13614 while (MATRIX_ROW_CONTINUATION_LINE_P (row
))
13616 xassert (row
->enabled_p
);
13618 /* If we hit the beginning of the displayed portion
13619 without finding the first row of a continued
13621 if (row
<= w
->current_matrix
->rows
)
13623 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13631 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
13632 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
)
13633 && make_cursor_line_fully_visible_p
)
13635 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
13636 && !row
->ends_at_zv_p
13637 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
13638 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13639 else if (row
->height
> window_box_height (w
))
13641 /* If we end up in a partially visible line, let's
13642 make it fully visible, except when it's taller
13643 than the window, in which case we can't do much
13646 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13650 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13651 if (!cursor_row_fully_visible_p (w
, 0, 1))
13652 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13654 rc
= CURSOR_MOVEMENT_SUCCESS
;
13658 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13659 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
13660 && !NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
))
13662 /* With bidi-reordered rows, there could be more than
13663 one candidate row whose start and end positions
13664 occlude point. We need to let set_cursor_from_row
13665 find the best candidate. */
13666 /* FIXME: Revisit this when glyph ``spilling'' in
13667 continuation lines' rows is implemented for
13668 bidi-reordered rows. */
13673 if (MATRIX_ROW_START_CHARPOS (row
) <= PT
13674 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
13675 && cursor_row_p (w
, row
))
13676 rv
|= set_cursor_from_row (w
, row
, w
->current_matrix
,
13678 /* As soon as we've found the first suitable row
13679 whose ends_at_zv_p flag is set, we are done. */
13681 && MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
)->ends_at_zv_p
)
13683 rc
= CURSOR_MOVEMENT_SUCCESS
;
13688 while ((MATRIX_ROW_CONTINUATION_LINE_P (row
)
13689 && MATRIX_ROW_BOTTOM_Y (row
) <= last_y
)
13690 || (MATRIX_ROW_START_CHARPOS (row
) == PT
13691 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
));
13692 /* If we didn't find any candidate rows, or exited the
13693 loop before all the candidates were examined, signal
13694 to the caller that this method failed. */
13695 if (rc
!= CURSOR_MOVEMENT_SUCCESS
13696 && (!rv
|| MATRIX_ROW_CONTINUATION_LINE_P (row
)))
13697 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
13699 rc
= CURSOR_MOVEMENT_SUCCESS
;
13705 if (set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0))
13707 rc
= CURSOR_MOVEMENT_SUCCESS
;
13712 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
13713 && MATRIX_ROW_START_CHARPOS (row
) == PT
13714 && cursor_row_p (w
, row
));
13723 set_vertical_scroll_bar (struct window
*w
)
13725 int start
, end
, whole
;
13727 /* Calculate the start and end positions for the current window.
13728 At some point, it would be nice to choose between scrollbars
13729 which reflect the whole buffer size, with special markers
13730 indicating narrowing, and scrollbars which reflect only the
13733 Note that mini-buffers sometimes aren't displaying any text. */
13734 if (!MINI_WINDOW_P (w
)
13735 || (w
== XWINDOW (minibuf_window
)
13736 && NILP (echo_area_buffer
[0])))
13738 struct buffer
*buf
= XBUFFER (w
->buffer
);
13739 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
13740 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
13741 /* I don't think this is guaranteed to be right. For the
13742 moment, we'll pretend it is. */
13743 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
13747 if (whole
< (end
- start
))
13748 whole
= end
- start
;
13751 start
= end
= whole
= 0;
13753 /* Indicate what this scroll bar ought to be displaying now. */
13754 if (FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
13755 (*FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
13756 (w
, end
- start
, whole
, start
);
13760 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13761 selected_window is redisplayed.
13763 We can return without actually redisplaying the window if
13764 fonts_changed_p is nonzero. In that case, redisplay_internal will
13768 redisplay_window (Lisp_Object window
, int just_this_one_p
)
13770 struct window
*w
= XWINDOW (window
);
13771 struct frame
*f
= XFRAME (w
->frame
);
13772 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13773 struct buffer
*old
= current_buffer
;
13774 struct text_pos lpoint
, opoint
, startp
;
13775 int update_mode_line
;
13778 /* Record it now because it's overwritten. */
13779 int current_matrix_up_to_date_p
= 0;
13780 int used_current_matrix_p
= 0;
13781 /* This is less strict than current_matrix_up_to_date_p.
13782 It indictes that the buffer contents and narrowing are unchanged. */
13783 int buffer_unchanged_p
= 0;
13784 int temp_scroll_step
= 0;
13785 int count
= SPECPDL_INDEX ();
13787 int centering_position
= -1;
13788 int last_line_misfit
= 0;
13789 int beg_unchanged
, end_unchanged
;
13791 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
13794 /* W must be a leaf window here. */
13795 xassert (!NILP (w
->buffer
));
13797 *w
->desired_matrix
->method
= 0;
13801 reconsider_clip_changes (w
, buffer
);
13803 /* Has the mode line to be updated? */
13804 update_mode_line
= (!NILP (w
->update_mode_line
)
13805 || update_mode_lines
13806 || buffer
->clip_changed
13807 || buffer
->prevent_redisplay_optimizations_p
);
13809 if (MINI_WINDOW_P (w
))
13811 if (w
== XWINDOW (echo_area_window
)
13812 && !NILP (echo_area_buffer
[0]))
13814 if (update_mode_line
)
13815 /* We may have to update a tty frame's menu bar or a
13816 tool-bar. Example `M-x C-h C-h C-g'. */
13817 goto finish_menu_bars
;
13819 /* We've already displayed the echo area glyphs in this window. */
13820 goto finish_scroll_bars
;
13822 else if ((w
!= XWINDOW (minibuf_window
)
13823 || minibuf_level
== 0)
13824 /* When buffer is nonempty, redisplay window normally. */
13825 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
13826 /* Quail displays non-mini buffers in minibuffer window.
13827 In that case, redisplay the window normally. */
13828 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
13830 /* W is a mini-buffer window, but it's not active, so clear
13832 int yb
= window_text_bottom_y (w
);
13833 struct glyph_row
*row
;
13836 for (y
= 0, row
= w
->desired_matrix
->rows
;
13838 y
+= row
->height
, ++row
)
13839 blank_row (w
, row
, y
);
13840 goto finish_scroll_bars
;
13843 clear_glyph_matrix (w
->desired_matrix
);
13846 /* Otherwise set up data on this window; select its buffer and point
13848 /* Really select the buffer, for the sake of buffer-local
13850 set_buffer_internal_1 (XBUFFER (w
->buffer
));
13852 current_matrix_up_to_date_p
13853 = (!NILP (w
->window_end_valid
)
13854 && !current_buffer
->clip_changed
13855 && !current_buffer
->prevent_redisplay_optimizations_p
13856 && XFASTINT (w
->last_modified
) >= MODIFF
13857 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
13859 /* Run the window-bottom-change-functions
13860 if it is possible that the text on the screen has changed
13861 (either due to modification of the text, or any other reason). */
13862 if (!current_matrix_up_to_date_p
13863 && !NILP (Vwindow_text_change_functions
))
13865 safe_run_hooks (Qwindow_text_change_functions
);
13869 beg_unchanged
= BEG_UNCHANGED
;
13870 end_unchanged
= END_UNCHANGED
;
13872 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
13874 specbind (Qinhibit_point_motion_hooks
, Qt
);
13877 = (!NILP (w
->window_end_valid
)
13878 && !current_buffer
->clip_changed
13879 && XFASTINT (w
->last_modified
) >= MODIFF
13880 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
13882 /* When windows_or_buffers_changed is non-zero, we can't rely on
13883 the window end being valid, so set it to nil there. */
13884 if (windows_or_buffers_changed
)
13886 /* If window starts on a continuation line, maybe adjust the
13887 window start in case the window's width changed. */
13888 if (XMARKER (w
->start
)->buffer
== current_buffer
)
13889 compute_window_start_on_continuation_line (w
);
13891 w
->window_end_valid
= Qnil
;
13894 /* Some sanity checks. */
13895 CHECK_WINDOW_END (w
);
13896 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
13898 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
13901 /* If %c is in mode line, update it if needed. */
13902 if (!NILP (w
->column_number_displayed
)
13903 /* This alternative quickly identifies a common case
13904 where no change is needed. */
13905 && !(PT
== XFASTINT (w
->last_point
)
13906 && XFASTINT (w
->last_modified
) >= MODIFF
13907 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
13908 && (XFASTINT (w
->column_number_displayed
)
13909 != (int) current_column ())) /* iftc */
13910 update_mode_line
= 1;
13912 /* Count number of windows showing the selected buffer. An indirect
13913 buffer counts as its base buffer. */
13914 if (!just_this_one_p
)
13916 struct buffer
*current_base
, *window_base
;
13917 current_base
= current_buffer
;
13918 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
13919 if (current_base
->base_buffer
)
13920 current_base
= current_base
->base_buffer
;
13921 if (window_base
->base_buffer
)
13922 window_base
= window_base
->base_buffer
;
13923 if (current_base
== window_base
)
13927 /* Point refers normally to the selected window. For any other
13928 window, set up appropriate value. */
13929 if (!EQ (window
, selected_window
))
13931 int new_pt
= XMARKER (w
->pointm
)->charpos
;
13932 int new_pt_byte
= marker_byte_position (w
->pointm
);
13936 new_pt_byte
= BEGV_BYTE
;
13937 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
13939 else if (new_pt
> (ZV
- 1))
13942 new_pt_byte
= ZV_BYTE
;
13943 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
13946 /* We don't use SET_PT so that the point-motion hooks don't run. */
13947 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
13950 /* If any of the character widths specified in the display table
13951 have changed, invalidate the width run cache. It's true that
13952 this may be a bit late to catch such changes, but the rest of
13953 redisplay goes (non-fatally) haywire when the display table is
13954 changed, so why should we worry about doing any better? */
13955 if (current_buffer
->width_run_cache
)
13957 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
13959 if (! disptab_matches_widthtab (disptab
,
13960 XVECTOR (current_buffer
->width_table
)))
13962 invalidate_region_cache (current_buffer
,
13963 current_buffer
->width_run_cache
,
13965 recompute_width_table (current_buffer
, disptab
);
13969 /* If window-start is screwed up, choose a new one. */
13970 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
13973 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
13975 /* If someone specified a new starting point but did not insist,
13976 check whether it can be used. */
13977 if (!NILP (w
->optional_new_start
)
13978 && CHARPOS (startp
) >= BEGV
13979 && CHARPOS (startp
) <= ZV
)
13981 w
->optional_new_start
= Qnil
;
13982 start_display (&it
, w
, startp
);
13983 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
13984 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
13985 if (IT_CHARPOS (it
) == PT
)
13986 w
->force_start
= Qt
;
13987 /* IT may overshoot PT if text at PT is invisible. */
13988 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
13989 w
->force_start
= Qt
;
13994 /* Handle case where place to start displaying has been specified,
13995 unless the specified location is outside the accessible range. */
13996 if (!NILP (w
->force_start
)
13997 || w
->frozen_window_start_p
)
13999 /* We set this later on if we have to adjust point. */
14002 w
->force_start
= Qnil
;
14004 w
->window_end_valid
= Qnil
;
14006 /* Forget any recorded base line for line number display. */
14007 if (!buffer_unchanged_p
)
14008 w
->base_line_number
= Qnil
;
14010 /* Redisplay the mode line. Select the buffer properly for that.
14011 Also, run the hook window-scroll-functions
14012 because we have scrolled. */
14013 /* Note, we do this after clearing force_start because
14014 if there's an error, it is better to forget about force_start
14015 than to get into an infinite loop calling the hook functions
14016 and having them get more errors. */
14017 if (!update_mode_line
14018 || ! NILP (Vwindow_scroll_functions
))
14020 update_mode_line
= 1;
14021 w
->update_mode_line
= Qt
;
14022 startp
= run_window_scroll_functions (window
, startp
);
14025 w
->last_modified
= make_number (0);
14026 w
->last_overlay_modified
= make_number (0);
14027 if (CHARPOS (startp
) < BEGV
)
14028 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
14029 else if (CHARPOS (startp
) > ZV
)
14030 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
14032 /* Redisplay, then check if cursor has been set during the
14033 redisplay. Give up if new fonts were loaded. */
14034 /* We used to issue a CHECK_MARGINS argument to try_window here,
14035 but this causes scrolling to fail when point begins inside
14036 the scroll margin (bug#148) -- cyd */
14037 if (!try_window (window
, startp
, 0))
14039 w
->force_start
= Qt
;
14040 clear_glyph_matrix (w
->desired_matrix
);
14041 goto need_larger_matrices
;
14044 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
14046 /* If point does not appear, try to move point so it does
14047 appear. The desired matrix has been built above, so we
14048 can use it here. */
14049 new_vpos
= window_box_height (w
) / 2;
14052 if (!cursor_row_fully_visible_p (w
, 0, 0))
14054 /* Point does appear, but on a line partly visible at end of window.
14055 Move it back to a fully-visible line. */
14056 new_vpos
= window_box_height (w
);
14059 /* If we need to move point for either of the above reasons,
14060 now actually do it. */
14063 struct glyph_row
*row
;
14065 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
14066 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
14069 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
14070 MATRIX_ROW_START_BYTEPOS (row
));
14072 if (w
!= XWINDOW (selected_window
))
14073 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
14074 else if (current_buffer
== old
)
14075 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
14077 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
14079 /* If we are highlighting the region, then we just changed
14080 the region, so redisplay to show it. */
14081 if (!NILP (Vtransient_mark_mode
)
14082 && !NILP (current_buffer
->mark_active
))
14084 clear_glyph_matrix (w
->desired_matrix
);
14085 if (!try_window (window
, startp
, 0))
14086 goto need_larger_matrices
;
14091 debug_method_add (w
, "forced window start");
14096 /* Handle case where text has not changed, only point, and it has
14097 not moved off the frame, and we are not retrying after hscroll.
14098 (current_matrix_up_to_date_p is nonzero when retrying.) */
14099 if (current_matrix_up_to_date_p
14100 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
14101 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
14105 case CURSOR_MOVEMENT_SUCCESS
:
14106 used_current_matrix_p
= 1;
14109 case CURSOR_MOVEMENT_MUST_SCROLL
:
14110 goto try_to_scroll
;
14116 /* If current starting point was originally the beginning of a line
14117 but no longer is, find a new starting point. */
14118 else if (!NILP (w
->start_at_line_beg
)
14119 && !(CHARPOS (startp
) <= BEGV
14120 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
14123 debug_method_add (w
, "recenter 1");
14128 /* Try scrolling with try_window_id. Value is > 0 if update has
14129 been done, it is -1 if we know that the same window start will
14130 not work. It is 0 if unsuccessful for some other reason. */
14131 else if ((tem
= try_window_id (w
)) != 0)
14134 debug_method_add (w
, "try_window_id %d", tem
);
14137 if (fonts_changed_p
)
14138 goto need_larger_matrices
;
14142 /* Otherwise try_window_id has returned -1 which means that we
14143 don't want the alternative below this comment to execute. */
14145 else if (CHARPOS (startp
) >= BEGV
14146 && CHARPOS (startp
) <= ZV
14147 && PT
>= CHARPOS (startp
)
14148 && (CHARPOS (startp
) < ZV
14149 /* Avoid starting at end of buffer. */
14150 || CHARPOS (startp
) == BEGV
14151 || (XFASTINT (w
->last_modified
) >= MODIFF
14152 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
14155 /* If first window line is a continuation line, and window start
14156 is inside the modified region, but the first change is before
14157 current window start, we must select a new window start.
14159 However, if this is the result of a down-mouse event (e.g. by
14160 extending the mouse-drag-overlay), we don't want to select a
14161 new window start, since that would change the position under
14162 the mouse, resulting in an unwanted mouse-movement rather
14163 than a simple mouse-click. */
14164 if (NILP (w
->start_at_line_beg
)
14165 && NILP (do_mouse_tracking
)
14166 && CHARPOS (startp
) > BEGV
14167 && CHARPOS (startp
) > BEG
+ beg_unchanged
14168 && CHARPOS (startp
) <= Z
- end_unchanged
14169 /* Even if w->start_at_line_beg is nil, a new window may
14170 start at a line_beg, since that's how set_buffer_window
14171 sets it. So, we need to check the return value of
14172 compute_window_start_on_continuation_line. (See also
14174 && XMARKER (w
->start
)->buffer
== current_buffer
14175 && compute_window_start_on_continuation_line (w
))
14177 w
->force_start
= Qt
;
14178 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14183 debug_method_add (w
, "same window start");
14186 /* Try to redisplay starting at same place as before.
14187 If point has not moved off frame, accept the results. */
14188 if (!current_matrix_up_to_date_p
14189 /* Don't use try_window_reusing_current_matrix in this case
14190 because a window scroll function can have changed the
14192 || !NILP (Vwindow_scroll_functions
)
14193 || MINI_WINDOW_P (w
)
14194 || !(used_current_matrix_p
14195 = try_window_reusing_current_matrix (w
)))
14197 IF_DEBUG (debug_method_add (w
, "1"));
14198 if (try_window (window
, startp
, TRY_WINDOW_CHECK_MARGINS
) < 0)
14199 /* -1 means we need to scroll.
14200 0 means we need new matrices, but fonts_changed_p
14201 is set in that case, so we will detect it below. */
14202 goto try_to_scroll
;
14205 if (fonts_changed_p
)
14206 goto need_larger_matrices
;
14208 if (w
->cursor
.vpos
>= 0)
14210 if (!just_this_one_p
14211 || current_buffer
->clip_changed
14212 || BEG_UNCHANGED
< CHARPOS (startp
))
14213 /* Forget any recorded base line for line number display. */
14214 w
->base_line_number
= Qnil
;
14216 if (!cursor_row_fully_visible_p (w
, 1, 0))
14218 clear_glyph_matrix (w
->desired_matrix
);
14219 last_line_misfit
= 1;
14221 /* Drop through and scroll. */
14226 clear_glyph_matrix (w
->desired_matrix
);
14231 w
->last_modified
= make_number (0);
14232 w
->last_overlay_modified
= make_number (0);
14234 /* Redisplay the mode line. Select the buffer properly for that. */
14235 if (!update_mode_line
)
14237 update_mode_line
= 1;
14238 w
->update_mode_line
= Qt
;
14241 /* Try to scroll by specified few lines. */
14242 if ((scroll_conservatively
14244 || temp_scroll_step
14245 || NUMBERP (current_buffer
->scroll_up_aggressively
)
14246 || NUMBERP (current_buffer
->scroll_down_aggressively
))
14247 && !current_buffer
->clip_changed
14248 && CHARPOS (startp
) >= BEGV
14249 && CHARPOS (startp
) <= ZV
)
14251 /* The function returns -1 if new fonts were loaded, 1 if
14252 successful, 0 if not successful. */
14253 int rc
= try_scrolling (window
, just_this_one_p
,
14254 scroll_conservatively
,
14256 temp_scroll_step
, last_line_misfit
);
14259 case SCROLLING_SUCCESS
:
14262 case SCROLLING_NEED_LARGER_MATRICES
:
14263 goto need_larger_matrices
;
14265 case SCROLLING_FAILED
:
14273 /* Finally, just choose place to start which centers point */
14276 if (centering_position
< 0)
14277 centering_position
= window_box_height (w
) / 2;
14280 debug_method_add (w
, "recenter");
14283 /* w->vscroll = 0; */
14285 /* Forget any previously recorded base line for line number display. */
14286 if (!buffer_unchanged_p
)
14287 w
->base_line_number
= Qnil
;
14289 /* Move backward half the height of the window. */
14290 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
14291 it
.current_y
= it
.last_visible_y
;
14292 move_it_vertically_backward (&it
, centering_position
);
14293 xassert (IT_CHARPOS (it
) >= BEGV
);
14295 /* The function move_it_vertically_backward may move over more
14296 than the specified y-distance. If it->w is small, e.g. a
14297 mini-buffer window, we may end up in front of the window's
14298 display area. Start displaying at the start of the line
14299 containing PT in this case. */
14300 if (it
.current_y
<= 0)
14302 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
14303 move_it_vertically_backward (&it
, 0);
14307 it
.current_x
= it
.hpos
= 0;
14309 /* Set startp here explicitly in case that helps avoid an infinite loop
14310 in case the window-scroll-functions functions get errors. */
14311 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
14313 /* Run scroll hooks. */
14314 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
14316 /* Redisplay the window. */
14317 if (!current_matrix_up_to_date_p
14318 || windows_or_buffers_changed
14319 || cursor_type_changed
14320 /* Don't use try_window_reusing_current_matrix in this case
14321 because it can have changed the buffer. */
14322 || !NILP (Vwindow_scroll_functions
)
14323 || !just_this_one_p
14324 || MINI_WINDOW_P (w
)
14325 || !(used_current_matrix_p
14326 = try_window_reusing_current_matrix (w
)))
14327 try_window (window
, startp
, 0);
14329 /* If new fonts have been loaded (due to fontsets), give up. We
14330 have to start a new redisplay since we need to re-adjust glyph
14332 if (fonts_changed_p
)
14333 goto need_larger_matrices
;
14335 /* If cursor did not appear assume that the middle of the window is
14336 in the first line of the window. Do it again with the next line.
14337 (Imagine a window of height 100, displaying two lines of height
14338 60. Moving back 50 from it->last_visible_y will end in the first
14340 if (w
->cursor
.vpos
< 0)
14342 if (!NILP (w
->window_end_valid
)
14343 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
14345 clear_glyph_matrix (w
->desired_matrix
);
14346 move_it_by_lines (&it
, 1, 0);
14347 try_window (window
, it
.current
.pos
, 0);
14349 else if (PT
< IT_CHARPOS (it
))
14351 clear_glyph_matrix (w
->desired_matrix
);
14352 move_it_by_lines (&it
, -1, 0);
14353 try_window (window
, it
.current
.pos
, 0);
14357 /* Not much we can do about it. */
14361 /* Consider the following case: Window starts at BEGV, there is
14362 invisible, intangible text at BEGV, so that display starts at
14363 some point START > BEGV. It can happen that we are called with
14364 PT somewhere between BEGV and START. Try to handle that case. */
14365 if (w
->cursor
.vpos
< 0)
14367 struct glyph_row
*row
= w
->current_matrix
->rows
;
14368 if (row
->mode_line_p
)
14370 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
14373 if (!cursor_row_fully_visible_p (w
, 0, 0))
14375 /* If vscroll is enabled, disable it and try again. */
14379 clear_glyph_matrix (w
->desired_matrix
);
14383 /* If centering point failed to make the whole line visible,
14384 put point at the top instead. That has to make the whole line
14385 visible, if it can be done. */
14386 if (centering_position
== 0)
14389 clear_glyph_matrix (w
->desired_matrix
);
14390 centering_position
= 0;
14396 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14397 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
14398 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
14401 /* Display the mode line, if we must. */
14402 if ((update_mode_line
14403 /* If window not full width, must redo its mode line
14404 if (a) the window to its side is being redone and
14405 (b) we do a frame-based redisplay. This is a consequence
14406 of how inverted lines are drawn in frame-based redisplay. */
14407 || (!just_this_one_p
14408 && !FRAME_WINDOW_P (f
)
14409 && !WINDOW_FULL_WIDTH_P (w
))
14410 /* Line number to display. */
14411 || INTEGERP (w
->base_line_pos
)
14412 /* Column number is displayed and different from the one displayed. */
14413 || (!NILP (w
->column_number_displayed
)
14414 && (XFASTINT (w
->column_number_displayed
)
14415 != (int) current_column ()))) /* iftc */
14416 /* This means that the window has a mode line. */
14417 && (WINDOW_WANTS_MODELINE_P (w
)
14418 || WINDOW_WANTS_HEADER_LINE_P (w
)))
14420 display_mode_lines (w
);
14422 /* If mode line height has changed, arrange for a thorough
14423 immediate redisplay using the correct mode line height. */
14424 if (WINDOW_WANTS_MODELINE_P (w
)
14425 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
14427 fonts_changed_p
= 1;
14428 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
14429 = DESIRED_MODE_LINE_HEIGHT (w
);
14432 /* If header line height has changed, arrange for a thorough
14433 immediate redisplay using the correct header line height. */
14434 if (WINDOW_WANTS_HEADER_LINE_P (w
)
14435 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
14437 fonts_changed_p
= 1;
14438 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
14439 = DESIRED_HEADER_LINE_HEIGHT (w
);
14442 if (fonts_changed_p
)
14443 goto need_larger_matrices
;
14446 if (!line_number_displayed
14447 && !BUFFERP (w
->base_line_pos
))
14449 w
->base_line_pos
= Qnil
;
14450 w
->base_line_number
= Qnil
;
14455 /* When we reach a frame's selected window, redo the frame's menu bar. */
14456 if (update_mode_line
14457 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
14459 int redisplay_menu_p
= 0;
14460 int redisplay_tool_bar_p
= 0;
14462 if (FRAME_WINDOW_P (f
))
14464 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14465 || defined (HAVE_NS) || defined (USE_GTK)
14466 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
14468 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
14472 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
14474 if (redisplay_menu_p
)
14475 display_menu_bar (w
);
14477 #ifdef HAVE_WINDOW_SYSTEM
14478 if (FRAME_WINDOW_P (f
))
14480 #if defined (USE_GTK) || defined (HAVE_NS)
14481 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
14483 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
14484 && (FRAME_TOOL_BAR_LINES (f
) > 0
14485 || !NILP (Vauto_resize_tool_bars
));
14488 if (redisplay_tool_bar_p
&& redisplay_tool_bar (f
))
14490 extern int ignore_mouse_drag_p
;
14491 ignore_mouse_drag_p
= 1;
14497 #ifdef HAVE_WINDOW_SYSTEM
14498 if (FRAME_WINDOW_P (f
)
14499 && update_window_fringes (w
, (just_this_one_p
14500 || (!used_current_matrix_p
&& !overlay_arrow_seen
)
14501 || w
->pseudo_window_p
)))
14505 if (draw_window_fringes (w
, 1))
14506 x_draw_vertical_border (w
);
14510 #endif /* HAVE_WINDOW_SYSTEM */
14512 /* We go to this label, with fonts_changed_p nonzero,
14513 if it is necessary to try again using larger glyph matrices.
14514 We have to redeem the scroll bar even in this case,
14515 because the loop in redisplay_internal expects that. */
14516 need_larger_matrices
:
14518 finish_scroll_bars
:
14520 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
14522 /* Set the thumb's position and size. */
14523 set_vertical_scroll_bar (w
);
14525 /* Note that we actually used the scroll bar attached to this
14526 window, so it shouldn't be deleted at the end of redisplay. */
14527 if (FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
)
14528 (*FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
) (w
);
14531 /* Restore current_buffer and value of point in it. The window
14532 update may have changed the buffer, so first make sure `opoint'
14533 is still valid (Bug#6177). */
14534 if (CHARPOS (opoint
) < BEGV
)
14535 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
14536 else if (CHARPOS (opoint
) > ZV
)
14537 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
14539 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
14541 set_buffer_internal_1 (old
);
14542 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14543 shorter. This can be caused by log truncation in *Messages*. */
14544 if (CHARPOS (lpoint
) <= ZV
)
14545 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
14547 unbind_to (count
, Qnil
);
14551 /* Build the complete desired matrix of WINDOW with a window start
14552 buffer position POS.
14554 Value is 1 if successful. It is zero if fonts were loaded during
14555 redisplay which makes re-adjusting glyph matrices necessary, and -1
14556 if point would appear in the scroll margins.
14557 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14558 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14562 try_window (Lisp_Object window
, struct text_pos pos
, int flags
)
14564 struct window
*w
= XWINDOW (window
);
14566 struct glyph_row
*last_text_row
= NULL
;
14567 struct frame
*f
= XFRAME (w
->frame
);
14569 /* Make POS the new window start. */
14570 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
14572 /* Mark cursor position as unknown. No overlay arrow seen. */
14573 w
->cursor
.vpos
= -1;
14574 overlay_arrow_seen
= 0;
14576 /* Initialize iterator and info to start at POS. */
14577 start_display (&it
, w
, pos
);
14579 /* Display all lines of W. */
14580 while (it
.current_y
< it
.last_visible_y
)
14582 if (display_line (&it
))
14583 last_text_row
= it
.glyph_row
- 1;
14584 if (fonts_changed_p
&& !(flags
& TRY_WINDOW_IGNORE_FONTS_CHANGE
))
14588 /* Don't let the cursor end in the scroll margins. */
14589 if ((flags
& TRY_WINDOW_CHECK_MARGINS
)
14590 && !MINI_WINDOW_P (w
))
14592 int this_scroll_margin
;
14594 if (scroll_margin
> 0)
14596 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
14597 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
14600 this_scroll_margin
= 0;
14602 if ((w
->cursor
.y
>= 0 /* not vscrolled */
14603 && w
->cursor
.y
< this_scroll_margin
14604 && CHARPOS (pos
) > BEGV
14605 && IT_CHARPOS (it
) < ZV
)
14606 /* rms: considering make_cursor_line_fully_visible_p here
14607 seems to give wrong results. We don't want to recenter
14608 when the last line is partly visible, we want to allow
14609 that case to be handled in the usual way. */
14610 || w
->cursor
.y
> it
.last_visible_y
- this_scroll_margin
- 1)
14612 w
->cursor
.vpos
= -1;
14613 clear_glyph_matrix (w
->desired_matrix
);
14618 /* If bottom moved off end of frame, change mode line percentage. */
14619 if (XFASTINT (w
->window_end_pos
) <= 0
14620 && Z
!= IT_CHARPOS (it
))
14621 w
->update_mode_line
= Qt
;
14623 /* Set window_end_pos to the offset of the last character displayed
14624 on the window from the end of current_buffer. Set
14625 window_end_vpos to its row number. */
14628 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
14629 w
->window_end_bytepos
14630 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
14632 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
14634 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
14635 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
14636 ->displays_text_p
);
14640 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
14641 w
->window_end_pos
= make_number (Z
- ZV
);
14642 w
->window_end_vpos
= make_number (0);
14645 /* But that is not valid info until redisplay finishes. */
14646 w
->window_end_valid
= Qnil
;
14652 /************************************************************************
14653 Window redisplay reusing current matrix when buffer has not changed
14654 ************************************************************************/
14656 /* Try redisplay of window W showing an unchanged buffer with a
14657 different window start than the last time it was displayed by
14658 reusing its current matrix. Value is non-zero if successful.
14659 W->start is the new window start. */
14662 try_window_reusing_current_matrix (struct window
*w
)
14664 struct frame
*f
= XFRAME (w
->frame
);
14665 struct glyph_row
*row
, *bottom_row
;
14668 struct text_pos start
, new_start
;
14669 int nrows_scrolled
, i
;
14670 struct glyph_row
*last_text_row
;
14671 struct glyph_row
*last_reused_text_row
;
14672 struct glyph_row
*start_row
;
14673 int start_vpos
, min_y
, max_y
;
14676 if (inhibit_try_window_reusing
)
14680 if (/* This function doesn't handle terminal frames. */
14681 !FRAME_WINDOW_P (f
)
14682 /* Don't try to reuse the display if windows have been split
14684 || windows_or_buffers_changed
14685 || cursor_type_changed
)
14688 /* Can't do this if region may have changed. */
14689 if ((!NILP (Vtransient_mark_mode
)
14690 && !NILP (current_buffer
->mark_active
))
14691 || !NILP (w
->region_showing
)
14692 || !NILP (Vshow_trailing_whitespace
))
14695 /* If top-line visibility has changed, give up. */
14696 if (WINDOW_WANTS_HEADER_LINE_P (w
)
14697 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
14700 /* Give up if old or new display is scrolled vertically. We could
14701 make this function handle this, but right now it doesn't. */
14702 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
14703 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
))
14706 /* The variable new_start now holds the new window start. The old
14707 start `start' can be determined from the current matrix. */
14708 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
14709 start
= start_row
->minpos
;
14710 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
14712 /* Clear the desired matrix for the display below. */
14713 clear_glyph_matrix (w
->desired_matrix
);
14715 if (CHARPOS (new_start
) <= CHARPOS (start
))
14719 /* Don't use this method if the display starts with an ellipsis
14720 displayed for invisible text. It's not easy to handle that case
14721 below, and it's certainly not worth the effort since this is
14722 not a frequent case. */
14723 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
14726 IF_DEBUG (debug_method_add (w
, "twu1"));
14728 /* Display up to a row that can be reused. The variable
14729 last_text_row is set to the last row displayed that displays
14730 text. Note that it.vpos == 0 if or if not there is a
14731 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14732 start_display (&it
, w
, new_start
);
14733 first_row_y
= it
.current_y
;
14734 w
->cursor
.vpos
= -1;
14735 last_text_row
= last_reused_text_row
= NULL
;
14737 while (it
.current_y
< it
.last_visible_y
14738 && !fonts_changed_p
)
14740 /* If we have reached into the characters in the START row,
14741 that means the line boundaries have changed. So we
14742 can't start copying with the row START. Maybe it will
14743 work to start copying with the following row. */
14744 while (IT_CHARPOS (it
) > CHARPOS (start
))
14746 /* Advance to the next row as the "start". */
14748 start
= start_row
->minpos
;
14749 /* If there are no more rows to try, or just one, give up. */
14750 if (start_row
== MATRIX_MODE_LINE_ROW (w
->current_matrix
) - 1
14751 || w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
)
14752 || CHARPOS (start
) == ZV
)
14754 clear_glyph_matrix (w
->desired_matrix
);
14758 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
14760 /* If we have reached alignment,
14761 we can copy the rest of the rows. */
14762 if (IT_CHARPOS (it
) == CHARPOS (start
))
14765 if (display_line (&it
))
14766 last_text_row
= it
.glyph_row
- 1;
14769 /* A value of current_y < last_visible_y means that we stopped
14770 at the previous window start, which in turn means that we
14771 have at least one reusable row. */
14772 if (it
.current_y
< it
.last_visible_y
)
14774 /* IT.vpos always starts from 0; it counts text lines. */
14775 nrows_scrolled
= it
.vpos
- (start_row
- MATRIX_FIRST_TEXT_ROW (w
->current_matrix
));
14777 /* Find PT if not already found in the lines displayed. */
14778 if (w
->cursor
.vpos
< 0)
14780 int dy
= it
.current_y
- start_row
->y
;
14782 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
14783 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
14785 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
14786 dy
, nrows_scrolled
);
14789 clear_glyph_matrix (w
->desired_matrix
);
14794 /* Scroll the display. Do it before the current matrix is
14795 changed. The problem here is that update has not yet
14796 run, i.e. part of the current matrix is not up to date.
14797 scroll_run_hook will clear the cursor, and use the
14798 current matrix to get the height of the row the cursor is
14800 run
.current_y
= start_row
->y
;
14801 run
.desired_y
= it
.current_y
;
14802 run
.height
= it
.last_visible_y
- it
.current_y
;
14804 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
14807 FRAME_RIF (f
)->update_window_begin_hook (w
);
14808 FRAME_RIF (f
)->clear_window_mouse_face (w
);
14809 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
14810 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
14814 /* Shift current matrix down by nrows_scrolled lines. */
14815 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
14816 rotate_matrix (w
->current_matrix
,
14818 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
14821 /* Disable lines that must be updated. */
14822 for (i
= 0; i
< nrows_scrolled
; ++i
)
14823 (start_row
+ i
)->enabled_p
= 0;
14825 /* Re-compute Y positions. */
14826 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
14827 max_y
= it
.last_visible_y
;
14828 for (row
= start_row
+ nrows_scrolled
;
14832 row
->y
= it
.current_y
;
14833 row
->visible_height
= row
->height
;
14835 if (row
->y
< min_y
)
14836 row
->visible_height
-= min_y
- row
->y
;
14837 if (row
->y
+ row
->height
> max_y
)
14838 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
14839 row
->redraw_fringe_bitmaps_p
= 1;
14841 it
.current_y
+= row
->height
;
14843 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
14844 last_reused_text_row
= row
;
14845 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
14849 /* Disable lines in the current matrix which are now
14850 below the window. */
14851 for (++row
; row
< bottom_row
; ++row
)
14852 row
->enabled_p
= row
->mode_line_p
= 0;
14855 /* Update window_end_pos etc.; last_reused_text_row is the last
14856 reused row from the current matrix containing text, if any.
14857 The value of last_text_row is the last displayed line
14858 containing text. */
14859 if (last_reused_text_row
)
14861 w
->window_end_bytepos
14862 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
14864 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
14866 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
14867 w
->current_matrix
));
14869 else if (last_text_row
)
14871 w
->window_end_bytepos
14872 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
14874 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
14876 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
14880 /* This window must be completely empty. */
14881 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
14882 w
->window_end_pos
= make_number (Z
- ZV
);
14883 w
->window_end_vpos
= make_number (0);
14885 w
->window_end_valid
= Qnil
;
14887 /* Update hint: don't try scrolling again in update_window. */
14888 w
->desired_matrix
->no_scrolling_p
= 1;
14891 debug_method_add (w
, "try_window_reusing_current_matrix 1");
14895 else if (CHARPOS (new_start
) > CHARPOS (start
))
14897 struct glyph_row
*pt_row
, *row
;
14898 struct glyph_row
*first_reusable_row
;
14899 struct glyph_row
*first_row_to_display
;
14901 int yb
= window_text_bottom_y (w
);
14903 /* Find the row starting at new_start, if there is one. Don't
14904 reuse a partially visible line at the end. */
14905 first_reusable_row
= start_row
;
14906 while (first_reusable_row
->enabled_p
14907 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
14908 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
14909 < CHARPOS (new_start
)))
14910 ++first_reusable_row
;
14912 /* Give up if there is no row to reuse. */
14913 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
14914 || !first_reusable_row
->enabled_p
14915 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
14916 != CHARPOS (new_start
)))
14919 /* We can reuse fully visible rows beginning with
14920 first_reusable_row to the end of the window. Set
14921 first_row_to_display to the first row that cannot be reused.
14922 Set pt_row to the row containing point, if there is any. */
14924 for (first_row_to_display
= first_reusable_row
;
14925 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
14926 ++first_row_to_display
)
14928 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
14929 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
14930 pt_row
= first_row_to_display
;
14933 /* Start displaying at the start of first_row_to_display. */
14934 xassert (first_row_to_display
->y
< yb
);
14935 init_to_row_start (&it
, w
, first_row_to_display
);
14937 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
14939 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
14941 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
14942 + WINDOW_HEADER_LINE_HEIGHT (w
));
14944 /* Display lines beginning with first_row_to_display in the
14945 desired matrix. Set last_text_row to the last row displayed
14946 that displays text. */
14947 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
14948 if (pt_row
== NULL
)
14949 w
->cursor
.vpos
= -1;
14950 last_text_row
= NULL
;
14951 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
14952 if (display_line (&it
))
14953 last_text_row
= it
.glyph_row
- 1;
14955 /* If point is in a reused row, adjust y and vpos of the cursor
14959 w
->cursor
.vpos
-= nrows_scrolled
;
14960 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
14963 /* Give up if point isn't in a row displayed or reused. (This
14964 also handles the case where w->cursor.vpos < nrows_scrolled
14965 after the calls to display_line, which can happen with scroll
14966 margins. See bug#1295.) */
14967 if (w
->cursor
.vpos
< 0)
14969 clear_glyph_matrix (w
->desired_matrix
);
14973 /* Scroll the display. */
14974 run
.current_y
= first_reusable_row
->y
;
14975 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
14976 run
.height
= it
.last_visible_y
- run
.current_y
;
14977 dy
= run
.current_y
- run
.desired_y
;
14982 FRAME_RIF (f
)->update_window_begin_hook (w
);
14983 FRAME_RIF (f
)->clear_window_mouse_face (w
);
14984 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
14985 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
14989 /* Adjust Y positions of reused rows. */
14990 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
14991 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
14992 max_y
= it
.last_visible_y
;
14993 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
14996 row
->visible_height
= row
->height
;
14997 if (row
->y
< min_y
)
14998 row
->visible_height
-= min_y
- row
->y
;
14999 if (row
->y
+ row
->height
> max_y
)
15000 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
15001 row
->redraw_fringe_bitmaps_p
= 1;
15004 /* Scroll the current matrix. */
15005 xassert (nrows_scrolled
> 0);
15006 rotate_matrix (w
->current_matrix
,
15008 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
15011 /* Disable rows not reused. */
15012 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
15013 row
->enabled_p
= 0;
15015 /* Point may have moved to a different line, so we cannot assume that
15016 the previous cursor position is valid; locate the correct row. */
15019 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
15020 row
< bottom_row
&& PT
>= MATRIX_ROW_END_CHARPOS (row
);
15024 w
->cursor
.y
= row
->y
;
15026 if (row
< bottom_row
)
15028 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
15029 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
15031 /* Can't use this optimization with bidi-reordered glyph
15032 rows, unless cursor is already at point. */
15033 if (!NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
))
15035 if (!(w
->cursor
.hpos
>= 0
15036 && w
->cursor
.hpos
< row
->used
[TEXT_AREA
]
15037 && BUFFERP (glyph
->object
)
15038 && glyph
->charpos
== PT
))
15043 && (!BUFFERP (glyph
->object
)
15044 || glyph
->charpos
< PT
);
15048 w
->cursor
.x
+= glyph
->pixel_width
;
15053 /* Adjust window end. A null value of last_text_row means that
15054 the window end is in reused rows which in turn means that
15055 only its vpos can have changed. */
15058 w
->window_end_bytepos
15059 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
15061 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
15063 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
15068 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
15071 w
->window_end_valid
= Qnil
;
15072 w
->desired_matrix
->no_scrolling_p
= 1;
15075 debug_method_add (w
, "try_window_reusing_current_matrix 2");
15085 /************************************************************************
15086 Window redisplay reusing current matrix when buffer has changed
15087 ************************************************************************/
15089 static struct glyph_row
*find_last_unchanged_at_beg_row (struct window
*);
15090 static struct glyph_row
*find_first_unchanged_at_end_row (struct window
*,
15092 static struct glyph_row
*
15093 find_last_row_displaying_text (struct glyph_matrix
*, struct it
*,
15094 struct glyph_row
*);
15097 /* Return the last row in MATRIX displaying text. If row START is
15098 non-null, start searching with that row. IT gives the dimensions
15099 of the display. Value is null if matrix is empty; otherwise it is
15100 a pointer to the row found. */
15102 static struct glyph_row
*
15103 find_last_row_displaying_text (struct glyph_matrix
*matrix
, struct it
*it
,
15104 struct glyph_row
*start
)
15106 struct glyph_row
*row
, *row_found
;
15108 /* Set row_found to the last row in IT->w's current matrix
15109 displaying text. The loop looks funny but think of partially
15112 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
15113 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
15115 xassert (row
->enabled_p
);
15117 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
15126 /* Return the last row in the current matrix of W that is not affected
15127 by changes at the start of current_buffer that occurred since W's
15128 current matrix was built. Value is null if no such row exists.
15130 BEG_UNCHANGED us the number of characters unchanged at the start of
15131 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15132 first changed character in current_buffer. Characters at positions <
15133 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15134 when the current matrix was built. */
15136 static struct glyph_row
*
15137 find_last_unchanged_at_beg_row (struct window
*w
)
15139 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
15140 struct glyph_row
*row
;
15141 struct glyph_row
*row_found
= NULL
;
15142 int yb
= window_text_bottom_y (w
);
15144 /* Find the last row displaying unchanged text. */
15145 for (row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
15146 MATRIX_ROW_DISPLAYS_TEXT_P (row
)
15147 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
;
15150 if (/* If row ends before first_changed_pos, it is unchanged,
15151 except in some case. */
15152 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
15153 /* When row ends in ZV and we write at ZV it is not
15155 && !row
->ends_at_zv_p
15156 /* When first_changed_pos is the end of a continued line,
15157 row is not unchanged because it may be no longer
15159 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
15160 && (row
->continued_p
15161 || row
->exact_window_width_line_p
)))
15164 /* Stop if last visible row. */
15165 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
15173 /* Find the first glyph row in the current matrix of W that is not
15174 affected by changes at the end of current_buffer since the
15175 time W's current matrix was built.
15177 Return in *DELTA the number of chars by which buffer positions in
15178 unchanged text at the end of current_buffer must be adjusted.
15180 Return in *DELTA_BYTES the corresponding number of bytes.
15182 Value is null if no such row exists, i.e. all rows are affected by
15185 static struct glyph_row
*
15186 find_first_unchanged_at_end_row (struct window
*w
, int *delta
, int *delta_bytes
)
15188 struct glyph_row
*row
;
15189 struct glyph_row
*row_found
= NULL
;
15191 *delta
= *delta_bytes
= 0;
15193 /* Display must not have been paused, otherwise the current matrix
15194 is not up to date. */
15195 eassert (!NILP (w
->window_end_valid
));
15197 /* A value of window_end_pos >= END_UNCHANGED means that the window
15198 end is in the range of changed text. If so, there is no
15199 unchanged row at the end of W's current matrix. */
15200 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
15203 /* Set row to the last row in W's current matrix displaying text. */
15204 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
15206 /* If matrix is entirely empty, no unchanged row exists. */
15207 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
15209 /* The value of row is the last glyph row in the matrix having a
15210 meaningful buffer position in it. The end position of row
15211 corresponds to window_end_pos. This allows us to translate
15212 buffer positions in the current matrix to current buffer
15213 positions for characters not in changed text. */
15214 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
15215 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
15216 int last_unchanged_pos
, last_unchanged_pos_old
;
15217 struct glyph_row
*first_text_row
15218 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
15220 *delta
= Z
- Z_old
;
15221 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
15223 /* Set last_unchanged_pos to the buffer position of the last
15224 character in the buffer that has not been changed. Z is the
15225 index + 1 of the last character in current_buffer, i.e. by
15226 subtracting END_UNCHANGED we get the index of the last
15227 unchanged character, and we have to add BEG to get its buffer
15229 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
15230 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
15232 /* Search backward from ROW for a row displaying a line that
15233 starts at a minimum position >= last_unchanged_pos_old. */
15234 for (; row
> first_text_row
; --row
)
15236 /* This used to abort, but it can happen.
15237 It is ok to just stop the search instead here. KFS. */
15238 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
15241 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
15246 eassert (!row_found
|| MATRIX_ROW_DISPLAYS_TEXT_P (row_found
));
15252 /* Make sure that glyph rows in the current matrix of window W
15253 reference the same glyph memory as corresponding rows in the
15254 frame's frame matrix. This function is called after scrolling W's
15255 current matrix on a terminal frame in try_window_id and
15256 try_window_reusing_current_matrix. */
15259 sync_frame_with_window_matrix_rows (struct window
*w
)
15261 struct frame
*f
= XFRAME (w
->frame
);
15262 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
15264 /* Preconditions: W must be a leaf window and full-width. Its frame
15265 must have a frame matrix. */
15266 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
15267 xassert (WINDOW_FULL_WIDTH_P (w
));
15268 xassert (!FRAME_WINDOW_P (f
));
15270 /* If W is a full-width window, glyph pointers in W's current matrix
15271 have, by definition, to be the same as glyph pointers in the
15272 corresponding frame matrix. Note that frame matrices have no
15273 marginal areas (see build_frame_matrix). */
15274 window_row
= w
->current_matrix
->rows
;
15275 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
15276 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
15277 while (window_row
< window_row_end
)
15279 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
15280 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
15282 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
15283 frame_row
->glyphs
[TEXT_AREA
] = start
;
15284 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
15285 frame_row
->glyphs
[LAST_AREA
] = end
;
15287 /* Disable frame rows whose corresponding window rows have
15288 been disabled in try_window_id. */
15289 if (!window_row
->enabled_p
)
15290 frame_row
->enabled_p
= 0;
15292 ++window_row
, ++frame_row
;
15297 /* Find the glyph row in window W containing CHARPOS. Consider all
15298 rows between START and END (not inclusive). END null means search
15299 all rows to the end of the display area of W. Value is the row
15300 containing CHARPOS or null. */
15303 row_containing_pos (struct window
*w
, int charpos
, struct glyph_row
*start
,
15304 struct glyph_row
*end
, int dy
)
15306 struct glyph_row
*row
= start
;
15307 struct glyph_row
*best_row
= NULL
;
15308 EMACS_INT mindif
= BUF_ZV (XBUFFER (w
->buffer
)) + 1;
15311 /* If we happen to start on a header-line, skip that. */
15312 if (row
->mode_line_p
)
15315 if ((end
&& row
>= end
) || !row
->enabled_p
)
15318 last_y
= window_text_bottom_y (w
) - dy
;
15322 /* Give up if we have gone too far. */
15323 if (end
&& row
>= end
)
15325 /* This formerly returned if they were equal.
15326 I think that both quantities are of a "last plus one" type;
15327 if so, when they are equal, the row is within the screen. -- rms. */
15328 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
15331 /* If it is in this row, return this row. */
15332 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
15333 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
15334 /* The end position of a row equals the start
15335 position of the next row. If CHARPOS is there, we
15336 would rather display it in the next line, except
15337 when this line ends in ZV. */
15338 && !row
->ends_at_zv_p
15339 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
15340 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
15344 if (NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
))
15346 /* In bidi-reordered rows, there could be several rows
15347 occluding point. We need to find the one which fits
15348 CHARPOS the best. */
15349 for (g
= row
->glyphs
[TEXT_AREA
];
15350 g
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
15353 if (!STRINGP (g
->object
))
15355 if (g
->charpos
> 0 && eabs (g
->charpos
- charpos
) < mindif
)
15357 mindif
= eabs (g
->charpos
- charpos
);
15370 /* Try to redisplay window W by reusing its existing display. W's
15371 current matrix must be up to date when this function is called,
15372 i.e. window_end_valid must not be nil.
15376 1 if display has been updated
15377 0 if otherwise unsuccessful
15378 -1 if redisplay with same window start is known not to succeed
15380 The following steps are performed:
15382 1. Find the last row in the current matrix of W that is not
15383 affected by changes at the start of current_buffer. If no such row
15386 2. Find the first row in W's current matrix that is not affected by
15387 changes at the end of current_buffer. Maybe there is no such row.
15389 3. Display lines beginning with the row + 1 found in step 1 to the
15390 row found in step 2 or, if step 2 didn't find a row, to the end of
15393 4. If cursor is not known to appear on the window, give up.
15395 5. If display stopped at the row found in step 2, scroll the
15396 display and current matrix as needed.
15398 6. Maybe display some lines at the end of W, if we must. This can
15399 happen under various circumstances, like a partially visible line
15400 becoming fully visible, or because newly displayed lines are displayed
15401 in smaller font sizes.
15403 7. Update W's window end information. */
15406 try_window_id (struct window
*w
)
15408 struct frame
*f
= XFRAME (w
->frame
);
15409 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
15410 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
15411 struct glyph_row
*last_unchanged_at_beg_row
;
15412 struct glyph_row
*first_unchanged_at_end_row
;
15413 struct glyph_row
*row
;
15414 struct glyph_row
*bottom_row
;
15417 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
15418 struct text_pos start_pos
;
15420 int first_unchanged_at_end_vpos
= 0;
15421 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
15422 struct text_pos start
;
15423 int first_changed_charpos
, last_changed_charpos
;
15426 if (inhibit_try_window_id
)
15430 /* This is handy for debugging. */
15432 #define GIVE_UP(X) \
15434 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15438 #define GIVE_UP(X) return 0
15441 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
15443 /* Don't use this for mini-windows because these can show
15444 messages and mini-buffers, and we don't handle that here. */
15445 if (MINI_WINDOW_P (w
))
15448 /* This flag is used to prevent redisplay optimizations. */
15449 if (windows_or_buffers_changed
|| cursor_type_changed
)
15452 /* Verify that narrowing has not changed.
15453 Also verify that we were not told to prevent redisplay optimizations.
15454 It would be nice to further
15455 reduce the number of cases where this prevents try_window_id. */
15456 if (current_buffer
->clip_changed
15457 || current_buffer
->prevent_redisplay_optimizations_p
)
15460 /* Window must either use window-based redisplay or be full width. */
15461 if (!FRAME_WINDOW_P (f
)
15462 && (!FRAME_LINE_INS_DEL_OK (f
)
15463 || !WINDOW_FULL_WIDTH_P (w
)))
15466 /* Give up if point is known NOT to appear in W. */
15467 if (PT
< CHARPOS (start
))
15470 /* Another way to prevent redisplay optimizations. */
15471 if (XFASTINT (w
->last_modified
) == 0)
15474 /* Verify that window is not hscrolled. */
15475 if (XFASTINT (w
->hscroll
) != 0)
15478 /* Verify that display wasn't paused. */
15479 if (NILP (w
->window_end_valid
))
15482 /* Can't use this if highlighting a region because a cursor movement
15483 will do more than just set the cursor. */
15484 if (!NILP (Vtransient_mark_mode
)
15485 && !NILP (current_buffer
->mark_active
))
15488 /* Likewise if highlighting trailing whitespace. */
15489 if (!NILP (Vshow_trailing_whitespace
))
15492 /* Likewise if showing a region. */
15493 if (!NILP (w
->region_showing
))
15496 /* Can't use this if overlay arrow position and/or string have
15498 if (overlay_arrows_changed_p ())
15501 /* When word-wrap is on, adding a space to the first word of a
15502 wrapped line can change the wrap position, altering the line
15503 above it. It might be worthwhile to handle this more
15504 intelligently, but for now just redisplay from scratch. */
15505 if (!NILP (XBUFFER (w
->buffer
)->word_wrap
))
15508 /* Under bidi reordering, adding or deleting a character in the
15509 beginning of a paragraph, before the first strong directional
15510 character, can change the base direction of the paragraph (unless
15511 the buffer specifies a fixed paragraph direction), which will
15512 require to redisplay the whole paragraph. It might be worthwhile
15513 to find the paragraph limits and widen the range of redisplayed
15514 lines to that, but for now just give up this optimization and
15515 redisplay from scratch. */
15516 if (!NILP (XBUFFER (w
->buffer
)->bidi_display_reordering
)
15517 && NILP (XBUFFER (w
->buffer
)->bidi_paragraph_direction
))
15520 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15521 only if buffer has really changed. The reason is that the gap is
15522 initially at Z for freshly visited files. The code below would
15523 set end_unchanged to 0 in that case. */
15524 if (MODIFF
> SAVE_MODIFF
15525 /* This seems to happen sometimes after saving a buffer. */
15526 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
15528 if (GPT
- BEG
< BEG_UNCHANGED
)
15529 BEG_UNCHANGED
= GPT
- BEG
;
15530 if (Z
- GPT
< END_UNCHANGED
)
15531 END_UNCHANGED
= Z
- GPT
;
15534 /* The position of the first and last character that has been changed. */
15535 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
15536 last_changed_charpos
= Z
- END_UNCHANGED
;
15538 /* If window starts after a line end, and the last change is in
15539 front of that newline, then changes don't affect the display.
15540 This case happens with stealth-fontification. Note that although
15541 the display is unchanged, glyph positions in the matrix have to
15542 be adjusted, of course. */
15543 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
15544 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
15545 && ((last_changed_charpos
< CHARPOS (start
)
15546 && CHARPOS (start
) == BEGV
)
15547 || (last_changed_charpos
< CHARPOS (start
) - 1
15548 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
15550 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
15551 struct glyph_row
*r0
;
15553 /* Compute how many chars/bytes have been added to or removed
15554 from the buffer. */
15555 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
15556 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
15558 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
15560 /* Give up if PT is not in the window. Note that it already has
15561 been checked at the start of try_window_id that PT is not in
15562 front of the window start. */
15563 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
15566 /* If window start is unchanged, we can reuse the whole matrix
15567 as is, after adjusting glyph positions. No need to compute
15568 the window end again, since its offset from Z hasn't changed. */
15569 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
15570 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
15571 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
15572 /* PT must not be in a partially visible line. */
15573 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
15574 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
15576 /* Adjust positions in the glyph matrix. */
15577 if (delta
|| delta_bytes
)
15579 struct glyph_row
*r1
15580 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
15581 increment_matrix_positions (w
->current_matrix
,
15582 MATRIX_ROW_VPOS (r0
, current_matrix
),
15583 MATRIX_ROW_VPOS (r1
, current_matrix
),
15584 delta
, delta_bytes
);
15587 /* Set the cursor. */
15588 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
15590 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
15597 /* Handle the case that changes are all below what is displayed in
15598 the window, and that PT is in the window. This shortcut cannot
15599 be taken if ZV is visible in the window, and text has been added
15600 there that is visible in the window. */
15601 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
15602 /* ZV is not visible in the window, or there are no
15603 changes at ZV, actually. */
15604 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
15605 || first_changed_charpos
== last_changed_charpos
))
15607 struct glyph_row
*r0
;
15609 /* Give up if PT is not in the window. Note that it already has
15610 been checked at the start of try_window_id that PT is not in
15611 front of the window start. */
15612 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
15615 /* If window start is unchanged, we can reuse the whole matrix
15616 as is, without changing glyph positions since no text has
15617 been added/removed in front of the window end. */
15618 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
15619 if (TEXT_POS_EQUAL_P (start
, r0
->minpos
)
15620 /* PT must not be in a partially visible line. */
15621 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
15622 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
15624 /* We have to compute the window end anew since text
15625 could have been added/removed after it. */
15627 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
15628 w
->window_end_bytepos
15629 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
15631 /* Set the cursor. */
15632 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
15634 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
15641 /* Give up if window start is in the changed area.
15643 The condition used to read
15645 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15647 but why that was tested escapes me at the moment. */
15648 if (CHARPOS (start
) >= first_changed_charpos
15649 && CHARPOS (start
) <= last_changed_charpos
)
15652 /* Check that window start agrees with the start of the first glyph
15653 row in its current matrix. Check this after we know the window
15654 start is not in changed text, otherwise positions would not be
15656 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
15657 if (!TEXT_POS_EQUAL_P (start
, row
->minpos
))
15660 /* Give up if the window ends in strings. Overlay strings
15661 at the end are difficult to handle, so don't try. */
15662 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
15663 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
15666 /* Compute the position at which we have to start displaying new
15667 lines. Some of the lines at the top of the window might be
15668 reusable because they are not displaying changed text. Find the
15669 last row in W's current matrix not affected by changes at the
15670 start of current_buffer. Value is null if changes start in the
15671 first line of window. */
15672 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
15673 if (last_unchanged_at_beg_row
)
15675 /* Avoid starting to display in the moddle of a character, a TAB
15676 for instance. This is easier than to set up the iterator
15677 exactly, and it's not a frequent case, so the additional
15678 effort wouldn't really pay off. */
15679 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
15680 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
15681 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
15682 --last_unchanged_at_beg_row
;
15684 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
15687 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
15689 start_pos
= it
.current
.pos
;
15691 /* Start displaying new lines in the desired matrix at the same
15692 vpos we would use in the current matrix, i.e. below
15693 last_unchanged_at_beg_row. */
15694 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
15696 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
15697 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
15699 xassert (it
.hpos
== 0 && it
.current_x
== 0);
15703 /* There are no reusable lines at the start of the window.
15704 Start displaying in the first text line. */
15705 start_display (&it
, w
, start
);
15706 it
.vpos
= it
.first_vpos
;
15707 start_pos
= it
.current
.pos
;
15710 /* Find the first row that is not affected by changes at the end of
15711 the buffer. Value will be null if there is no unchanged row, in
15712 which case we must redisplay to the end of the window. delta
15713 will be set to the value by which buffer positions beginning with
15714 first_unchanged_at_end_row have to be adjusted due to text
15716 first_unchanged_at_end_row
15717 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
15718 IF_DEBUG (debug_delta
= delta
);
15719 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
15721 /* Set stop_pos to the buffer position up to which we will have to
15722 display new lines. If first_unchanged_at_end_row != NULL, this
15723 is the buffer position of the start of the line displayed in that
15724 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15725 that we don't stop at a buffer position. */
15727 if (first_unchanged_at_end_row
)
15729 xassert (last_unchanged_at_beg_row
== NULL
15730 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
15732 /* If this is a continuation line, move forward to the next one
15733 that isn't. Changes in lines above affect this line.
15734 Caution: this may move first_unchanged_at_end_row to a row
15735 not displaying text. */
15736 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
15737 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
15738 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
15739 < it
.last_visible_y
))
15740 ++first_unchanged_at_end_row
;
15742 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
15743 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
15744 >= it
.last_visible_y
))
15745 first_unchanged_at_end_row
= NULL
;
15748 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
15750 first_unchanged_at_end_vpos
15751 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
15752 xassert (stop_pos
>= Z
- END_UNCHANGED
);
15755 else if (last_unchanged_at_beg_row
== NULL
)
15761 /* Either there is no unchanged row at the end, or the one we have
15762 now displays text. This is a necessary condition for the window
15763 end pos calculation at the end of this function. */
15764 xassert (first_unchanged_at_end_row
== NULL
15765 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
15767 debug_last_unchanged_at_beg_vpos
15768 = (last_unchanged_at_beg_row
15769 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
15771 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
15773 #endif /* GLYPH_DEBUG != 0 */
15776 /* Display new lines. Set last_text_row to the last new line
15777 displayed which has text on it, i.e. might end up as being the
15778 line where the window_end_vpos is. */
15779 w
->cursor
.vpos
= -1;
15780 last_text_row
= NULL
;
15781 overlay_arrow_seen
= 0;
15782 while (it
.current_y
< it
.last_visible_y
15783 && !fonts_changed_p
15784 && (first_unchanged_at_end_row
== NULL
15785 || IT_CHARPOS (it
) < stop_pos
))
15787 if (display_line (&it
))
15788 last_text_row
= it
.glyph_row
- 1;
15791 if (fonts_changed_p
)
15795 /* Compute differences in buffer positions, y-positions etc. for
15796 lines reused at the bottom of the window. Compute what we can
15798 if (first_unchanged_at_end_row
15799 /* No lines reused because we displayed everything up to the
15800 bottom of the window. */
15801 && it
.current_y
< it
.last_visible_y
)
15804 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
15806 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
15807 run
.current_y
= first_unchanged_at_end_row
->y
;
15808 run
.desired_y
= run
.current_y
+ dy
;
15809 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
15813 delta
= delta_bytes
= dvpos
= dy
15814 = run
.current_y
= run
.desired_y
= run
.height
= 0;
15815 first_unchanged_at_end_row
= NULL
;
15817 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
15820 /* Find the cursor if not already found. We have to decide whether
15821 PT will appear on this window (it sometimes doesn't, but this is
15822 not a very frequent case.) This decision has to be made before
15823 the current matrix is altered. A value of cursor.vpos < 0 means
15824 that PT is either in one of the lines beginning at
15825 first_unchanged_at_end_row or below the window. Don't care for
15826 lines that might be displayed later at the window end; as
15827 mentioned, this is not a frequent case. */
15828 if (w
->cursor
.vpos
< 0)
15830 /* Cursor in unchanged rows at the top? */
15831 if (PT
< CHARPOS (start_pos
)
15832 && last_unchanged_at_beg_row
)
15834 row
= row_containing_pos (w
, PT
,
15835 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
15836 last_unchanged_at_beg_row
+ 1, 0);
15838 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
15841 /* Start from first_unchanged_at_end_row looking for PT. */
15842 else if (first_unchanged_at_end_row
)
15844 row
= row_containing_pos (w
, PT
- delta
,
15845 first_unchanged_at_end_row
, NULL
, 0);
15847 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
15848 delta_bytes
, dy
, dvpos
);
15851 /* Give up if cursor was not found. */
15852 if (w
->cursor
.vpos
< 0)
15854 clear_glyph_matrix (w
->desired_matrix
);
15859 /* Don't let the cursor end in the scroll margins. */
15861 int this_scroll_margin
, cursor_height
;
15863 this_scroll_margin
= max (0, scroll_margin
);
15864 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
15865 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
15866 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
15868 if ((w
->cursor
.y
< this_scroll_margin
15869 && CHARPOS (start
) > BEGV
)
15870 /* Old redisplay didn't take scroll margin into account at the bottom,
15871 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15872 || (w
->cursor
.y
+ (make_cursor_line_fully_visible_p
15873 ? cursor_height
+ this_scroll_margin
15874 : 1)) > it
.last_visible_y
)
15876 w
->cursor
.vpos
= -1;
15877 clear_glyph_matrix (w
->desired_matrix
);
15882 /* Scroll the display. Do it before changing the current matrix so
15883 that xterm.c doesn't get confused about where the cursor glyph is
15885 if (dy
&& run
.height
)
15889 if (FRAME_WINDOW_P (f
))
15891 FRAME_RIF (f
)->update_window_begin_hook (w
);
15892 FRAME_RIF (f
)->clear_window_mouse_face (w
);
15893 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
15894 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
15898 /* Terminal frame. In this case, dvpos gives the number of
15899 lines to scroll by; dvpos < 0 means scroll up. */
15900 int first_unchanged_at_end_vpos
15901 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
15902 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
15903 int end
= (WINDOW_TOP_EDGE_LINE (w
)
15904 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
15905 + window_internal_height (w
));
15907 /* Perform the operation on the screen. */
15910 /* Scroll last_unchanged_at_beg_row to the end of the
15911 window down dvpos lines. */
15912 set_terminal_window (f
, end
);
15914 /* On dumb terminals delete dvpos lines at the end
15915 before inserting dvpos empty lines. */
15916 if (!FRAME_SCROLL_REGION_OK (f
))
15917 ins_del_lines (f
, end
- dvpos
, -dvpos
);
15919 /* Insert dvpos empty lines in front of
15920 last_unchanged_at_beg_row. */
15921 ins_del_lines (f
, from
, dvpos
);
15923 else if (dvpos
< 0)
15925 /* Scroll up last_unchanged_at_beg_vpos to the end of
15926 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15927 set_terminal_window (f
, end
);
15929 /* Delete dvpos lines in front of
15930 last_unchanged_at_beg_vpos. ins_del_lines will set
15931 the cursor to the given vpos and emit |dvpos| delete
15933 ins_del_lines (f
, from
+ dvpos
, dvpos
);
15935 /* On a dumb terminal insert dvpos empty lines at the
15937 if (!FRAME_SCROLL_REGION_OK (f
))
15938 ins_del_lines (f
, end
+ dvpos
, -dvpos
);
15941 set_terminal_window (f
, 0);
15947 /* Shift reused rows of the current matrix to the right position.
15948 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15950 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
15951 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
15954 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
15955 bottom_vpos
, dvpos
);
15956 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
15959 else if (dvpos
> 0)
15961 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
15962 bottom_vpos
, dvpos
);
15963 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
15964 first_unchanged_at_end_vpos
+ dvpos
, 0);
15967 /* For frame-based redisplay, make sure that current frame and window
15968 matrix are in sync with respect to glyph memory. */
15969 if (!FRAME_WINDOW_P (f
))
15970 sync_frame_with_window_matrix_rows (w
);
15972 /* Adjust buffer positions in reused rows. */
15973 if (delta
|| delta_bytes
)
15974 increment_matrix_positions (current_matrix
,
15975 first_unchanged_at_end_vpos
+ dvpos
,
15976 bottom_vpos
, delta
, delta_bytes
);
15978 /* Adjust Y positions. */
15980 shift_glyph_matrix (w
, current_matrix
,
15981 first_unchanged_at_end_vpos
+ dvpos
,
15984 if (first_unchanged_at_end_row
)
15986 first_unchanged_at_end_row
+= dvpos
;
15987 if (first_unchanged_at_end_row
->y
>= it
.last_visible_y
15988 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
))
15989 first_unchanged_at_end_row
= NULL
;
15992 /* If scrolling up, there may be some lines to display at the end of
15994 last_text_row_at_end
= NULL
;
15997 /* Scrolling up can leave for example a partially visible line
15998 at the end of the window to be redisplayed. */
15999 /* Set last_row to the glyph row in the current matrix where the
16000 window end line is found. It has been moved up or down in
16001 the matrix by dvpos. */
16002 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
16003 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
16005 /* If last_row is the window end line, it should display text. */
16006 xassert (last_row
->displays_text_p
);
16008 /* If window end line was partially visible before, begin
16009 displaying at that line. Otherwise begin displaying with the
16010 line following it. */
16011 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
16013 init_to_row_start (&it
, w
, last_row
);
16014 it
.vpos
= last_vpos
;
16015 it
.current_y
= last_row
->y
;
16019 init_to_row_end (&it
, w
, last_row
);
16020 it
.vpos
= 1 + last_vpos
;
16021 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
16025 /* We may start in a continuation line. If so, we have to
16026 get the right continuation_lines_width and current_x. */
16027 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
16028 it
.hpos
= it
.current_x
= 0;
16030 /* Display the rest of the lines at the window end. */
16031 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
16032 while (it
.current_y
< it
.last_visible_y
16033 && !fonts_changed_p
)
16035 /* Is it always sure that the display agrees with lines in
16036 the current matrix? I don't think so, so we mark rows
16037 displayed invalid in the current matrix by setting their
16038 enabled_p flag to zero. */
16039 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
16040 if (display_line (&it
))
16041 last_text_row_at_end
= it
.glyph_row
- 1;
16045 /* Update window_end_pos and window_end_vpos. */
16046 if (first_unchanged_at_end_row
16047 && !last_text_row_at_end
)
16049 /* Window end line if one of the preserved rows from the current
16050 matrix. Set row to the last row displaying text in current
16051 matrix starting at first_unchanged_at_end_row, after
16053 xassert (first_unchanged_at_end_row
->displays_text_p
);
16054 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
16055 first_unchanged_at_end_row
);
16056 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
16058 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
16059 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
16061 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
16062 xassert (w
->window_end_bytepos
>= 0);
16063 IF_DEBUG (debug_method_add (w
, "A"));
16065 else if (last_text_row_at_end
)
16068 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
16069 w
->window_end_bytepos
16070 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
16072 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
16073 xassert (w
->window_end_bytepos
>= 0);
16074 IF_DEBUG (debug_method_add (w
, "B"));
16076 else if (last_text_row
)
16078 /* We have displayed either to the end of the window or at the
16079 end of the window, i.e. the last row with text is to be found
16080 in the desired matrix. */
16082 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
16083 w
->window_end_bytepos
16084 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
16086 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
16087 xassert (w
->window_end_bytepos
>= 0);
16089 else if (first_unchanged_at_end_row
== NULL
16090 && last_text_row
== NULL
16091 && last_text_row_at_end
== NULL
)
16093 /* Displayed to end of window, but no line containing text was
16094 displayed. Lines were deleted at the end of the window. */
16095 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
16096 int vpos
= XFASTINT (w
->window_end_vpos
);
16097 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
16098 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
16101 row
== NULL
&& vpos
>= first_vpos
;
16102 --vpos
, --current_row
, --desired_row
)
16104 if (desired_row
->enabled_p
)
16106 if (desired_row
->displays_text_p
)
16109 else if (current_row
->displays_text_p
)
16113 xassert (row
!= NULL
);
16114 w
->window_end_vpos
= make_number (vpos
+ 1);
16115 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
16116 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
16117 xassert (w
->window_end_bytepos
>= 0);
16118 IF_DEBUG (debug_method_add (w
, "C"));
16123 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
16124 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
16126 /* Record that display has not been completed. */
16127 w
->window_end_valid
= Qnil
;
16128 w
->desired_matrix
->no_scrolling_p
= 1;
16136 /***********************************************************************
16137 More debugging support
16138 ***********************************************************************/
16142 void dump_glyph_row (struct glyph_row
*, int, int);
16143 void dump_glyph_matrix (struct glyph_matrix
*, int);
16144 void dump_glyph (struct glyph_row
*, struct glyph
*, int);
16147 /* Dump the contents of glyph matrix MATRIX on stderr.
16149 GLYPHS 0 means don't show glyph contents.
16150 GLYPHS 1 means show glyphs in short form
16151 GLYPHS > 1 means show glyphs in long form. */
16154 dump_glyph_matrix (matrix
, glyphs
)
16155 struct glyph_matrix
*matrix
;
16159 for (i
= 0; i
< matrix
->nrows
; ++i
)
16160 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
16164 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16165 the glyph row and area where the glyph comes from. */
16168 dump_glyph (row
, glyph
, area
)
16169 struct glyph_row
*row
;
16170 struct glyph
*glyph
;
16173 if (glyph
->type
== CHAR_GLYPH
)
16176 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16177 glyph
- row
->glyphs
[TEXT_AREA
],
16180 (BUFFERP (glyph
->object
)
16182 : (STRINGP (glyph
->object
)
16185 glyph
->pixel_width
,
16187 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
16191 glyph
->left_box_line_p
,
16192 glyph
->right_box_line_p
);
16194 else if (glyph
->type
== STRETCH_GLYPH
)
16197 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16198 glyph
- row
->glyphs
[TEXT_AREA
],
16201 (BUFFERP (glyph
->object
)
16203 : (STRINGP (glyph
->object
)
16206 glyph
->pixel_width
,
16210 glyph
->left_box_line_p
,
16211 glyph
->right_box_line_p
);
16213 else if (glyph
->type
== IMAGE_GLYPH
)
16216 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16217 glyph
- row
->glyphs
[TEXT_AREA
],
16220 (BUFFERP (glyph
->object
)
16222 : (STRINGP (glyph
->object
)
16225 glyph
->pixel_width
,
16229 glyph
->left_box_line_p
,
16230 glyph
->right_box_line_p
);
16232 else if (glyph
->type
== COMPOSITE_GLYPH
)
16235 " %5d %4c %6d %c %3d 0x%05x",
16236 glyph
- row
->glyphs
[TEXT_AREA
],
16239 (BUFFERP (glyph
->object
)
16241 : (STRINGP (glyph
->object
)
16244 glyph
->pixel_width
,
16246 if (glyph
->u
.cmp
.automatic
)
16249 glyph
->u
.cmp
.from
, glyph
->u
.cmp
.to
);
16250 fprintf (stderr
, " . %4d %1.1d%1.1d\n",
16252 glyph
->left_box_line_p
,
16253 glyph
->right_box_line_p
);
16258 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16259 GLYPHS 0 means don't show glyph contents.
16260 GLYPHS 1 means show glyphs in short form
16261 GLYPHS > 1 means show glyphs in long form. */
16264 dump_glyph_row (row
, vpos
, glyphs
)
16265 struct glyph_row
*row
;
16270 fprintf (stderr
, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16271 fprintf (stderr
, "======================================================================\n");
16273 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16274 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16276 MATRIX_ROW_START_CHARPOS (row
),
16277 MATRIX_ROW_END_CHARPOS (row
),
16278 row
->used
[TEXT_AREA
],
16279 row
->contains_overlapping_glyphs_p
,
16281 row
->truncated_on_left_p
,
16282 row
->truncated_on_right_p
,
16284 MATRIX_ROW_CONTINUATION_LINE_P (row
),
16285 row
->displays_text_p
,
16288 row
->ends_in_middle_of_char_p
,
16289 row
->starts_in_middle_of_char_p
,
16295 row
->visible_height
,
16298 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
16299 row
->end
.overlay_string_index
,
16300 row
->continuation_lines_width
);
16301 fprintf (stderr
, "%9d %5d\n",
16302 CHARPOS (row
->start
.string_pos
),
16303 CHARPOS (row
->end
.string_pos
));
16304 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
16305 row
->end
.dpvec_index
);
16312 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
16314 struct glyph
*glyph
= row
->glyphs
[area
];
16315 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
16317 /* Glyph for a line end in text. */
16318 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
16321 if (glyph
< glyph_end
)
16322 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
16324 for (; glyph
< glyph_end
; ++glyph
)
16325 dump_glyph (row
, glyph
, area
);
16328 else if (glyphs
== 1)
16332 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
16334 char *s
= (char *) alloca (row
->used
[area
] + 1);
16337 for (i
= 0; i
< row
->used
[area
]; ++i
)
16339 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
16340 if (glyph
->type
== CHAR_GLYPH
16341 && glyph
->u
.ch
< 0x80
16342 && glyph
->u
.ch
>= ' ')
16343 s
[i
] = glyph
->u
.ch
;
16349 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
16355 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
16356 Sdump_glyph_matrix
, 0, 1, "p",
16357 doc
: /* Dump the current matrix of the selected window to stderr.
16358 Shows contents of glyph row structures. With non-nil
16359 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16360 glyphs in short form, otherwise show glyphs in long form. */)
16361 (Lisp_Object glyphs
)
16363 struct window
*w
= XWINDOW (selected_window
);
16364 struct buffer
*buffer
= XBUFFER (w
->buffer
);
16366 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
16367 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
16368 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16369 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
16370 fprintf (stderr
, "=============================================\n");
16371 dump_glyph_matrix (w
->current_matrix
,
16372 NILP (glyphs
) ? 0 : XINT (glyphs
));
16377 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
16378 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
16381 struct frame
*f
= XFRAME (selected_frame
);
16382 dump_glyph_matrix (f
->current_matrix
, 1);
16387 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
16388 doc
: /* Dump glyph row ROW to stderr.
16389 GLYPH 0 means don't dump glyphs.
16390 GLYPH 1 means dump glyphs in short form.
16391 GLYPH > 1 or omitted means dump glyphs in long form. */)
16392 (Lisp_Object row
, Lisp_Object glyphs
)
16394 struct glyph_matrix
*matrix
;
16397 CHECK_NUMBER (row
);
16398 matrix
= XWINDOW (selected_window
)->current_matrix
;
16400 if (vpos
>= 0 && vpos
< matrix
->nrows
)
16401 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
16403 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
16408 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
16409 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16410 GLYPH 0 means don't dump glyphs.
16411 GLYPH 1 means dump glyphs in short form.
16412 GLYPH > 1 or omitted means dump glyphs in long form. */)
16413 (Lisp_Object row
, Lisp_Object glyphs
)
16415 struct frame
*sf
= SELECTED_FRAME ();
16416 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
16419 CHECK_NUMBER (row
);
16421 if (vpos
>= 0 && vpos
< m
->nrows
)
16422 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
16423 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
16428 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
16429 doc
: /* Toggle tracing of redisplay.
16430 With ARG, turn tracing on if and only if ARG is positive. */)
16434 trace_redisplay_p
= !trace_redisplay_p
;
16437 arg
= Fprefix_numeric_value (arg
);
16438 trace_redisplay_p
= XINT (arg
) > 0;
16445 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
16446 doc
: /* Like `format', but print result to stderr.
16447 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16448 (int nargs
, Lisp_Object
*args
)
16450 Lisp_Object s
= Fformat (nargs
, args
);
16451 fprintf (stderr
, "%s", SDATA (s
));
16455 #endif /* GLYPH_DEBUG */
16459 /***********************************************************************
16460 Building Desired Matrix Rows
16461 ***********************************************************************/
16463 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16464 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16466 static struct glyph_row
*
16467 get_overlay_arrow_glyph_row (struct window
*w
, Lisp_Object overlay_arrow_string
)
16469 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
16470 struct buffer
*buffer
= XBUFFER (w
->buffer
);
16471 struct buffer
*old
= current_buffer
;
16472 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
16473 int arrow_len
= SCHARS (overlay_arrow_string
);
16474 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
16475 const unsigned char *p
;
16478 int n_glyphs_before
;
16480 set_buffer_temp (buffer
);
16481 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
16482 it
.glyph_row
->used
[TEXT_AREA
] = 0;
16483 SET_TEXT_POS (it
.position
, 0, 0);
16485 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
16487 while (p
< arrow_end
)
16489 Lisp_Object face
, ilisp
;
16491 /* Get the next character. */
16493 it
.c
= string_char_and_length (p
, &it
.len
);
16495 it
.c
= *p
, it
.len
= 1;
16498 /* Get its face. */
16499 ilisp
= make_number (p
- arrow_string
);
16500 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
16501 it
.face_id
= compute_char_face (f
, it
.c
, face
);
16503 /* Compute its width, get its glyphs. */
16504 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
16505 SET_TEXT_POS (it
.position
, -1, -1);
16506 PRODUCE_GLYPHS (&it
);
16508 /* If this character doesn't fit any more in the line, we have
16509 to remove some glyphs. */
16510 if (it
.current_x
> it
.last_visible_x
)
16512 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
16517 set_buffer_temp (old
);
16518 return it
.glyph_row
;
16522 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16523 glyphs are only inserted for terminal frames since we can't really
16524 win with truncation glyphs when partially visible glyphs are
16525 involved. Which glyphs to insert is determined by
16526 produce_special_glyphs. */
16529 insert_left_trunc_glyphs (struct it
*it
)
16531 struct it truncate_it
;
16532 struct glyph
*from
, *end
, *to
, *toend
;
16534 xassert (!FRAME_WINDOW_P (it
->f
));
16536 /* Get the truncation glyphs. */
16538 truncate_it
.current_x
= 0;
16539 truncate_it
.face_id
= DEFAULT_FACE_ID
;
16540 truncate_it
.glyph_row
= &scratch_glyph_row
;
16541 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
16542 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
16543 truncate_it
.object
= make_number (0);
16544 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
16546 /* Overwrite glyphs from IT with truncation glyphs. */
16547 if (!it
->glyph_row
->reversed_p
)
16549 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
16550 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
16551 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
16552 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
16557 /* There may be padding glyphs left over. Overwrite them too. */
16558 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
16560 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
16566 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
16570 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16571 that back to front. */
16572 end
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
16573 from
= end
+ truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
16574 toend
= it
->glyph_row
->glyphs
[TEXT_AREA
];
16575 to
= toend
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
16577 while (from
>= end
&& to
>= toend
)
16579 while (to
>= toend
&& CHAR_GLYPH_PADDING_P (*to
))
16582 truncate_it
.glyph_row
->glyphs
[TEXT_AREA
]
16583 + truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
16584 while (from
>= end
&& to
>= toend
)
16589 /* Need to free some room before prepending additional
16591 int move_by
= from
- end
+ 1;
16592 struct glyph
*g0
= it
->glyph_row
->glyphs
[TEXT_AREA
];
16593 struct glyph
*g
= g0
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
16595 for ( ; g
>= g0
; g
--)
16597 while (from
>= end
)
16599 it
->glyph_row
->used
[TEXT_AREA
] += move_by
;
16605 /* Compute the pixel height and width of IT->glyph_row.
16607 Most of the time, ascent and height of a display line will be equal
16608 to the max_ascent and max_height values of the display iterator
16609 structure. This is not the case if
16611 1. We hit ZV without displaying anything. In this case, max_ascent
16612 and max_height will be zero.
16614 2. We have some glyphs that don't contribute to the line height.
16615 (The glyph row flag contributes_to_line_height_p is for future
16616 pixmap extensions).
16618 The first case is easily covered by using default values because in
16619 these cases, the line height does not really matter, except that it
16620 must not be zero. */
16623 compute_line_metrics (struct it
*it
)
16625 struct glyph_row
*row
= it
->glyph_row
;
16628 if (FRAME_WINDOW_P (it
->f
))
16630 int i
, min_y
, max_y
;
16632 /* The line may consist of one space only, that was added to
16633 place the cursor on it. If so, the row's height hasn't been
16635 if (row
->height
== 0)
16637 if (it
->max_ascent
+ it
->max_descent
== 0)
16638 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
16639 row
->ascent
= it
->max_ascent
;
16640 row
->height
= it
->max_ascent
+ it
->max_descent
;
16641 row
->phys_ascent
= it
->max_phys_ascent
;
16642 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
16643 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
16646 /* Compute the width of this line. */
16647 row
->pixel_width
= row
->x
;
16648 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
16649 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
16651 xassert (row
->pixel_width
>= 0);
16652 xassert (row
->ascent
>= 0 && row
->height
> 0);
16654 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
16655 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
16657 /* If first line's physical ascent is larger than its logical
16658 ascent, use the physical ascent, and make the row taller.
16659 This makes accented characters fully visible. */
16660 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
16661 && row
->phys_ascent
> row
->ascent
)
16663 row
->height
+= row
->phys_ascent
- row
->ascent
;
16664 row
->ascent
= row
->phys_ascent
;
16667 /* Compute how much of the line is visible. */
16668 row
->visible_height
= row
->height
;
16670 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
16671 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
16673 if (row
->y
< min_y
)
16674 row
->visible_height
-= min_y
- row
->y
;
16675 if (row
->y
+ row
->height
> max_y
)
16676 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
16680 row
->pixel_width
= row
->used
[TEXT_AREA
];
16681 if (row
->continued_p
)
16682 row
->pixel_width
-= it
->continuation_pixel_width
;
16683 else if (row
->truncated_on_right_p
)
16684 row
->pixel_width
-= it
->truncation_pixel_width
;
16685 row
->ascent
= row
->phys_ascent
= 0;
16686 row
->height
= row
->phys_height
= row
->visible_height
= 1;
16687 row
->extra_line_spacing
= 0;
16690 /* Compute a hash code for this row. */
16692 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
16693 for (i
= 0; i
< row
->used
[area
]; ++i
)
16694 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
16695 + row
->glyphs
[area
][i
].u
.val
16696 + row
->glyphs
[area
][i
].face_id
16697 + row
->glyphs
[area
][i
].padding_p
16698 + (row
->glyphs
[area
][i
].type
<< 2));
16700 it
->max_ascent
= it
->max_descent
= 0;
16701 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
16705 /* Append one space to the glyph row of iterator IT if doing a
16706 window-based redisplay. The space has the same face as
16707 IT->face_id. Value is non-zero if a space was added.
16709 This function is called to make sure that there is always one glyph
16710 at the end of a glyph row that the cursor can be set on under
16711 window-systems. (If there weren't such a glyph we would not know
16712 how wide and tall a box cursor should be displayed).
16714 At the same time this space let's a nicely handle clearing to the
16715 end of the line if the row ends in italic text. */
16718 append_space_for_newline (struct it
*it
, int default_face_p
)
16720 if (FRAME_WINDOW_P (it
->f
))
16722 int n
= it
->glyph_row
->used
[TEXT_AREA
];
16724 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
16725 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
16727 /* Save some values that must not be changed.
16728 Must save IT->c and IT->len because otherwise
16729 ITERATOR_AT_END_P wouldn't work anymore after
16730 append_space_for_newline has been called. */
16731 enum display_element_type saved_what
= it
->what
;
16732 int saved_c
= it
->c
, saved_len
= it
->len
;
16733 int saved_x
= it
->current_x
;
16734 int saved_face_id
= it
->face_id
;
16735 struct text_pos saved_pos
;
16736 Lisp_Object saved_object
;
16739 saved_object
= it
->object
;
16740 saved_pos
= it
->position
;
16742 it
->what
= IT_CHARACTER
;
16743 memset (&it
->position
, 0, sizeof it
->position
);
16744 it
->object
= make_number (0);
16748 if (default_face_p
)
16749 it
->face_id
= DEFAULT_FACE_ID
;
16750 else if (it
->face_before_selective_p
)
16751 it
->face_id
= it
->saved_face_id
;
16752 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
16753 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0, -1, Qnil
);
16755 PRODUCE_GLYPHS (it
);
16757 it
->override_ascent
= -1;
16758 it
->constrain_row_ascent_descent_p
= 0;
16759 it
->current_x
= saved_x
;
16760 it
->object
= saved_object
;
16761 it
->position
= saved_pos
;
16762 it
->what
= saved_what
;
16763 it
->face_id
= saved_face_id
;
16764 it
->len
= saved_len
;
16774 /* Extend the face of the last glyph in the text area of IT->glyph_row
16775 to the end of the display line. Called from display_line. If the
16776 glyph row is empty, add a space glyph to it so that we know the
16777 face to draw. Set the glyph row flag fill_line_p. If the glyph
16778 row is R2L, prepend a stretch glyph to cover the empty space to the
16779 left of the leftmost glyph. */
16782 extend_face_to_end_of_line (struct it
*it
)
16785 struct frame
*f
= it
->f
;
16787 /* If line is already filled, do nothing. Non window-system frames
16788 get a grace of one more ``pixel'' because their characters are
16789 1-``pixel'' wide, so they hit the equality too early. This grace
16790 is needed only for R2L rows that are not continued, to produce
16791 one extra blank where we could display the cursor. */
16792 if (it
->current_x
>= it
->last_visible_x
16793 + (!FRAME_WINDOW_P (f
)
16794 && it
->glyph_row
->reversed_p
16795 && !it
->glyph_row
->continued_p
))
16798 /* Face extension extends the background and box of IT->face_id
16799 to the end of the line. If the background equals the background
16800 of the frame, we don't have to do anything. */
16801 if (it
->face_before_selective_p
)
16802 face
= FACE_FROM_ID (f
, it
->saved_face_id
);
16804 face
= FACE_FROM_ID (f
, it
->face_id
);
16806 if (FRAME_WINDOW_P (f
)
16807 && it
->glyph_row
->displays_text_p
16808 && face
->box
== FACE_NO_BOX
16809 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
16811 && !it
->glyph_row
->reversed_p
)
16814 /* Set the glyph row flag indicating that the face of the last glyph
16815 in the text area has to be drawn to the end of the text area. */
16816 it
->glyph_row
->fill_line_p
= 1;
16818 /* If current character of IT is not ASCII, make sure we have the
16819 ASCII face. This will be automatically undone the next time
16820 get_next_display_element returns a multibyte character. Note
16821 that the character will always be single byte in unibyte
16823 if (!ASCII_CHAR_P (it
->c
))
16825 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0, -1, Qnil
);
16828 if (FRAME_WINDOW_P (f
))
16830 /* If the row is empty, add a space with the current face of IT,
16831 so that we know which face to draw. */
16832 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
16834 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
16835 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
16836 it
->glyph_row
->used
[TEXT_AREA
] = 1;
16838 #ifdef HAVE_WINDOW_SYSTEM
16839 if (it
->glyph_row
->reversed_p
)
16841 /* Prepend a stretch glyph to the row, such that the
16842 rightmost glyph will be drawn flushed all the way to the
16843 right margin of the window. The stretch glyph that will
16844 occupy the empty space, if any, to the left of the
16846 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (f
);
16847 struct glyph
*row_start
= it
->glyph_row
->glyphs
[TEXT_AREA
];
16848 struct glyph
*row_end
= row_start
+ it
->glyph_row
->used
[TEXT_AREA
];
16850 int row_width
, stretch_ascent
, stretch_width
;
16851 struct text_pos saved_pos
;
16852 int saved_face_id
, saved_avoid_cursor
;
16854 for (row_width
= 0, g
= row_start
; g
< row_end
; g
++)
16855 row_width
+= g
->pixel_width
;
16856 stretch_width
= window_box_width (it
->w
, TEXT_AREA
) - row_width
;
16857 if (stretch_width
> 0)
16860 (((it
->ascent
+ it
->descent
)
16861 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
16862 saved_pos
= it
->position
;
16863 memset (&it
->position
, 0, sizeof it
->position
);
16864 saved_avoid_cursor
= it
->avoid_cursor_p
;
16865 it
->avoid_cursor_p
= 1;
16866 saved_face_id
= it
->face_id
;
16867 /* The last row's stretch glyph should get the default
16868 face, to avoid painting the rest of the window with
16869 the region face, if the region ends at ZV. */
16870 if (it
->glyph_row
->ends_at_zv_p
)
16871 it
->face_id
= DEFAULT_FACE_ID
;
16873 it
->face_id
= face
->id
;
16874 append_stretch_glyph (it
, make_number (0), stretch_width
,
16875 it
->ascent
+ it
->descent
, stretch_ascent
);
16876 it
->position
= saved_pos
;
16877 it
->avoid_cursor_p
= saved_avoid_cursor
;
16878 it
->face_id
= saved_face_id
;
16881 #endif /* HAVE_WINDOW_SYSTEM */
16885 /* Save some values that must not be changed. */
16886 int saved_x
= it
->current_x
;
16887 struct text_pos saved_pos
;
16888 Lisp_Object saved_object
;
16889 enum display_element_type saved_what
= it
->what
;
16890 int saved_face_id
= it
->face_id
;
16892 saved_object
= it
->object
;
16893 saved_pos
= it
->position
;
16895 it
->what
= IT_CHARACTER
;
16896 memset (&it
->position
, 0, sizeof it
->position
);
16897 it
->object
= make_number (0);
16900 /* The last row's blank glyphs should get the default face, to
16901 avoid painting the rest of the window with the region face,
16902 if the region ends at ZV. */
16903 if (it
->glyph_row
->ends_at_zv_p
)
16904 it
->face_id
= DEFAULT_FACE_ID
;
16906 it
->face_id
= face
->id
;
16908 PRODUCE_GLYPHS (it
);
16910 while (it
->current_x
<= it
->last_visible_x
)
16911 PRODUCE_GLYPHS (it
);
16913 /* Don't count these blanks really. It would let us insert a left
16914 truncation glyph below and make us set the cursor on them, maybe. */
16915 it
->current_x
= saved_x
;
16916 it
->object
= saved_object
;
16917 it
->position
= saved_pos
;
16918 it
->what
= saved_what
;
16919 it
->face_id
= saved_face_id
;
16924 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16925 trailing whitespace. */
16928 trailing_whitespace_p (int charpos
)
16930 int bytepos
= CHAR_TO_BYTE (charpos
);
16933 while (bytepos
< ZV_BYTE
16934 && (c
= FETCH_CHAR (bytepos
),
16935 c
== ' ' || c
== '\t'))
16938 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
16940 if (bytepos
!= PT_BYTE
)
16947 /* Highlight trailing whitespace, if any, in ROW. */
16950 highlight_trailing_whitespace (struct frame
*f
, struct glyph_row
*row
)
16952 int used
= row
->used
[TEXT_AREA
];
16956 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
16957 struct glyph
*glyph
= start
+ used
- 1;
16959 if (row
->reversed_p
)
16961 /* Right-to-left rows need to be processed in the opposite
16962 direction, so swap the edge pointers. */
16964 start
= row
->glyphs
[TEXT_AREA
] + used
- 1;
16967 /* Skip over glyphs inserted to display the cursor at the
16968 end of a line, for extending the face of the last glyph
16969 to the end of the line on terminals, and for truncation
16970 and continuation glyphs. */
16971 if (!row
->reversed_p
)
16973 while (glyph
>= start
16974 && glyph
->type
== CHAR_GLYPH
16975 && INTEGERP (glyph
->object
))
16980 while (glyph
<= start
16981 && glyph
->type
== CHAR_GLYPH
16982 && INTEGERP (glyph
->object
))
16986 /* If last glyph is a space or stretch, and it's trailing
16987 whitespace, set the face of all trailing whitespace glyphs in
16988 IT->glyph_row to `trailing-whitespace'. */
16989 if ((row
->reversed_p
? glyph
<= start
: glyph
>= start
)
16990 && BUFFERP (glyph
->object
)
16991 && (glyph
->type
== STRETCH_GLYPH
16992 || (glyph
->type
== CHAR_GLYPH
16993 && glyph
->u
.ch
== ' '))
16994 && trailing_whitespace_p (glyph
->charpos
))
16996 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
17000 if (!row
->reversed_p
)
17002 while (glyph
>= start
17003 && BUFFERP (glyph
->object
)
17004 && (glyph
->type
== STRETCH_GLYPH
17005 || (glyph
->type
== CHAR_GLYPH
17006 && glyph
->u
.ch
== ' ')))
17007 (glyph
--)->face_id
= face_id
;
17011 while (glyph
<= start
17012 && BUFFERP (glyph
->object
)
17013 && (glyph
->type
== STRETCH_GLYPH
17014 || (glyph
->type
== CHAR_GLYPH
17015 && glyph
->u
.ch
== ' ')))
17016 (glyph
++)->face_id
= face_id
;
17023 /* Value is non-zero if glyph row ROW in window W should be
17024 used to hold the cursor. */
17027 cursor_row_p (struct window
*w
, struct glyph_row
*row
)
17029 int cursor_row_p
= 1;
17031 if (PT
== CHARPOS (row
->end
.pos
))
17033 /* Suppose the row ends on a string.
17034 Unless the row is continued, that means it ends on a newline
17035 in the string. If it's anything other than a display string
17036 (e.g. a before-string from an overlay), we don't want the
17037 cursor there. (This heuristic seems to give the optimal
17038 behavior for the various types of multi-line strings.) */
17039 if (CHARPOS (row
->end
.string_pos
) >= 0)
17041 if (row
->continued_p
)
17045 /* Check for `display' property. */
17046 struct glyph
*beg
= row
->glyphs
[TEXT_AREA
];
17047 struct glyph
*end
= beg
+ row
->used
[TEXT_AREA
] - 1;
17048 struct glyph
*glyph
;
17051 for (glyph
= end
; glyph
>= beg
; --glyph
)
17052 if (STRINGP (glyph
->object
))
17055 = Fget_char_property (make_number (PT
),
17059 && display_prop_string_p (prop
, glyph
->object
));
17064 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
17066 /* If the row ends in middle of a real character,
17067 and the line is continued, we want the cursor here.
17068 That's because CHARPOS (ROW->end.pos) would equal
17069 PT if PT is before the character. */
17070 if (!row
->ends_in_ellipsis_p
)
17071 cursor_row_p
= row
->continued_p
;
17073 /* If the row ends in an ellipsis, then
17074 CHARPOS (ROW->end.pos) will equal point after the
17075 invisible text. We want that position to be displayed
17076 after the ellipsis. */
17079 /* If the row ends at ZV, display the cursor at the end of that
17080 row instead of at the start of the row below. */
17081 else if (row
->ends_at_zv_p
)
17087 return cursor_row_p
;
17092 /* Push the display property PROP so that it will be rendered at the
17093 current position in IT. Return 1 if PROP was successfully pushed,
17097 push_display_prop (struct it
*it
, Lisp_Object prop
)
17101 if (STRINGP (prop
))
17103 if (SCHARS (prop
) == 0)
17110 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
17111 it
->current
.overlay_string_index
= -1;
17112 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
17113 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
17114 it
->method
= GET_FROM_STRING
;
17115 it
->stop_charpos
= 0;
17117 else if (CONSP (prop
) && EQ (XCAR (prop
), Qspace
))
17119 it
->method
= GET_FROM_STRETCH
;
17122 #ifdef HAVE_WINDOW_SYSTEM
17123 else if (IMAGEP (prop
))
17125 it
->what
= IT_IMAGE
;
17126 it
->image_id
= lookup_image (it
->f
, prop
);
17127 it
->method
= GET_FROM_IMAGE
;
17129 #endif /* HAVE_WINDOW_SYSTEM */
17132 pop_it (it
); /* bogus display property, give up */
17139 /* Return the character-property PROP at the current position in IT. */
17142 get_it_property (struct it
*it
, Lisp_Object prop
)
17144 Lisp_Object position
;
17146 if (STRINGP (it
->object
))
17147 position
= make_number (IT_STRING_CHARPOS (*it
));
17148 else if (BUFFERP (it
->object
))
17149 position
= make_number (IT_CHARPOS (*it
));
17153 return Fget_char_property (position
, prop
, it
->object
);
17156 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17159 handle_line_prefix (struct it
*it
)
17161 Lisp_Object prefix
;
17162 if (it
->continuation_lines_width
> 0)
17164 prefix
= get_it_property (it
, Qwrap_prefix
);
17166 prefix
= Vwrap_prefix
;
17170 prefix
= get_it_property (it
, Qline_prefix
);
17172 prefix
= Vline_prefix
;
17174 if (! NILP (prefix
) && push_display_prop (it
, prefix
))
17176 /* If the prefix is wider than the window, and we try to wrap
17177 it, it would acquire its own wrap prefix, and so on till the
17178 iterator stack overflows. So, don't wrap the prefix. */
17179 it
->line_wrap
= TRUNCATE
;
17180 it
->avoid_cursor_p
= 1;
17186 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17187 only for R2L lines from display_line, when it decides that too many
17188 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17191 unproduce_glyphs (struct it
*it
, int n
)
17193 struct glyph
*glyph
, *end
;
17195 xassert (it
->glyph_row
);
17196 xassert (it
->glyph_row
->reversed_p
);
17197 xassert (it
->area
== TEXT_AREA
);
17198 xassert (n
<= it
->glyph_row
->used
[TEXT_AREA
]);
17200 if (n
> it
->glyph_row
->used
[TEXT_AREA
])
17201 n
= it
->glyph_row
->used
[TEXT_AREA
];
17202 glyph
= it
->glyph_row
->glyphs
[TEXT_AREA
] + n
;
17203 end
= it
->glyph_row
->glyphs
[TEXT_AREA
] + it
->glyph_row
->used
[TEXT_AREA
];
17204 for ( ; glyph
< end
; glyph
++)
17205 glyph
[-n
] = *glyph
;
17208 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17209 and ROW->maxpos. */
17211 find_row_edges (struct it
*it
, struct glyph_row
*row
,
17212 EMACS_INT min_pos
, EMACS_INT min_bpos
,
17213 EMACS_INT max_pos
, EMACS_INT max_bpos
)
17215 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17216 lines' rows is implemented for bidi-reordered rows. */
17218 /* ROW->minpos is the value of min_pos, the minimal buffer position
17221 SET_TEXT_POS (row
->minpos
, min_pos
, min_bpos
);
17224 /* We didn't find _any_ valid buffer positions in any of the
17225 glyphs, so we must trust the iterator's computed
17227 row
->minpos
= row
->start
.pos
;
17228 max_pos
= CHARPOS (it
->current
.pos
);
17229 max_bpos
= BYTEPOS (it
->current
.pos
);
17235 /* Here are the various use-cases for ending the row, and the
17236 corresponding values for ROW->maxpos:
17238 Line ends in a newline from buffer eol_pos + 1
17239 Line is continued from buffer max_pos + 1
17240 Line is truncated on right it->current.pos
17241 Line ends in a newline from string max_pos
17242 Line is continued from string max_pos
17243 Line is continued from display vector max_pos
17244 Line is entirely from a string min_pos == max_pos
17245 Line is entirely from a display vector min_pos == max_pos
17246 Line that ends at ZV ZV
17248 If you discover other use-cases, please add them here as
17250 if (row
->ends_at_zv_p
)
17251 row
->maxpos
= it
->current
.pos
;
17252 else if (row
->used
[TEXT_AREA
])
17254 if (row
->ends_in_newline_from_string_p
)
17255 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
17256 else if (CHARPOS (it
->eol_pos
) > 0)
17257 SET_TEXT_POS (row
->maxpos
,
17258 CHARPOS (it
->eol_pos
) + 1, BYTEPOS (it
->eol_pos
) + 1);
17259 else if (row
->continued_p
)
17261 /* If max_pos is different from IT's current position, it
17262 means IT->method does not belong to the display element
17263 at max_pos. However, it also means that the display
17264 element at max_pos was displayed in its entirety on this
17265 line, which is equivalent to saying that the next line
17266 starts at the next buffer position. */
17267 if (IT_CHARPOS (*it
) == max_pos
&& it
->method
!= GET_FROM_BUFFER
)
17268 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
17271 INC_BOTH (max_pos
, max_bpos
);
17272 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
17275 else if (row
->truncated_on_right_p
)
17276 /* display_line already called reseat_at_next_visible_line_start,
17277 which puts the iterator at the beginning of the next line, in
17278 the logical order. */
17279 row
->maxpos
= it
->current
.pos
;
17280 else if (max_pos
== min_pos
&& it
->method
!= GET_FROM_BUFFER
)
17281 /* A line that is entirely from a string/image/stretch... */
17282 row
->maxpos
= row
->minpos
;
17287 row
->maxpos
= it
->current
.pos
;
17290 /* Construct the glyph row IT->glyph_row in the desired matrix of
17291 IT->w from text at the current position of IT. See dispextern.h
17292 for an overview of struct it. Value is non-zero if
17293 IT->glyph_row displays text, as opposed to a line displaying ZV
17297 display_line (struct it
*it
)
17299 struct glyph_row
*row
= it
->glyph_row
;
17300 Lisp_Object overlay_arrow_string
;
17302 int may_wrap
= 0, wrap_x
;
17303 int wrap_row_used
= -1, wrap_row_ascent
, wrap_row_height
;
17304 int wrap_row_phys_ascent
, wrap_row_phys_height
;
17305 int wrap_row_extra_line_spacing
;
17306 EMACS_INT wrap_row_min_pos
, wrap_row_min_bpos
;
17307 EMACS_INT wrap_row_max_pos
, wrap_row_max_bpos
;
17309 EMACS_INT min_pos
= ZV
+ 1, min_bpos
, max_pos
= 0, max_bpos
;
17311 /* We always start displaying at hpos zero even if hscrolled. */
17312 xassert (it
->hpos
== 0 && it
->current_x
== 0);
17314 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
17315 >= it
->w
->desired_matrix
->nrows
)
17317 it
->w
->nrows_scale_factor
++;
17318 fonts_changed_p
= 1;
17322 /* Is IT->w showing the region? */
17323 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
17325 /* Clear the result glyph row and enable it. */
17326 prepare_desired_row (row
);
17328 row
->y
= it
->current_y
;
17329 row
->start
= it
->start
;
17330 row
->continuation_lines_width
= it
->continuation_lines_width
;
17331 row
->displays_text_p
= 1;
17332 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
17333 it
->starts_in_middle_of_char_p
= 0;
17335 /* Arrange the overlays nicely for our purposes. Usually, we call
17336 display_line on only one line at a time, in which case this
17337 can't really hurt too much, or we call it on lines which appear
17338 one after another in the buffer, in which case all calls to
17339 recenter_overlay_lists but the first will be pretty cheap. */
17340 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
17342 /* Move over display elements that are not visible because we are
17343 hscrolled. This may stop at an x-position < IT->first_visible_x
17344 if the first glyph is partially visible or if we hit a line end. */
17345 if (it
->current_x
< it
->first_visible_x
)
17347 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
17348 MOVE_TO_POS
| MOVE_TO_X
);
17352 /* We only do this when not calling `move_it_in_display_line_to'
17353 above, because move_it_in_display_line_to calls
17354 handle_line_prefix itself. */
17355 handle_line_prefix (it
);
17358 /* Get the initial row height. This is either the height of the
17359 text hscrolled, if there is any, or zero. */
17360 row
->ascent
= it
->max_ascent
;
17361 row
->height
= it
->max_ascent
+ it
->max_descent
;
17362 row
->phys_ascent
= it
->max_phys_ascent
;
17363 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
17364 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
17366 /* Utility macro to record max and min buffer positions seen until now. */
17367 #define RECORD_MAX_MIN_POS(IT) \
17370 if (IT_CHARPOS (*(IT)) < min_pos) \
17372 min_pos = IT_CHARPOS (*(IT)); \
17373 min_bpos = IT_BYTEPOS (*(IT)); \
17375 if (IT_CHARPOS (*(IT)) > max_pos) \
17377 max_pos = IT_CHARPOS (*(IT)); \
17378 max_bpos = IT_BYTEPOS (*(IT)); \
17383 /* Loop generating characters. The loop is left with IT on the next
17384 character to display. */
17387 int n_glyphs_before
, hpos_before
, x_before
;
17389 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
17391 /* Retrieve the next thing to display. Value is zero if end of
17393 if (!get_next_display_element (it
))
17395 /* Maybe add a space at the end of this line that is used to
17396 display the cursor there under X. Set the charpos of the
17397 first glyph of blank lines not corresponding to any text
17399 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
17400 row
->exact_window_width_line_p
= 1;
17401 else if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
17402 || row
->used
[TEXT_AREA
] == 0)
17404 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
17405 row
->displays_text_p
= 0;
17407 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
17408 && (!MINI_WINDOW_P (it
->w
)
17409 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
17410 row
->indicate_empty_line_p
= 1;
17413 it
->continuation_lines_width
= 0;
17414 row
->ends_at_zv_p
= 1;
17415 /* A row that displays right-to-left text must always have
17416 its last face extended all the way to the end of line,
17417 even if this row ends in ZV, because we still write to th
17418 screen left to right. */
17419 if (row
->reversed_p
)
17420 extend_face_to_end_of_line (it
);
17424 /* Now, get the metrics of what we want to display. This also
17425 generates glyphs in `row' (which is IT->glyph_row). */
17426 n_glyphs_before
= row
->used
[TEXT_AREA
];
17429 /* Remember the line height so far in case the next element doesn't
17430 fit on the line. */
17431 if (it
->line_wrap
!= TRUNCATE
)
17433 ascent
= it
->max_ascent
;
17434 descent
= it
->max_descent
;
17435 phys_ascent
= it
->max_phys_ascent
;
17436 phys_descent
= it
->max_phys_descent
;
17438 if (it
->line_wrap
== WORD_WRAP
&& it
->area
== TEXT_AREA
)
17440 if (IT_DISPLAYING_WHITESPACE (it
))
17446 wrap_row_used
= row
->used
[TEXT_AREA
];
17447 wrap_row_ascent
= row
->ascent
;
17448 wrap_row_height
= row
->height
;
17449 wrap_row_phys_ascent
= row
->phys_ascent
;
17450 wrap_row_phys_height
= row
->phys_height
;
17451 wrap_row_extra_line_spacing
= row
->extra_line_spacing
;
17452 wrap_row_min_pos
= min_pos
;
17453 wrap_row_min_bpos
= min_bpos
;
17454 wrap_row_max_pos
= max_pos
;
17455 wrap_row_max_bpos
= max_bpos
;
17461 PRODUCE_GLYPHS (it
);
17463 /* If this display element was in marginal areas, continue with
17465 if (it
->area
!= TEXT_AREA
)
17467 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
17468 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
17469 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
17470 row
->phys_height
= max (row
->phys_height
,
17471 it
->max_phys_ascent
+ it
->max_phys_descent
);
17472 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
17473 it
->max_extra_line_spacing
);
17474 set_iterator_to_next (it
, 1);
17478 /* Does the display element fit on the line? If we truncate
17479 lines, we should draw past the right edge of the window. If
17480 we don't truncate, we want to stop so that we can display the
17481 continuation glyph before the right margin. If lines are
17482 continued, there are two possible strategies for characters
17483 resulting in more than 1 glyph (e.g. tabs): Display as many
17484 glyphs as possible in this line and leave the rest for the
17485 continuation line, or display the whole element in the next
17486 line. Original redisplay did the former, so we do it also. */
17487 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
17488 hpos_before
= it
->hpos
;
17491 if (/* Not a newline. */
17493 /* Glyphs produced fit entirely in the line. */
17494 && it
->current_x
< it
->last_visible_x
)
17496 it
->hpos
+= nglyphs
;
17497 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
17498 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
17499 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
17500 row
->phys_height
= max (row
->phys_height
,
17501 it
->max_phys_ascent
+ it
->max_phys_descent
);
17502 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
17503 it
->max_extra_line_spacing
);
17504 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
17505 row
->x
= x
- it
->first_visible_x
;
17506 /* Record the maximum and minimum buffer positions seen so
17507 far in glyphs that will be displayed by this row. */
17509 RECORD_MAX_MIN_POS (it
);
17514 struct glyph
*glyph
;
17516 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
17518 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
17519 new_x
= x
+ glyph
->pixel_width
;
17521 if (/* Lines are continued. */
17522 it
->line_wrap
!= TRUNCATE
17523 && (/* Glyph doesn't fit on the line. */
17524 new_x
> it
->last_visible_x
17525 /* Or it fits exactly on a window system frame. */
17526 || (new_x
== it
->last_visible_x
17527 && FRAME_WINDOW_P (it
->f
))))
17529 /* End of a continued line. */
17532 || (new_x
== it
->last_visible_x
17533 && FRAME_WINDOW_P (it
->f
)))
17535 /* Current glyph is the only one on the line or
17536 fits exactly on the line. We must continue
17537 the line because we can't draw the cursor
17538 after the glyph. */
17539 row
->continued_p
= 1;
17540 it
->current_x
= new_x
;
17541 it
->continuation_lines_width
+= new_x
;
17543 /* Record the maximum and minimum buffer
17544 positions seen so far in glyphs that will be
17545 displayed by this row. */
17547 RECORD_MAX_MIN_POS (it
);
17548 if (i
== nglyphs
- 1)
17550 /* If line-wrap is on, check if a previous
17551 wrap point was found. */
17552 if (wrap_row_used
> 0
17553 /* Even if there is a previous wrap
17554 point, continue the line here as
17555 usual, if (i) the previous character
17556 was a space or tab AND (ii) the
17557 current character is not. */
17559 || IT_DISPLAYING_WHITESPACE (it
)))
17562 set_iterator_to_next (it
, 1);
17563 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
17565 if (!get_next_display_element (it
))
17567 row
->exact_window_width_line_p
= 1;
17568 it
->continuation_lines_width
= 0;
17569 row
->continued_p
= 0;
17570 row
->ends_at_zv_p
= 1;
17572 else if (ITERATOR_AT_END_OF_LINE_P (it
))
17574 row
->continued_p
= 0;
17575 row
->exact_window_width_line_p
= 1;
17580 else if (CHAR_GLYPH_PADDING_P (*glyph
)
17581 && !FRAME_WINDOW_P (it
->f
))
17583 /* A padding glyph that doesn't fit on this line.
17584 This means the whole character doesn't fit
17586 if (row
->reversed_p
)
17587 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
17588 - n_glyphs_before
);
17589 row
->used
[TEXT_AREA
] = n_glyphs_before
;
17591 /* Fill the rest of the row with continuation
17592 glyphs like in 20.x. */
17593 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
17594 < row
->glyphs
[1 + TEXT_AREA
])
17595 produce_special_glyphs (it
, IT_CONTINUATION
);
17597 row
->continued_p
= 1;
17598 it
->current_x
= x_before
;
17599 it
->continuation_lines_width
+= x_before
;
17601 /* Restore the height to what it was before the
17602 element not fitting on the line. */
17603 it
->max_ascent
= ascent
;
17604 it
->max_descent
= descent
;
17605 it
->max_phys_ascent
= phys_ascent
;
17606 it
->max_phys_descent
= phys_descent
;
17608 else if (wrap_row_used
> 0)
17611 if (row
->reversed_p
)
17612 unproduce_glyphs (it
,
17613 row
->used
[TEXT_AREA
] - wrap_row_used
);
17615 it
->continuation_lines_width
+= wrap_x
;
17616 row
->used
[TEXT_AREA
] = wrap_row_used
;
17617 row
->ascent
= wrap_row_ascent
;
17618 row
->height
= wrap_row_height
;
17619 row
->phys_ascent
= wrap_row_phys_ascent
;
17620 row
->phys_height
= wrap_row_phys_height
;
17621 row
->extra_line_spacing
= wrap_row_extra_line_spacing
;
17622 min_pos
= wrap_row_min_pos
;
17623 min_bpos
= wrap_row_min_bpos
;
17624 max_pos
= wrap_row_max_pos
;
17625 max_bpos
= wrap_row_max_bpos
;
17626 row
->continued_p
= 1;
17627 row
->ends_at_zv_p
= 0;
17628 row
->exact_window_width_line_p
= 0;
17629 it
->continuation_lines_width
+= x
;
17631 /* Make sure that a non-default face is extended
17632 up to the right margin of the window. */
17633 extend_face_to_end_of_line (it
);
17635 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
17637 /* A TAB that extends past the right edge of the
17638 window. This produces a single glyph on
17639 window system frames. We leave the glyph in
17640 this row and let it fill the row, but don't
17641 consume the TAB. */
17642 it
->continuation_lines_width
+= it
->last_visible_x
;
17643 row
->ends_in_middle_of_char_p
= 1;
17644 row
->continued_p
= 1;
17645 glyph
->pixel_width
= it
->last_visible_x
- x
;
17646 it
->starts_in_middle_of_char_p
= 1;
17650 /* Something other than a TAB that draws past
17651 the right edge of the window. Restore
17652 positions to values before the element. */
17653 if (row
->reversed_p
)
17654 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
17655 - (n_glyphs_before
+ i
));
17656 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
17658 /* Display continuation glyphs. */
17659 if (!FRAME_WINDOW_P (it
->f
))
17660 produce_special_glyphs (it
, IT_CONTINUATION
);
17661 row
->continued_p
= 1;
17663 it
->current_x
= x_before
;
17664 it
->continuation_lines_width
+= x
;
17665 extend_face_to_end_of_line (it
);
17667 if (nglyphs
> 1 && i
> 0)
17669 row
->ends_in_middle_of_char_p
= 1;
17670 it
->starts_in_middle_of_char_p
= 1;
17673 /* Restore the height to what it was before the
17674 element not fitting on the line. */
17675 it
->max_ascent
= ascent
;
17676 it
->max_descent
= descent
;
17677 it
->max_phys_ascent
= phys_ascent
;
17678 it
->max_phys_descent
= phys_descent
;
17683 else if (new_x
> it
->first_visible_x
)
17685 /* Increment number of glyphs actually displayed. */
17688 /* Record the maximum and minimum buffer positions
17689 seen so far in glyphs that will be displayed by
17692 RECORD_MAX_MIN_POS (it
);
17694 if (x
< it
->first_visible_x
)
17695 /* Glyph is partially visible, i.e. row starts at
17696 negative X position. */
17697 row
->x
= x
- it
->first_visible_x
;
17701 /* Glyph is completely off the left margin of the
17702 window. This should not happen because of the
17703 move_it_in_display_line at the start of this
17704 function, unless the text display area of the
17705 window is empty. */
17706 xassert (it
->first_visible_x
<= it
->last_visible_x
);
17710 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
17711 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
17712 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
17713 row
->phys_height
= max (row
->phys_height
,
17714 it
->max_phys_ascent
+ it
->max_phys_descent
);
17715 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
17716 it
->max_extra_line_spacing
);
17718 /* End of this display line if row is continued. */
17719 if (row
->continued_p
|| row
->ends_at_zv_p
)
17724 /* Is this a line end? If yes, we're also done, after making
17725 sure that a non-default face is extended up to the right
17726 margin of the window. */
17727 if (ITERATOR_AT_END_OF_LINE_P (it
))
17729 int used_before
= row
->used
[TEXT_AREA
];
17731 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
17733 /* Add a space at the end of the line that is used to
17734 display the cursor there. */
17735 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
17736 append_space_for_newline (it
, 0);
17738 /* Extend the face to the end of the line. */
17739 extend_face_to_end_of_line (it
);
17741 /* Make sure we have the position. */
17742 if (used_before
== 0)
17743 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
17745 /* Record the position of the newline, for use in
17747 it
->eol_pos
= it
->current
.pos
;
17749 /* Consume the line end. This skips over invisible lines. */
17750 set_iterator_to_next (it
, 1);
17751 it
->continuation_lines_width
= 0;
17755 /* Proceed with next display element. Note that this skips
17756 over lines invisible because of selective display. */
17757 set_iterator_to_next (it
, 1);
17759 /* If we truncate lines, we are done when the last displayed
17760 glyphs reach past the right margin of the window. */
17761 if (it
->line_wrap
== TRUNCATE
17762 && (FRAME_WINDOW_P (it
->f
)
17763 ? (it
->current_x
>= it
->last_visible_x
)
17764 : (it
->current_x
> it
->last_visible_x
)))
17766 /* Maybe add truncation glyphs. */
17767 if (!FRAME_WINDOW_P (it
->f
))
17771 if (!row
->reversed_p
)
17773 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
17774 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
17779 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
17780 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
17782 /* Remove any padding glyphs at the front of ROW, to
17783 make room for the truncation glyphs we will be
17784 adding below. The loop below always inserts at
17785 least one truncation glyph, so also remove the
17786 last glyph added to ROW. */
17787 unproduce_glyphs (it
, i
+ 1);
17788 /* Adjust i for the loop below. */
17789 i
= row
->used
[TEXT_AREA
] - (i
+ 1);
17792 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
17794 row
->used
[TEXT_AREA
] = i
;
17795 produce_special_glyphs (it
, IT_TRUNCATION
);
17798 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
17800 /* Don't truncate if we can overflow newline into fringe. */
17801 if (!get_next_display_element (it
))
17803 it
->continuation_lines_width
= 0;
17804 row
->ends_at_zv_p
= 1;
17805 row
->exact_window_width_line_p
= 1;
17808 if (ITERATOR_AT_END_OF_LINE_P (it
))
17810 row
->exact_window_width_line_p
= 1;
17811 goto at_end_of_line
;
17815 row
->truncated_on_right_p
= 1;
17816 it
->continuation_lines_width
= 0;
17817 reseat_at_next_visible_line_start (it
, 0);
17818 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
17819 it
->hpos
= hpos_before
;
17820 it
->current_x
= x_before
;
17825 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17826 at the left window margin. */
17827 if (it
->first_visible_x
17828 && IT_CHARPOS (*it
) != CHARPOS (row
->start
.pos
))
17830 if (!FRAME_WINDOW_P (it
->f
))
17831 insert_left_trunc_glyphs (it
);
17832 row
->truncated_on_left_p
= 1;
17835 /* If the start of this line is the overlay arrow-position, then
17836 mark this glyph row as the one containing the overlay arrow.
17837 This is clearly a mess with variable size fonts. It would be
17838 better to let it be displayed like cursors under X. */
17839 if ((row
->displays_text_p
|| !overlay_arrow_seen
)
17840 && (overlay_arrow_string
= overlay_arrow_at_row (it
, row
),
17841 !NILP (overlay_arrow_string
)))
17843 /* Overlay arrow in window redisplay is a fringe bitmap. */
17844 if (STRINGP (overlay_arrow_string
))
17846 struct glyph_row
*arrow_row
17847 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
17848 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
17849 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
17850 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
17851 struct glyph
*p2
, *end
;
17853 /* Copy the arrow glyphs. */
17854 while (glyph
< arrow_end
)
17857 /* Throw away padding glyphs. */
17859 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
17860 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
17866 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
17871 xassert (INTEGERP (overlay_arrow_string
));
17872 row
->overlay_arrow_bitmap
= XINT (overlay_arrow_string
);
17874 overlay_arrow_seen
= 1;
17877 /* Compute pixel dimensions of this line. */
17878 compute_line_metrics (it
);
17880 /* Remember the position at which this line ends. */
17881 row
->end
= it
->current
;
17884 row
->minpos
= row
->start
.pos
;
17885 row
->maxpos
= row
->end
.pos
;
17889 /* ROW->minpos and ROW->maxpos must be the smallest and
17890 `1 + the largest' buffer positions in ROW. But if ROW was
17891 bidi-reordered, these two positions can be anywhere in the
17892 row, so we must determine them now. */
17893 find_row_edges (it
, row
, min_pos
, min_bpos
, max_pos
, max_bpos
);
17896 /* Record whether this row ends inside an ellipsis. */
17897 row
->ends_in_ellipsis_p
17898 = (it
->method
== GET_FROM_DISPLAY_VECTOR
17899 && it
->ellipsis_p
);
17901 /* Save fringe bitmaps in this row. */
17902 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
17903 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
17904 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
17905 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
17907 it
->left_user_fringe_bitmap
= 0;
17908 it
->left_user_fringe_face_id
= 0;
17909 it
->right_user_fringe_bitmap
= 0;
17910 it
->right_user_fringe_face_id
= 0;
17912 /* Maybe set the cursor. */
17913 cvpos
= it
->w
->cursor
.vpos
;
17915 /* In bidi-reordered rows, keep checking for proper cursor
17916 position even if one has been found already, because buffer
17917 positions in such rows change non-linearly with ROW->VPOS,
17918 when a line is continued. One exception: when we are at ZV,
17919 display cursor on the first suitable glyph row, since all
17920 the empty rows after that also have their position set to ZV. */
17921 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17922 lines' rows is implemented for bidi-reordered rows. */
17924 && !MATRIX_ROW (it
->w
->desired_matrix
, cvpos
)->ends_at_zv_p
))
17925 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
17926 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
17927 && cursor_row_p (it
->w
, row
))
17928 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
17930 /* Highlight trailing whitespace. */
17931 if (!NILP (Vshow_trailing_whitespace
))
17932 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
17934 /* Prepare for the next line. This line starts horizontally at (X
17935 HPOS) = (0 0). Vertical positions are incremented. As a
17936 convenience for the caller, IT->glyph_row is set to the next
17938 it
->current_x
= it
->hpos
= 0;
17939 it
->current_y
+= row
->height
;
17940 SET_TEXT_POS (it
->eol_pos
, 0, 0);
17943 /* The next row should by default use the same value of the
17944 reversed_p flag as this one. set_iterator_to_next decides when
17945 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
17946 the flag accordingly. */
17947 if (it
->glyph_row
< MATRIX_BOTTOM_TEXT_ROW (it
->w
->desired_matrix
, it
->w
))
17948 it
->glyph_row
->reversed_p
= row
->reversed_p
;
17949 it
->start
= row
->end
;
17950 return row
->displays_text_p
;
17952 #undef RECORD_MAX_MIN_POS
17955 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction
,
17956 Scurrent_bidi_paragraph_direction
, 0, 1, 0,
17957 doc
: /* Return paragraph direction at point in BUFFER.
17958 Value is either `left-to-right' or `right-to-left'.
17959 If BUFFER is omitted or nil, it defaults to the current buffer.
17961 Paragraph direction determines how the text in the paragraph is displayed.
17962 In left-to-right paragraphs, text begins at the left margin of the window
17963 and the reading direction is generally left to right. In right-to-left
17964 paragraphs, text begins at the right margin and is read from right to left.
17966 See also `bidi-paragraph-direction'. */)
17967 (Lisp_Object buffer
)
17969 struct buffer
*buf
;
17970 struct buffer
*old
;
17973 buf
= current_buffer
;
17976 CHECK_BUFFER (buffer
);
17977 buf
= XBUFFER (buffer
);
17978 old
= current_buffer
;
17981 if (NILP (buf
->bidi_display_reordering
))
17982 return Qleft_to_right
;
17983 else if (!NILP (buf
->bidi_paragraph_direction
))
17984 return buf
->bidi_paragraph_direction
;
17987 /* Determine the direction from buffer text. We could try to
17988 use current_matrix if it is up to date, but this seems fast
17989 enough as it is. */
17990 struct bidi_it itb
;
17991 EMACS_INT pos
= BUF_PT (buf
);
17992 EMACS_INT bytepos
= BUF_PT_BYTE (buf
);
17994 if (buf
!= current_buffer
)
17995 set_buffer_temp (buf
);
17996 /* Find previous non-empty line. */
17997 if (pos
>= ZV
&& pos
> BEGV
)
18000 bytepos
= CHAR_TO_BYTE (pos
);
18002 while (FETCH_BYTE (bytepos
) == '\n')
18004 if (bytepos
<= BEGV_BYTE
)
18009 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos
)))
18012 itb
.bytepos
= bytepos
;
18015 bidi_paragraph_init (NEUTRAL_DIR
, &itb
);
18016 if (buf
!= current_buffer
)
18017 set_buffer_temp (old
);
18018 switch (itb
.paragraph_dir
)
18021 return Qleft_to_right
;
18024 return Qright_to_left
;
18034 /***********************************************************************
18036 ***********************************************************************/
18038 /* Redisplay the menu bar in the frame for window W.
18040 The menu bar of X frames that don't have X toolkit support is
18041 displayed in a special window W->frame->menu_bar_window.
18043 The menu bar of terminal frames is treated specially as far as
18044 glyph matrices are concerned. Menu bar lines are not part of
18045 windows, so the update is done directly on the frame matrix rows
18046 for the menu bar. */
18049 display_menu_bar (struct window
*w
)
18051 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
18056 /* Don't do all this for graphical frames. */
18058 if (FRAME_W32_P (f
))
18061 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18067 if (FRAME_NS_P (f
))
18069 #endif /* HAVE_NS */
18071 #ifdef USE_X_TOOLKIT
18072 xassert (!FRAME_WINDOW_P (f
));
18073 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
18074 it
.first_visible_x
= 0;
18075 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
18076 #else /* not USE_X_TOOLKIT */
18077 if (FRAME_WINDOW_P (f
))
18079 /* Menu bar lines are displayed in the desired matrix of the
18080 dummy window menu_bar_window. */
18081 struct window
*menu_w
;
18082 xassert (WINDOWP (f
->menu_bar_window
));
18083 menu_w
= XWINDOW (f
->menu_bar_window
);
18084 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
18086 it
.first_visible_x
= 0;
18087 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
18091 /* This is a TTY frame, i.e. character hpos/vpos are used as
18093 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
18095 it
.first_visible_x
= 0;
18096 it
.last_visible_x
= FRAME_COLS (f
);
18098 #endif /* not USE_X_TOOLKIT */
18100 if (! mode_line_inverse_video
)
18101 /* Force the menu-bar to be displayed in the default face. */
18102 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
18104 /* Clear all rows of the menu bar. */
18105 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
18107 struct glyph_row
*row
= it
.glyph_row
+ i
;
18108 clear_glyph_row (row
);
18109 row
->enabled_p
= 1;
18110 row
->full_width_p
= 1;
18113 /* Display all items of the menu bar. */
18114 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
18115 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
18117 Lisp_Object string
;
18119 /* Stop at nil string. */
18120 string
= AREF (items
, i
+ 1);
18124 /* Remember where item was displayed. */
18125 ASET (items
, i
+ 3, make_number (it
.hpos
));
18127 /* Display the item, pad with one space. */
18128 if (it
.current_x
< it
.last_visible_x
)
18129 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
18130 SCHARS (string
) + 1, 0, 0, -1);
18133 /* Fill out the line with spaces. */
18134 if (it
.current_x
< it
.last_visible_x
)
18135 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
18137 /* Compute the total height of the lines. */
18138 compute_line_metrics (&it
);
18143 /***********************************************************************
18145 ***********************************************************************/
18147 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18148 FORCE is non-zero, redisplay mode lines unconditionally.
18149 Otherwise, redisplay only mode lines that are garbaged. Value is
18150 the number of windows whose mode lines were redisplayed. */
18153 redisplay_mode_lines (Lisp_Object window
, int force
)
18157 while (!NILP (window
))
18159 struct window
*w
= XWINDOW (window
);
18161 if (WINDOWP (w
->hchild
))
18162 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
18163 else if (WINDOWP (w
->vchild
))
18164 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
18166 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
18167 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
18169 struct text_pos lpoint
;
18170 struct buffer
*old
= current_buffer
;
18172 /* Set the window's buffer for the mode line display. */
18173 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
18174 set_buffer_internal_1 (XBUFFER (w
->buffer
));
18176 /* Point refers normally to the selected window. For any
18177 other window, set up appropriate value. */
18178 if (!EQ (window
, selected_window
))
18180 struct text_pos pt
;
18182 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
18183 if (CHARPOS (pt
) < BEGV
)
18184 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
18185 else if (CHARPOS (pt
) > (ZV
- 1))
18186 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
18188 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
18191 /* Display mode lines. */
18192 clear_glyph_matrix (w
->desired_matrix
);
18193 if (display_mode_lines (w
))
18196 w
->must_be_updated_p
= 1;
18199 /* Restore old settings. */
18200 set_buffer_internal_1 (old
);
18201 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
18211 /* Display the mode and/or header line of window W. Value is the
18212 sum number of mode lines and header lines displayed. */
18215 display_mode_lines (struct window
*w
)
18217 Lisp_Object old_selected_window
, old_selected_frame
;
18220 old_selected_frame
= selected_frame
;
18221 selected_frame
= w
->frame
;
18222 old_selected_window
= selected_window
;
18223 XSETWINDOW (selected_window
, w
);
18225 /* These will be set while the mode line specs are processed. */
18226 line_number_displayed
= 0;
18227 w
->column_number_displayed
= Qnil
;
18229 if (WINDOW_WANTS_MODELINE_P (w
))
18231 struct window
*sel_w
= XWINDOW (old_selected_window
);
18233 /* Select mode line face based on the real selected window. */
18234 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
18235 current_buffer
->mode_line_format
);
18239 if (WINDOW_WANTS_HEADER_LINE_P (w
))
18241 display_mode_line (w
, HEADER_LINE_FACE_ID
,
18242 current_buffer
->header_line_format
);
18246 selected_frame
= old_selected_frame
;
18247 selected_window
= old_selected_window
;
18252 /* Display mode or header line of window W. FACE_ID specifies which
18253 line to display; it is either MODE_LINE_FACE_ID or
18254 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18255 display. Value is the pixel height of the mode/header line
18259 display_mode_line (struct window
*w
, enum face_id face_id
, Lisp_Object format
)
18263 int count
= SPECPDL_INDEX ();
18265 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
18266 /* Don't extend on a previously drawn mode-line.
18267 This may happen if called from pos_visible_p. */
18268 it
.glyph_row
->enabled_p
= 0;
18269 prepare_desired_row (it
.glyph_row
);
18271 it
.glyph_row
->mode_line_p
= 1;
18273 if (! mode_line_inverse_video
)
18274 /* Force the mode-line to be displayed in the default face. */
18275 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
18277 record_unwind_protect (unwind_format_mode_line
,
18278 format_mode_line_unwind_data (NULL
, Qnil
, 0));
18280 mode_line_target
= MODE_LINE_DISPLAY
;
18282 /* Temporarily make frame's keyboard the current kboard so that
18283 kboard-local variables in the mode_line_format will get the right
18285 push_kboard (FRAME_KBOARD (it
.f
));
18286 record_unwind_save_match_data ();
18287 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
18290 unbind_to (count
, Qnil
);
18292 /* Fill up with spaces. */
18293 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
18295 compute_line_metrics (&it
);
18296 it
.glyph_row
->full_width_p
= 1;
18297 it
.glyph_row
->continued_p
= 0;
18298 it
.glyph_row
->truncated_on_left_p
= 0;
18299 it
.glyph_row
->truncated_on_right_p
= 0;
18301 /* Make a 3D mode-line have a shadow at its right end. */
18302 face
= FACE_FROM_ID (it
.f
, face_id
);
18303 extend_face_to_end_of_line (&it
);
18304 if (face
->box
!= FACE_NO_BOX
)
18306 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
18307 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
18308 last
->right_box_line_p
= 1;
18311 return it
.glyph_row
->height
;
18314 /* Move element ELT in LIST to the front of LIST.
18315 Return the updated list. */
18318 move_elt_to_front (Lisp_Object elt
, Lisp_Object list
)
18320 register Lisp_Object tail
, prev
;
18321 register Lisp_Object tem
;
18325 while (CONSP (tail
))
18331 /* Splice out the link TAIL. */
18333 list
= XCDR (tail
);
18335 Fsetcdr (prev
, XCDR (tail
));
18337 /* Now make it the first. */
18338 Fsetcdr (tail
, list
);
18343 tail
= XCDR (tail
);
18347 /* Not found--return unchanged LIST. */
18351 /* Contribute ELT to the mode line for window IT->w. How it
18352 translates into text depends on its data type.
18354 IT describes the display environment in which we display, as usual.
18356 DEPTH is the depth in recursion. It is used to prevent
18357 infinite recursion here.
18359 FIELD_WIDTH is the number of characters the display of ELT should
18360 occupy in the mode line, and PRECISION is the maximum number of
18361 characters to display from ELT's representation. See
18362 display_string for details.
18364 Returns the hpos of the end of the text generated by ELT.
18366 PROPS is a property list to add to any string we encounter.
18368 If RISKY is nonzero, remove (disregard) any properties in any string
18369 we encounter, and ignore :eval and :propertize.
18371 The global variable `mode_line_target' determines whether the
18372 output is passed to `store_mode_line_noprop',
18373 `store_mode_line_string', or `display_string'. */
18376 display_mode_element (struct it
*it
, int depth
, int field_width
, int precision
,
18377 Lisp_Object elt
, Lisp_Object props
, int risky
)
18379 int n
= 0, field
, prec
;
18384 elt
= build_string ("*too-deep*");
18388 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
18392 /* A string: output it and check for %-constructs within it. */
18396 if (SCHARS (elt
) > 0
18397 && (!NILP (props
) || risky
))
18399 Lisp_Object oprops
, aelt
;
18400 oprops
= Ftext_properties_at (make_number (0), elt
);
18402 /* If the starting string's properties are not what
18403 we want, translate the string. Also, if the string
18404 is risky, do that anyway. */
18406 if (NILP (Fequal (props
, oprops
)) || risky
)
18408 /* If the starting string has properties,
18409 merge the specified ones onto the existing ones. */
18410 if (! NILP (oprops
) && !risky
)
18414 oprops
= Fcopy_sequence (oprops
);
18416 while (CONSP (tem
))
18418 oprops
= Fplist_put (oprops
, XCAR (tem
),
18419 XCAR (XCDR (tem
)));
18420 tem
= XCDR (XCDR (tem
));
18425 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
18426 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
18428 /* AELT is what we want. Move it to the front
18429 without consing. */
18431 mode_line_proptrans_alist
18432 = move_elt_to_front (aelt
, mode_line_proptrans_alist
);
18438 /* If AELT has the wrong props, it is useless.
18439 so get rid of it. */
18441 mode_line_proptrans_alist
18442 = Fdelq (aelt
, mode_line_proptrans_alist
);
18444 elt
= Fcopy_sequence (elt
);
18445 Fset_text_properties (make_number (0), Flength (elt
),
18447 /* Add this item to mode_line_proptrans_alist. */
18448 mode_line_proptrans_alist
18449 = Fcons (Fcons (elt
, props
),
18450 mode_line_proptrans_alist
);
18451 /* Truncate mode_line_proptrans_alist
18452 to at most 50 elements. */
18453 tem
= Fnthcdr (make_number (50),
18454 mode_line_proptrans_alist
);
18456 XSETCDR (tem
, Qnil
);
18465 prec
= precision
- n
;
18466 switch (mode_line_target
)
18468 case MODE_LINE_NOPROP
:
18469 case MODE_LINE_TITLE
:
18470 n
+= store_mode_line_noprop (SDATA (elt
), -1, prec
);
18472 case MODE_LINE_STRING
:
18473 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
18475 case MODE_LINE_DISPLAY
:
18476 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
18477 0, prec
, 0, STRING_MULTIBYTE (elt
));
18484 /* Handle the non-literal case. */
18486 while ((precision
<= 0 || n
< precision
)
18487 && SREF (elt
, offset
) != 0
18488 && (mode_line_target
!= MODE_LINE_DISPLAY
18489 || it
->current_x
< it
->last_visible_x
))
18491 int last_offset
= offset
;
18493 /* Advance to end of string or next format specifier. */
18494 while ((c
= SREF (elt
, offset
++)) != '\0' && c
!= '%')
18497 if (offset
- 1 != last_offset
)
18499 int nchars
, nbytes
;
18501 /* Output to end of string or up to '%'. Field width
18502 is length of string. Don't output more than
18503 PRECISION allows us. */
18506 prec
= c_string_width (SDATA (elt
) + last_offset
,
18507 offset
- last_offset
, precision
- n
,
18510 switch (mode_line_target
)
18512 case MODE_LINE_NOPROP
:
18513 case MODE_LINE_TITLE
:
18514 n
+= store_mode_line_noprop (SDATA (elt
) + last_offset
, 0, prec
);
18516 case MODE_LINE_STRING
:
18518 int bytepos
= last_offset
;
18519 int charpos
= string_byte_to_char (elt
, bytepos
);
18520 int endpos
= (precision
<= 0
18521 ? string_byte_to_char (elt
, offset
)
18522 : charpos
+ nchars
);
18524 n
+= store_mode_line_string (NULL
,
18525 Fsubstring (elt
, make_number (charpos
),
18526 make_number (endpos
)),
18530 case MODE_LINE_DISPLAY
:
18532 int bytepos
= last_offset
;
18533 int charpos
= string_byte_to_char (elt
, bytepos
);
18535 if (precision
<= 0)
18536 nchars
= string_byte_to_char (elt
, offset
) - charpos
;
18537 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
18539 STRING_MULTIBYTE (elt
));
18544 else /* c == '%' */
18546 int percent_position
= offset
;
18548 /* Get the specified minimum width. Zero means
18551 while ((c
= SREF (elt
, offset
++)) >= '0' && c
<= '9')
18552 field
= field
* 10 + c
- '0';
18554 /* Don't pad beyond the total padding allowed. */
18555 if (field_width
- n
> 0 && field
> field_width
- n
)
18556 field
= field_width
- n
;
18558 /* Note that either PRECISION <= 0 or N < PRECISION. */
18559 prec
= precision
- n
;
18562 n
+= display_mode_element (it
, depth
, field
, prec
,
18563 Vglobal_mode_string
, props
,
18568 int bytepos
, charpos
;
18569 unsigned char *spec
;
18570 Lisp_Object string
;
18572 bytepos
= percent_position
;
18573 charpos
= (STRING_MULTIBYTE (elt
)
18574 ? string_byte_to_char (elt
, bytepos
)
18576 spec
= decode_mode_spec (it
->w
, c
, field
, prec
, &string
);
18577 multibyte
= STRINGP (string
) && STRING_MULTIBYTE (string
);
18579 switch (mode_line_target
)
18581 case MODE_LINE_NOPROP
:
18582 case MODE_LINE_TITLE
:
18583 n
+= store_mode_line_noprop (spec
, field
, prec
);
18585 case MODE_LINE_STRING
:
18587 int len
= strlen (spec
);
18588 Lisp_Object tem
= make_string (spec
, len
);
18589 props
= Ftext_properties_at (make_number (charpos
), elt
);
18590 /* Should only keep face property in props */
18591 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
18594 case MODE_LINE_DISPLAY
:
18596 int nglyphs_before
, nwritten
;
18598 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
18599 nwritten
= display_string (spec
, string
, elt
,
18604 /* Assign to the glyphs written above the
18605 string where the `%x' came from, position
18609 struct glyph
*glyph
18610 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
18614 for (i
= 0; i
< nwritten
; ++i
)
18616 glyph
[i
].object
= elt
;
18617 glyph
[i
].charpos
= charpos
;
18634 /* A symbol: process the value of the symbol recursively
18635 as if it appeared here directly. Avoid error if symbol void.
18636 Special case: if value of symbol is a string, output the string
18639 register Lisp_Object tem
;
18641 /* If the variable is not marked as risky to set
18642 then its contents are risky to use. */
18643 if (NILP (Fget (elt
, Qrisky_local_variable
)))
18646 tem
= Fboundp (elt
);
18649 tem
= Fsymbol_value (elt
);
18650 /* If value is a string, output that string literally:
18651 don't check for % within it. */
18655 if (!EQ (tem
, elt
))
18657 /* Give up right away for nil or t. */
18667 register Lisp_Object car
, tem
;
18669 /* A cons cell: five distinct cases.
18670 If first element is :eval or :propertize, do something special.
18671 If first element is a string or a cons, process all the elements
18672 and effectively concatenate them.
18673 If first element is a negative number, truncate displaying cdr to
18674 at most that many characters. If positive, pad (with spaces)
18675 to at least that many characters.
18676 If first element is a symbol, process the cadr or caddr recursively
18677 according to whether the symbol's value is non-nil or nil. */
18679 if (EQ (car
, QCeval
))
18681 /* An element of the form (:eval FORM) means evaluate FORM
18682 and use the result as mode line elements. */
18687 if (CONSP (XCDR (elt
)))
18690 spec
= safe_eval (XCAR (XCDR (elt
)));
18691 n
+= display_mode_element (it
, depth
, field_width
- n
,
18692 precision
- n
, spec
, props
,
18696 else if (EQ (car
, QCpropertize
))
18698 /* An element of the form (:propertize ELT PROPS...)
18699 means display ELT but applying properties PROPS. */
18704 if (CONSP (XCDR (elt
)))
18705 n
+= display_mode_element (it
, depth
, field_width
- n
,
18706 precision
- n
, XCAR (XCDR (elt
)),
18707 XCDR (XCDR (elt
)), risky
);
18709 else if (SYMBOLP (car
))
18711 tem
= Fboundp (car
);
18715 /* elt is now the cdr, and we know it is a cons cell.
18716 Use its car if CAR has a non-nil value. */
18719 tem
= Fsymbol_value (car
);
18726 /* Symbol's value is nil (or symbol is unbound)
18727 Get the cddr of the original list
18728 and if possible find the caddr and use that. */
18732 else if (!CONSP (elt
))
18737 else if (INTEGERP (car
))
18739 register int lim
= XINT (car
);
18743 /* Negative int means reduce maximum width. */
18744 if (precision
<= 0)
18747 precision
= min (precision
, -lim
);
18751 /* Padding specified. Don't let it be more than
18752 current maximum. */
18754 lim
= min (precision
, lim
);
18756 /* If that's more padding than already wanted, queue it.
18757 But don't reduce padding already specified even if
18758 that is beyond the current truncation point. */
18759 field_width
= max (lim
, field_width
);
18763 else if (STRINGP (car
) || CONSP (car
))
18765 Lisp_Object halftail
= elt
;
18769 && (precision
<= 0 || n
< precision
))
18771 n
+= display_mode_element (it
, depth
,
18772 /* Do padding only after the last
18773 element in the list. */
18774 (! CONSP (XCDR (elt
))
18777 precision
- n
, XCAR (elt
),
18781 if ((len
& 1) == 0)
18782 halftail
= XCDR (halftail
);
18783 /* Check for cycle. */
18784 if (EQ (halftail
, elt
))
18793 elt
= build_string ("*invalid*");
18797 /* Pad to FIELD_WIDTH. */
18798 if (field_width
> 0 && n
< field_width
)
18800 switch (mode_line_target
)
18802 case MODE_LINE_NOPROP
:
18803 case MODE_LINE_TITLE
:
18804 n
+= store_mode_line_noprop ("", field_width
- n
, 0);
18806 case MODE_LINE_STRING
:
18807 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
18809 case MODE_LINE_DISPLAY
:
18810 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
18819 /* Store a mode-line string element in mode_line_string_list.
18821 If STRING is non-null, display that C string. Otherwise, the Lisp
18822 string LISP_STRING is displayed.
18824 FIELD_WIDTH is the minimum number of output glyphs to produce.
18825 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18826 with spaces. FIELD_WIDTH <= 0 means don't pad.
18828 PRECISION is the maximum number of characters to output from
18829 STRING. PRECISION <= 0 means don't truncate the string.
18831 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18832 properties to the string.
18834 PROPS are the properties to add to the string.
18835 The mode_line_string_face face property is always added to the string.
18839 store_mode_line_string (char *string
, Lisp_Object lisp_string
, int copy_string
,
18840 int field_width
, int precision
, Lisp_Object props
)
18845 if (string
!= NULL
)
18847 len
= strlen (string
);
18848 if (precision
> 0 && len
> precision
)
18850 lisp_string
= make_string (string
, len
);
18852 props
= mode_line_string_face_prop
;
18853 else if (!NILP (mode_line_string_face
))
18855 Lisp_Object face
= Fplist_get (props
, Qface
);
18856 props
= Fcopy_sequence (props
);
18858 face
= mode_line_string_face
;
18860 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
18861 props
= Fplist_put (props
, Qface
, face
);
18863 Fadd_text_properties (make_number (0), make_number (len
),
18864 props
, lisp_string
);
18868 len
= XFASTINT (Flength (lisp_string
));
18869 if (precision
> 0 && len
> precision
)
18872 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
18875 if (!NILP (mode_line_string_face
))
18879 props
= Ftext_properties_at (make_number (0), lisp_string
);
18880 face
= Fplist_get (props
, Qface
);
18882 face
= mode_line_string_face
;
18884 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
18885 props
= Fcons (Qface
, Fcons (face
, Qnil
));
18887 lisp_string
= Fcopy_sequence (lisp_string
);
18890 Fadd_text_properties (make_number (0), make_number (len
),
18891 props
, lisp_string
);
18896 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
18900 if (field_width
> len
)
18902 field_width
-= len
;
18903 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
18905 Fadd_text_properties (make_number (0), make_number (field_width
),
18906 props
, lisp_string
);
18907 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
18915 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
18917 doc
: /* Format a string out of a mode line format specification.
18918 First arg FORMAT specifies the mode line format (see `mode-line-format'
18919 for details) to use.
18921 Optional second arg FACE specifies the face property to put
18922 on all characters for which no face is specified.
18923 The value t means whatever face the window's mode line currently uses
18924 \(either `mode-line' or `mode-line-inactive', depending).
18925 A value of nil means the default is no face property.
18926 If FACE is an integer, the value string has no text properties.
18928 Optional third and fourth args WINDOW and BUFFER specify the window
18929 and buffer to use as the context for the formatting (defaults
18930 are the selected window and the window's buffer). */)
18931 (Lisp_Object format
, Lisp_Object face
, Lisp_Object window
, Lisp_Object buffer
)
18936 struct buffer
*old_buffer
= NULL
;
18938 int no_props
= INTEGERP (face
);
18939 int count
= SPECPDL_INDEX ();
18941 int string_start
= 0;
18944 window
= selected_window
;
18945 CHECK_WINDOW (window
);
18946 w
= XWINDOW (window
);
18949 buffer
= w
->buffer
;
18950 CHECK_BUFFER (buffer
);
18952 /* Make formatting the modeline a non-op when noninteractive, otherwise
18953 there will be problems later caused by a partially initialized frame. */
18954 if (NILP (format
) || noninteractive
)
18955 return empty_unibyte_string
;
18963 face
= (EQ (window
, selected_window
) ? Qmode_line
: Qmode_line_inactive
);
18964 face_id
= lookup_named_face (XFRAME (WINDOW_FRAME (w
)), face
, 0);
18968 face_id
= DEFAULT_FACE_ID
;
18970 if (XBUFFER (buffer
) != current_buffer
)
18971 old_buffer
= current_buffer
;
18973 /* Save things including mode_line_proptrans_alist,
18974 and set that to nil so that we don't alter the outer value. */
18975 record_unwind_protect (unwind_format_mode_line
,
18976 format_mode_line_unwind_data
18977 (old_buffer
, selected_window
, 1));
18978 mode_line_proptrans_alist
= Qnil
;
18980 Fselect_window (window
, Qt
);
18982 set_buffer_internal_1 (XBUFFER (buffer
));
18984 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
18988 mode_line_target
= MODE_LINE_NOPROP
;
18989 mode_line_string_face_prop
= Qnil
;
18990 mode_line_string_list
= Qnil
;
18991 string_start
= MODE_LINE_NOPROP_LEN (0);
18995 mode_line_target
= MODE_LINE_STRING
;
18996 mode_line_string_list
= Qnil
;
18997 mode_line_string_face
= face
;
18998 mode_line_string_face_prop
18999 = (NILP (face
) ? Qnil
: Fcons (Qface
, Fcons (face
, Qnil
)));
19002 push_kboard (FRAME_KBOARD (it
.f
));
19003 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
19008 len
= MODE_LINE_NOPROP_LEN (string_start
);
19009 str
= make_string (mode_line_noprop_buf
+ string_start
, len
);
19013 mode_line_string_list
= Fnreverse (mode_line_string_list
);
19014 str
= Fmapconcat (intern ("identity"), mode_line_string_list
,
19015 empty_unibyte_string
);
19018 unbind_to (count
, Qnil
);
19022 /* Write a null-terminated, right justified decimal representation of
19023 the positive integer D to BUF using a minimal field width WIDTH. */
19026 pint2str (register char *buf
, register int width
, register int d
)
19028 register char *p
= buf
;
19036 *p
++ = d
% 10 + '0';
19041 for (width
-= (int) (p
- buf
); width
> 0; --width
)
19052 /* Write a null-terminated, right justified decimal and "human
19053 readable" representation of the nonnegative integer D to BUF using
19054 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19056 static const char power_letter
[] =
19070 pint2hrstr (char *buf
, int width
, int d
)
19072 /* We aim to represent the nonnegative integer D as
19073 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19076 /* -1 means: do not use TENTHS. */
19080 /* Length of QUOTIENT.TENTHS as a string. */
19086 if (1000 <= quotient
)
19088 /* Scale to the appropriate EXPONENT. */
19091 remainder
= quotient
% 1000;
19095 while (1000 <= quotient
);
19097 /* Round to nearest and decide whether to use TENTHS or not. */
19100 tenths
= remainder
/ 100;
19101 if (50 <= remainder
% 100)
19108 if (quotient
== 10)
19116 if (500 <= remainder
)
19118 if (quotient
< 999)
19129 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19130 if (tenths
== -1 && quotient
<= 99)
19137 p
= psuffix
= buf
+ max (width
, length
);
19139 /* Print EXPONENT. */
19141 *psuffix
++ = power_letter
[exponent
];
19144 /* Print TENTHS. */
19147 *--p
= '0' + tenths
;
19151 /* Print QUOTIENT. */
19154 int digit
= quotient
% 10;
19155 *--p
= '0' + digit
;
19157 while ((quotient
/= 10) != 0);
19159 /* Print leading spaces. */
19164 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19165 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19166 type of CODING_SYSTEM. Return updated pointer into BUF. */
19168 static unsigned char invalid_eol_type
[] = "(*invalid*)";
19171 decode_mode_spec_coding (Lisp_Object coding_system
, register char *buf
, int eol_flag
)
19174 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
19175 const unsigned char *eol_str
;
19177 /* The EOL conversion we are using. */
19178 Lisp_Object eoltype
;
19180 val
= CODING_SYSTEM_SPEC (coding_system
);
19183 if (!VECTORP (val
)) /* Not yet decided. */
19188 eoltype
= eol_mnemonic_undecided
;
19189 /* Don't mention EOL conversion if it isn't decided. */
19194 Lisp_Object eolvalue
;
19196 attrs
= AREF (val
, 0);
19197 eolvalue
= AREF (val
, 2);
19200 *buf
++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs
));
19204 /* The EOL conversion that is normal on this system. */
19206 if (NILP (eolvalue
)) /* Not yet decided. */
19207 eoltype
= eol_mnemonic_undecided
;
19208 else if (VECTORP (eolvalue
)) /* Not yet decided. */
19209 eoltype
= eol_mnemonic_undecided
;
19210 else /* eolvalue is Qunix, Qdos, or Qmac. */
19211 eoltype
= (EQ (eolvalue
, Qunix
)
19212 ? eol_mnemonic_unix
19213 : (EQ (eolvalue
, Qdos
) == 1
19214 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
19220 /* Mention the EOL conversion if it is not the usual one. */
19221 if (STRINGP (eoltype
))
19223 eol_str
= SDATA (eoltype
);
19224 eol_str_len
= SBYTES (eoltype
);
19226 else if (CHARACTERP (eoltype
))
19228 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
19229 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
19234 eol_str
= invalid_eol_type
;
19235 eol_str_len
= sizeof (invalid_eol_type
) - 1;
19237 memcpy (buf
, eol_str
, eol_str_len
);
19238 buf
+= eol_str_len
;
19244 /* Return a string for the output of a mode line %-spec for window W,
19245 generated by character C. PRECISION >= 0 means don't return a
19246 string longer than that value. FIELD_WIDTH > 0 means pad the
19247 string returned with spaces to that value. Return a Lisp string in
19248 *STRING if the resulting string is taken from that Lisp string.
19250 Note we operate on the current buffer for most purposes,
19251 the exception being w->base_line_pos. */
19253 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19256 decode_mode_spec (struct window
*w
, register int c
, int field_width
,
19257 int precision
, Lisp_Object
*string
)
19260 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
19261 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
19262 struct buffer
*b
= current_buffer
;
19270 if (!NILP (b
->read_only
))
19272 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
19277 /* This differs from %* only for a modified read-only buffer. */
19278 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
19280 if (!NILP (b
->read_only
))
19285 /* This differs from %* in ignoring read-only-ness. */
19286 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
19298 if (command_loop_level
> 5)
19300 p
= decode_mode_spec_buf
;
19301 for (i
= 0; i
< command_loop_level
; i
++)
19304 return decode_mode_spec_buf
;
19312 if (command_loop_level
> 5)
19314 p
= decode_mode_spec_buf
;
19315 for (i
= 0; i
< command_loop_level
; i
++)
19318 return decode_mode_spec_buf
;
19325 /* Let lots_of_dashes be a string of infinite length. */
19326 if (mode_line_target
== MODE_LINE_NOPROP
||
19327 mode_line_target
== MODE_LINE_STRING
)
19329 if (field_width
<= 0
19330 || field_width
> sizeof (lots_of_dashes
))
19332 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
19333 decode_mode_spec_buf
[i
] = '-';
19334 decode_mode_spec_buf
[i
] = '\0';
19335 return decode_mode_spec_buf
;
19338 return lots_of_dashes
;
19346 /* %c and %l are ignored in `frame-title-format'.
19347 (In redisplay_internal, the frame title is drawn _before_ the
19348 windows are updated, so the stuff which depends on actual
19349 window contents (such as %l) may fail to render properly, or
19350 even crash emacs.) */
19351 if (mode_line_target
== MODE_LINE_TITLE
)
19355 int col
= (int) current_column (); /* iftc */
19356 w
->column_number_displayed
= make_number (col
);
19357 pint2str (decode_mode_spec_buf
, field_width
, col
);
19358 return decode_mode_spec_buf
;
19362 #ifndef SYSTEM_MALLOC
19364 if (NILP (Vmemory_full
))
19367 return "!MEM FULL! ";
19374 /* %F displays the frame name. */
19375 if (!NILP (f
->title
))
19376 return (char *) SDATA (f
->title
);
19377 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
19378 return (char *) SDATA (f
->name
);
19387 int size
= ZV
- BEGV
;
19388 pint2str (decode_mode_spec_buf
, field_width
, size
);
19389 return decode_mode_spec_buf
;
19394 int size
= ZV
- BEGV
;
19395 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
19396 return decode_mode_spec_buf
;
19401 int startpos
, startpos_byte
, line
, linepos
, linepos_byte
;
19402 int topline
, nlines
, junk
, height
;
19404 /* %c and %l are ignored in `frame-title-format'. */
19405 if (mode_line_target
== MODE_LINE_TITLE
)
19408 startpos
= XMARKER (w
->start
)->charpos
;
19409 startpos_byte
= marker_byte_position (w
->start
);
19410 height
= WINDOW_TOTAL_LINES (w
);
19412 /* If we decided that this buffer isn't suitable for line numbers,
19413 don't forget that too fast. */
19414 if (EQ (w
->base_line_pos
, w
->buffer
))
19416 /* But do forget it, if the window shows a different buffer now. */
19417 else if (BUFFERP (w
->base_line_pos
))
19418 w
->base_line_pos
= Qnil
;
19420 /* If the buffer is very big, don't waste time. */
19421 if (INTEGERP (Vline_number_display_limit
)
19422 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
19424 w
->base_line_pos
= Qnil
;
19425 w
->base_line_number
= Qnil
;
19429 if (INTEGERP (w
->base_line_number
)
19430 && INTEGERP (w
->base_line_pos
)
19431 && XFASTINT (w
->base_line_pos
) <= startpos
)
19433 line
= XFASTINT (w
->base_line_number
);
19434 linepos
= XFASTINT (w
->base_line_pos
);
19435 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
19440 linepos
= BUF_BEGV (b
);
19441 linepos_byte
= BUF_BEGV_BYTE (b
);
19444 /* Count lines from base line to window start position. */
19445 nlines
= display_count_lines (linepos
, linepos_byte
,
19449 topline
= nlines
+ line
;
19451 /* Determine a new base line, if the old one is too close
19452 or too far away, or if we did not have one.
19453 "Too close" means it's plausible a scroll-down would
19454 go back past it. */
19455 if (startpos
== BUF_BEGV (b
))
19457 w
->base_line_number
= make_number (topline
);
19458 w
->base_line_pos
= make_number (BUF_BEGV (b
));
19460 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
19461 || linepos
== BUF_BEGV (b
))
19463 int limit
= BUF_BEGV (b
);
19464 int limit_byte
= BUF_BEGV_BYTE (b
);
19466 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
19468 if (startpos
- distance
> limit
)
19470 limit
= startpos
- distance
;
19471 limit_byte
= CHAR_TO_BYTE (limit
);
19474 nlines
= display_count_lines (startpos
, startpos_byte
,
19476 - (height
* 2 + 30),
19478 /* If we couldn't find the lines we wanted within
19479 line_number_display_limit_width chars per line,
19480 give up on line numbers for this window. */
19481 if (position
== limit_byte
&& limit
== startpos
- distance
)
19483 w
->base_line_pos
= w
->buffer
;
19484 w
->base_line_number
= Qnil
;
19488 w
->base_line_number
= make_number (topline
- nlines
);
19489 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
19492 /* Now count lines from the start pos to point. */
19493 nlines
= display_count_lines (startpos
, startpos_byte
,
19494 PT_BYTE
, PT
, &junk
);
19496 /* Record that we did display the line number. */
19497 line_number_displayed
= 1;
19499 /* Make the string to show. */
19500 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
19501 return decode_mode_spec_buf
;
19504 char* p
= decode_mode_spec_buf
;
19505 int pad
= field_width
- 2;
19511 return decode_mode_spec_buf
;
19517 obj
= b
->mode_name
;
19521 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
19527 int pos
= marker_position (w
->start
);
19528 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
19530 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
19532 if (pos
<= BUF_BEGV (b
))
19537 else if (pos
<= BUF_BEGV (b
))
19541 if (total
> 1000000)
19542 /* Do it differently for a large value, to avoid overflow. */
19543 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
19545 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
19546 /* We can't normally display a 3-digit number,
19547 so get us a 2-digit number that is close. */
19550 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
19551 return decode_mode_spec_buf
;
19555 /* Display percentage of size above the bottom of the screen. */
19558 int toppos
= marker_position (w
->start
);
19559 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
19560 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
19562 if (botpos
>= BUF_ZV (b
))
19564 if (toppos
<= BUF_BEGV (b
))
19571 if (total
> 1000000)
19572 /* Do it differently for a large value, to avoid overflow. */
19573 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
19575 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
19576 /* We can't normally display a 3-digit number,
19577 so get us a 2-digit number that is close. */
19580 if (toppos
<= BUF_BEGV (b
))
19581 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
19583 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
19584 return decode_mode_spec_buf
;
19589 /* status of process */
19590 obj
= Fget_buffer_process (Fcurrent_buffer ());
19592 return "no process";
19594 obj
= Fsymbol_name (Fprocess_status (obj
));
19600 int count
= inhibit_garbage_collection ();
19601 Lisp_Object val
= call1 (intern ("file-remote-p"),
19602 current_buffer
->directory
);
19603 unbind_to (count
, Qnil
);
19611 case 't': /* indicate TEXT or BINARY */
19612 #ifdef MODE_LINE_BINARY_TEXT
19613 return MODE_LINE_BINARY_TEXT (b
);
19619 /* coding-system (not including end-of-line format) */
19621 /* coding-system (including end-of-line type) */
19623 int eol_flag
= (c
== 'Z');
19624 char *p
= decode_mode_spec_buf
;
19626 if (! FRAME_WINDOW_P (f
))
19628 /* No need to mention EOL here--the terminal never needs
19629 to do EOL conversion. */
19630 p
= decode_mode_spec_coding (CODING_ID_NAME
19631 (FRAME_KEYBOARD_CODING (f
)->id
),
19633 p
= decode_mode_spec_coding (CODING_ID_NAME
19634 (FRAME_TERMINAL_CODING (f
)->id
),
19637 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
19640 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19641 #ifdef subprocesses
19642 obj
= Fget_buffer_process (Fcurrent_buffer ());
19643 if (PROCESSP (obj
))
19645 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
19647 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
19650 #endif /* subprocesses */
19653 return decode_mode_spec_buf
;
19660 return (char *) SDATA (obj
);
19667 /* Count up to COUNT lines starting from START / START_BYTE.
19668 But don't go beyond LIMIT_BYTE.
19669 Return the number of lines thus found (always nonnegative).
19671 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19674 display_count_lines (int start
, int start_byte
, int limit_byte
, int count
,
19677 register unsigned char *cursor
;
19678 unsigned char *base
;
19680 register int ceiling
;
19681 register unsigned char *ceiling_addr
;
19682 int orig_count
= count
;
19684 /* If we are not in selective display mode,
19685 check only for newlines. */
19686 int selective_display
= (!NILP (current_buffer
->selective_display
)
19687 && !INTEGERP (current_buffer
->selective_display
));
19691 while (start_byte
< limit_byte
)
19693 ceiling
= BUFFER_CEILING_OF (start_byte
);
19694 ceiling
= min (limit_byte
- 1, ceiling
);
19695 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
19696 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
19699 if (selective_display
)
19700 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
19703 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
19706 if (cursor
!= ceiling_addr
)
19710 start_byte
+= cursor
- base
+ 1;
19711 *byte_pos_ptr
= start_byte
;
19715 if (++cursor
== ceiling_addr
)
19721 start_byte
+= cursor
- base
;
19726 while (start_byte
> limit_byte
)
19728 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
19729 ceiling
= max (limit_byte
, ceiling
);
19730 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
19731 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
19734 if (selective_display
)
19735 while (--cursor
!= ceiling_addr
19736 && *cursor
!= '\n' && *cursor
!= 015)
19739 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
19742 if (cursor
!= ceiling_addr
)
19746 start_byte
+= cursor
- base
+ 1;
19747 *byte_pos_ptr
= start_byte
;
19748 /* When scanning backwards, we should
19749 not count the newline posterior to which we stop. */
19750 return - orig_count
- 1;
19756 /* Here we add 1 to compensate for the last decrement
19757 of CURSOR, which took it past the valid range. */
19758 start_byte
+= cursor
- base
+ 1;
19762 *byte_pos_ptr
= limit_byte
;
19765 return - orig_count
+ count
;
19766 return orig_count
- count
;
19772 /***********************************************************************
19774 ***********************************************************************/
19776 /* Display a NUL-terminated string, starting with index START.
19778 If STRING is non-null, display that C string. Otherwise, the Lisp
19779 string LISP_STRING is displayed. There's a case that STRING is
19780 non-null and LISP_STRING is not nil. It means STRING is a string
19781 data of LISP_STRING. In that case, we display LISP_STRING while
19782 ignoring its text properties.
19784 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19785 FACE_STRING. Display STRING or LISP_STRING with the face at
19786 FACE_STRING_POS in FACE_STRING:
19788 Display the string in the environment given by IT, but use the
19789 standard display table, temporarily.
19791 FIELD_WIDTH is the minimum number of output glyphs to produce.
19792 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19793 with spaces. If STRING has more characters, more than FIELD_WIDTH
19794 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19796 PRECISION is the maximum number of characters to output from
19797 STRING. PRECISION < 0 means don't truncate the string.
19799 This is roughly equivalent to printf format specifiers:
19801 FIELD_WIDTH PRECISION PRINTF
19802 ----------------------------------------
19808 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19809 display them, and < 0 means obey the current buffer's value of
19810 enable_multibyte_characters.
19812 Value is the number of columns displayed. */
19815 display_string (unsigned char *string
, Lisp_Object lisp_string
, Lisp_Object face_string
,
19816 EMACS_INT face_string_pos
, EMACS_INT start
, struct it
*it
,
19817 int field_width
, int precision
, int max_x
, int multibyte
)
19819 int hpos_at_start
= it
->hpos
;
19820 int saved_face_id
= it
->face_id
;
19821 struct glyph_row
*row
= it
->glyph_row
;
19823 /* Initialize the iterator IT for iteration over STRING beginning
19824 with index START. */
19825 reseat_to_string (it
, NILP (lisp_string
) ? string
: NULL
, lisp_string
, start
,
19826 precision
, field_width
, multibyte
);
19827 if (string
&& STRINGP (lisp_string
))
19828 /* LISP_STRING is the one returned by decode_mode_spec. We should
19829 ignore its text properties. */
19830 it
->stop_charpos
= -1;
19832 /* If displaying STRING, set up the face of the iterator
19833 from LISP_STRING, if that's given. */
19834 if (STRINGP (face_string
))
19840 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
19841 0, it
->region_beg_charpos
,
19842 it
->region_end_charpos
,
19843 &endptr
, it
->base_face_id
, 0);
19844 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19845 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
19848 /* Set max_x to the maximum allowed X position. Don't let it go
19849 beyond the right edge of the window. */
19851 max_x
= it
->last_visible_x
;
19853 max_x
= min (max_x
, it
->last_visible_x
);
19855 /* Skip over display elements that are not visible. because IT->w is
19857 if (it
->current_x
< it
->first_visible_x
)
19858 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
19859 MOVE_TO_POS
| MOVE_TO_X
);
19861 row
->ascent
= it
->max_ascent
;
19862 row
->height
= it
->max_ascent
+ it
->max_descent
;
19863 row
->phys_ascent
= it
->max_phys_ascent
;
19864 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
19865 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
19867 /* This condition is for the case that we are called with current_x
19868 past last_visible_x. */
19869 while (it
->current_x
< max_x
)
19871 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
19873 /* Get the next display element. */
19874 if (!get_next_display_element (it
))
19877 /* Produce glyphs. */
19878 x_before
= it
->current_x
;
19879 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
19880 PRODUCE_GLYPHS (it
);
19882 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
19885 while (i
< nglyphs
)
19887 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
19889 if (it
->line_wrap
!= TRUNCATE
19890 && x
+ glyph
->pixel_width
> max_x
)
19892 /* End of continued line or max_x reached. */
19893 if (CHAR_GLYPH_PADDING_P (*glyph
))
19895 /* A wide character is unbreakable. */
19896 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
19897 it
->current_x
= x_before
;
19901 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
19906 else if (x
+ glyph
->pixel_width
>= it
->first_visible_x
)
19908 /* Glyph is at least partially visible. */
19910 if (x
< it
->first_visible_x
)
19911 it
->glyph_row
->x
= x
- it
->first_visible_x
;
19915 /* Glyph is off the left margin of the display area.
19916 Should not happen. */
19920 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19921 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19922 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19923 row
->phys_height
= max (row
->phys_height
,
19924 it
->max_phys_ascent
+ it
->max_phys_descent
);
19925 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19926 it
->max_extra_line_spacing
);
19927 x
+= glyph
->pixel_width
;
19931 /* Stop if max_x reached. */
19935 /* Stop at line ends. */
19936 if (ITERATOR_AT_END_OF_LINE_P (it
))
19938 it
->continuation_lines_width
= 0;
19942 set_iterator_to_next (it
, 1);
19944 /* Stop if truncating at the right edge. */
19945 if (it
->line_wrap
== TRUNCATE
19946 && it
->current_x
>= it
->last_visible_x
)
19948 /* Add truncation mark, but don't do it if the line is
19949 truncated at a padding space. */
19950 if (IT_CHARPOS (*it
) < it
->string_nchars
)
19952 if (!FRAME_WINDOW_P (it
->f
))
19956 if (it
->current_x
> it
->last_visible_x
)
19958 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
19959 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
19961 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
19963 row
->used
[TEXT_AREA
] = i
;
19964 produce_special_glyphs (it
, IT_TRUNCATION
);
19967 produce_special_glyphs (it
, IT_TRUNCATION
);
19969 it
->glyph_row
->truncated_on_right_p
= 1;
19975 /* Maybe insert a truncation at the left. */
19976 if (it
->first_visible_x
19977 && IT_CHARPOS (*it
) > 0)
19979 if (!FRAME_WINDOW_P (it
->f
))
19980 insert_left_trunc_glyphs (it
);
19981 it
->glyph_row
->truncated_on_left_p
= 1;
19984 it
->face_id
= saved_face_id
;
19986 /* Value is number of columns displayed. */
19987 return it
->hpos
- hpos_at_start
;
19992 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
19993 appears as an element of LIST or as the car of an element of LIST.
19994 If PROPVAL is a list, compare each element against LIST in that
19995 way, and return 1/2 if any element of PROPVAL is found in LIST.
19996 Otherwise return 0. This function cannot quit.
19997 The return value is 2 if the text is invisible but with an ellipsis
19998 and 1 if it's invisible and without an ellipsis. */
20001 invisible_p (register Lisp_Object propval
, Lisp_Object list
)
20003 register Lisp_Object tail
, proptail
;
20005 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
20007 register Lisp_Object tem
;
20009 if (EQ (propval
, tem
))
20011 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
20012 return NILP (XCDR (tem
)) ? 1 : 2;
20015 if (CONSP (propval
))
20017 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
20019 Lisp_Object propelt
;
20020 propelt
= XCAR (proptail
);
20021 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
20023 register Lisp_Object tem
;
20025 if (EQ (propelt
, tem
))
20027 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
20028 return NILP (XCDR (tem
)) ? 1 : 2;
20036 DEFUN ("invisible-p", Finvisible_p
, Sinvisible_p
, 1, 1, 0,
20037 doc
: /* Non-nil if the property makes the text invisible.
20038 POS-OR-PROP can be a marker or number, in which case it is taken to be
20039 a position in the current buffer and the value of the `invisible' property
20040 is checked; or it can be some other value, which is then presumed to be the
20041 value of the `invisible' property of the text of interest.
20042 The non-nil value returned can be t for truly invisible text or something
20043 else if the text is replaced by an ellipsis. */)
20044 (Lisp_Object pos_or_prop
)
20047 = (NATNUMP (pos_or_prop
) || MARKERP (pos_or_prop
)
20048 ? Fget_char_property (pos_or_prop
, Qinvisible
, Qnil
)
20050 int invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
20051 return (invis
== 0 ? Qnil
20053 : make_number (invis
));
20056 /* Calculate a width or height in pixels from a specification using
20057 the following elements:
20060 NUM - a (fractional) multiple of the default font width/height
20061 (NUM) - specifies exactly NUM pixels
20062 UNIT - a fixed number of pixels, see below.
20063 ELEMENT - size of a display element in pixels, see below.
20064 (NUM . SPEC) - equals NUM * SPEC
20065 (+ SPEC SPEC ...) - add pixel values
20066 (- SPEC SPEC ...) - subtract pixel values
20067 (- SPEC) - negate pixel value
20070 INT or FLOAT - a number constant
20071 SYMBOL - use symbol's (buffer local) variable binding.
20074 in - pixels per inch *)
20075 mm - pixels per 1/1000 meter *)
20076 cm - pixels per 1/100 meter *)
20077 width - width of current font in pixels.
20078 height - height of current font in pixels.
20080 *) using the ratio(s) defined in display-pixels-per-inch.
20084 left-fringe - left fringe width in pixels
20085 right-fringe - right fringe width in pixels
20087 left-margin - left margin width in pixels
20088 right-margin - right margin width in pixels
20090 scroll-bar - scroll-bar area width in pixels
20094 Pixels corresponding to 5 inches:
20097 Total width of non-text areas on left side of window (if scroll-bar is on left):
20098 '(space :width (+ left-fringe left-margin scroll-bar))
20100 Align to first text column (in header line):
20101 '(space :align-to 0)
20103 Align to middle of text area minus half the width of variable `my-image'
20104 containing a loaded image:
20105 '(space :align-to (0.5 . (- text my-image)))
20107 Width of left margin minus width of 1 character in the default font:
20108 '(space :width (- left-margin 1))
20110 Width of left margin minus width of 2 characters in the current font:
20111 '(space :width (- left-margin (2 . width)))
20113 Center 1 character over left-margin (in header line):
20114 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20116 Different ways to express width of left fringe plus left margin minus one pixel:
20117 '(space :width (- (+ left-fringe left-margin) (1)))
20118 '(space :width (+ left-fringe left-margin (- (1))))
20119 '(space :width (+ left-fringe left-margin (-1)))
20123 #define NUMVAL(X) \
20124 ((INTEGERP (X) || FLOATP (X)) \
20129 calc_pixel_width_or_height (double *res
, struct it
*it
, Lisp_Object prop
,
20130 struct font
*font
, int width_p
, int *align_to
)
20134 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20135 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20138 return OK_PIXELS (0);
20140 xassert (FRAME_LIVE_P (it
->f
));
20142 if (SYMBOLP (prop
))
20144 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
20146 char *unit
= SDATA (SYMBOL_NAME (prop
));
20148 if (unit
[0] == 'i' && unit
[1] == 'n')
20150 else if (unit
[0] == 'm' && unit
[1] == 'm')
20152 else if (unit
[0] == 'c' && unit
[1] == 'm')
20159 #ifdef HAVE_WINDOW_SYSTEM
20160 if (FRAME_WINDOW_P (it
->f
)
20162 ? FRAME_X_DISPLAY_INFO (it
->f
)->resx
20163 : FRAME_X_DISPLAY_INFO (it
->f
)->resy
),
20165 return OK_PIXELS (ppi
/ pixels
);
20168 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
20169 || (CONSP (Vdisplay_pixels_per_inch
)
20171 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
20172 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
20174 return OK_PIXELS (ppi
/ pixels
);
20180 #ifdef HAVE_WINDOW_SYSTEM
20181 if (EQ (prop
, Qheight
))
20182 return OK_PIXELS (font
? FONT_HEIGHT (font
) : FRAME_LINE_HEIGHT (it
->f
));
20183 if (EQ (prop
, Qwidth
))
20184 return OK_PIXELS (font
? FONT_WIDTH (font
) : FRAME_COLUMN_WIDTH (it
->f
));
20186 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
20187 return OK_PIXELS (1);
20190 if (EQ (prop
, Qtext
))
20191 return OK_PIXELS (width_p
20192 ? window_box_width (it
->w
, TEXT_AREA
)
20193 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
20195 if (align_to
&& *align_to
< 0)
20198 if (EQ (prop
, Qleft
))
20199 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
20200 if (EQ (prop
, Qright
))
20201 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
20202 if (EQ (prop
, Qcenter
))
20203 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
20204 + window_box_width (it
->w
, TEXT_AREA
) / 2);
20205 if (EQ (prop
, Qleft_fringe
))
20206 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
20207 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
20208 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
20209 if (EQ (prop
, Qright_fringe
))
20210 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
20211 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
20212 : window_box_right_offset (it
->w
, TEXT_AREA
));
20213 if (EQ (prop
, Qleft_margin
))
20214 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
20215 if (EQ (prop
, Qright_margin
))
20216 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
20217 if (EQ (prop
, Qscroll_bar
))
20218 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
20220 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
20221 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
20222 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
20227 if (EQ (prop
, Qleft_fringe
))
20228 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
20229 if (EQ (prop
, Qright_fringe
))
20230 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
20231 if (EQ (prop
, Qleft_margin
))
20232 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
20233 if (EQ (prop
, Qright_margin
))
20234 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
20235 if (EQ (prop
, Qscroll_bar
))
20236 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
20239 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
20242 if (INTEGERP (prop
) || FLOATP (prop
))
20244 int base_unit
= (width_p
20245 ? FRAME_COLUMN_WIDTH (it
->f
)
20246 : FRAME_LINE_HEIGHT (it
->f
));
20247 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
20252 Lisp_Object car
= XCAR (prop
);
20253 Lisp_Object cdr
= XCDR (prop
);
20257 #ifdef HAVE_WINDOW_SYSTEM
20258 if (FRAME_WINDOW_P (it
->f
)
20259 && valid_image_p (prop
))
20261 int id
= lookup_image (it
->f
, prop
);
20262 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
20264 return OK_PIXELS (width_p
? img
->width
: img
->height
);
20267 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
20273 while (CONSP (cdr
))
20275 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
20276 font
, width_p
, align_to
))
20279 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
20284 if (EQ (car
, Qminus
))
20286 return OK_PIXELS (pixels
);
20289 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
20292 if (INTEGERP (car
) || FLOATP (car
))
20295 pixels
= XFLOATINT (car
);
20297 return OK_PIXELS (pixels
);
20298 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
20299 font
, width_p
, align_to
))
20300 return OK_PIXELS (pixels
* fact
);
20311 /***********************************************************************
20313 ***********************************************************************/
20315 #ifdef HAVE_WINDOW_SYSTEM
20320 dump_glyph_string (s
)
20321 struct glyph_string
*s
;
20323 fprintf (stderr
, "glyph string\n");
20324 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
20325 s
->x
, s
->y
, s
->width
, s
->height
);
20326 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
20327 fprintf (stderr
, " hl = %d\n", s
->hl
);
20328 fprintf (stderr
, " left overhang = %d, right = %d\n",
20329 s
->left_overhang
, s
->right_overhang
);
20330 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
20331 fprintf (stderr
, " extends to end of line = %d\n",
20332 s
->extends_to_end_of_line_p
);
20333 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
20334 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
20337 #endif /* GLYPH_DEBUG */
20339 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20340 of XChar2b structures for S; it can't be allocated in
20341 init_glyph_string because it must be allocated via `alloca'. W
20342 is the window on which S is drawn. ROW and AREA are the glyph row
20343 and area within the row from which S is constructed. START is the
20344 index of the first glyph structure covered by S. HL is a
20345 face-override for drawing S. */
20348 #define OPTIONAL_HDC(hdc) HDC hdc,
20349 #define DECLARE_HDC(hdc) HDC hdc;
20350 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20351 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20354 #ifndef OPTIONAL_HDC
20355 #define OPTIONAL_HDC(hdc)
20356 #define DECLARE_HDC(hdc)
20357 #define ALLOCATE_HDC(hdc, f)
20358 #define RELEASE_HDC(hdc, f)
20362 init_glyph_string (struct glyph_string
*s
,
20364 XChar2b
*char2b
, struct window
*w
, struct glyph_row
*row
,
20365 enum glyph_row_area area
, int start
, enum draw_glyphs_face hl
)
20367 memset (s
, 0, sizeof *s
);
20369 s
->f
= XFRAME (w
->frame
);
20373 s
->display
= FRAME_X_DISPLAY (s
->f
);
20374 s
->window
= FRAME_X_WINDOW (s
->f
);
20375 s
->char2b
= char2b
;
20379 s
->first_glyph
= row
->glyphs
[area
] + start
;
20380 s
->height
= row
->height
;
20381 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
20382 s
->ybase
= s
->y
+ row
->ascent
;
20386 /* Append the list of glyph strings with head H and tail T to the list
20387 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20390 append_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
20391 struct glyph_string
*h
, struct glyph_string
*t
)
20405 /* Prepend the list of glyph strings with head H and tail T to the
20406 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20410 prepend_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
20411 struct glyph_string
*h
, struct glyph_string
*t
)
20425 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20426 Set *HEAD and *TAIL to the resulting list. */
20429 append_glyph_string (struct glyph_string
**head
, struct glyph_string
**tail
,
20430 struct glyph_string
*s
)
20432 s
->next
= s
->prev
= NULL
;
20433 append_glyph_string_lists (head
, tail
, s
, s
);
20437 /* Get face and two-byte form of character C in face FACE_ID on frame
20438 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
20439 means we want to display multibyte text. DISPLAY_P non-zero means
20440 make sure that X resources for the face returned are allocated.
20441 Value is a pointer to a realized face that is ready for display if
20442 DISPLAY_P is non-zero. */
20444 static INLINE
struct face
*
20445 get_char_face_and_encoding (struct frame
*f
, int c
, int face_id
,
20446 XChar2b
*char2b
, int multibyte_p
, int display_p
)
20448 struct face
*face
= FACE_FROM_ID (f
, face_id
);
20452 unsigned code
= face
->font
->driver
->encode_char (face
->font
, c
);
20454 if (code
!= FONT_INVALID_CODE
)
20455 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
20457 STORE_XCHAR2B (char2b
, 0, 0);
20460 /* Make sure X resources of the face are allocated. */
20461 #ifdef HAVE_X_WINDOWS
20465 xassert (face
!= NULL
);
20466 PREPARE_FACE_FOR_DISPLAY (f
, face
);
20473 /* Get face and two-byte form of character glyph GLYPH on frame F.
20474 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20475 a pointer to a realized face that is ready for display. */
20477 static INLINE
struct face
*
20478 get_glyph_face_and_encoding (struct frame
*f
, struct glyph
*glyph
,
20479 XChar2b
*char2b
, int *two_byte_p
)
20483 xassert (glyph
->type
== CHAR_GLYPH
);
20484 face
= FACE_FROM_ID (f
, glyph
->face_id
);
20491 unsigned code
= face
->font
->driver
->encode_char (face
->font
, glyph
->u
.ch
);
20493 if (code
!= FONT_INVALID_CODE
)
20494 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
20496 STORE_XCHAR2B (char2b
, 0, 0);
20499 /* Make sure X resources of the face are allocated. */
20500 xassert (face
!= NULL
);
20501 PREPARE_FACE_FOR_DISPLAY (f
, face
);
20506 /* Fill glyph string S with composition components specified by S->cmp.
20508 BASE_FACE is the base face of the composition.
20509 S->cmp_from is the index of the first component for S.
20511 OVERLAPS non-zero means S should draw the foreground only, and use
20512 its physical height for clipping. See also draw_glyphs.
20514 Value is the index of a component not in S. */
20517 fill_composite_glyph_string (struct glyph_string
*s
, struct face
*base_face
,
20521 /* For all glyphs of this composition, starting at the offset
20522 S->cmp_from, until we reach the end of the definition or encounter a
20523 glyph that requires the different face, add it to S. */
20528 s
->for_overlaps
= overlaps
;
20531 for (i
= s
->cmp_from
; i
< s
->cmp
->glyph_len
; i
++)
20533 int c
= COMPOSITION_GLYPH (s
->cmp
, i
);
20537 int face_id
= FACE_FOR_CHAR (s
->f
, base_face
->ascii_face
, c
,
20540 face
= get_char_face_and_encoding (s
->f
, c
, face_id
,
20541 s
->char2b
+ i
, 1, 1);
20547 s
->font
= s
->face
->font
;
20549 else if (s
->face
!= face
)
20557 /* All glyph strings for the same composition has the same width,
20558 i.e. the width set for the first component of the composition. */
20559 s
->width
= s
->first_glyph
->pixel_width
;
20561 /* If the specified font could not be loaded, use the frame's
20562 default font, but record the fact that we couldn't load it in
20563 the glyph string so that we can draw rectangles for the
20564 characters of the glyph string. */
20565 if (s
->font
== NULL
)
20567 s
->font_not_found_p
= 1;
20568 s
->font
= FRAME_FONT (s
->f
);
20571 /* Adjust base line for subscript/superscript text. */
20572 s
->ybase
+= s
->first_glyph
->voffset
;
20574 /* This glyph string must always be drawn with 16-bit functions. */
20581 fill_gstring_glyph_string (struct glyph_string
*s
, int face_id
,
20582 int start
, int end
, int overlaps
)
20584 struct glyph
*glyph
, *last
;
20585 Lisp_Object lgstring
;
20588 s
->for_overlaps
= overlaps
;
20589 glyph
= s
->row
->glyphs
[s
->area
] + start
;
20590 last
= s
->row
->glyphs
[s
->area
] + end
;
20591 s
->cmp_id
= glyph
->u
.cmp
.id
;
20592 s
->cmp_from
= glyph
->u
.cmp
.from
;
20593 s
->cmp_to
= glyph
->u
.cmp
.to
+ 1;
20594 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
20595 lgstring
= composition_gstring_from_id (s
->cmp_id
);
20596 s
->font
= XFONT_OBJECT (LGSTRING_FONT (lgstring
));
20598 while (glyph
< last
20599 && glyph
->u
.cmp
.automatic
20600 && glyph
->u
.cmp
.id
== s
->cmp_id
20601 && s
->cmp_to
== glyph
->u
.cmp
.from
)
20602 s
->cmp_to
= (glyph
++)->u
.cmp
.to
+ 1;
20604 for (i
= s
->cmp_from
; i
< s
->cmp_to
; i
++)
20606 Lisp_Object lglyph
= LGSTRING_GLYPH (lgstring
, i
);
20607 unsigned code
= LGLYPH_CODE (lglyph
);
20609 STORE_XCHAR2B ((s
->char2b
+ i
), code
>> 8, code
& 0xFF);
20611 s
->width
= composition_gstring_width (lgstring
, s
->cmp_from
, s
->cmp_to
, NULL
);
20612 return glyph
- s
->row
->glyphs
[s
->area
];
20616 /* Fill glyph string S from a sequence of character glyphs.
20618 FACE_ID is the face id of the string. START is the index of the
20619 first glyph to consider, END is the index of the last + 1.
20620 OVERLAPS non-zero means S should draw the foreground only, and use
20621 its physical height for clipping. See also draw_glyphs.
20623 Value is the index of the first glyph not in S. */
20626 fill_glyph_string (struct glyph_string
*s
, int face_id
,
20627 int start
, int end
, int overlaps
)
20629 struct glyph
*glyph
, *last
;
20631 int glyph_not_available_p
;
20633 xassert (s
->f
== XFRAME (s
->w
->frame
));
20634 xassert (s
->nchars
== 0);
20635 xassert (start
>= 0 && end
> start
);
20637 s
->for_overlaps
= overlaps
;
20638 glyph
= s
->row
->glyphs
[s
->area
] + start
;
20639 last
= s
->row
->glyphs
[s
->area
] + end
;
20640 voffset
= glyph
->voffset
;
20641 s
->padding_p
= glyph
->padding_p
;
20642 glyph_not_available_p
= glyph
->glyph_not_available_p
;
20644 while (glyph
< last
20645 && glyph
->type
== CHAR_GLYPH
20646 && glyph
->voffset
== voffset
20647 /* Same face id implies same font, nowadays. */
20648 && glyph
->face_id
== face_id
20649 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
20653 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
20654 s
->char2b
+ s
->nchars
,
20656 s
->two_byte_p
= two_byte_p
;
20658 xassert (s
->nchars
<= end
- start
);
20659 s
->width
+= glyph
->pixel_width
;
20660 if (glyph
++->padding_p
!= s
->padding_p
)
20664 s
->font
= s
->face
->font
;
20666 /* If the specified font could not be loaded, use the frame's font,
20667 but record the fact that we couldn't load it in
20668 S->font_not_found_p so that we can draw rectangles for the
20669 characters of the glyph string. */
20670 if (s
->font
== NULL
|| glyph_not_available_p
)
20672 s
->font_not_found_p
= 1;
20673 s
->font
= FRAME_FONT (s
->f
);
20676 /* Adjust base line for subscript/superscript text. */
20677 s
->ybase
+= voffset
;
20679 xassert (s
->face
&& s
->face
->gc
);
20680 return glyph
- s
->row
->glyphs
[s
->area
];
20684 /* Fill glyph string S from image glyph S->first_glyph. */
20687 fill_image_glyph_string (struct glyph_string
*s
)
20689 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
20690 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
20692 s
->slice
= s
->first_glyph
->slice
;
20693 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
20694 s
->font
= s
->face
->font
;
20695 s
->width
= s
->first_glyph
->pixel_width
;
20697 /* Adjust base line for subscript/superscript text. */
20698 s
->ybase
+= s
->first_glyph
->voffset
;
20702 /* Fill glyph string S from a sequence of stretch glyphs.
20704 ROW is the glyph row in which the glyphs are found, AREA is the
20705 area within the row. START is the index of the first glyph to
20706 consider, END is the index of the last + 1.
20708 Value is the index of the first glyph not in S. */
20711 fill_stretch_glyph_string (struct glyph_string
*s
, struct glyph_row
*row
,
20712 enum glyph_row_area area
, int start
, int end
)
20714 struct glyph
*glyph
, *last
;
20715 int voffset
, face_id
;
20717 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
20719 glyph
= s
->row
->glyphs
[s
->area
] + start
;
20720 last
= s
->row
->glyphs
[s
->area
] + end
;
20721 face_id
= glyph
->face_id
;
20722 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
20723 s
->font
= s
->face
->font
;
20724 s
->width
= glyph
->pixel_width
;
20726 voffset
= glyph
->voffset
;
20730 && glyph
->type
== STRETCH_GLYPH
20731 && glyph
->voffset
== voffset
20732 && glyph
->face_id
== face_id
);
20734 s
->width
+= glyph
->pixel_width
;
20736 /* Adjust base line for subscript/superscript text. */
20737 s
->ybase
+= voffset
;
20739 /* The case that face->gc == 0 is handled when drawing the glyph
20740 string by calling PREPARE_FACE_FOR_DISPLAY. */
20742 return glyph
- s
->row
->glyphs
[s
->area
];
20745 static struct font_metrics
*
20746 get_per_char_metric (struct frame
*f
, struct font
*font
, XChar2b
*char2b
)
20748 static struct font_metrics metrics
;
20749 unsigned code
= (XCHAR2B_BYTE1 (char2b
) << 8) | XCHAR2B_BYTE2 (char2b
);
20751 if (! font
|| code
== FONT_INVALID_CODE
)
20753 font
->driver
->text_extents (font
, &code
, 1, &metrics
);
20758 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20759 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20760 assumed to be zero. */
20763 x_get_glyph_overhangs (struct glyph
*glyph
, struct frame
*f
, int *left
, int *right
)
20765 *left
= *right
= 0;
20767 if (glyph
->type
== CHAR_GLYPH
)
20771 struct font_metrics
*pcm
;
20773 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
20774 if (face
->font
&& (pcm
= get_per_char_metric (f
, face
->font
, &char2b
)))
20776 if (pcm
->rbearing
> pcm
->width
)
20777 *right
= pcm
->rbearing
- pcm
->width
;
20778 if (pcm
->lbearing
< 0)
20779 *left
= -pcm
->lbearing
;
20782 else if (glyph
->type
== COMPOSITE_GLYPH
)
20784 if (! glyph
->u
.cmp
.automatic
)
20786 struct composition
*cmp
= composition_table
[glyph
->u
.cmp
.id
];
20788 if (cmp
->rbearing
> cmp
->pixel_width
)
20789 *right
= cmp
->rbearing
- cmp
->pixel_width
;
20790 if (cmp
->lbearing
< 0)
20791 *left
= - cmp
->lbearing
;
20795 Lisp_Object gstring
= composition_gstring_from_id (glyph
->u
.cmp
.id
);
20796 struct font_metrics metrics
;
20798 composition_gstring_width (gstring
, glyph
->u
.cmp
.from
,
20799 glyph
->u
.cmp
.to
+ 1, &metrics
);
20800 if (metrics
.rbearing
> metrics
.width
)
20801 *right
= metrics
.rbearing
- metrics
.width
;
20802 if (metrics
.lbearing
< 0)
20803 *left
= - metrics
.lbearing
;
20809 /* Return the index of the first glyph preceding glyph string S that
20810 is overwritten by S because of S's left overhang. Value is -1
20811 if no glyphs are overwritten. */
20814 left_overwritten (struct glyph_string
*s
)
20818 if (s
->left_overhang
)
20821 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
20822 int first
= s
->first_glyph
- glyphs
;
20824 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
20825 x
-= glyphs
[i
].pixel_width
;
20836 /* Return the index of the first glyph preceding glyph string S that
20837 is overwriting S because of its right overhang. Value is -1 if no
20838 glyph in front of S overwrites S. */
20841 left_overwriting (struct glyph_string
*s
)
20844 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
20845 int first
= s
->first_glyph
- glyphs
;
20849 for (i
= first
- 1; i
>= 0; --i
)
20852 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
20855 x
-= glyphs
[i
].pixel_width
;
20862 /* Return the index of the last glyph following glyph string S that is
20863 overwritten by S because of S's right overhang. Value is -1 if
20864 no such glyph is found. */
20867 right_overwritten (struct glyph_string
*s
)
20871 if (s
->right_overhang
)
20874 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
20875 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
20876 int end
= s
->row
->used
[s
->area
];
20878 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
20879 x
+= glyphs
[i
].pixel_width
;
20888 /* Return the index of the last glyph following glyph string S that
20889 overwrites S because of its left overhang. Value is negative
20890 if no such glyph is found. */
20893 right_overwriting (struct glyph_string
*s
)
20896 int end
= s
->row
->used
[s
->area
];
20897 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
20898 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
20902 for (i
= first
; i
< end
; ++i
)
20905 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
20908 x
+= glyphs
[i
].pixel_width
;
20915 /* Set background width of glyph string S. START is the index of the
20916 first glyph following S. LAST_X is the right-most x-position + 1
20917 in the drawing area. */
20920 set_glyph_string_background_width (struct glyph_string
*s
, int start
, int last_x
)
20922 /* If the face of this glyph string has to be drawn to the end of
20923 the drawing area, set S->extends_to_end_of_line_p. */
20925 if (start
== s
->row
->used
[s
->area
]
20926 && s
->area
== TEXT_AREA
20927 && ((s
->row
->fill_line_p
20928 && (s
->hl
== DRAW_NORMAL_TEXT
20929 || s
->hl
== DRAW_IMAGE_RAISED
20930 || s
->hl
== DRAW_IMAGE_SUNKEN
))
20931 || s
->hl
== DRAW_MOUSE_FACE
))
20932 s
->extends_to_end_of_line_p
= 1;
20934 /* If S extends its face to the end of the line, set its
20935 background_width to the distance to the right edge of the drawing
20937 if (s
->extends_to_end_of_line_p
)
20938 s
->background_width
= last_x
- s
->x
+ 1;
20940 s
->background_width
= s
->width
;
20944 /* Compute overhangs and x-positions for glyph string S and its
20945 predecessors, or successors. X is the starting x-position for S.
20946 BACKWARD_P non-zero means process predecessors. */
20949 compute_overhangs_and_x (struct glyph_string
*s
, int x
, int backward_p
)
20955 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
20956 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
20966 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
20967 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
20977 /* The following macros are only called from draw_glyphs below.
20978 They reference the following parameters of that function directly:
20979 `w', `row', `area', and `overlap_p'
20980 as well as the following local variables:
20981 `s', `f', and `hdc' (in W32) */
20984 /* On W32, silently add local `hdc' variable to argument list of
20985 init_glyph_string. */
20986 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20987 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
20989 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20990 init_glyph_string (s, char2b, w, row, area, start, hl)
20993 /* Add a glyph string for a stretch glyph to the list of strings
20994 between HEAD and TAIL. START is the index of the stretch glyph in
20995 row area AREA of glyph row ROW. END is the index of the last glyph
20996 in that glyph row area. X is the current output position assigned
20997 to the new glyph string constructed. HL overrides that face of the
20998 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
20999 is the right-most x-position of the drawing area. */
21001 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21002 and below -- keep them on one line. */
21003 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21006 s = (struct glyph_string *) alloca (sizeof *s); \
21007 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21008 START = fill_stretch_glyph_string (s, row, area, START, END); \
21009 append_glyph_string (&HEAD, &TAIL, s); \
21015 /* Add a glyph string for an image glyph to the list of strings
21016 between HEAD and TAIL. START is the index of the image glyph in
21017 row area AREA of glyph row ROW. END is the index of the last glyph
21018 in that glyph row area. X is the current output position assigned
21019 to the new glyph string constructed. HL overrides that face of the
21020 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21021 is the right-most x-position of the drawing area. */
21023 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21026 s = (struct glyph_string *) alloca (sizeof *s); \
21027 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21028 fill_image_glyph_string (s); \
21029 append_glyph_string (&HEAD, &TAIL, s); \
21036 /* Add a glyph string for a sequence of character glyphs to the list
21037 of strings between HEAD and TAIL. START is the index of the first
21038 glyph in row area AREA of glyph row ROW that is part of the new
21039 glyph string. END is the index of the last glyph in that glyph row
21040 area. X is the current output position assigned to the new glyph
21041 string constructed. HL overrides that face of the glyph; e.g. it
21042 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21043 right-most x-position of the drawing area. */
21045 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21051 face_id = (row)->glyphs[area][START].face_id; \
21053 s = (struct glyph_string *) alloca (sizeof *s); \
21054 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21055 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21056 append_glyph_string (&HEAD, &TAIL, s); \
21058 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21063 /* Add a glyph string for a composite sequence to the list of strings
21064 between HEAD and TAIL. START is the index of the first glyph in
21065 row area AREA of glyph row ROW that is part of the new glyph
21066 string. END is the index of the last glyph in that glyph row area.
21067 X is the current output position assigned to the new glyph string
21068 constructed. HL overrides that face of the glyph; e.g. it is
21069 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21070 x-position of the drawing area. */
21072 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21074 int face_id = (row)->glyphs[area][START].face_id; \
21075 struct face *base_face = FACE_FROM_ID (f, face_id); \
21076 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21077 struct composition *cmp = composition_table[cmp_id]; \
21079 struct glyph_string *first_s; \
21082 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21084 /* Make glyph_strings for each glyph sequence that is drawable by \
21085 the same face, and append them to HEAD/TAIL. */ \
21086 for (n = 0; n < cmp->glyph_len;) \
21088 s = (struct glyph_string *) alloca (sizeof *s); \
21089 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21090 append_glyph_string (&(HEAD), &(TAIL), s); \
21096 n = fill_composite_glyph_string (s, base_face, overlaps); \
21104 /* Add a glyph string for a glyph-string sequence to the list of strings
21105 between HEAD and TAIL. */
21107 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21111 Lisp_Object gstring; \
21113 face_id = (row)->glyphs[area][START].face_id; \
21114 gstring = (composition_gstring_from_id \
21115 ((row)->glyphs[area][START].u.cmp.id)); \
21116 s = (struct glyph_string *) alloca (sizeof *s); \
21117 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21118 * LGSTRING_GLYPH_LEN (gstring)); \
21119 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21120 append_glyph_string (&(HEAD), &(TAIL), s); \
21122 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21126 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21127 of AREA of glyph row ROW on window W between indices START and END.
21128 HL overrides the face for drawing glyph strings, e.g. it is
21129 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21130 x-positions of the drawing area.
21132 This is an ugly monster macro construct because we must use alloca
21133 to allocate glyph strings (because draw_glyphs can be called
21134 asynchronously). */
21136 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21139 HEAD = TAIL = NULL; \
21140 while (START < END) \
21142 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21143 switch (first_glyph->type) \
21146 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21150 case COMPOSITE_GLYPH: \
21151 if (first_glyph->u.cmp.automatic) \
21152 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21155 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21159 case STRETCH_GLYPH: \
21160 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21164 case IMAGE_GLYPH: \
21165 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21175 set_glyph_string_background_width (s, START, LAST_X); \
21182 /* Draw glyphs between START and END in AREA of ROW on window W,
21183 starting at x-position X. X is relative to AREA in W. HL is a
21184 face-override with the following meaning:
21186 DRAW_NORMAL_TEXT draw normally
21187 DRAW_CURSOR draw in cursor face
21188 DRAW_MOUSE_FACE draw in mouse face.
21189 DRAW_INVERSE_VIDEO draw in mode line face
21190 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21191 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21193 If OVERLAPS is non-zero, draw only the foreground of characters and
21194 clip to the physical height of ROW. Non-zero value also defines
21195 the overlapping part to be drawn:
21197 OVERLAPS_PRED overlap with preceding rows
21198 OVERLAPS_SUCC overlap with succeeding rows
21199 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21200 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21202 Value is the x-position reached, relative to AREA of W. */
21205 draw_glyphs (struct window
*w
, int x
, struct glyph_row
*row
,
21206 enum glyph_row_area area
, EMACS_INT start
, EMACS_INT end
,
21207 enum draw_glyphs_face hl
, int overlaps
)
21209 struct glyph_string
*head
, *tail
;
21210 struct glyph_string
*s
;
21211 struct glyph_string
*clip_head
= NULL
, *clip_tail
= NULL
;
21212 int i
, j
, x_reached
, last_x
, area_left
= 0;
21213 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
21216 ALLOCATE_HDC (hdc
, f
);
21218 /* Let's rather be paranoid than getting a SEGV. */
21219 end
= min (end
, row
->used
[area
]);
21220 start
= max (0, start
);
21221 start
= min (end
, start
);
21223 /* Translate X to frame coordinates. Set last_x to the right
21224 end of the drawing area. */
21225 if (row
->full_width_p
)
21227 /* X is relative to the left edge of W, without scroll bars
21229 area_left
= WINDOW_LEFT_EDGE_X (w
);
21230 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
21234 area_left
= window_box_left (w
, area
);
21235 last_x
= area_left
+ window_box_width (w
, area
);
21239 /* Build a doubly-linked list of glyph_string structures between
21240 head and tail from what we have to draw. Note that the macro
21241 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21242 the reason we use a separate variable `i'. */
21244 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
21246 x_reached
= tail
->x
+ tail
->background_width
;
21250 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21251 the row, redraw some glyphs in front or following the glyph
21252 strings built above. */
21253 if (head
&& !overlaps
&& row
->contains_overlapping_glyphs_p
)
21255 struct glyph_string
*h
, *t
;
21256 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21257 int mouse_beg_col
, mouse_end_col
, check_mouse_face
= 0;
21260 /* If mouse highlighting is on, we may need to draw adjacent
21261 glyphs using mouse-face highlighting. */
21262 if (area
== TEXT_AREA
&& row
->mouse_face_p
)
21264 struct glyph_row
*mouse_beg_row
, *mouse_end_row
;
21266 mouse_beg_row
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
21267 mouse_end_row
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
21269 if (row
>= mouse_beg_row
&& row
<= mouse_end_row
)
21271 check_mouse_face
= 1;
21272 mouse_beg_col
= (row
== mouse_beg_row
)
21273 ? dpyinfo
->mouse_face_beg_col
: 0;
21274 mouse_end_col
= (row
== mouse_end_row
)
21275 ? dpyinfo
->mouse_face_end_col
21276 : row
->used
[TEXT_AREA
];
21280 /* Compute overhangs for all glyph strings. */
21281 if (FRAME_RIF (f
)->compute_glyph_string_overhangs
)
21282 for (s
= head
; s
; s
= s
->next
)
21283 FRAME_RIF (f
)->compute_glyph_string_overhangs (s
);
21285 /* Prepend glyph strings for glyphs in front of the first glyph
21286 string that are overwritten because of the first glyph
21287 string's left overhang. The background of all strings
21288 prepended must be drawn because the first glyph string
21290 i
= left_overwritten (head
);
21293 enum draw_glyphs_face overlap_hl
;
21295 /* If this row contains mouse highlighting, attempt to draw
21296 the overlapped glyphs with the correct highlight. This
21297 code fails if the overlap encompasses more than one glyph
21298 and mouse-highlight spans only some of these glyphs.
21299 However, making it work perfectly involves a lot more
21300 code, and I don't know if the pathological case occurs in
21301 practice, so we'll stick to this for now. --- cyd */
21302 if (check_mouse_face
21303 && mouse_beg_col
< start
&& mouse_end_col
> i
)
21304 overlap_hl
= DRAW_MOUSE_FACE
;
21306 overlap_hl
= DRAW_NORMAL_TEXT
;
21309 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
21310 overlap_hl
, dummy_x
, last_x
);
21312 compute_overhangs_and_x (t
, head
->x
, 1);
21313 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
21317 /* Prepend glyph strings for glyphs in front of the first glyph
21318 string that overwrite that glyph string because of their
21319 right overhang. For these strings, only the foreground must
21320 be drawn, because it draws over the glyph string at `head'.
21321 The background must not be drawn because this would overwrite
21322 right overhangs of preceding glyphs for which no glyph
21324 i
= left_overwriting (head
);
21327 enum draw_glyphs_face overlap_hl
;
21329 if (check_mouse_face
21330 && mouse_beg_col
< start
&& mouse_end_col
> i
)
21331 overlap_hl
= DRAW_MOUSE_FACE
;
21333 overlap_hl
= DRAW_NORMAL_TEXT
;
21336 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
21337 overlap_hl
, dummy_x
, last_x
);
21338 for (s
= h
; s
; s
= s
->next
)
21339 s
->background_filled_p
= 1;
21340 compute_overhangs_and_x (t
, head
->x
, 1);
21341 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
21344 /* Append glyphs strings for glyphs following the last glyph
21345 string tail that are overwritten by tail. The background of
21346 these strings has to be drawn because tail's foreground draws
21348 i
= right_overwritten (tail
);
21351 enum draw_glyphs_face overlap_hl
;
21353 if (check_mouse_face
21354 && mouse_beg_col
< i
&& mouse_end_col
> end
)
21355 overlap_hl
= DRAW_MOUSE_FACE
;
21357 overlap_hl
= DRAW_NORMAL_TEXT
;
21359 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
21360 overlap_hl
, x
, last_x
);
21361 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21362 we don't have `end = i;' here. */
21363 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
21364 append_glyph_string_lists (&head
, &tail
, h
, t
);
21368 /* Append glyph strings for glyphs following the last glyph
21369 string tail that overwrite tail. The foreground of such
21370 glyphs has to be drawn because it writes into the background
21371 of tail. The background must not be drawn because it could
21372 paint over the foreground of following glyphs. */
21373 i
= right_overwriting (tail
);
21376 enum draw_glyphs_face overlap_hl
;
21377 if (check_mouse_face
21378 && mouse_beg_col
< i
&& mouse_end_col
> end
)
21379 overlap_hl
= DRAW_MOUSE_FACE
;
21381 overlap_hl
= DRAW_NORMAL_TEXT
;
21384 i
++; /* We must include the Ith glyph. */
21385 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
21386 overlap_hl
, x
, last_x
);
21387 for (s
= h
; s
; s
= s
->next
)
21388 s
->background_filled_p
= 1;
21389 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
21390 append_glyph_string_lists (&head
, &tail
, h
, t
);
21392 if (clip_head
|| clip_tail
)
21393 for (s
= head
; s
; s
= s
->next
)
21395 s
->clip_head
= clip_head
;
21396 s
->clip_tail
= clip_tail
;
21400 /* Draw all strings. */
21401 for (s
= head
; s
; s
= s
->next
)
21402 FRAME_RIF (f
)->draw_glyph_string (s
);
21405 /* When focus a sole frame and move horizontally, this sets on_p to 0
21406 causing a failure to erase prev cursor position. */
21407 if (area
== TEXT_AREA
21408 && !row
->full_width_p
21409 /* When drawing overlapping rows, only the glyph strings'
21410 foreground is drawn, which doesn't erase a cursor
21414 int x0
= clip_head
? clip_head
->x
: (head
? head
->x
: x
);
21415 int x1
= (clip_tail
? clip_tail
->x
+ clip_tail
->background_width
21416 : (tail
? tail
->x
+ tail
->background_width
: x
));
21420 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
21421 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
21425 /* Value is the x-position up to which drawn, relative to AREA of W.
21426 This doesn't include parts drawn because of overhangs. */
21427 if (row
->full_width_p
)
21428 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
21430 x_reached
-= area_left
;
21432 RELEASE_HDC (hdc
, f
);
21437 /* Expand row matrix if too narrow. Don't expand if area
21440 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21442 if (!fonts_changed_p \
21443 && (it->glyph_row->glyphs[area] \
21444 < it->glyph_row->glyphs[area + 1])) \
21446 it->w->ncols_scale_factor++; \
21447 fonts_changed_p = 1; \
21451 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21452 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21455 append_glyph (struct it
*it
)
21457 struct glyph
*glyph
;
21458 enum glyph_row_area area
= it
->area
;
21460 xassert (it
->glyph_row
);
21461 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
21463 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
21464 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
21466 /* If the glyph row is reversed, we need to prepend the glyph
21467 rather than append it. */
21468 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
21472 /* Make room for the additional glyph. */
21473 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
21475 glyph
= it
->glyph_row
->glyphs
[area
];
21477 glyph
->charpos
= CHARPOS (it
->position
);
21478 glyph
->object
= it
->object
;
21479 if (it
->pixel_width
> 0)
21481 glyph
->pixel_width
= it
->pixel_width
;
21482 glyph
->padding_p
= 0;
21486 /* Assure at least 1-pixel width. Otherwise, cursor can't
21487 be displayed correctly. */
21488 glyph
->pixel_width
= 1;
21489 glyph
->padding_p
= 1;
21491 glyph
->ascent
= it
->ascent
;
21492 glyph
->descent
= it
->descent
;
21493 glyph
->voffset
= it
->voffset
;
21494 glyph
->type
= CHAR_GLYPH
;
21495 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
21496 glyph
->multibyte_p
= it
->multibyte_p
;
21497 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
21498 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
21499 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
21500 || it
->phys_descent
> it
->descent
);
21501 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
21502 glyph
->face_id
= it
->face_id
;
21503 glyph
->u
.ch
= it
->char_to_display
;
21504 glyph
->slice
= null_glyph_slice
;
21505 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
21508 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
21509 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
21511 glyph
->bidi_type
= it
->bidi_it
.type
;
21515 glyph
->resolved_level
= 0;
21516 glyph
->bidi_type
= UNKNOWN_BT
;
21518 ++it
->glyph_row
->used
[area
];
21521 IT_EXPAND_MATRIX_WIDTH (it
, area
);
21524 /* Store one glyph for the composition IT->cmp_it.id in
21525 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21529 append_composite_glyph (struct it
*it
)
21531 struct glyph
*glyph
;
21532 enum glyph_row_area area
= it
->area
;
21534 xassert (it
->glyph_row
);
21536 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
21537 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
21539 /* If the glyph row is reversed, we need to prepend the glyph
21540 rather than append it. */
21541 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
21545 /* Make room for the new glyph. */
21546 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
21548 glyph
= it
->glyph_row
->glyphs
[it
->area
];
21550 glyph
->charpos
= it
->cmp_it
.charpos
;
21551 glyph
->object
= it
->object
;
21552 glyph
->pixel_width
= it
->pixel_width
;
21553 glyph
->ascent
= it
->ascent
;
21554 glyph
->descent
= it
->descent
;
21555 glyph
->voffset
= it
->voffset
;
21556 glyph
->type
= COMPOSITE_GLYPH
;
21557 if (it
->cmp_it
.ch
< 0)
21559 glyph
->u
.cmp
.automatic
= 0;
21560 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
21564 glyph
->u
.cmp
.automatic
= 1;
21565 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
21566 glyph
->u
.cmp
.from
= it
->cmp_it
.from
;
21567 glyph
->u
.cmp
.to
= it
->cmp_it
.to
- 1;
21569 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
21570 glyph
->multibyte_p
= it
->multibyte_p
;
21571 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
21572 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
21573 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
21574 || it
->phys_descent
> it
->descent
);
21575 glyph
->padding_p
= 0;
21576 glyph
->glyph_not_available_p
= 0;
21577 glyph
->face_id
= it
->face_id
;
21578 glyph
->slice
= null_glyph_slice
;
21579 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
21582 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
21583 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
21585 glyph
->bidi_type
= it
->bidi_it
.type
;
21587 ++it
->glyph_row
->used
[area
];
21590 IT_EXPAND_MATRIX_WIDTH (it
, area
);
21594 /* Change IT->ascent and IT->height according to the setting of
21598 take_vertical_position_into_account (struct it
*it
)
21602 if (it
->voffset
< 0)
21603 /* Increase the ascent so that we can display the text higher
21605 it
->ascent
-= it
->voffset
;
21607 /* Increase the descent so that we can display the text lower
21609 it
->descent
+= it
->voffset
;
21614 /* Produce glyphs/get display metrics for the image IT is loaded with.
21615 See the description of struct display_iterator in dispextern.h for
21616 an overview of struct display_iterator. */
21619 produce_image_glyph (struct it
*it
)
21623 int glyph_ascent
, crop
;
21624 struct glyph_slice slice
;
21626 xassert (it
->what
== IT_IMAGE
);
21628 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
21630 /* Make sure X resources of the face is loaded. */
21631 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
21633 if (it
->image_id
< 0)
21635 /* Fringe bitmap. */
21636 it
->ascent
= it
->phys_ascent
= 0;
21637 it
->descent
= it
->phys_descent
= 0;
21638 it
->pixel_width
= 0;
21643 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
21645 /* Make sure X resources of the image is loaded. */
21646 prepare_image_for_display (it
->f
, img
);
21648 slice
.x
= slice
.y
= 0;
21649 slice
.width
= img
->width
;
21650 slice
.height
= img
->height
;
21652 if (INTEGERP (it
->slice
.x
))
21653 slice
.x
= XINT (it
->slice
.x
);
21654 else if (FLOATP (it
->slice
.x
))
21655 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
21657 if (INTEGERP (it
->slice
.y
))
21658 slice
.y
= XINT (it
->slice
.y
);
21659 else if (FLOATP (it
->slice
.y
))
21660 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
21662 if (INTEGERP (it
->slice
.width
))
21663 slice
.width
= XINT (it
->slice
.width
);
21664 else if (FLOATP (it
->slice
.width
))
21665 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
21667 if (INTEGERP (it
->slice
.height
))
21668 slice
.height
= XINT (it
->slice
.height
);
21669 else if (FLOATP (it
->slice
.height
))
21670 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
21672 if (slice
.x
>= img
->width
)
21673 slice
.x
= img
->width
;
21674 if (slice
.y
>= img
->height
)
21675 slice
.y
= img
->height
;
21676 if (slice
.x
+ slice
.width
>= img
->width
)
21677 slice
.width
= img
->width
- slice
.x
;
21678 if (slice
.y
+ slice
.height
> img
->height
)
21679 slice
.height
= img
->height
- slice
.y
;
21681 if (slice
.width
== 0 || slice
.height
== 0)
21684 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
21686 it
->descent
= slice
.height
- glyph_ascent
;
21688 it
->descent
+= img
->vmargin
;
21689 if (slice
.y
+ slice
.height
== img
->height
)
21690 it
->descent
+= img
->vmargin
;
21691 it
->phys_descent
= it
->descent
;
21693 it
->pixel_width
= slice
.width
;
21695 it
->pixel_width
+= img
->hmargin
;
21696 if (slice
.x
+ slice
.width
== img
->width
)
21697 it
->pixel_width
+= img
->hmargin
;
21699 /* It's quite possible for images to have an ascent greater than
21700 their height, so don't get confused in that case. */
21701 if (it
->descent
< 0)
21706 if (face
->box
!= FACE_NO_BOX
)
21708 if (face
->box_line_width
> 0)
21711 it
->ascent
+= face
->box_line_width
;
21712 if (slice
.y
+ slice
.height
== img
->height
)
21713 it
->descent
+= face
->box_line_width
;
21716 if (it
->start_of_box_run_p
&& slice
.x
== 0)
21717 it
->pixel_width
+= eabs (face
->box_line_width
);
21718 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
21719 it
->pixel_width
+= eabs (face
->box_line_width
);
21722 take_vertical_position_into_account (it
);
21724 /* Automatically crop wide image glyphs at right edge so we can
21725 draw the cursor on same display row. */
21726 if ((crop
= it
->pixel_width
- (it
->last_visible_x
- it
->current_x
), crop
> 0)
21727 && (it
->hpos
== 0 || it
->pixel_width
> it
->last_visible_x
/ 4))
21729 it
->pixel_width
-= crop
;
21730 slice
.width
-= crop
;
21735 struct glyph
*glyph
;
21736 enum glyph_row_area area
= it
->area
;
21738 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
21739 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
21741 glyph
->charpos
= CHARPOS (it
->position
);
21742 glyph
->object
= it
->object
;
21743 glyph
->pixel_width
= it
->pixel_width
;
21744 glyph
->ascent
= glyph_ascent
;
21745 glyph
->descent
= it
->descent
;
21746 glyph
->voffset
= it
->voffset
;
21747 glyph
->type
= IMAGE_GLYPH
;
21748 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
21749 glyph
->multibyte_p
= it
->multibyte_p
;
21750 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
21751 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
21752 glyph
->overlaps_vertically_p
= 0;
21753 glyph
->padding_p
= 0;
21754 glyph
->glyph_not_available_p
= 0;
21755 glyph
->face_id
= it
->face_id
;
21756 glyph
->u
.img_id
= img
->id
;
21757 glyph
->slice
= slice
;
21758 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
21761 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
21762 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
21764 glyph
->bidi_type
= it
->bidi_it
.type
;
21766 ++it
->glyph_row
->used
[area
];
21769 IT_EXPAND_MATRIX_WIDTH (it
, area
);
21774 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
21775 of the glyph, WIDTH and HEIGHT are the width and height of the
21776 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
21779 append_stretch_glyph (struct it
*it
, Lisp_Object object
,
21780 int width
, int height
, int ascent
)
21782 struct glyph
*glyph
;
21783 enum glyph_row_area area
= it
->area
;
21785 xassert (ascent
>= 0 && ascent
<= height
);
21787 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
21788 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
21790 /* If the glyph row is reversed, we need to prepend the glyph
21791 rather than append it. */
21792 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
21796 /* Make room for the additional glyph. */
21797 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
21799 glyph
= it
->glyph_row
->glyphs
[area
];
21801 glyph
->charpos
= CHARPOS (it
->position
);
21802 glyph
->object
= object
;
21803 glyph
->pixel_width
= width
;
21804 glyph
->ascent
= ascent
;
21805 glyph
->descent
= height
- ascent
;
21806 glyph
->voffset
= it
->voffset
;
21807 glyph
->type
= STRETCH_GLYPH
;
21808 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
21809 glyph
->multibyte_p
= it
->multibyte_p
;
21810 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
21811 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
21812 glyph
->overlaps_vertically_p
= 0;
21813 glyph
->padding_p
= 0;
21814 glyph
->glyph_not_available_p
= 0;
21815 glyph
->face_id
= it
->face_id
;
21816 glyph
->u
.stretch
.ascent
= ascent
;
21817 glyph
->u
.stretch
.height
= height
;
21818 glyph
->slice
= null_glyph_slice
;
21819 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
21822 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
21823 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
21825 glyph
->bidi_type
= it
->bidi_it
.type
;
21829 glyph
->resolved_level
= 0;
21830 glyph
->bidi_type
= UNKNOWN_BT
;
21832 ++it
->glyph_row
->used
[area
];
21835 IT_EXPAND_MATRIX_WIDTH (it
, area
);
21839 /* Produce a stretch glyph for iterator IT. IT->object is the value
21840 of the glyph property displayed. The value must be a list
21841 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
21844 1. `:width WIDTH' specifies that the space should be WIDTH *
21845 canonical char width wide. WIDTH may be an integer or floating
21848 2. `:relative-width FACTOR' specifies that the width of the stretch
21849 should be computed from the width of the first character having the
21850 `glyph' property, and should be FACTOR times that width.
21852 3. `:align-to HPOS' specifies that the space should be wide enough
21853 to reach HPOS, a value in canonical character units.
21855 Exactly one of the above pairs must be present.
21857 4. `:height HEIGHT' specifies that the height of the stretch produced
21858 should be HEIGHT, measured in canonical character units.
21860 5. `:relative-height FACTOR' specifies that the height of the
21861 stretch should be FACTOR times the height of the characters having
21862 the glyph property.
21864 Either none or exactly one of 4 or 5 must be present.
21866 6. `:ascent ASCENT' specifies that ASCENT percent of the height
21867 of the stretch should be used for the ascent of the stretch.
21868 ASCENT must be in the range 0 <= ASCENT <= 100. */
21871 produce_stretch_glyph (struct it
*it
)
21873 /* (space :width WIDTH :height HEIGHT ...) */
21874 Lisp_Object prop
, plist
;
21875 int width
= 0, height
= 0, align_to
= -1;
21876 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
21879 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
21880 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
21882 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
21884 /* List should start with `space'. */
21885 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
21886 plist
= XCDR (it
->object
);
21888 /* Compute the width of the stretch. */
21889 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
21890 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
21892 /* Absolute width `:width WIDTH' specified and valid. */
21893 zero_width_ok_p
= 1;
21896 else if (prop
= Fplist_get (plist
, QCrelative_width
),
21899 /* Relative width `:relative-width FACTOR' specified and valid.
21900 Compute the width of the characters having the `glyph'
21903 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
21906 if (it
->multibyte_p
)
21908 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
21909 - IT_BYTEPOS (*it
));
21910 it2
.c
= STRING_CHAR_AND_LENGTH (p
, it2
.len
);
21913 it2
.c
= *p
, it2
.len
= 1;
21915 it2
.glyph_row
= NULL
;
21916 it2
.what
= IT_CHARACTER
;
21917 x_produce_glyphs (&it2
);
21918 width
= NUMVAL (prop
) * it2
.pixel_width
;
21920 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
21921 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
21923 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
21924 align_to
= (align_to
< 0
21926 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
21927 else if (align_to
< 0)
21928 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
21929 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
21930 zero_width_ok_p
= 1;
21933 /* Nothing specified -> width defaults to canonical char width. */
21934 width
= FRAME_COLUMN_WIDTH (it
->f
);
21936 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
21939 /* Compute height. */
21940 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
21941 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
21944 zero_height_ok_p
= 1;
21946 else if (prop
= Fplist_get (plist
, QCrelative_height
),
21948 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
21950 height
= FONT_HEIGHT (font
);
21952 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
21955 /* Compute percentage of height used for ascent. If
21956 `:ascent ASCENT' is present and valid, use that. Otherwise,
21957 derive the ascent from the font in use. */
21958 if (prop
= Fplist_get (plist
, QCascent
),
21959 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
21960 ascent
= height
* NUMVAL (prop
) / 100.0;
21961 else if (!NILP (prop
)
21962 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
21963 ascent
= min (max (0, (int)tem
), height
);
21965 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
21967 if (width
> 0 && it
->line_wrap
!= TRUNCATE
21968 && it
->current_x
+ width
> it
->last_visible_x
)
21969 width
= it
->last_visible_x
- it
->current_x
- 1;
21971 if (width
> 0 && height
> 0 && it
->glyph_row
)
21973 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
21974 if (!STRINGP (object
))
21975 object
= it
->w
->buffer
;
21976 append_stretch_glyph (it
, object
, width
, height
, ascent
);
21979 it
->pixel_width
= width
;
21980 it
->ascent
= it
->phys_ascent
= ascent
;
21981 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
21982 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
21984 take_vertical_position_into_account (it
);
21987 /* Calculate line-height and line-spacing properties.
21988 An integer value specifies explicit pixel value.
21989 A float value specifies relative value to current face height.
21990 A cons (float . face-name) specifies relative value to
21991 height of specified face font.
21993 Returns height in pixels, or nil. */
21997 calc_line_height_property (struct it
*it
, Lisp_Object val
, struct font
*font
,
21998 int boff
, int override
)
22000 Lisp_Object face_name
= Qnil
;
22001 int ascent
, descent
, height
;
22003 if (NILP (val
) || INTEGERP (val
) || (override
&& EQ (val
, Qt
)))
22008 face_name
= XCAR (val
);
22010 if (!NUMBERP (val
))
22011 val
= make_number (1);
22012 if (NILP (face_name
))
22014 height
= it
->ascent
+ it
->descent
;
22019 if (NILP (face_name
))
22021 font
= FRAME_FONT (it
->f
);
22022 boff
= FRAME_BASELINE_OFFSET (it
->f
);
22024 else if (EQ (face_name
, Qt
))
22033 face_id
= lookup_named_face (it
->f
, face_name
, 0);
22035 return make_number (-1);
22037 face
= FACE_FROM_ID (it
->f
, face_id
);
22040 return make_number (-1);
22041 boff
= font
->baseline_offset
;
22042 if (font
->vertical_centering
)
22043 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
22046 ascent
= FONT_BASE (font
) + boff
;
22047 descent
= FONT_DESCENT (font
) - boff
;
22051 it
->override_ascent
= ascent
;
22052 it
->override_descent
= descent
;
22053 it
->override_boff
= boff
;
22056 height
= ascent
+ descent
;
22060 height
= (int)(XFLOAT_DATA (val
) * height
);
22061 else if (INTEGERP (val
))
22062 height
*= XINT (val
);
22064 return make_number (height
);
22069 Produce glyphs/get display metrics for the display element IT is
22070 loaded with. See the description of struct it in dispextern.h
22071 for an overview of struct it. */
22074 x_produce_glyphs (struct it
*it
)
22076 int extra_line_spacing
= it
->extra_line_spacing
;
22078 it
->glyph_not_available_p
= 0;
22080 if (it
->what
== IT_CHARACTER
)
22084 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22085 struct font_metrics
*pcm
;
22086 int font_not_found_p
;
22087 int boff
; /* baseline offset */
22088 /* We may change it->multibyte_p upon unibyte<->multibyte
22089 conversion. So, save the current value now and restore it
22092 Note: It seems that we don't have to record multibyte_p in
22093 struct glyph because the character code itself tells whether
22094 or not the character is multibyte. Thus, in the future, we
22095 must consider eliminating the field `multibyte_p' in the
22097 int saved_multibyte_p
= it
->multibyte_p
;
22099 /* Maybe translate single-byte characters to multibyte, or the
22101 it
->char_to_display
= it
->c
;
22102 if (!ASCII_BYTE_P (it
->c
)
22103 && ! it
->multibyte_p
)
22105 if (SINGLE_BYTE_CHAR_P (it
->c
)
22106 && unibyte_display_via_language_environment
)
22108 struct charset
*unibyte
= CHARSET_FROM_ID (charset_unibyte
);
22110 /* get_next_display_element assures that this decoding
22112 it
->char_to_display
= DECODE_CHAR (unibyte
, it
->c
);
22113 it
->multibyte_p
= 1;
22114 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
,
22116 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22120 /* Get font to use. Encode IT->char_to_display. */
22121 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
22122 &char2b
, it
->multibyte_p
, 0);
22125 font_not_found_p
= font
== NULL
;
22126 if (font_not_found_p
)
22128 /* When no suitable font found, display an empty box based
22129 on the metrics of the font of the default face (or what
22131 struct face
*no_font_face
22132 = FACE_FROM_ID (it
->f
,
22133 NILP (Vface_remapping_alist
) ? DEFAULT_FACE_ID
22134 : lookup_basic_face (it
->f
, DEFAULT_FACE_ID
));
22135 font
= no_font_face
->font
;
22136 boff
= font
->baseline_offset
;
22140 boff
= font
->baseline_offset
;
22141 if (font
->vertical_centering
)
22142 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
22145 if (it
->char_to_display
>= ' '
22146 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
22148 /* Either unibyte or ASCII. */
22153 pcm
= get_per_char_metric (it
->f
, font
, &char2b
);
22155 if (it
->override_ascent
>= 0)
22157 it
->ascent
= it
->override_ascent
;
22158 it
->descent
= it
->override_descent
;
22159 boff
= it
->override_boff
;
22163 it
->ascent
= FONT_BASE (font
) + boff
;
22164 it
->descent
= FONT_DESCENT (font
) - boff
;
22169 it
->phys_ascent
= pcm
->ascent
+ boff
;
22170 it
->phys_descent
= pcm
->descent
- boff
;
22171 it
->pixel_width
= pcm
->width
;
22175 it
->glyph_not_available_p
= 1;
22176 it
->phys_ascent
= it
->ascent
;
22177 it
->phys_descent
= it
->descent
;
22178 it
->pixel_width
= FONT_WIDTH (font
);
22181 if (it
->constrain_row_ascent_descent_p
)
22183 if (it
->descent
> it
->max_descent
)
22185 it
->ascent
+= it
->descent
- it
->max_descent
;
22186 it
->descent
= it
->max_descent
;
22188 if (it
->ascent
> it
->max_ascent
)
22190 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
22191 it
->ascent
= it
->max_ascent
;
22193 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
22194 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
22195 extra_line_spacing
= 0;
22198 /* If this is a space inside a region of text with
22199 `space-width' property, change its width. */
22200 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
22202 it
->pixel_width
*= XFLOATINT (it
->space_width
);
22204 /* If face has a box, add the box thickness to the character
22205 height. If character has a box line to the left and/or
22206 right, add the box line width to the character's width. */
22207 if (face
->box
!= FACE_NO_BOX
)
22209 int thick
= face
->box_line_width
;
22213 it
->ascent
+= thick
;
22214 it
->descent
+= thick
;
22219 if (it
->start_of_box_run_p
)
22220 it
->pixel_width
+= thick
;
22221 if (it
->end_of_box_run_p
)
22222 it
->pixel_width
+= thick
;
22225 /* If face has an overline, add the height of the overline
22226 (1 pixel) and a 1 pixel margin to the character height. */
22227 if (face
->overline_p
)
22228 it
->ascent
+= overline_margin
;
22230 if (it
->constrain_row_ascent_descent_p
)
22232 if (it
->ascent
> it
->max_ascent
)
22233 it
->ascent
= it
->max_ascent
;
22234 if (it
->descent
> it
->max_descent
)
22235 it
->descent
= it
->max_descent
;
22238 take_vertical_position_into_account (it
);
22240 /* If we have to actually produce glyphs, do it. */
22245 /* Translate a space with a `space-width' property
22246 into a stretch glyph. */
22247 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
22248 / FONT_HEIGHT (font
));
22249 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
22250 it
->ascent
+ it
->descent
, ascent
);
22255 /* If characters with lbearing or rbearing are displayed
22256 in this line, record that fact in a flag of the
22257 glyph row. This is used to optimize X output code. */
22258 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
22259 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
22261 if (! stretched_p
&& it
->pixel_width
== 0)
22262 /* We assure that all visible glyphs have at least 1-pixel
22264 it
->pixel_width
= 1;
22266 else if (it
->char_to_display
== '\n')
22268 /* A newline has no width, but we need the height of the
22269 line. But if previous part of the line sets a height,
22270 don't increase that height */
22272 Lisp_Object height
;
22273 Lisp_Object total_height
= Qnil
;
22275 it
->override_ascent
= -1;
22276 it
->pixel_width
= 0;
22279 height
= get_it_property (it
, Qline_height
);
22280 /* Split (line-height total-height) list */
22282 && CONSP (XCDR (height
))
22283 && NILP (XCDR (XCDR (height
))))
22285 total_height
= XCAR (XCDR (height
));
22286 height
= XCAR (height
);
22288 height
= calc_line_height_property (it
, height
, font
, boff
, 1);
22290 if (it
->override_ascent
>= 0)
22292 it
->ascent
= it
->override_ascent
;
22293 it
->descent
= it
->override_descent
;
22294 boff
= it
->override_boff
;
22298 it
->ascent
= FONT_BASE (font
) + boff
;
22299 it
->descent
= FONT_DESCENT (font
) - boff
;
22302 if (EQ (height
, Qt
))
22304 if (it
->descent
> it
->max_descent
)
22306 it
->ascent
+= it
->descent
- it
->max_descent
;
22307 it
->descent
= it
->max_descent
;
22309 if (it
->ascent
> it
->max_ascent
)
22311 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
22312 it
->ascent
= it
->max_ascent
;
22314 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
22315 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
22316 it
->constrain_row_ascent_descent_p
= 1;
22317 extra_line_spacing
= 0;
22321 Lisp_Object spacing
;
22323 it
->phys_ascent
= it
->ascent
;
22324 it
->phys_descent
= it
->descent
;
22326 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
22327 && face
->box
!= FACE_NO_BOX
22328 && face
->box_line_width
> 0)
22330 it
->ascent
+= face
->box_line_width
;
22331 it
->descent
+= face
->box_line_width
;
22334 && XINT (height
) > it
->ascent
+ it
->descent
)
22335 it
->ascent
= XINT (height
) - it
->descent
;
22337 if (!NILP (total_height
))
22338 spacing
= calc_line_height_property (it
, total_height
, font
, boff
, 0);
22341 spacing
= get_it_property (it
, Qline_spacing
);
22342 spacing
= calc_line_height_property (it
, spacing
, font
, boff
, 0);
22344 if (INTEGERP (spacing
))
22346 extra_line_spacing
= XINT (spacing
);
22347 if (!NILP (total_height
))
22348 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
22352 else if (it
->char_to_display
== '\t')
22354 if (font
->space_width
> 0)
22356 int tab_width
= it
->tab_width
* font
->space_width
;
22357 int x
= it
->current_x
+ it
->continuation_lines_width
;
22358 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
22360 /* If the distance from the current position to the next tab
22361 stop is less than a space character width, use the
22362 tab stop after that. */
22363 if (next_tab_x
- x
< font
->space_width
)
22364 next_tab_x
+= tab_width
;
22366 it
->pixel_width
= next_tab_x
- x
;
22368 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
22369 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
22373 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
22374 it
->ascent
+ it
->descent
, it
->ascent
);
22379 it
->pixel_width
= 0;
22385 /* A multi-byte character. Assume that the display width of the
22386 character is the width of the character multiplied by the
22387 width of the font. */
22389 /* If we found a font, this font should give us the right
22390 metrics. If we didn't find a font, use the frame's
22391 default font and calculate the width of the character by
22392 multiplying the width of font by the width of the
22395 pcm
= get_per_char_metric (it
->f
, font
, &char2b
);
22397 if (font_not_found_p
|| !pcm
)
22399 int char_width
= CHAR_WIDTH (it
->char_to_display
);
22401 if (char_width
== 0)
22402 /* This is a non spacing character. But, as we are
22403 going to display an empty box, the box must occupy
22404 at least one column. */
22406 it
->glyph_not_available_p
= 1;
22407 it
->pixel_width
= font
->space_width
* char_width
;
22408 it
->phys_ascent
= FONT_BASE (font
) + boff
;
22409 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
22413 it
->pixel_width
= pcm
->width
;
22414 it
->phys_ascent
= pcm
->ascent
+ boff
;
22415 it
->phys_descent
= pcm
->descent
- boff
;
22417 && (pcm
->lbearing
< 0
22418 || pcm
->rbearing
> pcm
->width
))
22419 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
22422 it
->ascent
= FONT_BASE (font
) + boff
;
22423 it
->descent
= FONT_DESCENT (font
) - boff
;
22424 if (face
->box
!= FACE_NO_BOX
)
22426 int thick
= face
->box_line_width
;
22430 it
->ascent
+= thick
;
22431 it
->descent
+= thick
;
22436 if (it
->start_of_box_run_p
)
22437 it
->pixel_width
+= thick
;
22438 if (it
->end_of_box_run_p
)
22439 it
->pixel_width
+= thick
;
22442 /* If face has an overline, add the height of the overline
22443 (1 pixel) and a 1 pixel margin to the character height. */
22444 if (face
->overline_p
)
22445 it
->ascent
+= overline_margin
;
22447 take_vertical_position_into_account (it
);
22449 if (it
->ascent
< 0)
22451 if (it
->descent
< 0)
22456 if (it
->pixel_width
== 0)
22457 /* We assure that all visible glyphs have at least 1-pixel
22459 it
->pixel_width
= 1;
22461 it
->multibyte_p
= saved_multibyte_p
;
22463 else if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
< 0)
22465 /* A static composition.
22467 Note: A composition is represented as one glyph in the
22468 glyph matrix. There are no padding glyphs.
22470 Important note: pixel_width, ascent, and descent are the
22471 values of what is drawn by draw_glyphs (i.e. the values of
22472 the overall glyphs composed). */
22473 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22474 int boff
; /* baseline offset */
22475 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
22476 int glyph_len
= cmp
->glyph_len
;
22477 struct font
*font
= face
->font
;
22481 /* If we have not yet calculated pixel size data of glyphs of
22482 the composition for the current face font, calculate them
22483 now. Theoretically, we have to check all fonts for the
22484 glyphs, but that requires much time and memory space. So,
22485 here we check only the font of the first glyph. This may
22486 lead to incorrect display, but it's very rare, and C-l
22487 (recenter-top-bottom) can correct the display anyway. */
22488 if (! cmp
->font
|| cmp
->font
!= font
)
22490 /* Ascent and descent of the font of the first character
22491 of this composition (adjusted by baseline offset).
22492 Ascent and descent of overall glyphs should not be less
22493 than these, respectively. */
22494 int font_ascent
, font_descent
, font_height
;
22495 /* Bounding box of the overall glyphs. */
22496 int leftmost
, rightmost
, lowest
, highest
;
22497 int lbearing
, rbearing
;
22498 int i
, width
, ascent
, descent
;
22499 int left_padded
= 0, right_padded
= 0;
22502 struct font_metrics
*pcm
;
22503 int font_not_found_p
;
22506 for (glyph_len
= cmp
->glyph_len
; glyph_len
> 0; glyph_len
--)
22507 if ((c
= COMPOSITION_GLYPH (cmp
, glyph_len
- 1)) != '\t')
22509 if (glyph_len
< cmp
->glyph_len
)
22511 for (i
= 0; i
< glyph_len
; i
++)
22513 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
22515 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
22520 pos
= (STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
22521 : IT_CHARPOS (*it
));
22522 /* If no suitable font is found, use the default font. */
22523 font_not_found_p
= font
== NULL
;
22524 if (font_not_found_p
)
22526 face
= face
->ascii_face
;
22529 boff
= font
->baseline_offset
;
22530 if (font
->vertical_centering
)
22531 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
22532 font_ascent
= FONT_BASE (font
) + boff
;
22533 font_descent
= FONT_DESCENT (font
) - boff
;
22534 font_height
= FONT_HEIGHT (font
);
22536 cmp
->font
= (void *) font
;
22539 if (! font_not_found_p
)
22541 get_char_face_and_encoding (it
->f
, c
, it
->face_id
,
22542 &char2b
, it
->multibyte_p
, 0);
22543 pcm
= get_per_char_metric (it
->f
, font
, &char2b
);
22546 /* Initialize the bounding box. */
22549 width
= pcm
->width
;
22550 ascent
= pcm
->ascent
;
22551 descent
= pcm
->descent
;
22552 lbearing
= pcm
->lbearing
;
22553 rbearing
= pcm
->rbearing
;
22557 width
= FONT_WIDTH (font
);
22558 ascent
= FONT_BASE (font
);
22559 descent
= FONT_DESCENT (font
);
22566 lowest
= - descent
+ boff
;
22567 highest
= ascent
+ boff
;
22569 if (! font_not_found_p
22570 && font
->default_ascent
22571 && CHAR_TABLE_P (Vuse_default_ascent
)
22572 && !NILP (Faref (Vuse_default_ascent
,
22573 make_number (it
->char_to_display
))))
22574 highest
= font
->default_ascent
+ boff
;
22576 /* Draw the first glyph at the normal position. It may be
22577 shifted to right later if some other glyphs are drawn
22579 cmp
->offsets
[i
* 2] = 0;
22580 cmp
->offsets
[i
* 2 + 1] = boff
;
22581 cmp
->lbearing
= lbearing
;
22582 cmp
->rbearing
= rbearing
;
22584 /* Set cmp->offsets for the remaining glyphs. */
22585 for (i
++; i
< glyph_len
; i
++)
22587 int left
, right
, btm
, top
;
22588 int ch
= COMPOSITION_GLYPH (cmp
, i
);
22590 struct face
*this_face
;
22595 face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
, pos
, it
->string
);
22596 this_face
= FACE_FROM_ID (it
->f
, face_id
);
22597 font
= this_face
->font
;
22603 this_boff
= font
->baseline_offset
;
22604 if (font
->vertical_centering
)
22605 this_boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
22606 get_char_face_and_encoding (it
->f
, ch
, face_id
,
22607 &char2b
, it
->multibyte_p
, 0);
22608 pcm
= get_per_char_metric (it
->f
, font
, &char2b
);
22611 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
22614 width
= pcm
->width
;
22615 ascent
= pcm
->ascent
;
22616 descent
= pcm
->descent
;
22617 lbearing
= pcm
->lbearing
;
22618 rbearing
= pcm
->rbearing
;
22619 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
22621 /* Relative composition with or without
22622 alternate chars. */
22623 left
= (leftmost
+ rightmost
- width
) / 2;
22624 btm
= - descent
+ boff
;
22625 if (font
->relative_compose
22626 && (! CHAR_TABLE_P (Vignore_relative_composition
)
22627 || NILP (Faref (Vignore_relative_composition
,
22628 make_number (ch
)))))
22631 if (- descent
>= font
->relative_compose
)
22632 /* One extra pixel between two glyphs. */
22634 else if (ascent
<= 0)
22635 /* One extra pixel between two glyphs. */
22636 btm
= lowest
- 1 - ascent
- descent
;
22641 /* A composition rule is specified by an integer
22642 value that encodes global and new reference
22643 points (GREF and NREF). GREF and NREF are
22644 specified by numbers as below:
22646 0---1---2 -- ascent
22650 9--10--11 -- center
22652 ---3---4---5--- baseline
22654 6---7---8 -- descent
22656 int rule
= COMPOSITION_RULE (cmp
, i
);
22657 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
, xoff
, yoff
;
22659 COMPOSITION_DECODE_RULE (rule
, gref
, nref
, xoff
, yoff
);
22660 grefx
= gref
% 3, nrefx
= nref
% 3;
22661 grefy
= gref
/ 3, nrefy
= nref
/ 3;
22663 xoff
= font_height
* (xoff
- 128) / 256;
22665 yoff
= font_height
* (yoff
- 128) / 256;
22668 + grefx
* (rightmost
- leftmost
) / 2
22669 - nrefx
* width
/ 2
22672 btm
= ((grefy
== 0 ? highest
22674 : grefy
== 2 ? lowest
22675 : (highest
+ lowest
) / 2)
22676 - (nrefy
== 0 ? ascent
+ descent
22677 : nrefy
== 1 ? descent
- boff
22679 : (ascent
+ descent
) / 2)
22683 cmp
->offsets
[i
* 2] = left
;
22684 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
22686 /* Update the bounding box of the overall glyphs. */
22689 right
= left
+ width
;
22690 if (left
< leftmost
)
22692 if (right
> rightmost
)
22695 top
= btm
+ descent
+ ascent
;
22701 if (cmp
->lbearing
> left
+ lbearing
)
22702 cmp
->lbearing
= left
+ lbearing
;
22703 if (cmp
->rbearing
< left
+ rbearing
)
22704 cmp
->rbearing
= left
+ rbearing
;
22708 /* If there are glyphs whose x-offsets are negative,
22709 shift all glyphs to the right and make all x-offsets
22713 for (i
= 0; i
< cmp
->glyph_len
; i
++)
22714 cmp
->offsets
[i
* 2] -= leftmost
;
22715 rightmost
-= leftmost
;
22716 cmp
->lbearing
-= leftmost
;
22717 cmp
->rbearing
-= leftmost
;
22720 if (left_padded
&& cmp
->lbearing
< 0)
22722 for (i
= 0; i
< cmp
->glyph_len
; i
++)
22723 cmp
->offsets
[i
* 2] -= cmp
->lbearing
;
22724 rightmost
-= cmp
->lbearing
;
22725 cmp
->rbearing
-= cmp
->lbearing
;
22728 if (right_padded
&& rightmost
< cmp
->rbearing
)
22730 rightmost
= cmp
->rbearing
;
22733 cmp
->pixel_width
= rightmost
;
22734 cmp
->ascent
= highest
;
22735 cmp
->descent
= - lowest
;
22736 if (cmp
->ascent
< font_ascent
)
22737 cmp
->ascent
= font_ascent
;
22738 if (cmp
->descent
< font_descent
)
22739 cmp
->descent
= font_descent
;
22743 && (cmp
->lbearing
< 0
22744 || cmp
->rbearing
> cmp
->pixel_width
))
22745 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
22747 it
->pixel_width
= cmp
->pixel_width
;
22748 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
22749 it
->descent
= it
->phys_descent
= cmp
->descent
;
22750 if (face
->box
!= FACE_NO_BOX
)
22752 int thick
= face
->box_line_width
;
22756 it
->ascent
+= thick
;
22757 it
->descent
+= thick
;
22762 if (it
->start_of_box_run_p
)
22763 it
->pixel_width
+= thick
;
22764 if (it
->end_of_box_run_p
)
22765 it
->pixel_width
+= thick
;
22768 /* If face has an overline, add the height of the overline
22769 (1 pixel) and a 1 pixel margin to the character height. */
22770 if (face
->overline_p
)
22771 it
->ascent
+= overline_margin
;
22773 take_vertical_position_into_account (it
);
22774 if (it
->ascent
< 0)
22776 if (it
->descent
< 0)
22780 append_composite_glyph (it
);
22782 else if (it
->what
== IT_COMPOSITION
)
22784 /* A dynamic (automatic) composition. */
22785 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22786 Lisp_Object gstring
;
22787 struct font_metrics metrics
;
22789 gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
22791 = composition_gstring_width (gstring
, it
->cmp_it
.from
, it
->cmp_it
.to
,
22794 && (metrics
.lbearing
< 0 || metrics
.rbearing
> metrics
.width
))
22795 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
22796 it
->ascent
= it
->phys_ascent
= metrics
.ascent
;
22797 it
->descent
= it
->phys_descent
= metrics
.descent
;
22798 if (face
->box
!= FACE_NO_BOX
)
22800 int thick
= face
->box_line_width
;
22804 it
->ascent
+= thick
;
22805 it
->descent
+= thick
;
22810 if (it
->start_of_box_run_p
)
22811 it
->pixel_width
+= thick
;
22812 if (it
->end_of_box_run_p
)
22813 it
->pixel_width
+= thick
;
22815 /* If face has an overline, add the height of the overline
22816 (1 pixel) and a 1 pixel margin to the character height. */
22817 if (face
->overline_p
)
22818 it
->ascent
+= overline_margin
;
22819 take_vertical_position_into_account (it
);
22820 if (it
->ascent
< 0)
22822 if (it
->descent
< 0)
22826 append_composite_glyph (it
);
22828 else if (it
->what
== IT_IMAGE
)
22829 produce_image_glyph (it
);
22830 else if (it
->what
== IT_STRETCH
)
22831 produce_stretch_glyph (it
);
22833 /* Accumulate dimensions. Note: can't assume that it->descent > 0
22834 because this isn't true for images with `:ascent 100'. */
22835 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
22836 if (it
->area
== TEXT_AREA
)
22837 it
->current_x
+= it
->pixel_width
;
22839 if (extra_line_spacing
> 0)
22841 it
->descent
+= extra_line_spacing
;
22842 if (extra_line_spacing
> it
->max_extra_line_spacing
)
22843 it
->max_extra_line_spacing
= extra_line_spacing
;
22846 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
22847 it
->max_descent
= max (it
->max_descent
, it
->descent
);
22848 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
22849 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
22853 Output LEN glyphs starting at START at the nominal cursor position.
22854 Advance the nominal cursor over the text. The global variable
22855 updated_window contains the window being updated, updated_row is
22856 the glyph row being updated, and updated_area is the area of that
22857 row being updated. */
22860 x_write_glyphs (struct glyph
*start
, int len
)
22864 xassert (updated_window
&& updated_row
);
22867 /* Write glyphs. */
22869 hpos
= start
- updated_row
->glyphs
[updated_area
];
22870 x
= draw_glyphs (updated_window
, output_cursor
.x
,
22871 updated_row
, updated_area
,
22873 DRAW_NORMAL_TEXT
, 0);
22875 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
22876 if (updated_area
== TEXT_AREA
22877 && updated_window
->phys_cursor_on_p
22878 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
22879 && updated_window
->phys_cursor
.hpos
>= hpos
22880 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
22881 updated_window
->phys_cursor_on_p
= 0;
22885 /* Advance the output cursor. */
22886 output_cursor
.hpos
+= len
;
22887 output_cursor
.x
= x
;
22892 Insert LEN glyphs from START at the nominal cursor position. */
22895 x_insert_glyphs (struct glyph
*start
, int len
)
22899 int line_height
, shift_by_width
, shifted_region_width
;
22900 struct glyph_row
*row
;
22901 struct glyph
*glyph
;
22902 int frame_x
, frame_y
;
22905 xassert (updated_window
&& updated_row
);
22907 w
= updated_window
;
22908 f
= XFRAME (WINDOW_FRAME (w
));
22910 /* Get the height of the line we are in. */
22912 line_height
= row
->height
;
22914 /* Get the width of the glyphs to insert. */
22915 shift_by_width
= 0;
22916 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
22917 shift_by_width
+= glyph
->pixel_width
;
22919 /* Get the width of the region to shift right. */
22920 shifted_region_width
= (window_box_width (w
, updated_area
)
22925 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
22926 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
22928 FRAME_RIF (f
)->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
22929 line_height
, shift_by_width
);
22931 /* Write the glyphs. */
22932 hpos
= start
- row
->glyphs
[updated_area
];
22933 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
22935 DRAW_NORMAL_TEXT
, 0);
22937 /* Advance the output cursor. */
22938 output_cursor
.hpos
+= len
;
22939 output_cursor
.x
+= shift_by_width
;
22945 Erase the current text line from the nominal cursor position
22946 (inclusive) to pixel column TO_X (exclusive). The idea is that
22947 everything from TO_X onward is already erased.
22949 TO_X is a pixel position relative to updated_area of
22950 updated_window. TO_X == -1 means clear to the end of this area. */
22953 x_clear_end_of_line (int to_x
)
22956 struct window
*w
= updated_window
;
22957 int max_x
, min_y
, max_y
;
22958 int from_x
, from_y
, to_y
;
22960 xassert (updated_window
&& updated_row
);
22961 f
= XFRAME (w
->frame
);
22963 if (updated_row
->full_width_p
)
22964 max_x
= WINDOW_TOTAL_WIDTH (w
);
22966 max_x
= window_box_width (w
, updated_area
);
22967 max_y
= window_text_bottom_y (w
);
22969 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
22970 of window. For TO_X > 0, truncate to end of drawing area. */
22976 to_x
= min (to_x
, max_x
);
22978 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
22980 /* Notice if the cursor will be cleared by this operation. */
22981 if (!updated_row
->full_width_p
)
22982 notice_overwritten_cursor (w
, updated_area
,
22983 output_cursor
.x
, -1,
22985 MATRIX_ROW_BOTTOM_Y (updated_row
));
22987 from_x
= output_cursor
.x
;
22989 /* Translate to frame coordinates. */
22990 if (updated_row
->full_width_p
)
22992 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
22993 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
22997 int area_left
= window_box_left (w
, updated_area
);
22998 from_x
+= area_left
;
23002 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
23003 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
23004 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
23006 /* Prevent inadvertently clearing to end of the X window. */
23007 if (to_x
> from_x
&& to_y
> from_y
)
23010 FRAME_RIF (f
)->clear_frame_area (f
, from_x
, from_y
,
23011 to_x
- from_x
, to_y
- from_y
);
23016 #endif /* HAVE_WINDOW_SYSTEM */
23020 /***********************************************************************
23022 ***********************************************************************/
23024 /* Value is the internal representation of the specified cursor type
23025 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23026 of the bar cursor. */
23028 static enum text_cursor_kinds
23029 get_specified_cursor_type (Lisp_Object arg
, int *width
)
23031 enum text_cursor_kinds type
;
23036 if (EQ (arg
, Qbox
))
23037 return FILLED_BOX_CURSOR
;
23039 if (EQ (arg
, Qhollow
))
23040 return HOLLOW_BOX_CURSOR
;
23042 if (EQ (arg
, Qbar
))
23049 && EQ (XCAR (arg
), Qbar
)
23050 && INTEGERP (XCDR (arg
))
23051 && XINT (XCDR (arg
)) >= 0)
23053 *width
= XINT (XCDR (arg
));
23057 if (EQ (arg
, Qhbar
))
23060 return HBAR_CURSOR
;
23064 && EQ (XCAR (arg
), Qhbar
)
23065 && INTEGERP (XCDR (arg
))
23066 && XINT (XCDR (arg
)) >= 0)
23068 *width
= XINT (XCDR (arg
));
23069 return HBAR_CURSOR
;
23072 /* Treat anything unknown as "hollow box cursor".
23073 It was bad to signal an error; people have trouble fixing
23074 .Xdefaults with Emacs, when it has something bad in it. */
23075 type
= HOLLOW_BOX_CURSOR
;
23080 /* Set the default cursor types for specified frame. */
23082 set_frame_cursor_types (struct frame
*f
, Lisp_Object arg
)
23087 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
23088 FRAME_CURSOR_WIDTH (f
) = width
;
23090 /* By default, set up the blink-off state depending on the on-state. */
23092 tem
= Fassoc (arg
, Vblink_cursor_alist
);
23095 FRAME_BLINK_OFF_CURSOR (f
)
23096 = get_specified_cursor_type (XCDR (tem
), &width
);
23097 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
23100 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
23104 /* Return the cursor we want to be displayed in window W. Return
23105 width of bar/hbar cursor through WIDTH arg. Return with
23106 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23107 (i.e. if the `system caret' should track this cursor).
23109 In a mini-buffer window, we want the cursor only to appear if we
23110 are reading input from this window. For the selected window, we
23111 want the cursor type given by the frame parameter or buffer local
23112 setting of cursor-type. If explicitly marked off, draw no cursor.
23113 In all other cases, we want a hollow box cursor. */
23115 static enum text_cursor_kinds
23116 get_window_cursor_type (struct window
*w
, struct glyph
*glyph
, int *width
,
23117 int *active_cursor
)
23119 struct frame
*f
= XFRAME (w
->frame
);
23120 struct buffer
*b
= XBUFFER (w
->buffer
);
23121 int cursor_type
= DEFAULT_CURSOR
;
23122 Lisp_Object alt_cursor
;
23123 int non_selected
= 0;
23125 *active_cursor
= 1;
23128 if (cursor_in_echo_area
23129 && FRAME_HAS_MINIBUF_P (f
)
23130 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
23132 if (w
== XWINDOW (echo_area_window
))
23134 if (EQ (b
->cursor_type
, Qt
) || NILP (b
->cursor_type
))
23136 *width
= FRAME_CURSOR_WIDTH (f
);
23137 return FRAME_DESIRED_CURSOR (f
);
23140 return get_specified_cursor_type (b
->cursor_type
, width
);
23143 *active_cursor
= 0;
23147 /* Detect a nonselected window or nonselected frame. */
23148 else if (w
!= XWINDOW (f
->selected_window
)
23149 #ifdef HAVE_WINDOW_SYSTEM
23150 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
23154 *active_cursor
= 0;
23156 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
23162 /* Never display a cursor in a window in which cursor-type is nil. */
23163 if (NILP (b
->cursor_type
))
23166 /* Get the normal cursor type for this window. */
23167 if (EQ (b
->cursor_type
, Qt
))
23169 cursor_type
= FRAME_DESIRED_CURSOR (f
);
23170 *width
= FRAME_CURSOR_WIDTH (f
);
23173 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
23175 /* Use cursor-in-non-selected-windows instead
23176 for non-selected window or frame. */
23179 alt_cursor
= b
->cursor_in_non_selected_windows
;
23180 if (!EQ (Qt
, alt_cursor
))
23181 return get_specified_cursor_type (alt_cursor
, width
);
23182 /* t means modify the normal cursor type. */
23183 if (cursor_type
== FILLED_BOX_CURSOR
)
23184 cursor_type
= HOLLOW_BOX_CURSOR
;
23185 else if (cursor_type
== BAR_CURSOR
&& *width
> 1)
23187 return cursor_type
;
23190 /* Use normal cursor if not blinked off. */
23191 if (!w
->cursor_off_p
)
23193 #ifdef HAVE_WINDOW_SYSTEM
23194 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
23196 if (cursor_type
== FILLED_BOX_CURSOR
)
23198 /* Using a block cursor on large images can be very annoying.
23199 So use a hollow cursor for "large" images.
23200 If image is not transparent (no mask), also use hollow cursor. */
23201 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
23202 if (img
!= NULL
&& IMAGEP (img
->spec
))
23204 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23205 where N = size of default frame font size.
23206 This should cover most of the "tiny" icons people may use. */
23208 || img
->width
> max (32, WINDOW_FRAME_COLUMN_WIDTH (w
))
23209 || img
->height
> max (32, WINDOW_FRAME_LINE_HEIGHT (w
)))
23210 cursor_type
= HOLLOW_BOX_CURSOR
;
23213 else if (cursor_type
!= NO_CURSOR
)
23215 /* Display current only supports BOX and HOLLOW cursors for images.
23216 So for now, unconditionally use a HOLLOW cursor when cursor is
23217 not a solid box cursor. */
23218 cursor_type
= HOLLOW_BOX_CURSOR
;
23222 return cursor_type
;
23225 /* Cursor is blinked off, so determine how to "toggle" it. */
23227 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23228 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
23229 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
23231 /* Then see if frame has specified a specific blink off cursor type. */
23232 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
23234 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
23235 return FRAME_BLINK_OFF_CURSOR (f
);
23239 /* Some people liked having a permanently visible blinking cursor,
23240 while others had very strong opinions against it. So it was
23241 decided to remove it. KFS 2003-09-03 */
23243 /* Finally perform built-in cursor blinking:
23244 filled box <-> hollow box
23245 wide [h]bar <-> narrow [h]bar
23246 narrow [h]bar <-> no cursor
23247 other type <-> no cursor */
23249 if (cursor_type
== FILLED_BOX_CURSOR
)
23250 return HOLLOW_BOX_CURSOR
;
23252 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
23255 return cursor_type
;
23263 #ifdef HAVE_WINDOW_SYSTEM
23265 /* Notice when the text cursor of window W has been completely
23266 overwritten by a drawing operation that outputs glyphs in AREA
23267 starting at X0 and ending at X1 in the line starting at Y0 and
23268 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23269 the rest of the line after X0 has been written. Y coordinates
23270 are window-relative. */
23273 notice_overwritten_cursor (struct window
*w
, enum glyph_row_area area
,
23274 int x0
, int x1
, int y0
, int y1
)
23276 int cx0
, cx1
, cy0
, cy1
;
23277 struct glyph_row
*row
;
23279 if (!w
->phys_cursor_on_p
)
23281 if (area
!= TEXT_AREA
)
23284 if (w
->phys_cursor
.vpos
< 0
23285 || w
->phys_cursor
.vpos
>= w
->current_matrix
->nrows
23286 || (row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
,
23287 !(row
->enabled_p
&& row
->displays_text_p
)))
23290 if (row
->cursor_in_fringe_p
)
23292 row
->cursor_in_fringe_p
= 0;
23293 draw_fringe_bitmap (w
, row
, row
->reversed_p
);
23294 w
->phys_cursor_on_p
= 0;
23298 cx0
= w
->phys_cursor
.x
;
23299 cx1
= cx0
+ w
->phys_cursor_width
;
23300 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
23303 /* The cursor image will be completely removed from the
23304 screen if the output area intersects the cursor area in
23305 y-direction. When we draw in [y0 y1[, and some part of
23306 the cursor is at y < y0, that part must have been drawn
23307 before. When scrolling, the cursor is erased before
23308 actually scrolling, so we don't come here. When not
23309 scrolling, the rows above the old cursor row must have
23310 changed, and in this case these rows must have written
23311 over the cursor image.
23313 Likewise if part of the cursor is below y1, with the
23314 exception of the cursor being in the first blank row at
23315 the buffer and window end because update_text_area
23316 doesn't draw that row. (Except when it does, but
23317 that's handled in update_text_area.) */
23319 cy0
= w
->phys_cursor
.y
;
23320 cy1
= cy0
+ w
->phys_cursor_height
;
23321 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
23324 w
->phys_cursor_on_p
= 0;
23327 #endif /* HAVE_WINDOW_SYSTEM */
23330 /************************************************************************
23332 ************************************************************************/
23334 #ifdef HAVE_WINDOW_SYSTEM
23337 Fix the display of area AREA of overlapping row ROW in window W
23338 with respect to the overlapping part OVERLAPS. */
23341 x_fix_overlapping_area (struct window
*w
, struct glyph_row
*row
,
23342 enum glyph_row_area area
, int overlaps
)
23349 for (i
= 0; i
< row
->used
[area
];)
23351 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
23353 int start
= i
, start_x
= x
;
23357 x
+= row
->glyphs
[area
][i
].pixel_width
;
23360 while (i
< row
->used
[area
]
23361 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
23363 draw_glyphs (w
, start_x
, row
, area
,
23365 DRAW_NORMAL_TEXT
, overlaps
);
23369 x
+= row
->glyphs
[area
][i
].pixel_width
;
23379 Draw the cursor glyph of window W in glyph row ROW. See the
23380 comment of draw_glyphs for the meaning of HL. */
23383 draw_phys_cursor_glyph (struct window
*w
, struct glyph_row
*row
,
23384 enum draw_glyphs_face hl
)
23386 /* If cursor hpos is out of bounds, don't draw garbage. This can
23387 happen in mini-buffer windows when switching between echo area
23388 glyphs and mini-buffer. */
23389 if ((row
->reversed_p
23390 ? (w
->phys_cursor
.hpos
>= 0)
23391 : (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])))
23393 int on_p
= w
->phys_cursor_on_p
;
23395 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
23396 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
23398 w
->phys_cursor_on_p
= on_p
;
23400 if (hl
== DRAW_CURSOR
)
23401 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
23402 /* When we erase the cursor, and ROW is overlapped by other
23403 rows, make sure that these overlapping parts of other rows
23405 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
23407 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
23409 if (row
> w
->current_matrix
->rows
23410 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
23411 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
,
23412 OVERLAPS_ERASED_CURSOR
);
23414 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
23415 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
23416 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
,
23417 OVERLAPS_ERASED_CURSOR
);
23424 Erase the image of a cursor of window W from the screen. */
23427 erase_phys_cursor (struct window
*w
)
23429 struct frame
*f
= XFRAME (w
->frame
);
23430 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
23431 int hpos
= w
->phys_cursor
.hpos
;
23432 int vpos
= w
->phys_cursor
.vpos
;
23433 int mouse_face_here_p
= 0;
23434 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
23435 struct glyph_row
*cursor_row
;
23436 struct glyph
*cursor_glyph
;
23437 enum draw_glyphs_face hl
;
23439 /* No cursor displayed or row invalidated => nothing to do on the
23441 if (w
->phys_cursor_type
== NO_CURSOR
)
23442 goto mark_cursor_off
;
23444 /* VPOS >= active_glyphs->nrows means that window has been resized.
23445 Don't bother to erase the cursor. */
23446 if (vpos
>= active_glyphs
->nrows
)
23447 goto mark_cursor_off
;
23449 /* If row containing cursor is marked invalid, there is nothing we
23451 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
23452 if (!cursor_row
->enabled_p
)
23453 goto mark_cursor_off
;
23455 /* If line spacing is > 0, old cursor may only be partially visible in
23456 window after split-window. So adjust visible height. */
23457 cursor_row
->visible_height
= min (cursor_row
->visible_height
,
23458 window_text_bottom_y (w
) - cursor_row
->y
);
23460 /* If row is completely invisible, don't attempt to delete a cursor which
23461 isn't there. This can happen if cursor is at top of a window, and
23462 we switch to a buffer with a header line in that window. */
23463 if (cursor_row
->visible_height
<= 0)
23464 goto mark_cursor_off
;
23466 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23467 if (cursor_row
->cursor_in_fringe_p
)
23469 cursor_row
->cursor_in_fringe_p
= 0;
23470 draw_fringe_bitmap (w
, cursor_row
, cursor_row
->reversed_p
);
23471 goto mark_cursor_off
;
23474 /* This can happen when the new row is shorter than the old one.
23475 In this case, either draw_glyphs or clear_end_of_line
23476 should have cleared the cursor. Note that we wouldn't be
23477 able to erase the cursor in this case because we don't have a
23478 cursor glyph at hand. */
23479 if ((cursor_row
->reversed_p
23480 ? (w
->phys_cursor
.hpos
< 0)
23481 : (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])))
23482 goto mark_cursor_off
;
23484 /* If the cursor is in the mouse face area, redisplay that when
23485 we clear the cursor. */
23486 if (! NILP (dpyinfo
->mouse_face_window
)
23487 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
23488 && (vpos
> dpyinfo
->mouse_face_beg_row
23489 || (vpos
== dpyinfo
->mouse_face_beg_row
23490 && hpos
>= dpyinfo
->mouse_face_beg_col
))
23491 && (vpos
< dpyinfo
->mouse_face_end_row
23492 || (vpos
== dpyinfo
->mouse_face_end_row
23493 && hpos
< dpyinfo
->mouse_face_end_col
))
23494 /* Don't redraw the cursor's spot in mouse face if it is at the
23495 end of a line (on a newline). The cursor appears there, but
23496 mouse highlighting does not. */
23497 && cursor_row
->used
[TEXT_AREA
] > hpos
&& hpos
>= 0)
23498 mouse_face_here_p
= 1;
23500 /* Maybe clear the display under the cursor. */
23501 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
23504 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
23507 cursor_glyph
= get_phys_cursor_glyph (w
);
23508 if (cursor_glyph
== NULL
)
23509 goto mark_cursor_off
;
23511 width
= cursor_glyph
->pixel_width
;
23512 left_x
= window_box_left_offset (w
, TEXT_AREA
);
23513 x
= w
->phys_cursor
.x
;
23515 width
-= left_x
- x
;
23516 width
= min (width
, window_box_width (w
, TEXT_AREA
) - x
);
23517 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
23518 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, max (x
, left_x
));
23521 FRAME_RIF (f
)->clear_frame_area (f
, x
, y
, width
, cursor_row
->visible_height
);
23524 /* Erase the cursor by redrawing the character underneath it. */
23525 if (mouse_face_here_p
)
23526 hl
= DRAW_MOUSE_FACE
;
23528 hl
= DRAW_NORMAL_TEXT
;
23529 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
23532 w
->phys_cursor_on_p
= 0;
23533 w
->phys_cursor_type
= NO_CURSOR
;
23538 Display or clear cursor of window W. If ON is zero, clear the
23539 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23540 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23543 display_and_set_cursor (struct window
*w
, int on
,
23544 int hpos
, int vpos
, int x
, int y
)
23546 struct frame
*f
= XFRAME (w
->frame
);
23547 int new_cursor_type
;
23548 int new_cursor_width
;
23550 struct glyph_row
*glyph_row
;
23551 struct glyph
*glyph
;
23553 /* This is pointless on invisible frames, and dangerous on garbaged
23554 windows and frames; in the latter case, the frame or window may
23555 be in the midst of changing its size, and x and y may be off the
23557 if (! FRAME_VISIBLE_P (f
)
23558 || FRAME_GARBAGED_P (f
)
23559 || vpos
>= w
->current_matrix
->nrows
23560 || hpos
>= w
->current_matrix
->matrix_w
)
23563 /* If cursor is off and we want it off, return quickly. */
23564 if (!on
&& !w
->phys_cursor_on_p
)
23567 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
23568 /* If cursor row is not enabled, we don't really know where to
23569 display the cursor. */
23570 if (!glyph_row
->enabled_p
)
23572 w
->phys_cursor_on_p
= 0;
23577 if (!glyph_row
->exact_window_width_line_p
23578 || (0 <= hpos
&& hpos
< glyph_row
->used
[TEXT_AREA
]))
23579 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
23581 xassert (interrupt_input_blocked
);
23583 /* Set new_cursor_type to the cursor we want to be displayed. */
23584 new_cursor_type
= get_window_cursor_type (w
, glyph
,
23585 &new_cursor_width
, &active_cursor
);
23587 /* If cursor is currently being shown and we don't want it to be or
23588 it is in the wrong place, or the cursor type is not what we want,
23590 if (w
->phys_cursor_on_p
23592 || w
->phys_cursor
.x
!= x
23593 || w
->phys_cursor
.y
!= y
23594 || new_cursor_type
!= w
->phys_cursor_type
23595 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
23596 && new_cursor_width
!= w
->phys_cursor_width
)))
23597 erase_phys_cursor (w
);
23599 /* Don't check phys_cursor_on_p here because that flag is only set
23600 to zero in some cases where we know that the cursor has been
23601 completely erased, to avoid the extra work of erasing the cursor
23602 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23603 still not be visible, or it has only been partly erased. */
23606 w
->phys_cursor_ascent
= glyph_row
->ascent
;
23607 w
->phys_cursor_height
= glyph_row
->height
;
23609 /* Set phys_cursor_.* before x_draw_.* is called because some
23610 of them may need the information. */
23611 w
->phys_cursor
.x
= x
;
23612 w
->phys_cursor
.y
= glyph_row
->y
;
23613 w
->phys_cursor
.hpos
= hpos
;
23614 w
->phys_cursor
.vpos
= vpos
;
23617 FRAME_RIF (f
)->draw_window_cursor (w
, glyph_row
, x
, y
,
23618 new_cursor_type
, new_cursor_width
,
23619 on
, active_cursor
);
23623 /* Switch the display of W's cursor on or off, according to the value
23627 update_window_cursor (struct window
*w
, int on
)
23629 /* Don't update cursor in windows whose frame is in the process
23630 of being deleted. */
23631 if (w
->current_matrix
)
23634 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
23635 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
23641 /* Call update_window_cursor with parameter ON_P on all leaf windows
23642 in the window tree rooted at W. */
23645 update_cursor_in_window_tree (struct window
*w
, int on_p
)
23649 if (!NILP (w
->hchild
))
23650 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
23651 else if (!NILP (w
->vchild
))
23652 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
23654 update_window_cursor (w
, on_p
);
23656 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
23662 Display the cursor on window W, or clear it, according to ON_P.
23663 Don't change the cursor's position. */
23666 x_update_cursor (struct frame
*f
, int on_p
)
23668 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
23673 Clear the cursor of window W to background color, and mark the
23674 cursor as not shown. This is used when the text where the cursor
23675 is about to be rewritten. */
23678 x_clear_cursor (struct window
*w
)
23680 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
23681 update_window_cursor (w
, 0);
23686 Display the active region described by mouse_face_* according to DRAW. */
23689 show_mouse_face (Display_Info
*dpyinfo
, enum draw_glyphs_face draw
)
23691 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
23692 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
23694 if (/* If window is in the process of being destroyed, don't bother
23696 w
->current_matrix
!= NULL
23697 /* Don't update mouse highlight if hidden */
23698 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
23699 /* Recognize when we are called to operate on rows that don't exist
23700 anymore. This can happen when a window is split. */
23701 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
23703 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
23704 struct glyph_row
*row
, *first
, *last
;
23706 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
23707 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
23709 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
23711 int start_hpos
, end_hpos
, start_x
;
23713 /* For all but the first row, the highlight starts at column 0. */
23716 start_hpos
= dpyinfo
->mouse_face_beg_col
;
23717 start_x
= dpyinfo
->mouse_face_beg_x
;
23726 end_hpos
= dpyinfo
->mouse_face_end_col
;
23729 end_hpos
= row
->used
[TEXT_AREA
];
23730 if (draw
== DRAW_NORMAL_TEXT
)
23731 row
->fill_line_p
= 1; /* Clear to end of line */
23734 if (end_hpos
> start_hpos
)
23736 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
23737 start_hpos
, end_hpos
,
23741 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
23745 /* When we've written over the cursor, arrange for it to
23746 be displayed again. */
23747 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
23750 display_and_set_cursor (w
, 1,
23751 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
23752 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
23757 /* Change the mouse cursor. */
23758 if (draw
== DRAW_NORMAL_TEXT
&& !EQ (dpyinfo
->mouse_face_window
, f
->tool_bar_window
))
23759 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
23760 else if (draw
== DRAW_MOUSE_FACE
)
23761 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
23763 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
23767 Clear out the mouse-highlighted active region.
23768 Redraw it un-highlighted first. Value is non-zero if mouse
23769 face was actually drawn unhighlighted. */
23772 clear_mouse_face (Display_Info
*dpyinfo
)
23776 if (!dpyinfo
->mouse_face_hidden
&& !NILP (dpyinfo
->mouse_face_window
))
23778 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
23782 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
23783 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
23784 dpyinfo
->mouse_face_window
= Qnil
;
23785 dpyinfo
->mouse_face_overlay
= Qnil
;
23791 Non-zero if physical cursor of window W is within mouse face. */
23794 cursor_in_mouse_face_p (struct window
*w
)
23796 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
23797 int in_mouse_face
= 0;
23799 if (WINDOWP (dpyinfo
->mouse_face_window
)
23800 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
23802 int hpos
= w
->phys_cursor
.hpos
;
23803 int vpos
= w
->phys_cursor
.vpos
;
23805 if (vpos
>= dpyinfo
->mouse_face_beg_row
23806 && vpos
<= dpyinfo
->mouse_face_end_row
23807 && (vpos
> dpyinfo
->mouse_face_beg_row
23808 || hpos
>= dpyinfo
->mouse_face_beg_col
)
23809 && (vpos
< dpyinfo
->mouse_face_end_row
23810 || hpos
< dpyinfo
->mouse_face_end_col
23811 || dpyinfo
->mouse_face_past_end
))
23815 return in_mouse_face
;
23821 /* This function sets the mouse_face_* elements of DPYINFO, assuming
23822 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
23823 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
23824 for the overlay or run of text properties specifying the mouse
23825 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
23826 before-string and after-string that must also be highlighted.
23827 DISPLAY_STRING, if non-nil, is a display string that may cover some
23828 or all of the highlighted text. */
23831 mouse_face_from_buffer_pos (Lisp_Object window
,
23832 Display_Info
*dpyinfo
,
23833 EMACS_INT mouse_charpos
,
23834 EMACS_INT start_charpos
,
23835 EMACS_INT end_charpos
,
23836 Lisp_Object before_string
,
23837 Lisp_Object after_string
,
23838 Lisp_Object display_string
)
23840 struct window
*w
= XWINDOW (window
);
23841 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
23842 struct glyph_row
*row
;
23843 struct glyph
*glyph
, *end
;
23847 xassert (NILP (display_string
) || STRINGP (display_string
));
23848 xassert (NILP (before_string
) || STRINGP (before_string
));
23849 xassert (NILP (after_string
) || STRINGP (after_string
));
23851 /* Find the first highlighted glyph. */
23852 if (start_charpos
< MATRIX_ROW_START_CHARPOS (first
))
23854 dpyinfo
->mouse_face_beg_col
= 0;
23855 dpyinfo
->mouse_face_beg_row
= MATRIX_ROW_VPOS (first
, w
->current_matrix
);
23856 dpyinfo
->mouse_face_beg_x
= first
->x
;
23857 dpyinfo
->mouse_face_beg_y
= first
->y
;
23861 row
= row_containing_pos (w
, start_charpos
, first
, NULL
, 0);
23863 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
23865 /* If the before-string or display-string contains newlines,
23866 row_containing_pos skips to its last row. Move back. */
23867 if (!NILP (before_string
) || !NILP (display_string
))
23869 struct glyph_row
*prev
;
23870 while ((prev
= row
- 1, prev
>= first
)
23871 && MATRIX_ROW_END_CHARPOS (prev
) == start_charpos
23872 && prev
->used
[TEXT_AREA
] > 0)
23874 struct glyph
*beg
= prev
->glyphs
[TEXT_AREA
];
23875 glyph
= beg
+ prev
->used
[TEXT_AREA
];
23876 while (--glyph
>= beg
&& INTEGERP (glyph
->object
));
23878 || !(EQ (glyph
->object
, before_string
)
23879 || EQ (glyph
->object
, display_string
)))
23885 glyph
= row
->glyphs
[TEXT_AREA
];
23886 end
= glyph
+ row
->used
[TEXT_AREA
];
23888 dpyinfo
->mouse_face_beg_y
= row
->y
;
23889 dpyinfo
->mouse_face_beg_row
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
23891 /* Skip truncation glyphs at the start of the glyph row. */
23892 if (row
->displays_text_p
)
23894 && INTEGERP (glyph
->object
)
23895 && glyph
->charpos
< 0;
23897 x
+= glyph
->pixel_width
;
23899 /* Scan the glyph row, stopping before BEFORE_STRING or
23900 DISPLAY_STRING or START_CHARPOS. */
23902 && !INTEGERP (glyph
->object
)
23903 && !EQ (glyph
->object
, before_string
)
23904 && !EQ (glyph
->object
, display_string
)
23905 && !(BUFFERP (glyph
->object
)
23906 && glyph
->charpos
>= start_charpos
);
23908 x
+= glyph
->pixel_width
;
23910 dpyinfo
->mouse_face_beg_x
= x
;
23911 dpyinfo
->mouse_face_beg_col
= glyph
- row
->glyphs
[TEXT_AREA
];
23914 /* Find the last highlighted glyph. */
23915 row
= row_containing_pos (w
, end_charpos
, first
, NULL
, 0);
23918 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
23919 dpyinfo
->mouse_face_past_end
= 1;
23921 else if (!NILP (after_string
))
23923 /* If the after-string has newlines, advance to its last row. */
23924 struct glyph_row
*next
;
23925 struct glyph_row
*last
23926 = MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
23928 for (next
= row
+ 1;
23930 && next
->used
[TEXT_AREA
] > 0
23931 && EQ (next
->glyphs
[TEXT_AREA
]->object
, after_string
);
23936 glyph
= row
->glyphs
[TEXT_AREA
];
23937 end
= glyph
+ row
->used
[TEXT_AREA
];
23939 dpyinfo
->mouse_face_end_y
= row
->y
;
23940 dpyinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
23942 /* Skip truncation glyphs at the start of the row. */
23943 if (row
->displays_text_p
)
23945 && INTEGERP (glyph
->object
)
23946 && glyph
->charpos
< 0;
23948 x
+= glyph
->pixel_width
;
23950 /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
23953 && !INTEGERP (glyph
->object
)
23954 && !EQ (glyph
->object
, after_string
)
23955 && !(BUFFERP (glyph
->object
) && glyph
->charpos
>= end_charpos
);
23957 x
+= glyph
->pixel_width
;
23959 /* If we found AFTER_STRING, consume it and stop. */
23960 if (EQ (glyph
->object
, after_string
))
23962 for (; EQ (glyph
->object
, after_string
) && glyph
< end
; ++glyph
)
23963 x
+= glyph
->pixel_width
;
23967 /* If there's no after-string, we must check if we overshot,
23968 which might be the case if we stopped after a string glyph.
23969 That glyph may belong to a before-string or display-string
23970 associated with the end position, which must not be
23972 Lisp_Object prev_object
;
23975 while (glyph
> row
->glyphs
[TEXT_AREA
])
23977 prev_object
= (glyph
- 1)->object
;
23978 if (!STRINGP (prev_object
) || EQ (prev_object
, display_string
))
23981 pos
= string_buffer_position (w
, prev_object
, end_charpos
);
23982 if (pos
&& pos
< end_charpos
)
23985 for (; glyph
> row
->glyphs
[TEXT_AREA
]
23986 && EQ ((glyph
- 1)->object
, prev_object
);
23988 x
-= (glyph
- 1)->pixel_width
;
23992 dpyinfo
->mouse_face_end_x
= x
;
23993 dpyinfo
->mouse_face_end_col
= glyph
- row
->glyphs
[TEXT_AREA
];
23994 dpyinfo
->mouse_face_window
= window
;
23995 dpyinfo
->mouse_face_face_id
23996 = face_at_buffer_position (w
, mouse_charpos
, 0, 0, &ignore
,
23998 !dpyinfo
->mouse_face_hidden
, -1);
23999 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
24003 /* Find the position of the glyph for position POS in OBJECT in
24004 window W's current matrix, and return in *X, *Y the pixel
24005 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24007 RIGHT_P non-zero means return the position of the right edge of the
24008 glyph, RIGHT_P zero means return the left edge position.
24010 If no glyph for POS exists in the matrix, return the position of
24011 the glyph with the next smaller position that is in the matrix, if
24012 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24013 exists in the matrix, return the position of the glyph with the
24014 next larger position in OBJECT.
24016 Value is non-zero if a glyph was found. */
24019 fast_find_string_pos (struct window
*w
, EMACS_INT pos
, Lisp_Object object
,
24020 int *hpos
, int *vpos
, int *x
, int *y
, int right_p
)
24022 int yb
= window_text_bottom_y (w
);
24023 struct glyph_row
*r
;
24024 struct glyph
*best_glyph
= NULL
;
24025 struct glyph_row
*best_row
= NULL
;
24028 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
24029 r
->enabled_p
&& r
->y
< yb
;
24032 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
24033 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
24036 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
24037 if (EQ (g
->object
, object
))
24039 if (g
->charpos
== pos
)
24046 else if (best_glyph
== NULL
24047 || ((eabs (g
->charpos
- pos
)
24048 < eabs (best_glyph
->charpos
- pos
))
24051 : g
->charpos
> pos
)))
24065 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
24069 *x
+= best_glyph
->pixel_width
;
24074 *vpos
= best_row
- w
->current_matrix
->rows
;
24077 return best_glyph
!= NULL
;
24081 /* See if position X, Y is within a hot-spot of an image. */
24084 on_hot_spot_p (Lisp_Object hot_spot
, int x
, int y
)
24086 if (!CONSP (hot_spot
))
24089 if (EQ (XCAR (hot_spot
), Qrect
))
24091 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24092 Lisp_Object rect
= XCDR (hot_spot
);
24096 if (!CONSP (XCAR (rect
)))
24098 if (!CONSP (XCDR (rect
)))
24100 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
24102 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
24104 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
24106 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
24110 else if (EQ (XCAR (hot_spot
), Qcircle
))
24112 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24113 Lisp_Object circ
= XCDR (hot_spot
);
24114 Lisp_Object lr
, lx0
, ly0
;
24116 && CONSP (XCAR (circ
))
24117 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
24118 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
24119 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
24121 double r
= XFLOATINT (lr
);
24122 double dx
= XINT (lx0
) - x
;
24123 double dy
= XINT (ly0
) - y
;
24124 return (dx
* dx
+ dy
* dy
<= r
* r
);
24127 else if (EQ (XCAR (hot_spot
), Qpoly
))
24129 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24130 if (VECTORP (XCDR (hot_spot
)))
24132 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
24133 Lisp_Object
*poly
= v
->contents
;
24137 Lisp_Object lx
, ly
;
24140 /* Need an even number of coordinates, and at least 3 edges. */
24141 if (n
< 6 || n
& 1)
24144 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24145 If count is odd, we are inside polygon. Pixels on edges
24146 may or may not be included depending on actual geometry of the
24148 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
24149 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
24151 x0
= XINT (lx
), y0
= XINT (ly
);
24152 for (i
= 0; i
< n
; i
+= 2)
24154 int x1
= x0
, y1
= y0
;
24155 if ((lx
= poly
[i
], !INTEGERP (lx
))
24156 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
24158 x0
= XINT (lx
), y0
= XINT (ly
);
24160 /* Does this segment cross the X line? */
24168 if (y
> y0
&& y
> y1
)
24170 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
24180 find_hot_spot (Lisp_Object map
, int x
, int y
)
24182 while (CONSP (map
))
24184 if (CONSP (XCAR (map
))
24185 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
24193 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
24195 doc
: /* Lookup in image map MAP coordinates X and Y.
24196 An image map is an alist where each element has the format (AREA ID PLIST).
24197 An AREA is specified as either a rectangle, a circle, or a polygon:
24198 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
24199 pixel coordinates of the upper left and bottom right corners.
24200 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
24201 and the radius of the circle; r may be a float or integer.
24202 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
24203 vector describes one corner in the polygon.
24204 Returns the alist element for the first matching AREA in MAP. */)
24205 (Lisp_Object map
, Lisp_Object x
, Lisp_Object y
)
24213 return find_hot_spot (map
, XINT (x
), XINT (y
));
24217 /* Display frame CURSOR, optionally using shape defined by POINTER. */
24219 define_frame_cursor1 (struct frame
*f
, Cursor cursor
, Lisp_Object pointer
)
24221 /* Do not change cursor shape while dragging mouse. */
24222 if (!NILP (do_mouse_tracking
))
24225 if (!NILP (pointer
))
24227 if (EQ (pointer
, Qarrow
))
24228 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24229 else if (EQ (pointer
, Qhand
))
24230 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
24231 else if (EQ (pointer
, Qtext
))
24232 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
24233 else if (EQ (pointer
, intern ("hdrag")))
24234 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
24235 #ifdef HAVE_X_WINDOWS
24236 else if (EQ (pointer
, intern ("vdrag")))
24237 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
24239 else if (EQ (pointer
, intern ("hourglass")))
24240 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
24241 else if (EQ (pointer
, Qmodeline
))
24242 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
24244 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24247 if (cursor
!= No_Cursor
)
24248 FRAME_RIF (f
)->define_frame_cursor (f
, cursor
);
24251 /* Take proper action when mouse has moved to the mode or header line
24252 or marginal area AREA of window W, x-position X and y-position Y.
24253 X is relative to the start of the text display area of W, so the
24254 width of bitmap areas and scroll bars must be subtracted to get a
24255 position relative to the start of the mode line. */
24258 note_mode_line_or_margin_highlight (Lisp_Object window
, int x
, int y
,
24259 enum window_part area
)
24261 struct window
*w
= XWINDOW (window
);
24262 struct frame
*f
= XFRAME (w
->frame
);
24263 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
24264 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24265 Lisp_Object pointer
= Qnil
;
24266 int charpos
, dx
, dy
, width
, height
;
24267 Lisp_Object string
, object
= Qnil
;
24268 Lisp_Object pos
, help
;
24270 Lisp_Object mouse_face
;
24271 int original_x_pixel
= x
;
24272 struct glyph
* glyph
= NULL
, * row_start_glyph
= NULL
;
24273 struct glyph_row
*row
;
24275 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
24280 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
24281 &object
, &dx
, &dy
, &width
, &height
);
24283 row
= (area
== ON_MODE_LINE
24284 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
24285 : MATRIX_HEADER_LINE_ROW (w
->current_matrix
));
24288 if (row
->mode_line_p
&& row
->enabled_p
)
24290 glyph
= row_start_glyph
= row
->glyphs
[TEXT_AREA
];
24291 end
= glyph
+ row
->used
[TEXT_AREA
];
24293 for (x0
= original_x_pixel
;
24294 glyph
< end
&& x0
>= glyph
->pixel_width
;
24296 x0
-= glyph
->pixel_width
;
24304 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
24305 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
24306 &object
, &dx
, &dy
, &width
, &height
);
24311 if (IMAGEP (object
))
24313 Lisp_Object image_map
, hotspot
;
24314 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
24316 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
24318 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
24320 Lisp_Object area_id
, plist
;
24322 area_id
= XCAR (hotspot
);
24323 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24324 If so, we could look for mouse-enter, mouse-leave
24325 properties in PLIST (and do something...). */
24326 hotspot
= XCDR (hotspot
);
24327 if (CONSP (hotspot
)
24328 && (plist
= XCAR (hotspot
), CONSP (plist
)))
24330 pointer
= Fplist_get (plist
, Qpointer
);
24331 if (NILP (pointer
))
24333 help
= Fplist_get (plist
, Qhelp_echo
);
24336 help_echo_string
= help
;
24337 /* Is this correct? ++kfs */
24338 XSETWINDOW (help_echo_window
, w
);
24339 help_echo_object
= w
->buffer
;
24340 help_echo_pos
= charpos
;
24344 if (NILP (pointer
))
24345 pointer
= Fplist_get (XCDR (object
), QCpointer
);
24348 if (STRINGP (string
))
24350 pos
= make_number (charpos
);
24351 /* If we're on a string with `help-echo' text property, arrange
24352 for the help to be displayed. This is done by setting the
24353 global variable help_echo_string to the help string. */
24356 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
24359 help_echo_string
= help
;
24360 XSETWINDOW (help_echo_window
, w
);
24361 help_echo_object
= string
;
24362 help_echo_pos
= charpos
;
24366 if (NILP (pointer
))
24367 pointer
= Fget_text_property (pos
, Qpointer
, string
);
24369 /* Change the mouse pointer according to what is under X/Y. */
24370 if (NILP (pointer
) && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
24373 map
= Fget_text_property (pos
, Qlocal_map
, string
);
24374 if (!KEYMAPP (map
))
24375 map
= Fget_text_property (pos
, Qkeymap
, string
);
24376 if (!KEYMAPP (map
))
24377 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
24380 /* Change the mouse face according to what is under X/Y. */
24381 mouse_face
= Fget_text_property (pos
, Qmouse_face
, string
);
24382 if (!NILP (mouse_face
)
24383 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
24388 struct glyph
* tmp_glyph
;
24392 int total_pixel_width
;
24397 b
= Fprevious_single_property_change (make_number (charpos
+ 1),
24398 Qmouse_face
, string
, Qnil
);
24400 b
= make_number (0);
24402 e
= Fnext_single_property_change (pos
, Qmouse_face
, string
, Qnil
);
24404 e
= make_number (SCHARS (string
));
24406 /* Calculate the position(glyph position: GPOS) of GLYPH in
24407 displayed string. GPOS is different from CHARPOS.
24409 CHARPOS is the position of glyph in internal string
24410 object. A mode line string format has structures which
24411 is converted to a flatten by emacs lisp interpreter.
24412 The internal string is an element of the structures.
24413 The displayed string is the flatten string. */
24415 if (glyph
> row_start_glyph
)
24417 tmp_glyph
= glyph
- 1;
24418 while (tmp_glyph
>= row_start_glyph
24419 && tmp_glyph
->charpos
>= XINT (b
)
24420 && EQ (tmp_glyph
->object
, glyph
->object
))
24427 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
24428 displayed string holding GLYPH.
24430 GSEQ_LENGTH is different from SCHARS (STRING).
24431 SCHARS (STRING) returns the length of the internal string. */
24432 for (tmp_glyph
= glyph
, gseq_length
= gpos
;
24433 tmp_glyph
->charpos
< XINT (e
);
24434 tmp_glyph
++, gseq_length
++)
24436 if (!EQ (tmp_glyph
->object
, glyph
->object
))
24440 total_pixel_width
= 0;
24441 for (tmp_glyph
= glyph
- gpos
; tmp_glyph
!= glyph
; tmp_glyph
++)
24442 total_pixel_width
+= tmp_glyph
->pixel_width
;
24444 /* Pre calculation of re-rendering position */
24446 hpos
= (area
== ON_MODE_LINE
24447 ? (w
->current_matrix
)->nrows
- 1
24450 /* If the re-rendering position is included in the last
24451 re-rendering area, we should do nothing. */
24452 if ( EQ (window
, dpyinfo
->mouse_face_window
)
24453 && dpyinfo
->mouse_face_beg_col
<= vpos
24454 && vpos
< dpyinfo
->mouse_face_end_col
24455 && dpyinfo
->mouse_face_beg_row
== hpos
)
24458 if (clear_mouse_face (dpyinfo
))
24459 cursor
= No_Cursor
;
24461 dpyinfo
->mouse_face_beg_col
= vpos
;
24462 dpyinfo
->mouse_face_beg_row
= hpos
;
24464 dpyinfo
->mouse_face_beg_x
= original_x_pixel
- (total_pixel_width
+ dx
);
24465 dpyinfo
->mouse_face_beg_y
= 0;
24467 dpyinfo
->mouse_face_end_col
= vpos
+ gseq_length
;
24468 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_beg_row
;
24470 dpyinfo
->mouse_face_end_x
= 0;
24471 dpyinfo
->mouse_face_end_y
= 0;
24473 dpyinfo
->mouse_face_past_end
= 0;
24474 dpyinfo
->mouse_face_window
= window
;
24476 dpyinfo
->mouse_face_face_id
= face_at_string_position (w
, string
,
24479 glyph
->face_id
, 1);
24480 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
24482 if (NILP (pointer
))
24485 else if ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
24486 clear_mouse_face (dpyinfo
);
24488 define_frame_cursor1 (f
, cursor
, pointer
);
24493 Take proper action when the mouse has moved to position X, Y on
24494 frame F as regards highlighting characters that have mouse-face
24495 properties. Also de-highlighting chars where the mouse was before.
24496 X and Y can be negative or out of range. */
24499 note_mouse_highlight (struct frame
*f
, int x
, int y
)
24501 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
24502 enum window_part part
;
24503 Lisp_Object window
;
24505 Cursor cursor
= No_Cursor
;
24506 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
24509 /* When a menu is active, don't highlight because this looks odd. */
24510 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
24511 if (popup_activated ())
24515 if (NILP (Vmouse_highlight
)
24516 || !f
->glyphs_initialized_p
24517 || f
->pointer_invisible
)
24520 dpyinfo
->mouse_face_mouse_x
= x
;
24521 dpyinfo
->mouse_face_mouse_y
= y
;
24522 dpyinfo
->mouse_face_mouse_frame
= f
;
24524 if (dpyinfo
->mouse_face_defer
)
24527 if (gc_in_progress
)
24529 dpyinfo
->mouse_face_deferred_gc
= 1;
24533 /* Which window is that in? */
24534 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
24536 /* If we were displaying active text in another window, clear that.
24537 Also clear if we move out of text area in same window. */
24538 if (! EQ (window
, dpyinfo
->mouse_face_window
)
24539 || (part
!= ON_TEXT
&& part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
24540 && !NILP (dpyinfo
->mouse_face_window
)))
24541 clear_mouse_face (dpyinfo
);
24543 /* Not on a window -> return. */
24544 if (!WINDOWP (window
))
24547 /* Reset help_echo_string. It will get recomputed below. */
24548 help_echo_string
= Qnil
;
24550 /* Convert to window-relative pixel coordinates. */
24551 w
= XWINDOW (window
);
24552 frame_to_window_pixel_xy (w
, &x
, &y
);
24554 /* Handle tool-bar window differently since it doesn't display a
24556 if (EQ (window
, f
->tool_bar_window
))
24558 note_tool_bar_highlight (f
, x
, y
);
24562 /* Mouse is on the mode, header line or margin? */
24563 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
24564 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
24566 note_mode_line_or_margin_highlight (window
, x
, y
, part
);
24570 if (part
== ON_VERTICAL_BORDER
)
24572 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
24573 help_echo_string
= build_string ("drag-mouse-1: resize");
24575 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
24576 || part
== ON_SCROLL_BAR
)
24577 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24579 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
24581 /* Are we in a window whose display is up to date?
24582 And verify the buffer's text has not changed. */
24583 b
= XBUFFER (w
->buffer
);
24584 if (part
== ON_TEXT
24585 && EQ (w
->window_end_valid
, w
->buffer
)
24586 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
24587 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
24589 int hpos
, vpos
, i
, dx
, dy
, area
;
24591 struct glyph
*glyph
;
24592 Lisp_Object object
;
24593 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
24594 Lisp_Object
*overlay_vec
= NULL
;
24596 struct buffer
*obuf
;
24597 int obegv
, ozv
, same_region
;
24599 /* Find the glyph under X/Y. */
24600 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
24602 /* Look for :pointer property on image. */
24603 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
24605 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
24606 if (img
!= NULL
&& IMAGEP (img
->spec
))
24608 Lisp_Object image_map
, hotspot
;
24609 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
24611 && (hotspot
= find_hot_spot (image_map
,
24612 glyph
->slice
.x
+ dx
,
24613 glyph
->slice
.y
+ dy
),
24615 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
24617 Lisp_Object area_id
, plist
;
24619 area_id
= XCAR (hotspot
);
24620 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24621 If so, we could look for mouse-enter, mouse-leave
24622 properties in PLIST (and do something...). */
24623 hotspot
= XCDR (hotspot
);
24624 if (CONSP (hotspot
)
24625 && (plist
= XCAR (hotspot
), CONSP (plist
)))
24627 pointer
= Fplist_get (plist
, Qpointer
);
24628 if (NILP (pointer
))
24630 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
24631 if (!NILP (help_echo_string
))
24633 help_echo_window
= window
;
24634 help_echo_object
= glyph
->object
;
24635 help_echo_pos
= glyph
->charpos
;
24639 if (NILP (pointer
))
24640 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
24644 /* Clear mouse face if X/Y not over text. */
24646 || area
!= TEXT_AREA
24647 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
24649 if (clear_mouse_face (dpyinfo
))
24650 cursor
= No_Cursor
;
24651 if (NILP (pointer
))
24653 if (area
!= TEXT_AREA
)
24654 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
24656 pointer
= Vvoid_text_area_pointer
;
24661 pos
= glyph
->charpos
;
24662 object
= glyph
->object
;
24663 if (!STRINGP (object
) && !BUFFERP (object
))
24666 /* If we get an out-of-range value, return now; avoid an error. */
24667 if (BUFFERP (object
) && pos
> BUF_Z (b
))
24670 /* Make the window's buffer temporarily current for
24671 overlays_at and compute_char_face. */
24672 obuf
= current_buffer
;
24673 current_buffer
= b
;
24679 /* Is this char mouse-active or does it have help-echo? */
24680 position
= make_number (pos
);
24682 if (BUFFERP (object
))
24684 /* Put all the overlays we want in a vector in overlay_vec. */
24685 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
24686 /* Sort overlays into increasing priority order. */
24687 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
24692 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
24693 && vpos
>= dpyinfo
->mouse_face_beg_row
24694 && vpos
<= dpyinfo
->mouse_face_end_row
24695 && (vpos
> dpyinfo
->mouse_face_beg_row
24696 || hpos
>= dpyinfo
->mouse_face_beg_col
)
24697 && (vpos
< dpyinfo
->mouse_face_end_row
24698 || hpos
< dpyinfo
->mouse_face_end_col
24699 || dpyinfo
->mouse_face_past_end
));
24702 cursor
= No_Cursor
;
24704 /* Check mouse-face highlighting. */
24706 /* If there exists an overlay with mouse-face overlapping
24707 the one we are currently highlighting, we have to
24708 check if we enter the overlapping overlay, and then
24709 highlight only that. */
24710 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
24711 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
24713 /* Find the highest priority overlay with a mouse-face. */
24715 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
24717 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
24718 if (!NILP (mouse_face
))
24719 overlay
= overlay_vec
[i
];
24722 /* If we're highlighting the same overlay as before, there's
24723 no need to do that again. */
24724 if (!NILP (overlay
) && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
24725 goto check_help_echo
;
24726 dpyinfo
->mouse_face_overlay
= overlay
;
24728 /* Clear the display of the old active region, if any. */
24729 if (clear_mouse_face (dpyinfo
))
24730 cursor
= No_Cursor
;
24732 /* If no overlay applies, get a text property. */
24733 if (NILP (overlay
))
24734 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
24736 /* Next, compute the bounds of the mouse highlighting and
24738 if (!NILP (mouse_face
) && STRINGP (object
))
24740 /* The mouse-highlighting comes from a display string
24741 with a mouse-face. */
24745 b
= Fprevious_single_property_change
24746 (make_number (pos
+ 1), Qmouse_face
, object
, Qnil
);
24747 e
= Fnext_single_property_change
24748 (position
, Qmouse_face
, object
, Qnil
);
24750 b
= make_number (0);
24752 e
= make_number (SCHARS (object
) - 1);
24754 fast_find_string_pos (w
, XINT (b
), object
,
24755 &dpyinfo
->mouse_face_beg_col
,
24756 &dpyinfo
->mouse_face_beg_row
,
24757 &dpyinfo
->mouse_face_beg_x
,
24758 &dpyinfo
->mouse_face_beg_y
, 0);
24759 fast_find_string_pos (w
, XINT (e
), object
,
24760 &dpyinfo
->mouse_face_end_col
,
24761 &dpyinfo
->mouse_face_end_row
,
24762 &dpyinfo
->mouse_face_end_x
,
24763 &dpyinfo
->mouse_face_end_y
, 1);
24764 dpyinfo
->mouse_face_past_end
= 0;
24765 dpyinfo
->mouse_face_window
= window
;
24766 dpyinfo
->mouse_face_face_id
24767 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
24768 glyph
->face_id
, 1);
24769 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
24770 cursor
= No_Cursor
;
24774 /* The mouse-highlighting, if any, comes from an overlay
24775 or text property in the buffer. */
24776 Lisp_Object buffer
, display_string
;
24778 if (STRINGP (object
))
24780 /* If we are on a display string with no mouse-face,
24781 check if the text under it has one. */
24782 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
24783 int start
= MATRIX_ROW_START_CHARPOS (r
);
24784 pos
= string_buffer_position (w
, object
, start
);
24787 mouse_face
= get_char_property_and_overlay
24788 (make_number (pos
), Qmouse_face
, w
->buffer
, &overlay
);
24789 buffer
= w
->buffer
;
24790 display_string
= object
;
24796 display_string
= Qnil
;
24799 if (!NILP (mouse_face
))
24801 Lisp_Object before
, after
;
24802 Lisp_Object before_string
, after_string
;
24804 if (NILP (overlay
))
24806 /* Handle the text property case. */
24807 before
= Fprevious_single_property_change
24808 (make_number (pos
+ 1), Qmouse_face
, buffer
,
24809 Fmarker_position (w
->start
));
24810 after
= Fnext_single_property_change
24811 (make_number (pos
), Qmouse_face
, buffer
,
24812 make_number (BUF_Z (XBUFFER (buffer
))
24813 - XFASTINT (w
->window_end_pos
)));
24814 before_string
= after_string
= Qnil
;
24818 /* Handle the overlay case. */
24819 before
= Foverlay_start (overlay
);
24820 after
= Foverlay_end (overlay
);
24821 before_string
= Foverlay_get (overlay
, Qbefore_string
);
24822 after_string
= Foverlay_get (overlay
, Qafter_string
);
24824 if (!STRINGP (before_string
)) before_string
= Qnil
;
24825 if (!STRINGP (after_string
)) after_string
= Qnil
;
24828 mouse_face_from_buffer_pos (window
, dpyinfo
, pos
,
24831 before_string
, after_string
,
24833 cursor
= No_Cursor
;
24840 /* Look for a `help-echo' property. */
24841 if (NILP (help_echo_string
)) {
24842 Lisp_Object help
, overlay
;
24844 /* Check overlays first. */
24845 help
= overlay
= Qnil
;
24846 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
24848 overlay
= overlay_vec
[i
];
24849 help
= Foverlay_get (overlay
, Qhelp_echo
);
24854 help_echo_string
= help
;
24855 help_echo_window
= window
;
24856 help_echo_object
= overlay
;
24857 help_echo_pos
= pos
;
24861 Lisp_Object object
= glyph
->object
;
24862 int charpos
= glyph
->charpos
;
24864 /* Try text properties. */
24865 if (STRINGP (object
)
24867 && charpos
< SCHARS (object
))
24869 help
= Fget_text_property (make_number (charpos
),
24870 Qhelp_echo
, object
);
24873 /* If the string itself doesn't specify a help-echo,
24874 see if the buffer text ``under'' it does. */
24875 struct glyph_row
*r
24876 = MATRIX_ROW (w
->current_matrix
, vpos
);
24877 int start
= MATRIX_ROW_START_CHARPOS (r
);
24878 EMACS_INT pos
= string_buffer_position (w
, object
, start
);
24881 help
= Fget_char_property (make_number (pos
),
24882 Qhelp_echo
, w
->buffer
);
24886 object
= w
->buffer
;
24891 else if (BUFFERP (object
)
24894 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
24899 help_echo_string
= help
;
24900 help_echo_window
= window
;
24901 help_echo_object
= object
;
24902 help_echo_pos
= charpos
;
24907 /* Look for a `pointer' property. */
24908 if (NILP (pointer
))
24910 /* Check overlays first. */
24911 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
24912 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
24914 if (NILP (pointer
))
24916 Lisp_Object object
= glyph
->object
;
24917 int charpos
= glyph
->charpos
;
24919 /* Try text properties. */
24920 if (STRINGP (object
)
24922 && charpos
< SCHARS (object
))
24924 pointer
= Fget_text_property (make_number (charpos
),
24926 if (NILP (pointer
))
24928 /* If the string itself doesn't specify a pointer,
24929 see if the buffer text ``under'' it does. */
24930 struct glyph_row
*r
24931 = MATRIX_ROW (w
->current_matrix
, vpos
);
24932 int start
= MATRIX_ROW_START_CHARPOS (r
);
24933 EMACS_INT pos
= string_buffer_position (w
, object
,
24936 pointer
= Fget_char_property (make_number (pos
),
24937 Qpointer
, w
->buffer
);
24940 else if (BUFFERP (object
)
24943 pointer
= Fget_text_property (make_number (charpos
),
24950 current_buffer
= obuf
;
24955 define_frame_cursor1 (f
, cursor
, pointer
);
24960 Clear any mouse-face on window W. This function is part of the
24961 redisplay interface, and is called from try_window_id and similar
24962 functions to ensure the mouse-highlight is off. */
24965 x_clear_window_mouse_face (struct window
*w
)
24967 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
24968 Lisp_Object window
;
24971 XSETWINDOW (window
, w
);
24972 if (EQ (window
, dpyinfo
->mouse_face_window
))
24973 clear_mouse_face (dpyinfo
);
24979 Just discard the mouse face information for frame F, if any.
24980 This is used when the size of F is changed. */
24983 cancel_mouse_face (struct frame
*f
)
24985 Lisp_Object window
;
24986 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
24988 window
= dpyinfo
->mouse_face_window
;
24989 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
24991 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
24992 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
24993 dpyinfo
->mouse_face_window
= Qnil
;
24998 #endif /* HAVE_WINDOW_SYSTEM */
25001 /***********************************************************************
25003 ***********************************************************************/
25005 #ifdef HAVE_WINDOW_SYSTEM
25007 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25008 which intersects rectangle R. R is in window-relative coordinates. */
25011 expose_area (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
,
25012 enum glyph_row_area area
)
25014 struct glyph
*first
= row
->glyphs
[area
];
25015 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
25016 struct glyph
*last
;
25017 int first_x
, start_x
, x
;
25019 if (area
== TEXT_AREA
&& row
->fill_line_p
)
25020 /* If row extends face to end of line write the whole line. */
25021 draw_glyphs (w
, 0, row
, area
,
25022 0, row
->used
[area
],
25023 DRAW_NORMAL_TEXT
, 0);
25026 /* Set START_X to the window-relative start position for drawing glyphs of
25027 AREA. The first glyph of the text area can be partially visible.
25028 The first glyphs of other areas cannot. */
25029 start_x
= window_box_left_offset (w
, area
);
25031 if (area
== TEXT_AREA
)
25034 /* Find the first glyph that must be redrawn. */
25036 && x
+ first
->pixel_width
< r
->x
)
25038 x
+= first
->pixel_width
;
25042 /* Find the last one. */
25046 && x
< r
->x
+ r
->width
)
25048 x
+= last
->pixel_width
;
25054 draw_glyphs (w
, first_x
- start_x
, row
, area
,
25055 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
25056 DRAW_NORMAL_TEXT
, 0);
25061 /* Redraw the parts of the glyph row ROW on window W intersecting
25062 rectangle R. R is in window-relative coordinates. Value is
25063 non-zero if mouse-face was overwritten. */
25066 expose_line (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
)
25068 xassert (row
->enabled_p
);
25070 if (row
->mode_line_p
|| w
->pseudo_window_p
)
25071 draw_glyphs (w
, 0, row
, TEXT_AREA
,
25072 0, row
->used
[TEXT_AREA
],
25073 DRAW_NORMAL_TEXT
, 0);
25076 if (row
->used
[LEFT_MARGIN_AREA
])
25077 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
25078 if (row
->used
[TEXT_AREA
])
25079 expose_area (w
, row
, r
, TEXT_AREA
);
25080 if (row
->used
[RIGHT_MARGIN_AREA
])
25081 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
25082 draw_row_fringe_bitmaps (w
, row
);
25085 return row
->mouse_face_p
;
25089 /* Redraw those parts of glyphs rows during expose event handling that
25090 overlap other rows. Redrawing of an exposed line writes over parts
25091 of lines overlapping that exposed line; this function fixes that.
25093 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25094 row in W's current matrix that is exposed and overlaps other rows.
25095 LAST_OVERLAPPING_ROW is the last such row. */
25098 expose_overlaps (struct window
*w
,
25099 struct glyph_row
*first_overlapping_row
,
25100 struct glyph_row
*last_overlapping_row
,
25103 struct glyph_row
*row
;
25105 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
25106 if (row
->overlapping_p
)
25108 xassert (row
->enabled_p
&& !row
->mode_line_p
);
25111 if (row
->used
[LEFT_MARGIN_AREA
])
25112 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
, OVERLAPS_BOTH
);
25114 if (row
->used
[TEXT_AREA
])
25115 x_fix_overlapping_area (w
, row
, TEXT_AREA
, OVERLAPS_BOTH
);
25117 if (row
->used
[RIGHT_MARGIN_AREA
])
25118 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
, OVERLAPS_BOTH
);
25124 /* Return non-zero if W's cursor intersects rectangle R. */
25127 phys_cursor_in_rect_p (struct window
*w
, XRectangle
*r
)
25129 XRectangle cr
, result
;
25130 struct glyph
*cursor_glyph
;
25131 struct glyph_row
*row
;
25133 if (w
->phys_cursor
.vpos
>= 0
25134 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
25135 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
25137 && row
->cursor_in_fringe_p
)
25139 /* Cursor is in the fringe. */
25140 cr
.x
= window_box_right_offset (w
,
25141 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
25142 ? RIGHT_MARGIN_AREA
25145 cr
.width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
25146 cr
.height
= row
->height
;
25147 return x_intersect_rectangles (&cr
, r
, &result
);
25150 cursor_glyph
= get_phys_cursor_glyph (w
);
25153 /* r is relative to W's box, but w->phys_cursor.x is relative
25154 to left edge of W's TEXT area. Adjust it. */
25155 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
25156 cr
.y
= w
->phys_cursor
.y
;
25157 cr
.width
= cursor_glyph
->pixel_width
;
25158 cr
.height
= w
->phys_cursor_height
;
25159 /* ++KFS: W32 version used W32-specific IntersectRect here, but
25160 I assume the effect is the same -- and this is portable. */
25161 return x_intersect_rectangles (&cr
, r
, &result
);
25163 /* If we don't understand the format, pretend we're not in the hot-spot. */
25169 Draw a vertical window border to the right of window W if W doesn't
25170 have vertical scroll bars. */
25173 x_draw_vertical_border (struct window
*w
)
25175 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
25177 /* We could do better, if we knew what type of scroll-bar the adjacent
25178 windows (on either side) have... But we don't :-(
25179 However, I think this works ok. ++KFS 2003-04-25 */
25181 /* Redraw borders between horizontally adjacent windows. Don't
25182 do it for frames with vertical scroll bars because either the
25183 right scroll bar of a window, or the left scroll bar of its
25184 neighbor will suffice as a border. */
25185 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w
->frame
)))
25188 if (!WINDOW_RIGHTMOST_P (w
)
25189 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
25191 int x0
, x1
, y0
, y1
;
25193 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
25196 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
25199 FRAME_RIF (f
)->draw_vertical_window_border (w
, x1
, y0
, y1
);
25201 else if (!WINDOW_LEFTMOST_P (w
)
25202 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
25204 int x0
, x1
, y0
, y1
;
25206 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
25209 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
25212 FRAME_RIF (f
)->draw_vertical_window_border (w
, x0
, y0
, y1
);
25217 /* Redraw the part of window W intersection rectangle FR. Pixel
25218 coordinates in FR are frame-relative. Call this function with
25219 input blocked. Value is non-zero if the exposure overwrites
25223 expose_window (struct window
*w
, XRectangle
*fr
)
25225 struct frame
*f
= XFRAME (w
->frame
);
25227 int mouse_face_overwritten_p
= 0;
25229 /* If window is not yet fully initialized, do nothing. This can
25230 happen when toolkit scroll bars are used and a window is split.
25231 Reconfiguring the scroll bar will generate an expose for a newly
25233 if (w
->current_matrix
== NULL
)
25236 /* When we're currently updating the window, display and current
25237 matrix usually don't agree. Arrange for a thorough display
25239 if (w
== updated_window
)
25241 SET_FRAME_GARBAGED (f
);
25245 /* Frame-relative pixel rectangle of W. */
25246 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
25247 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
25248 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
25249 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
25251 if (x_intersect_rectangles (fr
, &wr
, &r
))
25253 int yb
= window_text_bottom_y (w
);
25254 struct glyph_row
*row
;
25255 int cursor_cleared_p
;
25256 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
25258 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
25259 r
.x
, r
.y
, r
.width
, r
.height
));
25261 /* Convert to window coordinates. */
25262 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
25263 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
25265 /* Turn off the cursor. */
25266 if (!w
->pseudo_window_p
25267 && phys_cursor_in_rect_p (w
, &r
))
25269 x_clear_cursor (w
);
25270 cursor_cleared_p
= 1;
25273 cursor_cleared_p
= 0;
25275 /* Update lines intersecting rectangle R. */
25276 first_overlapping_row
= last_overlapping_row
= NULL
;
25277 for (row
= w
->current_matrix
->rows
;
25282 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
25284 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
25285 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
25286 || (r
.y
>= y0
&& r
.y
< y1
)
25287 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
25289 /* A header line may be overlapping, but there is no need
25290 to fix overlapping areas for them. KFS 2005-02-12 */
25291 if (row
->overlapping_p
&& !row
->mode_line_p
)
25293 if (first_overlapping_row
== NULL
)
25294 first_overlapping_row
= row
;
25295 last_overlapping_row
= row
;
25299 if (expose_line (w
, row
, &r
))
25300 mouse_face_overwritten_p
= 1;
25303 else if (row
->overlapping_p
)
25305 /* We must redraw a row overlapping the exposed area. */
25307 ? y0
+ row
->phys_height
> r
.y
25308 : y0
+ row
->ascent
- row
->phys_ascent
< r
.y
+r
.height
)
25310 if (first_overlapping_row
== NULL
)
25311 first_overlapping_row
= row
;
25312 last_overlapping_row
= row
;
25320 /* Display the mode line if there is one. */
25321 if (WINDOW_WANTS_MODELINE_P (w
)
25322 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
25324 && row
->y
< r
.y
+ r
.height
)
25326 if (expose_line (w
, row
, &r
))
25327 mouse_face_overwritten_p
= 1;
25330 if (!w
->pseudo_window_p
)
25332 /* Fix the display of overlapping rows. */
25333 if (first_overlapping_row
)
25334 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
,
25337 /* Draw border between windows. */
25338 x_draw_vertical_border (w
);
25340 /* Turn the cursor on again. */
25341 if (cursor_cleared_p
)
25342 update_window_cursor (w
, 1);
25346 return mouse_face_overwritten_p
;
25351 /* Redraw (parts) of all windows in the window tree rooted at W that
25352 intersect R. R contains frame pixel coordinates. Value is
25353 non-zero if the exposure overwrites mouse-face. */
25356 expose_window_tree (struct window
*w
, XRectangle
*r
)
25358 struct frame
*f
= XFRAME (w
->frame
);
25359 int mouse_face_overwritten_p
= 0;
25361 while (w
&& !FRAME_GARBAGED_P (f
))
25363 if (!NILP (w
->hchild
))
25364 mouse_face_overwritten_p
25365 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
25366 else if (!NILP (w
->vchild
))
25367 mouse_face_overwritten_p
25368 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
25370 mouse_face_overwritten_p
|= expose_window (w
, r
);
25372 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
25375 return mouse_face_overwritten_p
;
25380 Redisplay an exposed area of frame F. X and Y are the upper-left
25381 corner of the exposed rectangle. W and H are width and height of
25382 the exposed area. All are pixel values. W or H zero means redraw
25383 the entire frame. */
25386 expose_frame (struct frame
*f
, int x
, int y
, int w
, int h
)
25389 int mouse_face_overwritten_p
= 0;
25391 TRACE ((stderr
, "expose_frame "));
25393 /* No need to redraw if frame will be redrawn soon. */
25394 if (FRAME_GARBAGED_P (f
))
25396 TRACE ((stderr
, " garbaged\n"));
25400 /* If basic faces haven't been realized yet, there is no point in
25401 trying to redraw anything. This can happen when we get an expose
25402 event while Emacs is starting, e.g. by moving another window. */
25403 if (FRAME_FACE_CACHE (f
) == NULL
25404 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
25406 TRACE ((stderr
, " no faces\n"));
25410 if (w
== 0 || h
== 0)
25413 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
25414 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
25424 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
25425 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
25427 if (WINDOWP (f
->tool_bar_window
))
25428 mouse_face_overwritten_p
25429 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
25431 #ifdef HAVE_X_WINDOWS
25433 #ifndef USE_X_TOOLKIT
25434 if (WINDOWP (f
->menu_bar_window
))
25435 mouse_face_overwritten_p
25436 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
25437 #endif /* not USE_X_TOOLKIT */
25441 /* Some window managers support a focus-follows-mouse style with
25442 delayed raising of frames. Imagine a partially obscured frame,
25443 and moving the mouse into partially obscured mouse-face on that
25444 frame. The visible part of the mouse-face will be highlighted,
25445 then the WM raises the obscured frame. With at least one WM, KDE
25446 2.1, Emacs is not getting any event for the raising of the frame
25447 (even tried with SubstructureRedirectMask), only Expose events.
25448 These expose events will draw text normally, i.e. not
25449 highlighted. Which means we must redo the highlight here.
25450 Subsume it under ``we love X''. --gerd 2001-08-15 */
25451 /* Included in Windows version because Windows most likely does not
25452 do the right thing if any third party tool offers
25453 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
25454 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
25456 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
25457 if (f
== dpyinfo
->mouse_face_mouse_frame
)
25459 int x
= dpyinfo
->mouse_face_mouse_x
;
25460 int y
= dpyinfo
->mouse_face_mouse_y
;
25461 clear_mouse_face (dpyinfo
);
25462 note_mouse_highlight (f
, x
, y
);
25469 Determine the intersection of two rectangles R1 and R2. Return
25470 the intersection in *RESULT. Value is non-zero if RESULT is not
25474 x_intersect_rectangles (XRectangle
*r1
, XRectangle
*r2
, XRectangle
*result
)
25476 XRectangle
*left
, *right
;
25477 XRectangle
*upper
, *lower
;
25478 int intersection_p
= 0;
25480 /* Rearrange so that R1 is the left-most rectangle. */
25482 left
= r1
, right
= r2
;
25484 left
= r2
, right
= r1
;
25486 /* X0 of the intersection is right.x0, if this is inside R1,
25487 otherwise there is no intersection. */
25488 if (right
->x
<= left
->x
+ left
->width
)
25490 result
->x
= right
->x
;
25492 /* The right end of the intersection is the minimum of the
25493 the right ends of left and right. */
25494 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
25497 /* Same game for Y. */
25499 upper
= r1
, lower
= r2
;
25501 upper
= r2
, lower
= r1
;
25503 /* The upper end of the intersection is lower.y0, if this is inside
25504 of upper. Otherwise, there is no intersection. */
25505 if (lower
->y
<= upper
->y
+ upper
->height
)
25507 result
->y
= lower
->y
;
25509 /* The lower end of the intersection is the minimum of the lower
25510 ends of upper and lower. */
25511 result
->height
= (min (lower
->y
+ lower
->height
,
25512 upper
->y
+ upper
->height
)
25514 intersection_p
= 1;
25518 return intersection_p
;
25521 #endif /* HAVE_WINDOW_SYSTEM */
25524 /***********************************************************************
25526 ***********************************************************************/
25529 syms_of_xdisp (void)
25531 Vwith_echo_area_save_vector
= Qnil
;
25532 staticpro (&Vwith_echo_area_save_vector
);
25534 Vmessage_stack
= Qnil
;
25535 staticpro (&Vmessage_stack
);
25537 Qinhibit_redisplay
= intern_c_string ("inhibit-redisplay");
25538 staticpro (&Qinhibit_redisplay
);
25540 message_dolog_marker1
= Fmake_marker ();
25541 staticpro (&message_dolog_marker1
);
25542 message_dolog_marker2
= Fmake_marker ();
25543 staticpro (&message_dolog_marker2
);
25544 message_dolog_marker3
= Fmake_marker ();
25545 staticpro (&message_dolog_marker3
);
25548 defsubr (&Sdump_frame_glyph_matrix
);
25549 defsubr (&Sdump_glyph_matrix
);
25550 defsubr (&Sdump_glyph_row
);
25551 defsubr (&Sdump_tool_bar_row
);
25552 defsubr (&Strace_redisplay
);
25553 defsubr (&Strace_to_stderr
);
25555 #ifdef HAVE_WINDOW_SYSTEM
25556 defsubr (&Stool_bar_lines_needed
);
25557 defsubr (&Slookup_image_map
);
25559 defsubr (&Sformat_mode_line
);
25560 defsubr (&Sinvisible_p
);
25561 defsubr (&Scurrent_bidi_paragraph_direction
);
25563 staticpro (&Qmenu_bar_update_hook
);
25564 Qmenu_bar_update_hook
= intern_c_string ("menu-bar-update-hook");
25566 staticpro (&Qoverriding_terminal_local_map
);
25567 Qoverriding_terminal_local_map
= intern_c_string ("overriding-terminal-local-map");
25569 staticpro (&Qoverriding_local_map
);
25570 Qoverriding_local_map
= intern_c_string ("overriding-local-map");
25572 staticpro (&Qwindow_scroll_functions
);
25573 Qwindow_scroll_functions
= intern_c_string ("window-scroll-functions");
25575 staticpro (&Qwindow_text_change_functions
);
25576 Qwindow_text_change_functions
= intern_c_string ("window-text-change-functions");
25578 staticpro (&Qredisplay_end_trigger_functions
);
25579 Qredisplay_end_trigger_functions
= intern_c_string ("redisplay-end-trigger-functions");
25581 staticpro (&Qinhibit_point_motion_hooks
);
25582 Qinhibit_point_motion_hooks
= intern_c_string ("inhibit-point-motion-hooks");
25584 Qeval
= intern_c_string ("eval");
25585 staticpro (&Qeval
);
25587 QCdata
= intern_c_string (":data");
25588 staticpro (&QCdata
);
25589 Qdisplay
= intern_c_string ("display");
25590 staticpro (&Qdisplay
);
25591 Qspace_width
= intern_c_string ("space-width");
25592 staticpro (&Qspace_width
);
25593 Qraise
= intern_c_string ("raise");
25594 staticpro (&Qraise
);
25595 Qslice
= intern_c_string ("slice");
25596 staticpro (&Qslice
);
25597 Qspace
= intern_c_string ("space");
25598 staticpro (&Qspace
);
25599 Qmargin
= intern_c_string ("margin");
25600 staticpro (&Qmargin
);
25601 Qpointer
= intern_c_string ("pointer");
25602 staticpro (&Qpointer
);
25603 Qleft_margin
= intern_c_string ("left-margin");
25604 staticpro (&Qleft_margin
);
25605 Qright_margin
= intern_c_string ("right-margin");
25606 staticpro (&Qright_margin
);
25607 Qcenter
= intern_c_string ("center");
25608 staticpro (&Qcenter
);
25609 Qline_height
= intern_c_string ("line-height");
25610 staticpro (&Qline_height
);
25611 QCalign_to
= intern_c_string (":align-to");
25612 staticpro (&QCalign_to
);
25613 QCrelative_width
= intern_c_string (":relative-width");
25614 staticpro (&QCrelative_width
);
25615 QCrelative_height
= intern_c_string (":relative-height");
25616 staticpro (&QCrelative_height
);
25617 QCeval
= intern_c_string (":eval");
25618 staticpro (&QCeval
);
25619 QCpropertize
= intern_c_string (":propertize");
25620 staticpro (&QCpropertize
);
25621 QCfile
= intern_c_string (":file");
25622 staticpro (&QCfile
);
25623 Qfontified
= intern_c_string ("fontified");
25624 staticpro (&Qfontified
);
25625 Qfontification_functions
= intern_c_string ("fontification-functions");
25626 staticpro (&Qfontification_functions
);
25627 Qtrailing_whitespace
= intern_c_string ("trailing-whitespace");
25628 staticpro (&Qtrailing_whitespace
);
25629 Qescape_glyph
= intern_c_string ("escape-glyph");
25630 staticpro (&Qescape_glyph
);
25631 Qnobreak_space
= intern_c_string ("nobreak-space");
25632 staticpro (&Qnobreak_space
);
25633 Qimage
= intern_c_string ("image");
25634 staticpro (&Qimage
);
25635 Qtext
= intern_c_string ("text");
25636 staticpro (&Qtext
);
25637 Qboth
= intern_c_string ("both");
25638 staticpro (&Qboth
);
25639 Qboth_horiz
= intern_c_string ("both-horiz");
25640 staticpro (&Qboth_horiz
);
25641 QCmap
= intern_c_string (":map");
25642 staticpro (&QCmap
);
25643 QCpointer
= intern_c_string (":pointer");
25644 staticpro (&QCpointer
);
25645 Qrect
= intern_c_string ("rect");
25646 staticpro (&Qrect
);
25647 Qcircle
= intern_c_string ("circle");
25648 staticpro (&Qcircle
);
25649 Qpoly
= intern_c_string ("poly");
25650 staticpro (&Qpoly
);
25651 Qmessage_truncate_lines
= intern_c_string ("message-truncate-lines");
25652 staticpro (&Qmessage_truncate_lines
);
25653 Qgrow_only
= intern_c_string ("grow-only");
25654 staticpro (&Qgrow_only
);
25655 Qinhibit_menubar_update
= intern_c_string ("inhibit-menubar-update");
25656 staticpro (&Qinhibit_menubar_update
);
25657 Qinhibit_eval_during_redisplay
= intern_c_string ("inhibit-eval-during-redisplay");
25658 staticpro (&Qinhibit_eval_during_redisplay
);
25659 Qposition
= intern_c_string ("position");
25660 staticpro (&Qposition
);
25661 Qbuffer_position
= intern_c_string ("buffer-position");
25662 staticpro (&Qbuffer_position
);
25663 Qobject
= intern_c_string ("object");
25664 staticpro (&Qobject
);
25665 Qbar
= intern_c_string ("bar");
25667 Qhbar
= intern_c_string ("hbar");
25668 staticpro (&Qhbar
);
25669 Qbox
= intern_c_string ("box");
25671 Qhollow
= intern_c_string ("hollow");
25672 staticpro (&Qhollow
);
25673 Qhand
= intern_c_string ("hand");
25674 staticpro (&Qhand
);
25675 Qarrow
= intern_c_string ("arrow");
25676 staticpro (&Qarrow
);
25677 Qtext
= intern_c_string ("text");
25678 staticpro (&Qtext
);
25679 Qrisky_local_variable
= intern_c_string ("risky-local-variable");
25680 staticpro (&Qrisky_local_variable
);
25681 Qinhibit_free_realized_faces
= intern_c_string ("inhibit-free-realized-faces");
25682 staticpro (&Qinhibit_free_realized_faces
);
25684 list_of_error
= Fcons (Fcons (intern_c_string ("error"),
25685 Fcons (intern_c_string ("void-variable"), Qnil
)),
25687 staticpro (&list_of_error
);
25689 Qlast_arrow_position
= intern_c_string ("last-arrow-position");
25690 staticpro (&Qlast_arrow_position
);
25691 Qlast_arrow_string
= intern_c_string ("last-arrow-string");
25692 staticpro (&Qlast_arrow_string
);
25694 Qoverlay_arrow_string
= intern_c_string ("overlay-arrow-string");
25695 staticpro (&Qoverlay_arrow_string
);
25696 Qoverlay_arrow_bitmap
= intern_c_string ("overlay-arrow-bitmap");
25697 staticpro (&Qoverlay_arrow_bitmap
);
25699 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
25700 staticpro (&echo_buffer
[0]);
25701 staticpro (&echo_buffer
[1]);
25703 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
25704 staticpro (&echo_area_buffer
[0]);
25705 staticpro (&echo_area_buffer
[1]);
25707 Vmessages_buffer_name
= make_pure_c_string ("*Messages*");
25708 staticpro (&Vmessages_buffer_name
);
25710 mode_line_proptrans_alist
= Qnil
;
25711 staticpro (&mode_line_proptrans_alist
);
25712 mode_line_string_list
= Qnil
;
25713 staticpro (&mode_line_string_list
);
25714 mode_line_string_face
= Qnil
;
25715 staticpro (&mode_line_string_face
);
25716 mode_line_string_face_prop
= Qnil
;
25717 staticpro (&mode_line_string_face_prop
);
25718 Vmode_line_unwind_vector
= Qnil
;
25719 staticpro (&Vmode_line_unwind_vector
);
25721 help_echo_string
= Qnil
;
25722 staticpro (&help_echo_string
);
25723 help_echo_object
= Qnil
;
25724 staticpro (&help_echo_object
);
25725 help_echo_window
= Qnil
;
25726 staticpro (&help_echo_window
);
25727 previous_help_echo_string
= Qnil
;
25728 staticpro (&previous_help_echo_string
);
25729 help_echo_pos
= -1;
25731 Qright_to_left
= intern_c_string ("right-to-left");
25732 staticpro (&Qright_to_left
);
25733 Qleft_to_right
= intern_c_string ("left-to-right");
25734 staticpro (&Qleft_to_right
);
25736 #ifdef HAVE_WINDOW_SYSTEM
25737 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
25738 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
25739 For example, if a block cursor is over a tab, it will be drawn as
25740 wide as that tab on the display. */);
25741 x_stretch_cursor_p
= 0;
25744 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
25745 doc
: /* *Non-nil means highlight trailing whitespace.
25746 The face used for trailing whitespace is `trailing-whitespace'. */);
25747 Vshow_trailing_whitespace
= Qnil
;
25749 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display
,
25750 doc
: /* *Control highlighting of nobreak space and soft hyphen.
25751 A value of t means highlight the character itself (for nobreak space,
25752 use face `nobreak-space').
25753 A value of nil means no highlighting.
25754 Other values mean display the escape glyph followed by an ordinary
25755 space or ordinary hyphen. */);
25756 Vnobreak_char_display
= Qt
;
25758 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer
,
25759 doc
: /* *The pointer shape to show in void text areas.
25760 A value of nil means to show the text pointer. Other options are `arrow',
25761 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
25762 Vvoid_text_area_pointer
= Qarrow
;
25764 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
25765 doc
: /* Non-nil means don't actually do any redisplay.
25766 This is used for internal purposes. */);
25767 Vinhibit_redisplay
= Qnil
;
25769 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
25770 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
25771 Vglobal_mode_string
= Qnil
;
25773 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
25774 doc
: /* Marker for where to display an arrow on top of the buffer text.
25775 This must be the beginning of a line in order to work.
25776 See also `overlay-arrow-string'. */);
25777 Voverlay_arrow_position
= Qnil
;
25779 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
25780 doc
: /* String to display as an arrow in non-window frames.
25781 See also `overlay-arrow-position'. */);
25782 Voverlay_arrow_string
= make_pure_c_string ("=>");
25784 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list
,
25785 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
25786 The symbols on this list are examined during redisplay to determine
25787 where to display overlay arrows. */);
25788 Voverlay_arrow_variable_list
25789 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil
);
25791 DEFVAR_INT ("scroll-step", &scroll_step
,
25792 doc
: /* *The number of lines to try scrolling a window by when point moves out.
25793 If that fails to bring point back on frame, point is centered instead.
25794 If this is zero, point is always centered after it moves off frame.
25795 If you want scrolling to always be a line at a time, you should set
25796 `scroll-conservatively' to a large value rather than set this to 1. */);
25798 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
25799 doc
: /* *Scroll up to this many lines, to bring point back on screen.
25800 If point moves off-screen, redisplay will scroll by up to
25801 `scroll-conservatively' lines in order to bring point just barely
25802 onto the screen again. If that cannot be done, then redisplay
25803 recenters point as usual.
25805 A value of zero means always recenter point if it moves off screen. */);
25806 scroll_conservatively
= 0;
25808 DEFVAR_INT ("scroll-margin", &scroll_margin
,
25809 doc
: /* *Number of lines of margin at the top and bottom of a window.
25810 Recenter the window whenever point gets within this many lines
25811 of the top or bottom of the window. */);
25814 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch
,
25815 doc
: /* Pixels per inch value for non-window system displays.
25816 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
25817 Vdisplay_pixels_per_inch
= make_float (72.0);
25820 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, doc
: /* Don't ask. */);
25823 DEFVAR_LISP ("truncate-partial-width-windows",
25824 &Vtruncate_partial_width_windows
,
25825 doc
: /* Non-nil means truncate lines in windows narrower than the frame.
25826 For an integer value, truncate lines in each window narrower than the
25827 full frame width, provided the window width is less than that integer;
25828 otherwise, respect the value of `truncate-lines'.
25830 For any other non-nil value, truncate lines in all windows that do
25831 not span the full frame width.
25833 A value of nil means to respect the value of `truncate-lines'.
25835 If `word-wrap' is enabled, you might want to reduce this. */);
25836 Vtruncate_partial_width_windows
= make_number (50);
25838 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
25839 doc
: /* When nil, display the mode-line/header-line/menu-bar in the default face.
25840 Any other value means to use the appropriate face, `mode-line',
25841 `header-line', or `menu' respectively. */);
25842 mode_line_inverse_video
= 1;
25844 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
25845 doc
: /* *Maximum buffer size for which line number should be displayed.
25846 If the buffer is bigger than this, the line number does not appear
25847 in the mode line. A value of nil means no limit. */);
25848 Vline_number_display_limit
= Qnil
;
25850 DEFVAR_INT ("line-number-display-limit-width",
25851 &line_number_display_limit_width
,
25852 doc
: /* *Maximum line width (in characters) for line number display.
25853 If the average length of the lines near point is bigger than this, then the
25854 line number may be omitted from the mode line. */);
25855 line_number_display_limit_width
= 200;
25857 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
25858 doc
: /* *Non-nil means highlight region even in nonselected windows. */);
25859 highlight_nonselected_windows
= 0;
25861 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
25862 doc
: /* Non-nil if more than one frame is visible on this display.
25863 Minibuffer-only frames don't count, but iconified frames do.
25864 This variable is not guaranteed to be accurate except while processing
25865 `frame-title-format' and `icon-title-format'. */);
25867 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
25868 doc
: /* Template for displaying the title bar of visible frames.
25869 \(Assuming the window manager supports this feature.)
25871 This variable has the same structure as `mode-line-format', except that
25872 the %c and %l constructs are ignored. It is used only on frames for
25873 which no explicit name has been set \(see `modify-frame-parameters'). */);
25875 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
25876 doc
: /* Template for displaying the title bar of an iconified frame.
25877 \(Assuming the window manager supports this feature.)
25878 This variable has the same structure as `mode-line-format' (which see),
25879 and is used only on frames for which no explicit name has been set
25880 \(see `modify-frame-parameters'). */);
25882 = Vframe_title_format
25883 = pure_cons (intern_c_string ("multiple-frames"),
25884 pure_cons (make_pure_c_string ("%b"),
25885 pure_cons (pure_cons (empty_unibyte_string
,
25886 pure_cons (intern_c_string ("invocation-name"),
25887 pure_cons (make_pure_c_string ("@"),
25888 pure_cons (intern_c_string ("system-name"),
25892 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
25893 doc
: /* Maximum number of lines to keep in the message log buffer.
25894 If nil, disable message logging. If t, log messages but don't truncate
25895 the buffer when it becomes large. */);
25896 Vmessage_log_max
= make_number (100);
25898 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
25899 doc
: /* Functions called before redisplay, if window sizes have changed.
25900 The value should be a list of functions that take one argument.
25901 Just before redisplay, for each frame, if any of its windows have changed
25902 size since the last redisplay, or have been split or deleted,
25903 all the functions in the list are called, with the frame as argument. */);
25904 Vwindow_size_change_functions
= Qnil
;
25906 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
25907 doc
: /* List of functions to call before redisplaying a window with scrolling.
25908 Each function is called with two arguments, the window and its new
25909 display-start position. Note that these functions are also called by
25910 `set-window-buffer'. Also note that the value of `window-end' is not
25911 valid when these functions are called. */);
25912 Vwindow_scroll_functions
= Qnil
;
25914 DEFVAR_LISP ("window-text-change-functions",
25915 &Vwindow_text_change_functions
,
25916 doc
: /* Functions to call in redisplay when text in the window might change. */);
25917 Vwindow_text_change_functions
= Qnil
;
25919 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions
,
25920 doc
: /* Functions called when redisplay of a window reaches the end trigger.
25921 Each function is called with two arguments, the window and the end trigger value.
25922 See `set-window-redisplay-end-trigger'. */);
25923 Vredisplay_end_trigger_functions
= Qnil
;
25925 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window
,
25926 doc
: /* *Non-nil means autoselect window with mouse pointer.
25927 If nil, do not autoselect windows.
25928 A positive number means delay autoselection by that many seconds: a
25929 window is autoselected only after the mouse has remained in that
25930 window for the duration of the delay.
25931 A negative number has a similar effect, but causes windows to be
25932 autoselected only after the mouse has stopped moving. \(Because of
25933 the way Emacs compares mouse events, you will occasionally wait twice
25934 that time before the window gets selected.\)
25935 Any other value means to autoselect window instantaneously when the
25936 mouse pointer enters it.
25938 Autoselection selects the minibuffer only if it is active, and never
25939 unselects the minibuffer if it is active.
25941 When customizing this variable make sure that the actual value of
25942 `focus-follows-mouse' matches the behavior of your window manager. */);
25943 Vmouse_autoselect_window
= Qnil
;
25945 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars
,
25946 doc
: /* *Non-nil means automatically resize tool-bars.
25947 This dynamically changes the tool-bar's height to the minimum height
25948 that is needed to make all tool-bar items visible.
25949 If value is `grow-only', the tool-bar's height is only increased
25950 automatically; to decrease the tool-bar height, use \\[recenter]. */);
25951 Vauto_resize_tool_bars
= Qt
;
25953 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
25954 doc
: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
25955 auto_raise_tool_bar_buttons_p
= 1;
25957 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p
,
25958 doc
: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
25959 make_cursor_line_fully_visible_p
= 1;
25961 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border
,
25962 doc
: /* *Border below tool-bar in pixels.
25963 If an integer, use it as the height of the border.
25964 If it is one of `internal-border-width' or `border-width', use the
25965 value of the corresponding frame parameter.
25966 Otherwise, no border is added below the tool-bar. */);
25967 Vtool_bar_border
= Qinternal_border_width
;
25969 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin
,
25970 doc
: /* *Margin around tool-bar buttons in pixels.
25971 If an integer, use that for both horizontal and vertical margins.
25972 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
25973 HORZ specifying the horizontal margin, and VERT specifying the
25974 vertical margin. */);
25975 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
25977 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
25978 doc
: /* *Relief thickness of tool-bar buttons. */);
25979 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
25981 DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style
,
25982 doc
: /* *Tool bar style to use.
25984 image - show images only
25985 text - show text only
25986 both - show both, text under image
25987 both-horiz - show text to the right of the image
25988 any other - use system default or image if no system default. */);
25989 Vtool_bar_style
= Qnil
;
25991 DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size
,
25992 doc
: /* *Maximum number of characters a label can have to be shown.
25993 The tool bar style must also show labels for this to have any effect, see
25994 `tool-bar-style'. */);
25995 tool_bar_max_label_size
= DEFAULT_TOOL_BAR_LABEL_SIZE
;
25997 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
25998 doc
: /* List of functions to call to fontify regions of text.
25999 Each function is called with one argument POS. Functions must
26000 fontify a region starting at POS in the current buffer, and give
26001 fontified regions the property `fontified'. */);
26002 Vfontification_functions
= Qnil
;
26003 Fmake_variable_buffer_local (Qfontification_functions
);
26005 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26006 &unibyte_display_via_language_environment
,
26007 doc
: /* *Non-nil means display unibyte text according to language environment.
26008 Specifically, this means that raw bytes in the range 160-255 decimal
26009 are displayed by converting them to the equivalent multibyte characters
26010 according to the current language environment. As a result, they are
26011 displayed according to the current fontset.
26013 Note that this variable affects only how these bytes are displayed,
26014 but does not change the fact they are interpreted as raw bytes. */);
26015 unibyte_display_via_language_environment
= 0;
26017 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
26018 doc
: /* *Maximum height for resizing mini-windows.
26019 If a float, it specifies a fraction of the mini-window frame's height.
26020 If an integer, it specifies a number of lines. */);
26021 Vmax_mini_window_height
= make_float (0.25);
26023 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
26024 doc
: /* *How to resize mini-windows.
26025 A value of nil means don't automatically resize mini-windows.
26026 A value of t means resize them to fit the text displayed in them.
26027 A value of `grow-only', the default, means let mini-windows grow
26028 only, until their display becomes empty, at which point the windows
26029 go back to their normal size. */);
26030 Vresize_mini_windows
= Qgrow_only
;
26032 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist
,
26033 doc
: /* Alist specifying how to blink the cursor off.
26034 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26035 `cursor-type' frame-parameter or variable equals ON-STATE,
26036 comparing using `equal', Emacs uses OFF-STATE to specify
26037 how to blink it off. ON-STATE and OFF-STATE are values for
26038 the `cursor-type' frame parameter.
26040 If a frame's ON-STATE has no entry in this list,
26041 the frame's other specifications determine how to blink the cursor off. */);
26042 Vblink_cursor_alist
= Qnil
;
26044 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p
,
26045 doc
: /* *Non-nil means scroll the display automatically to make point visible. */);
26046 automatic_hscrolling_p
= 1;
26047 Qauto_hscroll_mode
= intern_c_string ("auto-hscroll-mode");
26048 staticpro (&Qauto_hscroll_mode
);
26050 DEFVAR_INT ("hscroll-margin", &hscroll_margin
,
26051 doc
: /* *How many columns away from the window edge point is allowed to get
26052 before automatic hscrolling will horizontally scroll the window. */);
26053 hscroll_margin
= 5;
26055 DEFVAR_LISP ("hscroll-step", &Vhscroll_step
,
26056 doc
: /* *How many columns to scroll the window when point gets too close to the edge.
26057 When point is less than `hscroll-margin' columns from the window
26058 edge, automatic hscrolling will scroll the window by the amount of columns
26059 determined by this variable. If its value is a positive integer, scroll that
26060 many columns. If it's a positive floating-point number, it specifies the
26061 fraction of the window's width to scroll. If it's nil or zero, point will be
26062 centered horizontally after the scroll. Any other value, including negative
26063 numbers, are treated as if the value were zero.
26065 Automatic hscrolling always moves point outside the scroll margin, so if
26066 point was more than scroll step columns inside the margin, the window will
26067 scroll more than the value given by the scroll step.
26069 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26070 and `scroll-right' overrides this variable's effect. */);
26071 Vhscroll_step
= make_number (0);
26073 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
26074 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
26075 Bind this around calls to `message' to let it take effect. */);
26076 message_truncate_lines
= 0;
26078 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
26079 doc
: /* Normal hook run to update the menu bar definitions.
26080 Redisplay runs this hook before it redisplays the menu bar.
26081 This is used to update submenus such as Buffers,
26082 whose contents depend on various data. */);
26083 Vmenu_bar_update_hook
= Qnil
;
26085 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame
,
26086 doc
: /* Frame for which we are updating a menu.
26087 The enable predicate for a menu binding should check this variable. */);
26088 Vmenu_updating_frame
= Qnil
;
26090 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update
,
26091 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
26092 inhibit_menubar_update
= 0;
26094 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix
,
26095 doc
: /* Prefix prepended to all continuation lines at display time.
26096 The value may be a string, an image, or a stretch-glyph; it is
26097 interpreted in the same way as the value of a `display' text property.
26099 This variable is overridden by any `wrap-prefix' text or overlay
26102 To add a prefix to non-continuation lines, use `line-prefix'. */);
26103 Vwrap_prefix
= Qnil
;
26104 staticpro (&Qwrap_prefix
);
26105 Qwrap_prefix
= intern_c_string ("wrap-prefix");
26106 Fmake_variable_buffer_local (Qwrap_prefix
);
26108 DEFVAR_LISP ("line-prefix", &Vline_prefix
,
26109 doc
: /* Prefix prepended to all non-continuation lines at display time.
26110 The value may be a string, an image, or a stretch-glyph; it is
26111 interpreted in the same way as the value of a `display' text property.
26113 This variable is overridden by any `line-prefix' text or overlay
26116 To add a prefix to continuation lines, use `wrap-prefix'. */);
26117 Vline_prefix
= Qnil
;
26118 staticpro (&Qline_prefix
);
26119 Qline_prefix
= intern_c_string ("line-prefix");
26120 Fmake_variable_buffer_local (Qline_prefix
);
26122 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay
,
26123 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
26124 inhibit_eval_during_redisplay
= 0;
26126 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces
,
26127 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
26128 inhibit_free_realized_faces
= 0;
26131 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id
,
26132 doc
: /* Inhibit try_window_id display optimization. */);
26133 inhibit_try_window_id
= 0;
26135 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing
,
26136 doc
: /* Inhibit try_window_reusing display optimization. */);
26137 inhibit_try_window_reusing
= 0;
26139 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement
,
26140 doc
: /* Inhibit try_cursor_movement display optimization. */);
26141 inhibit_try_cursor_movement
= 0;
26142 #endif /* GLYPH_DEBUG */
26144 DEFVAR_INT ("overline-margin", &overline_margin
,
26145 doc
: /* *Space between overline and text, in pixels.
26146 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
26147 margin to the caracter height. */);
26148 overline_margin
= 2;
26150 DEFVAR_INT ("underline-minimum-offset",
26151 &underline_minimum_offset
,
26152 doc
: /* Minimum distance between baseline and underline.
26153 This can improve legibility of underlined text at small font sizes,
26154 particularly when using variable `x-use-underline-position-properties'
26155 with fonts that specify an UNDERLINE_POSITION relatively close to the
26156 baseline. The default value is 1. */);
26157 underline_minimum_offset
= 1;
26159 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
26160 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
26161 display_hourglass_p
= 1;
26163 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
26164 doc
: /* *Seconds to wait before displaying an hourglass pointer.
26165 Value must be an integer or float. */);
26166 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
26168 hourglass_atimer
= NULL
;
26169 hourglass_shown_p
= 0;
26173 /* Initialize this module when Emacs starts. */
26178 Lisp_Object root_window
;
26179 struct window
*mini_w
;
26181 current_header_line_height
= current_mode_line_height
= -1;
26183 CHARPOS (this_line_start_pos
) = 0;
26185 mini_w
= XWINDOW (minibuf_window
);
26186 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
26188 if (!noninteractive
)
26190 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
26193 XWINDOW (root_window
)->top_line
= make_number (FRAME_TOP_MARGIN (f
));
26194 set_window_height (root_window
,
26195 FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
),
26197 mini_w
->top_line
= make_number (FRAME_LINES (f
) - 1);
26198 set_window_height (minibuf_window
, 1, 0);
26200 XWINDOW (root_window
)->total_cols
= make_number (FRAME_COLS (f
));
26201 mini_w
->total_cols
= make_number (FRAME_COLS (f
));
26203 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
26204 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
26205 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
26207 /* The default ellipsis glyphs `...'. */
26208 for (i
= 0; i
< 3; ++i
)
26209 default_invis_vector
[i
] = make_number ('.');
26213 /* Allocate the buffer for frame titles.
26214 Also used for `format-mode-line'. */
26216 mode_line_noprop_buf
= (char *) xmalloc (size
);
26217 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
26218 mode_line_noprop_ptr
= mode_line_noprop_buf
;
26219 mode_line_target
= MODE_LINE_DISPLAY
;
26222 help_echo_showing_p
= 0;
26225 /* Since w32 does not support atimers, it defines its own implementation of
26226 the following three functions in w32fns.c. */
26229 /* Platform-independent portion of hourglass implementation. */
26231 /* Return non-zero if houglass timer has been started or hourglass is shown. */
26233 hourglass_started (void)
26235 return hourglass_shown_p
|| hourglass_atimer
!= NULL
;
26238 /* Cancel a currently active hourglass timer, and start a new one. */
26240 start_hourglass (void)
26242 #if defined (HAVE_WINDOW_SYSTEM)
26244 int secs
, usecs
= 0;
26246 cancel_hourglass ();
26248 if (INTEGERP (Vhourglass_delay
)
26249 && XINT (Vhourglass_delay
) > 0)
26250 secs
= XFASTINT (Vhourglass_delay
);
26251 else if (FLOATP (Vhourglass_delay
)
26252 && XFLOAT_DATA (Vhourglass_delay
) > 0)
26255 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
26256 secs
= XFASTINT (tem
);
26257 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
26260 secs
= DEFAULT_HOURGLASS_DELAY
;
26262 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
26263 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
26264 show_hourglass
, NULL
);
26269 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
26272 cancel_hourglass (void)
26274 #if defined (HAVE_WINDOW_SYSTEM)
26275 if (hourglass_atimer
)
26277 cancel_atimer (hourglass_atimer
);
26278 hourglass_atimer
= NULL
;
26281 if (hourglass_shown_p
)
26285 #endif /* ! WINDOWSNT */
26287 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
26288 (do not change this comment) */