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 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
27 Emacs separates the task of updating the display from code
28 modifying global state, e.g. buffer text. This way functions
29 operating on buffers don't also have to be concerned with updating
32 Updating the display is triggered by the Lisp interpreter when it
33 decides it's time to do it. This is done either automatically for
34 you as part of the interpreter's command loop or as the result of
35 calling Lisp functions like `sit-for'. The C function `redisplay'
36 in xdisp.c is the only entry into the inner redisplay code. (Or,
37 let's say almost---see the description of direct update
40 The following diagram shows how redisplay code is invoked. As you
41 can see, Lisp calls redisplay and vice versa. Under window systems
42 like X, some portions of the redisplay code are also called
43 asynchronously during mouse movement or expose events. It is very
44 important that these code parts do NOT use the C library (malloc,
45 free) because many C libraries under Unix are not reentrant. They
46 may also NOT call functions of the Lisp interpreter which could
47 change the interpreter's state. If you don't follow these rules,
48 you will encounter bugs which are very hard to explain.
50 (Direct functions, see below)
51 direct_output_for_insert,
52 direct_forward_char (dispnew.c)
53 +---------------------------------+
56 +--------------+ redisplay +----------------+
57 | Lisp machine |---------------->| Redisplay code |<--+
58 +--------------+ (xdisp.c) +----------------+ |
60 +----------------------------------+ |
61 Don't use this path when called |
64 expose_window (asynchronous) |
66 X expose events -----+
68 What does redisplay do? Obviously, it has to figure out somehow what
69 has been changed since the last time the display has been updated,
70 and to make these changes visible. Preferably it would do that in
71 a moderately intelligent way, i.e. fast.
73 Changes in buffer text can be deduced from window and buffer
74 structures, and from some global variables like `beg_unchanged' and
75 `end_unchanged'. The contents of the display are additionally
76 recorded in a `glyph matrix', a two-dimensional matrix of glyph
77 structures. Each row in such a matrix corresponds to a line on the
78 display, and each glyph in a row corresponds to a column displaying
79 a character, an image, or what else. This matrix is called the
80 `current glyph matrix' or `current matrix' in redisplay
83 For buffer parts that have been changed since the last update, a
84 second glyph matrix is constructed, the so called `desired glyph
85 matrix' or short `desired matrix'. Current and desired matrix are
86 then compared to find a cheap way to update the display, e.g. by
87 reusing part of the display by scrolling lines.
92 You will find a lot of redisplay optimizations when you start
93 looking at the innards of redisplay. The overall goal of all these
94 optimizations is to make redisplay fast because it is done
97 Two optimizations are not found in xdisp.c. These are the direct
98 operations mentioned above. As the name suggests they follow a
99 different principle than the rest of redisplay. Instead of
100 building a desired matrix and then comparing it with the current
101 display, they perform their actions directly on the display and on
104 One direct operation updates the display after one character has
105 been entered. The other one moves the cursor by one position
106 forward or backward. You find these functions under the names
107 `direct_output_for_insert' and `direct_output_forward_char' in
113 Desired matrices are always built per Emacs window. The function
114 `display_line' is the central function to look at if you are
115 interested. It constructs one row in a desired matrix given an
116 iterator structure containing both a buffer position and a
117 description of the environment in which the text is to be
118 displayed. But this is too early, read on.
120 Characters and pixmaps displayed for a range of buffer text depend
121 on various settings of buffers and windows, on overlays and text
122 properties, on display tables, on selective display. The good news
123 is that all this hairy stuff is hidden behind a small set of
124 interface functions taking an iterator structure (struct it)
127 Iteration over things to be displayed is then simple. It is
128 started by initializing an iterator with a call to init_iterator.
129 Calls to get_next_display_element fill the iterator structure with
130 relevant information about the next thing to display. Calls to
131 set_iterator_to_next move the iterator to the next thing.
133 Besides this, an iterator also contains information about the
134 display environment in which glyphs for display elements are to be
135 produced. It has fields for the width and height of the display,
136 the information whether long lines are truncated or continued, a
137 current X and Y position, and lots of other stuff you can better
140 Glyphs in a desired matrix are normally constructed in a loop
141 calling get_next_display_element and then produce_glyphs. The call
142 to produce_glyphs will fill the iterator structure with pixel
143 information about the element being displayed and at the same time
144 produce glyphs for it. If the display element fits on the line
145 being displayed, set_iterator_to_next is called next, otherwise the
146 glyphs produced are discarded.
151 That just couldn't be all, could it? What about terminal types not
152 supporting operations on sub-windows of the screen? To update the
153 display on such a terminal, window-based glyph matrices are not
154 well suited. To be able to reuse part of the display (scrolling
155 lines up and down), we must instead have a view of the whole
156 screen. This is what `frame matrices' are for. They are a trick.
158 Frames on terminals like above have a glyph pool. Windows on such
159 a frame sub-allocate their glyph memory from their frame's glyph
160 pool. The frame itself is given its own glyph matrices. By
161 coincidence---or maybe something else---rows in window glyph
162 matrices are slices of corresponding rows in frame matrices. Thus
163 writing to window matrices implicitly updates a frame matrix which
164 provides us with the view of the whole screen that we originally
165 wanted to have without having to move many bytes around. To be
166 honest, there is a little bit more done, but not much more. If you
167 plan to extend that code, take a look at dispnew.c. The function
168 build_frame_matrix is a good starting point. */
174 #include "keyboard.h"
177 #include "termchar.h"
178 #include "dispextern.h"
182 #include "commands.h"
186 #include "termhooks.h"
187 #include "intervals.h"
190 #include "region-cache.h"
192 #include "blockinput.h"
194 #ifdef HAVE_X_WINDOWS
204 #ifndef FRAME_X_OUTPUT
205 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
208 #define INFINITY 10000000
210 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 extern void set_frame_menubar
P_ ((struct frame
*f
, int, int));
213 extern int pending_menu_activation
;
216 extern int interrupt_input
;
217 extern int command_loop_level
;
219 extern Lisp_Object do_mouse_tracking
;
221 extern int minibuffer_auto_raise
;
222 extern Lisp_Object Vminibuffer_list
;
224 extern Lisp_Object Qface
;
225 extern Lisp_Object Qmode_line
, Qmode_line_inactive
, Qheader_line
;
227 extern Lisp_Object Voverriding_local_map
;
228 extern Lisp_Object Voverriding_local_map_menu_flag
;
229 extern Lisp_Object Qmenu_item
;
230 extern Lisp_Object Qwhen
;
231 extern Lisp_Object Qhelp_echo
;
233 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
234 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
235 Lisp_Object Qredisplay_end_trigger_functions
, Vredisplay_end_trigger_functions
;
236 Lisp_Object Qinhibit_point_motion_hooks
;
237 Lisp_Object QCeval
, QCfile
, QCdata
, QCpropertize
;
238 Lisp_Object Qfontified
;
239 Lisp_Object Qgrow_only
;
240 Lisp_Object Qinhibit_eval_during_redisplay
;
241 Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
244 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
247 Lisp_Object Qarrow
, Qhand
, Qtext
;
249 Lisp_Object Qrisky_local_variable
;
251 /* Holds the list (error). */
252 Lisp_Object list_of_error
;
254 /* Functions called to fontify regions of text. */
256 Lisp_Object Vfontification_functions
;
257 Lisp_Object Qfontification_functions
;
259 /* Non-nil means automatically select any window when the mouse
260 cursor moves into it. */
261 Lisp_Object Vmouse_autoselect_window
;
263 /* Non-zero means draw tool bar buttons raised when the mouse moves
266 int auto_raise_tool_bar_buttons_p
;
268 /* Non-zero means to reposition window if cursor line is only partially visible. */
270 int make_cursor_line_fully_visible_p
;
272 /* Margin below tool bar in pixels. 0 or nil means no margin.
273 If value is `internal-border-width' or `border-width',
274 the corresponding frame parameter is used. */
276 Lisp_Object Vtool_bar_border
;
278 /* Margin around tool bar buttons in pixels. */
280 Lisp_Object Vtool_bar_button_margin
;
282 /* Thickness of shadow to draw around tool bar buttons. */
284 EMACS_INT tool_bar_button_relief
;
286 /* Non-zero means automatically resize tool-bars so that all tool-bar
287 items are visible, and no blank lines remain. */
289 int auto_resize_tool_bars_p
;
291 /* Non-zero means draw block and hollow cursor as wide as the glyph
292 under it. For example, if a block cursor is over a tab, it will be
293 drawn as wide as that tab on the display. */
295 int x_stretch_cursor_p
;
297 /* Non-nil means don't actually do any redisplay. */
299 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
301 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
303 int inhibit_eval_during_redisplay
;
305 /* Names of text properties relevant for redisplay. */
307 Lisp_Object Qdisplay
;
308 extern Lisp_Object Qface
, Qinvisible
, Qwidth
;
310 /* Symbols used in text property values. */
312 Lisp_Object Vdisplay_pixels_per_inch
;
313 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
314 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qraise
;
317 Lisp_Object Qmargin
, Qpointer
;
318 Lisp_Object Qline_height
;
319 extern Lisp_Object Qheight
;
320 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
321 extern Lisp_Object Qscroll_bar
;
322 extern Lisp_Object Qcursor
;
324 /* Non-nil means highlight trailing whitespace. */
326 Lisp_Object Vshow_trailing_whitespace
;
328 /* Non-nil means escape non-break space and hyphens. */
330 Lisp_Object Vnobreak_char_display
;
332 #ifdef HAVE_WINDOW_SYSTEM
333 extern Lisp_Object Voverflow_newline_into_fringe
;
335 /* Test if overflow newline into fringe. Called with iterator IT
336 at or past right window margin, and with IT->current_x set. */
338 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
339 (!NILP (Voverflow_newline_into_fringe) \
340 && FRAME_WINDOW_P (it->f) \
341 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
342 && it->current_x == it->last_visible_x)
344 #endif /* HAVE_WINDOW_SYSTEM */
346 /* Non-nil means show the text cursor in void text areas
347 i.e. in blank areas after eol and eob. This used to be
348 the default in 21.3. */
350 Lisp_Object Vvoid_text_area_pointer
;
352 /* Name of the face used to highlight trailing whitespace. */
354 Lisp_Object Qtrailing_whitespace
;
356 /* Name and number of the face used to highlight escape glyphs. */
358 Lisp_Object Qescape_glyph
;
360 /* Name and number of the face used to highlight non-breaking spaces. */
362 Lisp_Object Qnobreak_space
;
364 /* The symbol `image' which is the car of the lists used to represent
369 /* The image map types. */
370 Lisp_Object QCmap
, QCpointer
;
371 Lisp_Object Qrect
, Qcircle
, Qpoly
;
373 /* Non-zero means print newline to stdout before next mini-buffer
376 int noninteractive_need_newline
;
378 /* Non-zero means print newline to message log before next message. */
380 static int message_log_need_newline
;
382 /* Three markers that message_dolog uses.
383 It could allocate them itself, but that causes trouble
384 in handling memory-full errors. */
385 static Lisp_Object message_dolog_marker1
;
386 static Lisp_Object message_dolog_marker2
;
387 static Lisp_Object message_dolog_marker3
;
389 /* The buffer position of the first character appearing entirely or
390 partially on the line of the selected window which contains the
391 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
392 redisplay optimization in redisplay_internal. */
394 static struct text_pos this_line_start_pos
;
396 /* Number of characters past the end of the line above, including the
397 terminating newline. */
399 static struct text_pos this_line_end_pos
;
401 /* The vertical positions and the height of this line. */
403 static int this_line_vpos
;
404 static int this_line_y
;
405 static int this_line_pixel_height
;
407 /* X position at which this display line starts. Usually zero;
408 negative if first character is partially visible. */
410 static int this_line_start_x
;
412 /* Buffer that this_line_.* variables are referring to. */
414 static struct buffer
*this_line_buffer
;
416 /* Nonzero means truncate lines in all windows less wide than the
419 int truncate_partial_width_windows
;
421 /* A flag to control how to display unibyte 8-bit character. */
423 int unibyte_display_via_language_environment
;
425 /* Nonzero means we have more than one non-mini-buffer-only frame.
426 Not guaranteed to be accurate except while parsing
427 frame-title-format. */
431 Lisp_Object Vglobal_mode_string
;
434 /* List of variables (symbols) which hold markers for overlay arrows.
435 The symbols on this list are examined during redisplay to determine
436 where to display overlay arrows. */
438 Lisp_Object Voverlay_arrow_variable_list
;
440 /* Marker for where to display an arrow on top of the buffer text. */
442 Lisp_Object Voverlay_arrow_position
;
444 /* String to display for the arrow. Only used on terminal frames. */
446 Lisp_Object Voverlay_arrow_string
;
448 /* Values of those variables at last redisplay are stored as
449 properties on `overlay-arrow-position' symbol. However, if
450 Voverlay_arrow_position is a marker, last-arrow-position is its
451 numerical position. */
453 Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
455 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
456 properties on a symbol in overlay-arrow-variable-list. */
458 Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
460 /* Like mode-line-format, but for the title bar on a visible frame. */
462 Lisp_Object Vframe_title_format
;
464 /* Like mode-line-format, but for the title bar on an iconified frame. */
466 Lisp_Object Vicon_title_format
;
468 /* List of functions to call when a window's size changes. These
469 functions get one arg, a frame on which one or more windows' sizes
472 static Lisp_Object Vwindow_size_change_functions
;
474 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
476 /* Nonzero if an overlay arrow has been displayed in this window. */
478 static int overlay_arrow_seen
;
480 /* Nonzero means highlight the region even in nonselected windows. */
482 int highlight_nonselected_windows
;
484 /* If cursor motion alone moves point off frame, try scrolling this
485 many lines up or down if that will bring it back. */
487 static EMACS_INT scroll_step
;
489 /* Nonzero means scroll just far enough to bring point back on the
490 screen, when appropriate. */
492 static EMACS_INT scroll_conservatively
;
494 /* Recenter the window whenever point gets within this many lines of
495 the top or bottom of the window. This value is translated into a
496 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
497 that there is really a fixed pixel height scroll margin. */
499 EMACS_INT scroll_margin
;
501 /* Number of windows showing the buffer of the selected window (or
502 another buffer with the same base buffer). keyboard.c refers to
507 /* Vector containing glyphs for an ellipsis `...'. */
509 static Lisp_Object default_invis_vector
[3];
511 /* Zero means display the mode-line/header-line/menu-bar in the default face
512 (this slightly odd definition is for compatibility with previous versions
513 of emacs), non-zero means display them using their respective faces.
515 This variable is deprecated. */
517 int mode_line_inverse_video
;
519 /* Prompt to display in front of the mini-buffer contents. */
521 Lisp_Object minibuf_prompt
;
523 /* Width of current mini-buffer prompt. Only set after display_line
524 of the line that contains the prompt. */
526 int minibuf_prompt_width
;
528 /* This is the window where the echo area message was displayed. It
529 is always a mini-buffer window, but it may not be the same window
530 currently active as a mini-buffer. */
532 Lisp_Object echo_area_window
;
534 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
535 pushes the current message and the value of
536 message_enable_multibyte on the stack, the function restore_message
537 pops the stack and displays MESSAGE again. */
539 Lisp_Object Vmessage_stack
;
541 /* Nonzero means multibyte characters were enabled when the echo area
542 message was specified. */
544 int message_enable_multibyte
;
546 /* Nonzero if we should redraw the mode lines on the next redisplay. */
548 int update_mode_lines
;
550 /* Nonzero if window sizes or contents have changed since last
551 redisplay that finished. */
553 int windows_or_buffers_changed
;
555 /* Nonzero means a frame's cursor type has been changed. */
557 int cursor_type_changed
;
559 /* Nonzero after display_mode_line if %l was used and it displayed a
562 int line_number_displayed
;
564 /* Maximum buffer size for which to display line numbers. */
566 Lisp_Object Vline_number_display_limit
;
568 /* Line width to consider when repositioning for line number display. */
570 static EMACS_INT line_number_display_limit_width
;
572 /* Number of lines to keep in the message log buffer. t means
573 infinite. nil means don't log at all. */
575 Lisp_Object Vmessage_log_max
;
577 /* The name of the *Messages* buffer, a string. */
579 static Lisp_Object Vmessages_buffer_name
;
581 /* Index 0 is the buffer that holds the current (desired) echo area message,
582 or nil if none is desired right now.
584 Index 1 is the buffer that holds the previously displayed echo area message,
585 or nil to indicate no message. This is normally what's on the screen now.
587 These two can point to the same buffer. That happens when the last
588 message output by the user (or made by echoing) has been displayed. */
590 Lisp_Object echo_area_buffer
[2];
592 /* Permanent pointers to the two buffers that are used for echo area
593 purposes. Once the two buffers are made, and their pointers are
594 placed here, these two slots remain unchanged unless those buffers
595 need to be created afresh. */
597 static Lisp_Object echo_buffer
[2];
599 /* A vector saved used in with_area_buffer to reduce consing. */
601 static Lisp_Object Vwith_echo_area_save_vector
;
603 /* Non-zero means display_echo_area should display the last echo area
604 message again. Set by redisplay_preserve_echo_area. */
606 static int display_last_displayed_message_p
;
608 /* Nonzero if echo area is being used by print; zero if being used by
611 int message_buf_print
;
613 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
615 Lisp_Object Qinhibit_menubar_update
;
616 int inhibit_menubar_update
;
618 /* When evaluating expressions from menu bar items (enable conditions,
619 for instance), this is the frame they are being processed for. */
621 Lisp_Object Vmenu_updating_frame
;
623 /* Maximum height for resizing mini-windows. Either a float
624 specifying a fraction of the available height, or an integer
625 specifying a number of lines. */
627 Lisp_Object Vmax_mini_window_height
;
629 /* Non-zero means messages should be displayed with truncated
630 lines instead of being continued. */
632 int message_truncate_lines
;
633 Lisp_Object Qmessage_truncate_lines
;
635 /* Set to 1 in clear_message to make redisplay_internal aware
636 of an emptied echo area. */
638 static int message_cleared_p
;
640 /* How to blink the default frame cursor off. */
641 Lisp_Object Vblink_cursor_alist
;
643 /* A scratch glyph row with contents used for generating truncation
644 glyphs. Also used in direct_output_for_insert. */
646 #define MAX_SCRATCH_GLYPHS 100
647 struct glyph_row scratch_glyph_row
;
648 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
650 /* Ascent and height of the last line processed by move_it_to. */
652 static int last_max_ascent
, last_height
;
654 /* Non-zero if there's a help-echo in the echo area. */
656 int help_echo_showing_p
;
658 /* If >= 0, computed, exact values of mode-line and header-line height
659 to use in the macros CURRENT_MODE_LINE_HEIGHT and
660 CURRENT_HEADER_LINE_HEIGHT. */
662 int current_mode_line_height
, current_header_line_height
;
664 /* The maximum distance to look ahead for text properties. Values
665 that are too small let us call compute_char_face and similar
666 functions too often which is expensive. Values that are too large
667 let us call compute_char_face and alike too often because we
668 might not be interested in text properties that far away. */
670 #define TEXT_PROP_DISTANCE_LIMIT 100
674 /* Variables to turn off display optimizations from Lisp. */
676 int inhibit_try_window_id
, inhibit_try_window_reusing
;
677 int inhibit_try_cursor_movement
;
679 /* Non-zero means print traces of redisplay if compiled with
682 int trace_redisplay_p
;
684 #endif /* GLYPH_DEBUG */
686 #ifdef DEBUG_TRACE_MOVE
687 /* Non-zero means trace with TRACE_MOVE to stderr. */
690 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
692 #define TRACE_MOVE(x) (void) 0
695 /* Non-zero means automatically scroll windows horizontally to make
698 int automatic_hscrolling_p
;
700 /* How close to the margin can point get before the window is scrolled
702 EMACS_INT hscroll_margin
;
704 /* How much to scroll horizontally when point is inside the above margin. */
705 Lisp_Object Vhscroll_step
;
707 /* The variable `resize-mini-windows'. If nil, don't resize
708 mini-windows. If t, always resize them to fit the text they
709 display. If `grow-only', let mini-windows grow only until they
712 Lisp_Object Vresize_mini_windows
;
714 /* Buffer being redisplayed -- for redisplay_window_error. */
716 struct buffer
*displayed_buffer
;
718 /* Space between overline and text. */
720 EMACS_INT overline_margin
;
722 /* Value returned from text property handlers (see below). */
727 HANDLED_RECOMPUTE_PROPS
,
728 HANDLED_OVERLAY_STRING_CONSUMED
,
732 /* A description of text properties that redisplay is interested
737 /* The name of the property. */
740 /* A unique index for the property. */
743 /* A handler function called to set up iterator IT from the property
744 at IT's current position. Value is used to steer handle_stop. */
745 enum prop_handled (*handler
) P_ ((struct it
*it
));
748 static enum prop_handled handle_face_prop
P_ ((struct it
*));
749 static enum prop_handled handle_invisible_prop
P_ ((struct it
*));
750 static enum prop_handled handle_display_prop
P_ ((struct it
*));
751 static enum prop_handled handle_composition_prop
P_ ((struct it
*));
752 static enum prop_handled handle_overlay_change
P_ ((struct it
*));
753 static enum prop_handled handle_fontified_prop
P_ ((struct it
*));
755 /* Properties handled by iterators. */
757 static struct props it_props
[] =
759 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
760 /* Handle `face' before `display' because some sub-properties of
761 `display' need to know the face. */
762 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
763 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
764 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
765 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
769 /* Value is the position described by X. If X is a marker, value is
770 the marker_position of X. Otherwise, value is X. */
772 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
774 /* Enumeration returned by some move_it_.* functions internally. */
778 /* Not used. Undefined value. */
781 /* Move ended at the requested buffer position or ZV. */
782 MOVE_POS_MATCH_OR_ZV
,
784 /* Move ended at the requested X pixel position. */
787 /* Move within a line ended at the end of a line that must be
791 /* Move within a line ended at the end of a line that would
792 be displayed truncated. */
795 /* Move within a line ended at a line end. */
799 /* This counter is used to clear the face cache every once in a while
800 in redisplay_internal. It is incremented for each redisplay.
801 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
804 #define CLEAR_FACE_CACHE_COUNT 500
805 static int clear_face_cache_count
;
807 /* Similarly for the image cache. */
809 #ifdef HAVE_WINDOW_SYSTEM
810 #define CLEAR_IMAGE_CACHE_COUNT 101
811 static int clear_image_cache_count
;
814 /* Record the previous terminal frame we displayed. */
816 static struct frame
*previous_terminal_frame
;
818 /* Non-zero while redisplay_internal is in progress. */
822 /* Non-zero means don't free realized faces. Bound while freeing
823 realized faces is dangerous because glyph matrices might still
826 int inhibit_free_realized_faces
;
827 Lisp_Object Qinhibit_free_realized_faces
;
829 /* If a string, XTread_socket generates an event to display that string.
830 (The display is done in read_char.) */
832 Lisp_Object help_echo_string
;
833 Lisp_Object help_echo_window
;
834 Lisp_Object help_echo_object
;
837 /* Temporary variable for XTread_socket. */
839 Lisp_Object previous_help_echo_string
;
841 /* Null glyph slice */
843 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
846 /* Function prototypes. */
848 static void setup_for_ellipsis
P_ ((struct it
*, int));
849 static void mark_window_display_accurate_1
P_ ((struct window
*, int));
850 static int single_display_spec_string_p
P_ ((Lisp_Object
, Lisp_Object
));
851 static int display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
852 static int cursor_row_p
P_ ((struct window
*, struct glyph_row
*));
853 static int redisplay_mode_lines
P_ ((Lisp_Object
, int));
854 static char *decode_mode_spec_coding
P_ ((Lisp_Object
, char *, int));
857 static int invisible_text_between_p
P_ ((struct it
*, int, int));
860 static void pint2str
P_ ((char *, int, int));
861 static void pint2hrstr
P_ ((char *, int, int));
862 static struct text_pos run_window_scroll_functions
P_ ((Lisp_Object
,
864 static void reconsider_clip_changes
P_ ((struct window
*, struct buffer
*));
865 static int text_outside_line_unchanged_p
P_ ((struct window
*, int, int));
866 static void store_mode_line_noprop_char
P_ ((char));
867 static int store_mode_line_noprop
P_ ((const unsigned char *, int, int));
868 static void x_consider_frame_title
P_ ((Lisp_Object
));
869 static void handle_stop
P_ ((struct it
*));
870 static int tool_bar_lines_needed
P_ ((struct frame
*, int *));
871 static int single_display_spec_intangible_p
P_ ((Lisp_Object
));
872 static void ensure_echo_area_buffers
P_ ((void));
873 static Lisp_Object unwind_with_echo_area_buffer
P_ ((Lisp_Object
));
874 static Lisp_Object with_echo_area_buffer_unwind_data
P_ ((struct window
*));
875 static int with_echo_area_buffer
P_ ((struct window
*, int,
876 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
877 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
878 static void clear_garbaged_frames
P_ ((void));
879 static int current_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
880 static int truncate_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
881 static int set_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
882 static int display_echo_area
P_ ((struct window
*));
883 static int display_echo_area_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
884 static int resize_mini_window_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
885 static Lisp_Object unwind_redisplay
P_ ((Lisp_Object
));
886 static int string_char_and_length
P_ ((const unsigned char *, int, int *));
887 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
889 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
890 static Lisp_Object safe_eval_handler
P_ ((Lisp_Object
));
891 static void insert_left_trunc_glyphs
P_ ((struct it
*));
892 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*,
894 static void extend_face_to_end_of_line
P_ ((struct it
*));
895 static int append_space_for_newline
P_ ((struct it
*, int));
896 static int cursor_row_fully_visible_p
P_ ((struct window
*, int, int));
897 static int try_scrolling
P_ ((Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int));
898 static int try_cursor_movement
P_ ((Lisp_Object
, struct text_pos
, int *));
899 static int trailing_whitespace_p
P_ ((int));
900 static int message_log_check_duplicate
P_ ((int, int, int, int));
901 static void push_it
P_ ((struct it
*));
902 static void pop_it
P_ ((struct it
*));
903 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
904 static void select_frame_for_redisplay
P_ ((Lisp_Object
));
905 static void redisplay_internal
P_ ((int));
906 static int echo_area_display
P_ ((int));
907 static void redisplay_windows
P_ ((Lisp_Object
));
908 static void redisplay_window
P_ ((Lisp_Object
, int));
909 static Lisp_Object
redisplay_window_error ();
910 static Lisp_Object redisplay_window_0
P_ ((Lisp_Object
));
911 static Lisp_Object redisplay_window_1
P_ ((Lisp_Object
));
912 static int update_menu_bar
P_ ((struct frame
*, int, int));
913 static int try_window_reusing_current_matrix
P_ ((struct window
*));
914 static int try_window_id
P_ ((struct window
*));
915 static int display_line
P_ ((struct it
*));
916 static int display_mode_lines
P_ ((struct window
*));
917 static int display_mode_line
P_ ((struct window
*, enum face_id
, Lisp_Object
));
918 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int));
919 static int store_mode_line_string
P_ ((char *, Lisp_Object
, int, int, int, Lisp_Object
));
920 static char *decode_mode_spec
P_ ((struct window
*, int, int, int, int *));
921 static void display_menu_bar
P_ ((struct window
*));
922 static int display_count_lines
P_ ((int, int, int, int, int *));
923 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
924 int, int, struct it
*, int, int, int, int));
925 static void compute_line_metrics
P_ ((struct it
*));
926 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
927 static int get_overlay_strings
P_ ((struct it
*, int));
928 static int get_overlay_strings_1
P_ ((struct it
*, int, int));
929 static void next_overlay_string
P_ ((struct it
*));
930 static void reseat
P_ ((struct it
*, struct text_pos
, int));
931 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
932 static void back_to_previous_visible_line_start
P_ ((struct it
*));
933 void reseat_at_previous_visible_line_start
P_ ((struct it
*));
934 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
935 static int next_element_from_ellipsis
P_ ((struct it
*));
936 static int next_element_from_display_vector
P_ ((struct it
*));
937 static int next_element_from_string
P_ ((struct it
*));
938 static int next_element_from_c_string
P_ ((struct it
*));
939 static int next_element_from_buffer
P_ ((struct it
*));
940 static int next_element_from_composition
P_ ((struct it
*));
941 static int next_element_from_image
P_ ((struct it
*));
942 static int next_element_from_stretch
P_ ((struct it
*));
943 static void load_overlay_strings
P_ ((struct it
*, int));
944 static int init_from_display_pos
P_ ((struct it
*, struct window
*,
945 struct display_pos
*));
946 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
947 Lisp_Object
, int, int, int, int));
948 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
950 void move_it_vertically_backward
P_ ((struct it
*, int));
951 static void init_to_row_start
P_ ((struct it
*, struct window
*,
952 struct glyph_row
*));
953 static int init_to_row_end
P_ ((struct it
*, struct window
*,
954 struct glyph_row
*));
955 static void back_to_previous_line_start
P_ ((struct it
*));
956 static int forward_to_next_line_start
P_ ((struct it
*, int *));
957 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
959 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
960 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
961 static int number_of_chars
P_ ((unsigned char *, int));
962 static void compute_stop_pos
P_ ((struct it
*));
963 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
965 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
966 static int next_overlay_change
P_ ((int));
967 static int handle_single_display_spec
P_ ((struct it
*, Lisp_Object
,
968 Lisp_Object
, struct text_pos
*,
970 static int underlying_face_id
P_ ((struct it
*));
971 static int in_ellipses_for_invisible_text_p
P_ ((struct display_pos
*,
974 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
975 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
977 #ifdef HAVE_WINDOW_SYSTEM
979 static void update_tool_bar
P_ ((struct frame
*, int));
980 static void build_desired_tool_bar_string
P_ ((struct frame
*f
));
981 static int redisplay_tool_bar
P_ ((struct frame
*));
982 static void display_tool_bar_line
P_ ((struct it
*, int));
983 static void notice_overwritten_cursor
P_ ((struct window
*,
985 int, int, int, int));
989 #endif /* HAVE_WINDOW_SYSTEM */
992 /***********************************************************************
993 Window display dimensions
994 ***********************************************************************/
996 /* Return the bottom boundary y-position for text lines in window W.
997 This is the first y position at which a line cannot start.
998 It is relative to the top of the window.
1000 This is the height of W minus the height of a mode line, if any. */
1003 window_text_bottom_y (w
)
1006 int height
= WINDOW_TOTAL_HEIGHT (w
);
1008 if (WINDOW_WANTS_MODELINE_P (w
))
1009 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
1013 /* Return the pixel width of display area AREA of window W. AREA < 0
1014 means return the total width of W, not including fringes to
1015 the left and right of the window. */
1018 window_box_width (w
, area
)
1022 int cols
= XFASTINT (w
->total_cols
);
1025 if (!w
->pseudo_window_p
)
1027 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
1029 if (area
== TEXT_AREA
)
1031 if (INTEGERP (w
->left_margin_cols
))
1032 cols
-= XFASTINT (w
->left_margin_cols
);
1033 if (INTEGERP (w
->right_margin_cols
))
1034 cols
-= XFASTINT (w
->right_margin_cols
);
1035 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
1037 else if (area
== LEFT_MARGIN_AREA
)
1039 cols
= (INTEGERP (w
->left_margin_cols
)
1040 ? XFASTINT (w
->left_margin_cols
) : 0);
1043 else if (area
== RIGHT_MARGIN_AREA
)
1045 cols
= (INTEGERP (w
->right_margin_cols
)
1046 ? XFASTINT (w
->right_margin_cols
) : 0);
1051 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1055 /* Return the pixel height of the display area of window W, not
1056 including mode lines of W, if any. */
1059 window_box_height (w
)
1062 struct frame
*f
= XFRAME (w
->frame
);
1063 int height
= WINDOW_TOTAL_HEIGHT (w
);
1065 xassert (height
>= 0);
1067 /* Note: the code below that determines the mode-line/header-line
1068 height is essentially the same as that contained in the macro
1069 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1070 the appropriate glyph row has its `mode_line_p' flag set,
1071 and if it doesn't, uses estimate_mode_line_height instead. */
1073 if (WINDOW_WANTS_MODELINE_P (w
))
1075 struct glyph_row
*ml_row
1076 = (w
->current_matrix
&& w
->current_matrix
->rows
1077 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1079 if (ml_row
&& ml_row
->mode_line_p
)
1080 height
-= ml_row
->height
;
1082 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1085 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1087 struct glyph_row
*hl_row
1088 = (w
->current_matrix
&& w
->current_matrix
->rows
1089 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1091 if (hl_row
&& hl_row
->mode_line_p
)
1092 height
-= hl_row
->height
;
1094 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1097 /* With a very small font and a mode-line that's taller than
1098 default, we might end up with a negative height. */
1099 return max (0, height
);
1102 /* Return the window-relative coordinate of the left edge of display
1103 area AREA of window W. AREA < 0 means return the left edge of the
1104 whole window, to the right of the left fringe of W. */
1107 window_box_left_offset (w
, area
)
1113 if (w
->pseudo_window_p
)
1116 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1118 if (area
== TEXT_AREA
)
1119 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1120 + window_box_width (w
, LEFT_MARGIN_AREA
));
1121 else if (area
== RIGHT_MARGIN_AREA
)
1122 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1123 + window_box_width (w
, LEFT_MARGIN_AREA
)
1124 + window_box_width (w
, TEXT_AREA
)
1125 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1127 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1128 else if (area
== LEFT_MARGIN_AREA
1129 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1130 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1136 /* Return the window-relative coordinate of the right edge of display
1137 area AREA of window W. AREA < 0 means return the left edge of the
1138 whole window, to the left of the right fringe of W. */
1141 window_box_right_offset (w
, area
)
1145 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1148 /* Return the frame-relative coordinate of the left edge of display
1149 area AREA of window W. AREA < 0 means return the left edge of the
1150 whole window, to the right of the left fringe of W. */
1153 window_box_left (w
, area
)
1157 struct frame
*f
= XFRAME (w
->frame
);
1160 if (w
->pseudo_window_p
)
1161 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1163 x
= (WINDOW_LEFT_EDGE_X (w
)
1164 + window_box_left_offset (w
, area
));
1170 /* Return the frame-relative coordinate of the right edge of display
1171 area AREA of window W. AREA < 0 means return the left edge of the
1172 whole window, to the left of the right fringe of W. */
1175 window_box_right (w
, area
)
1179 return window_box_left (w
, area
) + window_box_width (w
, area
);
1182 /* Get the bounding box of the display area AREA of window W, without
1183 mode lines, in frame-relative coordinates. AREA < 0 means the
1184 whole window, not including the left and right fringes of
1185 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1186 coordinates of the upper-left corner of the box. Return in
1187 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1190 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
1193 int *box_x
, *box_y
, *box_width
, *box_height
;
1196 *box_width
= window_box_width (w
, area
);
1198 *box_height
= window_box_height (w
);
1200 *box_x
= window_box_left (w
, area
);
1203 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1204 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1205 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1210 /* Get the bounding box of the display area AREA of window W, without
1211 mode lines. AREA < 0 means the whole window, not including the
1212 left and right fringe of the window. Return in *TOP_LEFT_X
1213 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1214 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1215 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1219 window_box_edges (w
, area
, top_left_x
, top_left_y
,
1220 bottom_right_x
, bottom_right_y
)
1223 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
1225 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1227 *bottom_right_x
+= *top_left_x
;
1228 *bottom_right_y
+= *top_left_y
;
1233 /***********************************************************************
1235 ***********************************************************************/
1237 /* Return the bottom y-position of the line the iterator IT is in.
1238 This can modify IT's settings. */
1244 int line_height
= it
->max_ascent
+ it
->max_descent
;
1245 int line_top_y
= it
->current_y
;
1247 if (line_height
== 0)
1250 line_height
= last_height
;
1251 else if (IT_CHARPOS (*it
) < ZV
)
1253 move_it_by_lines (it
, 1, 1);
1254 line_height
= (it
->max_ascent
|| it
->max_descent
1255 ? it
->max_ascent
+ it
->max_descent
1260 struct glyph_row
*row
= it
->glyph_row
;
1262 /* Use the default character height. */
1263 it
->glyph_row
= NULL
;
1264 it
->what
= IT_CHARACTER
;
1267 PRODUCE_GLYPHS (it
);
1268 line_height
= it
->ascent
+ it
->descent
;
1269 it
->glyph_row
= row
;
1273 return line_top_y
+ line_height
;
1277 /* Return 1 if position CHARPOS is visible in window W.
1278 CHARPOS < 0 means return info about WINDOW_END position.
1279 If visible, set *X and *Y to pixel coordinates of top left corner.
1280 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1281 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1284 pos_visible_p (w
, charpos
, x
, y
, rtop
, rbot
, rowh
, vpos
)
1286 int charpos
, *x
, *y
, *rtop
, *rbot
, *rowh
, *vpos
;
1289 struct text_pos top
;
1291 struct buffer
*old_buffer
= NULL
;
1296 if (XBUFFER (w
->buffer
) != current_buffer
)
1298 old_buffer
= current_buffer
;
1299 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1302 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1304 /* Compute exact mode line heights. */
1305 if (WINDOW_WANTS_MODELINE_P (w
))
1306 current_mode_line_height
1307 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1308 current_buffer
->mode_line_format
);
1310 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1311 current_header_line_height
1312 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1313 current_buffer
->header_line_format
);
1315 start_display (&it
, w
, top
);
1316 move_it_to (&it
, charpos
, -1, it
.last_visible_y
-1, -1,
1317 (charpos
>= 0 ? MOVE_TO_POS
: 0) | MOVE_TO_Y
);
1319 /* Note that we may overshoot because of invisible text. */
1320 if (charpos
>= 0 && IT_CHARPOS (it
) >= charpos
)
1322 int top_x
= it
.current_x
;
1323 int top_y
= it
.current_y
;
1324 int bottom_y
= (last_height
= 0, line_bottom_y (&it
));
1325 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1327 if (top_y
< window_top_y
)
1328 visible_p
= bottom_y
> window_top_y
;
1329 else if (top_y
< it
.last_visible_y
)
1334 *y
= max (top_y
+ max (0, it
.max_ascent
- it
.ascent
), window_top_y
);
1335 *rtop
= max (0, window_top_y
- top_y
);
1336 *rbot
= max (0, bottom_y
- it
.last_visible_y
);
1337 *rowh
= max (0, (min (bottom_y
, it
.last_visible_y
)
1338 - max (top_y
, window_top_y
)));
1347 if (IT_CHARPOS (it
) < ZV
&& FETCH_BYTE (IT_BYTEPOS (it
)) != '\n')
1348 move_it_by_lines (&it
, 1, 0);
1349 if (charpos
< IT_CHARPOS (it
))
1352 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1354 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1355 *rtop
= max (0, -it2
.current_y
);
1356 *rbot
= max (0, ((it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
)
1357 - it
.last_visible_y
));
1358 *rowh
= max (0, (min (it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
,
1360 - max (it2
.current_y
,
1361 WINDOW_HEADER_LINE_HEIGHT (w
))));
1367 set_buffer_internal_1 (old_buffer
);
1369 current_header_line_height
= current_mode_line_height
= -1;
1371 if (visible_p
&& XFASTINT (w
->hscroll
) > 0)
1372 *x
-= XFASTINT (w
->hscroll
) * WINDOW_FRAME_COLUMN_WIDTH (w
);
1375 /* Debugging code. */
1377 fprintf (stderr
, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1378 charpos
, w
->vscroll
, *x
, *y
, *rtop
, *rbot
, *rowh
, *vpos
);
1380 fprintf (stderr
, "-pv pt=%d vs=%d\n", charpos
, w
->vscroll
);
1387 /* Return the next character from STR which is MAXLEN bytes long.
1388 Return in *LEN the length of the character. This is like
1389 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1390 we find one, we return a `?', but with the length of the invalid
1394 string_char_and_length (str
, maxlen
, len
)
1395 const unsigned char *str
;
1400 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
1401 if (!CHAR_VALID_P (c
, 1))
1402 /* We may not change the length here because other places in Emacs
1403 don't use this function, i.e. they silently accept invalid
1412 /* Given a position POS containing a valid character and byte position
1413 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1415 static struct text_pos
1416 string_pos_nchars_ahead (pos
, string
, nchars
)
1417 struct text_pos pos
;
1421 xassert (STRINGP (string
) && nchars
>= 0);
1423 if (STRING_MULTIBYTE (string
))
1425 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1426 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1431 string_char_and_length (p
, rest
, &len
);
1432 p
+= len
, rest
-= len
;
1433 xassert (rest
>= 0);
1435 BYTEPOS (pos
) += len
;
1439 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1445 /* Value is the text position, i.e. character and byte position,
1446 for character position CHARPOS in STRING. */
1448 static INLINE
struct text_pos
1449 string_pos (charpos
, string
)
1453 struct text_pos pos
;
1454 xassert (STRINGP (string
));
1455 xassert (charpos
>= 0);
1456 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1461 /* Value is a text position, i.e. character and byte position, for
1462 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1463 means recognize multibyte characters. */
1465 static struct text_pos
1466 c_string_pos (charpos
, s
, multibyte_p
)
1471 struct text_pos pos
;
1473 xassert (s
!= NULL
);
1474 xassert (charpos
>= 0);
1478 int rest
= strlen (s
), len
;
1480 SET_TEXT_POS (pos
, 0, 0);
1483 string_char_and_length (s
, rest
, &len
);
1484 s
+= len
, rest
-= len
;
1485 xassert (rest
>= 0);
1487 BYTEPOS (pos
) += len
;
1491 SET_TEXT_POS (pos
, charpos
, charpos
);
1497 /* Value is the number of characters in C string S. MULTIBYTE_P
1498 non-zero means recognize multibyte characters. */
1501 number_of_chars (s
, multibyte_p
)
1509 int rest
= strlen (s
), len
;
1510 unsigned char *p
= (unsigned char *) s
;
1512 for (nchars
= 0; rest
> 0; ++nchars
)
1514 string_char_and_length (p
, rest
, &len
);
1515 rest
-= len
, p
+= len
;
1519 nchars
= strlen (s
);
1525 /* Compute byte position NEWPOS->bytepos corresponding to
1526 NEWPOS->charpos. POS is a known position in string STRING.
1527 NEWPOS->charpos must be >= POS.charpos. */
1530 compute_string_pos (newpos
, pos
, string
)
1531 struct text_pos
*newpos
, pos
;
1534 xassert (STRINGP (string
));
1535 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1537 if (STRING_MULTIBYTE (string
))
1538 *newpos
= string_pos_nchars_ahead (pos
, string
,
1539 CHARPOS (*newpos
) - CHARPOS (pos
));
1541 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1545 Return an estimation of the pixel height of mode or top lines on
1546 frame F. FACE_ID specifies what line's height to estimate. */
1549 estimate_mode_line_height (f
, face_id
)
1551 enum face_id face_id
;
1553 #ifdef HAVE_WINDOW_SYSTEM
1554 if (FRAME_WINDOW_P (f
))
1556 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1558 /* This function is called so early when Emacs starts that the face
1559 cache and mode line face are not yet initialized. */
1560 if (FRAME_FACE_CACHE (f
))
1562 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1566 height
= FONT_HEIGHT (face
->font
);
1567 if (face
->box_line_width
> 0)
1568 height
+= 2 * face
->box_line_width
;
1579 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1580 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1581 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1582 not force the value into range. */
1585 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
1587 register int pix_x
, pix_y
;
1589 NativeRectangle
*bounds
;
1593 #ifdef HAVE_WINDOW_SYSTEM
1594 if (FRAME_WINDOW_P (f
))
1596 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1597 even for negative values. */
1599 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1601 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1603 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1604 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1607 STORE_NATIVE_RECT (*bounds
,
1608 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1609 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1610 FRAME_COLUMN_WIDTH (f
) - 1,
1611 FRAME_LINE_HEIGHT (f
) - 1);
1617 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1618 pix_x
= FRAME_TOTAL_COLS (f
);
1622 else if (pix_y
> FRAME_LINES (f
))
1623 pix_y
= FRAME_LINES (f
);
1633 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1634 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1635 can't tell the positions because W's display is not up to date,
1639 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
1642 int *frame_x
, *frame_y
;
1644 #ifdef HAVE_WINDOW_SYSTEM
1645 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1649 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1650 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1652 if (display_completed
)
1654 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1655 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1656 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1662 hpos
+= glyph
->pixel_width
;
1666 /* If first glyph is partially visible, its first visible position is still 0. */
1678 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1679 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1690 #ifdef HAVE_WINDOW_SYSTEM
1692 /* Find the glyph under window-relative coordinates X/Y in window W.
1693 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1694 strings. Return in *HPOS and *VPOS the row and column number of
1695 the glyph found. Return in *AREA the glyph area containing X.
1696 Value is a pointer to the glyph found or null if X/Y is not on
1697 text, or we can't tell because W's current matrix is not up to
1700 static struct glyph
*
1701 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, dx
, dy
, area
)
1704 int *hpos
, *vpos
, *dx
, *dy
, *area
;
1706 struct glyph
*glyph
, *end
;
1707 struct glyph_row
*row
= NULL
;
1710 /* Find row containing Y. Give up if some row is not enabled. */
1711 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1713 row
= MATRIX_ROW (w
->current_matrix
, i
);
1714 if (!row
->enabled_p
)
1716 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1723 /* Give up if Y is not in the window. */
1724 if (i
== w
->current_matrix
->nrows
)
1727 /* Get the glyph area containing X. */
1728 if (w
->pseudo_window_p
)
1735 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1737 *area
= LEFT_MARGIN_AREA
;
1738 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1740 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1743 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1747 *area
= RIGHT_MARGIN_AREA
;
1748 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1752 /* Find glyph containing X. */
1753 glyph
= row
->glyphs
[*area
];
1754 end
= glyph
+ row
->used
[*area
];
1756 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1758 x
-= glyph
->pixel_width
;
1768 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1771 *hpos
= glyph
- row
->glyphs
[*area
];
1777 Convert frame-relative x/y to coordinates relative to window W.
1778 Takes pseudo-windows into account. */
1781 frame_to_window_pixel_xy (w
, x
, y
)
1785 if (w
->pseudo_window_p
)
1787 /* A pseudo-window is always full-width, and starts at the
1788 left edge of the frame, plus a frame border. */
1789 struct frame
*f
= XFRAME (w
->frame
);
1790 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1791 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1795 *x
-= WINDOW_LEFT_EDGE_X (w
);
1796 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1801 Return in RECTS[] at most N clipping rectangles for glyph string S.
1802 Return the number of stored rectangles. */
1805 get_glyph_string_clip_rects (s
, rects
, n
)
1806 struct glyph_string
*s
;
1807 NativeRectangle
*rects
;
1815 if (s
->row
->full_width_p
)
1817 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1818 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1819 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1821 /* Unless displaying a mode or menu bar line, which are always
1822 fully visible, clip to the visible part of the row. */
1823 if (s
->w
->pseudo_window_p
)
1824 r
.height
= s
->row
->visible_height
;
1826 r
.height
= s
->height
;
1830 /* This is a text line that may be partially visible. */
1831 r
.x
= window_box_left (s
->w
, s
->area
);
1832 r
.width
= window_box_width (s
->w
, s
->area
);
1833 r
.height
= s
->row
->visible_height
;
1837 if (r
.x
< s
->clip_head
->x
)
1839 if (r
.width
>= s
->clip_head
->x
- r
.x
)
1840 r
.width
-= s
->clip_head
->x
- r
.x
;
1843 r
.x
= s
->clip_head
->x
;
1846 if (r
.x
+ r
.width
> s
->clip_tail
->x
+ s
->clip_tail
->background_width
)
1848 if (s
->clip_tail
->x
+ s
->clip_tail
->background_width
>= r
.x
)
1849 r
.width
= s
->clip_tail
->x
+ s
->clip_tail
->background_width
- r
.x
;
1854 /* If S draws overlapping rows, it's sufficient to use the top and
1855 bottom of the window for clipping because this glyph string
1856 intentionally draws over other lines. */
1857 if (s
->for_overlaps
)
1859 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1860 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1862 /* Alas, the above simple strategy does not work for the
1863 environments with anti-aliased text: if the same text is
1864 drawn onto the same place multiple times, it gets thicker.
1865 If the overlap we are processing is for the erased cursor, we
1866 take the intersection with the rectagle of the cursor. */
1867 if (s
->for_overlaps
& OVERLAPS_ERASED_CURSOR
)
1869 XRectangle rc
, r_save
= r
;
1871 rc
.x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (s
->w
, s
->w
->phys_cursor
.x
);
1872 rc
.y
= s
->w
->phys_cursor
.y
;
1873 rc
.width
= s
->w
->phys_cursor_width
;
1874 rc
.height
= s
->w
->phys_cursor_height
;
1876 x_intersect_rectangles (&r_save
, &rc
, &r
);
1881 /* Don't use S->y for clipping because it doesn't take partially
1882 visible lines into account. For example, it can be negative for
1883 partially visible lines at the top of a window. */
1884 if (!s
->row
->full_width_p
1885 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1886 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1888 r
.y
= max (0, s
->row
->y
);
1890 /* If drawing a tool-bar window, draw it over the internal border
1891 at the top of the window. */
1892 if (WINDOWP (s
->f
->tool_bar_window
)
1893 && s
->w
== XWINDOW (s
->f
->tool_bar_window
))
1894 r
.y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
1897 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1899 /* If drawing the cursor, don't let glyph draw outside its
1900 advertised boundaries. Cleartype does this under some circumstances. */
1901 if (s
->hl
== DRAW_CURSOR
)
1903 struct glyph
*glyph
= s
->first_glyph
;
1908 r
.width
-= s
->x
- r
.x
;
1911 r
.width
= min (r
.width
, glyph
->pixel_width
);
1913 /* If r.y is below window bottom, ensure that we still see a cursor. */
1914 height
= min (glyph
->ascent
+ glyph
->descent
,
1915 min (FRAME_LINE_HEIGHT (s
->f
), s
->row
->visible_height
));
1916 max_y
= window_text_bottom_y (s
->w
) - height
;
1917 max_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, max_y
);
1918 if (s
->ybase
- glyph
->ascent
> max_y
)
1925 /* Don't draw cursor glyph taller than our actual glyph. */
1926 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
1927 if (height
< r
.height
)
1929 max_y
= r
.y
+ r
.height
;
1930 r
.y
= min (max_y
, max (r
.y
, s
->ybase
+ glyph
->descent
- height
));
1931 r
.height
= min (max_y
- r
.y
, height
);
1936 if ((s
->for_overlaps
& OVERLAPS_BOTH
) == 0
1937 || ((s
->for_overlaps
& OVERLAPS_BOTH
) == OVERLAPS_BOTH
&& n
== 1))
1939 #ifdef CONVERT_FROM_XRECT
1940 CONVERT_FROM_XRECT (r
, *rects
);
1948 /* If we are processing overlapping and allowed to return
1949 multiple clipping rectangles, we exclude the row of the glyph
1950 string from the clipping rectangle. This is to avoid drawing
1951 the same text on the environment with anti-aliasing. */
1952 #ifdef CONVERT_FROM_XRECT
1955 XRectangle
*rs
= rects
;
1957 int i
= 0, row_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, s
->row
->y
);
1959 if (s
->for_overlaps
& OVERLAPS_PRED
)
1962 if (r
.y
+ r
.height
> row_y
)
1965 rs
[i
].height
= row_y
- r
.y
;
1971 if (s
->for_overlaps
& OVERLAPS_SUCC
)
1974 if (r
.y
< row_y
+ s
->row
->visible_height
)
1976 if (r
.y
+ r
.height
> row_y
+ s
->row
->visible_height
)
1978 rs
[i
].y
= row_y
+ s
->row
->visible_height
;
1979 rs
[i
].height
= r
.y
+ r
.height
- rs
[i
].y
;
1988 #ifdef CONVERT_FROM_XRECT
1989 for (i
= 0; i
< n
; i
++)
1990 CONVERT_FROM_XRECT (rs
[i
], rects
[i
]);
1997 Return in *NR the clipping rectangle for glyph string S. */
2000 get_glyph_string_clip_rect (s
, nr
)
2001 struct glyph_string
*s
;
2002 NativeRectangle
*nr
;
2004 get_glyph_string_clip_rects (s
, nr
, 1);
2009 Return the position and height of the phys cursor in window W.
2010 Set w->phys_cursor_width to width of phys cursor.
2014 get_phys_cursor_geometry (w
, row
, glyph
, xp
, yp
, heightp
)
2016 struct glyph_row
*row
;
2017 struct glyph
*glyph
;
2018 int *xp
, *yp
, *heightp
;
2020 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2021 int x
, y
, wd
, h
, h0
, y0
;
2023 /* Compute the width of the rectangle to draw. If on a stretch
2024 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2025 rectangle as wide as the glyph, but use a canonical character
2027 wd
= glyph
->pixel_width
- 1;
2032 x
= w
->phys_cursor
.x
;
2039 if (glyph
->type
== STRETCH_GLYPH
2040 && !x_stretch_cursor_p
)
2041 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
2042 w
->phys_cursor_width
= wd
;
2044 y
= w
->phys_cursor
.y
+ row
->ascent
- glyph
->ascent
;
2046 /* If y is below window bottom, ensure that we still see a cursor. */
2047 h0
= min (FRAME_LINE_HEIGHT (f
), row
->visible_height
);
2049 h
= max (h0
, glyph
->ascent
+ glyph
->descent
);
2050 h0
= min (h0
, glyph
->ascent
+ glyph
->descent
);
2052 y0
= WINDOW_HEADER_LINE_HEIGHT (w
);
2055 h
= max (h
- (y0
- y
) + 1, h0
);
2060 y0
= window_text_bottom_y (w
) - h0
;
2068 *xp
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, x
);
2069 *yp
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
);
2074 * Remember which glyph the mouse is over.
2078 remember_mouse_glyph (f
, gx
, gy
, rect
)
2081 NativeRectangle
*rect
;
2085 struct glyph_row
*r
, *gr
, *end_row
;
2086 enum window_part part
;
2087 enum glyph_row_area area
;
2088 int x
, y
, width
, height
;
2090 /* Try to determine frame pixel position and size of the glyph under
2091 frame pixel coordinates X/Y on frame F. */
2093 window
= window_from_coordinates (f
, gx
, gy
, &part
, &x
, &y
, 0);
2096 width
= FRAME_SMALLEST_CHAR_WIDTH (f
);
2097 height
= FRAME_SMALLEST_FONT_HEIGHT (f
);
2101 w
= XWINDOW (window
);
2102 width
= WINDOW_FRAME_COLUMN_WIDTH (w
);
2103 height
= WINDOW_FRAME_LINE_HEIGHT (w
);
2105 r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
2106 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
2108 if (w
->pseudo_window_p
)
2111 part
= ON_MODE_LINE
; /* Don't adjust margin. */
2117 case ON_LEFT_MARGIN
:
2118 area
= LEFT_MARGIN_AREA
;
2121 case ON_RIGHT_MARGIN
:
2122 area
= RIGHT_MARGIN_AREA
;
2125 case ON_HEADER_LINE
:
2127 gr
= (part
== ON_HEADER_LINE
2128 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
2129 : MATRIX_MODE_LINE_ROW (w
->current_matrix
));
2132 goto text_glyph_row_found
;
2139 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2140 if (r
->y
+ r
->height
> y
)
2146 text_glyph_row_found
:
2149 struct glyph
*g
= gr
->glyphs
[area
];
2150 struct glyph
*end
= g
+ gr
->used
[area
];
2152 height
= gr
->height
;
2153 for (gx
= gr
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
2154 if (gx
+ g
->pixel_width
> x
)
2159 if (g
->type
== IMAGE_GLYPH
)
2161 /* Don't remember when mouse is over image, as
2162 image may have hot-spots. */
2163 STORE_NATIVE_RECT (*rect
, 0, 0, 0, 0);
2166 width
= g
->pixel_width
;
2170 /* Use nominal char spacing at end of line. */
2172 gx
+= (x
/ width
) * width
;
2175 if (part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
)
2176 gx
+= window_box_left_offset (w
, area
);
2180 /* Use nominal line height at end of window. */
2181 gx
= (x
/ width
) * width
;
2183 gy
+= (y
/ height
) * height
;
2187 case ON_LEFT_FRINGE
:
2188 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2189 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
)
2190 : window_box_right_offset (w
, LEFT_MARGIN_AREA
));
2191 width
= WINDOW_LEFT_FRINGE_WIDTH (w
);
2194 case ON_RIGHT_FRINGE
:
2195 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2196 ? window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2197 : window_box_right_offset (w
, TEXT_AREA
));
2198 width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
2202 gx
= (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
2204 : (window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2205 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2206 ? WINDOW_RIGHT_FRINGE_WIDTH (w
)
2208 width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
2212 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2213 if (r
->y
+ r
->height
> y
)
2220 height
= gr
->height
;
2223 /* Use nominal line height at end of window. */
2225 gy
+= (y
/ height
) * height
;
2232 /* If there is no glyph under the mouse, then we divide the screen
2233 into a grid of the smallest glyph in the frame, and use that
2236 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2237 round down even for negative values. */
2243 gx
= (gx
/ width
) * width
;
2244 gy
= (gy
/ height
) * height
;
2249 gx
+= WINDOW_LEFT_EDGE_X (w
);
2250 gy
+= WINDOW_TOP_EDGE_Y (w
);
2253 STORE_NATIVE_RECT (*rect
, gx
, gy
, width
, height
);
2255 /* Visible feedback for debugging. */
2258 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2259 f
->output_data
.x
->normal_gc
,
2260 gx
, gy
, width
, height
);
2266 #endif /* HAVE_WINDOW_SYSTEM */
2269 /***********************************************************************
2270 Lisp form evaluation
2271 ***********************************************************************/
2273 /* Error handler for safe_eval and safe_call. */
2276 safe_eval_handler (arg
)
2279 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
2284 /* Evaluate SEXPR and return the result, or nil if something went
2285 wrong. Prevent redisplay during the evaluation. */
2293 if (inhibit_eval_during_redisplay
)
2297 int count
= SPECPDL_INDEX ();
2298 struct gcpro gcpro1
;
2301 specbind (Qinhibit_redisplay
, Qt
);
2302 /* Use Qt to ensure debugger does not run,
2303 so there is no possibility of wanting to redisplay. */
2304 val
= internal_condition_case_1 (Feval
, sexpr
, Qt
,
2307 val
= unbind_to (count
, val
);
2314 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2315 Return the result, or nil if something went wrong. Prevent
2316 redisplay during the evaluation. */
2319 safe_call (nargs
, args
)
2325 if (inhibit_eval_during_redisplay
)
2329 int count
= SPECPDL_INDEX ();
2330 struct gcpro gcpro1
;
2333 gcpro1
.nvars
= nargs
;
2334 specbind (Qinhibit_redisplay
, Qt
);
2335 /* Use Qt to ensure debugger does not run,
2336 so there is no possibility of wanting to redisplay. */
2337 val
= internal_condition_case_2 (Ffuncall
, nargs
, args
, Qt
,
2340 val
= unbind_to (count
, val
);
2347 /* Call function FN with one argument ARG.
2348 Return the result, or nil if something went wrong. */
2351 safe_call1 (fn
, arg
)
2352 Lisp_Object fn
, arg
;
2354 Lisp_Object args
[2];
2357 return safe_call (2, args
);
2362 /***********************************************************************
2364 ***********************************************************************/
2368 /* Define CHECK_IT to perform sanity checks on iterators.
2369 This is for debugging. It is too slow to do unconditionally. */
2375 if (it
->method
== GET_FROM_STRING
)
2377 xassert (STRINGP (it
->string
));
2378 xassert (IT_STRING_CHARPOS (*it
) >= 0);
2382 xassert (IT_STRING_CHARPOS (*it
) < 0);
2383 if (it
->method
== GET_FROM_BUFFER
)
2385 /* Check that character and byte positions agree. */
2386 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
2391 xassert (it
->current
.dpvec_index
>= 0);
2393 xassert (it
->current
.dpvec_index
< 0);
2396 #define CHECK_IT(IT) check_it ((IT))
2400 #define CHECK_IT(IT) (void) 0
2407 /* Check that the window end of window W is what we expect it
2408 to be---the last row in the current matrix displaying text. */
2411 check_window_end (w
)
2414 if (!MINI_WINDOW_P (w
)
2415 && !NILP (w
->window_end_valid
))
2417 struct glyph_row
*row
;
2418 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
2419 XFASTINT (w
->window_end_vpos
)),
2421 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
2422 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
2426 #define CHECK_WINDOW_END(W) check_window_end ((W))
2428 #else /* not GLYPH_DEBUG */
2430 #define CHECK_WINDOW_END(W) (void) 0
2432 #endif /* not GLYPH_DEBUG */
2436 /***********************************************************************
2437 Iterator initialization
2438 ***********************************************************************/
2440 /* Initialize IT for displaying current_buffer in window W, starting
2441 at character position CHARPOS. CHARPOS < 0 means that no buffer
2442 position is specified which is useful when the iterator is assigned
2443 a position later. BYTEPOS is the byte position corresponding to
2444 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2446 If ROW is not null, calls to produce_glyphs with IT as parameter
2447 will produce glyphs in that row.
2449 BASE_FACE_ID is the id of a base face to use. It must be one of
2450 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2451 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2452 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2454 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2455 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2456 will be initialized to use the corresponding mode line glyph row of
2457 the desired matrix of W. */
2460 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
2463 int charpos
, bytepos
;
2464 struct glyph_row
*row
;
2465 enum face_id base_face_id
;
2467 int highlight_region_p
;
2469 /* Some precondition checks. */
2470 xassert (w
!= NULL
&& it
!= NULL
);
2471 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2474 /* If face attributes have been changed since the last redisplay,
2475 free realized faces now because they depend on face definitions
2476 that might have changed. Don't free faces while there might be
2477 desired matrices pending which reference these faces. */
2478 if (face_change_count
&& !inhibit_free_realized_faces
)
2480 face_change_count
= 0;
2481 free_all_realized_faces (Qnil
);
2484 /* Use one of the mode line rows of W's desired matrix if
2488 if (base_face_id
== MODE_LINE_FACE_ID
2489 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2490 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2491 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2492 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2496 bzero (it
, sizeof *it
);
2497 it
->current
.overlay_string_index
= -1;
2498 it
->current
.dpvec_index
= -1;
2499 it
->base_face_id
= base_face_id
;
2501 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2503 /* The window in which we iterate over current_buffer: */
2504 XSETWINDOW (it
->window
, w
);
2506 it
->f
= XFRAME (w
->frame
);
2508 /* Extra space between lines (on window systems only). */
2509 if (base_face_id
== DEFAULT_FACE_ID
2510 && FRAME_WINDOW_P (it
->f
))
2512 if (NATNUMP (current_buffer
->extra_line_spacing
))
2513 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2514 else if (FLOATP (current_buffer
->extra_line_spacing
))
2515 it
->extra_line_spacing
= (XFLOAT_DATA (current_buffer
->extra_line_spacing
)
2516 * FRAME_LINE_HEIGHT (it
->f
));
2517 else if (it
->f
->extra_line_spacing
> 0)
2518 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2519 it
->max_extra_line_spacing
= 0;
2522 /* If realized faces have been removed, e.g. because of face
2523 attribute changes of named faces, recompute them. When running
2524 in batch mode, the face cache of Vterminal_frame is null. If
2525 we happen to get called, make a dummy face cache. */
2526 if (noninteractive
&& FRAME_FACE_CACHE (it
->f
) == NULL
)
2527 init_frame_faces (it
->f
);
2528 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2529 recompute_basic_faces (it
->f
);
2531 /* Current value of the `slice', `space-width', and 'height' properties. */
2532 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2533 it
->space_width
= Qnil
;
2534 it
->font_height
= Qnil
;
2535 it
->override_ascent
= -1;
2537 /* Are control characters displayed as `^C'? */
2538 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2540 /* -1 means everything between a CR and the following line end
2541 is invisible. >0 means lines indented more than this value are
2543 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2544 ? XFASTINT (current_buffer
->selective_display
)
2545 : (!NILP (current_buffer
->selective_display
)
2547 it
->selective_display_ellipsis_p
2548 = !NILP (current_buffer
->selective_display_ellipses
);
2550 /* Display table to use. */
2551 it
->dp
= window_display_table (w
);
2553 /* Are multibyte characters enabled in current_buffer? */
2554 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2556 /* Non-zero if we should highlight the region. */
2558 = (!NILP (Vtransient_mark_mode
)
2559 && !NILP (current_buffer
->mark_active
)
2560 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2562 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2563 start and end of a visible region in window IT->w. Set both to
2564 -1 to indicate no region. */
2565 if (highlight_region_p
2566 /* Maybe highlight only in selected window. */
2567 && (/* Either show region everywhere. */
2568 highlight_nonselected_windows
2569 /* Or show region in the selected window. */
2570 || w
== XWINDOW (selected_window
)
2571 /* Or show the region if we are in the mini-buffer and W is
2572 the window the mini-buffer refers to. */
2573 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2574 && WINDOWP (minibuf_selected_window
)
2575 && w
== XWINDOW (minibuf_selected_window
))))
2577 int charpos
= marker_position (current_buffer
->mark
);
2578 it
->region_beg_charpos
= min (PT
, charpos
);
2579 it
->region_end_charpos
= max (PT
, charpos
);
2582 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2584 /* Get the position at which the redisplay_end_trigger hook should
2585 be run, if it is to be run at all. */
2586 if (MARKERP (w
->redisplay_end_trigger
)
2587 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2588 it
->redisplay_end_trigger_charpos
2589 = marker_position (w
->redisplay_end_trigger
);
2590 else if (INTEGERP (w
->redisplay_end_trigger
))
2591 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2593 /* Correct bogus values of tab_width. */
2594 it
->tab_width
= XINT (current_buffer
->tab_width
);
2595 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2598 /* Are lines in the display truncated? */
2599 it
->truncate_lines_p
2600 = (base_face_id
!= DEFAULT_FACE_ID
2601 || XINT (it
->w
->hscroll
)
2602 || (truncate_partial_width_windows
2603 && !WINDOW_FULL_WIDTH_P (it
->w
))
2604 || !NILP (current_buffer
->truncate_lines
));
2606 /* Get dimensions of truncation and continuation glyphs. These are
2607 displayed as fringe bitmaps under X, so we don't need them for such
2609 if (!FRAME_WINDOW_P (it
->f
))
2611 if (it
->truncate_lines_p
)
2613 /* We will need the truncation glyph. */
2614 xassert (it
->glyph_row
== NULL
);
2615 produce_special_glyphs (it
, IT_TRUNCATION
);
2616 it
->truncation_pixel_width
= it
->pixel_width
;
2620 /* We will need the continuation glyph. */
2621 xassert (it
->glyph_row
== NULL
);
2622 produce_special_glyphs (it
, IT_CONTINUATION
);
2623 it
->continuation_pixel_width
= it
->pixel_width
;
2626 /* Reset these values to zero because the produce_special_glyphs
2627 above has changed them. */
2628 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2629 it
->phys_ascent
= it
->phys_descent
= 0;
2632 /* Set this after getting the dimensions of truncation and
2633 continuation glyphs, so that we don't produce glyphs when calling
2634 produce_special_glyphs, above. */
2635 it
->glyph_row
= row
;
2636 it
->area
= TEXT_AREA
;
2638 /* Get the dimensions of the display area. The display area
2639 consists of the visible window area plus a horizontally scrolled
2640 part to the left of the window. All x-values are relative to the
2641 start of this total display area. */
2642 if (base_face_id
!= DEFAULT_FACE_ID
)
2644 /* Mode lines, menu bar in terminal frames. */
2645 it
->first_visible_x
= 0;
2646 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2651 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2652 it
->last_visible_x
= (it
->first_visible_x
2653 + window_box_width (w
, TEXT_AREA
));
2655 /* If we truncate lines, leave room for the truncator glyph(s) at
2656 the right margin. Otherwise, leave room for the continuation
2657 glyph(s). Truncation and continuation glyphs are not inserted
2658 for window-based redisplay. */
2659 if (!FRAME_WINDOW_P (it
->f
))
2661 if (it
->truncate_lines_p
)
2662 it
->last_visible_x
-= it
->truncation_pixel_width
;
2664 it
->last_visible_x
-= it
->continuation_pixel_width
;
2667 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2668 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2671 /* Leave room for a border glyph. */
2672 if (!FRAME_WINDOW_P (it
->f
)
2673 && !WINDOW_RIGHTMOST_P (it
->w
))
2674 it
->last_visible_x
-= 1;
2676 it
->last_visible_y
= window_text_bottom_y (w
);
2678 /* For mode lines and alike, arrange for the first glyph having a
2679 left box line if the face specifies a box. */
2680 if (base_face_id
!= DEFAULT_FACE_ID
)
2684 it
->face_id
= base_face_id
;
2686 /* If we have a boxed mode line, make the first character appear
2687 with a left box line. */
2688 face
= FACE_FROM_ID (it
->f
, base_face_id
);
2689 if (face
->box
!= FACE_NO_BOX
)
2690 it
->start_of_box_run_p
= 1;
2693 /* If a buffer position was specified, set the iterator there,
2694 getting overlays and face properties from that position. */
2695 if (charpos
>= BUF_BEG (current_buffer
))
2697 it
->end_charpos
= ZV
;
2699 IT_CHARPOS (*it
) = charpos
;
2701 /* Compute byte position if not specified. */
2702 if (bytepos
< charpos
)
2703 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2705 IT_BYTEPOS (*it
) = bytepos
;
2707 it
->start
= it
->current
;
2709 /* Compute faces etc. */
2710 reseat (it
, it
->current
.pos
, 1);
2717 /* Initialize IT for the display of window W with window start POS. */
2720 start_display (it
, w
, pos
)
2723 struct text_pos pos
;
2725 struct glyph_row
*row
;
2726 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2728 row
= w
->desired_matrix
->rows
+ first_vpos
;
2729 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2730 it
->first_vpos
= first_vpos
;
2732 /* Don't reseat to previous visible line start if current start
2733 position is in a string or image. */
2734 if (it
->method
== GET_FROM_BUFFER
&& !it
->truncate_lines_p
)
2736 int start_at_line_beg_p
;
2737 int first_y
= it
->current_y
;
2739 /* If window start is not at a line start, skip forward to POS to
2740 get the correct continuation lines width. */
2741 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2742 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2743 if (!start_at_line_beg_p
)
2747 reseat_at_previous_visible_line_start (it
);
2748 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2750 new_x
= it
->current_x
+ it
->pixel_width
;
2752 /* If lines are continued, this line may end in the middle
2753 of a multi-glyph character (e.g. a control character
2754 displayed as \003, or in the middle of an overlay
2755 string). In this case move_it_to above will not have
2756 taken us to the start of the continuation line but to the
2757 end of the continued line. */
2758 if (it
->current_x
> 0
2759 && !it
->truncate_lines_p
/* Lines are continued. */
2760 && (/* And glyph doesn't fit on the line. */
2761 new_x
> it
->last_visible_x
2762 /* Or it fits exactly and we're on a window
2764 || (new_x
== it
->last_visible_x
2765 && FRAME_WINDOW_P (it
->f
))))
2767 if (it
->current
.dpvec_index
>= 0
2768 || it
->current
.overlay_string_index
>= 0)
2770 set_iterator_to_next (it
, 1);
2771 move_it_in_display_line_to (it
, -1, -1, 0);
2774 it
->continuation_lines_width
+= it
->current_x
;
2777 /* We're starting a new display line, not affected by the
2778 height of the continued line, so clear the appropriate
2779 fields in the iterator structure. */
2780 it
->max_ascent
= it
->max_descent
= 0;
2781 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2783 it
->current_y
= first_y
;
2785 it
->current_x
= it
->hpos
= 0;
2789 #if 0 /* Don't assert the following because start_display is sometimes
2790 called intentionally with a window start that is not at a
2791 line start. Please leave this code in as a comment. */
2793 /* Window start should be on a line start, now. */
2794 xassert (it
->continuation_lines_width
2795 || IT_CHARPOS (it
) == BEGV
2796 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
2801 /* Return 1 if POS is a position in ellipses displayed for invisible
2802 text. W is the window we display, for text property lookup. */
2805 in_ellipses_for_invisible_text_p (pos
, w
)
2806 struct display_pos
*pos
;
2809 Lisp_Object prop
, window
;
2811 int charpos
= CHARPOS (pos
->pos
);
2813 /* If POS specifies a position in a display vector, this might
2814 be for an ellipsis displayed for invisible text. We won't
2815 get the iterator set up for delivering that ellipsis unless
2816 we make sure that it gets aware of the invisible text. */
2817 if (pos
->dpvec_index
>= 0
2818 && pos
->overlay_string_index
< 0
2819 && CHARPOS (pos
->string_pos
) < 0
2821 && (XSETWINDOW (window
, w
),
2822 prop
= Fget_char_property (make_number (charpos
),
2823 Qinvisible
, window
),
2824 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2826 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2828 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2835 /* Initialize IT for stepping through current_buffer in window W,
2836 starting at position POS that includes overlay string and display
2837 vector/ control character translation position information. Value
2838 is zero if there are overlay strings with newlines at POS. */
2841 init_from_display_pos (it
, w
, pos
)
2844 struct display_pos
*pos
;
2846 int charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2847 int i
, overlay_strings_with_newlines
= 0;
2849 /* If POS specifies a position in a display vector, this might
2850 be for an ellipsis displayed for invisible text. We won't
2851 get the iterator set up for delivering that ellipsis unless
2852 we make sure that it gets aware of the invisible text. */
2853 if (in_ellipses_for_invisible_text_p (pos
, w
))
2859 /* Keep in mind: the call to reseat in init_iterator skips invisible
2860 text, so we might end up at a position different from POS. This
2861 is only a problem when POS is a row start after a newline and an
2862 overlay starts there with an after-string, and the overlay has an
2863 invisible property. Since we don't skip invisible text in
2864 display_line and elsewhere immediately after consuming the
2865 newline before the row start, such a POS will not be in a string,
2866 but the call to init_iterator below will move us to the
2868 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2870 /* This only scans the current chunk -- it should scan all chunks.
2871 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2872 to 16 in 22.1 to make this a lesser problem. */
2873 for (i
= 0; i
< it
->n_overlay_strings
&& i
< OVERLAY_STRING_CHUNK_SIZE
; ++i
)
2875 const char *s
= SDATA (it
->overlay_strings
[i
]);
2876 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2878 while (s
< e
&& *s
!= '\n')
2883 overlay_strings_with_newlines
= 1;
2888 /* If position is within an overlay string, set up IT to the right
2890 if (pos
->overlay_string_index
>= 0)
2894 /* If the first overlay string happens to have a `display'
2895 property for an image, the iterator will be set up for that
2896 image, and we have to undo that setup first before we can
2897 correct the overlay string index. */
2898 if (it
->method
== GET_FROM_IMAGE
)
2901 /* We already have the first chunk of overlay strings in
2902 IT->overlay_strings. Load more until the one for
2903 pos->overlay_string_index is in IT->overlay_strings. */
2904 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
2906 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
2907 it
->current
.overlay_string_index
= 0;
2910 load_overlay_strings (it
, 0);
2911 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
2915 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
2916 relative_index
= (it
->current
.overlay_string_index
2917 % OVERLAY_STRING_CHUNK_SIZE
);
2918 it
->string
= it
->overlay_strings
[relative_index
];
2919 xassert (STRINGP (it
->string
));
2920 it
->current
.string_pos
= pos
->string_pos
;
2921 it
->method
= GET_FROM_STRING
;
2924 #if 0 /* This is bogus because POS not having an overlay string
2925 position does not mean it's after the string. Example: A
2926 line starting with a before-string and initialization of IT
2927 to the previous row's end position. */
2928 else if (it
->current
.overlay_string_index
>= 0)
2930 /* If POS says we're already after an overlay string ending at
2931 POS, make sure to pop the iterator because it will be in
2932 front of that overlay string. When POS is ZV, we've thereby
2933 also ``processed'' overlay strings at ZV. */
2936 xassert (it
->current
.overlay_string_index
== -1);
2937 xassert (it
->method
== GET_FROM_BUFFER
);
2938 if (CHARPOS (pos
->pos
) == ZV
)
2939 it
->overlay_strings_at_end_processed_p
= 1;
2943 if (CHARPOS (pos
->string_pos
) >= 0)
2945 /* Recorded position is not in an overlay string, but in another
2946 string. This can only be a string from a `display' property.
2947 IT should already be filled with that string. */
2948 it
->current
.string_pos
= pos
->string_pos
;
2949 xassert (STRINGP (it
->string
));
2952 /* Restore position in display vector translations, control
2953 character translations or ellipses. */
2954 if (pos
->dpvec_index
>= 0)
2956 if (it
->dpvec
== NULL
)
2957 get_next_display_element (it
);
2958 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
2959 it
->current
.dpvec_index
= pos
->dpvec_index
;
2963 return !overlay_strings_with_newlines
;
2967 /* Initialize IT for stepping through current_buffer in window W
2968 starting at ROW->start. */
2971 init_to_row_start (it
, w
, row
)
2974 struct glyph_row
*row
;
2976 init_from_display_pos (it
, w
, &row
->start
);
2977 it
->start
= row
->start
;
2978 it
->continuation_lines_width
= row
->continuation_lines_width
;
2983 /* Initialize IT for stepping through current_buffer in window W
2984 starting in the line following ROW, i.e. starting at ROW->end.
2985 Value is zero if there are overlay strings with newlines at ROW's
2989 init_to_row_end (it
, w
, row
)
2992 struct glyph_row
*row
;
2996 if (init_from_display_pos (it
, w
, &row
->end
))
2998 if (row
->continued_p
)
2999 it
->continuation_lines_width
3000 = row
->continuation_lines_width
+ row
->pixel_width
;
3011 /***********************************************************************
3013 ***********************************************************************/
3015 /* Called when IT reaches IT->stop_charpos. Handle text property and
3016 overlay changes. Set IT->stop_charpos to the next position where
3023 enum prop_handled handled
;
3024 int handle_overlay_change_p
;
3028 it
->current
.dpvec_index
= -1;
3029 handle_overlay_change_p
= !it
->ignore_overlay_strings_at_pos_p
;
3030 it
->ignore_overlay_strings_at_pos_p
= 0;
3032 /* Use face of preceding text for ellipsis (if invisible) */
3033 if (it
->selective_display_ellipsis_p
)
3034 it
->saved_face_id
= it
->face_id
;
3038 handled
= HANDLED_NORMALLY
;
3040 /* Call text property handlers. */
3041 for (p
= it_props
; p
->handler
; ++p
)
3043 handled
= p
->handler (it
);
3045 if (handled
== HANDLED_RECOMPUTE_PROPS
)
3047 else if (handled
== HANDLED_RETURN
)
3049 /* We still want to show before and after strings from
3050 overlays even if the actual buffer text is replaced. */
3051 if (!handle_overlay_change_p
|| it
->sp
> 1)
3053 if (!get_overlay_strings_1 (it
, 0, 0))
3055 it
->ignore_overlay_strings_at_pos_p
= 1;
3056 it
->string_from_display_prop_p
= 0;
3057 handle_overlay_change_p
= 0;
3058 handled
= HANDLED_RECOMPUTE_PROPS
;
3061 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
3062 handle_overlay_change_p
= 0;
3065 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
3067 /* Don't check for overlay strings below when set to deliver
3068 characters from a display vector. */
3069 if (it
->method
== GET_FROM_DISPLAY_VECTOR
)
3070 handle_overlay_change_p
= 0;
3072 /* Handle overlay changes. */
3073 if (handle_overlay_change_p
)
3074 handled
= handle_overlay_change (it
);
3076 /* Determine where to stop next. */
3077 if (handled
== HANDLED_NORMALLY
)
3078 compute_stop_pos (it
);
3081 while (handled
== HANDLED_RECOMPUTE_PROPS
);
3085 /* Compute IT->stop_charpos from text property and overlay change
3086 information for IT's current position. */
3089 compute_stop_pos (it
)
3092 register INTERVAL iv
, next_iv
;
3093 Lisp_Object object
, limit
, position
;
3095 /* If nowhere else, stop at the end. */
3096 it
->stop_charpos
= it
->end_charpos
;
3098 if (STRINGP (it
->string
))
3100 /* Strings are usually short, so don't limit the search for
3102 object
= it
->string
;
3104 position
= make_number (IT_STRING_CHARPOS (*it
));
3110 /* If next overlay change is in front of the current stop pos
3111 (which is IT->end_charpos), stop there. Note: value of
3112 next_overlay_change is point-max if no overlay change
3114 charpos
= next_overlay_change (IT_CHARPOS (*it
));
3115 if (charpos
< it
->stop_charpos
)
3116 it
->stop_charpos
= charpos
;
3118 /* If showing the region, we have to stop at the region
3119 start or end because the face might change there. */
3120 if (it
->region_beg_charpos
> 0)
3122 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
3123 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
3124 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
3125 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
3128 /* Set up variables for computing the stop position from text
3129 property changes. */
3130 XSETBUFFER (object
, current_buffer
);
3131 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
3132 position
= make_number (IT_CHARPOS (*it
));
3136 /* Get the interval containing IT's position. Value is a null
3137 interval if there isn't such an interval. */
3138 iv
= validate_interval_range (object
, &position
, &position
, 0);
3139 if (!NULL_INTERVAL_P (iv
))
3141 Lisp_Object values_here
[LAST_PROP_IDX
];
3144 /* Get properties here. */
3145 for (p
= it_props
; p
->handler
; ++p
)
3146 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
3148 /* Look for an interval following iv that has different
3150 for (next_iv
= next_interval (iv
);
3151 (!NULL_INTERVAL_P (next_iv
)
3153 || XFASTINT (limit
) > next_iv
->position
));
3154 next_iv
= next_interval (next_iv
))
3156 for (p
= it_props
; p
->handler
; ++p
)
3158 Lisp_Object new_value
;
3160 new_value
= textget (next_iv
->plist
, *p
->name
);
3161 if (!EQ (values_here
[p
->idx
], new_value
))
3169 if (!NULL_INTERVAL_P (next_iv
))
3171 if (INTEGERP (limit
)
3172 && next_iv
->position
>= XFASTINT (limit
))
3173 /* No text property change up to limit. */
3174 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
3176 /* Text properties change in next_iv. */
3177 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
3181 xassert (STRINGP (it
->string
)
3182 || (it
->stop_charpos
>= BEGV
3183 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
3187 /* Return the position of the next overlay change after POS in
3188 current_buffer. Value is point-max if no overlay change
3189 follows. This is like `next-overlay-change' but doesn't use
3193 next_overlay_change (pos
)
3198 Lisp_Object
*overlays
;
3201 /* Get all overlays at the given position. */
3202 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
3204 /* If any of these overlays ends before endpos,
3205 use its ending point instead. */
3206 for (i
= 0; i
< noverlays
; ++i
)
3211 oend
= OVERLAY_END (overlays
[i
]);
3212 oendpos
= OVERLAY_POSITION (oend
);
3213 endpos
= min (endpos
, oendpos
);
3221 /***********************************************************************
3223 ***********************************************************************/
3225 /* Handle changes in the `fontified' property of the current buffer by
3226 calling hook functions from Qfontification_functions to fontify
3229 static enum prop_handled
3230 handle_fontified_prop (it
)
3233 Lisp_Object prop
, pos
;
3234 enum prop_handled handled
= HANDLED_NORMALLY
;
3236 if (!NILP (Vmemory_full
))
3239 /* Get the value of the `fontified' property at IT's current buffer
3240 position. (The `fontified' property doesn't have a special
3241 meaning in strings.) If the value is nil, call functions from
3242 Qfontification_functions. */
3243 if (!STRINGP (it
->string
)
3245 && !NILP (Vfontification_functions
)
3246 && !NILP (Vrun_hooks
)
3247 && (pos
= make_number (IT_CHARPOS (*it
)),
3248 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
3251 int count
= SPECPDL_INDEX ();
3254 val
= Vfontification_functions
;
3255 specbind (Qfontification_functions
, Qnil
);
3257 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
3258 safe_call1 (val
, pos
);
3261 Lisp_Object globals
, fn
;
3262 struct gcpro gcpro1
, gcpro2
;
3265 GCPRO2 (val
, globals
);
3267 for (; CONSP (val
); val
= XCDR (val
))
3273 /* A value of t indicates this hook has a local
3274 binding; it means to run the global binding too.
3275 In a global value, t should not occur. If it
3276 does, we must ignore it to avoid an endless
3278 for (globals
= Fdefault_value (Qfontification_functions
);
3280 globals
= XCDR (globals
))
3282 fn
= XCAR (globals
);
3284 safe_call1 (fn
, pos
);
3288 safe_call1 (fn
, pos
);
3294 unbind_to (count
, Qnil
);
3296 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3297 something. This avoids an endless loop if they failed to
3298 fontify the text for which reason ever. */
3299 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
3300 handled
= HANDLED_RECOMPUTE_PROPS
;
3308 /***********************************************************************
3310 ***********************************************************************/
3312 /* Set up iterator IT from face properties at its current position.
3313 Called from handle_stop. */
3315 static enum prop_handled
3316 handle_face_prop (it
)
3319 int new_face_id
, next_stop
;
3321 if (!STRINGP (it
->string
))
3324 = face_at_buffer_position (it
->w
,
3326 it
->region_beg_charpos
,
3327 it
->region_end_charpos
,
3330 + TEXT_PROP_DISTANCE_LIMIT
),
3333 /* Is this a start of a run of characters with box face?
3334 Caveat: this can be called for a freshly initialized
3335 iterator; face_id is -1 in this case. We know that the new
3336 face will not change until limit, i.e. if the new face has a
3337 box, all characters up to limit will have one. But, as
3338 usual, we don't know whether limit is really the end. */
3339 if (new_face_id
!= it
->face_id
)
3341 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3343 /* If new face has a box but old face has not, this is
3344 the start of a run of characters with box, i.e. it has
3345 a shadow on the left side. The value of face_id of the
3346 iterator will be -1 if this is the initial call that gets
3347 the face. In this case, we have to look in front of IT's
3348 position and see whether there is a face != new_face_id. */
3349 it
->start_of_box_run_p
3350 = (new_face
->box
!= FACE_NO_BOX
3351 && (it
->face_id
>= 0
3352 || IT_CHARPOS (*it
) == BEG
3353 || new_face_id
!= face_before_it_pos (it
)));
3354 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3359 int base_face_id
, bufpos
;
3361 if (it
->current
.overlay_string_index
>= 0)
3362 bufpos
= IT_CHARPOS (*it
);
3366 /* For strings from a buffer, i.e. overlay strings or strings
3367 from a `display' property, use the face at IT's current
3368 buffer position as the base face to merge with, so that
3369 overlay strings appear in the same face as surrounding
3370 text, unless they specify their own faces. */
3371 base_face_id
= underlying_face_id (it
);
3373 new_face_id
= face_at_string_position (it
->w
,
3375 IT_STRING_CHARPOS (*it
),
3377 it
->region_beg_charpos
,
3378 it
->region_end_charpos
,
3382 #if 0 /* This shouldn't be neccessary. Let's check it. */
3383 /* If IT is used to display a mode line we would really like to
3384 use the mode line face instead of the frame's default face. */
3385 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
3386 && new_face_id
== DEFAULT_FACE_ID
)
3387 new_face_id
= CURRENT_MODE_LINE_FACE_ID (it
->w
);
3390 /* Is this a start of a run of characters with box? Caveat:
3391 this can be called for a freshly allocated iterator; face_id
3392 is -1 is this case. We know that the new face will not
3393 change until the next check pos, i.e. if the new face has a
3394 box, all characters up to that position will have a
3395 box. But, as usual, we don't know whether that position
3396 is really the end. */
3397 if (new_face_id
!= it
->face_id
)
3399 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3400 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3402 /* If new face has a box but old face hasn't, this is the
3403 start of a run of characters with box, i.e. it has a
3404 shadow on the left side. */
3405 it
->start_of_box_run_p
3406 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
3407 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3411 it
->face_id
= new_face_id
;
3412 return HANDLED_NORMALLY
;
3416 /* Return the ID of the face ``underlying'' IT's current position,
3417 which is in a string. If the iterator is associated with a
3418 buffer, return the face at IT's current buffer position.
3419 Otherwise, use the iterator's base_face_id. */
3422 underlying_face_id (it
)
3425 int face_id
= it
->base_face_id
, i
;
3427 xassert (STRINGP (it
->string
));
3429 for (i
= it
->sp
- 1; i
>= 0; --i
)
3430 if (NILP (it
->stack
[i
].string
))
3431 face_id
= it
->stack
[i
].face_id
;
3437 /* Compute the face one character before or after the current position
3438 of IT. BEFORE_P non-zero means get the face in front of IT's
3439 position. Value is the id of the face. */
3442 face_before_or_after_it_pos (it
, before_p
)
3447 int next_check_charpos
;
3448 struct text_pos pos
;
3450 xassert (it
->s
== NULL
);
3452 if (STRINGP (it
->string
))
3454 int bufpos
, base_face_id
;
3456 /* No face change past the end of the string (for the case
3457 we are padding with spaces). No face change before the
3459 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
3460 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
3463 /* Set pos to the position before or after IT's current position. */
3465 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
3467 /* For composition, we must check the character after the
3469 pos
= (it
->what
== IT_COMPOSITION
3470 ? string_pos (IT_STRING_CHARPOS (*it
) + it
->cmp_len
, it
->string
)
3471 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
3473 if (it
->current
.overlay_string_index
>= 0)
3474 bufpos
= IT_CHARPOS (*it
);
3478 base_face_id
= underlying_face_id (it
);
3480 /* Get the face for ASCII, or unibyte. */
3481 face_id
= face_at_string_position (it
->w
,
3485 it
->region_beg_charpos
,
3486 it
->region_end_charpos
,
3487 &next_check_charpos
,
3490 /* Correct the face for charsets different from ASCII. Do it
3491 for the multibyte case only. The face returned above is
3492 suitable for unibyte text if IT->string is unibyte. */
3493 if (STRING_MULTIBYTE (it
->string
))
3495 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
3496 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
3498 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3500 c
= string_char_and_length (p
, rest
, &len
);
3501 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3506 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3507 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3510 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3511 pos
= it
->current
.pos
;
3514 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3517 if (it
->what
== IT_COMPOSITION
)
3518 /* For composition, we must check the position after the
3520 pos
.charpos
+= it
->cmp_len
, pos
.bytepos
+= it
->len
;
3522 INC_TEXT_POS (pos
, it
->multibyte_p
);
3525 /* Determine face for CHARSET_ASCII, or unibyte. */
3526 face_id
= face_at_buffer_position (it
->w
,
3528 it
->region_beg_charpos
,
3529 it
->region_end_charpos
,
3530 &next_check_charpos
,
3533 /* Correct the face for charsets different from ASCII. Do it
3534 for the multibyte case only. The face returned above is
3535 suitable for unibyte text if current_buffer is unibyte. */
3536 if (it
->multibyte_p
)
3538 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3539 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3540 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3549 /***********************************************************************
3551 ***********************************************************************/
3553 /* Set up iterator IT from invisible properties at its current
3554 position. Called from handle_stop. */
3556 static enum prop_handled
3557 handle_invisible_prop (it
)
3560 enum prop_handled handled
= HANDLED_NORMALLY
;
3562 if (STRINGP (it
->string
))
3564 extern Lisp_Object Qinvisible
;
3565 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3567 /* Get the value of the invisible text property at the
3568 current position. Value will be nil if there is no such
3570 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3571 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3574 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3576 handled
= HANDLED_RECOMPUTE_PROPS
;
3578 /* Get the position at which the next change of the
3579 invisible text property can be found in IT->string.
3580 Value will be nil if the property value is the same for
3581 all the rest of IT->string. */
3582 XSETINT (limit
, SCHARS (it
->string
));
3583 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3586 /* Text at current position is invisible. The next
3587 change in the property is at position end_charpos.
3588 Move IT's current position to that position. */
3589 if (INTEGERP (end_charpos
)
3590 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3592 struct text_pos old
;
3593 old
= it
->current
.string_pos
;
3594 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3595 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3599 /* The rest of the string is invisible. If this is an
3600 overlay string, proceed with the next overlay string
3601 or whatever comes and return a character from there. */
3602 if (it
->current
.overlay_string_index
>= 0)
3604 next_overlay_string (it
);
3605 /* Don't check for overlay strings when we just
3606 finished processing them. */
3607 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3611 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3612 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3619 int invis_p
, newpos
, next_stop
, start_charpos
;
3620 Lisp_Object pos
, prop
, overlay
;
3622 /* First of all, is there invisible text at this position? */
3623 start_charpos
= IT_CHARPOS (*it
);
3624 pos
= make_number (IT_CHARPOS (*it
));
3625 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3627 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3629 /* If we are on invisible text, skip over it. */
3630 if (invis_p
&& IT_CHARPOS (*it
) < it
->end_charpos
)
3632 /* Record whether we have to display an ellipsis for the
3634 int display_ellipsis_p
= invis_p
== 2;
3636 handled
= HANDLED_RECOMPUTE_PROPS
;
3638 /* Loop skipping over invisible text. The loop is left at
3639 ZV or with IT on the first char being visible again. */
3642 /* Try to skip some invisible text. Return value is the
3643 position reached which can be equal to IT's position
3644 if there is nothing invisible here. This skips both
3645 over invisible text properties and overlays with
3646 invisible property. */
3647 newpos
= skip_invisible (IT_CHARPOS (*it
),
3648 &next_stop
, ZV
, it
->window
);
3650 /* If we skipped nothing at all we weren't at invisible
3651 text in the first place. If everything to the end of
3652 the buffer was skipped, end the loop. */
3653 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
3657 /* We skipped some characters but not necessarily
3658 all there are. Check if we ended up on visible
3659 text. Fget_char_property returns the property of
3660 the char before the given position, i.e. if we
3661 get invis_p = 0, this means that the char at
3662 newpos is visible. */
3663 pos
= make_number (newpos
);
3664 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3665 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3668 /* If we ended up on invisible text, proceed to
3669 skip starting with next_stop. */
3671 IT_CHARPOS (*it
) = next_stop
;
3673 /* If there are adjacent invisible texts, don't lose the
3674 second one's ellipsis. */
3676 display_ellipsis_p
= 1;
3680 /* The position newpos is now either ZV or on visible text. */
3681 IT_CHARPOS (*it
) = newpos
;
3682 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3684 /* If there are before-strings at the start of invisible
3685 text, and the text is invisible because of a text
3686 property, arrange to show before-strings because 20.x did
3687 it that way. (If the text is invisible because of an
3688 overlay property instead of a text property, this is
3689 already handled in the overlay code.) */
3691 && get_overlay_strings (it
, start_charpos
))
3693 handled
= HANDLED_RECOMPUTE_PROPS
;
3694 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3696 else if (display_ellipsis_p
)
3698 /* Make sure that the glyphs of the ellipsis will get
3699 correct `charpos' values. If we would not update
3700 it->position here, the glyphs would belong to the
3701 last visible character _before_ the invisible
3702 text, which confuses `set_cursor_from_row'.
3704 We use the last invisible position instead of the
3705 first because this way the cursor is always drawn on
3706 the first "." of the ellipsis, whenever PT is inside
3707 the invisible text. Otherwise the cursor would be
3708 placed _after_ the ellipsis when the point is after the
3709 first invisible character. */
3710 if (!STRINGP (it
->object
))
3712 it
->position
.charpos
= IT_CHARPOS (*it
) - 1;
3713 it
->position
.bytepos
= CHAR_TO_BYTE (it
->position
.charpos
);
3715 setup_for_ellipsis (it
, 0);
3724 /* Make iterator IT return `...' next.
3725 Replaces LEN characters from buffer. */
3728 setup_for_ellipsis (it
, len
)
3732 /* Use the display table definition for `...'. Invalid glyphs
3733 will be handled by the method returning elements from dpvec. */
3734 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3736 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3737 it
->dpvec
= v
->contents
;
3738 it
->dpend
= v
->contents
+ v
->size
;
3742 /* Default `...'. */
3743 it
->dpvec
= default_invis_vector
;
3744 it
->dpend
= default_invis_vector
+ 3;
3747 it
->dpvec_char_len
= len
;
3748 it
->current
.dpvec_index
= 0;
3749 it
->dpvec_face_id
= -1;
3751 /* Remember the current face id in case glyphs specify faces.
3752 IT's face is restored in set_iterator_to_next.
3753 saved_face_id was set to preceding char's face in handle_stop. */
3754 if (it
->saved_face_id
< 0 || it
->saved_face_id
!= it
->face_id
)
3755 it
->saved_face_id
= it
->face_id
= DEFAULT_FACE_ID
;
3757 it
->method
= GET_FROM_DISPLAY_VECTOR
;
3763 /***********************************************************************
3765 ***********************************************************************/
3767 /* Set up iterator IT from `display' property at its current position.
3768 Called from handle_stop.
3769 We return HANDLED_RETURN if some part of the display property
3770 overrides the display of the buffer text itself.
3771 Otherwise we return HANDLED_NORMALLY. */
3773 static enum prop_handled
3774 handle_display_prop (it
)
3777 Lisp_Object prop
, object
;
3778 struct text_pos
*position
;
3779 /* Nonzero if some property replaces the display of the text itself. */
3780 int display_replaced_p
= 0;
3782 if (STRINGP (it
->string
))
3784 object
= it
->string
;
3785 position
= &it
->current
.string_pos
;
3789 XSETWINDOW (object
, it
->w
);
3790 position
= &it
->current
.pos
;
3793 /* Reset those iterator values set from display property values. */
3794 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
3795 it
->space_width
= Qnil
;
3796 it
->font_height
= Qnil
;
3799 /* We don't support recursive `display' properties, i.e. string
3800 values that have a string `display' property, that have a string
3801 `display' property etc. */
3802 if (!it
->string_from_display_prop_p
)
3803 it
->area
= TEXT_AREA
;
3805 prop
= Fget_char_property (make_number (position
->charpos
),
3808 return HANDLED_NORMALLY
;
3810 if (!STRINGP (it
->string
))
3811 object
= it
->w
->buffer
;
3814 /* Simple properties. */
3815 && !EQ (XCAR (prop
), Qimage
)
3816 && !EQ (XCAR (prop
), Qspace
)
3817 && !EQ (XCAR (prop
), Qwhen
)
3818 && !EQ (XCAR (prop
), Qslice
)
3819 && !EQ (XCAR (prop
), Qspace_width
)
3820 && !EQ (XCAR (prop
), Qheight
)
3821 && !EQ (XCAR (prop
), Qraise
)
3822 /* Marginal area specifications. */
3823 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3824 && !EQ (XCAR (prop
), Qleft_fringe
)
3825 && !EQ (XCAR (prop
), Qright_fringe
)
3826 && !NILP (XCAR (prop
)))
3828 for (; CONSP (prop
); prop
= XCDR (prop
))
3830 if (handle_single_display_spec (it
, XCAR (prop
), object
,
3831 position
, display_replaced_p
))
3832 display_replaced_p
= 1;
3835 else if (VECTORP (prop
))
3838 for (i
= 0; i
< ASIZE (prop
); ++i
)
3839 if (handle_single_display_spec (it
, AREF (prop
, i
), object
,
3840 position
, display_replaced_p
))
3841 display_replaced_p
= 1;
3845 int ret
= handle_single_display_spec (it
, prop
, object
, position
, 0);
3846 if (ret
< 0) /* Replaced by "", i.e. nothing. */
3847 return HANDLED_RECOMPUTE_PROPS
;
3849 display_replaced_p
= 1;
3852 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
3856 /* Value is the position of the end of the `display' property starting
3857 at START_POS in OBJECT. */
3859 static struct text_pos
3860 display_prop_end (it
, object
, start_pos
)
3863 struct text_pos start_pos
;
3866 struct text_pos end_pos
;
3868 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
3869 Qdisplay
, object
, Qnil
);
3870 CHARPOS (end_pos
) = XFASTINT (end
);
3871 if (STRINGP (object
))
3872 compute_string_pos (&end_pos
, start_pos
, it
->string
);
3874 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
3880 /* Set up IT from a single `display' specification PROP. OBJECT
3881 is the object in which the `display' property was found. *POSITION
3882 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3883 means that we previously saw a display specification which already
3884 replaced text display with something else, for example an image;
3885 we ignore such properties after the first one has been processed.
3887 If PROP is a `space' or `image' specification, and in some other
3888 cases too, set *POSITION to the position where the `display'
3891 Value is non-zero if something was found which replaces the display
3892 of buffer or string text. Specifically, the value is -1 if that
3893 "something" is "nothing". */
3896 handle_single_display_spec (it
, spec
, object
, position
,
3897 display_replaced_before_p
)
3901 struct text_pos
*position
;
3902 int display_replaced_before_p
;
3905 Lisp_Object location
, value
;
3906 struct text_pos start_pos
, save_pos
;
3909 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3910 If the result is non-nil, use VALUE instead of SPEC. */
3912 if (CONSP (spec
) && EQ (XCAR (spec
), Qwhen
))
3921 if (!NILP (form
) && !EQ (form
, Qt
))
3923 int count
= SPECPDL_INDEX ();
3924 struct gcpro gcpro1
;
3926 /* Bind `object' to the object having the `display' property, a
3927 buffer or string. Bind `position' to the position in the
3928 object where the property was found, and `buffer-position'
3929 to the current position in the buffer. */
3930 specbind (Qobject
, object
);
3931 specbind (Qposition
, make_number (CHARPOS (*position
)));
3932 specbind (Qbuffer_position
,
3933 make_number (STRINGP (object
)
3934 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
3936 form
= safe_eval (form
);
3938 unbind_to (count
, Qnil
);
3944 /* Handle `(height HEIGHT)' specifications. */
3946 && EQ (XCAR (spec
), Qheight
)
3947 && CONSP (XCDR (spec
)))
3949 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3952 it
->font_height
= XCAR (XCDR (spec
));
3953 if (!NILP (it
->font_height
))
3955 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3956 int new_height
= -1;
3958 if (CONSP (it
->font_height
)
3959 && (EQ (XCAR (it
->font_height
), Qplus
)
3960 || EQ (XCAR (it
->font_height
), Qminus
))
3961 && CONSP (XCDR (it
->font_height
))
3962 && INTEGERP (XCAR (XCDR (it
->font_height
))))
3964 /* `(+ N)' or `(- N)' where N is an integer. */
3965 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
3966 if (EQ (XCAR (it
->font_height
), Qplus
))
3968 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
3970 else if (FUNCTIONP (it
->font_height
))
3972 /* Call function with current height as argument.
3973 Value is the new height. */
3975 height
= safe_call1 (it
->font_height
,
3976 face
->lface
[LFACE_HEIGHT_INDEX
]);
3977 if (NUMBERP (height
))
3978 new_height
= XFLOATINT (height
);
3980 else if (NUMBERP (it
->font_height
))
3982 /* Value is a multiple of the canonical char height. */
3985 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
3986 new_height
= (XFLOATINT (it
->font_height
)
3987 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
3991 /* Evaluate IT->font_height with `height' bound to the
3992 current specified height to get the new height. */
3993 int count
= SPECPDL_INDEX ();
3995 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
3996 value
= safe_eval (it
->font_height
);
3997 unbind_to (count
, Qnil
);
3999 if (NUMBERP (value
))
4000 new_height
= XFLOATINT (value
);
4004 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
4010 /* Handle `(space_width WIDTH)'. */
4012 && EQ (XCAR (spec
), Qspace_width
)
4013 && CONSP (XCDR (spec
)))
4015 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
4018 value
= XCAR (XCDR (spec
));
4019 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
4020 it
->space_width
= value
;
4025 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4027 && EQ (XCAR (spec
), Qslice
))
4031 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
4034 if (tem
= XCDR (spec
), CONSP (tem
))
4036 it
->slice
.x
= XCAR (tem
);
4037 if (tem
= XCDR (tem
), CONSP (tem
))
4039 it
->slice
.y
= XCAR (tem
);
4040 if (tem
= XCDR (tem
), CONSP (tem
))
4042 it
->slice
.width
= XCAR (tem
);
4043 if (tem
= XCDR (tem
), CONSP (tem
))
4044 it
->slice
.height
= XCAR (tem
);
4052 /* Handle `(raise FACTOR)'. */
4054 && EQ (XCAR (spec
), Qraise
)
4055 && CONSP (XCDR (spec
)))
4057 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
4060 #ifdef HAVE_WINDOW_SYSTEM
4061 value
= XCAR (XCDR (spec
));
4062 if (NUMBERP (value
))
4064 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4065 it
->voffset
= - (XFLOATINT (value
)
4066 * (FONT_HEIGHT (face
->font
)));
4068 #endif /* HAVE_WINDOW_SYSTEM */
4073 /* Don't handle the other kinds of display specifications
4074 inside a string that we got from a `display' property. */
4075 if (it
->string_from_display_prop_p
)
4078 /* Characters having this form of property are not displayed, so
4079 we have to find the end of the property. */
4080 start_pos
= *position
;
4081 *position
= display_prop_end (it
, object
, start_pos
);
4084 /* Stop the scan at that end position--we assume that all
4085 text properties change there. */
4086 it
->stop_charpos
= position
->charpos
;
4088 /* Handle `(left-fringe BITMAP [FACE])'
4089 and `(right-fringe BITMAP [FACE])'. */
4091 && (EQ (XCAR (spec
), Qleft_fringe
)
4092 || EQ (XCAR (spec
), Qright_fringe
))
4093 && CONSP (XCDR (spec
)))
4095 int face_id
= DEFAULT_FACE_ID
;
4098 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
4099 /* If we return here, POSITION has been advanced
4100 across the text with this property. */
4103 #ifdef HAVE_WINDOW_SYSTEM
4104 value
= XCAR (XCDR (spec
));
4105 if (!SYMBOLP (value
)
4106 || !(fringe_bitmap
= lookup_fringe_bitmap (value
)))
4107 /* If we return here, POSITION has been advanced
4108 across the text with this property. */
4111 if (CONSP (XCDR (XCDR (spec
))))
4113 Lisp_Object face_name
= XCAR (XCDR (XCDR (spec
)));
4114 int face_id2
= lookup_derived_face (it
->f
, face_name
,
4115 'A', FRINGE_FACE_ID
, 0);
4120 /* Save current settings of IT so that we can restore them
4121 when we are finished with the glyph property value. */
4123 save_pos
= it
->position
;
4124 it
->position
= *position
;
4126 it
->position
= save_pos
;
4128 it
->area
= TEXT_AREA
;
4129 it
->what
= IT_IMAGE
;
4130 it
->image_id
= -1; /* no image */
4131 it
->position
= start_pos
;
4132 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
4133 it
->method
= GET_FROM_IMAGE
;
4134 it
->face_id
= face_id
;
4136 /* Say that we haven't consumed the characters with
4137 `display' property yet. The call to pop_it in
4138 set_iterator_to_next will clean this up. */
4139 *position
= start_pos
;
4141 if (EQ (XCAR (spec
), Qleft_fringe
))
4143 it
->left_user_fringe_bitmap
= fringe_bitmap
;
4144 it
->left_user_fringe_face_id
= face_id
;
4148 it
->right_user_fringe_bitmap
= fringe_bitmap
;
4149 it
->right_user_fringe_face_id
= face_id
;
4151 #endif /* HAVE_WINDOW_SYSTEM */
4155 /* Prepare to handle `((margin left-margin) ...)',
4156 `((margin right-margin) ...)' and `((margin nil) ...)'
4157 prefixes for display specifications. */
4158 location
= Qunbound
;
4159 if (CONSP (spec
) && CONSP (XCAR (spec
)))
4163 value
= XCDR (spec
);
4165 value
= XCAR (value
);
4168 if (EQ (XCAR (tem
), Qmargin
)
4169 && (tem
= XCDR (tem
),
4170 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
4172 || EQ (tem
, Qleft_margin
)
4173 || EQ (tem
, Qright_margin
))))
4177 if (EQ (location
, Qunbound
))
4183 /* After this point, VALUE is the property after any
4184 margin prefix has been stripped. It must be a string,
4185 an image specification, or `(space ...)'.
4187 LOCATION specifies where to display: `left-margin',
4188 `right-margin' or nil. */
4190 valid_p
= (STRINGP (value
)
4191 #ifdef HAVE_WINDOW_SYSTEM
4192 || (!FRAME_TERMCAP_P (it
->f
) && valid_image_p (value
))
4193 #endif /* not HAVE_WINDOW_SYSTEM */
4194 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
4196 if (valid_p
&& !display_replaced_before_p
)
4198 /* Save current settings of IT so that we can restore them
4199 when we are finished with the glyph property value. */
4200 save_pos
= it
->position
;
4201 it
->position
= *position
;
4203 it
->position
= save_pos
;
4205 if (NILP (location
))
4206 it
->area
= TEXT_AREA
;
4207 else if (EQ (location
, Qleft_margin
))
4208 it
->area
= LEFT_MARGIN_AREA
;
4210 it
->area
= RIGHT_MARGIN_AREA
;
4212 if (STRINGP (value
))
4214 if (SCHARS (value
) == 0)
4217 return -1; /* Replaced by "", i.e. nothing. */
4220 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4221 it
->current
.overlay_string_index
= -1;
4222 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4223 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
4224 it
->method
= GET_FROM_STRING
;
4225 it
->stop_charpos
= 0;
4226 it
->string_from_display_prop_p
= 1;
4227 /* Say that we haven't consumed the characters with
4228 `display' property yet. The call to pop_it in
4229 set_iterator_to_next will clean this up. */
4230 *position
= start_pos
;
4232 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
4234 it
->method
= GET_FROM_STRETCH
;
4236 *position
= it
->position
= start_pos
;
4238 #ifdef HAVE_WINDOW_SYSTEM
4241 it
->what
= IT_IMAGE
;
4242 it
->image_id
= lookup_image (it
->f
, value
);
4243 it
->position
= start_pos
;
4244 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
4245 it
->method
= GET_FROM_IMAGE
;
4247 /* Say that we haven't consumed the characters with
4248 `display' property yet. The call to pop_it in
4249 set_iterator_to_next will clean this up. */
4250 *position
= start_pos
;
4252 #endif /* HAVE_WINDOW_SYSTEM */
4257 /* Invalid property or property not supported. Restore
4258 POSITION to what it was before. */
4259 *position
= start_pos
;
4264 /* Check if SPEC is a display specification value whose text should be
4265 treated as intangible. */
4268 single_display_spec_intangible_p (prop
)
4271 /* Skip over `when FORM'. */
4272 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
4286 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4287 we don't need to treat text as intangible. */
4288 if (EQ (XCAR (prop
), Qmargin
))
4296 || EQ (XCAR (prop
), Qleft_margin
)
4297 || EQ (XCAR (prop
), Qright_margin
))
4301 return (CONSP (prop
)
4302 && (EQ (XCAR (prop
), Qimage
)
4303 || EQ (XCAR (prop
), Qspace
)));
4307 /* Check if PROP is a display property value whose text should be
4308 treated as intangible. */
4311 display_prop_intangible_p (prop
)
4315 && CONSP (XCAR (prop
))
4316 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
4318 /* A list of sub-properties. */
4319 while (CONSP (prop
))
4321 if (single_display_spec_intangible_p (XCAR (prop
)))
4326 else if (VECTORP (prop
))
4328 /* A vector of sub-properties. */
4330 for (i
= 0; i
< ASIZE (prop
); ++i
)
4331 if (single_display_spec_intangible_p (AREF (prop
, i
)))
4335 return single_display_spec_intangible_p (prop
);
4341 /* Return 1 if PROP is a display sub-property value containing STRING. */
4344 single_display_spec_string_p (prop
, string
)
4345 Lisp_Object prop
, string
;
4347 if (EQ (string
, prop
))
4350 /* Skip over `when FORM'. */
4351 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
4360 /* Skip over `margin LOCATION'. */
4361 if (EQ (XCAR (prop
), Qmargin
))
4372 return CONSP (prop
) && EQ (XCAR (prop
), string
);
4376 /* Return 1 if STRING appears in the `display' property PROP. */
4379 display_prop_string_p (prop
, string
)
4380 Lisp_Object prop
, string
;
4383 && CONSP (XCAR (prop
))
4384 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
4386 /* A list of sub-properties. */
4387 while (CONSP (prop
))
4389 if (single_display_spec_string_p (XCAR (prop
), string
))
4394 else if (VECTORP (prop
))
4396 /* A vector of sub-properties. */
4398 for (i
= 0; i
< ASIZE (prop
); ++i
)
4399 if (single_display_spec_string_p (AREF (prop
, i
), string
))
4403 return single_display_spec_string_p (prop
, string
);
4409 /* Determine from which buffer position in W's buffer STRING comes
4410 from. AROUND_CHARPOS is an approximate position where it could
4411 be from. Value is the buffer position or 0 if it couldn't be
4414 W's buffer must be current.
4416 This function is necessary because we don't record buffer positions
4417 in glyphs generated from strings (to keep struct glyph small).
4418 This function may only use code that doesn't eval because it is
4419 called asynchronously from note_mouse_highlight. */
4422 string_buffer_position (w
, string
, around_charpos
)
4427 Lisp_Object limit
, prop
, pos
;
4428 const int MAX_DISTANCE
= 1000;
4431 pos
= make_number (around_charpos
);
4432 limit
= make_number (min (XINT (pos
) + MAX_DISTANCE
, ZV
));
4433 while (!found
&& !EQ (pos
, limit
))
4435 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
4436 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
4439 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
, limit
);
4444 pos
= make_number (around_charpos
);
4445 limit
= make_number (max (XINT (pos
) - MAX_DISTANCE
, BEGV
));
4446 while (!found
&& !EQ (pos
, limit
))
4448 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
4449 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
4452 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
4457 return found
? XINT (pos
) : 0;
4462 /***********************************************************************
4463 `composition' property
4464 ***********************************************************************/
4466 /* Set up iterator IT from `composition' property at its current
4467 position. Called from handle_stop. */
4469 static enum prop_handled
4470 handle_composition_prop (it
)
4473 Lisp_Object prop
, string
;
4474 int pos
, pos_byte
, end
;
4475 enum prop_handled handled
= HANDLED_NORMALLY
;
4477 if (STRINGP (it
->string
))
4479 pos
= IT_STRING_CHARPOS (*it
);
4480 pos_byte
= IT_STRING_BYTEPOS (*it
);
4481 string
= it
->string
;
4485 pos
= IT_CHARPOS (*it
);
4486 pos_byte
= IT_BYTEPOS (*it
);
4490 /* If there's a valid composition and point is not inside of the
4491 composition (in the case that the composition is from the current
4492 buffer), draw a glyph composed from the composition components. */
4493 if (find_composition (pos
, -1, &pos
, &end
, &prop
, string
)
4494 && COMPOSITION_VALID_P (pos
, end
, prop
)
4495 && (STRINGP (it
->string
) || (PT
<= pos
|| PT
>= end
)))
4497 int id
= get_composition_id (pos
, pos_byte
, end
- pos
, prop
, string
);
4501 struct composition
*cmp
= composition_table
[id
];
4503 if (cmp
->glyph_len
== 0)
4506 if (STRINGP (it
->string
))
4508 IT_STRING_CHARPOS (*it
) = end
;
4509 IT_STRING_BYTEPOS (*it
) = string_char_to_byte (it
->string
,
4514 IT_CHARPOS (*it
) = end
;
4515 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (end
);
4517 return HANDLED_RECOMPUTE_PROPS
;
4520 it
->stop_charpos
= end
;
4523 it
->method
= GET_FROM_COMPOSITION
;
4525 it
->cmp_len
= COMPOSITION_LENGTH (prop
);
4526 /* For a terminal, draw only the first character of the
4528 it
->c
= COMPOSITION_GLYPH (composition_table
[id
], 0);
4529 it
->len
= (STRINGP (it
->string
)
4530 ? string_char_to_byte (it
->string
, end
)
4531 : CHAR_TO_BYTE (end
)) - pos_byte
;
4532 handled
= HANDLED_RETURN
;
4541 /***********************************************************************
4543 ***********************************************************************/
4545 /* The following structure is used to record overlay strings for
4546 later sorting in load_overlay_strings. */
4548 struct overlay_entry
4550 Lisp_Object overlay
;
4557 /* Set up iterator IT from overlay strings at its current position.
4558 Called from handle_stop. */
4560 static enum prop_handled
4561 handle_overlay_change (it
)
4564 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
4565 return HANDLED_RECOMPUTE_PROPS
;
4567 return HANDLED_NORMALLY
;
4571 /* Set up the next overlay string for delivery by IT, if there is an
4572 overlay string to deliver. Called by set_iterator_to_next when the
4573 end of the current overlay string is reached. If there are more
4574 overlay strings to display, IT->string and
4575 IT->current.overlay_string_index are set appropriately here.
4576 Otherwise IT->string is set to nil. */
4579 next_overlay_string (it
)
4582 ++it
->current
.overlay_string_index
;
4583 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
4585 /* No more overlay strings. Restore IT's settings to what
4586 they were before overlay strings were processed, and
4587 continue to deliver from current_buffer. */
4588 int display_ellipsis_p
= it
->stack
[it
->sp
- 1].display_ellipsis_p
;
4592 || it
->method
== GET_FROM_COMPOSITION
4593 || (NILP (it
->string
)
4594 && it
->method
== GET_FROM_BUFFER
4595 && it
->stop_charpos
>= BEGV
4596 && it
->stop_charpos
<= it
->end_charpos
));
4597 it
->current
.overlay_string_index
= -1;
4598 it
->n_overlay_strings
= 0;
4600 /* If we're at the end of the buffer, record that we have
4601 processed the overlay strings there already, so that
4602 next_element_from_buffer doesn't try it again. */
4603 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
4604 it
->overlay_strings_at_end_processed_p
= 1;
4606 /* If we have to display `...' for invisible text, set
4607 the iterator up for that. */
4608 if (display_ellipsis_p
)
4609 setup_for_ellipsis (it
, 0);
4613 /* There are more overlay strings to process. If
4614 IT->current.overlay_string_index has advanced to a position
4615 where we must load IT->overlay_strings with more strings, do
4617 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
4619 if (it
->current
.overlay_string_index
&& i
== 0)
4620 load_overlay_strings (it
, 0);
4622 /* Initialize IT to deliver display elements from the overlay
4624 it
->string
= it
->overlay_strings
[i
];
4625 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4626 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
4627 it
->method
= GET_FROM_STRING
;
4628 it
->stop_charpos
= 0;
4635 /* Compare two overlay_entry structures E1 and E2. Used as a
4636 comparison function for qsort in load_overlay_strings. Overlay
4637 strings for the same position are sorted so that
4639 1. All after-strings come in front of before-strings, except
4640 when they come from the same overlay.
4642 2. Within after-strings, strings are sorted so that overlay strings
4643 from overlays with higher priorities come first.
4645 2. Within before-strings, strings are sorted so that overlay
4646 strings from overlays with higher priorities come last.
4648 Value is analogous to strcmp. */
4652 compare_overlay_entries (e1
, e2
)
4655 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4656 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4659 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4661 /* Let after-strings appear in front of before-strings if
4662 they come from different overlays. */
4663 if (EQ (entry1
->overlay
, entry2
->overlay
))
4664 result
= entry1
->after_string_p
? 1 : -1;
4666 result
= entry1
->after_string_p
? -1 : 1;
4668 else if (entry1
->after_string_p
)
4669 /* After-strings sorted in order of decreasing priority. */
4670 result
= entry2
->priority
- entry1
->priority
;
4672 /* Before-strings sorted in order of increasing priority. */
4673 result
= entry1
->priority
- entry2
->priority
;
4679 /* Load the vector IT->overlay_strings with overlay strings from IT's
4680 current buffer position, or from CHARPOS if that is > 0. Set
4681 IT->n_overlays to the total number of overlay strings found.
4683 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4684 a time. On entry into load_overlay_strings,
4685 IT->current.overlay_string_index gives the number of overlay
4686 strings that have already been loaded by previous calls to this
4689 IT->add_overlay_start contains an additional overlay start
4690 position to consider for taking overlay strings from, if non-zero.
4691 This position comes into play when the overlay has an `invisible'
4692 property, and both before and after-strings. When we've skipped to
4693 the end of the overlay, because of its `invisible' property, we
4694 nevertheless want its before-string to appear.
4695 IT->add_overlay_start will contain the overlay start position
4698 Overlay strings are sorted so that after-string strings come in
4699 front of before-string strings. Within before and after-strings,
4700 strings are sorted by overlay priority. See also function
4701 compare_overlay_entries. */
4704 load_overlay_strings (it
, charpos
)
4708 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
4709 Lisp_Object overlay
, window
, str
, invisible
;
4710 struct Lisp_Overlay
*ov
;
4713 int n
= 0, i
, j
, invis_p
;
4714 struct overlay_entry
*entries
4715 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4718 charpos
= IT_CHARPOS (*it
);
4720 /* Append the overlay string STRING of overlay OVERLAY to vector
4721 `entries' which has size `size' and currently contains `n'
4722 elements. AFTER_P non-zero means STRING is an after-string of
4724 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4727 Lisp_Object priority; \
4731 int new_size = 2 * size; \
4732 struct overlay_entry *old = entries; \
4734 (struct overlay_entry *) alloca (new_size \
4735 * sizeof *entries); \
4736 bcopy (old, entries, size * sizeof *entries); \
4740 entries[n].string = (STRING); \
4741 entries[n].overlay = (OVERLAY); \
4742 priority = Foverlay_get ((OVERLAY), Qpriority); \
4743 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4744 entries[n].after_string_p = (AFTER_P); \
4749 /* Process overlay before the overlay center. */
4750 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4752 XSETMISC (overlay
, ov
);
4753 xassert (OVERLAYP (overlay
));
4754 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4755 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4760 /* Skip this overlay if it doesn't start or end at IT's current
4762 if (end
!= charpos
&& start
!= charpos
)
4765 /* Skip this overlay if it doesn't apply to IT->w. */
4766 window
= Foverlay_get (overlay
, Qwindow
);
4767 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4770 /* If the text ``under'' the overlay is invisible, both before-
4771 and after-strings from this overlay are visible; start and
4772 end position are indistinguishable. */
4773 invisible
= Foverlay_get (overlay
, Qinvisible
);
4774 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4776 /* If overlay has a non-empty before-string, record it. */
4777 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4778 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4780 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4782 /* If overlay has a non-empty after-string, record it. */
4783 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4784 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4786 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4789 /* Process overlays after the overlay center. */
4790 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4792 XSETMISC (overlay
, ov
);
4793 xassert (OVERLAYP (overlay
));
4794 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4795 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4797 if (start
> charpos
)
4800 /* Skip this overlay if it doesn't start or end at IT's current
4802 if (end
!= charpos
&& start
!= charpos
)
4805 /* Skip this overlay if it doesn't apply to IT->w. */
4806 window
= Foverlay_get (overlay
, Qwindow
);
4807 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4810 /* If the text ``under'' the overlay is invisible, it has a zero
4811 dimension, and both before- and after-strings apply. */
4812 invisible
= Foverlay_get (overlay
, Qinvisible
);
4813 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4815 /* If overlay has a non-empty before-string, record it. */
4816 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4817 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4819 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4821 /* If overlay has a non-empty after-string, record it. */
4822 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4823 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4825 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4828 #undef RECORD_OVERLAY_STRING
4832 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
4834 /* Record the total number of strings to process. */
4835 it
->n_overlay_strings
= n
;
4837 /* IT->current.overlay_string_index is the number of overlay strings
4838 that have already been consumed by IT. Copy some of the
4839 remaining overlay strings to IT->overlay_strings. */
4841 j
= it
->current
.overlay_string_index
;
4842 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
4843 it
->overlay_strings
[i
++] = entries
[j
++].string
;
4849 /* Get the first chunk of overlay strings at IT's current buffer
4850 position, or at CHARPOS if that is > 0. Value is non-zero if at
4851 least one overlay string was found. */
4854 get_overlay_strings_1 (it
, charpos
, compute_stop_p
)
4858 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4859 process. This fills IT->overlay_strings with strings, and sets
4860 IT->n_overlay_strings to the total number of strings to process.
4861 IT->pos.overlay_string_index has to be set temporarily to zero
4862 because load_overlay_strings needs this; it must be set to -1
4863 when no overlay strings are found because a zero value would
4864 indicate a position in the first overlay string. */
4865 it
->current
.overlay_string_index
= 0;
4866 load_overlay_strings (it
, charpos
);
4868 /* If we found overlay strings, set up IT to deliver display
4869 elements from the first one. Otherwise set up IT to deliver
4870 from current_buffer. */
4871 if (it
->n_overlay_strings
)
4873 /* Make sure we know settings in current_buffer, so that we can
4874 restore meaningful values when we're done with the overlay
4877 compute_stop_pos (it
);
4878 xassert (it
->face_id
>= 0);
4880 /* Save IT's settings. They are restored after all overlay
4881 strings have been processed. */
4882 xassert (!compute_stop_p
|| it
->sp
== 0);
4885 /* Set up IT to deliver display elements from the first overlay
4887 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4888 it
->string
= it
->overlay_strings
[0];
4889 it
->stop_charpos
= 0;
4890 xassert (STRINGP (it
->string
));
4891 it
->end_charpos
= SCHARS (it
->string
);
4892 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4893 it
->method
= GET_FROM_STRING
;
4897 it
->current
.overlay_string_index
= -1;
4902 get_overlay_strings (it
, charpos
)
4907 it
->method
= GET_FROM_BUFFER
;
4909 (void) get_overlay_strings_1 (it
, charpos
, 1);
4913 /* Value is non-zero if we found at least one overlay string. */
4914 return STRINGP (it
->string
);
4919 /***********************************************************************
4920 Saving and restoring state
4921 ***********************************************************************/
4923 /* Save current settings of IT on IT->stack. Called, for example,
4924 before setting up IT for an overlay string, to be able to restore
4925 IT's settings to what they were after the overlay string has been
4932 struct iterator_stack_entry
*p
;
4934 xassert (it
->sp
< IT_STACK_SIZE
);
4935 p
= it
->stack
+ it
->sp
;
4937 p
->stop_charpos
= it
->stop_charpos
;
4938 xassert (it
->face_id
>= 0);
4939 p
->face_id
= it
->face_id
;
4940 p
->string
= it
->string
;
4941 p
->method
= it
->method
;
4944 case GET_FROM_IMAGE
:
4945 p
->u
.image
.object
= it
->object
;
4946 p
->u
.image
.image_id
= it
->image_id
;
4947 p
->u
.image
.slice
= it
->slice
;
4949 case GET_FROM_COMPOSITION
:
4950 p
->u
.comp
.object
= it
->object
;
4951 p
->u
.comp
.c
= it
->c
;
4952 p
->u
.comp
.len
= it
->len
;
4953 p
->u
.comp
.cmp_id
= it
->cmp_id
;
4954 p
->u
.comp
.cmp_len
= it
->cmp_len
;
4956 case GET_FROM_STRETCH
:
4957 p
->u
.stretch
.object
= it
->object
;
4960 p
->position
= it
->position
;
4961 p
->current
= it
->current
;
4962 p
->end_charpos
= it
->end_charpos
;
4963 p
->string_nchars
= it
->string_nchars
;
4965 p
->multibyte_p
= it
->multibyte_p
;
4966 p
->space_width
= it
->space_width
;
4967 p
->font_height
= it
->font_height
;
4968 p
->voffset
= it
->voffset
;
4969 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
4970 p
->display_ellipsis_p
= 0;
4975 /* Restore IT's settings from IT->stack. Called, for example, when no
4976 more overlay strings must be processed, and we return to delivering
4977 display elements from a buffer, or when the end of a string from a
4978 `display' property is reached and we return to delivering display
4979 elements from an overlay string, or from a buffer. */
4985 struct iterator_stack_entry
*p
;
4987 xassert (it
->sp
> 0);
4989 p
= it
->stack
+ it
->sp
;
4990 it
->stop_charpos
= p
->stop_charpos
;
4991 it
->face_id
= p
->face_id
;
4992 it
->current
= p
->current
;
4993 it
->position
= p
->position
;
4994 it
->string
= p
->string
;
4995 if (NILP (it
->string
))
4996 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
4997 it
->method
= p
->method
;
5000 case GET_FROM_IMAGE
:
5001 it
->image_id
= p
->u
.image
.image_id
;
5002 it
->object
= p
->u
.image
.object
;
5003 it
->slice
= p
->u
.image
.slice
;
5005 case GET_FROM_COMPOSITION
:
5006 it
->object
= p
->u
.comp
.object
;
5007 it
->c
= p
->u
.comp
.c
;
5008 it
->len
= p
->u
.comp
.len
;
5009 it
->cmp_id
= p
->u
.comp
.cmp_id
;
5010 it
->cmp_len
= p
->u
.comp
.cmp_len
;
5012 case GET_FROM_STRETCH
:
5013 it
->object
= p
->u
.comp
.object
;
5015 case GET_FROM_BUFFER
:
5016 it
->object
= it
->w
->buffer
;
5018 case GET_FROM_STRING
:
5019 it
->object
= it
->string
;
5022 it
->end_charpos
= p
->end_charpos
;
5023 it
->string_nchars
= p
->string_nchars
;
5025 it
->multibyte_p
= p
->multibyte_p
;
5026 it
->space_width
= p
->space_width
;
5027 it
->font_height
= p
->font_height
;
5028 it
->voffset
= p
->voffset
;
5029 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
5034 /***********************************************************************
5036 ***********************************************************************/
5038 /* Set IT's current position to the previous line start. */
5041 back_to_previous_line_start (it
)
5044 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
5045 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
5049 /* Move IT to the next line start.
5051 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5052 we skipped over part of the text (as opposed to moving the iterator
5053 continuously over the text). Otherwise, don't change the value
5056 Newlines may come from buffer text, overlay strings, or strings
5057 displayed via the `display' property. That's the reason we can't
5058 simply use find_next_newline_no_quit.
5060 Note that this function may not skip over invisible text that is so
5061 because of text properties and immediately follows a newline. If
5062 it would, function reseat_at_next_visible_line_start, when called
5063 from set_iterator_to_next, would effectively make invisible
5064 characters following a newline part of the wrong glyph row, which
5065 leads to wrong cursor motion. */
5068 forward_to_next_line_start (it
, skipped_p
)
5072 int old_selective
, newline_found_p
, n
;
5073 const int MAX_NEWLINE_DISTANCE
= 500;
5075 /* If already on a newline, just consume it to avoid unintended
5076 skipping over invisible text below. */
5077 if (it
->what
== IT_CHARACTER
5079 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
5081 set_iterator_to_next (it
, 0);
5086 /* Don't handle selective display in the following. It's (a)
5087 unnecessary because it's done by the caller, and (b) leads to an
5088 infinite recursion because next_element_from_ellipsis indirectly
5089 calls this function. */
5090 old_selective
= it
->selective
;
5093 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5094 from buffer text. */
5095 for (n
= newline_found_p
= 0;
5096 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
5097 n
+= STRINGP (it
->string
) ? 0 : 1)
5099 if (!get_next_display_element (it
))
5101 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
5102 set_iterator_to_next (it
, 0);
5105 /* If we didn't find a newline near enough, see if we can use a
5107 if (!newline_found_p
)
5109 int start
= IT_CHARPOS (*it
);
5110 int limit
= find_next_newline_no_quit (start
, 1);
5113 xassert (!STRINGP (it
->string
));
5115 /* If there isn't any `display' property in sight, and no
5116 overlays, we can just use the position of the newline in
5118 if (it
->stop_charpos
>= limit
5119 || ((pos
= Fnext_single_property_change (make_number (start
),
5121 Qnil
, make_number (limit
)),
5123 && next_overlay_change (start
) == ZV
))
5125 IT_CHARPOS (*it
) = limit
;
5126 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
5127 *skipped_p
= newline_found_p
= 1;
5131 while (get_next_display_element (it
)
5132 && !newline_found_p
)
5134 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
5135 set_iterator_to_next (it
, 0);
5140 it
->selective
= old_selective
;
5141 return newline_found_p
;
5145 /* Set IT's current position to the previous visible line start. Skip
5146 invisible text that is so either due to text properties or due to
5147 selective display. Caution: this does not change IT->current_x and
5151 back_to_previous_visible_line_start (it
)
5154 while (IT_CHARPOS (*it
) > BEGV
)
5156 back_to_previous_line_start (it
);
5158 if (IT_CHARPOS (*it
) <= BEGV
)
5161 /* If selective > 0, then lines indented more than that values
5163 if (it
->selective
> 0
5164 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
5165 (double) it
->selective
)) /* iftc */
5168 /* Check the newline before point for invisibility. */
5171 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
) - 1),
5172 Qinvisible
, it
->window
);
5173 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
5177 if (IT_CHARPOS (*it
) <= BEGV
)
5184 Lisp_Object val
, overlay
;
5186 /* If newline is part of a composition, continue from start of composition */
5187 if (find_composition (IT_CHARPOS (*it
), -1, &beg
, &end
, &val
, Qnil
)
5188 && beg
< IT_CHARPOS (*it
))
5191 /* If newline is replaced by a display property, find start of overlay
5192 or interval and continue search from that point. */
5194 pos
= --IT_CHARPOS (it2
);
5197 if (handle_display_prop (&it2
) == HANDLED_RETURN
5198 && !NILP (val
= get_char_property_and_overlay
5199 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
5200 && (OVERLAYP (overlay
)
5201 ? (beg
= OVERLAY_POSITION (OVERLAY_START (overlay
)))
5202 : get_property_and_range (pos
, Qdisplay
, &val
, &beg
, &end
, Qnil
)))
5205 /* Newline is not replaced by anything -- so we are done. */
5211 IT_CHARPOS (*it
) = beg
;
5212 IT_BYTEPOS (*it
) = buf_charpos_to_bytepos (current_buffer
, beg
);
5216 it
->continuation_lines_width
= 0;
5218 xassert (IT_CHARPOS (*it
) >= BEGV
);
5219 xassert (IT_CHARPOS (*it
) == BEGV
5220 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
5225 /* Reseat iterator IT at the previous visible line start. Skip
5226 invisible text that is so either due to text properties or due to
5227 selective display. At the end, update IT's overlay information,
5228 face information etc. */
5231 reseat_at_previous_visible_line_start (it
)
5234 back_to_previous_visible_line_start (it
);
5235 reseat (it
, it
->current
.pos
, 1);
5240 /* Reseat iterator IT on the next visible line start in the current
5241 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5242 preceding the line start. Skip over invisible text that is so
5243 because of selective display. Compute faces, overlays etc at the
5244 new position. Note that this function does not skip over text that
5245 is invisible because of text properties. */
5248 reseat_at_next_visible_line_start (it
, on_newline_p
)
5252 int newline_found_p
, skipped_p
= 0;
5254 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
5256 /* Skip over lines that are invisible because they are indented
5257 more than the value of IT->selective. */
5258 if (it
->selective
> 0)
5259 while (IT_CHARPOS (*it
) < ZV
5260 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
5261 (double) it
->selective
)) /* iftc */
5263 xassert (IT_BYTEPOS (*it
) == BEGV
5264 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
5265 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
5268 /* Position on the newline if that's what's requested. */
5269 if (on_newline_p
&& newline_found_p
)
5271 if (STRINGP (it
->string
))
5273 if (IT_STRING_CHARPOS (*it
) > 0)
5275 --IT_STRING_CHARPOS (*it
);
5276 --IT_STRING_BYTEPOS (*it
);
5279 else if (IT_CHARPOS (*it
) > BEGV
)
5283 reseat (it
, it
->current
.pos
, 0);
5287 reseat (it
, it
->current
.pos
, 0);
5294 /***********************************************************************
5295 Changing an iterator's position
5296 ***********************************************************************/
5298 /* Change IT's current position to POS in current_buffer. If FORCE_P
5299 is non-zero, always check for text properties at the new position.
5300 Otherwise, text properties are only looked up if POS >=
5301 IT->check_charpos of a property. */
5304 reseat (it
, pos
, force_p
)
5306 struct text_pos pos
;
5309 int original_pos
= IT_CHARPOS (*it
);
5311 reseat_1 (it
, pos
, 0);
5313 /* Determine where to check text properties. Avoid doing it
5314 where possible because text property lookup is very expensive. */
5316 || CHARPOS (pos
) > it
->stop_charpos
5317 || CHARPOS (pos
) < original_pos
)
5324 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5325 IT->stop_pos to POS, also. */
5328 reseat_1 (it
, pos
, set_stop_p
)
5330 struct text_pos pos
;
5333 /* Don't call this function when scanning a C string. */
5334 xassert (it
->s
== NULL
);
5336 /* POS must be a reasonable value. */
5337 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
5339 it
->current
.pos
= it
->position
= pos
;
5340 it
->end_charpos
= ZV
;
5342 it
->current
.dpvec_index
= -1;
5343 it
->current
.overlay_string_index
= -1;
5344 IT_STRING_CHARPOS (*it
) = -1;
5345 IT_STRING_BYTEPOS (*it
) = -1;
5347 it
->method
= GET_FROM_BUFFER
;
5348 it
->object
= it
->w
->buffer
;
5349 it
->area
= TEXT_AREA
;
5350 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
5352 it
->string_from_display_prop_p
= 0;
5353 it
->face_before_selective_p
= 0;
5356 it
->stop_charpos
= CHARPOS (pos
);
5360 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5361 If S is non-null, it is a C string to iterate over. Otherwise,
5362 STRING gives a Lisp string to iterate over.
5364 If PRECISION > 0, don't return more then PRECISION number of
5365 characters from the string.
5367 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5368 characters have been returned. FIELD_WIDTH < 0 means an infinite
5371 MULTIBYTE = 0 means disable processing of multibyte characters,
5372 MULTIBYTE > 0 means enable it,
5373 MULTIBYTE < 0 means use IT->multibyte_p.
5375 IT must be initialized via a prior call to init_iterator before
5376 calling this function. */
5379 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
5384 int precision
, field_width
, multibyte
;
5386 /* No region in strings. */
5387 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
5389 /* No text property checks performed by default, but see below. */
5390 it
->stop_charpos
= -1;
5392 /* Set iterator position and end position. */
5393 bzero (&it
->current
, sizeof it
->current
);
5394 it
->current
.overlay_string_index
= -1;
5395 it
->current
.dpvec_index
= -1;
5396 xassert (charpos
>= 0);
5398 /* If STRING is specified, use its multibyteness, otherwise use the
5399 setting of MULTIBYTE, if specified. */
5401 it
->multibyte_p
= multibyte
> 0;
5405 xassert (STRINGP (string
));
5406 it
->string
= string
;
5408 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
5409 it
->method
= GET_FROM_STRING
;
5410 it
->current
.string_pos
= string_pos (charpos
, string
);
5417 /* Note that we use IT->current.pos, not it->current.string_pos,
5418 for displaying C strings. */
5419 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
5420 if (it
->multibyte_p
)
5422 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
5423 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
5427 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
5428 it
->end_charpos
= it
->string_nchars
= strlen (s
);
5431 it
->method
= GET_FROM_C_STRING
;
5434 /* PRECISION > 0 means don't return more than PRECISION characters
5436 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
5437 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
5439 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5440 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5441 FIELD_WIDTH < 0 means infinite field width. This is useful for
5442 padding with `-' at the end of a mode line. */
5443 if (field_width
< 0)
5444 field_width
= INFINITY
;
5445 if (field_width
> it
->end_charpos
- charpos
)
5446 it
->end_charpos
= charpos
+ field_width
;
5448 /* Use the standard display table for displaying strings. */
5449 if (DISP_TABLE_P (Vstandard_display_table
))
5450 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
5452 it
->stop_charpos
= charpos
;
5458 /***********************************************************************
5460 ***********************************************************************/
5462 /* Map enum it_method value to corresponding next_element_from_* function. */
5464 static int (* get_next_element
[NUM_IT_METHODS
]) P_ ((struct it
*it
)) =
5466 next_element_from_buffer
,
5467 next_element_from_display_vector
,
5468 next_element_from_composition
,
5469 next_element_from_string
,
5470 next_element_from_c_string
,
5471 next_element_from_image
,
5472 next_element_from_stretch
5476 /* Load IT's display element fields with information about the next
5477 display element from the current position of IT. Value is zero if
5478 end of buffer (or C string) is reached. */
5480 static struct frame
*last_escape_glyph_frame
= NULL
;
5481 static unsigned last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
5482 static int last_escape_glyph_merged_face_id
= 0;
5485 get_next_display_element (it
)
5488 /* Non-zero means that we found a display element. Zero means that
5489 we hit the end of what we iterate over. Performance note: the
5490 function pointer `method' used here turns out to be faster than
5491 using a sequence of if-statements. */
5495 success_p
= (*get_next_element
[it
->method
]) (it
);
5497 if (it
->what
== IT_CHARACTER
)
5499 /* Map via display table or translate control characters.
5500 IT->c, IT->len etc. have been set to the next character by
5501 the function call above. If we have a display table, and it
5502 contains an entry for IT->c, translate it. Don't do this if
5503 IT->c itself comes from a display table, otherwise we could
5504 end up in an infinite recursion. (An alternative could be to
5505 count the recursion depth of this function and signal an
5506 error when a certain maximum depth is reached.) Is it worth
5508 if (success_p
&& it
->dpvec
== NULL
)
5513 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
5516 struct Lisp_Vector
*v
= XVECTOR (dv
);
5518 /* Return the first character from the display table
5519 entry, if not empty. If empty, don't display the
5520 current character. */
5523 it
->dpvec_char_len
= it
->len
;
5524 it
->dpvec
= v
->contents
;
5525 it
->dpend
= v
->contents
+ v
->size
;
5526 it
->current
.dpvec_index
= 0;
5527 it
->dpvec_face_id
= -1;
5528 it
->saved_face_id
= it
->face_id
;
5529 it
->method
= GET_FROM_DISPLAY_VECTOR
;
5534 set_iterator_to_next (it
, 0);
5539 /* Translate control characters into `\003' or `^C' form.
5540 Control characters coming from a display table entry are
5541 currently not translated because we use IT->dpvec to hold
5542 the translation. This could easily be changed but I
5543 don't believe that it is worth doing.
5545 If it->multibyte_p is nonzero, eight-bit characters and
5546 non-printable multibyte characters are also translated to
5549 If it->multibyte_p is zero, eight-bit characters that
5550 don't have corresponding multibyte char code are also
5551 translated to octal form. */
5552 else if ((it
->c
< ' '
5553 && (it
->area
!= TEXT_AREA
5554 /* In mode line, treat \n like other crl chars. */
5556 && it
->glyph_row
&& it
->glyph_row
->mode_line_p
)
5557 || (it
->c
!= '\n' && it
->c
!= '\t')))
5561 || !CHAR_PRINTABLE_P (it
->c
)
5562 || (!NILP (Vnobreak_char_display
)
5563 && (it
->c
== 0x8a0 || it
->c
== 0x8ad
5564 || it
->c
== 0x920 || it
->c
== 0x92d
5565 || it
->c
== 0xe20 || it
->c
== 0xe2d
5566 || it
->c
== 0xf20 || it
->c
== 0xf2d)))
5568 && (!unibyte_display_via_language_environment
5569 || it
->c
== unibyte_char_to_multibyte (it
->c
)))))
5571 /* IT->c is a control character which must be displayed
5572 either as '\003' or as `^C' where the '\\' and '^'
5573 can be defined in the display table. Fill
5574 IT->ctl_chars with glyphs for what we have to
5575 display. Then, set IT->dpvec to these glyphs. */
5578 int face_id
, lface_id
= 0 ;
5581 /* Handle control characters with ^. */
5583 if (it
->c
< 128 && it
->ctl_arrow_p
)
5585 g
= '^'; /* default glyph for Control */
5586 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5588 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
5589 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
5591 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
5592 lface_id
= FAST_GLYPH_FACE (g
);
5596 g
= FAST_GLYPH_CHAR (g
);
5597 face_id
= merge_faces (it
->f
, Qt
, lface_id
,
5600 else if (it
->f
== last_escape_glyph_frame
5601 && it
->face_id
== last_escape_glyph_face_id
)
5603 face_id
= last_escape_glyph_merged_face_id
;
5607 /* Merge the escape-glyph face into the current face. */
5608 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
5610 last_escape_glyph_frame
= it
->f
;
5611 last_escape_glyph_face_id
= it
->face_id
;
5612 last_escape_glyph_merged_face_id
= face_id
;
5615 XSETINT (it
->ctl_chars
[0], g
);
5617 XSETINT (it
->ctl_chars
[1], g
);
5619 goto display_control
;
5622 /* Handle non-break space in the mode where it only gets
5625 if (EQ (Vnobreak_char_display
, Qt
)
5626 && (it
->c
== 0x8a0 || it
->c
== 0x920
5627 || it
->c
== 0xe20 || it
->c
== 0xf20))
5629 /* Merge the no-break-space face into the current face. */
5630 face_id
= merge_faces (it
->f
, Qnobreak_space
, 0,
5634 XSETINT (it
->ctl_chars
[0], g
);
5636 goto display_control
;
5639 /* Handle sequences that start with the "escape glyph". */
5641 /* the default escape glyph is \. */
5642 escape_glyph
= '\\';
5645 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
5646 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
5648 escape_glyph
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
5649 lface_id
= FAST_GLYPH_FACE (escape_glyph
);
5653 /* The display table specified a face.
5654 Merge it into face_id and also into escape_glyph. */
5655 escape_glyph
= FAST_GLYPH_CHAR (escape_glyph
);
5656 face_id
= merge_faces (it
->f
, Qt
, lface_id
,
5659 else if (it
->f
== last_escape_glyph_frame
5660 && it
->face_id
== last_escape_glyph_face_id
)
5662 face_id
= last_escape_glyph_merged_face_id
;
5666 /* Merge the escape-glyph face into the current face. */
5667 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
5669 last_escape_glyph_frame
= it
->f
;
5670 last_escape_glyph_face_id
= it
->face_id
;
5671 last_escape_glyph_merged_face_id
= face_id
;
5674 /* Handle soft hyphens in the mode where they only get
5677 if (EQ (Vnobreak_char_display
, Qt
)
5678 && (it
->c
== 0x8ad || it
->c
== 0x92d
5679 || it
->c
== 0xe2d || it
->c
== 0xf2d))
5682 XSETINT (it
->ctl_chars
[0], g
);
5684 goto display_control
;
5687 /* Handle non-break space and soft hyphen
5688 with the escape glyph. */
5690 if (it
->c
== 0x8a0 || it
->c
== 0x8ad
5691 || it
->c
== 0x920 || it
->c
== 0x92d
5692 || it
->c
== 0xe20 || it
->c
== 0xe2d
5693 || it
->c
== 0xf20 || it
->c
== 0xf2d)
5695 XSETINT (it
->ctl_chars
[0], escape_glyph
);
5696 g
= it
->c
= ((it
->c
& 0xf) == 0 ? ' ' : '-');
5697 XSETINT (it
->ctl_chars
[1], g
);
5699 goto display_control
;
5703 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
5707 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5708 if (SINGLE_BYTE_CHAR_P (it
->c
))
5709 str
[0] = it
->c
, len
= 1;
5712 len
= CHAR_STRING_NO_SIGNAL (it
->c
, str
);
5715 /* It's an invalid character, which shouldn't
5716 happen actually, but due to bugs it may
5717 happen. Let's print the char as is, there's
5718 not much meaningful we can do with it. */
5720 str
[1] = it
->c
>> 8;
5721 str
[2] = it
->c
>> 16;
5722 str
[3] = it
->c
>> 24;
5727 for (i
= 0; i
< len
; i
++)
5729 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
5730 /* Insert three more glyphs into IT->ctl_chars for
5731 the octal display of the character. */
5732 g
= ((str
[i
] >> 6) & 7) + '0';
5733 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
5734 g
= ((str
[i
] >> 3) & 7) + '0';
5735 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
5736 g
= (str
[i
] & 7) + '0';
5737 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
5743 /* Set up IT->dpvec and return first character from it. */
5744 it
->dpvec_char_len
= it
->len
;
5745 it
->dpvec
= it
->ctl_chars
;
5746 it
->dpend
= it
->dpvec
+ ctl_len
;
5747 it
->current
.dpvec_index
= 0;
5748 it
->dpvec_face_id
= face_id
;
5749 it
->saved_face_id
= it
->face_id
;
5750 it
->method
= GET_FROM_DISPLAY_VECTOR
;
5756 /* Adjust face id for a multibyte character. There are no
5757 multibyte character in unibyte text. */
5760 && FRAME_WINDOW_P (it
->f
))
5762 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
5763 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
);
5767 /* Is this character the last one of a run of characters with
5768 box? If yes, set IT->end_of_box_run_p to 1. */
5775 it
->end_of_box_run_p
5776 = ((face_id
= face_after_it_pos (it
),
5777 face_id
!= it
->face_id
)
5778 && (face
= FACE_FROM_ID (it
->f
, face_id
),
5779 face
->box
== FACE_NO_BOX
));
5782 /* Value is 0 if end of buffer or string reached. */
5787 /* Move IT to the next display element.
5789 RESEAT_P non-zero means if called on a newline in buffer text,
5790 skip to the next visible line start.
5792 Functions get_next_display_element and set_iterator_to_next are
5793 separate because I find this arrangement easier to handle than a
5794 get_next_display_element function that also increments IT's
5795 position. The way it is we can first look at an iterator's current
5796 display element, decide whether it fits on a line, and if it does,
5797 increment the iterator position. The other way around we probably
5798 would either need a flag indicating whether the iterator has to be
5799 incremented the next time, or we would have to implement a
5800 decrement position function which would not be easy to write. */
5803 set_iterator_to_next (it
, reseat_p
)
5807 /* Reset flags indicating start and end of a sequence of characters
5808 with box. Reset them at the start of this function because
5809 moving the iterator to a new position might set them. */
5810 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
5814 case GET_FROM_BUFFER
:
5815 /* The current display element of IT is a character from
5816 current_buffer. Advance in the buffer, and maybe skip over
5817 invisible lines that are so because of selective display. */
5818 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
5819 reseat_at_next_visible_line_start (it
, 0);
5822 xassert (it
->len
!= 0);
5823 IT_BYTEPOS (*it
) += it
->len
;
5824 IT_CHARPOS (*it
) += 1;
5825 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
5829 case GET_FROM_COMPOSITION
:
5830 xassert (it
->cmp_id
>= 0 && it
->cmp_id
< n_compositions
);
5831 xassert (it
->sp
> 0);
5833 if (it
->method
== GET_FROM_STRING
)
5835 IT_STRING_BYTEPOS (*it
) += it
->len
;
5836 IT_STRING_CHARPOS (*it
) += it
->cmp_len
;
5837 goto consider_string_end
;
5839 else if (it
->method
== GET_FROM_BUFFER
)
5841 IT_BYTEPOS (*it
) += it
->len
;
5842 IT_CHARPOS (*it
) += it
->cmp_len
;
5846 case GET_FROM_C_STRING
:
5847 /* Current display element of IT is from a C string. */
5848 IT_BYTEPOS (*it
) += it
->len
;
5849 IT_CHARPOS (*it
) += 1;
5852 case GET_FROM_DISPLAY_VECTOR
:
5853 /* Current display element of IT is from a display table entry.
5854 Advance in the display table definition. Reset it to null if
5855 end reached, and continue with characters from buffers/
5857 ++it
->current
.dpvec_index
;
5859 /* Restore face of the iterator to what they were before the
5860 display vector entry (these entries may contain faces). */
5861 it
->face_id
= it
->saved_face_id
;
5863 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
5865 int recheck_faces
= it
->ellipsis_p
;
5868 it
->method
= GET_FROM_C_STRING
;
5869 else if (STRINGP (it
->string
))
5870 it
->method
= GET_FROM_STRING
;
5873 it
->method
= GET_FROM_BUFFER
;
5874 it
->object
= it
->w
->buffer
;
5878 it
->current
.dpvec_index
= -1;
5880 /* Skip over characters which were displayed via IT->dpvec. */
5881 if (it
->dpvec_char_len
< 0)
5882 reseat_at_next_visible_line_start (it
, 1);
5883 else if (it
->dpvec_char_len
> 0)
5885 if (it
->method
== GET_FROM_STRING
5886 && it
->n_overlay_strings
> 0)
5887 it
->ignore_overlay_strings_at_pos_p
= 1;
5888 it
->len
= it
->dpvec_char_len
;
5889 set_iterator_to_next (it
, reseat_p
);
5892 /* Maybe recheck faces after display vector */
5894 it
->stop_charpos
= IT_CHARPOS (*it
);
5898 case GET_FROM_STRING
:
5899 /* Current display element is a character from a Lisp string. */
5900 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
5901 IT_STRING_BYTEPOS (*it
) += it
->len
;
5902 IT_STRING_CHARPOS (*it
) += 1;
5904 consider_string_end
:
5906 if (it
->current
.overlay_string_index
>= 0)
5908 /* IT->string is an overlay string. Advance to the
5909 next, if there is one. */
5910 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5911 next_overlay_string (it
);
5915 /* IT->string is not an overlay string. If we reached
5916 its end, and there is something on IT->stack, proceed
5917 with what is on the stack. This can be either another
5918 string, this time an overlay string, or a buffer. */
5919 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
5923 if (it
->method
== GET_FROM_STRING
)
5924 goto consider_string_end
;
5929 case GET_FROM_IMAGE
:
5930 case GET_FROM_STRETCH
:
5931 /* The position etc with which we have to proceed are on
5932 the stack. The position may be at the end of a string,
5933 if the `display' property takes up the whole string. */
5934 xassert (it
->sp
> 0);
5936 if (it
->method
== GET_FROM_STRING
)
5937 goto consider_string_end
;
5941 /* There are no other methods defined, so this should be a bug. */
5945 xassert (it
->method
!= GET_FROM_STRING
5946 || (STRINGP (it
->string
)
5947 && IT_STRING_CHARPOS (*it
) >= 0));
5950 /* Load IT's display element fields with information about the next
5951 display element which comes from a display table entry or from the
5952 result of translating a control character to one of the forms `^C'
5955 IT->dpvec holds the glyphs to return as characters.
5956 IT->saved_face_id holds the face id before the display vector--
5957 it is restored into IT->face_idin set_iterator_to_next. */
5960 next_element_from_display_vector (it
)
5964 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
5966 it
->face_id
= it
->saved_face_id
;
5968 if (INTEGERP (*it
->dpvec
)
5969 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
5973 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
5974 it
->c
= FAST_GLYPH_CHAR (g
);
5975 it
->len
= CHAR_BYTES (it
->c
);
5977 /* The entry may contain a face id to use. Such a face id is
5978 the id of a Lisp face, not a realized face. A face id of
5979 zero means no face is specified. */
5980 if (it
->dpvec_face_id
>= 0)
5981 it
->face_id
= it
->dpvec_face_id
;
5984 int lface_id
= FAST_GLYPH_FACE (g
);
5986 it
->face_id
= merge_faces (it
->f
, Qt
, lface_id
,
5991 /* Display table entry is invalid. Return a space. */
5992 it
->c
= ' ', it
->len
= 1;
5994 /* Don't change position and object of the iterator here. They are
5995 still the values of the character that had this display table
5996 entry or was translated, and that's what we want. */
5997 it
->what
= IT_CHARACTER
;
6002 /* Load IT with the next display element from Lisp string IT->string.
6003 IT->current.string_pos is the current position within the string.
6004 If IT->current.overlay_string_index >= 0, the Lisp string is an
6008 next_element_from_string (it
)
6011 struct text_pos position
;
6013 xassert (STRINGP (it
->string
));
6014 xassert (IT_STRING_CHARPOS (*it
) >= 0);
6015 position
= it
->current
.string_pos
;
6017 /* Time to check for invisible text? */
6018 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
6019 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
6023 /* Since a handler may have changed IT->method, we must
6025 return get_next_display_element (it
);
6028 if (it
->current
.overlay_string_index
>= 0)
6030 /* Get the next character from an overlay string. In overlay
6031 strings, There is no field width or padding with spaces to
6033 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
6038 else if (STRING_MULTIBYTE (it
->string
))
6040 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
6041 const unsigned char *s
= (SDATA (it
->string
)
6042 + IT_STRING_BYTEPOS (*it
));
6043 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
6047 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
6053 /* Get the next character from a Lisp string that is not an
6054 overlay string. Such strings come from the mode line, for
6055 example. We may have to pad with spaces, or truncate the
6056 string. See also next_element_from_c_string. */
6057 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
6062 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
6064 /* Pad with spaces. */
6065 it
->c
= ' ', it
->len
= 1;
6066 CHARPOS (position
) = BYTEPOS (position
) = -1;
6068 else if (STRING_MULTIBYTE (it
->string
))
6070 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
6071 const unsigned char *s
= (SDATA (it
->string
)
6072 + IT_STRING_BYTEPOS (*it
));
6073 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
6077 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
6082 /* Record what we have and where it came from. */
6083 it
->what
= IT_CHARACTER
;
6084 it
->object
= it
->string
;
6085 it
->position
= position
;
6090 /* Load IT with next display element from C string IT->s.
6091 IT->string_nchars is the maximum number of characters to return
6092 from the string. IT->end_charpos may be greater than
6093 IT->string_nchars when this function is called, in which case we
6094 may have to return padding spaces. Value is zero if end of string
6095 reached, including padding spaces. */
6098 next_element_from_c_string (it
)
6104 it
->what
= IT_CHARACTER
;
6105 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
6108 /* IT's position can be greater IT->string_nchars in case a field
6109 width or precision has been specified when the iterator was
6111 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
6113 /* End of the game. */
6117 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
6119 /* Pad with spaces. */
6120 it
->c
= ' ', it
->len
= 1;
6121 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
6123 else if (it
->multibyte_p
)
6125 /* Implementation note: The calls to strlen apparently aren't a
6126 performance problem because there is no noticeable performance
6127 difference between Emacs running in unibyte or multibyte mode. */
6128 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
6129 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
6133 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
6139 /* Set up IT to return characters from an ellipsis, if appropriate.
6140 The definition of the ellipsis glyphs may come from a display table
6141 entry. This function Fills IT with the first glyph from the
6142 ellipsis if an ellipsis is to be displayed. */
6145 next_element_from_ellipsis (it
)
6148 if (it
->selective_display_ellipsis_p
)
6149 setup_for_ellipsis (it
, it
->len
);
6152 /* The face at the current position may be different from the
6153 face we find after the invisible text. Remember what it
6154 was in IT->saved_face_id, and signal that it's there by
6155 setting face_before_selective_p. */
6156 it
->saved_face_id
= it
->face_id
;
6157 it
->method
= GET_FROM_BUFFER
;
6158 it
->object
= it
->w
->buffer
;
6159 reseat_at_next_visible_line_start (it
, 1);
6160 it
->face_before_selective_p
= 1;
6163 return get_next_display_element (it
);
6167 /* Deliver an image display element. The iterator IT is already
6168 filled with image information (done in handle_display_prop). Value
6173 next_element_from_image (it
)
6176 it
->what
= IT_IMAGE
;
6181 /* Fill iterator IT with next display element from a stretch glyph
6182 property. IT->object is the value of the text property. Value is
6186 next_element_from_stretch (it
)
6189 it
->what
= IT_STRETCH
;
6194 /* Load IT with the next display element from current_buffer. Value
6195 is zero if end of buffer reached. IT->stop_charpos is the next
6196 position at which to stop and check for text properties or buffer
6200 next_element_from_buffer (it
)
6205 /* Check this assumption, otherwise, we would never enter the
6206 if-statement, below. */
6207 xassert (IT_CHARPOS (*it
) >= BEGV
6208 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
6210 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
6212 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
6214 int overlay_strings_follow_p
;
6216 /* End of the game, except when overlay strings follow that
6217 haven't been returned yet. */
6218 if (it
->overlay_strings_at_end_processed_p
)
6219 overlay_strings_follow_p
= 0;
6222 it
->overlay_strings_at_end_processed_p
= 1;
6223 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
6226 if (overlay_strings_follow_p
)
6227 success_p
= get_next_display_element (it
);
6231 it
->position
= it
->current
.pos
;
6238 return get_next_display_element (it
);
6243 /* No face changes, overlays etc. in sight, so just return a
6244 character from current_buffer. */
6247 /* Maybe run the redisplay end trigger hook. Performance note:
6248 This doesn't seem to cost measurable time. */
6249 if (it
->redisplay_end_trigger_charpos
6251 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
6252 run_redisplay_end_trigger_hook (it
);
6254 /* Get the next character, maybe multibyte. */
6255 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
6256 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
6258 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
6259 - IT_BYTEPOS (*it
));
6260 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
6263 it
->c
= *p
, it
->len
= 1;
6265 /* Record what we have and where it came from. */
6266 it
->what
= IT_CHARACTER
;;
6267 it
->object
= it
->w
->buffer
;
6268 it
->position
= it
->current
.pos
;
6270 /* Normally we return the character found above, except when we
6271 really want to return an ellipsis for selective display. */
6276 /* A value of selective > 0 means hide lines indented more
6277 than that number of columns. */
6278 if (it
->selective
> 0
6279 && IT_CHARPOS (*it
) + 1 < ZV
6280 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
6281 IT_BYTEPOS (*it
) + 1,
6282 (double) it
->selective
)) /* iftc */
6284 success_p
= next_element_from_ellipsis (it
);
6285 it
->dpvec_char_len
= -1;
6288 else if (it
->c
== '\r' && it
->selective
== -1)
6290 /* A value of selective == -1 means that everything from the
6291 CR to the end of the line is invisible, with maybe an
6292 ellipsis displayed for it. */
6293 success_p
= next_element_from_ellipsis (it
);
6294 it
->dpvec_char_len
= -1;
6299 /* Value is zero if end of buffer reached. */
6300 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
6305 /* Run the redisplay end trigger hook for IT. */
6308 run_redisplay_end_trigger_hook (it
)
6311 Lisp_Object args
[3];
6313 /* IT->glyph_row should be non-null, i.e. we should be actually
6314 displaying something, or otherwise we should not run the hook. */
6315 xassert (it
->glyph_row
);
6317 /* Set up hook arguments. */
6318 args
[0] = Qredisplay_end_trigger_functions
;
6319 args
[1] = it
->window
;
6320 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
6321 it
->redisplay_end_trigger_charpos
= 0;
6323 /* Since we are *trying* to run these functions, don't try to run
6324 them again, even if they get an error. */
6325 it
->w
->redisplay_end_trigger
= Qnil
;
6326 Frun_hook_with_args (3, args
);
6328 /* Notice if it changed the face of the character we are on. */
6329 handle_face_prop (it
);
6333 /* Deliver a composition display element. The iterator IT is already
6334 filled with composition information (done in
6335 handle_composition_prop). Value is always 1. */
6338 next_element_from_composition (it
)
6341 it
->what
= IT_COMPOSITION
;
6342 it
->position
= (STRINGP (it
->string
)
6343 ? it
->current
.string_pos
6345 if (STRINGP (it
->string
))
6346 it
->object
= it
->string
;
6348 it
->object
= it
->w
->buffer
;
6354 /***********************************************************************
6355 Moving an iterator without producing glyphs
6356 ***********************************************************************/
6358 /* Check if iterator is at a position corresponding to a valid buffer
6359 position after some move_it_ call. */
6361 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6362 ((it)->method == GET_FROM_STRING \
6363 ? IT_STRING_CHARPOS (*it) == 0 \
6367 /* Move iterator IT to a specified buffer or X position within one
6368 line on the display without producing glyphs.
6370 OP should be a bit mask including some or all of these bits:
6371 MOVE_TO_X: Stop on reaching x-position TO_X.
6372 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6373 Regardless of OP's value, stop in reaching the end of the display line.
6375 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6376 This means, in particular, that TO_X includes window's horizontal
6379 The return value has several possible values that
6380 say what condition caused the scan to stop:
6382 MOVE_POS_MATCH_OR_ZV
6383 - when TO_POS or ZV was reached.
6386 -when TO_X was reached before TO_POS or ZV were reached.
6389 - when we reached the end of the display area and the line must
6393 - when we reached the end of the display area and the line is
6397 - when we stopped at a line end, i.e. a newline or a CR and selective
6400 static enum move_it_result
6401 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
6403 int to_charpos
, to_x
, op
;
6405 enum move_it_result result
= MOVE_UNDEFINED
;
6406 struct glyph_row
*saved_glyph_row
;
6408 /* Don't produce glyphs in produce_glyphs. */
6409 saved_glyph_row
= it
->glyph_row
;
6410 it
->glyph_row
= NULL
;
6412 #define BUFFER_POS_REACHED_P() \
6413 ((op & MOVE_TO_POS) != 0 \
6414 && BUFFERP (it->object) \
6415 && IT_CHARPOS (*it) >= to_charpos \
6416 && (it->method == GET_FROM_BUFFER \
6417 || (it->method == GET_FROM_DISPLAY_VECTOR \
6418 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6423 int x
, i
, ascent
= 0, descent
= 0;
6425 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
6426 if ((op
& MOVE_TO_POS
) != 0
6427 && BUFFERP (it
->object
)
6428 && it
->method
== GET_FROM_BUFFER
6429 && IT_CHARPOS (*it
) > to_charpos
)
6431 result
= MOVE_POS_MATCH_OR_ZV
;
6435 /* Stop when ZV reached.
6436 We used to stop here when TO_CHARPOS reached as well, but that is
6437 too soon if this glyph does not fit on this line. So we handle it
6438 explicitly below. */
6439 if (!get_next_display_element (it
)
6440 || (it
->truncate_lines_p
6441 && BUFFER_POS_REACHED_P ()))
6443 result
= MOVE_POS_MATCH_OR_ZV
;
6447 /* The call to produce_glyphs will get the metrics of the
6448 display element IT is loaded with. We record in x the
6449 x-position before this display element in case it does not
6453 /* Remember the line height so far in case the next element doesn't
6455 if (!it
->truncate_lines_p
)
6457 ascent
= it
->max_ascent
;
6458 descent
= it
->max_descent
;
6461 PRODUCE_GLYPHS (it
);
6463 if (it
->area
!= TEXT_AREA
)
6465 set_iterator_to_next (it
, 1);
6469 /* The number of glyphs we get back in IT->nglyphs will normally
6470 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6471 character on a terminal frame, or (iii) a line end. For the
6472 second case, IT->nglyphs - 1 padding glyphs will be present
6473 (on X frames, there is only one glyph produced for a
6474 composite character.
6476 The behavior implemented below means, for continuation lines,
6477 that as many spaces of a TAB as fit on the current line are
6478 displayed there. For terminal frames, as many glyphs of a
6479 multi-glyph character are displayed in the current line, too.
6480 This is what the old redisplay code did, and we keep it that
6481 way. Under X, the whole shape of a complex character must
6482 fit on the line or it will be completely displayed in the
6485 Note that both for tabs and padding glyphs, all glyphs have
6489 /* More than one glyph or glyph doesn't fit on line. All
6490 glyphs have the same width. */
6491 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
6493 int x_before_this_char
= x
;
6494 int hpos_before_this_char
= it
->hpos
;
6496 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
6498 new_x
= x
+ single_glyph_width
;
6500 /* We want to leave anything reaching TO_X to the caller. */
6501 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
6503 if (BUFFER_POS_REACHED_P ())
6504 goto buffer_pos_reached
;
6506 result
= MOVE_X_REACHED
;
6509 else if (/* Lines are continued. */
6510 !it
->truncate_lines_p
6511 && (/* And glyph doesn't fit on the line. */
6512 new_x
> it
->last_visible_x
6513 /* Or it fits exactly and we're on a window
6515 || (new_x
== it
->last_visible_x
6516 && FRAME_WINDOW_P (it
->f
))))
6518 if (/* IT->hpos == 0 means the very first glyph
6519 doesn't fit on the line, e.g. a wide image. */
6521 || (new_x
== it
->last_visible_x
6522 && FRAME_WINDOW_P (it
->f
)))
6525 it
->current_x
= new_x
;
6527 /* The character's last glyph just barely fits
6529 if (i
== it
->nglyphs
- 1)
6531 /* If this is the destination position,
6532 return a position *before* it in this row,
6533 now that we know it fits in this row. */
6534 if (BUFFER_POS_REACHED_P ())
6536 it
->hpos
= hpos_before_this_char
;
6537 it
->current_x
= x_before_this_char
;
6538 result
= MOVE_POS_MATCH_OR_ZV
;
6542 set_iterator_to_next (it
, 1);
6543 #ifdef HAVE_WINDOW_SYSTEM
6544 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
6546 if (!get_next_display_element (it
))
6548 result
= MOVE_POS_MATCH_OR_ZV
;
6551 if (BUFFER_POS_REACHED_P ())
6553 if (ITERATOR_AT_END_OF_LINE_P (it
))
6554 result
= MOVE_POS_MATCH_OR_ZV
;
6556 result
= MOVE_LINE_CONTINUED
;
6559 if (ITERATOR_AT_END_OF_LINE_P (it
))
6561 result
= MOVE_NEWLINE_OR_CR
;
6565 #endif /* HAVE_WINDOW_SYSTEM */
6571 it
->max_ascent
= ascent
;
6572 it
->max_descent
= descent
;
6575 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
6577 result
= MOVE_LINE_CONTINUED
;
6580 else if (BUFFER_POS_REACHED_P ())
6581 goto buffer_pos_reached
;
6582 else if (new_x
> it
->first_visible_x
)
6584 /* Glyph is visible. Increment number of glyphs that
6585 would be displayed. */
6590 /* Glyph is completely off the left margin of the display
6591 area. Nothing to do. */
6595 if (result
!= MOVE_UNDEFINED
)
6598 else if (BUFFER_POS_REACHED_P ())
6602 it
->max_ascent
= ascent
;
6603 it
->max_descent
= descent
;
6604 result
= MOVE_POS_MATCH_OR_ZV
;
6607 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
6609 /* Stop when TO_X specified and reached. This check is
6610 necessary here because of lines consisting of a line end,
6611 only. The line end will not produce any glyphs and we
6612 would never get MOVE_X_REACHED. */
6613 xassert (it
->nglyphs
== 0);
6614 result
= MOVE_X_REACHED
;
6618 /* Is this a line end? If yes, we're done. */
6619 if (ITERATOR_AT_END_OF_LINE_P (it
))
6621 result
= MOVE_NEWLINE_OR_CR
;
6625 /* The current display element has been consumed. Advance
6627 set_iterator_to_next (it
, 1);
6629 /* Stop if lines are truncated and IT's current x-position is
6630 past the right edge of the window now. */
6631 if (it
->truncate_lines_p
6632 && it
->current_x
>= it
->last_visible_x
)
6634 #ifdef HAVE_WINDOW_SYSTEM
6635 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
6637 if (!get_next_display_element (it
)
6638 || BUFFER_POS_REACHED_P ())
6640 result
= MOVE_POS_MATCH_OR_ZV
;
6643 if (ITERATOR_AT_END_OF_LINE_P (it
))
6645 result
= MOVE_NEWLINE_OR_CR
;
6649 #endif /* HAVE_WINDOW_SYSTEM */
6650 result
= MOVE_LINE_TRUNCATED
;
6655 #undef BUFFER_POS_REACHED_P
6657 /* Restore the iterator settings altered at the beginning of this
6659 it
->glyph_row
= saved_glyph_row
;
6664 /* Move IT forward until it satisfies one or more of the criteria in
6665 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6667 OP is a bit-mask that specifies where to stop, and in particular,
6668 which of those four position arguments makes a difference. See the
6669 description of enum move_operation_enum.
6671 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6672 screen line, this function will set IT to the next position >
6676 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
6678 int to_charpos
, to_x
, to_y
, to_vpos
;
6681 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
6687 if (op
& MOVE_TO_VPOS
)
6689 /* If no TO_CHARPOS and no TO_X specified, stop at the
6690 start of the line TO_VPOS. */
6691 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
6693 if (it
->vpos
== to_vpos
)
6699 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
6703 /* TO_VPOS >= 0 means stop at TO_X in the line at
6704 TO_VPOS, or at TO_POS, whichever comes first. */
6705 if (it
->vpos
== to_vpos
)
6711 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
6713 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
6718 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
6720 /* We have reached TO_X but not in the line we want. */
6721 skip
= move_it_in_display_line_to (it
, to_charpos
,
6723 if (skip
== MOVE_POS_MATCH_OR_ZV
)
6731 else if (op
& MOVE_TO_Y
)
6733 struct it it_backup
;
6735 /* TO_Y specified means stop at TO_X in the line containing
6736 TO_Y---or at TO_CHARPOS if this is reached first. The
6737 problem is that we can't really tell whether the line
6738 contains TO_Y before we have completely scanned it, and
6739 this may skip past TO_X. What we do is to first scan to
6742 If TO_X is not specified, use a TO_X of zero. The reason
6743 is to make the outcome of this function more predictable.
6744 If we didn't use TO_X == 0, we would stop at the end of
6745 the line which is probably not what a caller would expect
6747 skip
= move_it_in_display_line_to (it
, to_charpos
,
6751 | (op
& MOVE_TO_POS
)));
6753 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6754 if (skip
== MOVE_POS_MATCH_OR_ZV
)
6760 /* If TO_X was reached, we would like to know whether TO_Y
6761 is in the line. This can only be said if we know the
6762 total line height which requires us to scan the rest of
6764 if (skip
== MOVE_X_REACHED
)
6767 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
6768 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
6770 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
6773 /* Now, decide whether TO_Y is in this line. */
6774 line_height
= it
->max_ascent
+ it
->max_descent
;
6775 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
6777 if (to_y
>= it
->current_y
6778 && to_y
< it
->current_y
+ line_height
)
6780 if (skip
== MOVE_X_REACHED
)
6781 /* If TO_Y is in this line and TO_X was reached above,
6782 we scanned too far. We have to restore IT's settings
6783 to the ones before skipping. */
6787 else if (skip
== MOVE_X_REACHED
)
6790 if (skip
== MOVE_POS_MATCH_OR_ZV
)
6797 else if (BUFFERP (it
->object
)
6798 && it
->method
== GET_FROM_BUFFER
6799 && IT_CHARPOS (*it
) >= to_charpos
)
6800 skip
= MOVE_POS_MATCH_OR_ZV
;
6802 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
6806 case MOVE_POS_MATCH_OR_ZV
:
6810 case MOVE_NEWLINE_OR_CR
:
6811 set_iterator_to_next (it
, 1);
6812 it
->continuation_lines_width
= 0;
6815 case MOVE_LINE_TRUNCATED
:
6816 it
->continuation_lines_width
= 0;
6817 reseat_at_next_visible_line_start (it
, 0);
6818 if ((op
& MOVE_TO_POS
) != 0
6819 && IT_CHARPOS (*it
) > to_charpos
)
6826 case MOVE_LINE_CONTINUED
:
6827 it
->continuation_lines_width
+= it
->current_x
;
6834 /* Reset/increment for the next run. */
6835 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
6836 it
->current_x
= it
->hpos
= 0;
6837 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
6839 last_height
= it
->max_ascent
+ it
->max_descent
;
6840 last_max_ascent
= it
->max_ascent
;
6841 it
->max_ascent
= it
->max_descent
= 0;
6846 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
6850 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6852 If DY > 0, move IT backward at least that many pixels. DY = 0
6853 means move IT backward to the preceding line start or BEGV. This
6854 function may move over more than DY pixels if IT->current_y - DY
6855 ends up in the middle of a line; in this case IT->current_y will be
6856 set to the top of the line moved to. */
6859 move_it_vertically_backward (it
, dy
)
6870 start_pos
= IT_CHARPOS (*it
);
6872 /* Estimate how many newlines we must move back. */
6873 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
6875 /* Set the iterator's position that many lines back. */
6876 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
6877 back_to_previous_visible_line_start (it
);
6879 /* Reseat the iterator here. When moving backward, we don't want
6880 reseat to skip forward over invisible text, set up the iterator
6881 to deliver from overlay strings at the new position etc. So,
6882 use reseat_1 here. */
6883 reseat_1 (it
, it
->current
.pos
, 1);
6885 /* We are now surely at a line start. */
6886 it
->current_x
= it
->hpos
= 0;
6887 it
->continuation_lines_width
= 0;
6889 /* Move forward and see what y-distance we moved. First move to the
6890 start of the next line so that we get its height. We need this
6891 height to be able to tell whether we reached the specified
6894 it2
.max_ascent
= it2
.max_descent
= 0;
6897 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
6898 MOVE_TO_POS
| MOVE_TO_VPOS
);
6900 while (!IT_POS_VALID_AFTER_MOVE_P (&it2
));
6901 xassert (IT_CHARPOS (*it
) >= BEGV
);
6904 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
6905 xassert (IT_CHARPOS (*it
) >= BEGV
);
6906 /* H is the actual vertical distance from the position in *IT
6907 and the starting position. */
6908 h
= it2
.current_y
- it
->current_y
;
6909 /* NLINES is the distance in number of lines. */
6910 nlines
= it2
.vpos
- it
->vpos
;
6912 /* Correct IT's y and vpos position
6913 so that they are relative to the starting point. */
6919 /* DY == 0 means move to the start of the screen line. The
6920 value of nlines is > 0 if continuation lines were involved. */
6922 move_it_by_lines (it
, nlines
, 1);
6924 /* I think this assert is bogus if buffer contains
6925 invisible text or images. KFS. */
6926 xassert (IT_CHARPOS (*it
) <= start_pos
);
6931 /* The y-position we try to reach, relative to *IT.
6932 Note that H has been subtracted in front of the if-statement. */
6933 int target_y
= it
->current_y
+ h
- dy
;
6934 int y0
= it3
.current_y
;
6935 int y1
= line_bottom_y (&it3
);
6936 int line_height
= y1
- y0
;
6938 /* If we did not reach target_y, try to move further backward if
6939 we can. If we moved too far backward, try to move forward. */
6940 if (target_y
< it
->current_y
6941 /* This is heuristic. In a window that's 3 lines high, with
6942 a line height of 13 pixels each, recentering with point
6943 on the bottom line will try to move -39/2 = 19 pixels
6944 backward. Try to avoid moving into the first line. */
6945 && (it
->current_y
- target_y
6946 > min (window_box_height (it
->w
), line_height
* 2 / 3))
6947 && IT_CHARPOS (*it
) > BEGV
)
6949 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
6950 target_y
- it
->current_y
));
6951 dy
= it
->current_y
- target_y
;
6952 goto move_further_back
;
6954 else if (target_y
>= it
->current_y
+ line_height
6955 && IT_CHARPOS (*it
) < ZV
)
6957 /* Should move forward by at least one line, maybe more.
6959 Note: Calling move_it_by_lines can be expensive on
6960 terminal frames, where compute_motion is used (via
6961 vmotion) to do the job, when there are very long lines
6962 and truncate-lines is nil. That's the reason for
6963 treating terminal frames specially here. */
6965 if (!FRAME_WINDOW_P (it
->f
))
6966 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
6971 move_it_by_lines (it
, 1, 1);
6973 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
6977 /* I think this assert is bogus if buffer contains
6978 invisible text or images. KFS. */
6979 xassert (IT_CHARPOS (*it
) >= BEGV
);
6986 /* Move IT by a specified amount of pixel lines DY. DY negative means
6987 move backwards. DY = 0 means move to start of screen line. At the
6988 end, IT will be on the start of a screen line. */
6991 move_it_vertically (it
, dy
)
6996 move_it_vertically_backward (it
, -dy
);
6999 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
7000 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
7001 MOVE_TO_POS
| MOVE_TO_Y
);
7002 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
7004 /* If buffer ends in ZV without a newline, move to the start of
7005 the line to satisfy the post-condition. */
7006 if (IT_CHARPOS (*it
) == ZV
7008 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
7009 move_it_by_lines (it
, 0, 0);
7014 /* Move iterator IT past the end of the text line it is in. */
7017 move_it_past_eol (it
)
7020 enum move_it_result rc
;
7022 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
7023 if (rc
== MOVE_NEWLINE_OR_CR
)
7024 set_iterator_to_next (it
, 0);
7028 #if 0 /* Currently not used. */
7030 /* Return non-zero if some text between buffer positions START_CHARPOS
7031 and END_CHARPOS is invisible. IT->window is the window for text
7035 invisible_text_between_p (it
, start_charpos
, end_charpos
)
7037 int start_charpos
, end_charpos
;
7039 Lisp_Object prop
, limit
;
7040 int invisible_found_p
;
7042 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
7044 /* Is text at START invisible? */
7045 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
7047 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
7048 invisible_found_p
= 1;
7051 limit
= Fnext_single_char_property_change (make_number (start_charpos
),
7053 make_number (end_charpos
));
7054 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
7057 return invisible_found_p
;
7063 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7064 negative means move up. DVPOS == 0 means move to the start of the
7065 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7066 NEED_Y_P is zero, IT->current_y will be left unchanged.
7068 Further optimization ideas: If we would know that IT->f doesn't use
7069 a face with proportional font, we could be faster for
7070 truncate-lines nil. */
7073 move_it_by_lines (it
, dvpos
, need_y_p
)
7075 int dvpos
, need_y_p
;
7077 struct position pos
;
7079 if (!FRAME_WINDOW_P (it
->f
))
7081 struct text_pos textpos
;
7083 /* We can use vmotion on frames without proportional fonts. */
7084 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
7085 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
7086 reseat (it
, textpos
, 1);
7087 it
->vpos
+= pos
.vpos
;
7088 it
->current_y
+= pos
.vpos
;
7090 else if (dvpos
== 0)
7092 /* DVPOS == 0 means move to the start of the screen line. */
7093 move_it_vertically_backward (it
, 0);
7094 xassert (it
->current_x
== 0 && it
->hpos
== 0);
7095 /* Let next call to line_bottom_y calculate real line height */
7100 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
7101 if (!IT_POS_VALID_AFTER_MOVE_P (it
))
7102 move_it_to (it
, IT_CHARPOS (*it
) + 1, -1, -1, -1, MOVE_TO_POS
);
7107 int start_charpos
, i
;
7109 /* Start at the beginning of the screen line containing IT's
7110 position. This may actually move vertically backwards,
7111 in case of overlays, so adjust dvpos accordingly. */
7113 move_it_vertically_backward (it
, 0);
7116 /* Go back -DVPOS visible lines and reseat the iterator there. */
7117 start_charpos
= IT_CHARPOS (*it
);
7118 for (i
= -dvpos
; i
> 0 && IT_CHARPOS (*it
) > BEGV
; --i
)
7119 back_to_previous_visible_line_start (it
);
7120 reseat (it
, it
->current
.pos
, 1);
7122 /* Move further back if we end up in a string or an image. */
7123 while (!IT_POS_VALID_AFTER_MOVE_P (it
))
7125 /* First try to move to start of display line. */
7127 move_it_vertically_backward (it
, 0);
7129 if (IT_POS_VALID_AFTER_MOVE_P (it
))
7131 /* If start of line is still in string or image,
7132 move further back. */
7133 back_to_previous_visible_line_start (it
);
7134 reseat (it
, it
->current
.pos
, 1);
7138 it
->current_x
= it
->hpos
= 0;
7140 /* Above call may have moved too far if continuation lines
7141 are involved. Scan forward and see if it did. */
7143 it2
.vpos
= it2
.current_y
= 0;
7144 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
7145 it
->vpos
-= it2
.vpos
;
7146 it
->current_y
-= it2
.current_y
;
7147 it
->current_x
= it
->hpos
= 0;
7149 /* If we moved too far back, move IT some lines forward. */
7150 if (it2
.vpos
> -dvpos
)
7152 int delta
= it2
.vpos
+ dvpos
;
7154 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
7155 /* Move back again if we got too far ahead. */
7156 if (IT_CHARPOS (*it
) >= start_charpos
)
7162 /* Return 1 if IT points into the middle of a display vector. */
7165 in_display_vector_p (it
)
7168 return (it
->method
== GET_FROM_DISPLAY_VECTOR
7169 && it
->current
.dpvec_index
> 0
7170 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
7174 /***********************************************************************
7176 ***********************************************************************/
7179 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7183 add_to_log (format
, arg1
, arg2
)
7185 Lisp_Object arg1
, arg2
;
7187 Lisp_Object args
[3];
7188 Lisp_Object msg
, fmt
;
7191 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
7194 /* Do nothing if called asynchronously. Inserting text into
7195 a buffer may call after-change-functions and alike and
7196 that would means running Lisp asynchronously. */
7197 if (handling_signal
)
7201 GCPRO4 (fmt
, msg
, arg1
, arg2
);
7203 args
[0] = fmt
= build_string (format
);
7206 msg
= Fformat (3, args
);
7208 len
= SBYTES (msg
) + 1;
7209 SAFE_ALLOCA (buffer
, char *, len
);
7210 bcopy (SDATA (msg
), buffer
, len
);
7212 message_dolog (buffer
, len
- 1, 1, 0);
7219 /* Output a newline in the *Messages* buffer if "needs" one. */
7222 message_log_maybe_newline ()
7224 if (message_log_need_newline
)
7225 message_dolog ("", 0, 1, 0);
7229 /* Add a string M of length NBYTES to the message log, optionally
7230 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7231 nonzero, means interpret the contents of M as multibyte. This
7232 function calls low-level routines in order to bypass text property
7233 hooks, etc. which might not be safe to run.
7235 This may GC (insert may run before/after change hooks),
7236 so the buffer M must NOT point to a Lisp string. */
7239 message_dolog (m
, nbytes
, nlflag
, multibyte
)
7241 int nbytes
, nlflag
, multibyte
;
7243 if (!NILP (Vmemory_full
))
7246 if (!NILP (Vmessage_log_max
))
7248 struct buffer
*oldbuf
;
7249 Lisp_Object oldpoint
, oldbegv
, oldzv
;
7250 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
7251 int point_at_end
= 0;
7253 Lisp_Object old_deactivate_mark
, tem
;
7254 struct gcpro gcpro1
;
7256 old_deactivate_mark
= Vdeactivate_mark
;
7257 oldbuf
= current_buffer
;
7258 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
7259 current_buffer
->undo_list
= Qt
;
7261 oldpoint
= message_dolog_marker1
;
7262 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
7263 oldbegv
= message_dolog_marker2
;
7264 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
7265 oldzv
= message_dolog_marker3
;
7266 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
7267 GCPRO1 (old_deactivate_mark
);
7275 BEGV_BYTE
= BEG_BYTE
;
7278 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
7280 /* Insert the string--maybe converting multibyte to single byte
7281 or vice versa, so that all the text fits the buffer. */
7283 && NILP (current_buffer
->enable_multibyte_characters
))
7285 int i
, c
, char_bytes
;
7286 unsigned char work
[1];
7288 /* Convert a multibyte string to single-byte
7289 for the *Message* buffer. */
7290 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
7292 c
= string_char_and_length (m
+ i
, nbytes
- i
, &char_bytes
);
7293 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
7295 : multibyte_char_to_unibyte (c
, Qnil
));
7296 insert_1_both (work
, 1, 1, 1, 0, 0);
7299 else if (! multibyte
7300 && ! NILP (current_buffer
->enable_multibyte_characters
))
7302 int i
, c
, char_bytes
;
7303 unsigned char *msg
= (unsigned char *) m
;
7304 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
7305 /* Convert a single-byte string to multibyte
7306 for the *Message* buffer. */
7307 for (i
= 0; i
< nbytes
; i
++)
7309 c
= unibyte_char_to_multibyte (msg
[i
]);
7310 char_bytes
= CHAR_STRING (c
, str
);
7311 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
7315 insert_1 (m
, nbytes
, 1, 0, 0);
7319 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
7320 insert_1 ("\n", 1, 1, 0, 0);
7322 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
7324 this_bol_byte
= PT_BYTE
;
7326 /* See if this line duplicates the previous one.
7327 If so, combine duplicates. */
7330 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
7332 prev_bol_byte
= PT_BYTE
;
7334 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
7335 this_bol
, this_bol_byte
);
7338 del_range_both (prev_bol
, prev_bol_byte
,
7339 this_bol
, this_bol_byte
, 0);
7345 /* If you change this format, don't forget to also
7346 change message_log_check_duplicate. */
7347 sprintf (dupstr
, " [%d times]", dup
);
7348 duplen
= strlen (dupstr
);
7349 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
7350 insert_1 (dupstr
, duplen
, 1, 0, 1);
7355 /* If we have more than the desired maximum number of lines
7356 in the *Messages* buffer now, delete the oldest ones.
7357 This is safe because we don't have undo in this buffer. */
7359 if (NATNUMP (Vmessage_log_max
))
7361 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
7362 -XFASTINT (Vmessage_log_max
) - 1, 0);
7363 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
7366 BEGV
= XMARKER (oldbegv
)->charpos
;
7367 BEGV_BYTE
= marker_byte_position (oldbegv
);
7376 ZV
= XMARKER (oldzv
)->charpos
;
7377 ZV_BYTE
= marker_byte_position (oldzv
);
7381 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
7383 /* We can't do Fgoto_char (oldpoint) because it will run some
7385 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
7386 XMARKER (oldpoint
)->bytepos
);
7389 unchain_marker (XMARKER (oldpoint
));
7390 unchain_marker (XMARKER (oldbegv
));
7391 unchain_marker (XMARKER (oldzv
));
7393 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
7394 set_buffer_internal (oldbuf
);
7396 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
7397 message_log_need_newline
= !nlflag
;
7398 Vdeactivate_mark
= old_deactivate_mark
;
7403 /* We are at the end of the buffer after just having inserted a newline.
7404 (Note: We depend on the fact we won't be crossing the gap.)
7405 Check to see if the most recent message looks a lot like the previous one.
7406 Return 0 if different, 1 if the new one should just replace it, or a
7407 value N > 1 if we should also append " [N times]". */
7410 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
7411 int prev_bol
, this_bol
;
7412 int prev_bol_byte
, this_bol_byte
;
7415 int len
= Z_BYTE
- 1 - this_bol_byte
;
7417 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
7418 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
7420 for (i
= 0; i
< len
; i
++)
7422 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
7430 if (*p1
++ == ' ' && *p1
++ == '[')
7433 while (*p1
>= '0' && *p1
<= '9')
7434 n
= n
* 10 + *p1
++ - '0';
7435 if (strncmp (p1
, " times]\n", 8) == 0)
7442 /* Display an echo area message M with a specified length of NBYTES
7443 bytes. The string may include null characters. If M is 0, clear
7444 out any existing message, and let the mini-buffer text show
7447 This may GC, so the buffer M must NOT point to a Lisp string. */
7450 message2 (m
, nbytes
, multibyte
)
7455 /* First flush out any partial line written with print. */
7456 message_log_maybe_newline ();
7458 message_dolog (m
, nbytes
, 1, multibyte
);
7459 message2_nolog (m
, nbytes
, multibyte
);
7463 /* The non-logging counterpart of message2. */
7466 message2_nolog (m
, nbytes
, multibyte
)
7468 int nbytes
, multibyte
;
7470 struct frame
*sf
= SELECTED_FRAME ();
7471 message_enable_multibyte
= multibyte
;
7475 if (noninteractive_need_newline
)
7476 putc ('\n', stderr
);
7477 noninteractive_need_newline
= 0;
7479 fwrite (m
, nbytes
, 1, stderr
);
7480 if (cursor_in_echo_area
== 0)
7481 fprintf (stderr
, "\n");
7484 /* A null message buffer means that the frame hasn't really been
7485 initialized yet. Error messages get reported properly by
7486 cmd_error, so this must be just an informative message; toss it. */
7487 else if (INTERACTIVE
7488 && sf
->glyphs_initialized_p
7489 && FRAME_MESSAGE_BUF (sf
))
7491 Lisp_Object mini_window
;
7494 /* Get the frame containing the mini-buffer
7495 that the selected frame is using. */
7496 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7497 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
7499 FRAME_SAMPLE_VISIBILITY (f
);
7500 if (FRAME_VISIBLE_P (sf
)
7501 && ! FRAME_VISIBLE_P (f
))
7502 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
7506 set_message (m
, Qnil
, nbytes
, multibyte
);
7507 if (minibuffer_auto_raise
)
7508 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
7511 clear_message (1, 1);
7513 do_pending_window_change (0);
7514 echo_area_display (1);
7515 do_pending_window_change (0);
7516 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
7517 (*frame_up_to_date_hook
) (f
);
7522 /* Display an echo area message M with a specified length of NBYTES
7523 bytes. The string may include null characters. If M is not a
7524 string, clear out any existing message, and let the mini-buffer
7527 This function cancels echoing. */
7530 message3 (m
, nbytes
, multibyte
)
7535 struct gcpro gcpro1
;
7538 clear_message (1,1);
7541 /* First flush out any partial line written with print. */
7542 message_log_maybe_newline ();
7548 SAFE_ALLOCA (buffer
, char *, nbytes
);
7549 bcopy (SDATA (m
), buffer
, nbytes
);
7550 message_dolog (buffer
, nbytes
, 1, multibyte
);
7553 message3_nolog (m
, nbytes
, multibyte
);
7559 /* The non-logging version of message3.
7560 This does not cancel echoing, because it is used for echoing.
7561 Perhaps we need to make a separate function for echoing
7562 and make this cancel echoing. */
7565 message3_nolog (m
, nbytes
, multibyte
)
7567 int nbytes
, multibyte
;
7569 struct frame
*sf
= SELECTED_FRAME ();
7570 message_enable_multibyte
= multibyte
;
7574 if (noninteractive_need_newline
)
7575 putc ('\n', stderr
);
7576 noninteractive_need_newline
= 0;
7578 fwrite (SDATA (m
), nbytes
, 1, stderr
);
7579 if (cursor_in_echo_area
== 0)
7580 fprintf (stderr
, "\n");
7583 /* A null message buffer means that the frame hasn't really been
7584 initialized yet. Error messages get reported properly by
7585 cmd_error, so this must be just an informative message; toss it. */
7586 else if (INTERACTIVE
7587 && sf
->glyphs_initialized_p
7588 && FRAME_MESSAGE_BUF (sf
))
7590 Lisp_Object mini_window
;
7594 /* Get the frame containing the mini-buffer
7595 that the selected frame is using. */
7596 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7597 frame
= XWINDOW (mini_window
)->frame
;
7600 FRAME_SAMPLE_VISIBILITY (f
);
7601 if (FRAME_VISIBLE_P (sf
)
7602 && !FRAME_VISIBLE_P (f
))
7603 Fmake_frame_visible (frame
);
7605 if (STRINGP (m
) && SCHARS (m
) > 0)
7607 set_message (NULL
, m
, nbytes
, multibyte
);
7608 if (minibuffer_auto_raise
)
7609 Fraise_frame (frame
);
7610 /* Assume we are not echoing.
7611 (If we are, echo_now will override this.) */
7612 echo_message_buffer
= Qnil
;
7615 clear_message (1, 1);
7617 do_pending_window_change (0);
7618 echo_area_display (1);
7619 do_pending_window_change (0);
7620 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
7621 (*frame_up_to_date_hook
) (f
);
7626 /* Display a null-terminated echo area message M. If M is 0, clear
7627 out any existing message, and let the mini-buffer text show through.
7629 The buffer M must continue to exist until after the echo area gets
7630 cleared or some other message gets displayed there. Do not pass
7631 text that is stored in a Lisp string. Do not pass text in a buffer
7632 that was alloca'd. */
7638 message2 (m
, (m
? strlen (m
) : 0), 0);
7642 /* The non-logging counterpart of message1. */
7648 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
7651 /* Display a message M which contains a single %s
7652 which gets replaced with STRING. */
7655 message_with_string (m
, string
, log
)
7660 CHECK_STRING (string
);
7666 if (noninteractive_need_newline
)
7667 putc ('\n', stderr
);
7668 noninteractive_need_newline
= 0;
7669 fprintf (stderr
, m
, SDATA (string
));
7670 if (cursor_in_echo_area
== 0)
7671 fprintf (stderr
, "\n");
7675 else if (INTERACTIVE
)
7677 /* The frame whose minibuffer we're going to display the message on.
7678 It may be larger than the selected frame, so we need
7679 to use its buffer, not the selected frame's buffer. */
7680 Lisp_Object mini_window
;
7681 struct frame
*f
, *sf
= SELECTED_FRAME ();
7683 /* Get the frame containing the minibuffer
7684 that the selected frame is using. */
7685 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7686 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
7688 /* A null message buffer means that the frame hasn't really been
7689 initialized yet. Error messages get reported properly by
7690 cmd_error, so this must be just an informative message; toss it. */
7691 if (FRAME_MESSAGE_BUF (f
))
7693 Lisp_Object args
[2], message
;
7694 struct gcpro gcpro1
, gcpro2
;
7696 args
[0] = build_string (m
);
7697 args
[1] = message
= string
;
7698 GCPRO2 (args
[0], message
);
7701 message
= Fformat (2, args
);
7704 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
7706 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
7710 /* Print should start at the beginning of the message
7711 buffer next time. */
7712 message_buf_print
= 0;
7718 /* Dump an informative message to the minibuf. If M is 0, clear out
7719 any existing message, and let the mini-buffer text show through. */
7723 message (m
, a1
, a2
, a3
)
7725 EMACS_INT a1
, a2
, a3
;
7731 if (noninteractive_need_newline
)
7732 putc ('\n', stderr
);
7733 noninteractive_need_newline
= 0;
7734 fprintf (stderr
, m
, a1
, a2
, a3
);
7735 if (cursor_in_echo_area
== 0)
7736 fprintf (stderr
, "\n");
7740 else if (INTERACTIVE
)
7742 /* The frame whose mini-buffer we're going to display the message
7743 on. It may be larger than the selected frame, so we need to
7744 use its buffer, not the selected frame's buffer. */
7745 Lisp_Object mini_window
;
7746 struct frame
*f
, *sf
= SELECTED_FRAME ();
7748 /* Get the frame containing the mini-buffer
7749 that the selected frame is using. */
7750 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7751 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
7753 /* A null message buffer means that the frame hasn't really been
7754 initialized yet. Error messages get reported properly by
7755 cmd_error, so this must be just an informative message; toss
7757 if (FRAME_MESSAGE_BUF (f
))
7768 len
= doprnt (FRAME_MESSAGE_BUF (f
),
7769 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
7771 len
= doprnt (FRAME_MESSAGE_BUF (f
),
7772 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
7774 #endif /* NO_ARG_ARRAY */
7776 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
7781 /* Print should start at the beginning of the message
7782 buffer next time. */
7783 message_buf_print
= 0;
7789 /* The non-logging version of message. */
7792 message_nolog (m
, a1
, a2
, a3
)
7794 EMACS_INT a1
, a2
, a3
;
7796 Lisp_Object old_log_max
;
7797 old_log_max
= Vmessage_log_max
;
7798 Vmessage_log_max
= Qnil
;
7799 message (m
, a1
, a2
, a3
);
7800 Vmessage_log_max
= old_log_max
;
7804 /* Display the current message in the current mini-buffer. This is
7805 only called from error handlers in process.c, and is not time
7811 if (!NILP (echo_area_buffer
[0]))
7814 string
= Fcurrent_message ();
7815 message3 (string
, SBYTES (string
),
7816 !NILP (current_buffer
->enable_multibyte_characters
));
7821 /* Make sure echo area buffers in `echo_buffers' are live.
7822 If they aren't, make new ones. */
7825 ensure_echo_area_buffers ()
7829 for (i
= 0; i
< 2; ++i
)
7830 if (!BUFFERP (echo_buffer
[i
])
7831 || NILP (XBUFFER (echo_buffer
[i
])->name
))
7834 Lisp_Object old_buffer
;
7837 old_buffer
= echo_buffer
[i
];
7838 sprintf (name
, " *Echo Area %d*", i
);
7839 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
7840 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
7842 for (j
= 0; j
< 2; ++j
)
7843 if (EQ (old_buffer
, echo_area_buffer
[j
]))
7844 echo_area_buffer
[j
] = echo_buffer
[i
];
7849 /* Call FN with args A1..A4 with either the current or last displayed
7850 echo_area_buffer as current buffer.
7852 WHICH zero means use the current message buffer
7853 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7854 from echo_buffer[] and clear it.
7856 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7857 suitable buffer from echo_buffer[] and clear it.
7859 Value is what FN returns. */
7862 with_echo_area_buffer (w
, which
, fn
, a1
, a2
, a3
, a4
)
7865 int (*fn
) P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
7871 int this_one
, the_other
, clear_buffer_p
, rc
;
7872 int count
= SPECPDL_INDEX ();
7874 /* If buffers aren't live, make new ones. */
7875 ensure_echo_area_buffers ();
7880 this_one
= 0, the_other
= 1;
7882 this_one
= 1, the_other
= 0;
7884 /* Choose a suitable buffer from echo_buffer[] is we don't
7886 if (NILP (echo_area_buffer
[this_one
]))
7888 echo_area_buffer
[this_one
]
7889 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
7890 ? echo_buffer
[the_other
]
7891 : echo_buffer
[this_one
]);
7895 buffer
= echo_area_buffer
[this_one
];
7897 /* Don't get confused by reusing the buffer used for echoing
7898 for a different purpose. */
7899 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
7902 record_unwind_protect (unwind_with_echo_area_buffer
,
7903 with_echo_area_buffer_unwind_data (w
));
7905 /* Make the echo area buffer current. Note that for display
7906 purposes, it is not necessary that the displayed window's buffer
7907 == current_buffer, except for text property lookup. So, let's
7908 only set that buffer temporarily here without doing a full
7909 Fset_window_buffer. We must also change w->pointm, though,
7910 because otherwise an assertions in unshow_buffer fails, and Emacs
7912 set_buffer_internal_1 (XBUFFER (buffer
));
7916 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
7919 current_buffer
->undo_list
= Qt
;
7920 current_buffer
->read_only
= Qnil
;
7921 specbind (Qinhibit_read_only
, Qt
);
7922 specbind (Qinhibit_modification_hooks
, Qt
);
7924 if (clear_buffer_p
&& Z
> BEG
)
7927 xassert (BEGV
>= BEG
);
7928 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7930 rc
= fn (a1
, a2
, a3
, a4
);
7932 xassert (BEGV
>= BEG
);
7933 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7935 unbind_to (count
, Qnil
);
7940 /* Save state that should be preserved around the call to the function
7941 FN called in with_echo_area_buffer. */
7944 with_echo_area_buffer_unwind_data (w
)
7950 /* Reduce consing by keeping one vector in
7951 Vwith_echo_area_save_vector. */
7952 vector
= Vwith_echo_area_save_vector
;
7953 Vwith_echo_area_save_vector
= Qnil
;
7956 vector
= Fmake_vector (make_number (7), Qnil
);
7958 XSETBUFFER (AREF (vector
, i
), current_buffer
); ++i
;
7959 AREF (vector
, i
) = Vdeactivate_mark
, ++i
;
7960 AREF (vector
, i
) = make_number (windows_or_buffers_changed
), ++i
;
7964 XSETWINDOW (AREF (vector
, i
), w
); ++i
;
7965 AREF (vector
, i
) = w
->buffer
; ++i
;
7966 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->charpos
); ++i
;
7967 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->bytepos
); ++i
;
7972 for (; i
< end
; ++i
)
7973 AREF (vector
, i
) = Qnil
;
7976 xassert (i
== ASIZE (vector
));
7981 /* Restore global state from VECTOR which was created by
7982 with_echo_area_buffer_unwind_data. */
7985 unwind_with_echo_area_buffer (vector
)
7988 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
7989 Vdeactivate_mark
= AREF (vector
, 1);
7990 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
7992 if (WINDOWP (AREF (vector
, 3)))
7995 Lisp_Object buffer
, charpos
, bytepos
;
7997 w
= XWINDOW (AREF (vector
, 3));
7998 buffer
= AREF (vector
, 4);
7999 charpos
= AREF (vector
, 5);
8000 bytepos
= AREF (vector
, 6);
8003 set_marker_both (w
->pointm
, buffer
,
8004 XFASTINT (charpos
), XFASTINT (bytepos
));
8007 Vwith_echo_area_save_vector
= vector
;
8012 /* Set up the echo area for use by print functions. MULTIBYTE_P
8013 non-zero means we will print multibyte. */
8016 setup_echo_area_for_printing (multibyte_p
)
8019 /* If we can't find an echo area any more, exit. */
8020 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
8023 ensure_echo_area_buffers ();
8025 if (!message_buf_print
)
8027 /* A message has been output since the last time we printed.
8028 Choose a fresh echo area buffer. */
8029 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
8030 echo_area_buffer
[0] = echo_buffer
[1];
8032 echo_area_buffer
[0] = echo_buffer
[0];
8034 /* Switch to that buffer and clear it. */
8035 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
8036 current_buffer
->truncate_lines
= Qnil
;
8040 int count
= SPECPDL_INDEX ();
8041 specbind (Qinhibit_read_only
, Qt
);
8042 /* Note that undo recording is always disabled. */
8044 unbind_to (count
, Qnil
);
8046 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
8048 /* Set up the buffer for the multibyteness we need. */
8050 != !NILP (current_buffer
->enable_multibyte_characters
))
8051 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
8053 /* Raise the frame containing the echo area. */
8054 if (minibuffer_auto_raise
)
8056 struct frame
*sf
= SELECTED_FRAME ();
8057 Lisp_Object mini_window
;
8058 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8059 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
8062 message_log_maybe_newline ();
8063 message_buf_print
= 1;
8067 if (NILP (echo_area_buffer
[0]))
8069 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
8070 echo_area_buffer
[0] = echo_buffer
[1];
8072 echo_area_buffer
[0] = echo_buffer
[0];
8075 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
8077 /* Someone switched buffers between print requests. */
8078 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
8079 current_buffer
->truncate_lines
= Qnil
;
8085 /* Display an echo area message in window W. Value is non-zero if W's
8086 height is changed. If display_last_displayed_message_p is
8087 non-zero, display the message that was last displayed, otherwise
8088 display the current message. */
8091 display_echo_area (w
)
8094 int i
, no_message_p
, window_height_changed_p
, count
;
8096 /* Temporarily disable garbage collections while displaying the echo
8097 area. This is done because a GC can print a message itself.
8098 That message would modify the echo area buffer's contents while a
8099 redisplay of the buffer is going on, and seriously confuse
8101 count
= inhibit_garbage_collection ();
8103 /* If there is no message, we must call display_echo_area_1
8104 nevertheless because it resizes the window. But we will have to
8105 reset the echo_area_buffer in question to nil at the end because
8106 with_echo_area_buffer will sets it to an empty buffer. */
8107 i
= display_last_displayed_message_p
? 1 : 0;
8108 no_message_p
= NILP (echo_area_buffer
[i
]);
8110 window_height_changed_p
8111 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
8112 display_echo_area_1
,
8113 (EMACS_INT
) w
, Qnil
, 0, 0);
8116 echo_area_buffer
[i
] = Qnil
;
8118 unbind_to (count
, Qnil
);
8119 return window_height_changed_p
;
8123 /* Helper for display_echo_area. Display the current buffer which
8124 contains the current echo area message in window W, a mini-window,
8125 a pointer to which is passed in A1. A2..A4 are currently not used.
8126 Change the height of W so that all of the message is displayed.
8127 Value is non-zero if height of W was changed. */
8130 display_echo_area_1 (a1
, a2
, a3
, a4
)
8135 struct window
*w
= (struct window
*) a1
;
8137 struct text_pos start
;
8138 int window_height_changed_p
= 0;
8140 /* Do this before displaying, so that we have a large enough glyph
8141 matrix for the display. If we can't get enough space for the
8142 whole text, display the last N lines. That works by setting w->start. */
8143 window_height_changed_p
= resize_mini_window (w
, 0);
8145 /* Use the starting position chosen by resize_mini_window. */
8146 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
8149 clear_glyph_matrix (w
->desired_matrix
);
8150 XSETWINDOW (window
, w
);
8151 try_window (window
, start
, 0);
8153 return window_height_changed_p
;
8157 /* Resize the echo area window to exactly the size needed for the
8158 currently displayed message, if there is one. If a mini-buffer
8159 is active, don't shrink it. */
8162 resize_echo_area_exactly ()
8164 if (BUFFERP (echo_area_buffer
[0])
8165 && WINDOWP (echo_area_window
))
8167 struct window
*w
= XWINDOW (echo_area_window
);
8169 Lisp_Object resize_exactly
;
8171 if (minibuf_level
== 0)
8172 resize_exactly
= Qt
;
8174 resize_exactly
= Qnil
;
8176 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
8177 (EMACS_INT
) w
, resize_exactly
, 0, 0);
8180 ++windows_or_buffers_changed
;
8181 ++update_mode_lines
;
8182 redisplay_internal (0);
8188 /* Callback function for with_echo_area_buffer, when used from
8189 resize_echo_area_exactly. A1 contains a pointer to the window to
8190 resize, EXACTLY non-nil means resize the mini-window exactly to the
8191 size of the text displayed. A3 and A4 are not used. Value is what
8192 resize_mini_window returns. */
8195 resize_mini_window_1 (a1
, exactly
, a3
, a4
)
8197 Lisp_Object exactly
;
8200 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
8204 /* Resize mini-window W to fit the size of its contents. EXACT:P
8205 means size the window exactly to the size needed. Otherwise, it's
8206 only enlarged until W's buffer is empty.
8208 Set W->start to the right place to begin display. If the whole
8209 contents fit, start at the beginning. Otherwise, start so as
8210 to make the end of the contents appear. This is particularly
8211 important for y-or-n-p, but seems desirable generally.
8213 Value is non-zero if the window height has been changed. */
8216 resize_mini_window (w
, exact_p
)
8220 struct frame
*f
= XFRAME (w
->frame
);
8221 int window_height_changed_p
= 0;
8223 xassert (MINI_WINDOW_P (w
));
8225 /* By default, start display at the beginning. */
8226 set_marker_both (w
->start
, w
->buffer
,
8227 BUF_BEGV (XBUFFER (w
->buffer
)),
8228 BUF_BEGV_BYTE (XBUFFER (w
->buffer
)));
8230 /* Don't resize windows while redisplaying a window; it would
8231 confuse redisplay functions when the size of the window they are
8232 displaying changes from under them. Such a resizing can happen,
8233 for instance, when which-func prints a long message while
8234 we are running fontification-functions. We're running these
8235 functions with safe_call which binds inhibit-redisplay to t. */
8236 if (!NILP (Vinhibit_redisplay
))
8239 /* Nil means don't try to resize. */
8240 if (NILP (Vresize_mini_windows
)
8241 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
8244 if (!FRAME_MINIBUF_ONLY_P (f
))
8247 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
8248 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
8249 int height
, max_height
;
8250 int unit
= FRAME_LINE_HEIGHT (f
);
8251 struct text_pos start
;
8252 struct buffer
*old_current_buffer
= NULL
;
8254 if (current_buffer
!= XBUFFER (w
->buffer
))
8256 old_current_buffer
= current_buffer
;
8257 set_buffer_internal (XBUFFER (w
->buffer
));
8260 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
8262 /* Compute the max. number of lines specified by the user. */
8263 if (FLOATP (Vmax_mini_window_height
))
8264 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
8265 else if (INTEGERP (Vmax_mini_window_height
))
8266 max_height
= XINT (Vmax_mini_window_height
);
8268 max_height
= total_height
/ 4;
8270 /* Correct that max. height if it's bogus. */
8271 max_height
= max (1, max_height
);
8272 max_height
= min (total_height
, max_height
);
8274 /* Find out the height of the text in the window. */
8275 if (it
.truncate_lines_p
)
8280 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
8281 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
8282 height
= it
.current_y
+ last_height
;
8284 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
8285 height
-= min (it
.extra_line_spacing
, it
.max_extra_line_spacing
);
8286 height
= (height
+ unit
- 1) / unit
;
8289 /* Compute a suitable window start. */
8290 if (height
> max_height
)
8292 height
= max_height
;
8293 init_iterator (&it
, w
, ZV
, ZV_BYTE
, NULL
, DEFAULT_FACE_ID
);
8294 move_it_vertically_backward (&it
, (height
- 1) * unit
);
8295 start
= it
.current
.pos
;
8298 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
8299 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
8301 if (EQ (Vresize_mini_windows
, Qgrow_only
))
8303 /* Let it grow only, until we display an empty message, in which
8304 case the window shrinks again. */
8305 if (height
> WINDOW_TOTAL_LINES (w
))
8307 int old_height
= WINDOW_TOTAL_LINES (w
);
8308 freeze_window_starts (f
, 1);
8309 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
8310 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
8312 else if (height
< WINDOW_TOTAL_LINES (w
)
8313 && (exact_p
|| BEGV
== ZV
))
8315 int old_height
= WINDOW_TOTAL_LINES (w
);
8316 freeze_window_starts (f
, 0);
8317 shrink_mini_window (w
);
8318 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
8323 /* Always resize to exact size needed. */
8324 if (height
> WINDOW_TOTAL_LINES (w
))
8326 int old_height
= WINDOW_TOTAL_LINES (w
);
8327 freeze_window_starts (f
, 1);
8328 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
8329 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
8331 else if (height
< WINDOW_TOTAL_LINES (w
))
8333 int old_height
= WINDOW_TOTAL_LINES (w
);
8334 freeze_window_starts (f
, 0);
8335 shrink_mini_window (w
);
8339 freeze_window_starts (f
, 1);
8340 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
8343 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
8347 if (old_current_buffer
)
8348 set_buffer_internal (old_current_buffer
);
8351 return window_height_changed_p
;
8355 /* Value is the current message, a string, or nil if there is no
8363 if (NILP (echo_area_buffer
[0]))
8367 with_echo_area_buffer (0, 0, current_message_1
,
8368 (EMACS_INT
) &msg
, Qnil
, 0, 0);
8370 echo_area_buffer
[0] = Qnil
;
8378 current_message_1 (a1
, a2
, a3
, a4
)
8383 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
8386 *msg
= make_buffer_string (BEG
, Z
, 1);
8393 /* Push the current message on Vmessage_stack for later restauration
8394 by restore_message. Value is non-zero if the current message isn't
8395 empty. This is a relatively infrequent operation, so it's not
8396 worth optimizing. */
8402 msg
= current_message ();
8403 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
8404 return STRINGP (msg
);
8408 /* Restore message display from the top of Vmessage_stack. */
8415 xassert (CONSP (Vmessage_stack
));
8416 msg
= XCAR (Vmessage_stack
);
8418 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
8420 message3_nolog (msg
, 0, 0);
8424 /* Handler for record_unwind_protect calling pop_message. */
8427 pop_message_unwind (dummy
)
8434 /* Pop the top-most entry off Vmessage_stack. */
8439 xassert (CONSP (Vmessage_stack
));
8440 Vmessage_stack
= XCDR (Vmessage_stack
);
8444 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8445 exits. If the stack is not empty, we have a missing pop_message
8449 check_message_stack ()
8451 if (!NILP (Vmessage_stack
))
8456 /* Truncate to NCHARS what will be displayed in the echo area the next
8457 time we display it---but don't redisplay it now. */
8460 truncate_echo_area (nchars
)
8464 echo_area_buffer
[0] = Qnil
;
8465 /* A null message buffer means that the frame hasn't really been
8466 initialized yet. Error messages get reported properly by
8467 cmd_error, so this must be just an informative message; toss it. */
8468 else if (!noninteractive
8470 && !NILP (echo_area_buffer
[0]))
8472 struct frame
*sf
= SELECTED_FRAME ();
8473 if (FRAME_MESSAGE_BUF (sf
))
8474 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
8479 /* Helper function for truncate_echo_area. Truncate the current
8480 message to at most NCHARS characters. */
8483 truncate_message_1 (nchars
, a2
, a3
, a4
)
8488 if (BEG
+ nchars
< Z
)
8489 del_range (BEG
+ nchars
, Z
);
8491 echo_area_buffer
[0] = Qnil
;
8496 /* Set the current message to a substring of S or STRING.
8498 If STRING is a Lisp string, set the message to the first NBYTES
8499 bytes from STRING. NBYTES zero means use the whole string. If
8500 STRING is multibyte, the message will be displayed multibyte.
8502 If S is not null, set the message to the first LEN bytes of S. LEN
8503 zero means use the whole string. MULTIBYTE_P non-zero means S is
8504 multibyte. Display the message multibyte in that case.
8506 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8507 to t before calling set_message_1 (which calls insert).
8511 set_message (s
, string
, nbytes
, multibyte_p
)
8514 int nbytes
, multibyte_p
;
8516 message_enable_multibyte
8517 = ((s
&& multibyte_p
)
8518 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
8520 with_echo_area_buffer (0, 0, set_message_1
,
8521 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
8522 message_buf_print
= 0;
8523 help_echo_showing_p
= 0;
8527 /* Helper function for set_message. Arguments have the same meaning
8528 as there, with A1 corresponding to S and A2 corresponding to STRING
8529 This function is called with the echo area buffer being
8533 set_message_1 (a1
, a2
, nbytes
, multibyte_p
)
8536 EMACS_INT nbytes
, multibyte_p
;
8538 const char *s
= (const char *) a1
;
8539 Lisp_Object string
= a2
;
8541 /* Change multibyteness of the echo buffer appropriately. */
8542 if (message_enable_multibyte
8543 != !NILP (current_buffer
->enable_multibyte_characters
))
8544 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
8546 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
8548 /* Insert new message at BEG. */
8549 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
8552 if (STRINGP (string
))
8557 nbytes
= SBYTES (string
);
8558 nchars
= string_byte_to_char (string
, nbytes
);
8560 /* This function takes care of single/multibyte conversion. We
8561 just have to ensure that the echo area buffer has the right
8562 setting of enable_multibyte_characters. */
8563 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
8568 nbytes
= strlen (s
);
8570 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
8572 /* Convert from multi-byte to single-byte. */
8574 unsigned char work
[1];
8576 /* Convert a multibyte string to single-byte. */
8577 for (i
= 0; i
< nbytes
; i
+= n
)
8579 c
= string_char_and_length (s
+ i
, nbytes
- i
, &n
);
8580 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
8582 : multibyte_char_to_unibyte (c
, Qnil
));
8583 insert_1_both (work
, 1, 1, 1, 0, 0);
8586 else if (!multibyte_p
8587 && !NILP (current_buffer
->enable_multibyte_characters
))
8589 /* Convert from single-byte to multi-byte. */
8591 const unsigned char *msg
= (const unsigned char *) s
;
8592 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
8594 /* Convert a single-byte string to multibyte. */
8595 for (i
= 0; i
< nbytes
; i
++)
8597 c
= unibyte_char_to_multibyte (msg
[i
]);
8598 n
= CHAR_STRING (c
, str
);
8599 insert_1_both (str
, 1, n
, 1, 0, 0);
8603 insert_1 (s
, nbytes
, 1, 0, 0);
8610 /* Clear messages. CURRENT_P non-zero means clear the current
8611 message. LAST_DISPLAYED_P non-zero means clear the message
8615 clear_message (current_p
, last_displayed_p
)
8616 int current_p
, last_displayed_p
;
8620 echo_area_buffer
[0] = Qnil
;
8621 message_cleared_p
= 1;
8624 if (last_displayed_p
)
8625 echo_area_buffer
[1] = Qnil
;
8627 message_buf_print
= 0;
8630 /* Clear garbaged frames.
8632 This function is used where the old redisplay called
8633 redraw_garbaged_frames which in turn called redraw_frame which in
8634 turn called clear_frame. The call to clear_frame was a source of
8635 flickering. I believe a clear_frame is not necessary. It should
8636 suffice in the new redisplay to invalidate all current matrices,
8637 and ensure a complete redisplay of all windows. */
8640 clear_garbaged_frames ()
8644 Lisp_Object tail
, frame
;
8645 int changed_count
= 0;
8647 FOR_EACH_FRAME (tail
, frame
)
8649 struct frame
*f
= XFRAME (frame
);
8651 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
8655 Fredraw_frame (frame
);
8656 f
->force_flush_display_p
= 1;
8658 clear_current_matrices (f
);
8667 ++windows_or_buffers_changed
;
8672 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8673 is non-zero update selected_frame. Value is non-zero if the
8674 mini-windows height has been changed. */
8677 echo_area_display (update_frame_p
)
8680 Lisp_Object mini_window
;
8683 int window_height_changed_p
= 0;
8684 struct frame
*sf
= SELECTED_FRAME ();
8686 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8687 w
= XWINDOW (mini_window
);
8688 f
= XFRAME (WINDOW_FRAME (w
));
8690 /* Don't display if frame is invisible or not yet initialized. */
8691 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
8694 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8696 #ifdef HAVE_WINDOW_SYSTEM
8697 /* When Emacs starts, selected_frame may be a visible terminal
8698 frame, even if we run under a window system. If we let this
8699 through, a message would be displayed on the terminal. */
8700 if (EQ (selected_frame
, Vterminal_frame
)
8701 && !NILP (Vwindow_system
))
8703 #endif /* HAVE_WINDOW_SYSTEM */
8706 /* Redraw garbaged frames. */
8708 clear_garbaged_frames ();
8710 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
8712 echo_area_window
= mini_window
;
8713 window_height_changed_p
= display_echo_area (w
);
8714 w
->must_be_updated_p
= 1;
8716 /* Update the display, unless called from redisplay_internal.
8717 Also don't update the screen during redisplay itself. The
8718 update will happen at the end of redisplay, and an update
8719 here could cause confusion. */
8720 if (update_frame_p
&& !redisplaying_p
)
8724 /* If the display update has been interrupted by pending
8725 input, update mode lines in the frame. Due to the
8726 pending input, it might have been that redisplay hasn't
8727 been called, so that mode lines above the echo area are
8728 garbaged. This looks odd, so we prevent it here. */
8729 if (!display_completed
)
8730 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
8732 if (window_height_changed_p
8733 /* Don't do this if Emacs is shutting down. Redisplay
8734 needs to run hooks. */
8735 && !NILP (Vrun_hooks
))
8737 /* Must update other windows. Likewise as in other
8738 cases, don't let this update be interrupted by
8740 int count
= SPECPDL_INDEX ();
8741 specbind (Qredisplay_dont_pause
, Qt
);
8742 windows_or_buffers_changed
= 1;
8743 redisplay_internal (0);
8744 unbind_to (count
, Qnil
);
8746 else if (FRAME_WINDOW_P (f
) && n
== 0)
8748 /* Window configuration is the same as before.
8749 Can do with a display update of the echo area,
8750 unless we displayed some mode lines. */
8751 update_single_window (w
, 1);
8752 rif
->flush_display (f
);
8755 update_frame (f
, 1, 1);
8757 /* If cursor is in the echo area, make sure that the next
8758 redisplay displays the minibuffer, so that the cursor will
8759 be replaced with what the minibuffer wants. */
8760 if (cursor_in_echo_area
)
8761 ++windows_or_buffers_changed
;
8764 else if (!EQ (mini_window
, selected_window
))
8765 windows_or_buffers_changed
++;
8767 /* The current message is now also the last one displayed. */
8768 echo_area_buffer
[1] = echo_area_buffer
[0];
8770 /* Prevent redisplay optimization in redisplay_internal by resetting
8771 this_line_start_pos. This is done because the mini-buffer now
8772 displays the message instead of its buffer text. */
8773 if (EQ (mini_window
, selected_window
))
8774 CHARPOS (this_line_start_pos
) = 0;
8776 return window_height_changed_p
;
8781 /***********************************************************************
8782 Mode Lines and Frame Titles
8783 ***********************************************************************/
8785 /* A buffer for constructing non-propertized mode-line strings and
8786 frame titles in it; allocated from the heap in init_xdisp and
8787 resized as needed in store_mode_line_noprop_char. */
8789 static char *mode_line_noprop_buf
;
8791 /* The buffer's end, and a current output position in it. */
8793 static char *mode_line_noprop_buf_end
;
8794 static char *mode_line_noprop_ptr
;
8796 #define MODE_LINE_NOPROP_LEN(start) \
8797 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8800 MODE_LINE_DISPLAY
= 0,
8806 /* Alist that caches the results of :propertize.
8807 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8808 static Lisp_Object mode_line_proptrans_alist
;
8810 /* List of strings making up the mode-line. */
8811 static Lisp_Object mode_line_string_list
;
8813 /* Base face property when building propertized mode line string. */
8814 static Lisp_Object mode_line_string_face
;
8815 static Lisp_Object mode_line_string_face_prop
;
8818 /* Unwind data for mode line strings */
8820 static Lisp_Object Vmode_line_unwind_vector
;
8823 format_mode_line_unwind_data (obuf
, save_proptrans
)
8824 struct buffer
*obuf
;
8828 /* Reduce consing by keeping one vector in
8829 Vwith_echo_area_save_vector. */
8830 vector
= Vmode_line_unwind_vector
;
8831 Vmode_line_unwind_vector
= Qnil
;
8834 vector
= Fmake_vector (make_number (7), Qnil
);
8836 AREF (vector
, 0) = make_number (mode_line_target
);
8837 AREF (vector
, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
8838 AREF (vector
, 2) = mode_line_string_list
;
8839 AREF (vector
, 3) = (save_proptrans
? mode_line_proptrans_alist
: Qt
);
8840 AREF (vector
, 4) = mode_line_string_face
;
8841 AREF (vector
, 5) = mode_line_string_face_prop
;
8844 XSETBUFFER (AREF (vector
, 6), obuf
);
8846 AREF (vector
, 6) = Qnil
;
8852 unwind_format_mode_line (vector
)
8855 mode_line_target
= XINT (AREF (vector
, 0));
8856 mode_line_noprop_ptr
= mode_line_noprop_buf
+ XINT (AREF (vector
, 1));
8857 mode_line_string_list
= AREF (vector
, 2);
8858 if (! EQ (AREF (vector
, 3), Qt
))
8859 mode_line_proptrans_alist
= AREF (vector
, 3);
8860 mode_line_string_face
= AREF (vector
, 4);
8861 mode_line_string_face_prop
= AREF (vector
, 5);
8863 if (!NILP (AREF (vector
, 6)))
8865 set_buffer_internal_1 (XBUFFER (AREF (vector
, 6)));
8866 AREF (vector
, 6) = Qnil
;
8869 Vmode_line_unwind_vector
= vector
;
8874 /* Store a single character C for the frame title in mode_line_noprop_buf.
8875 Re-allocate mode_line_noprop_buf if necessary. */
8879 store_mode_line_noprop_char (char c
)
8881 store_mode_line_noprop_char (c
)
8885 /* If output position has reached the end of the allocated buffer,
8886 double the buffer's size. */
8887 if (mode_line_noprop_ptr
== mode_line_noprop_buf_end
)
8889 int len
= MODE_LINE_NOPROP_LEN (0);
8890 int new_size
= 2 * len
* sizeof *mode_line_noprop_buf
;
8891 mode_line_noprop_buf
= (char *) xrealloc (mode_line_noprop_buf
, new_size
);
8892 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ new_size
;
8893 mode_line_noprop_ptr
= mode_line_noprop_buf
+ len
;
8896 *mode_line_noprop_ptr
++ = c
;
8900 /* Store part of a frame title in mode_line_noprop_buf, beginning at
8901 mode_line_noprop_ptr. STR is the string to store. Do not copy
8902 characters that yield more columns than PRECISION; PRECISION <= 0
8903 means copy the whole string. Pad with spaces until FIELD_WIDTH
8904 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8905 pad. Called from display_mode_element when it is used to build a
8909 store_mode_line_noprop (str
, field_width
, precision
)
8910 const unsigned char *str
;
8911 int field_width
, precision
;
8916 /* Copy at most PRECISION chars from STR. */
8917 nbytes
= strlen (str
);
8918 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
8920 store_mode_line_noprop_char (*str
++);
8922 /* Fill up with spaces until FIELD_WIDTH reached. */
8923 while (field_width
> 0
8926 store_mode_line_noprop_char (' ');
8933 /***********************************************************************
8935 ***********************************************************************/
8937 #ifdef HAVE_WINDOW_SYSTEM
8939 /* Set the title of FRAME, if it has changed. The title format is
8940 Vicon_title_format if FRAME is iconified, otherwise it is
8941 frame_title_format. */
8944 x_consider_frame_title (frame
)
8947 struct frame
*f
= XFRAME (frame
);
8949 if (FRAME_WINDOW_P (f
)
8950 || FRAME_MINIBUF_ONLY_P (f
)
8951 || f
->explicit_name
)
8953 /* Do we have more than one visible frame on this X display? */
8960 int count
= SPECPDL_INDEX ();
8962 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
8964 Lisp_Object other_frame
= XCAR (tail
);
8965 struct frame
*tf
= XFRAME (other_frame
);
8968 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
8969 && !FRAME_MINIBUF_ONLY_P (tf
)
8970 && !EQ (other_frame
, tip_frame
)
8971 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
8975 /* Set global variable indicating that multiple frames exist. */
8976 multiple_frames
= CONSP (tail
);
8978 /* Switch to the buffer of selected window of the frame. Set up
8979 mode_line_target so that display_mode_element will output into
8980 mode_line_noprop_buf; then display the title. */
8981 record_unwind_protect (unwind_format_mode_line
,
8982 format_mode_line_unwind_data (current_buffer
, 0));
8984 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
8985 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
8987 mode_line_target
= MODE_LINE_TITLE
;
8988 title_start
= MODE_LINE_NOPROP_LEN (0);
8989 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
8990 NULL
, DEFAULT_FACE_ID
);
8991 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
8992 len
= MODE_LINE_NOPROP_LEN (title_start
);
8993 title
= mode_line_noprop_buf
+ title_start
;
8994 unbind_to (count
, Qnil
);
8996 /* Set the title only if it's changed. This avoids consing in
8997 the common case where it hasn't. (If it turns out that we've
8998 already wasted too much time by walking through the list with
8999 display_mode_element, then we might need to optimize at a
9000 higher level than this.) */
9001 if (! STRINGP (f
->name
)
9002 || SBYTES (f
->name
) != len
9003 || bcmp (title
, SDATA (f
->name
), len
) != 0)
9004 x_implicitly_set_name (f
, make_string (title
, len
), Qnil
);
9008 #endif /* not HAVE_WINDOW_SYSTEM */
9013 /***********************************************************************
9015 ***********************************************************************/
9018 /* Prepare for redisplay by updating menu-bar item lists when
9019 appropriate. This can call eval. */
9022 prepare_menu_bars ()
9025 struct gcpro gcpro1
, gcpro2
;
9027 Lisp_Object tooltip_frame
;
9029 #ifdef HAVE_WINDOW_SYSTEM
9030 tooltip_frame
= tip_frame
;
9032 tooltip_frame
= Qnil
;
9035 /* Update all frame titles based on their buffer names, etc. We do
9036 this before the menu bars so that the buffer-menu will show the
9037 up-to-date frame titles. */
9038 #ifdef HAVE_WINDOW_SYSTEM
9039 if (windows_or_buffers_changed
|| update_mode_lines
)
9041 Lisp_Object tail
, frame
;
9043 FOR_EACH_FRAME (tail
, frame
)
9046 if (!EQ (frame
, tooltip_frame
)
9047 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
9048 x_consider_frame_title (frame
);
9051 #endif /* HAVE_WINDOW_SYSTEM */
9053 /* Update the menu bar item lists, if appropriate. This has to be
9054 done before any actual redisplay or generation of display lines. */
9055 all_windows
= (update_mode_lines
9056 || buffer_shared
> 1
9057 || windows_or_buffers_changed
);
9060 Lisp_Object tail
, frame
;
9061 int count
= SPECPDL_INDEX ();
9062 /* 1 means that update_menu_bar has run its hooks
9063 so any further calls to update_menu_bar shouldn't do so again. */
9064 int menu_bar_hooks_run
= 0;
9066 record_unwind_save_match_data ();
9068 FOR_EACH_FRAME (tail
, frame
)
9072 /* Ignore tooltip frame. */
9073 if (EQ (frame
, tooltip_frame
))
9076 /* If a window on this frame changed size, report that to
9077 the user and clear the size-change flag. */
9078 if (FRAME_WINDOW_SIZES_CHANGED (f
))
9080 Lisp_Object functions
;
9082 /* Clear flag first in case we get an error below. */
9083 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
9084 functions
= Vwindow_size_change_functions
;
9085 GCPRO2 (tail
, functions
);
9087 while (CONSP (functions
))
9089 call1 (XCAR (functions
), frame
);
9090 functions
= XCDR (functions
);
9096 menu_bar_hooks_run
= update_menu_bar (f
, 0, menu_bar_hooks_run
);
9097 #ifdef HAVE_WINDOW_SYSTEM
9098 update_tool_bar (f
, 0);
9100 mac_update_title_bar (f
, 0);
9106 unbind_to (count
, Qnil
);
9110 struct frame
*sf
= SELECTED_FRAME ();
9111 update_menu_bar (sf
, 1, 0);
9112 #ifdef HAVE_WINDOW_SYSTEM
9113 update_tool_bar (sf
, 1);
9115 mac_update_title_bar (sf
, 1);
9120 /* Motif needs this. See comment in xmenu.c. Turn it off when
9121 pending_menu_activation is not defined. */
9122 #ifdef USE_X_TOOLKIT
9123 pending_menu_activation
= 0;
9128 /* Update the menu bar item list for frame F. This has to be done
9129 before we start to fill in any display lines, because it can call
9132 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9134 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9135 already ran the menu bar hooks for this redisplay, so there
9136 is no need to run them again. The return value is the
9137 updated value of this flag, to pass to the next call. */
9140 update_menu_bar (f
, save_match_data
, hooks_run
)
9142 int save_match_data
;
9146 register struct window
*w
;
9148 /* If called recursively during a menu update, do nothing. This can
9149 happen when, for instance, an activate-menubar-hook causes a
9151 if (inhibit_menubar_update
)
9154 window
= FRAME_SELECTED_WINDOW (f
);
9155 w
= XWINDOW (window
);
9157 #if 0 /* The if statement below this if statement used to include the
9158 condition !NILP (w->update_mode_line), rather than using
9159 update_mode_lines directly, and this if statement may have
9160 been added to make that condition work. Now the if
9161 statement below matches its comment, this isn't needed. */
9162 if (update_mode_lines
)
9163 w
->update_mode_line
= Qt
;
9166 if (FRAME_WINDOW_P (f
)
9168 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9169 || defined (USE_GTK)
9170 FRAME_EXTERNAL_MENU_BAR (f
)
9172 FRAME_MENU_BAR_LINES (f
) > 0
9174 : FRAME_MENU_BAR_LINES (f
) > 0)
9176 /* If the user has switched buffers or windows, we need to
9177 recompute to reflect the new bindings. But we'll
9178 recompute when update_mode_lines is set too; that means
9179 that people can use force-mode-line-update to request
9180 that the menu bar be recomputed. The adverse effect on
9181 the rest of the redisplay algorithm is about the same as
9182 windows_or_buffers_changed anyway. */
9183 if (windows_or_buffers_changed
9184 /* This used to test w->update_mode_line, but we believe
9185 there is no need to recompute the menu in that case. */
9186 || update_mode_lines
9187 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
9188 < BUF_MODIFF (XBUFFER (w
->buffer
)))
9189 != !NILP (w
->last_had_star
))
9190 || ((!NILP (Vtransient_mark_mode
)
9191 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9192 != !NILP (w
->region_showing
)))
9194 struct buffer
*prev
= current_buffer
;
9195 int count
= SPECPDL_INDEX ();
9197 specbind (Qinhibit_menubar_update
, Qt
);
9199 set_buffer_internal_1 (XBUFFER (w
->buffer
));
9200 if (save_match_data
)
9201 record_unwind_save_match_data ();
9202 if (NILP (Voverriding_local_map_menu_flag
))
9204 specbind (Qoverriding_terminal_local_map
, Qnil
);
9205 specbind (Qoverriding_local_map
, Qnil
);
9210 /* Run the Lucid hook. */
9211 safe_run_hooks (Qactivate_menubar_hook
);
9213 /* If it has changed current-menubar from previous value,
9214 really recompute the menu-bar from the value. */
9215 if (! NILP (Vlucid_menu_bar_dirty_flag
))
9216 call0 (Qrecompute_lucid_menubar
);
9218 safe_run_hooks (Qmenu_bar_update_hook
);
9223 XSETFRAME (Vmenu_updating_frame
, f
);
9224 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
9226 /* Redisplay the menu bar in case we changed it. */
9227 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9228 || defined (USE_GTK)
9229 if (FRAME_WINDOW_P (f
))
9232 /* All frames on Mac OS share the same menubar. So only
9233 the selected frame should be allowed to set it. */
9234 if (f
== SELECTED_FRAME ())
9236 set_frame_menubar (f
, 0, 0);
9239 /* On a terminal screen, the menu bar is an ordinary screen
9240 line, and this makes it get updated. */
9241 w
->update_mode_line
= Qt
;
9242 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9243 /* In the non-toolkit version, the menu bar is an ordinary screen
9244 line, and this makes it get updated. */
9245 w
->update_mode_line
= Qt
;
9246 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9248 unbind_to (count
, Qnil
);
9249 set_buffer_internal_1 (prev
);
9258 /***********************************************************************
9260 ***********************************************************************/
9262 #ifdef HAVE_WINDOW_SYSTEM
9265 Nominal cursor position -- where to draw output.
9266 HPOS and VPOS are window relative glyph matrix coordinates.
9267 X and Y are window relative pixel coordinates. */
9269 struct cursor_pos output_cursor
;
9273 Set the global variable output_cursor to CURSOR. All cursor
9274 positions are relative to updated_window. */
9277 set_output_cursor (cursor
)
9278 struct cursor_pos
*cursor
;
9280 output_cursor
.hpos
= cursor
->hpos
;
9281 output_cursor
.vpos
= cursor
->vpos
;
9282 output_cursor
.x
= cursor
->x
;
9283 output_cursor
.y
= cursor
->y
;
9288 Set a nominal cursor position.
9290 HPOS and VPOS are column/row positions in a window glyph matrix. X
9291 and Y are window text area relative pixel positions.
9293 If this is done during an update, updated_window will contain the
9294 window that is being updated and the position is the future output
9295 cursor position for that window. If updated_window is null, use
9296 selected_window and display the cursor at the given position. */
9299 x_cursor_to (vpos
, hpos
, y
, x
)
9300 int vpos
, hpos
, y
, x
;
9304 /* If updated_window is not set, work on selected_window. */
9308 w
= XWINDOW (selected_window
);
9310 /* Set the output cursor. */
9311 output_cursor
.hpos
= hpos
;
9312 output_cursor
.vpos
= vpos
;
9313 output_cursor
.x
= x
;
9314 output_cursor
.y
= y
;
9316 /* If not called as part of an update, really display the cursor.
9317 This will also set the cursor position of W. */
9318 if (updated_window
== NULL
)
9321 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
9322 if (rif
->flush_display_optional
)
9323 rif
->flush_display_optional (SELECTED_FRAME ());
9328 #endif /* HAVE_WINDOW_SYSTEM */
9331 /***********************************************************************
9333 ***********************************************************************/
9335 #ifdef HAVE_WINDOW_SYSTEM
9337 /* Where the mouse was last time we reported a mouse event. */
9339 FRAME_PTR last_mouse_frame
;
9341 /* Tool-bar item index of the item on which a mouse button was pressed
9344 int last_tool_bar_item
;
9347 /* Update the tool-bar item list for frame F. This has to be done
9348 before we start to fill in any display lines. Called from
9349 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9350 and restore it here. */
9353 update_tool_bar (f
, save_match_data
)
9355 int save_match_data
;
9358 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
9360 int do_update
= WINDOWP (f
->tool_bar_window
)
9361 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
9369 window
= FRAME_SELECTED_WINDOW (f
);
9370 w
= XWINDOW (window
);
9372 /* If the user has switched buffers or windows, we need to
9373 recompute to reflect the new bindings. But we'll
9374 recompute when update_mode_lines is set too; that means
9375 that people can use force-mode-line-update to request
9376 that the menu bar be recomputed. The adverse effect on
9377 the rest of the redisplay algorithm is about the same as
9378 windows_or_buffers_changed anyway. */
9379 if (windows_or_buffers_changed
9380 || !NILP (w
->update_mode_line
)
9381 || update_mode_lines
9382 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
9383 < BUF_MODIFF (XBUFFER (w
->buffer
)))
9384 != !NILP (w
->last_had_star
))
9385 || ((!NILP (Vtransient_mark_mode
)
9386 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9387 != !NILP (w
->region_showing
)))
9389 struct buffer
*prev
= current_buffer
;
9390 int count
= SPECPDL_INDEX ();
9391 Lisp_Object new_tool_bar
;
9393 struct gcpro gcpro1
;
9395 /* Set current_buffer to the buffer of the selected
9396 window of the frame, so that we get the right local
9398 set_buffer_internal_1 (XBUFFER (w
->buffer
));
9400 /* Save match data, if we must. */
9401 if (save_match_data
)
9402 record_unwind_save_match_data ();
9404 /* Make sure that we don't accidentally use bogus keymaps. */
9405 if (NILP (Voverriding_local_map_menu_flag
))
9407 specbind (Qoverriding_terminal_local_map
, Qnil
);
9408 specbind (Qoverriding_local_map
, Qnil
);
9411 GCPRO1 (new_tool_bar
);
9413 /* Build desired tool-bar items from keymaps. */
9414 new_tool_bar
= tool_bar_items (Fcopy_sequence (f
->tool_bar_items
),
9417 /* Redisplay the tool-bar if we changed it. */
9418 if (new_n_tool_bar
!= f
->n_tool_bar_items
9419 || NILP (Fequal (new_tool_bar
, f
->tool_bar_items
)))
9421 /* Redisplay that happens asynchronously due to an expose event
9422 may access f->tool_bar_items. Make sure we update both
9423 variables within BLOCK_INPUT so no such event interrupts. */
9425 f
->tool_bar_items
= new_tool_bar
;
9426 f
->n_tool_bar_items
= new_n_tool_bar
;
9427 w
->update_mode_line
= Qt
;
9433 unbind_to (count
, Qnil
);
9434 set_buffer_internal_1 (prev
);
9440 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9441 F's desired tool-bar contents. F->tool_bar_items must have
9442 been set up previously by calling prepare_menu_bars. */
9445 build_desired_tool_bar_string (f
)
9448 int i
, size
, size_needed
;
9449 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9450 Lisp_Object image
, plist
, props
;
9452 image
= plist
= props
= Qnil
;
9453 GCPRO3 (image
, plist
, props
);
9455 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9456 Otherwise, make a new string. */
9458 /* The size of the string we might be able to reuse. */
9459 size
= (STRINGP (f
->desired_tool_bar_string
)
9460 ? SCHARS (f
->desired_tool_bar_string
)
9463 /* We need one space in the string for each image. */
9464 size_needed
= f
->n_tool_bar_items
;
9466 /* Reuse f->desired_tool_bar_string, if possible. */
9467 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
9468 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
9472 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
9473 Fremove_text_properties (make_number (0), make_number (size
),
9474 props
, f
->desired_tool_bar_string
);
9477 /* Put a `display' property on the string for the images to display,
9478 put a `menu_item' property on tool-bar items with a value that
9479 is the index of the item in F's tool-bar item vector. */
9480 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
9482 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9484 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
9485 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
9486 int hmargin
, vmargin
, relief
, idx
, end
;
9487 extern Lisp_Object QCrelief
, QCmargin
, QCconversion
;
9489 /* If image is a vector, choose the image according to the
9491 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
9492 if (VECTORP (image
))
9496 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9497 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
9500 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9501 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
9503 xassert (ASIZE (image
) >= idx
);
9504 image
= AREF (image
, idx
);
9509 /* Ignore invalid image specifications. */
9510 if (!valid_image_p (image
))
9513 /* Display the tool-bar button pressed, or depressed. */
9514 plist
= Fcopy_sequence (XCDR (image
));
9516 /* Compute margin and relief to draw. */
9517 relief
= (tool_bar_button_relief
>= 0
9518 ? tool_bar_button_relief
9519 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
9520 hmargin
= vmargin
= relief
;
9522 if (INTEGERP (Vtool_bar_button_margin
)
9523 && XINT (Vtool_bar_button_margin
) > 0)
9525 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
9526 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
9528 else if (CONSP (Vtool_bar_button_margin
))
9530 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
9531 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
9532 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
9534 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
9535 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
9536 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
9539 if (auto_raise_tool_bar_buttons_p
)
9541 /* Add a `:relief' property to the image spec if the item is
9545 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
9552 /* If image is selected, display it pressed, i.e. with a
9553 negative relief. If it's not selected, display it with a
9555 plist
= Fplist_put (plist
, QCrelief
,
9557 ? make_number (-relief
)
9558 : make_number (relief
)));
9563 /* Put a margin around the image. */
9564 if (hmargin
|| vmargin
)
9566 if (hmargin
== vmargin
)
9567 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
9569 plist
= Fplist_put (plist
, QCmargin
,
9570 Fcons (make_number (hmargin
),
9571 make_number (vmargin
)));
9574 /* If button is not enabled, and we don't have special images
9575 for the disabled state, make the image appear disabled by
9576 applying an appropriate algorithm to it. */
9577 if (!enabled_p
&& idx
< 0)
9578 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
9580 /* Put a `display' text property on the string for the image to
9581 display. Put a `menu-item' property on the string that gives
9582 the start of this item's properties in the tool-bar items
9584 image
= Fcons (Qimage
, plist
);
9585 props
= list4 (Qdisplay
, image
,
9586 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
9588 /* Let the last image hide all remaining spaces in the tool bar
9589 string. The string can be longer than needed when we reuse a
9591 if (i
+ 1 == f
->n_tool_bar_items
)
9592 end
= SCHARS (f
->desired_tool_bar_string
);
9595 Fadd_text_properties (make_number (i
), make_number (end
),
9596 props
, f
->desired_tool_bar_string
);
9604 /* Display one line of the tool-bar of frame IT->f.
9606 HEIGHT specifies the desired height of the tool-bar line.
9607 If the actual height of the glyph row is less than HEIGHT, the
9608 row's height is increased to HEIGHT, and the icons are centered
9609 vertically in the new height.
9611 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
9612 count a final empty row in case the tool-bar width exactly matches
9617 display_tool_bar_line (it
, height
)
9621 struct glyph_row
*row
= it
->glyph_row
;
9622 int max_x
= it
->last_visible_x
;
9625 prepare_desired_row (row
);
9626 row
->y
= it
->current_y
;
9628 /* Note that this isn't made use of if the face hasn't a box,
9629 so there's no need to check the face here. */
9630 it
->start_of_box_run_p
= 1;
9632 while (it
->current_x
< max_x
)
9634 int x
, n_glyphs_before
, i
, nglyphs
;
9635 struct it it_before
;
9637 /* Get the next display element. */
9638 if (!get_next_display_element (it
))
9640 /* Don't count empty row if we are counting needed tool-bar lines. */
9641 if (height
< 0 && !it
->hpos
)
9646 /* Produce glyphs. */
9647 n_glyphs_before
= row
->used
[TEXT_AREA
];
9650 PRODUCE_GLYPHS (it
);
9652 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
9654 x
= it_before
.current_x
;
9657 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
9659 if (x
+ glyph
->pixel_width
> max_x
)
9661 /* Glyph doesn't fit on line. Backtrack. */
9662 row
->used
[TEXT_AREA
] = n_glyphs_before
;
9664 /* If this is the only glyph on this line, it will never fit on the
9665 toolbar, so skip it. But ensure there is at least one glyph,
9666 so we don't accidentally disable the tool-bar. */
9667 if (n_glyphs_before
== 0
9668 && (it
->vpos
> 0 || IT_STRING_CHARPOS (*it
) < it
->end_charpos
-1))
9674 x
+= glyph
->pixel_width
;
9678 /* Stop at line ends. */
9679 if (ITERATOR_AT_END_OF_LINE_P (it
))
9682 set_iterator_to_next (it
, 1);
9687 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
9688 /* Use default face for the border below the tool bar. */
9689 if (!row
->displays_text_p
)
9690 it
->face_id
= DEFAULT_FACE_ID
;
9691 extend_face_to_end_of_line (it
);
9692 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
9693 last
->right_box_line_p
= 1;
9694 if (last
== row
->glyphs
[TEXT_AREA
])
9695 last
->left_box_line_p
= 1;
9697 /* Make line the desired height and center it vertically. */
9698 if ((height
-= it
->max_ascent
+ it
->max_descent
) > 0)
9700 /* Don't add more than one line height. */
9701 height
%= FRAME_LINE_HEIGHT (it
->f
);
9702 it
->max_ascent
+= height
/ 2;
9703 it
->max_descent
+= (height
+ 1) / 2;
9706 compute_line_metrics (it
);
9708 /* If line is empty, make it occupy the rest of the tool-bar. */
9709 if (!row
->displays_text_p
)
9711 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
9712 row
->ascent
= row
->phys_ascent
= 0;
9713 row
->extra_line_spacing
= 0;
9716 row
->full_width_p
= 1;
9717 row
->continued_p
= 0;
9718 row
->truncated_on_left_p
= 0;
9719 row
->truncated_on_right_p
= 0;
9721 it
->current_x
= it
->hpos
= 0;
9722 it
->current_y
+= row
->height
;
9728 /* Max tool-bar height. */
9730 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
9731 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
9733 /* Value is the number of screen lines needed to make all tool-bar
9734 items of frame F visible. The number of actual rows needed is
9735 returned in *N_ROWS if non-NULL. */
9738 tool_bar_lines_needed (f
, n_rows
)
9742 struct window
*w
= XWINDOW (f
->tool_bar_window
);
9744 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
9745 the desired matrix, so use (unused) mode-line row as temporary row to
9746 avoid destroying the first tool-bar row. */
9747 struct glyph_row
*temp_row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
9749 /* Initialize an iterator for iteration over
9750 F->desired_tool_bar_string in the tool-bar window of frame F. */
9751 init_iterator (&it
, w
, -1, -1, temp_row
, TOOL_BAR_FACE_ID
);
9752 it
.first_visible_x
= 0;
9753 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
9754 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
9756 while (!ITERATOR_AT_END_P (&it
))
9758 clear_glyph_row (temp_row
);
9759 it
.glyph_row
= temp_row
;
9760 display_tool_bar_line (&it
, -1);
9762 clear_glyph_row (temp_row
);
9764 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
9766 *n_rows
= it
.vpos
> 0 ? it
.vpos
: -1;
9768 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
9772 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
9774 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
9783 frame
= selected_frame
;
9785 CHECK_FRAME (frame
);
9788 if (WINDOWP (f
->tool_bar_window
)
9789 || (w
= XWINDOW (f
->tool_bar_window
),
9790 WINDOW_TOTAL_LINES (w
) > 0))
9792 update_tool_bar (f
, 1);
9793 if (f
->n_tool_bar_items
)
9795 build_desired_tool_bar_string (f
);
9796 nlines
= tool_bar_lines_needed (f
, NULL
);
9800 return make_number (nlines
);
9804 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9805 height should be changed. */
9808 redisplay_tool_bar (f
)
9813 struct glyph_row
*row
;
9814 int change_height_p
= 0;
9817 if (FRAME_EXTERNAL_TOOL_BAR (f
))
9818 update_frame_tool_bar (f
);
9822 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9823 do anything. This means you must start with tool-bar-lines
9824 non-zero to get the auto-sizing effect. Or in other words, you
9825 can turn off tool-bars by specifying tool-bar-lines zero. */
9826 if (!WINDOWP (f
->tool_bar_window
)
9827 || (w
= XWINDOW (f
->tool_bar_window
),
9828 WINDOW_TOTAL_LINES (w
) == 0))
9831 /* Set up an iterator for the tool-bar window. */
9832 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
9833 it
.first_visible_x
= 0;
9834 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
9837 /* Build a string that represents the contents of the tool-bar. */
9838 build_desired_tool_bar_string (f
);
9839 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
9841 if (f
->n_tool_bar_rows
== 0)
9845 if ((nlines
= tool_bar_lines_needed (f
, &f
->n_tool_bar_rows
),
9846 nlines
!= WINDOW_TOTAL_LINES (w
)))
9848 extern Lisp_Object Qtool_bar_lines
;
9850 int old_height
= WINDOW_TOTAL_LINES (w
);
9852 XSETFRAME (frame
, f
);
9853 Fmodify_frame_parameters (frame
,
9854 Fcons (Fcons (Qtool_bar_lines
,
9855 make_number (nlines
)),
9857 if (WINDOW_TOTAL_LINES (w
) != old_height
)
9859 clear_glyph_matrix (w
->desired_matrix
);
9860 fonts_changed_p
= 1;
9866 /* Display as many lines as needed to display all tool-bar items. */
9868 if (f
->n_tool_bar_rows
> 0)
9870 int border
, rows
, height
, extra
;
9872 if (INTEGERP (Vtool_bar_border
))
9873 border
= XINT (Vtool_bar_border
);
9874 else if (EQ (Vtool_bar_border
, Qinternal_border_width
))
9875 border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
9876 else if (EQ (Vtool_bar_border
, Qborder_width
))
9877 border
= f
->border_width
;
9883 rows
= f
->n_tool_bar_rows
;
9884 height
= max (1, (it
.last_visible_y
- border
) / rows
);
9885 extra
= it
.last_visible_y
- border
- height
* rows
;
9887 while (it
.current_y
< it
.last_visible_y
)
9890 if (extra
> 0 && rows
-- > 0)
9892 h
= (extra
+ rows
- 1) / rows
;
9895 display_tool_bar_line (&it
, height
+ h
);
9900 while (it
.current_y
< it
.last_visible_y
)
9901 display_tool_bar_line (&it
, 0);
9904 /* It doesn't make much sense to try scrolling in the tool-bar
9905 window, so don't do it. */
9906 w
->desired_matrix
->no_scrolling_p
= 1;
9907 w
->must_be_updated_p
= 1;
9909 if (auto_resize_tool_bars_p
)
9912 int max_tool_bar_height
= MAX_FRAME_TOOL_BAR_HEIGHT (f
);
9914 /* If we couldn't display everything, change the tool-bar's
9915 height if there is room for more. */
9916 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
9917 && it
.current_y
< max_tool_bar_height
)
9918 change_height_p
= 1;
9920 row
= it
.glyph_row
- 1;
9922 /* If there are blank lines at the end, except for a partially
9923 visible blank line at the end that is smaller than
9924 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9925 if (!row
->displays_text_p
9926 && row
->height
>= FRAME_LINE_HEIGHT (f
))
9927 change_height_p
= 1;
9929 /* If row displays tool-bar items, but is partially visible,
9930 change the tool-bar's height. */
9931 if (row
->displays_text_p
9932 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
9933 && MATRIX_ROW_BOTTOM_Y (row
) < max_tool_bar_height
)
9934 change_height_p
= 1;
9936 /* Resize windows as needed by changing the `tool-bar-lines'
9939 && (nlines
= tool_bar_lines_needed (f
, &nrows
),
9940 nlines
!= WINDOW_TOTAL_LINES (w
)))
9942 extern Lisp_Object Qtool_bar_lines
;
9944 int old_height
= WINDOW_TOTAL_LINES (w
);
9946 XSETFRAME (frame
, f
);
9947 Fmodify_frame_parameters (frame
,
9948 Fcons (Fcons (Qtool_bar_lines
,
9949 make_number (nlines
)),
9951 if (WINDOW_TOTAL_LINES (w
) != old_height
)
9953 clear_glyph_matrix (w
->desired_matrix
);
9954 f
->n_tool_bar_rows
= nrows
;
9955 fonts_changed_p
= 1;
9960 return change_height_p
;
9964 /* Get information about the tool-bar item which is displayed in GLYPH
9965 on frame F. Return in *PROP_IDX the index where tool-bar item
9966 properties start in F->tool_bar_items. Value is zero if
9967 GLYPH doesn't display a tool-bar item. */
9970 tool_bar_item_info (f
, glyph
, prop_idx
)
9972 struct glyph
*glyph
;
9979 /* This function can be called asynchronously, which means we must
9980 exclude any possibility that Fget_text_property signals an
9982 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
9983 charpos
= max (0, charpos
);
9985 /* Get the text property `menu-item' at pos. The value of that
9986 property is the start index of this item's properties in
9987 F->tool_bar_items. */
9988 prop
= Fget_text_property (make_number (charpos
),
9989 Qmenu_item
, f
->current_tool_bar_string
);
9990 if (INTEGERP (prop
))
9992 *prop_idx
= XINT (prop
);
10002 /* Get information about the tool-bar item at position X/Y on frame F.
10003 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10004 the current matrix of the tool-bar window of F, or NULL if not
10005 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10006 item in F->tool_bar_items. Value is
10008 -1 if X/Y is not on a tool-bar item
10009 0 if X/Y is on the same item that was highlighted before.
10013 get_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
10016 struct glyph
**glyph
;
10017 int *hpos
, *vpos
, *prop_idx
;
10019 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10020 struct window
*w
= XWINDOW (f
->tool_bar_window
);
10023 /* Find the glyph under X/Y. */
10024 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
10025 if (*glyph
== NULL
)
10028 /* Get the start of this tool-bar item's properties in
10029 f->tool_bar_items. */
10030 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
10033 /* Is mouse on the highlighted item? */
10034 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
10035 && *vpos
>= dpyinfo
->mouse_face_beg_row
10036 && *vpos
<= dpyinfo
->mouse_face_end_row
10037 && (*vpos
> dpyinfo
->mouse_face_beg_row
10038 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
10039 && (*vpos
< dpyinfo
->mouse_face_end_row
10040 || *hpos
< dpyinfo
->mouse_face_end_col
10041 || dpyinfo
->mouse_face_past_end
))
10049 Handle mouse button event on the tool-bar of frame F, at
10050 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10051 0 for button release. MODIFIERS is event modifiers for button
10055 handle_tool_bar_click (f
, x
, y
, down_p
, modifiers
)
10058 unsigned int modifiers
;
10060 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10061 struct window
*w
= XWINDOW (f
->tool_bar_window
);
10062 int hpos
, vpos
, prop_idx
;
10063 struct glyph
*glyph
;
10064 Lisp_Object enabled_p
;
10066 /* If not on the highlighted tool-bar item, return. */
10067 frame_to_window_pixel_xy (w
, &x
, &y
);
10068 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
10071 /* If item is disabled, do nothing. */
10072 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
10073 if (NILP (enabled_p
))
10078 /* Show item in pressed state. */
10079 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
10080 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
10081 last_tool_bar_item
= prop_idx
;
10085 Lisp_Object key
, frame
;
10086 struct input_event event
;
10087 EVENT_INIT (event
);
10089 /* Show item in released state. */
10090 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
10091 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
10093 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
10095 XSETFRAME (frame
, f
);
10096 event
.kind
= TOOL_BAR_EVENT
;
10097 event
.frame_or_window
= frame
;
10099 kbd_buffer_store_event (&event
);
10101 event
.kind
= TOOL_BAR_EVENT
;
10102 event
.frame_or_window
= frame
;
10104 event
.modifiers
= modifiers
;
10105 kbd_buffer_store_event (&event
);
10106 last_tool_bar_item
= -1;
10111 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10112 tool-bar window-relative coordinates X/Y. Called from
10113 note_mouse_highlight. */
10116 note_tool_bar_highlight (f
, x
, y
)
10120 Lisp_Object window
= f
->tool_bar_window
;
10121 struct window
*w
= XWINDOW (window
);
10122 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10124 struct glyph
*glyph
;
10125 struct glyph_row
*row
;
10127 Lisp_Object enabled_p
;
10129 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
10130 int mouse_down_p
, rc
;
10132 /* Function note_mouse_highlight is called with negative x(y
10133 values when mouse moves outside of the frame. */
10134 if (x
<= 0 || y
<= 0)
10136 clear_mouse_face (dpyinfo
);
10140 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
10143 /* Not on tool-bar item. */
10144 clear_mouse_face (dpyinfo
);
10148 /* On same tool-bar item as before. */
10149 goto set_help_echo
;
10151 clear_mouse_face (dpyinfo
);
10153 /* Mouse is down, but on different tool-bar item? */
10154 mouse_down_p
= (dpyinfo
->grabbed
10155 && f
== last_mouse_frame
10156 && FRAME_LIVE_P (f
));
10158 && last_tool_bar_item
!= prop_idx
)
10161 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
10162 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
10164 /* If tool-bar item is not enabled, don't highlight it. */
10165 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
10166 if (!NILP (enabled_p
))
10168 /* Compute the x-position of the glyph. In front and past the
10169 image is a space. We include this in the highlighted area. */
10170 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
10171 for (i
= x
= 0; i
< hpos
; ++i
)
10172 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
10174 /* Record this as the current active region. */
10175 dpyinfo
->mouse_face_beg_col
= hpos
;
10176 dpyinfo
->mouse_face_beg_row
= vpos
;
10177 dpyinfo
->mouse_face_beg_x
= x
;
10178 dpyinfo
->mouse_face_beg_y
= row
->y
;
10179 dpyinfo
->mouse_face_past_end
= 0;
10181 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
10182 dpyinfo
->mouse_face_end_row
= vpos
;
10183 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
10184 dpyinfo
->mouse_face_end_y
= row
->y
;
10185 dpyinfo
->mouse_face_window
= window
;
10186 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
10188 /* Display it as active. */
10189 show_mouse_face (dpyinfo
, draw
);
10190 dpyinfo
->mouse_face_image_state
= draw
;
10195 /* Set help_echo_string to a help string to display for this tool-bar item.
10196 XTread_socket does the rest. */
10197 help_echo_object
= help_echo_window
= Qnil
;
10198 help_echo_pos
= -1;
10199 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
10200 if (NILP (help_echo_string
))
10201 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
10204 #endif /* HAVE_WINDOW_SYSTEM */
10208 /************************************************************************
10209 Horizontal scrolling
10210 ************************************************************************/
10212 static int hscroll_window_tree
P_ ((Lisp_Object
));
10213 static int hscroll_windows
P_ ((Lisp_Object
));
10215 /* For all leaf windows in the window tree rooted at WINDOW, set their
10216 hscroll value so that PT is (i) visible in the window, and (ii) so
10217 that it is not within a certain margin at the window's left and
10218 right border. Value is non-zero if any window's hscroll has been
10222 hscroll_window_tree (window
)
10223 Lisp_Object window
;
10225 int hscrolled_p
= 0;
10226 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
10227 int hscroll_step_abs
= 0;
10228 double hscroll_step_rel
= 0;
10230 if (hscroll_relative_p
)
10232 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
10233 if (hscroll_step_rel
< 0)
10235 hscroll_relative_p
= 0;
10236 hscroll_step_abs
= 0;
10239 else if (INTEGERP (Vhscroll_step
))
10241 hscroll_step_abs
= XINT (Vhscroll_step
);
10242 if (hscroll_step_abs
< 0)
10243 hscroll_step_abs
= 0;
10246 hscroll_step_abs
= 0;
10248 while (WINDOWP (window
))
10250 struct window
*w
= XWINDOW (window
);
10252 if (WINDOWP (w
->hchild
))
10253 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
10254 else if (WINDOWP (w
->vchild
))
10255 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
10256 else if (w
->cursor
.vpos
>= 0)
10259 int text_area_width
;
10260 struct glyph_row
*current_cursor_row
10261 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
10262 struct glyph_row
*desired_cursor_row
10263 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
10264 struct glyph_row
*cursor_row
10265 = (desired_cursor_row
->enabled_p
10266 ? desired_cursor_row
10267 : current_cursor_row
);
10269 text_area_width
= window_box_width (w
, TEXT_AREA
);
10271 /* Scroll when cursor is inside this scroll margin. */
10272 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
10274 if ((XFASTINT (w
->hscroll
)
10275 && w
->cursor
.x
<= h_margin
)
10276 || (cursor_row
->enabled_p
10277 && cursor_row
->truncated_on_right_p
10278 && (w
->cursor
.x
>= text_area_width
- h_margin
)))
10282 struct buffer
*saved_current_buffer
;
10286 /* Find point in a display of infinite width. */
10287 saved_current_buffer
= current_buffer
;
10288 current_buffer
= XBUFFER (w
->buffer
);
10290 if (w
== XWINDOW (selected_window
))
10291 pt
= BUF_PT (current_buffer
);
10294 pt
= marker_position (w
->pointm
);
10295 pt
= max (BEGV
, pt
);
10299 /* Move iterator to pt starting at cursor_row->start in
10300 a line with infinite width. */
10301 init_to_row_start (&it
, w
, cursor_row
);
10302 it
.last_visible_x
= INFINITY
;
10303 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
10304 current_buffer
= saved_current_buffer
;
10306 /* Position cursor in window. */
10307 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
10308 hscroll
= max (0, (it
.current_x
10309 - (ITERATOR_AT_END_OF_LINE_P (&it
)
10310 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
10311 : (text_area_width
/ 2))))
10312 / FRAME_COLUMN_WIDTH (it
.f
);
10313 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
10315 if (hscroll_relative_p
)
10316 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
10319 wanted_x
= text_area_width
10320 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
10323 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
10327 if (hscroll_relative_p
)
10328 wanted_x
= text_area_width
* hscroll_step_rel
10331 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
10334 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
10336 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
10338 /* Don't call Fset_window_hscroll if value hasn't
10339 changed because it will prevent redisplay
10341 if (XFASTINT (w
->hscroll
) != hscroll
)
10343 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
10344 w
->hscroll
= make_number (hscroll
);
10353 /* Value is non-zero if hscroll of any leaf window has been changed. */
10354 return hscrolled_p
;
10358 /* Set hscroll so that cursor is visible and not inside horizontal
10359 scroll margins for all windows in the tree rooted at WINDOW. See
10360 also hscroll_window_tree above. Value is non-zero if any window's
10361 hscroll has been changed. If it has, desired matrices on the frame
10362 of WINDOW are cleared. */
10365 hscroll_windows (window
)
10366 Lisp_Object window
;
10370 if (automatic_hscrolling_p
)
10372 hscrolled_p
= hscroll_window_tree (window
);
10374 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
10378 return hscrolled_p
;
10383 /************************************************************************
10385 ************************************************************************/
10387 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10388 to a non-zero value. This is sometimes handy to have in a debugger
10393 /* First and last unchanged row for try_window_id. */
10395 int debug_first_unchanged_at_end_vpos
;
10396 int debug_last_unchanged_at_beg_vpos
;
10398 /* Delta vpos and y. */
10400 int debug_dvpos
, debug_dy
;
10402 /* Delta in characters and bytes for try_window_id. */
10404 int debug_delta
, debug_delta_bytes
;
10406 /* Values of window_end_pos and window_end_vpos at the end of
10409 EMACS_INT debug_end_pos
, debug_end_vpos
;
10411 /* Append a string to W->desired_matrix->method. FMT is a printf
10412 format string. A1...A9 are a supplement for a variable-length
10413 argument list. If trace_redisplay_p is non-zero also printf the
10414 resulting string to stderr. */
10417 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
10420 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
10423 char *method
= w
->desired_matrix
->method
;
10424 int len
= strlen (method
);
10425 int size
= sizeof w
->desired_matrix
->method
;
10426 int remaining
= size
- len
- 1;
10428 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
10429 if (len
&& remaining
)
10432 --remaining
, ++len
;
10435 strncpy (method
+ len
, buffer
, remaining
);
10437 if (trace_redisplay_p
)
10438 fprintf (stderr
, "%p (%s): %s\n",
10440 ((BUFFERP (w
->buffer
)
10441 && STRINGP (XBUFFER (w
->buffer
)->name
))
10442 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
10447 #endif /* GLYPH_DEBUG */
10450 /* Value is non-zero if all changes in window W, which displays
10451 current_buffer, are in the text between START and END. START is a
10452 buffer position, END is given as a distance from Z. Used in
10453 redisplay_internal for display optimization. */
10456 text_outside_line_unchanged_p (w
, start
, end
)
10460 int unchanged_p
= 1;
10462 /* If text or overlays have changed, see where. */
10463 if (XFASTINT (w
->last_modified
) < MODIFF
10464 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
10466 /* Gap in the line? */
10467 if (GPT
< start
|| Z
- GPT
< end
)
10470 /* Changes start in front of the line, or end after it? */
10472 && (BEG_UNCHANGED
< start
- 1
10473 || END_UNCHANGED
< end
))
10476 /* If selective display, can't optimize if changes start at the
10477 beginning of the line. */
10479 && INTEGERP (current_buffer
->selective_display
)
10480 && XINT (current_buffer
->selective_display
) > 0
10481 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
10484 /* If there are overlays at the start or end of the line, these
10485 may have overlay strings with newlines in them. A change at
10486 START, for instance, may actually concern the display of such
10487 overlay strings as well, and they are displayed on different
10488 lines. So, quickly rule out this case. (For the future, it
10489 might be desirable to implement something more telling than
10490 just BEG/END_UNCHANGED.) */
10493 if (BEG
+ BEG_UNCHANGED
== start
10494 && overlay_touches_p (start
))
10496 if (END_UNCHANGED
== end
10497 && overlay_touches_p (Z
- end
))
10502 return unchanged_p
;
10506 /* Do a frame update, taking possible shortcuts into account. This is
10507 the main external entry point for redisplay.
10509 If the last redisplay displayed an echo area message and that message
10510 is no longer requested, we clear the echo area or bring back the
10511 mini-buffer if that is in use. */
10516 redisplay_internal (0);
10521 overlay_arrow_string_or_property (var
)
10526 if (val
= Fget (var
, Qoverlay_arrow_string
), STRINGP (val
))
10529 return Voverlay_arrow_string
;
10532 /* Return 1 if there are any overlay-arrows in current_buffer. */
10534 overlay_arrow_in_current_buffer_p ()
10538 for (vlist
= Voverlay_arrow_variable_list
;
10540 vlist
= XCDR (vlist
))
10542 Lisp_Object var
= XCAR (vlist
);
10545 if (!SYMBOLP (var
))
10547 val
= find_symbol_value (var
);
10549 && current_buffer
== XMARKER (val
)->buffer
)
10556 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
10560 overlay_arrows_changed_p ()
10564 for (vlist
= Voverlay_arrow_variable_list
;
10566 vlist
= XCDR (vlist
))
10568 Lisp_Object var
= XCAR (vlist
);
10569 Lisp_Object val
, pstr
;
10571 if (!SYMBOLP (var
))
10573 val
= find_symbol_value (var
);
10574 if (!MARKERP (val
))
10576 if (! EQ (COERCE_MARKER (val
),
10577 Fget (var
, Qlast_arrow_position
))
10578 || ! (pstr
= overlay_arrow_string_or_property (var
),
10579 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
10585 /* Mark overlay arrows to be updated on next redisplay. */
10588 update_overlay_arrows (up_to_date
)
10593 for (vlist
= Voverlay_arrow_variable_list
;
10595 vlist
= XCDR (vlist
))
10597 Lisp_Object var
= XCAR (vlist
);
10599 if (!SYMBOLP (var
))
10602 if (up_to_date
> 0)
10604 Lisp_Object val
= find_symbol_value (var
);
10605 Fput (var
, Qlast_arrow_position
,
10606 COERCE_MARKER (val
));
10607 Fput (var
, Qlast_arrow_string
,
10608 overlay_arrow_string_or_property (var
));
10610 else if (up_to_date
< 0
10611 || !NILP (Fget (var
, Qlast_arrow_position
)))
10613 Fput (var
, Qlast_arrow_position
, Qt
);
10614 Fput (var
, Qlast_arrow_string
, Qt
);
10620 /* Return overlay arrow string to display at row.
10621 Return integer (bitmap number) for arrow bitmap in left fringe.
10622 Return nil if no overlay arrow. */
10625 overlay_arrow_at_row (it
, row
)
10627 struct glyph_row
*row
;
10631 for (vlist
= Voverlay_arrow_variable_list
;
10633 vlist
= XCDR (vlist
))
10635 Lisp_Object var
= XCAR (vlist
);
10638 if (!SYMBOLP (var
))
10641 val
= find_symbol_value (var
);
10644 && current_buffer
== XMARKER (val
)->buffer
10645 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
10647 if (FRAME_WINDOW_P (it
->f
)
10648 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) > 0)
10650 #ifdef HAVE_WINDOW_SYSTEM
10651 if (val
= Fget (var
, Qoverlay_arrow_bitmap
), SYMBOLP (val
))
10654 if ((fringe_bitmap
= lookup_fringe_bitmap (val
)) != 0)
10655 return make_number (fringe_bitmap
);
10658 return make_number (-1); /* Use default arrow bitmap */
10660 return overlay_arrow_string_or_property (var
);
10667 /* Return 1 if point moved out of or into a composition. Otherwise
10668 return 0. PREV_BUF and PREV_PT are the last point buffer and
10669 position. BUF and PT are the current point buffer and position. */
10672 check_point_in_composition (prev_buf
, prev_pt
, buf
, pt
)
10673 struct buffer
*prev_buf
, *buf
;
10678 Lisp_Object buffer
;
10680 XSETBUFFER (buffer
, buf
);
10681 /* Check a composition at the last point if point moved within the
10683 if (prev_buf
== buf
)
10686 /* Point didn't move. */
10689 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
10690 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
10691 && COMPOSITION_VALID_P (start
, end
, prop
)
10692 && start
< prev_pt
&& end
> prev_pt
)
10693 /* The last point was within the composition. Return 1 iff
10694 point moved out of the composition. */
10695 return (pt
<= start
|| pt
>= end
);
10698 /* Check a composition at the current point. */
10699 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
10700 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
10701 && COMPOSITION_VALID_P (start
, end
, prop
)
10702 && start
< pt
&& end
> pt
);
10706 /* Reconsider the setting of B->clip_changed which is displayed
10710 reconsider_clip_changes (w
, b
)
10714 if (b
->clip_changed
10715 && !NILP (w
->window_end_valid
)
10716 && w
->current_matrix
->buffer
== b
10717 && w
->current_matrix
->zv
== BUF_ZV (b
)
10718 && w
->current_matrix
->begv
== BUF_BEGV (b
))
10719 b
->clip_changed
= 0;
10721 /* If display wasn't paused, and W is not a tool bar window, see if
10722 point has been moved into or out of a composition. In that case,
10723 we set b->clip_changed to 1 to force updating the screen. If
10724 b->clip_changed has already been set to 1, we can skip this
10726 if (!b
->clip_changed
10727 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
10731 if (w
== XWINDOW (selected_window
))
10732 pt
= BUF_PT (current_buffer
);
10734 pt
= marker_position (w
->pointm
);
10736 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
10737 || pt
!= XINT (w
->last_point
))
10738 && check_point_in_composition (w
->current_matrix
->buffer
,
10739 XINT (w
->last_point
),
10740 XBUFFER (w
->buffer
), pt
))
10741 b
->clip_changed
= 1;
10746 /* Select FRAME to forward the values of frame-local variables into C
10747 variables so that the redisplay routines can access those values
10751 select_frame_for_redisplay (frame
)
10754 Lisp_Object tail
, sym
, val
;
10755 Lisp_Object old
= selected_frame
;
10757 selected_frame
= frame
;
10759 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
10760 if (CONSP (XCAR (tail
))
10761 && (sym
= XCAR (XCAR (tail
)),
10763 && (sym
= indirect_variable (sym
),
10764 val
= SYMBOL_VALUE (sym
),
10765 (BUFFER_LOCAL_VALUEP (val
)
10766 || SOME_BUFFER_LOCAL_VALUEP (val
)))
10767 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
10768 /* Use find_symbol_value rather than Fsymbol_value
10769 to avoid an error if it is void. */
10770 find_symbol_value (sym
);
10772 for (tail
= XFRAME (old
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
10773 if (CONSP (XCAR (tail
))
10774 && (sym
= XCAR (XCAR (tail
)),
10776 && (sym
= indirect_variable (sym
),
10777 val
= SYMBOL_VALUE (sym
),
10778 (BUFFER_LOCAL_VALUEP (val
)
10779 || SOME_BUFFER_LOCAL_VALUEP (val
)))
10780 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
10781 find_symbol_value (sym
);
10785 #define STOP_POLLING \
10786 do { if (! polling_stopped_here) stop_polling (); \
10787 polling_stopped_here = 1; } while (0)
10789 #define RESUME_POLLING \
10790 do { if (polling_stopped_here) start_polling (); \
10791 polling_stopped_here = 0; } while (0)
10794 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
10795 response to any user action; therefore, we should preserve the echo
10796 area. (Actually, our caller does that job.) Perhaps in the future
10797 avoid recentering windows if it is not necessary; currently that
10798 causes some problems. */
10801 redisplay_internal (preserve_echo_area
)
10802 int preserve_echo_area
;
10804 struct window
*w
= XWINDOW (selected_window
);
10807 int must_finish
= 0;
10808 struct text_pos tlbufpos
, tlendpos
;
10809 int number_of_visible_frames
;
10812 int polling_stopped_here
= 0;
10814 /* Non-zero means redisplay has to consider all windows on all
10815 frames. Zero means, only selected_window is considered. */
10816 int consider_all_windows_p
;
10818 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
10820 /* No redisplay if running in batch mode or frame is not yet fully
10821 initialized, or redisplay is explicitly turned off by setting
10822 Vinhibit_redisplay. */
10824 || !NILP (Vinhibit_redisplay
))
10827 /* Don't examine these until after testing Vinhibit_redisplay.
10828 When Emacs is shutting down, perhaps because its connection to
10829 X has dropped, we should not look at them at all. */
10830 f
= XFRAME (w
->frame
);
10831 sf
= SELECTED_FRAME ();
10833 if (!f
->glyphs_initialized_p
)
10836 /* The flag redisplay_performed_directly_p is set by
10837 direct_output_for_insert when it already did the whole screen
10838 update necessary. */
10839 if (redisplay_performed_directly_p
)
10841 redisplay_performed_directly_p
= 0;
10842 if (!hscroll_windows (selected_window
))
10846 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
10847 if (popup_activated ())
10851 /* I don't think this happens but let's be paranoid. */
10852 if (redisplaying_p
)
10855 /* Record a function that resets redisplaying_p to its old value
10856 when we leave this function. */
10857 count
= SPECPDL_INDEX ();
10858 record_unwind_protect (unwind_redisplay
,
10859 Fcons (make_number (redisplaying_p
), selected_frame
));
10861 specbind (Qinhibit_free_realized_faces
, Qnil
);
10864 Lisp_Object tail
, frame
;
10866 FOR_EACH_FRAME (tail
, frame
)
10868 struct frame
*f
= XFRAME (frame
);
10869 f
->already_hscrolled_p
= 0;
10875 reconsider_clip_changes (w
, current_buffer
);
10876 last_escape_glyph_frame
= NULL
;
10877 last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
10879 /* If new fonts have been loaded that make a glyph matrix adjustment
10880 necessary, do it. */
10881 if (fonts_changed_p
)
10883 adjust_glyphs (NULL
);
10884 ++windows_or_buffers_changed
;
10885 fonts_changed_p
= 0;
10888 /* If face_change_count is non-zero, init_iterator will free all
10889 realized faces, which includes the faces referenced from current
10890 matrices. So, we can't reuse current matrices in this case. */
10891 if (face_change_count
)
10892 ++windows_or_buffers_changed
;
10894 if (! FRAME_WINDOW_P (sf
)
10895 && previous_terminal_frame
!= sf
)
10897 /* Since frames on an ASCII terminal share the same display
10898 area, displaying a different frame means redisplay the whole
10900 windows_or_buffers_changed
++;
10901 SET_FRAME_GARBAGED (sf
);
10902 XSETFRAME (Vterminal_frame
, sf
);
10904 previous_terminal_frame
= sf
;
10906 /* Set the visible flags for all frames. Do this before checking
10907 for resized or garbaged frames; they want to know if their frames
10908 are visible. See the comment in frame.h for
10909 FRAME_SAMPLE_VISIBILITY. */
10911 Lisp_Object tail
, frame
;
10913 number_of_visible_frames
= 0;
10915 FOR_EACH_FRAME (tail
, frame
)
10917 struct frame
*f
= XFRAME (frame
);
10919 FRAME_SAMPLE_VISIBILITY (f
);
10920 if (FRAME_VISIBLE_P (f
))
10921 ++number_of_visible_frames
;
10922 clear_desired_matrices (f
);
10926 /* Notice any pending interrupt request to change frame size. */
10927 do_pending_window_change (1);
10929 /* Clear frames marked as garbaged. */
10930 if (frame_garbaged
)
10931 clear_garbaged_frames ();
10933 /* Build menubar and tool-bar items. */
10934 if (NILP (Vmemory_full
))
10935 prepare_menu_bars ();
10937 if (windows_or_buffers_changed
)
10938 update_mode_lines
++;
10940 /* Detect case that we need to write or remove a star in the mode line. */
10941 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
10943 w
->update_mode_line
= Qt
;
10944 if (buffer_shared
> 1)
10945 update_mode_lines
++;
10948 /* If %c is in the mode line, update it if needed. */
10949 if (!NILP (w
->column_number_displayed
)
10950 /* This alternative quickly identifies a common case
10951 where no change is needed. */
10952 && !(PT
== XFASTINT (w
->last_point
)
10953 && XFASTINT (w
->last_modified
) >= MODIFF
10954 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
10955 && (XFASTINT (w
->column_number_displayed
)
10956 != (int) current_column ())) /* iftc */
10957 w
->update_mode_line
= Qt
;
10959 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
10961 /* The variable buffer_shared is set in redisplay_window and
10962 indicates that we redisplay a buffer in different windows. See
10964 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
10965 || cursor_type_changed
);
10967 /* If specs for an arrow have changed, do thorough redisplay
10968 to ensure we remove any arrow that should no longer exist. */
10969 if (overlay_arrows_changed_p ())
10970 consider_all_windows_p
= windows_or_buffers_changed
= 1;
10972 /* Normally the message* functions will have already displayed and
10973 updated the echo area, but the frame may have been trashed, or
10974 the update may have been preempted, so display the echo area
10975 again here. Checking message_cleared_p captures the case that
10976 the echo area should be cleared. */
10977 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
10978 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
10979 || (message_cleared_p
10980 && minibuf_level
== 0
10981 /* If the mini-window is currently selected, this means the
10982 echo-area doesn't show through. */
10983 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
10985 int window_height_changed_p
= echo_area_display (0);
10988 /* If we don't display the current message, don't clear the
10989 message_cleared_p flag, because, if we did, we wouldn't clear
10990 the echo area in the next redisplay which doesn't preserve
10992 if (!display_last_displayed_message_p
)
10993 message_cleared_p
= 0;
10995 if (fonts_changed_p
)
10997 else if (window_height_changed_p
)
10999 consider_all_windows_p
= 1;
11000 ++update_mode_lines
;
11001 ++windows_or_buffers_changed
;
11003 /* If window configuration was changed, frames may have been
11004 marked garbaged. Clear them or we will experience
11005 surprises wrt scrolling. */
11006 if (frame_garbaged
)
11007 clear_garbaged_frames ();
11010 else if (EQ (selected_window
, minibuf_window
)
11011 && (current_buffer
->clip_changed
11012 || XFASTINT (w
->last_modified
) < MODIFF
11013 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
11014 && resize_mini_window (w
, 0))
11016 /* Resized active mini-window to fit the size of what it is
11017 showing if its contents might have changed. */
11019 consider_all_windows_p
= 1;
11020 ++windows_or_buffers_changed
;
11021 ++update_mode_lines
;
11023 /* If window configuration was changed, frames may have been
11024 marked garbaged. Clear them or we will experience
11025 surprises wrt scrolling. */
11026 if (frame_garbaged
)
11027 clear_garbaged_frames ();
11031 /* If showing the region, and mark has changed, we must redisplay
11032 the whole window. The assignment to this_line_start_pos prevents
11033 the optimization directly below this if-statement. */
11034 if (((!NILP (Vtransient_mark_mode
)
11035 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
11036 != !NILP (w
->region_showing
))
11037 || (!NILP (w
->region_showing
)
11038 && !EQ (w
->region_showing
,
11039 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
11040 CHARPOS (this_line_start_pos
) = 0;
11042 /* Optimize the case that only the line containing the cursor in the
11043 selected window has changed. Variables starting with this_ are
11044 set in display_line and record information about the line
11045 containing the cursor. */
11046 tlbufpos
= this_line_start_pos
;
11047 tlendpos
= this_line_end_pos
;
11048 if (!consider_all_windows_p
11049 && CHARPOS (tlbufpos
) > 0
11050 && NILP (w
->update_mode_line
)
11051 && !current_buffer
->clip_changed
11052 && !current_buffer
->prevent_redisplay_optimizations_p
11053 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
11054 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
11055 /* Make sure recorded data applies to current buffer, etc. */
11056 && this_line_buffer
== current_buffer
11057 && current_buffer
== XBUFFER (w
->buffer
)
11058 && NILP (w
->force_start
)
11059 && NILP (w
->optional_new_start
)
11060 /* Point must be on the line that we have info recorded about. */
11061 && PT
>= CHARPOS (tlbufpos
)
11062 && PT
<= Z
- CHARPOS (tlendpos
)
11063 /* All text outside that line, including its final newline,
11064 must be unchanged */
11065 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
11066 CHARPOS (tlendpos
)))
11068 if (CHARPOS (tlbufpos
) > BEGV
11069 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
11070 && (CHARPOS (tlbufpos
) == ZV
11071 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
11072 /* Former continuation line has disappeared by becoming empty */
11074 else if (XFASTINT (w
->last_modified
) < MODIFF
11075 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
11076 || MINI_WINDOW_P (w
))
11078 /* We have to handle the case of continuation around a
11079 wide-column character (See the comment in indent.c around
11082 For instance, in the following case:
11084 -------- Insert --------
11085 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11086 J_I_ ==> J_I_ `^^' are cursors.
11090 As we have to redraw the line above, we should goto cancel. */
11093 int line_height_before
= this_line_pixel_height
;
11095 /* Note that start_display will handle the case that the
11096 line starting at tlbufpos is a continuation lines. */
11097 start_display (&it
, w
, tlbufpos
);
11099 /* Implementation note: It this still necessary? */
11100 if (it
.current_x
!= this_line_start_x
)
11103 TRACE ((stderr
, "trying display optimization 1\n"));
11104 w
->cursor
.vpos
= -1;
11105 overlay_arrow_seen
= 0;
11106 it
.vpos
= this_line_vpos
;
11107 it
.current_y
= this_line_y
;
11108 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
11109 display_line (&it
);
11111 /* If line contains point, is not continued,
11112 and ends at same distance from eob as before, we win */
11113 if (w
->cursor
.vpos
>= 0
11114 /* Line is not continued, otherwise this_line_start_pos
11115 would have been set to 0 in display_line. */
11116 && CHARPOS (this_line_start_pos
)
11117 /* Line ends as before. */
11118 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
11119 /* Line has same height as before. Otherwise other lines
11120 would have to be shifted up or down. */
11121 && this_line_pixel_height
== line_height_before
)
11123 /* If this is not the window's last line, we must adjust
11124 the charstarts of the lines below. */
11125 if (it
.current_y
< it
.last_visible_y
)
11127 struct glyph_row
*row
11128 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
11129 int delta
, delta_bytes
;
11131 if (Z
- CHARPOS (tlendpos
) == ZV
)
11133 /* This line ends at end of (accessible part of)
11134 buffer. There is no newline to count. */
11136 - CHARPOS (tlendpos
)
11137 - MATRIX_ROW_START_CHARPOS (row
));
11138 delta_bytes
= (Z_BYTE
11139 - BYTEPOS (tlendpos
)
11140 - MATRIX_ROW_START_BYTEPOS (row
));
11144 /* This line ends in a newline. Must take
11145 account of the newline and the rest of the
11146 text that follows. */
11148 - CHARPOS (tlendpos
)
11149 - MATRIX_ROW_START_CHARPOS (row
));
11150 delta_bytes
= (Z_BYTE
11151 - BYTEPOS (tlendpos
)
11152 - MATRIX_ROW_START_BYTEPOS (row
));
11155 increment_matrix_positions (w
->current_matrix
,
11156 this_line_vpos
+ 1,
11157 w
->current_matrix
->nrows
,
11158 delta
, delta_bytes
);
11161 /* If this row displays text now but previously didn't,
11162 or vice versa, w->window_end_vpos may have to be
11164 if ((it
.glyph_row
- 1)->displays_text_p
)
11166 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
11167 XSETINT (w
->window_end_vpos
, this_line_vpos
);
11169 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
11170 && this_line_vpos
> 0)
11171 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
11172 w
->window_end_valid
= Qnil
;
11174 /* Update hint: No need to try to scroll in update_window. */
11175 w
->desired_matrix
->no_scrolling_p
= 1;
11178 *w
->desired_matrix
->method
= 0;
11179 debug_method_add (w
, "optimization 1");
11181 #ifdef HAVE_WINDOW_SYSTEM
11182 update_window_fringes (w
, 0);
11189 else if (/* Cursor position hasn't changed. */
11190 PT
== XFASTINT (w
->last_point
)
11191 /* Make sure the cursor was last displayed
11192 in this window. Otherwise we have to reposition it. */
11193 && 0 <= w
->cursor
.vpos
11194 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
11198 do_pending_window_change (1);
11200 /* We used to always goto end_of_redisplay here, but this
11201 isn't enough if we have a blinking cursor. */
11202 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
11203 goto end_of_redisplay
;
11207 /* If highlighting the region, or if the cursor is in the echo area,
11208 then we can't just move the cursor. */
11209 else if (! (!NILP (Vtransient_mark_mode
)
11210 && !NILP (current_buffer
->mark_active
))
11211 && (EQ (selected_window
, current_buffer
->last_selected_window
)
11212 || highlight_nonselected_windows
)
11213 && NILP (w
->region_showing
)
11214 && NILP (Vshow_trailing_whitespace
)
11215 && !cursor_in_echo_area
)
11218 struct glyph_row
*row
;
11220 /* Skip from tlbufpos to PT and see where it is. Note that
11221 PT may be in invisible text. If so, we will end at the
11222 next visible position. */
11223 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
11224 NULL
, DEFAULT_FACE_ID
);
11225 it
.current_x
= this_line_start_x
;
11226 it
.current_y
= this_line_y
;
11227 it
.vpos
= this_line_vpos
;
11229 /* The call to move_it_to stops in front of PT, but
11230 moves over before-strings. */
11231 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
11233 if (it
.vpos
== this_line_vpos
11234 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
11237 xassert (this_line_vpos
== it
.vpos
);
11238 xassert (this_line_y
== it
.current_y
);
11239 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11241 *w
->desired_matrix
->method
= 0;
11242 debug_method_add (w
, "optimization 3");
11251 /* Text changed drastically or point moved off of line. */
11252 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
11255 CHARPOS (this_line_start_pos
) = 0;
11256 consider_all_windows_p
|= buffer_shared
> 1;
11257 ++clear_face_cache_count
;
11258 #ifdef HAVE_WINDOW_SYSTEM
11259 ++clear_image_cache_count
;
11262 /* Build desired matrices, and update the display. If
11263 consider_all_windows_p is non-zero, do it for all windows on all
11264 frames. Otherwise do it for selected_window, only. */
11266 if (consider_all_windows_p
)
11268 Lisp_Object tail
, frame
;
11270 FOR_EACH_FRAME (tail
, frame
)
11271 XFRAME (frame
)->updated_p
= 0;
11273 /* Recompute # windows showing selected buffer. This will be
11274 incremented each time such a window is displayed. */
11277 FOR_EACH_FRAME (tail
, frame
)
11279 struct frame
*f
= XFRAME (frame
);
11281 if (FRAME_WINDOW_P (f
) || f
== sf
)
11283 if (! EQ (frame
, selected_frame
))
11284 /* Select the frame, for the sake of frame-local
11286 select_frame_for_redisplay (frame
);
11288 /* Mark all the scroll bars to be removed; we'll redeem
11289 the ones we want when we redisplay their windows. */
11290 if (condemn_scroll_bars_hook
)
11291 condemn_scroll_bars_hook (f
);
11293 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
11294 redisplay_windows (FRAME_ROOT_WINDOW (f
));
11296 /* Any scroll bars which redisplay_windows should have
11297 nuked should now go away. */
11298 if (judge_scroll_bars_hook
)
11299 judge_scroll_bars_hook (f
);
11301 /* If fonts changed, display again. */
11302 /* ??? rms: I suspect it is a mistake to jump all the way
11303 back to retry here. It should just retry this frame. */
11304 if (fonts_changed_p
)
11307 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
11309 /* See if we have to hscroll. */
11310 if (!f
->already_hscrolled_p
)
11312 f
->already_hscrolled_p
= 1;
11313 if (hscroll_windows (f
->root_window
))
11317 /* Prevent various kinds of signals during display
11318 update. stdio is not robust about handling
11319 signals, which can cause an apparent I/O
11321 if (interrupt_input
)
11322 unrequest_sigio ();
11325 /* Update the display. */
11326 set_window_update_flags (XWINDOW (f
->root_window
), 1);
11327 pause
|= update_frame (f
, 0, 0);
11328 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
11340 /* Do the mark_window_display_accurate after all windows have
11341 been redisplayed because this call resets flags in buffers
11342 which are needed for proper redisplay. */
11343 FOR_EACH_FRAME (tail
, frame
)
11345 struct frame
*f
= XFRAME (frame
);
11348 mark_window_display_accurate (f
->root_window
, 1);
11349 if (frame_up_to_date_hook
)
11350 frame_up_to_date_hook (f
);
11355 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
11357 Lisp_Object mini_window
;
11358 struct frame
*mini_frame
;
11360 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
11361 /* Use list_of_error, not Qerror, so that
11362 we catch only errors and don't run the debugger. */
11363 internal_condition_case_1 (redisplay_window_1
, selected_window
,
11365 redisplay_window_error
);
11367 /* Compare desired and current matrices, perform output. */
11370 /* If fonts changed, display again. */
11371 if (fonts_changed_p
)
11374 /* Prevent various kinds of signals during display update.
11375 stdio is not robust about handling signals,
11376 which can cause an apparent I/O error. */
11377 if (interrupt_input
)
11378 unrequest_sigio ();
11381 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
11383 if (hscroll_windows (selected_window
))
11386 XWINDOW (selected_window
)->must_be_updated_p
= 1;
11387 pause
= update_frame (sf
, 0, 0);
11390 /* We may have called echo_area_display at the top of this
11391 function. If the echo area is on another frame, that may
11392 have put text on a frame other than the selected one, so the
11393 above call to update_frame would not have caught it. Catch
11395 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
11396 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
11398 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
11400 XWINDOW (mini_window
)->must_be_updated_p
= 1;
11401 pause
|= update_frame (mini_frame
, 0, 0);
11402 if (!pause
&& hscroll_windows (mini_window
))
11407 /* If display was paused because of pending input, make sure we do a
11408 thorough update the next time. */
11411 /* Prevent the optimization at the beginning of
11412 redisplay_internal that tries a single-line update of the
11413 line containing the cursor in the selected window. */
11414 CHARPOS (this_line_start_pos
) = 0;
11416 /* Let the overlay arrow be updated the next time. */
11417 update_overlay_arrows (0);
11419 /* If we pause after scrolling, some rows in the current
11420 matrices of some windows are not valid. */
11421 if (!WINDOW_FULL_WIDTH_P (w
)
11422 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
11423 update_mode_lines
= 1;
11427 if (!consider_all_windows_p
)
11429 /* This has already been done above if
11430 consider_all_windows_p is set. */
11431 mark_window_display_accurate_1 (w
, 1);
11433 /* Say overlay arrows are up to date. */
11434 update_overlay_arrows (1);
11436 if (frame_up_to_date_hook
!= 0)
11437 frame_up_to_date_hook (sf
);
11440 update_mode_lines
= 0;
11441 windows_or_buffers_changed
= 0;
11442 cursor_type_changed
= 0;
11445 /* Start SIGIO interrupts coming again. Having them off during the
11446 code above makes it less likely one will discard output, but not
11447 impossible, since there might be stuff in the system buffer here.
11448 But it is much hairier to try to do anything about that. */
11449 if (interrupt_input
)
11453 /* If a frame has become visible which was not before, redisplay
11454 again, so that we display it. Expose events for such a frame
11455 (which it gets when becoming visible) don't call the parts of
11456 redisplay constructing glyphs, so simply exposing a frame won't
11457 display anything in this case. So, we have to display these
11458 frames here explicitly. */
11461 Lisp_Object tail
, frame
;
11464 FOR_EACH_FRAME (tail
, frame
)
11466 int this_is_visible
= 0;
11468 if (XFRAME (frame
)->visible
)
11469 this_is_visible
= 1;
11470 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
11471 if (XFRAME (frame
)->visible
)
11472 this_is_visible
= 1;
11474 if (this_is_visible
)
11478 if (new_count
!= number_of_visible_frames
)
11479 windows_or_buffers_changed
++;
11482 /* Change frame size now if a change is pending. */
11483 do_pending_window_change (1);
11485 /* If we just did a pending size change, or have additional
11486 visible frames, redisplay again. */
11487 if (windows_or_buffers_changed
&& !pause
)
11490 /* Clear the face cache eventually. */
11491 if (consider_all_windows_p
)
11493 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
11495 clear_face_cache (0);
11496 clear_face_cache_count
= 0;
11498 #ifdef HAVE_WINDOW_SYSTEM
11499 if (clear_image_cache_count
> CLEAR_IMAGE_CACHE_COUNT
)
11501 Lisp_Object tail
, frame
;
11502 FOR_EACH_FRAME (tail
, frame
)
11504 struct frame
*f
= XFRAME (frame
);
11505 if (FRAME_WINDOW_P (f
))
11506 clear_image_cache (f
, 0);
11508 clear_image_cache_count
= 0;
11510 #endif /* HAVE_WINDOW_SYSTEM */
11514 unbind_to (count
, Qnil
);
11519 /* Redisplay, but leave alone any recent echo area message unless
11520 another message has been requested in its place.
11522 This is useful in situations where you need to redisplay but no
11523 user action has occurred, making it inappropriate for the message
11524 area to be cleared. See tracking_off and
11525 wait_reading_process_output for examples of these situations.
11527 FROM_WHERE is an integer saying from where this function was
11528 called. This is useful for debugging. */
11531 redisplay_preserve_echo_area (from_where
)
11534 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
11536 if (!NILP (echo_area_buffer
[1]))
11538 /* We have a previously displayed message, but no current
11539 message. Redisplay the previous message. */
11540 display_last_displayed_message_p
= 1;
11541 redisplay_internal (1);
11542 display_last_displayed_message_p
= 0;
11545 redisplay_internal (1);
11547 if (rif
!= NULL
&& rif
->flush_display_optional
)
11548 rif
->flush_display_optional (NULL
);
11552 /* Function registered with record_unwind_protect in
11553 redisplay_internal. Reset redisplaying_p to the value it had
11554 before redisplay_internal was called, and clear
11555 prevent_freeing_realized_faces_p. It also selects the previously
11559 unwind_redisplay (val
)
11562 Lisp_Object old_redisplaying_p
, old_frame
;
11564 old_redisplaying_p
= XCAR (val
);
11565 redisplaying_p
= XFASTINT (old_redisplaying_p
);
11566 old_frame
= XCDR (val
);
11567 if (! EQ (old_frame
, selected_frame
))
11568 select_frame_for_redisplay (old_frame
);
11573 /* Mark the display of window W as accurate or inaccurate. If
11574 ACCURATE_P is non-zero mark display of W as accurate. If
11575 ACCURATE_P is zero, arrange for W to be redisplayed the next time
11576 redisplay_internal is called. */
11579 mark_window_display_accurate_1 (w
, accurate_p
)
11583 if (BUFFERP (w
->buffer
))
11585 struct buffer
*b
= XBUFFER (w
->buffer
);
11588 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
11589 w
->last_overlay_modified
11590 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
11592 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
11596 b
->clip_changed
= 0;
11597 b
->prevent_redisplay_optimizations_p
= 0;
11599 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
11600 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
11601 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
11602 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
11604 w
->current_matrix
->buffer
= b
;
11605 w
->current_matrix
->begv
= BUF_BEGV (b
);
11606 w
->current_matrix
->zv
= BUF_ZV (b
);
11608 w
->last_cursor
= w
->cursor
;
11609 w
->last_cursor_off_p
= w
->cursor_off_p
;
11611 if (w
== XWINDOW (selected_window
))
11612 w
->last_point
= make_number (BUF_PT (b
));
11614 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
11620 w
->window_end_valid
= w
->buffer
;
11621 #if 0 /* This is incorrect with variable-height lines. */
11622 xassert (XINT (w
->window_end_vpos
)
11623 < (WINDOW_TOTAL_LINES (w
)
11624 - (WINDOW_WANTS_MODELINE_P (w
) ? 1 : 0)));
11626 w
->update_mode_line
= Qnil
;
11631 /* Mark the display of windows in the window tree rooted at WINDOW as
11632 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
11633 windows as accurate. If ACCURATE_P is zero, arrange for windows to
11634 be redisplayed the next time redisplay_internal is called. */
11637 mark_window_display_accurate (window
, accurate_p
)
11638 Lisp_Object window
;
11643 for (; !NILP (window
); window
= w
->next
)
11645 w
= XWINDOW (window
);
11646 mark_window_display_accurate_1 (w
, accurate_p
);
11648 if (!NILP (w
->vchild
))
11649 mark_window_display_accurate (w
->vchild
, accurate_p
);
11650 if (!NILP (w
->hchild
))
11651 mark_window_display_accurate (w
->hchild
, accurate_p
);
11656 update_overlay_arrows (1);
11660 /* Force a thorough redisplay the next time by setting
11661 last_arrow_position and last_arrow_string to t, which is
11662 unequal to any useful value of Voverlay_arrow_... */
11663 update_overlay_arrows (-1);
11668 /* Return value in display table DP (Lisp_Char_Table *) for character
11669 C. Since a display table doesn't have any parent, we don't have to
11670 follow parent. Do not call this function directly but use the
11671 macro DISP_CHAR_VECTOR. */
11674 disp_char_vector (dp
, c
)
11675 struct Lisp_Char_Table
*dp
;
11681 if (SINGLE_BYTE_CHAR_P (c
))
11682 return (dp
->contents
[c
]);
11684 SPLIT_CHAR (c
, code
[0], code
[1], code
[2]);
11687 else if (code
[2] < 32)
11690 /* Here, the possible range of code[0] (== charset ID) is
11691 128..max_charset. Since the top level char table contains data
11692 for multibyte characters after 256th element, we must increment
11693 code[0] by 128 to get a correct index. */
11695 code
[3] = -1; /* anchor */
11697 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
11699 val
= dp
->contents
[code
[i
]];
11700 if (!SUB_CHAR_TABLE_P (val
))
11701 return (NILP (val
) ? dp
->defalt
: val
);
11704 /* Here, val is a sub char table. We return the default value of
11706 return (dp
->defalt
);
11711 /***********************************************************************
11713 ***********************************************************************/
11715 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11718 redisplay_windows (window
)
11719 Lisp_Object window
;
11721 while (!NILP (window
))
11723 struct window
*w
= XWINDOW (window
);
11725 if (!NILP (w
->hchild
))
11726 redisplay_windows (w
->hchild
);
11727 else if (!NILP (w
->vchild
))
11728 redisplay_windows (w
->vchild
);
11731 displayed_buffer
= XBUFFER (w
->buffer
);
11732 /* Use list_of_error, not Qerror, so that
11733 we catch only errors and don't run the debugger. */
11734 internal_condition_case_1 (redisplay_window_0
, window
,
11736 redisplay_window_error
);
11744 redisplay_window_error ()
11746 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
11751 redisplay_window_0 (window
)
11752 Lisp_Object window
;
11754 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
11755 redisplay_window (window
, 0);
11760 redisplay_window_1 (window
)
11761 Lisp_Object window
;
11763 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
11764 redisplay_window (window
, 1);
11769 /* Increment GLYPH until it reaches END or CONDITION fails while
11770 adding (GLYPH)->pixel_width to X. */
11772 #define SKIP_GLYPHS(glyph, end, x, condition) \
11775 (x) += (glyph)->pixel_width; \
11778 while ((glyph) < (end) && (condition))
11781 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11782 DELTA is the number of bytes by which positions recorded in ROW
11783 differ from current buffer positions.
11785 Return 0 if cursor is not on this row. 1 otherwise. */
11788 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
11790 struct glyph_row
*row
;
11791 struct glyph_matrix
*matrix
;
11792 int delta
, delta_bytes
, dy
, dvpos
;
11794 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
11795 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
11796 struct glyph
*cursor
= NULL
;
11797 /* The first glyph that starts a sequence of glyphs from string. */
11798 struct glyph
*string_start
;
11799 /* The X coordinate of string_start. */
11800 int string_start_x
;
11801 /* The last known character position. */
11802 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
11803 /* The last known character position before string_start. */
11804 int string_before_pos
;
11807 int cursor_from_overlay_pos
= 0;
11808 int pt_old
= PT
- delta
;
11810 /* Skip over glyphs not having an object at the start of the row.
11811 These are special glyphs like truncation marks on terminal
11813 if (row
->displays_text_p
)
11815 && INTEGERP (glyph
->object
)
11816 && glyph
->charpos
< 0)
11818 x
+= glyph
->pixel_width
;
11822 string_start
= NULL
;
11824 && !INTEGERP (glyph
->object
)
11825 && (!BUFFERP (glyph
->object
)
11826 || (last_pos
= glyph
->charpos
) < pt_old
))
11828 if (! STRINGP (glyph
->object
))
11830 string_start
= NULL
;
11831 x
+= glyph
->pixel_width
;
11833 if (cursor_from_overlay_pos
11834 && last_pos
>= cursor_from_overlay_pos
)
11836 cursor_from_overlay_pos
= 0;
11842 if (string_start
== NULL
)
11844 string_before_pos
= last_pos
;
11845 string_start
= glyph
;
11846 string_start_x
= x
;
11848 /* Skip all glyphs from string. */
11853 if ((cursor
== NULL
|| glyph
> cursor
)
11854 && (cprop
= Fget_char_property (make_number ((glyph
)->charpos
),
11855 Qcursor
, (glyph
)->object
),
11857 && (pos
= string_buffer_position (w
, glyph
->object
,
11858 string_before_pos
),
11859 (pos
== 0 /* From overlay */
11860 || pos
== pt_old
)))
11862 /* Estimate overlay buffer position from the buffer
11863 positions of the glyphs before and after the overlay.
11864 Add 1 to last_pos so that if point corresponds to the
11865 glyph right after the overlay, we still use a 'cursor'
11866 property found in that overlay. */
11867 cursor_from_overlay_pos
= (pos
? 0 : last_pos
11868 + (INTEGERP (cprop
) ? XINT (cprop
) : 0));
11872 x
+= glyph
->pixel_width
;
11875 while (glyph
< end
&& EQ (glyph
->object
, string_start
->object
));
11879 if (cursor
!= NULL
)
11884 else if (row
->ends_in_ellipsis_p
&& glyph
== end
)
11886 /* Scan back over the ellipsis glyphs, decrementing positions. */
11887 while (glyph
> row
->glyphs
[TEXT_AREA
]
11888 && (glyph
- 1)->charpos
== last_pos
)
11889 glyph
--, x
-= glyph
->pixel_width
;
11890 /* That loop always goes one position too far,
11891 including the glyph before the ellipsis.
11892 So scan forward over that one. */
11893 x
+= glyph
->pixel_width
;
11896 else if (string_start
11897 && (glyph
== end
|| !BUFFERP (glyph
->object
) || last_pos
> pt_old
))
11899 /* We may have skipped over point because the previous glyphs
11900 are from string. As there's no easy way to know the
11901 character position of the current glyph, find the correct
11902 glyph on point by scanning from string_start again. */
11904 Lisp_Object string
;
11905 struct glyph
*stop
= glyph
;
11908 limit
= make_number (pt_old
+ 1);
11909 glyph
= string_start
;
11910 x
= string_start_x
;
11911 string
= glyph
->object
;
11912 pos
= string_buffer_position (w
, string
, string_before_pos
);
11913 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11914 because we always put cursor after overlay strings. */
11915 while (pos
== 0 && glyph
< stop
)
11917 string
= glyph
->object
;
11918 SKIP_GLYPHS (glyph
, stop
, x
, EQ (glyph
->object
, string
));
11920 pos
= string_buffer_position (w
, glyph
->object
, string_before_pos
);
11923 while (glyph
< stop
)
11925 pos
= XINT (Fnext_single_char_property_change
11926 (make_number (pos
), Qdisplay
, Qnil
, limit
));
11929 /* Skip glyphs from the same string. */
11930 string
= glyph
->object
;
11931 SKIP_GLYPHS (glyph
, stop
, x
, EQ (glyph
->object
, string
));
11932 /* Skip glyphs from an overlay. */
11933 while (glyph
< stop
11934 && ! string_buffer_position (w
, glyph
->object
, pos
))
11936 string
= glyph
->object
;
11937 SKIP_GLYPHS (glyph
, stop
, x
, EQ (glyph
->object
, string
));
11941 /* If we reached the end of the line, and end was from a string,
11942 cursor is not on this line. */
11943 if (glyph
== end
&& row
->continued_p
)
11947 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
11949 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
11950 w
->cursor
.y
= row
->y
+ dy
;
11952 if (w
== XWINDOW (selected_window
))
11954 if (!row
->continued_p
11955 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
11958 this_line_buffer
= XBUFFER (w
->buffer
);
11960 CHARPOS (this_line_start_pos
)
11961 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
11962 BYTEPOS (this_line_start_pos
)
11963 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
11965 CHARPOS (this_line_end_pos
)
11966 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
11967 BYTEPOS (this_line_end_pos
)
11968 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
11970 this_line_y
= w
->cursor
.y
;
11971 this_line_pixel_height
= row
->height
;
11972 this_line_vpos
= w
->cursor
.vpos
;
11973 this_line_start_x
= row
->x
;
11976 CHARPOS (this_line_start_pos
) = 0;
11983 /* Run window scroll functions, if any, for WINDOW with new window
11984 start STARTP. Sets the window start of WINDOW to that position.
11986 We assume that the window's buffer is really current. */
11988 static INLINE
struct text_pos
11989 run_window_scroll_functions (window
, startp
)
11990 Lisp_Object window
;
11991 struct text_pos startp
;
11993 struct window
*w
= XWINDOW (window
);
11994 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
11996 if (current_buffer
!= XBUFFER (w
->buffer
))
11999 if (!NILP (Vwindow_scroll_functions
))
12001 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
12002 make_number (CHARPOS (startp
)));
12003 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12004 /* In case the hook functions switch buffers. */
12005 if (current_buffer
!= XBUFFER (w
->buffer
))
12006 set_buffer_internal_1 (XBUFFER (w
->buffer
));
12013 /* Make sure the line containing the cursor is fully visible.
12014 A value of 1 means there is nothing to be done.
12015 (Either the line is fully visible, or it cannot be made so,
12016 or we cannot tell.)
12018 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12019 is higher than window.
12021 A value of 0 means the caller should do scrolling
12022 as if point had gone off the screen. */
12025 cursor_row_fully_visible_p (w
, force_p
, current_matrix_p
)
12028 int current_matrix_p
;
12030 struct glyph_matrix
*matrix
;
12031 struct glyph_row
*row
;
12034 if (!make_cursor_line_fully_visible_p
)
12037 /* It's not always possible to find the cursor, e.g, when a window
12038 is full of overlay strings. Don't do anything in that case. */
12039 if (w
->cursor
.vpos
< 0)
12042 matrix
= current_matrix_p
? w
->current_matrix
: w
->desired_matrix
;
12043 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
12045 /* If the cursor row is not partially visible, there's nothing to do. */
12046 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
))
12049 /* If the row the cursor is in is taller than the window's height,
12050 it's not clear what to do, so do nothing. */
12051 window_height
= window_box_height (w
);
12052 if (row
->height
>= window_height
)
12054 if (!force_p
|| MINI_WINDOW_P (w
)
12055 || w
->vscroll
|| w
->cursor
.vpos
== 0)
12061 /* This code used to try to scroll the window just enough to make
12062 the line visible. It returned 0 to say that the caller should
12063 allocate larger glyph matrices. */
12065 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
12067 int dy
= row
->height
- row
->visible_height
;
12070 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
12072 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
12074 int dy
= - (row
->height
- row
->visible_height
);
12077 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
12080 /* When we change the cursor y-position of the selected window,
12081 change this_line_y as well so that the display optimization for
12082 the cursor line of the selected window in redisplay_internal uses
12083 the correct y-position. */
12084 if (w
== XWINDOW (selected_window
))
12085 this_line_y
= w
->cursor
.y
;
12087 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
12088 redisplay with larger matrices. */
12089 if (matrix
->nrows
< required_matrix_height (w
))
12091 fonts_changed_p
= 1;
12100 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12101 non-zero means only WINDOW is redisplayed in redisplay_internal.
12102 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12103 in redisplay_window to bring a partially visible line into view in
12104 the case that only the cursor has moved.
12106 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12107 last screen line's vertical height extends past the end of the screen.
12111 1 if scrolling succeeded
12113 0 if scrolling didn't find point.
12115 -1 if new fonts have been loaded so that we must interrupt
12116 redisplay, adjust glyph matrices, and try again. */
12122 SCROLLING_NEED_LARGER_MATRICES
12126 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
12127 scroll_step
, temp_scroll_step
, last_line_misfit
)
12128 Lisp_Object window
;
12129 int just_this_one_p
;
12130 EMACS_INT scroll_conservatively
, scroll_step
;
12131 int temp_scroll_step
;
12132 int last_line_misfit
;
12134 struct window
*w
= XWINDOW (window
);
12135 struct frame
*f
= XFRAME (w
->frame
);
12136 struct text_pos scroll_margin_pos
;
12137 struct text_pos pos
;
12138 struct text_pos startp
;
12140 Lisp_Object window_end
;
12141 int this_scroll_margin
;
12145 int amount_to_scroll
= 0;
12146 Lisp_Object aggressive
;
12148 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
12151 debug_method_add (w
, "try_scrolling");
12154 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12156 /* Compute scroll margin height in pixels. We scroll when point is
12157 within this distance from the top or bottom of the window. */
12158 if (scroll_margin
> 0)
12160 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
12161 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
12164 this_scroll_margin
= 0;
12166 /* Force scroll_conservatively to have a reasonable value so it doesn't
12167 cause an overflow while computing how much to scroll. */
12168 if (scroll_conservatively
)
12169 scroll_conservatively
= min (scroll_conservatively
,
12170 MOST_POSITIVE_FIXNUM
/ FRAME_LINE_HEIGHT (f
));
12172 /* Compute how much we should try to scroll maximally to bring point
12174 if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
12175 scroll_max
= max (scroll_step
,
12176 max (scroll_conservatively
, temp_scroll_step
));
12177 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
12178 || NUMBERP (current_buffer
->scroll_up_aggressively
))
12179 /* We're trying to scroll because of aggressive scrolling
12180 but no scroll_step is set. Choose an arbitrary one. Maybe
12181 there should be a variable for this. */
12185 scroll_max
*= FRAME_LINE_HEIGHT (f
);
12187 /* Decide whether we have to scroll down. Start at the window end
12188 and move this_scroll_margin up to find the position of the scroll
12190 window_end
= Fwindow_end (window
, Qt
);
12194 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
12195 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
12197 if (this_scroll_margin
|| extra_scroll_margin_lines
)
12199 start_display (&it
, w
, scroll_margin_pos
);
12200 if (this_scroll_margin
)
12201 move_it_vertically_backward (&it
, this_scroll_margin
);
12202 if (extra_scroll_margin_lines
)
12203 move_it_by_lines (&it
, - extra_scroll_margin_lines
, 0);
12204 scroll_margin_pos
= it
.current
.pos
;
12207 if (PT
>= CHARPOS (scroll_margin_pos
))
12211 /* Point is in the scroll margin at the bottom of the window, or
12212 below. Compute a new window start that makes point visible. */
12214 /* Compute the distance from the scroll margin to PT.
12215 Give up if the distance is greater than scroll_max. */
12216 start_display (&it
, w
, scroll_margin_pos
);
12218 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
12219 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
12221 /* To make point visible, we have to move the window start
12222 down so that the line the cursor is in is visible, which
12223 means we have to add in the height of the cursor line. */
12224 dy
= line_bottom_y (&it
) - y0
;
12226 if (dy
> scroll_max
)
12227 return SCROLLING_FAILED
;
12229 /* Move the window start down. If scrolling conservatively,
12230 move it just enough down to make point visible. If
12231 scroll_step is set, move it down by scroll_step. */
12232 start_display (&it
, w
, startp
);
12234 if (scroll_conservatively
)
12235 /* Set AMOUNT_TO_SCROLL to at least one line,
12236 and at most scroll_conservatively lines. */
12238 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
12239 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
12240 else if (scroll_step
|| temp_scroll_step
)
12241 amount_to_scroll
= scroll_max
;
12244 aggressive
= current_buffer
->scroll_up_aggressively
;
12245 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
12246 if (NUMBERP (aggressive
))
12248 double float_amount
= XFLOATINT (aggressive
) * height
;
12249 amount_to_scroll
= float_amount
;
12250 if (amount_to_scroll
== 0 && float_amount
> 0)
12251 amount_to_scroll
= 1;
12255 if (amount_to_scroll
<= 0)
12256 return SCROLLING_FAILED
;
12258 /* If moving by amount_to_scroll leaves STARTP unchanged,
12259 move it down one screen line. */
12261 move_it_vertically (&it
, amount_to_scroll
);
12262 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
12263 move_it_by_lines (&it
, 1, 1);
12264 startp
= it
.current
.pos
;
12268 /* See if point is inside the scroll margin at the top of the
12270 scroll_margin_pos
= startp
;
12271 if (this_scroll_margin
)
12273 start_display (&it
, w
, startp
);
12274 move_it_vertically (&it
, this_scroll_margin
);
12275 scroll_margin_pos
= it
.current
.pos
;
12278 if (PT
< CHARPOS (scroll_margin_pos
))
12280 /* Point is in the scroll margin at the top of the window or
12281 above what is displayed in the window. */
12284 /* Compute the vertical distance from PT to the scroll
12285 margin position. Give up if distance is greater than
12287 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
12288 start_display (&it
, w
, pos
);
12290 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
12291 it
.last_visible_y
, -1,
12292 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
12293 dy
= it
.current_y
- y0
;
12294 if (dy
> scroll_max
)
12295 return SCROLLING_FAILED
;
12297 /* Compute new window start. */
12298 start_display (&it
, w
, startp
);
12300 if (scroll_conservatively
)
12302 = max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
12303 else if (scroll_step
|| temp_scroll_step
)
12304 amount_to_scroll
= scroll_max
;
12307 aggressive
= current_buffer
->scroll_down_aggressively
;
12308 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
12309 if (NUMBERP (aggressive
))
12311 double float_amount
= XFLOATINT (aggressive
) * height
;
12312 amount_to_scroll
= float_amount
;
12313 if (amount_to_scroll
== 0 && float_amount
> 0)
12314 amount_to_scroll
= 1;
12318 if (amount_to_scroll
<= 0)
12319 return SCROLLING_FAILED
;
12321 move_it_vertically_backward (&it
, amount_to_scroll
);
12322 startp
= it
.current
.pos
;
12326 /* Run window scroll functions. */
12327 startp
= run_window_scroll_functions (window
, startp
);
12329 /* Display the window. Give up if new fonts are loaded, or if point
12331 if (!try_window (window
, startp
, 0))
12332 rc
= SCROLLING_NEED_LARGER_MATRICES
;
12333 else if (w
->cursor
.vpos
< 0)
12335 clear_glyph_matrix (w
->desired_matrix
);
12336 rc
= SCROLLING_FAILED
;
12340 /* Maybe forget recorded base line for line number display. */
12341 if (!just_this_one_p
12342 || current_buffer
->clip_changed
12343 || BEG_UNCHANGED
< CHARPOS (startp
))
12344 w
->base_line_number
= Qnil
;
12346 /* If cursor ends up on a partially visible line,
12347 treat that as being off the bottom of the screen. */
12348 if (! cursor_row_fully_visible_p (w
, extra_scroll_margin_lines
<= 1, 0))
12350 clear_glyph_matrix (w
->desired_matrix
);
12351 ++extra_scroll_margin_lines
;
12354 rc
= SCROLLING_SUCCESS
;
12361 /* Compute a suitable window start for window W if display of W starts
12362 on a continuation line. Value is non-zero if a new window start
12365 The new window start will be computed, based on W's width, starting
12366 from the start of the continued line. It is the start of the
12367 screen line with the minimum distance from the old start W->start. */
12370 compute_window_start_on_continuation_line (w
)
12373 struct text_pos pos
, start_pos
;
12374 int window_start_changed_p
= 0;
12376 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
12378 /* If window start is on a continuation line... Window start may be
12379 < BEGV in case there's invisible text at the start of the
12380 buffer (M-x rmail, for example). */
12381 if (CHARPOS (start_pos
) > BEGV
12382 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
12385 struct glyph_row
*row
;
12387 /* Handle the case that the window start is out of range. */
12388 if (CHARPOS (start_pos
) < BEGV
)
12389 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
12390 else if (CHARPOS (start_pos
) > ZV
)
12391 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
12393 /* Find the start of the continued line. This should be fast
12394 because scan_buffer is fast (newline cache). */
12395 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
12396 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
12397 row
, DEFAULT_FACE_ID
);
12398 reseat_at_previous_visible_line_start (&it
);
12400 /* If the line start is "too far" away from the window start,
12401 say it takes too much time to compute a new window start. */
12402 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
12403 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
12405 int min_distance
, distance
;
12407 /* Move forward by display lines to find the new window
12408 start. If window width was enlarged, the new start can
12409 be expected to be > the old start. If window width was
12410 decreased, the new window start will be < the old start.
12411 So, we're looking for the display line start with the
12412 minimum distance from the old window start. */
12413 pos
= it
.current
.pos
;
12414 min_distance
= INFINITY
;
12415 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
12416 distance
< min_distance
)
12418 min_distance
= distance
;
12419 pos
= it
.current
.pos
;
12420 move_it_by_lines (&it
, 1, 0);
12423 /* Set the window start there. */
12424 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
12425 window_start_changed_p
= 1;
12429 return window_start_changed_p
;
12433 /* Try cursor movement in case text has not changed in window WINDOW,
12434 with window start STARTP. Value is
12436 CURSOR_MOVEMENT_SUCCESS if successful
12438 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12440 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12441 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12442 we want to scroll as if scroll-step were set to 1. See the code.
12444 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12445 which case we have to abort this redisplay, and adjust matrices
12450 CURSOR_MOVEMENT_SUCCESS
,
12451 CURSOR_MOVEMENT_CANNOT_BE_USED
,
12452 CURSOR_MOVEMENT_MUST_SCROLL
,
12453 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12457 try_cursor_movement (window
, startp
, scroll_step
)
12458 Lisp_Object window
;
12459 struct text_pos startp
;
12462 struct window
*w
= XWINDOW (window
);
12463 struct frame
*f
= XFRAME (w
->frame
);
12464 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
12467 if (inhibit_try_cursor_movement
)
12471 /* Handle case where text has not changed, only point, and it has
12472 not moved off the frame. */
12473 if (/* Point may be in this window. */
12474 PT
>= CHARPOS (startp
)
12475 /* Selective display hasn't changed. */
12476 && !current_buffer
->clip_changed
12477 /* Function force-mode-line-update is used to force a thorough
12478 redisplay. It sets either windows_or_buffers_changed or
12479 update_mode_lines. So don't take a shortcut here for these
12481 && !update_mode_lines
12482 && !windows_or_buffers_changed
12483 && !cursor_type_changed
12484 /* Can't use this case if highlighting a region. When a
12485 region exists, cursor movement has to do more than just
12487 && !(!NILP (Vtransient_mark_mode
)
12488 && !NILP (current_buffer
->mark_active
))
12489 && NILP (w
->region_showing
)
12490 && NILP (Vshow_trailing_whitespace
)
12491 /* Right after splitting windows, last_point may be nil. */
12492 && INTEGERP (w
->last_point
)
12493 /* This code is not used for mini-buffer for the sake of the case
12494 of redisplaying to replace an echo area message; since in
12495 that case the mini-buffer contents per se are usually
12496 unchanged. This code is of no real use in the mini-buffer
12497 since the handling of this_line_start_pos, etc., in redisplay
12498 handles the same cases. */
12499 && !EQ (window
, minibuf_window
)
12500 /* When splitting windows or for new windows, it happens that
12501 redisplay is called with a nil window_end_vpos or one being
12502 larger than the window. This should really be fixed in
12503 window.c. I don't have this on my list, now, so we do
12504 approximately the same as the old redisplay code. --gerd. */
12505 && INTEGERP (w
->window_end_vpos
)
12506 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
12507 && (FRAME_WINDOW_P (f
)
12508 || !overlay_arrow_in_current_buffer_p ()))
12510 int this_scroll_margin
, top_scroll_margin
;
12511 struct glyph_row
*row
= NULL
;
12514 debug_method_add (w
, "cursor movement");
12517 /* Scroll if point within this distance from the top or bottom
12518 of the window. This is a pixel value. */
12519 this_scroll_margin
= max (0, scroll_margin
);
12520 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
12521 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
12523 top_scroll_margin
= this_scroll_margin
;
12524 if (WINDOW_WANTS_HEADER_LINE_P (w
))
12525 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
12527 /* Start with the row the cursor was displayed during the last
12528 not paused redisplay. Give up if that row is not valid. */
12529 if (w
->last_cursor
.vpos
< 0
12530 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
12531 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
12534 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
12535 if (row
->mode_line_p
)
12537 if (!row
->enabled_p
)
12538 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
12541 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
12544 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
12546 if (PT
> XFASTINT (w
->last_point
))
12548 /* Point has moved forward. */
12549 while (MATRIX_ROW_END_CHARPOS (row
) < PT
12550 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
12552 xassert (row
->enabled_p
);
12556 /* The end position of a row equals the start position
12557 of the next row. If PT is there, we would rather
12558 display it in the next line. */
12559 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
12560 && MATRIX_ROW_END_CHARPOS (row
) == PT
12561 && !cursor_row_p (w
, row
))
12564 /* If within the scroll margin, scroll. Note that
12565 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
12566 the next line would be drawn, and that
12567 this_scroll_margin can be zero. */
12568 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
12569 || PT
> MATRIX_ROW_END_CHARPOS (row
)
12570 /* Line is completely visible last line in window
12571 and PT is to be set in the next line. */
12572 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
12573 && PT
== MATRIX_ROW_END_CHARPOS (row
)
12574 && !row
->ends_at_zv_p
12575 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
12578 else if (PT
< XFASTINT (w
->last_point
))
12580 /* Cursor has to be moved backward. Note that PT >=
12581 CHARPOS (startp) because of the outer if-statement. */
12582 while (!row
->mode_line_p
12583 && (MATRIX_ROW_START_CHARPOS (row
) > PT
12584 || (MATRIX_ROW_START_CHARPOS (row
) == PT
12585 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)
12586 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
12587 row
> w
->current_matrix
->rows
12588 && (row
-1)->ends_in_newline_from_string_p
))))
12589 && (row
->y
> top_scroll_margin
12590 || CHARPOS (startp
) == BEGV
))
12592 xassert (row
->enabled_p
);
12596 /* Consider the following case: Window starts at BEGV,
12597 there is invisible, intangible text at BEGV, so that
12598 display starts at some point START > BEGV. It can
12599 happen that we are called with PT somewhere between
12600 BEGV and START. Try to handle that case. */
12601 if (row
< w
->current_matrix
->rows
12602 || row
->mode_line_p
)
12604 row
= w
->current_matrix
->rows
;
12605 if (row
->mode_line_p
)
12609 /* Due to newlines in overlay strings, we may have to
12610 skip forward over overlay strings. */
12611 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
12612 && MATRIX_ROW_END_CHARPOS (row
) == PT
12613 && !cursor_row_p (w
, row
))
12616 /* If within the scroll margin, scroll. */
12617 if (row
->y
< top_scroll_margin
12618 && CHARPOS (startp
) != BEGV
)
12623 /* Cursor did not move. So don't scroll even if cursor line
12624 is partially visible, as it was so before. */
12625 rc
= CURSOR_MOVEMENT_SUCCESS
;
12628 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
12629 || PT
> MATRIX_ROW_END_CHARPOS (row
))
12631 /* if PT is not in the glyph row, give up. */
12632 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
12634 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
12635 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
)
12636 && make_cursor_line_fully_visible_p
)
12638 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
12639 && !row
->ends_at_zv_p
12640 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
12641 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
12642 else if (row
->height
> window_box_height (w
))
12644 /* If we end up in a partially visible line, let's
12645 make it fully visible, except when it's taller
12646 than the window, in which case we can't do much
12649 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
12653 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
12654 if (!cursor_row_fully_visible_p (w
, 0, 1))
12655 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
12657 rc
= CURSOR_MOVEMENT_SUCCESS
;
12661 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
12666 if (set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0))
12668 rc
= CURSOR_MOVEMENT_SUCCESS
;
12673 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
12674 && MATRIX_ROW_START_CHARPOS (row
) == PT
12675 && cursor_row_p (w
, row
));
12684 set_vertical_scroll_bar (w
)
12687 int start
, end
, whole
;
12689 /* Calculate the start and end positions for the current window.
12690 At some point, it would be nice to choose between scrollbars
12691 which reflect the whole buffer size, with special markers
12692 indicating narrowing, and scrollbars which reflect only the
12695 Note that mini-buffers sometimes aren't displaying any text. */
12696 if (!MINI_WINDOW_P (w
)
12697 || (w
== XWINDOW (minibuf_window
)
12698 && NILP (echo_area_buffer
[0])))
12700 struct buffer
*buf
= XBUFFER (w
->buffer
);
12701 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
12702 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
12703 /* I don't think this is guaranteed to be right. For the
12704 moment, we'll pretend it is. */
12705 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
12709 if (whole
< (end
- start
))
12710 whole
= end
- start
;
12713 start
= end
= whole
= 0;
12715 /* Indicate what this scroll bar ought to be displaying now. */
12716 set_vertical_scroll_bar_hook (w
, end
- start
, whole
, start
);
12720 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
12721 selected_window is redisplayed.
12723 We can return without actually redisplaying the window if
12724 fonts_changed_p is nonzero. In that case, redisplay_internal will
12728 redisplay_window (window
, just_this_one_p
)
12729 Lisp_Object window
;
12730 int just_this_one_p
;
12732 struct window
*w
= XWINDOW (window
);
12733 struct frame
*f
= XFRAME (w
->frame
);
12734 struct buffer
*buffer
= XBUFFER (w
->buffer
);
12735 struct buffer
*old
= current_buffer
;
12736 struct text_pos lpoint
, opoint
, startp
;
12737 int update_mode_line
;
12740 /* Record it now because it's overwritten. */
12741 int current_matrix_up_to_date_p
= 0;
12742 int used_current_matrix_p
= 0;
12743 /* This is less strict than current_matrix_up_to_date_p.
12744 It indictes that the buffer contents and narrowing are unchanged. */
12745 int buffer_unchanged_p
= 0;
12746 int temp_scroll_step
= 0;
12747 int count
= SPECPDL_INDEX ();
12749 int centering_position
= -1;
12750 int last_line_misfit
= 0;
12752 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
12755 /* W must be a leaf window here. */
12756 xassert (!NILP (w
->buffer
));
12758 *w
->desired_matrix
->method
= 0;
12761 specbind (Qinhibit_point_motion_hooks
, Qt
);
12763 reconsider_clip_changes (w
, buffer
);
12765 /* Has the mode line to be updated? */
12766 update_mode_line
= (!NILP (w
->update_mode_line
)
12767 || update_mode_lines
12768 || buffer
->clip_changed
12769 || buffer
->prevent_redisplay_optimizations_p
);
12771 if (MINI_WINDOW_P (w
))
12773 if (w
== XWINDOW (echo_area_window
)
12774 && !NILP (echo_area_buffer
[0]))
12776 if (update_mode_line
)
12777 /* We may have to update a tty frame's menu bar or a
12778 tool-bar. Example `M-x C-h C-h C-g'. */
12779 goto finish_menu_bars
;
12781 /* We've already displayed the echo area glyphs in this window. */
12782 goto finish_scroll_bars
;
12784 else if ((w
!= XWINDOW (minibuf_window
)
12785 || minibuf_level
== 0)
12786 /* When buffer is nonempty, redisplay window normally. */
12787 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
12788 /* Quail displays non-mini buffers in minibuffer window.
12789 In that case, redisplay the window normally. */
12790 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
12792 /* W is a mini-buffer window, but it's not active, so clear
12794 int yb
= window_text_bottom_y (w
);
12795 struct glyph_row
*row
;
12798 for (y
= 0, row
= w
->desired_matrix
->rows
;
12800 y
+= row
->height
, ++row
)
12801 blank_row (w
, row
, y
);
12802 goto finish_scroll_bars
;
12805 clear_glyph_matrix (w
->desired_matrix
);
12808 /* Otherwise set up data on this window; select its buffer and point
12810 /* Really select the buffer, for the sake of buffer-local
12812 set_buffer_internal_1 (XBUFFER (w
->buffer
));
12813 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
12815 current_matrix_up_to_date_p
12816 = (!NILP (w
->window_end_valid
)
12817 && !current_buffer
->clip_changed
12818 && !current_buffer
->prevent_redisplay_optimizations_p
12819 && XFASTINT (w
->last_modified
) >= MODIFF
12820 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
12823 = (!NILP (w
->window_end_valid
)
12824 && !current_buffer
->clip_changed
12825 && XFASTINT (w
->last_modified
) >= MODIFF
12826 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
12828 /* When windows_or_buffers_changed is non-zero, we can't rely on
12829 the window end being valid, so set it to nil there. */
12830 if (windows_or_buffers_changed
)
12832 /* If window starts on a continuation line, maybe adjust the
12833 window start in case the window's width changed. */
12834 if (XMARKER (w
->start
)->buffer
== current_buffer
)
12835 compute_window_start_on_continuation_line (w
);
12837 w
->window_end_valid
= Qnil
;
12840 /* Some sanity checks. */
12841 CHECK_WINDOW_END (w
);
12842 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
12844 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
12847 /* If %c is in mode line, update it if needed. */
12848 if (!NILP (w
->column_number_displayed
)
12849 /* This alternative quickly identifies a common case
12850 where no change is needed. */
12851 && !(PT
== XFASTINT (w
->last_point
)
12852 && XFASTINT (w
->last_modified
) >= MODIFF
12853 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
12854 && (XFASTINT (w
->column_number_displayed
)
12855 != (int) current_column ())) /* iftc */
12856 update_mode_line
= 1;
12858 /* Count number of windows showing the selected buffer. An indirect
12859 buffer counts as its base buffer. */
12860 if (!just_this_one_p
)
12862 struct buffer
*current_base
, *window_base
;
12863 current_base
= current_buffer
;
12864 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
12865 if (current_base
->base_buffer
)
12866 current_base
= current_base
->base_buffer
;
12867 if (window_base
->base_buffer
)
12868 window_base
= window_base
->base_buffer
;
12869 if (current_base
== window_base
)
12873 /* Point refers normally to the selected window. For any other
12874 window, set up appropriate value. */
12875 if (!EQ (window
, selected_window
))
12877 int new_pt
= XMARKER (w
->pointm
)->charpos
;
12878 int new_pt_byte
= marker_byte_position (w
->pointm
);
12882 new_pt_byte
= BEGV_BYTE
;
12883 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
12885 else if (new_pt
> (ZV
- 1))
12888 new_pt_byte
= ZV_BYTE
;
12889 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
12892 /* We don't use SET_PT so that the point-motion hooks don't run. */
12893 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
12896 /* If any of the character widths specified in the display table
12897 have changed, invalidate the width run cache. It's true that
12898 this may be a bit late to catch such changes, but the rest of
12899 redisplay goes (non-fatally) haywire when the display table is
12900 changed, so why should we worry about doing any better? */
12901 if (current_buffer
->width_run_cache
)
12903 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
12905 if (! disptab_matches_widthtab (disptab
,
12906 XVECTOR (current_buffer
->width_table
)))
12908 invalidate_region_cache (current_buffer
,
12909 current_buffer
->width_run_cache
,
12911 recompute_width_table (current_buffer
, disptab
);
12915 /* If window-start is screwed up, choose a new one. */
12916 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
12919 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12921 /* If someone specified a new starting point but did not insist,
12922 check whether it can be used. */
12923 if (!NILP (w
->optional_new_start
)
12924 && CHARPOS (startp
) >= BEGV
12925 && CHARPOS (startp
) <= ZV
)
12927 w
->optional_new_start
= Qnil
;
12928 start_display (&it
, w
, startp
);
12929 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
12930 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
12931 if (IT_CHARPOS (it
) == PT
)
12932 w
->force_start
= Qt
;
12933 /* IT may overshoot PT if text at PT is invisible. */
12934 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
12935 w
->force_start
= Qt
;
12938 /* Handle case where place to start displaying has been specified,
12939 unless the specified location is outside the accessible range. */
12940 if (!NILP (w
->force_start
)
12941 || w
->frozen_window_start_p
)
12943 /* We set this later on if we have to adjust point. */
12947 w
->force_start
= Qnil
;
12949 w
->window_end_valid
= Qnil
;
12951 /* Forget any recorded base line for line number display. */
12952 if (!buffer_unchanged_p
)
12953 w
->base_line_number
= Qnil
;
12955 /* Redisplay the mode line. Select the buffer properly for that.
12956 Also, run the hook window-scroll-functions
12957 because we have scrolled. */
12958 /* Note, we do this after clearing force_start because
12959 if there's an error, it is better to forget about force_start
12960 than to get into an infinite loop calling the hook functions
12961 and having them get more errors. */
12962 if (!update_mode_line
12963 || ! NILP (Vwindow_scroll_functions
))
12965 update_mode_line
= 1;
12966 w
->update_mode_line
= Qt
;
12967 startp
= run_window_scroll_functions (window
, startp
);
12970 w
->last_modified
= make_number (0);
12971 w
->last_overlay_modified
= make_number (0);
12972 if (CHARPOS (startp
) < BEGV
)
12973 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
12974 else if (CHARPOS (startp
) > ZV
)
12975 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
12977 /* Redisplay, then check if cursor has been set during the
12978 redisplay. Give up if new fonts were loaded. */
12979 val
= try_window (window
, startp
, 1);
12982 w
->force_start
= Qt
;
12983 clear_glyph_matrix (w
->desired_matrix
);
12984 goto need_larger_matrices
;
12986 /* Point was outside the scroll margins. */
12988 new_vpos
= window_box_height (w
) / 2;
12990 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
12992 /* If point does not appear, try to move point so it does
12993 appear. The desired matrix has been built above, so we
12994 can use it here. */
12995 new_vpos
= window_box_height (w
) / 2;
12998 if (!cursor_row_fully_visible_p (w
, 0, 0))
13000 /* Point does appear, but on a line partly visible at end of window.
13001 Move it back to a fully-visible line. */
13002 new_vpos
= window_box_height (w
);
13005 /* If we need to move point for either of the above reasons,
13006 now actually do it. */
13009 struct glyph_row
*row
;
13011 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
13012 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
13015 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
13016 MATRIX_ROW_START_BYTEPOS (row
));
13018 if (w
!= XWINDOW (selected_window
))
13019 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
13020 else if (current_buffer
== old
)
13021 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
13023 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
13025 /* If we are highlighting the region, then we just changed
13026 the region, so redisplay to show it. */
13027 if (!NILP (Vtransient_mark_mode
)
13028 && !NILP (current_buffer
->mark_active
))
13030 clear_glyph_matrix (w
->desired_matrix
);
13031 if (!try_window (window
, startp
, 0))
13032 goto need_larger_matrices
;
13037 debug_method_add (w
, "forced window start");
13042 /* Handle case where text has not changed, only point, and it has
13043 not moved off the frame, and we are not retrying after hscroll.
13044 (current_matrix_up_to_date_p is nonzero when retrying.) */
13045 if (current_matrix_up_to_date_p
13046 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
13047 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
13051 case CURSOR_MOVEMENT_SUCCESS
:
13052 used_current_matrix_p
= 1;
13055 #if 0 /* try_cursor_movement never returns this value. */
13056 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES
:
13057 goto need_larger_matrices
;
13060 case CURSOR_MOVEMENT_MUST_SCROLL
:
13061 goto try_to_scroll
;
13067 /* If current starting point was originally the beginning of a line
13068 but no longer is, find a new starting point. */
13069 else if (!NILP (w
->start_at_line_beg
)
13070 && !(CHARPOS (startp
) <= BEGV
13071 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
13074 debug_method_add (w
, "recenter 1");
13079 /* Try scrolling with try_window_id. Value is > 0 if update has
13080 been done, it is -1 if we know that the same window start will
13081 not work. It is 0 if unsuccessful for some other reason. */
13082 else if ((tem
= try_window_id (w
)) != 0)
13085 debug_method_add (w
, "try_window_id %d", tem
);
13088 if (fonts_changed_p
)
13089 goto need_larger_matrices
;
13093 /* Otherwise try_window_id has returned -1 which means that we
13094 don't want the alternative below this comment to execute. */
13096 else if (CHARPOS (startp
) >= BEGV
13097 && CHARPOS (startp
) <= ZV
13098 && PT
>= CHARPOS (startp
)
13099 && (CHARPOS (startp
) < ZV
13100 /* Avoid starting at end of buffer. */
13101 || CHARPOS (startp
) == BEGV
13102 || (XFASTINT (w
->last_modified
) >= MODIFF
13103 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
13106 /* If first window line is a continuation line, and window start
13107 is inside the modified region, but the first change is before
13108 current window start, we must select a new window start.*/
13109 if (NILP (w
->start_at_line_beg
)
13110 && CHARPOS (startp
) > BEGV
)
13112 /* Make sure beg_unchanged and end_unchanged are up to date.
13113 Do it only if buffer has really changed. This may or may
13114 not have been done by try_window_id (see which) already. */
13115 if (MODIFF
> SAVE_MODIFF
13116 /* This seems to happen sometimes after saving a buffer. */
13117 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
13119 if (GPT
- BEG
< BEG_UNCHANGED
)
13120 BEG_UNCHANGED
= GPT
- BEG
;
13121 if (Z
- GPT
< END_UNCHANGED
)
13122 END_UNCHANGED
= Z
- GPT
;
13125 if (CHARPOS (startp
) > BEG
+ BEG_UNCHANGED
13126 && CHARPOS (startp
) <= Z
- END_UNCHANGED
)
13128 /* There doesn't seems to be a simple way to find a new
13129 window start that is near the old window start, so
13130 we just recenter. */
13136 debug_method_add (w
, "same window start");
13139 /* Try to redisplay starting at same place as before.
13140 If point has not moved off frame, accept the results. */
13141 if (!current_matrix_up_to_date_p
13142 /* Don't use try_window_reusing_current_matrix in this case
13143 because a window scroll function can have changed the
13145 || !NILP (Vwindow_scroll_functions
)
13146 || MINI_WINDOW_P (w
)
13147 || !(used_current_matrix_p
13148 = try_window_reusing_current_matrix (w
)))
13150 IF_DEBUG (debug_method_add (w
, "1"));
13151 if (try_window (window
, startp
, 1) < 0)
13152 /* -1 means we need to scroll.
13153 0 means we need new matrices, but fonts_changed_p
13154 is set in that case, so we will detect it below. */
13155 goto try_to_scroll
;
13158 if (fonts_changed_p
)
13159 goto need_larger_matrices
;
13161 if (w
->cursor
.vpos
>= 0)
13163 if (!just_this_one_p
13164 || current_buffer
->clip_changed
13165 || BEG_UNCHANGED
< CHARPOS (startp
))
13166 /* Forget any recorded base line for line number display. */
13167 w
->base_line_number
= Qnil
;
13169 if (!cursor_row_fully_visible_p (w
, 1, 0))
13171 clear_glyph_matrix (w
->desired_matrix
);
13172 last_line_misfit
= 1;
13174 /* Drop through and scroll. */
13179 clear_glyph_matrix (w
->desired_matrix
);
13184 w
->last_modified
= make_number (0);
13185 w
->last_overlay_modified
= make_number (0);
13187 /* Redisplay the mode line. Select the buffer properly for that. */
13188 if (!update_mode_line
)
13190 update_mode_line
= 1;
13191 w
->update_mode_line
= Qt
;
13194 /* Try to scroll by specified few lines. */
13195 if ((scroll_conservatively
13197 || temp_scroll_step
13198 || NUMBERP (current_buffer
->scroll_up_aggressively
)
13199 || NUMBERP (current_buffer
->scroll_down_aggressively
))
13200 && !current_buffer
->clip_changed
13201 && CHARPOS (startp
) >= BEGV
13202 && CHARPOS (startp
) <= ZV
)
13204 /* The function returns -1 if new fonts were loaded, 1 if
13205 successful, 0 if not successful. */
13206 int rc
= try_scrolling (window
, just_this_one_p
,
13207 scroll_conservatively
,
13209 temp_scroll_step
, last_line_misfit
);
13212 case SCROLLING_SUCCESS
:
13215 case SCROLLING_NEED_LARGER_MATRICES
:
13216 goto need_larger_matrices
;
13218 case SCROLLING_FAILED
:
13226 /* Finally, just choose place to start which centers point */
13229 if (centering_position
< 0)
13230 centering_position
= window_box_height (w
) / 2;
13233 debug_method_add (w
, "recenter");
13236 /* w->vscroll = 0; */
13238 /* Forget any previously recorded base line for line number display. */
13239 if (!buffer_unchanged_p
)
13240 w
->base_line_number
= Qnil
;
13242 /* Move backward half the height of the window. */
13243 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
13244 it
.current_y
= it
.last_visible_y
;
13245 move_it_vertically_backward (&it
, centering_position
);
13246 xassert (IT_CHARPOS (it
) >= BEGV
);
13248 /* The function move_it_vertically_backward may move over more
13249 than the specified y-distance. If it->w is small, e.g. a
13250 mini-buffer window, we may end up in front of the window's
13251 display area. Start displaying at the start of the line
13252 containing PT in this case. */
13253 if (it
.current_y
<= 0)
13255 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
13256 move_it_vertically_backward (&it
, 0);
13258 /* I think this assert is bogus if buffer contains
13259 invisible text or images. KFS. */
13260 xassert (IT_CHARPOS (it
) <= PT
);
13265 it
.current_x
= it
.hpos
= 0;
13267 /* Set startp here explicitly in case that helps avoid an infinite loop
13268 in case the window-scroll-functions functions get errors. */
13269 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
13271 /* Run scroll hooks. */
13272 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
13274 /* Redisplay the window. */
13275 if (!current_matrix_up_to_date_p
13276 || windows_or_buffers_changed
13277 || cursor_type_changed
13278 /* Don't use try_window_reusing_current_matrix in this case
13279 because it can have changed the buffer. */
13280 || !NILP (Vwindow_scroll_functions
)
13281 || !just_this_one_p
13282 || MINI_WINDOW_P (w
)
13283 || !(used_current_matrix_p
13284 = try_window_reusing_current_matrix (w
)))
13285 try_window (window
, startp
, 0);
13287 /* If new fonts have been loaded (due to fontsets), give up. We
13288 have to start a new redisplay since we need to re-adjust glyph
13290 if (fonts_changed_p
)
13291 goto need_larger_matrices
;
13293 /* If cursor did not appear assume that the middle of the window is
13294 in the first line of the window. Do it again with the next line.
13295 (Imagine a window of height 100, displaying two lines of height
13296 60. Moving back 50 from it->last_visible_y will end in the first
13298 if (w
->cursor
.vpos
< 0)
13300 if (!NILP (w
->window_end_valid
)
13301 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
13303 clear_glyph_matrix (w
->desired_matrix
);
13304 move_it_by_lines (&it
, 1, 0);
13305 try_window (window
, it
.current
.pos
, 0);
13307 else if (PT
< IT_CHARPOS (it
))
13309 clear_glyph_matrix (w
->desired_matrix
);
13310 move_it_by_lines (&it
, -1, 0);
13311 try_window (window
, it
.current
.pos
, 0);
13315 /* Not much we can do about it. */
13319 /* Consider the following case: Window starts at BEGV, there is
13320 invisible, intangible text at BEGV, so that display starts at
13321 some point START > BEGV. It can happen that we are called with
13322 PT somewhere between BEGV and START. Try to handle that case. */
13323 if (w
->cursor
.vpos
< 0)
13325 struct glyph_row
*row
= w
->current_matrix
->rows
;
13326 if (row
->mode_line_p
)
13328 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13331 if (!cursor_row_fully_visible_p (w
, 0, 0))
13333 /* If vscroll is enabled, disable it and try again. */
13337 clear_glyph_matrix (w
->desired_matrix
);
13341 /* If centering point failed to make the whole line visible,
13342 put point at the top instead. That has to make the whole line
13343 visible, if it can be done. */
13344 if (centering_position
== 0)
13347 clear_glyph_matrix (w
->desired_matrix
);
13348 centering_position
= 0;
13354 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
13355 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
13356 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
13359 /* Display the mode line, if we must. */
13360 if ((update_mode_line
13361 /* If window not full width, must redo its mode line
13362 if (a) the window to its side is being redone and
13363 (b) we do a frame-based redisplay. This is a consequence
13364 of how inverted lines are drawn in frame-based redisplay. */
13365 || (!just_this_one_p
13366 && !FRAME_WINDOW_P (f
)
13367 && !WINDOW_FULL_WIDTH_P (w
))
13368 /* Line number to display. */
13369 || INTEGERP (w
->base_line_pos
)
13370 /* Column number is displayed and different from the one displayed. */
13371 || (!NILP (w
->column_number_displayed
)
13372 && (XFASTINT (w
->column_number_displayed
)
13373 != (int) current_column ()))) /* iftc */
13374 /* This means that the window has a mode line. */
13375 && (WINDOW_WANTS_MODELINE_P (w
)
13376 || WINDOW_WANTS_HEADER_LINE_P (w
)))
13378 display_mode_lines (w
);
13380 /* If mode line height has changed, arrange for a thorough
13381 immediate redisplay using the correct mode line height. */
13382 if (WINDOW_WANTS_MODELINE_P (w
)
13383 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
13385 fonts_changed_p
= 1;
13386 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
13387 = DESIRED_MODE_LINE_HEIGHT (w
);
13390 /* If top line height has changed, arrange for a thorough
13391 immediate redisplay using the correct mode line height. */
13392 if (WINDOW_WANTS_HEADER_LINE_P (w
)
13393 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
13395 fonts_changed_p
= 1;
13396 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
13397 = DESIRED_HEADER_LINE_HEIGHT (w
);
13400 if (fonts_changed_p
)
13401 goto need_larger_matrices
;
13404 if (!line_number_displayed
13405 && !BUFFERP (w
->base_line_pos
))
13407 w
->base_line_pos
= Qnil
;
13408 w
->base_line_number
= Qnil
;
13413 /* When we reach a frame's selected window, redo the frame's menu bar. */
13414 if (update_mode_line
13415 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
13417 int redisplay_menu_p
= 0;
13418 int redisplay_tool_bar_p
= 0;
13420 if (FRAME_WINDOW_P (f
))
13422 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
13423 || defined (USE_GTK)
13424 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
13426 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
13430 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
13432 if (redisplay_menu_p
)
13433 display_menu_bar (w
);
13435 #ifdef HAVE_WINDOW_SYSTEM
13437 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
13439 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
13440 && (FRAME_TOOL_BAR_LINES (f
) > 0
13441 || auto_resize_tool_bars_p
);
13445 if (redisplay_tool_bar_p
)
13446 redisplay_tool_bar (f
);
13450 #ifdef HAVE_WINDOW_SYSTEM
13451 if (FRAME_WINDOW_P (f
)
13452 && update_window_fringes (w
, (just_this_one_p
13453 || (!used_current_matrix_p
&& !overlay_arrow_seen
)
13454 || w
->pseudo_window_p
)))
13458 if (draw_window_fringes (w
, 1))
13459 x_draw_vertical_border (w
);
13463 #endif /* HAVE_WINDOW_SYSTEM */
13465 /* We go to this label, with fonts_changed_p nonzero,
13466 if it is necessary to try again using larger glyph matrices.
13467 We have to redeem the scroll bar even in this case,
13468 because the loop in redisplay_internal expects that. */
13469 need_larger_matrices
:
13471 finish_scroll_bars
:
13473 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
13475 /* Set the thumb's position and size. */
13476 set_vertical_scroll_bar (w
);
13478 /* Note that we actually used the scroll bar attached to this
13479 window, so it shouldn't be deleted at the end of redisplay. */
13480 redeem_scroll_bar_hook (w
);
13483 /* Restore current_buffer and value of point in it. */
13484 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
13485 set_buffer_internal_1 (old
);
13486 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
13488 unbind_to (count
, Qnil
);
13492 /* Build the complete desired matrix of WINDOW with a window start
13493 buffer position POS.
13495 Value is 1 if successful. It is zero if fonts were loaded during
13496 redisplay which makes re-adjusting glyph matrices necessary, and -1
13497 if point would appear in the scroll margins.
13498 (We check that only if CHECK_MARGINS is nonzero. */
13501 try_window (window
, pos
, check_margins
)
13502 Lisp_Object window
;
13503 struct text_pos pos
;
13506 struct window
*w
= XWINDOW (window
);
13508 struct glyph_row
*last_text_row
= NULL
;
13510 /* Make POS the new window start. */
13511 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
13513 /* Mark cursor position as unknown. No overlay arrow seen. */
13514 w
->cursor
.vpos
= -1;
13515 overlay_arrow_seen
= 0;
13517 /* Initialize iterator and info to start at POS. */
13518 start_display (&it
, w
, pos
);
13520 /* Display all lines of W. */
13521 while (it
.current_y
< it
.last_visible_y
)
13523 if (display_line (&it
))
13524 last_text_row
= it
.glyph_row
- 1;
13525 if (fonts_changed_p
)
13529 /* Don't let the cursor end in the scroll margins. */
13531 && !MINI_WINDOW_P (w
))
13533 int this_scroll_margin
;
13535 this_scroll_margin
= max (0, scroll_margin
);
13536 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13537 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
13539 if ((w
->cursor
.y
>= 0 /* not vscrolled */
13540 && w
->cursor
.y
< this_scroll_margin
13541 && CHARPOS (pos
) > BEGV
13542 && IT_CHARPOS (it
) < ZV
)
13543 /* rms: considering make_cursor_line_fully_visible_p here
13544 seems to give wrong results. We don't want to recenter
13545 when the last line is partly visible, we want to allow
13546 that case to be handled in the usual way. */
13547 || (w
->cursor
.y
+ 1) > it
.last_visible_y
)
13549 w
->cursor
.vpos
= -1;
13550 clear_glyph_matrix (w
->desired_matrix
);
13555 /* If bottom moved off end of frame, change mode line percentage. */
13556 if (XFASTINT (w
->window_end_pos
) <= 0
13557 && Z
!= IT_CHARPOS (it
))
13558 w
->update_mode_line
= Qt
;
13560 /* Set window_end_pos to the offset of the last character displayed
13561 on the window from the end of current_buffer. Set
13562 window_end_vpos to its row number. */
13565 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
13566 w
->window_end_bytepos
13567 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13569 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13571 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
13572 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
13573 ->displays_text_p
);
13577 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
13578 w
->window_end_pos
= make_number (Z
- ZV
);
13579 w
->window_end_vpos
= make_number (0);
13582 /* But that is not valid info until redisplay finishes. */
13583 w
->window_end_valid
= Qnil
;
13589 /************************************************************************
13590 Window redisplay reusing current matrix when buffer has not changed
13591 ************************************************************************/
13593 /* Try redisplay of window W showing an unchanged buffer with a
13594 different window start than the last time it was displayed by
13595 reusing its current matrix. Value is non-zero if successful.
13596 W->start is the new window start. */
13599 try_window_reusing_current_matrix (w
)
13602 struct frame
*f
= XFRAME (w
->frame
);
13603 struct glyph_row
*row
, *bottom_row
;
13606 struct text_pos start
, new_start
;
13607 int nrows_scrolled
, i
;
13608 struct glyph_row
*last_text_row
;
13609 struct glyph_row
*last_reused_text_row
;
13610 struct glyph_row
*start_row
;
13611 int start_vpos
, min_y
, max_y
;
13614 if (inhibit_try_window_reusing
)
13618 if (/* This function doesn't handle terminal frames. */
13619 !FRAME_WINDOW_P (f
)
13620 /* Don't try to reuse the display if windows have been split
13622 || windows_or_buffers_changed
13623 || cursor_type_changed
)
13626 /* Can't do this if region may have changed. */
13627 if ((!NILP (Vtransient_mark_mode
)
13628 && !NILP (current_buffer
->mark_active
))
13629 || !NILP (w
->region_showing
)
13630 || !NILP (Vshow_trailing_whitespace
))
13633 /* If top-line visibility has changed, give up. */
13634 if (WINDOW_WANTS_HEADER_LINE_P (w
)
13635 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
13638 /* Give up if old or new display is scrolled vertically. We could
13639 make this function handle this, but right now it doesn't. */
13640 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
13641 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
))
13644 /* The variable new_start now holds the new window start. The old
13645 start `start' can be determined from the current matrix. */
13646 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
13647 start
= start_row
->start
.pos
;
13648 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
13650 /* Clear the desired matrix for the display below. */
13651 clear_glyph_matrix (w
->desired_matrix
);
13653 if (CHARPOS (new_start
) <= CHARPOS (start
))
13657 /* Don't use this method if the display starts with an ellipsis
13658 displayed for invisible text. It's not easy to handle that case
13659 below, and it's certainly not worth the effort since this is
13660 not a frequent case. */
13661 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
13664 IF_DEBUG (debug_method_add (w
, "twu1"));
13666 /* Display up to a row that can be reused. The variable
13667 last_text_row is set to the last row displayed that displays
13668 text. Note that it.vpos == 0 if or if not there is a
13669 header-line; it's not the same as the MATRIX_ROW_VPOS! */
13670 start_display (&it
, w
, new_start
);
13671 first_row_y
= it
.current_y
;
13672 w
->cursor
.vpos
= -1;
13673 last_text_row
= last_reused_text_row
= NULL
;
13675 while (it
.current_y
< it
.last_visible_y
13676 && !fonts_changed_p
)
13678 /* If we have reached into the characters in the START row,
13679 that means the line boundaries have changed. So we
13680 can't start copying with the row START. Maybe it will
13681 work to start copying with the following row. */
13682 while (IT_CHARPOS (it
) > CHARPOS (start
))
13684 /* Advance to the next row as the "start". */
13686 start
= start_row
->start
.pos
;
13687 /* If there are no more rows to try, or just one, give up. */
13688 if (start_row
== MATRIX_MODE_LINE_ROW (w
->current_matrix
) - 1
13689 || w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
)
13690 || CHARPOS (start
) == ZV
)
13692 clear_glyph_matrix (w
->desired_matrix
);
13696 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
13698 /* If we have reached alignment,
13699 we can copy the rest of the rows. */
13700 if (IT_CHARPOS (it
) == CHARPOS (start
))
13703 if (display_line (&it
))
13704 last_text_row
= it
.glyph_row
- 1;
13707 /* A value of current_y < last_visible_y means that we stopped
13708 at the previous window start, which in turn means that we
13709 have at least one reusable row. */
13710 if (it
.current_y
< it
.last_visible_y
)
13712 /* IT.vpos always starts from 0; it counts text lines. */
13713 nrows_scrolled
= it
.vpos
- (start_row
- MATRIX_FIRST_TEXT_ROW (w
->current_matrix
));
13715 /* Find PT if not already found in the lines displayed. */
13716 if (w
->cursor
.vpos
< 0)
13718 int dy
= it
.current_y
- start_row
->y
;
13720 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
13721 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
13723 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
13724 dy
, nrows_scrolled
);
13727 clear_glyph_matrix (w
->desired_matrix
);
13732 /* Scroll the display. Do it before the current matrix is
13733 changed. The problem here is that update has not yet
13734 run, i.e. part of the current matrix is not up to date.
13735 scroll_run_hook will clear the cursor, and use the
13736 current matrix to get the height of the row the cursor is
13738 run
.current_y
= start_row
->y
;
13739 run
.desired_y
= it
.current_y
;
13740 run
.height
= it
.last_visible_y
- it
.current_y
;
13742 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
13745 rif
->update_window_begin_hook (w
);
13746 rif
->clear_window_mouse_face (w
);
13747 rif
->scroll_run_hook (w
, &run
);
13748 rif
->update_window_end_hook (w
, 0, 0);
13752 /* Shift current matrix down by nrows_scrolled lines. */
13753 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
13754 rotate_matrix (w
->current_matrix
,
13756 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
13759 /* Disable lines that must be updated. */
13760 for (i
= 0; i
< it
.vpos
; ++i
)
13761 (start_row
+ i
)->enabled_p
= 0;
13763 /* Re-compute Y positions. */
13764 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
13765 max_y
= it
.last_visible_y
;
13766 for (row
= start_row
+ nrows_scrolled
;
13770 row
->y
= it
.current_y
;
13771 row
->visible_height
= row
->height
;
13773 if (row
->y
< min_y
)
13774 row
->visible_height
-= min_y
- row
->y
;
13775 if (row
->y
+ row
->height
> max_y
)
13776 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
13777 row
->redraw_fringe_bitmaps_p
= 1;
13779 it
.current_y
+= row
->height
;
13781 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
13782 last_reused_text_row
= row
;
13783 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
13787 /* Disable lines in the current matrix which are now
13788 below the window. */
13789 for (++row
; row
< bottom_row
; ++row
)
13790 row
->enabled_p
= row
->mode_line_p
= 0;
13793 /* Update window_end_pos etc.; last_reused_text_row is the last
13794 reused row from the current matrix containing text, if any.
13795 The value of last_text_row is the last displayed line
13796 containing text. */
13797 if (last_reused_text_row
)
13799 w
->window_end_bytepos
13800 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
13802 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
13804 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
13805 w
->current_matrix
));
13807 else if (last_text_row
)
13809 w
->window_end_bytepos
13810 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13812 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13814 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
13818 /* This window must be completely empty. */
13819 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
13820 w
->window_end_pos
= make_number (Z
- ZV
);
13821 w
->window_end_vpos
= make_number (0);
13823 w
->window_end_valid
= Qnil
;
13825 /* Update hint: don't try scrolling again in update_window. */
13826 w
->desired_matrix
->no_scrolling_p
= 1;
13829 debug_method_add (w
, "try_window_reusing_current_matrix 1");
13833 else if (CHARPOS (new_start
) > CHARPOS (start
))
13835 struct glyph_row
*pt_row
, *row
;
13836 struct glyph_row
*first_reusable_row
;
13837 struct glyph_row
*first_row_to_display
;
13839 int yb
= window_text_bottom_y (w
);
13841 /* Find the row starting at new_start, if there is one. Don't
13842 reuse a partially visible line at the end. */
13843 first_reusable_row
= start_row
;
13844 while (first_reusable_row
->enabled_p
13845 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
13846 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
13847 < CHARPOS (new_start
)))
13848 ++first_reusable_row
;
13850 /* Give up if there is no row to reuse. */
13851 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
13852 || !first_reusable_row
->enabled_p
13853 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
13854 != CHARPOS (new_start
)))
13857 /* We can reuse fully visible rows beginning with
13858 first_reusable_row to the end of the window. Set
13859 first_row_to_display to the first row that cannot be reused.
13860 Set pt_row to the row containing point, if there is any. */
13862 for (first_row_to_display
= first_reusable_row
;
13863 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
13864 ++first_row_to_display
)
13866 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
13867 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
13868 pt_row
= first_row_to_display
;
13871 /* Start displaying at the start of first_row_to_display. */
13872 xassert (first_row_to_display
->y
< yb
);
13873 init_to_row_start (&it
, w
, first_row_to_display
);
13875 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
13877 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
13879 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
13880 + WINDOW_HEADER_LINE_HEIGHT (w
));
13882 /* Display lines beginning with first_row_to_display in the
13883 desired matrix. Set last_text_row to the last row displayed
13884 that displays text. */
13885 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
13886 if (pt_row
== NULL
)
13887 w
->cursor
.vpos
= -1;
13888 last_text_row
= NULL
;
13889 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
13890 if (display_line (&it
))
13891 last_text_row
= it
.glyph_row
- 1;
13893 /* Give up If point isn't in a row displayed or reused. */
13894 if (w
->cursor
.vpos
< 0)
13896 clear_glyph_matrix (w
->desired_matrix
);
13900 /* If point is in a reused row, adjust y and vpos of the cursor
13904 w
->cursor
.vpos
-= nrows_scrolled
;
13905 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
13908 /* Scroll the display. */
13909 run
.current_y
= first_reusable_row
->y
;
13910 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
13911 run
.height
= it
.last_visible_y
- run
.current_y
;
13912 dy
= run
.current_y
- run
.desired_y
;
13917 rif
->update_window_begin_hook (w
);
13918 rif
->clear_window_mouse_face (w
);
13919 rif
->scroll_run_hook (w
, &run
);
13920 rif
->update_window_end_hook (w
, 0, 0);
13924 /* Adjust Y positions of reused rows. */
13925 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
13926 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
13927 max_y
= it
.last_visible_y
;
13928 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
13931 row
->visible_height
= row
->height
;
13932 if (row
->y
< min_y
)
13933 row
->visible_height
-= min_y
- row
->y
;
13934 if (row
->y
+ row
->height
> max_y
)
13935 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
13936 row
->redraw_fringe_bitmaps_p
= 1;
13939 /* Scroll the current matrix. */
13940 xassert (nrows_scrolled
> 0);
13941 rotate_matrix (w
->current_matrix
,
13943 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
13946 /* Disable rows not reused. */
13947 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
13948 row
->enabled_p
= 0;
13950 /* Point may have moved to a different line, so we cannot assume that
13951 the previous cursor position is valid; locate the correct row. */
13954 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
13955 row
< bottom_row
&& PT
>= MATRIX_ROW_END_CHARPOS (row
);
13959 w
->cursor
.y
= row
->y
;
13961 if (row
< bottom_row
)
13963 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
13964 while (glyph
->charpos
< PT
)
13967 w
->cursor
.x
+= glyph
->pixel_width
;
13973 /* Adjust window end. A null value of last_text_row means that
13974 the window end is in reused rows which in turn means that
13975 only its vpos can have changed. */
13978 w
->window_end_bytepos
13979 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13981 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13983 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
13988 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
13991 w
->window_end_valid
= Qnil
;
13992 w
->desired_matrix
->no_scrolling_p
= 1;
13995 debug_method_add (w
, "try_window_reusing_current_matrix 2");
14005 /************************************************************************
14006 Window redisplay reusing current matrix when buffer has changed
14007 ************************************************************************/
14009 static struct glyph_row
*find_last_unchanged_at_beg_row
P_ ((struct window
*));
14010 static struct glyph_row
*find_first_unchanged_at_end_row
P_ ((struct window
*,
14012 static struct glyph_row
*
14013 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
14014 struct glyph_row
*));
14017 /* Return the last row in MATRIX displaying text. If row START is
14018 non-null, start searching with that row. IT gives the dimensions
14019 of the display. Value is null if matrix is empty; otherwise it is
14020 a pointer to the row found. */
14022 static struct glyph_row
*
14023 find_last_row_displaying_text (matrix
, it
, start
)
14024 struct glyph_matrix
*matrix
;
14026 struct glyph_row
*start
;
14028 struct glyph_row
*row
, *row_found
;
14030 /* Set row_found to the last row in IT->w's current matrix
14031 displaying text. The loop looks funny but think of partially
14034 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
14035 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
14037 xassert (row
->enabled_p
);
14039 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
14048 /* Return the last row in the current matrix of W that is not affected
14049 by changes at the start of current_buffer that occurred since W's
14050 current matrix was built. Value is null if no such row exists.
14052 BEG_UNCHANGED us the number of characters unchanged at the start of
14053 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14054 first changed character in current_buffer. Characters at positions <
14055 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14056 when the current matrix was built. */
14058 static struct glyph_row
*
14059 find_last_unchanged_at_beg_row (w
)
14062 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
14063 struct glyph_row
*row
;
14064 struct glyph_row
*row_found
= NULL
;
14065 int yb
= window_text_bottom_y (w
);
14067 /* Find the last row displaying unchanged text. */
14068 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
14069 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
14070 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
14072 if (/* If row ends before first_changed_pos, it is unchanged,
14073 except in some case. */
14074 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
14075 /* When row ends in ZV and we write at ZV it is not
14077 && !row
->ends_at_zv_p
14078 /* When first_changed_pos is the end of a continued line,
14079 row is not unchanged because it may be no longer
14081 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
14082 && (row
->continued_p
14083 || row
->exact_window_width_line_p
)))
14086 /* Stop if last visible row. */
14087 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
14097 /* Find the first glyph row in the current matrix of W that is not
14098 affected by changes at the end of current_buffer since the
14099 time W's current matrix was built.
14101 Return in *DELTA the number of chars by which buffer positions in
14102 unchanged text at the end of current_buffer must be adjusted.
14104 Return in *DELTA_BYTES the corresponding number of bytes.
14106 Value is null if no such row exists, i.e. all rows are affected by
14109 static struct glyph_row
*
14110 find_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
14112 int *delta
, *delta_bytes
;
14114 struct glyph_row
*row
;
14115 struct glyph_row
*row_found
= NULL
;
14117 *delta
= *delta_bytes
= 0;
14119 /* Display must not have been paused, otherwise the current matrix
14120 is not up to date. */
14121 if (NILP (w
->window_end_valid
))
14124 /* A value of window_end_pos >= END_UNCHANGED means that the window
14125 end is in the range of changed text. If so, there is no
14126 unchanged row at the end of W's current matrix. */
14127 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
14130 /* Set row to the last row in W's current matrix displaying text. */
14131 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
14133 /* If matrix is entirely empty, no unchanged row exists. */
14134 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
14136 /* The value of row is the last glyph row in the matrix having a
14137 meaningful buffer position in it. The end position of row
14138 corresponds to window_end_pos. This allows us to translate
14139 buffer positions in the current matrix to current buffer
14140 positions for characters not in changed text. */
14141 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
14142 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
14143 int last_unchanged_pos
, last_unchanged_pos_old
;
14144 struct glyph_row
*first_text_row
14145 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
14147 *delta
= Z
- Z_old
;
14148 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
14150 /* Set last_unchanged_pos to the buffer position of the last
14151 character in the buffer that has not been changed. Z is the
14152 index + 1 of the last character in current_buffer, i.e. by
14153 subtracting END_UNCHANGED we get the index of the last
14154 unchanged character, and we have to add BEG to get its buffer
14156 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
14157 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
14159 /* Search backward from ROW for a row displaying a line that
14160 starts at a minimum position >= last_unchanged_pos_old. */
14161 for (; row
> first_text_row
; --row
)
14163 /* This used to abort, but it can happen.
14164 It is ok to just stop the search instead here. KFS. */
14165 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
14168 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
14173 if (row_found
&& !MATRIX_ROW_DISPLAYS_TEXT_P (row_found
))
14180 /* Make sure that glyph rows in the current matrix of window W
14181 reference the same glyph memory as corresponding rows in the
14182 frame's frame matrix. This function is called after scrolling W's
14183 current matrix on a terminal frame in try_window_id and
14184 try_window_reusing_current_matrix. */
14187 sync_frame_with_window_matrix_rows (w
)
14190 struct frame
*f
= XFRAME (w
->frame
);
14191 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
14193 /* Preconditions: W must be a leaf window and full-width. Its frame
14194 must have a frame matrix. */
14195 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
14196 xassert (WINDOW_FULL_WIDTH_P (w
));
14197 xassert (!FRAME_WINDOW_P (f
));
14199 /* If W is a full-width window, glyph pointers in W's current matrix
14200 have, by definition, to be the same as glyph pointers in the
14201 corresponding frame matrix. Note that frame matrices have no
14202 marginal areas (see build_frame_matrix). */
14203 window_row
= w
->current_matrix
->rows
;
14204 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
14205 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
14206 while (window_row
< window_row_end
)
14208 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
14209 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
14211 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
14212 frame_row
->glyphs
[TEXT_AREA
] = start
;
14213 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
14214 frame_row
->glyphs
[LAST_AREA
] = end
;
14216 /* Disable frame rows whose corresponding window rows have
14217 been disabled in try_window_id. */
14218 if (!window_row
->enabled_p
)
14219 frame_row
->enabled_p
= 0;
14221 ++window_row
, ++frame_row
;
14226 /* Find the glyph row in window W containing CHARPOS. Consider all
14227 rows between START and END (not inclusive). END null means search
14228 all rows to the end of the display area of W. Value is the row
14229 containing CHARPOS or null. */
14232 row_containing_pos (w
, charpos
, start
, end
, dy
)
14235 struct glyph_row
*start
, *end
;
14238 struct glyph_row
*row
= start
;
14241 /* If we happen to start on a header-line, skip that. */
14242 if (row
->mode_line_p
)
14245 if ((end
&& row
>= end
) || !row
->enabled_p
)
14248 last_y
= window_text_bottom_y (w
) - dy
;
14252 /* Give up if we have gone too far. */
14253 if (end
&& row
>= end
)
14255 /* This formerly returned if they were equal.
14256 I think that both quantities are of a "last plus one" type;
14257 if so, when they are equal, the row is within the screen. -- rms. */
14258 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
14261 /* If it is in this row, return this row. */
14262 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
14263 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
14264 /* The end position of a row equals the start
14265 position of the next row. If CHARPOS is there, we
14266 would rather display it in the next line, except
14267 when this line ends in ZV. */
14268 && !row
->ends_at_zv_p
14269 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
14270 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
14277 /* Try to redisplay window W by reusing its existing display. W's
14278 current matrix must be up to date when this function is called,
14279 i.e. window_end_valid must not be nil.
14283 1 if display has been updated
14284 0 if otherwise unsuccessful
14285 -1 if redisplay with same window start is known not to succeed
14287 The following steps are performed:
14289 1. Find the last row in the current matrix of W that is not
14290 affected by changes at the start of current_buffer. If no such row
14293 2. Find the first row in W's current matrix that is not affected by
14294 changes at the end of current_buffer. Maybe there is no such row.
14296 3. Display lines beginning with the row + 1 found in step 1 to the
14297 row found in step 2 or, if step 2 didn't find a row, to the end of
14300 4. If cursor is not known to appear on the window, give up.
14302 5. If display stopped at the row found in step 2, scroll the
14303 display and current matrix as needed.
14305 6. Maybe display some lines at the end of W, if we must. This can
14306 happen under various circumstances, like a partially visible line
14307 becoming fully visible, or because newly displayed lines are displayed
14308 in smaller font sizes.
14310 7. Update W's window end information. */
14316 struct frame
*f
= XFRAME (w
->frame
);
14317 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
14318 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
14319 struct glyph_row
*last_unchanged_at_beg_row
;
14320 struct glyph_row
*first_unchanged_at_end_row
;
14321 struct glyph_row
*row
;
14322 struct glyph_row
*bottom_row
;
14325 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
14326 struct text_pos start_pos
;
14328 int first_unchanged_at_end_vpos
= 0;
14329 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
14330 struct text_pos start
;
14331 int first_changed_charpos
, last_changed_charpos
;
14334 if (inhibit_try_window_id
)
14338 /* This is handy for debugging. */
14340 #define GIVE_UP(X) \
14342 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14346 #define GIVE_UP(X) return 0
14349 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
14351 /* Don't use this for mini-windows because these can show
14352 messages and mini-buffers, and we don't handle that here. */
14353 if (MINI_WINDOW_P (w
))
14356 /* This flag is used to prevent redisplay optimizations. */
14357 if (windows_or_buffers_changed
|| cursor_type_changed
)
14360 /* Verify that narrowing has not changed.
14361 Also verify that we were not told to prevent redisplay optimizations.
14362 It would be nice to further
14363 reduce the number of cases where this prevents try_window_id. */
14364 if (current_buffer
->clip_changed
14365 || current_buffer
->prevent_redisplay_optimizations_p
)
14368 /* Window must either use window-based redisplay or be full width. */
14369 if (!FRAME_WINDOW_P (f
)
14370 && (!line_ins_del_ok
14371 || !WINDOW_FULL_WIDTH_P (w
)))
14374 /* Give up if point is not known NOT to appear in W. */
14375 if (PT
< CHARPOS (start
))
14378 /* Another way to prevent redisplay optimizations. */
14379 if (XFASTINT (w
->last_modified
) == 0)
14382 /* Verify that window is not hscrolled. */
14383 if (XFASTINT (w
->hscroll
) != 0)
14386 /* Verify that display wasn't paused. */
14387 if (NILP (w
->window_end_valid
))
14390 /* Can't use this if highlighting a region because a cursor movement
14391 will do more than just set the cursor. */
14392 if (!NILP (Vtransient_mark_mode
)
14393 && !NILP (current_buffer
->mark_active
))
14396 /* Likewise if highlighting trailing whitespace. */
14397 if (!NILP (Vshow_trailing_whitespace
))
14400 /* Likewise if showing a region. */
14401 if (!NILP (w
->region_showing
))
14404 /* Can use this if overlay arrow position and or string have changed. */
14405 if (overlay_arrows_changed_p ())
14409 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14410 only if buffer has really changed. The reason is that the gap is
14411 initially at Z for freshly visited files. The code below would
14412 set end_unchanged to 0 in that case. */
14413 if (MODIFF
> SAVE_MODIFF
14414 /* This seems to happen sometimes after saving a buffer. */
14415 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
14417 if (GPT
- BEG
< BEG_UNCHANGED
)
14418 BEG_UNCHANGED
= GPT
- BEG
;
14419 if (Z
- GPT
< END_UNCHANGED
)
14420 END_UNCHANGED
= Z
- GPT
;
14423 /* The position of the first and last character that has been changed. */
14424 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
14425 last_changed_charpos
= Z
- END_UNCHANGED
;
14427 /* If window starts after a line end, and the last change is in
14428 front of that newline, then changes don't affect the display.
14429 This case happens with stealth-fontification. Note that although
14430 the display is unchanged, glyph positions in the matrix have to
14431 be adjusted, of course. */
14432 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
14433 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
14434 && ((last_changed_charpos
< CHARPOS (start
)
14435 && CHARPOS (start
) == BEGV
)
14436 || (last_changed_charpos
< CHARPOS (start
) - 1
14437 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
14439 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
14440 struct glyph_row
*r0
;
14442 /* Compute how many chars/bytes have been added to or removed
14443 from the buffer. */
14444 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
14445 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
14447 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
14449 /* Give up if PT is not in the window. Note that it already has
14450 been checked at the start of try_window_id that PT is not in
14451 front of the window start. */
14452 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
14455 /* If window start is unchanged, we can reuse the whole matrix
14456 as is, after adjusting glyph positions. No need to compute
14457 the window end again, since its offset from Z hasn't changed. */
14458 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
14459 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
14460 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
14461 /* PT must not be in a partially visible line. */
14462 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
14463 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
14465 /* Adjust positions in the glyph matrix. */
14466 if (delta
|| delta_bytes
)
14468 struct glyph_row
*r1
14469 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
14470 increment_matrix_positions (w
->current_matrix
,
14471 MATRIX_ROW_VPOS (r0
, current_matrix
),
14472 MATRIX_ROW_VPOS (r1
, current_matrix
),
14473 delta
, delta_bytes
);
14476 /* Set the cursor. */
14477 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
14479 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
14486 /* Handle the case that changes are all below what is displayed in
14487 the window, and that PT is in the window. This shortcut cannot
14488 be taken if ZV is visible in the window, and text has been added
14489 there that is visible in the window. */
14490 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
14491 /* ZV is not visible in the window, or there are no
14492 changes at ZV, actually. */
14493 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
14494 || first_changed_charpos
== last_changed_charpos
))
14496 struct glyph_row
*r0
;
14498 /* Give up if PT is not in the window. Note that it already has
14499 been checked at the start of try_window_id that PT is not in
14500 front of the window start. */
14501 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
14504 /* If window start is unchanged, we can reuse the whole matrix
14505 as is, without changing glyph positions since no text has
14506 been added/removed in front of the window end. */
14507 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
14508 if (TEXT_POS_EQUAL_P (start
, r0
->start
.pos
)
14509 /* PT must not be in a partially visible line. */
14510 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
14511 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
14513 /* We have to compute the window end anew since text
14514 can have been added/removed after it. */
14516 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
14517 w
->window_end_bytepos
14518 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
14520 /* Set the cursor. */
14521 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
14523 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
14530 /* Give up if window start is in the changed area.
14532 The condition used to read
14534 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
14536 but why that was tested escapes me at the moment. */
14537 if (CHARPOS (start
) >= first_changed_charpos
14538 && CHARPOS (start
) <= last_changed_charpos
)
14541 /* Check that window start agrees with the start of the first glyph
14542 row in its current matrix. Check this after we know the window
14543 start is not in changed text, otherwise positions would not be
14545 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
14546 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
14549 /* Give up if the window ends in strings. Overlay strings
14550 at the end are difficult to handle, so don't try. */
14551 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
14552 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
14555 /* Compute the position at which we have to start displaying new
14556 lines. Some of the lines at the top of the window might be
14557 reusable because they are not displaying changed text. Find the
14558 last row in W's current matrix not affected by changes at the
14559 start of current_buffer. Value is null if changes start in the
14560 first line of window. */
14561 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
14562 if (last_unchanged_at_beg_row
)
14564 /* Avoid starting to display in the moddle of a character, a TAB
14565 for instance. This is easier than to set up the iterator
14566 exactly, and it's not a frequent case, so the additional
14567 effort wouldn't really pay off. */
14568 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
14569 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
14570 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
14571 --last_unchanged_at_beg_row
;
14573 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
14576 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
14578 start_pos
= it
.current
.pos
;
14580 /* Start displaying new lines in the desired matrix at the same
14581 vpos we would use in the current matrix, i.e. below
14582 last_unchanged_at_beg_row. */
14583 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
14585 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
14586 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
14588 xassert (it
.hpos
== 0 && it
.current_x
== 0);
14592 /* There are no reusable lines at the start of the window.
14593 Start displaying in the first text line. */
14594 start_display (&it
, w
, start
);
14595 it
.vpos
= it
.first_vpos
;
14596 start_pos
= it
.current
.pos
;
14599 /* Find the first row that is not affected by changes at the end of
14600 the buffer. Value will be null if there is no unchanged row, in
14601 which case we must redisplay to the end of the window. delta
14602 will be set to the value by which buffer positions beginning with
14603 first_unchanged_at_end_row have to be adjusted due to text
14605 first_unchanged_at_end_row
14606 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
14607 IF_DEBUG (debug_delta
= delta
);
14608 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
14610 /* Set stop_pos to the buffer position up to which we will have to
14611 display new lines. If first_unchanged_at_end_row != NULL, this
14612 is the buffer position of the start of the line displayed in that
14613 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
14614 that we don't stop at a buffer position. */
14616 if (first_unchanged_at_end_row
)
14618 xassert (last_unchanged_at_beg_row
== NULL
14619 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
14621 /* If this is a continuation line, move forward to the next one
14622 that isn't. Changes in lines above affect this line.
14623 Caution: this may move first_unchanged_at_end_row to a row
14624 not displaying text. */
14625 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
14626 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
14627 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
14628 < it
.last_visible_y
))
14629 ++first_unchanged_at_end_row
;
14631 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
14632 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
14633 >= it
.last_visible_y
))
14634 first_unchanged_at_end_row
= NULL
;
14637 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
14639 first_unchanged_at_end_vpos
14640 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
14641 xassert (stop_pos
>= Z
- END_UNCHANGED
);
14644 else if (last_unchanged_at_beg_row
== NULL
)
14650 /* Either there is no unchanged row at the end, or the one we have
14651 now displays text. This is a necessary condition for the window
14652 end pos calculation at the end of this function. */
14653 xassert (first_unchanged_at_end_row
== NULL
14654 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
14656 debug_last_unchanged_at_beg_vpos
14657 = (last_unchanged_at_beg_row
14658 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
14660 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
14662 #endif /* GLYPH_DEBUG != 0 */
14665 /* Display new lines. Set last_text_row to the last new line
14666 displayed which has text on it, i.e. might end up as being the
14667 line where the window_end_vpos is. */
14668 w
->cursor
.vpos
= -1;
14669 last_text_row
= NULL
;
14670 overlay_arrow_seen
= 0;
14671 while (it
.current_y
< it
.last_visible_y
14672 && !fonts_changed_p
14673 && (first_unchanged_at_end_row
== NULL
14674 || IT_CHARPOS (it
) < stop_pos
))
14676 if (display_line (&it
))
14677 last_text_row
= it
.glyph_row
- 1;
14680 if (fonts_changed_p
)
14684 /* Compute differences in buffer positions, y-positions etc. for
14685 lines reused at the bottom of the window. Compute what we can
14687 if (first_unchanged_at_end_row
14688 /* No lines reused because we displayed everything up to the
14689 bottom of the window. */
14690 && it
.current_y
< it
.last_visible_y
)
14693 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
14695 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
14696 run
.current_y
= first_unchanged_at_end_row
->y
;
14697 run
.desired_y
= run
.current_y
+ dy
;
14698 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
14702 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
14703 first_unchanged_at_end_row
= NULL
;
14705 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
14708 /* Find the cursor if not already found. We have to decide whether
14709 PT will appear on this window (it sometimes doesn't, but this is
14710 not a very frequent case.) This decision has to be made before
14711 the current matrix is altered. A value of cursor.vpos < 0 means
14712 that PT is either in one of the lines beginning at
14713 first_unchanged_at_end_row or below the window. Don't care for
14714 lines that might be displayed later at the window end; as
14715 mentioned, this is not a frequent case. */
14716 if (w
->cursor
.vpos
< 0)
14718 /* Cursor in unchanged rows at the top? */
14719 if (PT
< CHARPOS (start_pos
)
14720 && last_unchanged_at_beg_row
)
14722 row
= row_containing_pos (w
, PT
,
14723 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
14724 last_unchanged_at_beg_row
+ 1, 0);
14726 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
14729 /* Start from first_unchanged_at_end_row looking for PT. */
14730 else if (first_unchanged_at_end_row
)
14732 row
= row_containing_pos (w
, PT
- delta
,
14733 first_unchanged_at_end_row
, NULL
, 0);
14735 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
14736 delta_bytes
, dy
, dvpos
);
14739 /* Give up if cursor was not found. */
14740 if (w
->cursor
.vpos
< 0)
14742 clear_glyph_matrix (w
->desired_matrix
);
14747 /* Don't let the cursor end in the scroll margins. */
14749 int this_scroll_margin
, cursor_height
;
14751 this_scroll_margin
= max (0, scroll_margin
);
14752 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
14753 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
14754 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
14756 if ((w
->cursor
.y
< this_scroll_margin
14757 && CHARPOS (start
) > BEGV
)
14758 /* Old redisplay didn't take scroll margin into account at the bottom,
14759 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14760 || (w
->cursor
.y
+ (make_cursor_line_fully_visible_p
14761 ? cursor_height
+ this_scroll_margin
14762 : 1)) > it
.last_visible_y
)
14764 w
->cursor
.vpos
= -1;
14765 clear_glyph_matrix (w
->desired_matrix
);
14770 /* Scroll the display. Do it before changing the current matrix so
14771 that xterm.c doesn't get confused about where the cursor glyph is
14773 if (dy
&& run
.height
)
14777 if (FRAME_WINDOW_P (f
))
14779 rif
->update_window_begin_hook (w
);
14780 rif
->clear_window_mouse_face (w
);
14781 rif
->scroll_run_hook (w
, &run
);
14782 rif
->update_window_end_hook (w
, 0, 0);
14786 /* Terminal frame. In this case, dvpos gives the number of
14787 lines to scroll by; dvpos < 0 means scroll up. */
14788 int first_unchanged_at_end_vpos
14789 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
14790 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
14791 int end
= (WINDOW_TOP_EDGE_LINE (w
)
14792 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
14793 + window_internal_height (w
));
14795 /* Perform the operation on the screen. */
14798 /* Scroll last_unchanged_at_beg_row to the end of the
14799 window down dvpos lines. */
14800 set_terminal_window (end
);
14802 /* On dumb terminals delete dvpos lines at the end
14803 before inserting dvpos empty lines. */
14804 if (!scroll_region_ok
)
14805 ins_del_lines (end
- dvpos
, -dvpos
);
14807 /* Insert dvpos empty lines in front of
14808 last_unchanged_at_beg_row. */
14809 ins_del_lines (from
, dvpos
);
14811 else if (dvpos
< 0)
14813 /* Scroll up last_unchanged_at_beg_vpos to the end of
14814 the window to last_unchanged_at_beg_vpos - |dvpos|. */
14815 set_terminal_window (end
);
14817 /* Delete dvpos lines in front of
14818 last_unchanged_at_beg_vpos. ins_del_lines will set
14819 the cursor to the given vpos and emit |dvpos| delete
14821 ins_del_lines (from
+ dvpos
, dvpos
);
14823 /* On a dumb terminal insert dvpos empty lines at the
14825 if (!scroll_region_ok
)
14826 ins_del_lines (end
+ dvpos
, -dvpos
);
14829 set_terminal_window (0);
14835 /* Shift reused rows of the current matrix to the right position.
14836 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
14838 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
14839 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
14842 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
14843 bottom_vpos
, dvpos
);
14844 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
14847 else if (dvpos
> 0)
14849 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
14850 bottom_vpos
, dvpos
);
14851 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
14852 first_unchanged_at_end_vpos
+ dvpos
, 0);
14855 /* For frame-based redisplay, make sure that current frame and window
14856 matrix are in sync with respect to glyph memory. */
14857 if (!FRAME_WINDOW_P (f
))
14858 sync_frame_with_window_matrix_rows (w
);
14860 /* Adjust buffer positions in reused rows. */
14862 increment_matrix_positions (current_matrix
,
14863 first_unchanged_at_end_vpos
+ dvpos
,
14864 bottom_vpos
, delta
, delta_bytes
);
14866 /* Adjust Y positions. */
14868 shift_glyph_matrix (w
, current_matrix
,
14869 first_unchanged_at_end_vpos
+ dvpos
,
14872 if (first_unchanged_at_end_row
)
14874 first_unchanged_at_end_row
+= dvpos
;
14875 if (first_unchanged_at_end_row
->y
>= it
.last_visible_y
14876 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
))
14877 first_unchanged_at_end_row
= NULL
;
14880 /* If scrolling up, there may be some lines to display at the end of
14882 last_text_row_at_end
= NULL
;
14885 /* Scrolling up can leave for example a partially visible line
14886 at the end of the window to be redisplayed. */
14887 /* Set last_row to the glyph row in the current matrix where the
14888 window end line is found. It has been moved up or down in
14889 the matrix by dvpos. */
14890 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
14891 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
14893 /* If last_row is the window end line, it should display text. */
14894 xassert (last_row
->displays_text_p
);
14896 /* If window end line was partially visible before, begin
14897 displaying at that line. Otherwise begin displaying with the
14898 line following it. */
14899 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
14901 init_to_row_start (&it
, w
, last_row
);
14902 it
.vpos
= last_vpos
;
14903 it
.current_y
= last_row
->y
;
14907 init_to_row_end (&it
, w
, last_row
);
14908 it
.vpos
= 1 + last_vpos
;
14909 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
14913 /* We may start in a continuation line. If so, we have to
14914 get the right continuation_lines_width and current_x. */
14915 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
14916 it
.hpos
= it
.current_x
= 0;
14918 /* Display the rest of the lines at the window end. */
14919 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
14920 while (it
.current_y
< it
.last_visible_y
14921 && !fonts_changed_p
)
14923 /* Is it always sure that the display agrees with lines in
14924 the current matrix? I don't think so, so we mark rows
14925 displayed invalid in the current matrix by setting their
14926 enabled_p flag to zero. */
14927 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
14928 if (display_line (&it
))
14929 last_text_row_at_end
= it
.glyph_row
- 1;
14933 /* Update window_end_pos and window_end_vpos. */
14934 if (first_unchanged_at_end_row
14935 && !last_text_row_at_end
)
14937 /* Window end line if one of the preserved rows from the current
14938 matrix. Set row to the last row displaying text in current
14939 matrix starting at first_unchanged_at_end_row, after
14941 xassert (first_unchanged_at_end_row
->displays_text_p
);
14942 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
14943 first_unchanged_at_end_row
);
14944 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
14946 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
14947 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
14949 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
14950 xassert (w
->window_end_bytepos
>= 0);
14951 IF_DEBUG (debug_method_add (w
, "A"));
14953 else if (last_text_row_at_end
)
14956 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
14957 w
->window_end_bytepos
14958 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
14960 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
14961 xassert (w
->window_end_bytepos
>= 0);
14962 IF_DEBUG (debug_method_add (w
, "B"));
14964 else if (last_text_row
)
14966 /* We have displayed either to the end of the window or at the
14967 end of the window, i.e. the last row with text is to be found
14968 in the desired matrix. */
14970 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
14971 w
->window_end_bytepos
14972 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
14974 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
14975 xassert (w
->window_end_bytepos
>= 0);
14977 else if (first_unchanged_at_end_row
== NULL
14978 && last_text_row
== NULL
14979 && last_text_row_at_end
== NULL
)
14981 /* Displayed to end of window, but no line containing text was
14982 displayed. Lines were deleted at the end of the window. */
14983 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
14984 int vpos
= XFASTINT (w
->window_end_vpos
);
14985 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
14986 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
14989 row
== NULL
&& vpos
>= first_vpos
;
14990 --vpos
, --current_row
, --desired_row
)
14992 if (desired_row
->enabled_p
)
14994 if (desired_row
->displays_text_p
)
14997 else if (current_row
->displays_text_p
)
15001 xassert (row
!= NULL
);
15002 w
->window_end_vpos
= make_number (vpos
+ 1);
15003 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
15004 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
15005 xassert (w
->window_end_bytepos
>= 0);
15006 IF_DEBUG (debug_method_add (w
, "C"));
15011 #if 0 /* This leads to problems, for instance when the cursor is
15012 at ZV, and the cursor line displays no text. */
15013 /* Disable rows below what's displayed in the window. This makes
15014 debugging easier. */
15015 enable_glyph_matrix_rows (current_matrix
,
15016 XFASTINT (w
->window_end_vpos
) + 1,
15020 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
15021 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
15023 /* Record that display has not been completed. */
15024 w
->window_end_valid
= Qnil
;
15025 w
->desired_matrix
->no_scrolling_p
= 1;
15033 /***********************************************************************
15034 More debugging support
15035 ***********************************************************************/
15039 void dump_glyph_row
P_ ((struct glyph_row
*, int, int));
15040 void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
15041 void dump_glyph
P_ ((struct glyph_row
*, struct glyph
*, int));
15044 /* Dump the contents of glyph matrix MATRIX on stderr.
15046 GLYPHS 0 means don't show glyph contents.
15047 GLYPHS 1 means show glyphs in short form
15048 GLYPHS > 1 means show glyphs in long form. */
15051 dump_glyph_matrix (matrix
, glyphs
)
15052 struct glyph_matrix
*matrix
;
15056 for (i
= 0; i
< matrix
->nrows
; ++i
)
15057 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
15061 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15062 the glyph row and area where the glyph comes from. */
15065 dump_glyph (row
, glyph
, area
)
15066 struct glyph_row
*row
;
15067 struct glyph
*glyph
;
15070 if (glyph
->type
== CHAR_GLYPH
)
15073 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15074 glyph
- row
->glyphs
[TEXT_AREA
],
15077 (BUFFERP (glyph
->object
)
15079 : (STRINGP (glyph
->object
)
15082 glyph
->pixel_width
,
15084 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
15088 glyph
->left_box_line_p
,
15089 glyph
->right_box_line_p
);
15091 else if (glyph
->type
== STRETCH_GLYPH
)
15094 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15095 glyph
- row
->glyphs
[TEXT_AREA
],
15098 (BUFFERP (glyph
->object
)
15100 : (STRINGP (glyph
->object
)
15103 glyph
->pixel_width
,
15107 glyph
->left_box_line_p
,
15108 glyph
->right_box_line_p
);
15110 else if (glyph
->type
== IMAGE_GLYPH
)
15113 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15114 glyph
- row
->glyphs
[TEXT_AREA
],
15117 (BUFFERP (glyph
->object
)
15119 : (STRINGP (glyph
->object
)
15122 glyph
->pixel_width
,
15126 glyph
->left_box_line_p
,
15127 glyph
->right_box_line_p
);
15129 else if (glyph
->type
== COMPOSITE_GLYPH
)
15132 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15133 glyph
- row
->glyphs
[TEXT_AREA
],
15136 (BUFFERP (glyph
->object
)
15138 : (STRINGP (glyph
->object
)
15141 glyph
->pixel_width
,
15145 glyph
->left_box_line_p
,
15146 glyph
->right_box_line_p
);
15151 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15152 GLYPHS 0 means don't show glyph contents.
15153 GLYPHS 1 means show glyphs in short form
15154 GLYPHS > 1 means show glyphs in long form. */
15157 dump_glyph_row (row
, vpos
, glyphs
)
15158 struct glyph_row
*row
;
15163 fprintf (stderr
, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15164 fprintf (stderr
, "======================================================================\n");
15166 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15167 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15169 MATRIX_ROW_START_CHARPOS (row
),
15170 MATRIX_ROW_END_CHARPOS (row
),
15171 row
->used
[TEXT_AREA
],
15172 row
->contains_overlapping_glyphs_p
,
15174 row
->truncated_on_left_p
,
15175 row
->truncated_on_right_p
,
15177 MATRIX_ROW_CONTINUATION_LINE_P (row
),
15178 row
->displays_text_p
,
15181 row
->ends_in_middle_of_char_p
,
15182 row
->starts_in_middle_of_char_p
,
15188 row
->visible_height
,
15191 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
15192 row
->end
.overlay_string_index
,
15193 row
->continuation_lines_width
);
15194 fprintf (stderr
, "%9d %5d\n",
15195 CHARPOS (row
->start
.string_pos
),
15196 CHARPOS (row
->end
.string_pos
));
15197 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
15198 row
->end
.dpvec_index
);
15205 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
15207 struct glyph
*glyph
= row
->glyphs
[area
];
15208 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
15210 /* Glyph for a line end in text. */
15211 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
15214 if (glyph
< glyph_end
)
15215 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
15217 for (; glyph
< glyph_end
; ++glyph
)
15218 dump_glyph (row
, glyph
, area
);
15221 else if (glyphs
== 1)
15225 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
15227 char *s
= (char *) alloca (row
->used
[area
] + 1);
15230 for (i
= 0; i
< row
->used
[area
]; ++i
)
15232 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
15233 if (glyph
->type
== CHAR_GLYPH
15234 && glyph
->u
.ch
< 0x80
15235 && glyph
->u
.ch
>= ' ')
15236 s
[i
] = glyph
->u
.ch
;
15242 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
15248 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
15249 Sdump_glyph_matrix
, 0, 1, "p",
15250 doc
: /* Dump the current matrix of the selected window to stderr.
15251 Shows contents of glyph row structures. With non-nil
15252 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15253 glyphs in short form, otherwise show glyphs in long form. */)
15255 Lisp_Object glyphs
;
15257 struct window
*w
= XWINDOW (selected_window
);
15258 struct buffer
*buffer
= XBUFFER (w
->buffer
);
15260 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
15261 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
15262 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15263 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
15264 fprintf (stderr
, "=============================================\n");
15265 dump_glyph_matrix (w
->current_matrix
,
15266 NILP (glyphs
) ? 0 : XINT (glyphs
));
15271 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
15272 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
15275 struct frame
*f
= XFRAME (selected_frame
);
15276 dump_glyph_matrix (f
->current_matrix
, 1);
15281 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
15282 doc
: /* Dump glyph row ROW to stderr.
15283 GLYPH 0 means don't dump glyphs.
15284 GLYPH 1 means dump glyphs in short form.
15285 GLYPH > 1 or omitted means dump glyphs in long form. */)
15287 Lisp_Object row
, glyphs
;
15289 struct glyph_matrix
*matrix
;
15292 CHECK_NUMBER (row
);
15293 matrix
= XWINDOW (selected_window
)->current_matrix
;
15295 if (vpos
>= 0 && vpos
< matrix
->nrows
)
15296 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
15298 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
15303 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
15304 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15305 GLYPH 0 means don't dump glyphs.
15306 GLYPH 1 means dump glyphs in short form.
15307 GLYPH > 1 or omitted means dump glyphs in long form. */)
15309 Lisp_Object row
, glyphs
;
15311 struct frame
*sf
= SELECTED_FRAME ();
15312 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
15315 CHECK_NUMBER (row
);
15317 if (vpos
>= 0 && vpos
< m
->nrows
)
15318 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
15319 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
15324 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
15325 doc
: /* Toggle tracing of redisplay.
15326 With ARG, turn tracing on if and only if ARG is positive. */)
15331 trace_redisplay_p
= !trace_redisplay_p
;
15334 arg
= Fprefix_numeric_value (arg
);
15335 trace_redisplay_p
= XINT (arg
) > 0;
15342 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
15343 doc
: /* Like `format', but print result to stderr.
15344 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15349 Lisp_Object s
= Fformat (nargs
, args
);
15350 fprintf (stderr
, "%s", SDATA (s
));
15354 #endif /* GLYPH_DEBUG */
15358 /***********************************************************************
15359 Building Desired Matrix Rows
15360 ***********************************************************************/
15362 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15363 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15365 static struct glyph_row
*
15366 get_overlay_arrow_glyph_row (w
, overlay_arrow_string
)
15368 Lisp_Object overlay_arrow_string
;
15370 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
15371 struct buffer
*buffer
= XBUFFER (w
->buffer
);
15372 struct buffer
*old
= current_buffer
;
15373 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
15374 int arrow_len
= SCHARS (overlay_arrow_string
);
15375 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
15376 const unsigned char *p
;
15379 int n_glyphs_before
;
15381 set_buffer_temp (buffer
);
15382 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
15383 it
.glyph_row
->used
[TEXT_AREA
] = 0;
15384 SET_TEXT_POS (it
.position
, 0, 0);
15386 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
15388 while (p
< arrow_end
)
15390 Lisp_Object face
, ilisp
;
15392 /* Get the next character. */
15394 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
15396 it
.c
= *p
, it
.len
= 1;
15399 /* Get its face. */
15400 ilisp
= make_number (p
- arrow_string
);
15401 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
15402 it
.face_id
= compute_char_face (f
, it
.c
, face
);
15404 /* Compute its width, get its glyphs. */
15405 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
15406 SET_TEXT_POS (it
.position
, -1, -1);
15407 PRODUCE_GLYPHS (&it
);
15409 /* If this character doesn't fit any more in the line, we have
15410 to remove some glyphs. */
15411 if (it
.current_x
> it
.last_visible_x
)
15413 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
15418 set_buffer_temp (old
);
15419 return it
.glyph_row
;
15423 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15424 glyphs are only inserted for terminal frames since we can't really
15425 win with truncation glyphs when partially visible glyphs are
15426 involved. Which glyphs to insert is determined by
15427 produce_special_glyphs. */
15430 insert_left_trunc_glyphs (it
)
15433 struct it truncate_it
;
15434 struct glyph
*from
, *end
, *to
, *toend
;
15436 xassert (!FRAME_WINDOW_P (it
->f
));
15438 /* Get the truncation glyphs. */
15440 truncate_it
.current_x
= 0;
15441 truncate_it
.face_id
= DEFAULT_FACE_ID
;
15442 truncate_it
.glyph_row
= &scratch_glyph_row
;
15443 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
15444 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
15445 truncate_it
.object
= make_number (0);
15446 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
15448 /* Overwrite glyphs from IT with truncation glyphs. */
15449 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
15450 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
15451 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
15452 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
15457 /* There may be padding glyphs left over. Overwrite them too. */
15458 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
15460 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
15466 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
15470 /* Compute the pixel height and width of IT->glyph_row.
15472 Most of the time, ascent and height of a display line will be equal
15473 to the max_ascent and max_height values of the display iterator
15474 structure. This is not the case if
15476 1. We hit ZV without displaying anything. In this case, max_ascent
15477 and max_height will be zero.
15479 2. We have some glyphs that don't contribute to the line height.
15480 (The glyph row flag contributes_to_line_height_p is for future
15481 pixmap extensions).
15483 The first case is easily covered by using default values because in
15484 these cases, the line height does not really matter, except that it
15485 must not be zero. */
15488 compute_line_metrics (it
)
15491 struct glyph_row
*row
= it
->glyph_row
;
15494 if (FRAME_WINDOW_P (it
->f
))
15496 int i
, min_y
, max_y
;
15498 /* The line may consist of one space only, that was added to
15499 place the cursor on it. If so, the row's height hasn't been
15501 if (row
->height
== 0)
15503 if (it
->max_ascent
+ it
->max_descent
== 0)
15504 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
15505 row
->ascent
= it
->max_ascent
;
15506 row
->height
= it
->max_ascent
+ it
->max_descent
;
15507 row
->phys_ascent
= it
->max_phys_ascent
;
15508 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
15509 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
15512 /* Compute the width of this line. */
15513 row
->pixel_width
= row
->x
;
15514 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
15515 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
15517 xassert (row
->pixel_width
>= 0);
15518 xassert (row
->ascent
>= 0 && row
->height
> 0);
15520 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
15521 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
15523 /* If first line's physical ascent is larger than its logical
15524 ascent, use the physical ascent, and make the row taller.
15525 This makes accented characters fully visible. */
15526 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
15527 && row
->phys_ascent
> row
->ascent
)
15529 row
->height
+= row
->phys_ascent
- row
->ascent
;
15530 row
->ascent
= row
->phys_ascent
;
15533 /* Compute how much of the line is visible. */
15534 row
->visible_height
= row
->height
;
15536 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
15537 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
15539 if (row
->y
< min_y
)
15540 row
->visible_height
-= min_y
- row
->y
;
15541 if (row
->y
+ row
->height
> max_y
)
15542 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
15546 row
->pixel_width
= row
->used
[TEXT_AREA
];
15547 if (row
->continued_p
)
15548 row
->pixel_width
-= it
->continuation_pixel_width
;
15549 else if (row
->truncated_on_right_p
)
15550 row
->pixel_width
-= it
->truncation_pixel_width
;
15551 row
->ascent
= row
->phys_ascent
= 0;
15552 row
->height
= row
->phys_height
= row
->visible_height
= 1;
15553 row
->extra_line_spacing
= 0;
15556 /* Compute a hash code for this row. */
15558 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
15559 for (i
= 0; i
< row
->used
[area
]; ++i
)
15560 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
15561 + row
->glyphs
[area
][i
].u
.val
15562 + row
->glyphs
[area
][i
].face_id
15563 + row
->glyphs
[area
][i
].padding_p
15564 + (row
->glyphs
[area
][i
].type
<< 2));
15566 it
->max_ascent
= it
->max_descent
= 0;
15567 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
15571 /* Append one space to the glyph row of iterator IT if doing a
15572 window-based redisplay. The space has the same face as
15573 IT->face_id. Value is non-zero if a space was added.
15575 This function is called to make sure that there is always one glyph
15576 at the end of a glyph row that the cursor can be set on under
15577 window-systems. (If there weren't such a glyph we would not know
15578 how wide and tall a box cursor should be displayed).
15580 At the same time this space let's a nicely handle clearing to the
15581 end of the line if the row ends in italic text. */
15584 append_space_for_newline (it
, default_face_p
)
15586 int default_face_p
;
15588 if (FRAME_WINDOW_P (it
->f
))
15590 int n
= it
->glyph_row
->used
[TEXT_AREA
];
15592 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
15593 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
15595 /* Save some values that must not be changed.
15596 Must save IT->c and IT->len because otherwise
15597 ITERATOR_AT_END_P wouldn't work anymore after
15598 append_space_for_newline has been called. */
15599 enum display_element_type saved_what
= it
->what
;
15600 int saved_c
= it
->c
, saved_len
= it
->len
;
15601 int saved_x
= it
->current_x
;
15602 int saved_face_id
= it
->face_id
;
15603 struct text_pos saved_pos
;
15604 Lisp_Object saved_object
;
15607 saved_object
= it
->object
;
15608 saved_pos
= it
->position
;
15610 it
->what
= IT_CHARACTER
;
15611 bzero (&it
->position
, sizeof it
->position
);
15612 it
->object
= make_number (0);
15616 if (default_face_p
)
15617 it
->face_id
= DEFAULT_FACE_ID
;
15618 else if (it
->face_before_selective_p
)
15619 it
->face_id
= it
->saved_face_id
;
15620 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
15621 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0);
15623 PRODUCE_GLYPHS (it
);
15625 it
->override_ascent
= -1;
15626 it
->constrain_row_ascent_descent_p
= 0;
15627 it
->current_x
= saved_x
;
15628 it
->object
= saved_object
;
15629 it
->position
= saved_pos
;
15630 it
->what
= saved_what
;
15631 it
->face_id
= saved_face_id
;
15632 it
->len
= saved_len
;
15642 /* Extend the face of the last glyph in the text area of IT->glyph_row
15643 to the end of the display line. Called from display_line.
15644 If the glyph row is empty, add a space glyph to it so that we
15645 know the face to draw. Set the glyph row flag fill_line_p. */
15648 extend_face_to_end_of_line (it
)
15652 struct frame
*f
= it
->f
;
15654 /* If line is already filled, do nothing. */
15655 if (it
->current_x
>= it
->last_visible_x
)
15658 /* Face extension extends the background and box of IT->face_id
15659 to the end of the line. If the background equals the background
15660 of the frame, we don't have to do anything. */
15661 if (it
->face_before_selective_p
)
15662 face
= FACE_FROM_ID (it
->f
, it
->saved_face_id
);
15664 face
= FACE_FROM_ID (f
, it
->face_id
);
15666 if (FRAME_WINDOW_P (f
)
15667 && it
->glyph_row
->displays_text_p
15668 && face
->box
== FACE_NO_BOX
15669 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
15673 /* Set the glyph row flag indicating that the face of the last glyph
15674 in the text area has to be drawn to the end of the text area. */
15675 it
->glyph_row
->fill_line_p
= 1;
15677 /* If current character of IT is not ASCII, make sure we have the
15678 ASCII face. This will be automatically undone the next time
15679 get_next_display_element returns a multibyte character. Note
15680 that the character will always be single byte in unibyte text. */
15681 if (!SINGLE_BYTE_CHAR_P (it
->c
))
15683 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0);
15686 if (FRAME_WINDOW_P (f
))
15688 /* If the row is empty, add a space with the current face of IT,
15689 so that we know which face to draw. */
15690 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
15692 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
15693 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
15694 it
->glyph_row
->used
[TEXT_AREA
] = 1;
15699 /* Save some values that must not be changed. */
15700 int saved_x
= it
->current_x
;
15701 struct text_pos saved_pos
;
15702 Lisp_Object saved_object
;
15703 enum display_element_type saved_what
= it
->what
;
15704 int saved_face_id
= it
->face_id
;
15706 saved_object
= it
->object
;
15707 saved_pos
= it
->position
;
15709 it
->what
= IT_CHARACTER
;
15710 bzero (&it
->position
, sizeof it
->position
);
15711 it
->object
= make_number (0);
15714 it
->face_id
= face
->id
;
15716 PRODUCE_GLYPHS (it
);
15718 while (it
->current_x
<= it
->last_visible_x
)
15719 PRODUCE_GLYPHS (it
);
15721 /* Don't count these blanks really. It would let us insert a left
15722 truncation glyph below and make us set the cursor on them, maybe. */
15723 it
->current_x
= saved_x
;
15724 it
->object
= saved_object
;
15725 it
->position
= saved_pos
;
15726 it
->what
= saved_what
;
15727 it
->face_id
= saved_face_id
;
15732 /* Value is non-zero if text starting at CHARPOS in current_buffer is
15733 trailing whitespace. */
15736 trailing_whitespace_p (charpos
)
15739 int bytepos
= CHAR_TO_BYTE (charpos
);
15742 while (bytepos
< ZV_BYTE
15743 && (c
= FETCH_CHAR (bytepos
),
15744 c
== ' ' || c
== '\t'))
15747 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
15749 if (bytepos
!= PT_BYTE
)
15756 /* Highlight trailing whitespace, if any, in ROW. */
15759 highlight_trailing_whitespace (f
, row
)
15761 struct glyph_row
*row
;
15763 int used
= row
->used
[TEXT_AREA
];
15767 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
15768 struct glyph
*glyph
= start
+ used
- 1;
15770 /* Skip over glyphs inserted to display the cursor at the
15771 end of a line, for extending the face of the last glyph
15772 to the end of the line on terminals, and for truncation
15773 and continuation glyphs. */
15774 while (glyph
>= start
15775 && glyph
->type
== CHAR_GLYPH
15776 && INTEGERP (glyph
->object
))
15779 /* If last glyph is a space or stretch, and it's trailing
15780 whitespace, set the face of all trailing whitespace glyphs in
15781 IT->glyph_row to `trailing-whitespace'. */
15783 && BUFFERP (glyph
->object
)
15784 && (glyph
->type
== STRETCH_GLYPH
15785 || (glyph
->type
== CHAR_GLYPH
15786 && glyph
->u
.ch
== ' '))
15787 && trailing_whitespace_p (glyph
->charpos
))
15789 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0, 0);
15793 while (glyph
>= start
15794 && BUFFERP (glyph
->object
)
15795 && (glyph
->type
== STRETCH_GLYPH
15796 || (glyph
->type
== CHAR_GLYPH
15797 && glyph
->u
.ch
== ' ')))
15798 (glyph
--)->face_id
= face_id
;
15804 /* Value is non-zero if glyph row ROW in window W should be
15805 used to hold the cursor. */
15808 cursor_row_p (w
, row
)
15810 struct glyph_row
*row
;
15812 int cursor_row_p
= 1;
15814 if (PT
== MATRIX_ROW_END_CHARPOS (row
))
15816 /* If the row ends with a newline from a string, we don't want
15817 the cursor there, but we still want it at the start of the
15818 string if the string starts in this row.
15819 If the row is continued it doesn't end in a newline. */
15820 if (CHARPOS (row
->end
.string_pos
) >= 0)
15821 cursor_row_p
= (row
->continued_p
15822 || PT
>= MATRIX_ROW_START_CHARPOS (row
));
15823 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
15825 /* If the row ends in middle of a real character,
15826 and the line is continued, we want the cursor here.
15827 That's because MATRIX_ROW_END_CHARPOS would equal
15828 PT if PT is before the character. */
15829 if (!row
->ends_in_ellipsis_p
)
15830 cursor_row_p
= row
->continued_p
;
15832 /* If the row ends in an ellipsis, then
15833 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
15834 We want that position to be displayed after the ellipsis. */
15837 /* If the row ends at ZV, display the cursor at the end of that
15838 row instead of at the start of the row below. */
15839 else if (row
->ends_at_zv_p
)
15845 return cursor_row_p
;
15849 /* Construct the glyph row IT->glyph_row in the desired matrix of
15850 IT->w from text at the current position of IT. See dispextern.h
15851 for an overview of struct it. Value is non-zero if
15852 IT->glyph_row displays text, as opposed to a line displaying ZV
15859 struct glyph_row
*row
= it
->glyph_row
;
15860 Lisp_Object overlay_arrow_string
;
15862 /* We always start displaying at hpos zero even if hscrolled. */
15863 xassert (it
->hpos
== 0 && it
->current_x
== 0);
15865 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
15866 >= it
->w
->desired_matrix
->nrows
)
15868 it
->w
->nrows_scale_factor
++;
15869 fonts_changed_p
= 1;
15873 /* Is IT->w showing the region? */
15874 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
15876 /* Clear the result glyph row and enable it. */
15877 prepare_desired_row (row
);
15879 row
->y
= it
->current_y
;
15880 row
->start
= it
->start
;
15881 row
->continuation_lines_width
= it
->continuation_lines_width
;
15882 row
->displays_text_p
= 1;
15883 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
15884 it
->starts_in_middle_of_char_p
= 0;
15886 /* Arrange the overlays nicely for our purposes. Usually, we call
15887 display_line on only one line at a time, in which case this
15888 can't really hurt too much, or we call it on lines which appear
15889 one after another in the buffer, in which case all calls to
15890 recenter_overlay_lists but the first will be pretty cheap. */
15891 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
15893 /* Move over display elements that are not visible because we are
15894 hscrolled. This may stop at an x-position < IT->first_visible_x
15895 if the first glyph is partially visible or if we hit a line end. */
15896 if (it
->current_x
< it
->first_visible_x
)
15898 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
15899 MOVE_TO_POS
| MOVE_TO_X
);
15902 /* Get the initial row height. This is either the height of the
15903 text hscrolled, if there is any, or zero. */
15904 row
->ascent
= it
->max_ascent
;
15905 row
->height
= it
->max_ascent
+ it
->max_descent
;
15906 row
->phys_ascent
= it
->max_phys_ascent
;
15907 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
15908 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
15910 /* Loop generating characters. The loop is left with IT on the next
15911 character to display. */
15914 int n_glyphs_before
, hpos_before
, x_before
;
15916 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
15918 /* Retrieve the next thing to display. Value is zero if end of
15920 if (!get_next_display_element (it
))
15922 /* Maybe add a space at the end of this line that is used to
15923 display the cursor there under X. Set the charpos of the
15924 first glyph of blank lines not corresponding to any text
15926 #ifdef HAVE_WINDOW_SYSTEM
15927 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
15928 row
->exact_window_width_line_p
= 1;
15930 #endif /* HAVE_WINDOW_SYSTEM */
15931 if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
15932 || row
->used
[TEXT_AREA
] == 0)
15934 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
15935 row
->displays_text_p
= 0;
15937 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
15938 && (!MINI_WINDOW_P (it
->w
)
15939 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
15940 row
->indicate_empty_line_p
= 1;
15943 it
->continuation_lines_width
= 0;
15944 row
->ends_at_zv_p
= 1;
15948 /* Now, get the metrics of what we want to display. This also
15949 generates glyphs in `row' (which is IT->glyph_row). */
15950 n_glyphs_before
= row
->used
[TEXT_AREA
];
15953 /* Remember the line height so far in case the next element doesn't
15954 fit on the line. */
15955 if (!it
->truncate_lines_p
)
15957 ascent
= it
->max_ascent
;
15958 descent
= it
->max_descent
;
15959 phys_ascent
= it
->max_phys_ascent
;
15960 phys_descent
= it
->max_phys_descent
;
15963 PRODUCE_GLYPHS (it
);
15965 /* If this display element was in marginal areas, continue with
15967 if (it
->area
!= TEXT_AREA
)
15969 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
15970 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
15971 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
15972 row
->phys_height
= max (row
->phys_height
,
15973 it
->max_phys_ascent
+ it
->max_phys_descent
);
15974 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
15975 it
->max_extra_line_spacing
);
15976 set_iterator_to_next (it
, 1);
15980 /* Does the display element fit on the line? If we truncate
15981 lines, we should draw past the right edge of the window. If
15982 we don't truncate, we want to stop so that we can display the
15983 continuation glyph before the right margin. If lines are
15984 continued, there are two possible strategies for characters
15985 resulting in more than 1 glyph (e.g. tabs): Display as many
15986 glyphs as possible in this line and leave the rest for the
15987 continuation line, or display the whole element in the next
15988 line. Original redisplay did the former, so we do it also. */
15989 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
15990 hpos_before
= it
->hpos
;
15993 if (/* Not a newline. */
15995 /* Glyphs produced fit entirely in the line. */
15996 && it
->current_x
< it
->last_visible_x
)
15998 it
->hpos
+= nglyphs
;
15999 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
16000 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
16001 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
16002 row
->phys_height
= max (row
->phys_height
,
16003 it
->max_phys_ascent
+ it
->max_phys_descent
);
16004 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
16005 it
->max_extra_line_spacing
);
16006 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
16007 row
->x
= x
- it
->first_visible_x
;
16012 struct glyph
*glyph
;
16014 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
16016 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
16017 new_x
= x
+ glyph
->pixel_width
;
16019 if (/* Lines are continued. */
16020 !it
->truncate_lines_p
16021 && (/* Glyph doesn't fit on the line. */
16022 new_x
> it
->last_visible_x
16023 /* Or it fits exactly on a window system frame. */
16024 || (new_x
== it
->last_visible_x
16025 && FRAME_WINDOW_P (it
->f
))))
16027 /* End of a continued line. */
16030 || (new_x
== it
->last_visible_x
16031 && FRAME_WINDOW_P (it
->f
)))
16033 /* Current glyph is the only one on the line or
16034 fits exactly on the line. We must continue
16035 the line because we can't draw the cursor
16036 after the glyph. */
16037 row
->continued_p
= 1;
16038 it
->current_x
= new_x
;
16039 it
->continuation_lines_width
+= new_x
;
16041 if (i
== nglyphs
- 1)
16043 set_iterator_to_next (it
, 1);
16044 #ifdef HAVE_WINDOW_SYSTEM
16045 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
16047 if (!get_next_display_element (it
))
16049 row
->exact_window_width_line_p
= 1;
16050 it
->continuation_lines_width
= 0;
16051 row
->continued_p
= 0;
16052 row
->ends_at_zv_p
= 1;
16054 else if (ITERATOR_AT_END_OF_LINE_P (it
))
16056 row
->continued_p
= 0;
16057 row
->exact_window_width_line_p
= 1;
16060 #endif /* HAVE_WINDOW_SYSTEM */
16063 else if (CHAR_GLYPH_PADDING_P (*glyph
)
16064 && !FRAME_WINDOW_P (it
->f
))
16066 /* A padding glyph that doesn't fit on this line.
16067 This means the whole character doesn't fit
16069 row
->used
[TEXT_AREA
] = n_glyphs_before
;
16071 /* Fill the rest of the row with continuation
16072 glyphs like in 20.x. */
16073 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
16074 < row
->glyphs
[1 + TEXT_AREA
])
16075 produce_special_glyphs (it
, IT_CONTINUATION
);
16077 row
->continued_p
= 1;
16078 it
->current_x
= x_before
;
16079 it
->continuation_lines_width
+= x_before
;
16081 /* Restore the height to what it was before the
16082 element not fitting on the line. */
16083 it
->max_ascent
= ascent
;
16084 it
->max_descent
= descent
;
16085 it
->max_phys_ascent
= phys_ascent
;
16086 it
->max_phys_descent
= phys_descent
;
16088 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
16090 /* A TAB that extends past the right edge of the
16091 window. This produces a single glyph on
16092 window system frames. We leave the glyph in
16093 this row and let it fill the row, but don't
16094 consume the TAB. */
16095 it
->continuation_lines_width
+= it
->last_visible_x
;
16096 row
->ends_in_middle_of_char_p
= 1;
16097 row
->continued_p
= 1;
16098 glyph
->pixel_width
= it
->last_visible_x
- x
;
16099 it
->starts_in_middle_of_char_p
= 1;
16103 /* Something other than a TAB that draws past
16104 the right edge of the window. Restore
16105 positions to values before the element. */
16106 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
16108 /* Display continuation glyphs. */
16109 if (!FRAME_WINDOW_P (it
->f
))
16110 produce_special_glyphs (it
, IT_CONTINUATION
);
16111 row
->continued_p
= 1;
16113 it
->current_x
= x_before
;
16114 it
->continuation_lines_width
+= x
;
16115 extend_face_to_end_of_line (it
);
16117 if (nglyphs
> 1 && i
> 0)
16119 row
->ends_in_middle_of_char_p
= 1;
16120 it
->starts_in_middle_of_char_p
= 1;
16123 /* Restore the height to what it was before the
16124 element not fitting on the line. */
16125 it
->max_ascent
= ascent
;
16126 it
->max_descent
= descent
;
16127 it
->max_phys_ascent
= phys_ascent
;
16128 it
->max_phys_descent
= phys_descent
;
16133 else if (new_x
> it
->first_visible_x
)
16135 /* Increment number of glyphs actually displayed. */
16138 if (x
< it
->first_visible_x
)
16139 /* Glyph is partially visible, i.e. row starts at
16140 negative X position. */
16141 row
->x
= x
- it
->first_visible_x
;
16145 /* Glyph is completely off the left margin of the
16146 window. This should not happen because of the
16147 move_it_in_display_line at the start of this
16148 function, unless the text display area of the
16149 window is empty. */
16150 xassert (it
->first_visible_x
<= it
->last_visible_x
);
16154 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
16155 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
16156 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
16157 row
->phys_height
= max (row
->phys_height
,
16158 it
->max_phys_ascent
+ it
->max_phys_descent
);
16159 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
16160 it
->max_extra_line_spacing
);
16162 /* End of this display line if row is continued. */
16163 if (row
->continued_p
|| row
->ends_at_zv_p
)
16168 /* Is this a line end? If yes, we're also done, after making
16169 sure that a non-default face is extended up to the right
16170 margin of the window. */
16171 if (ITERATOR_AT_END_OF_LINE_P (it
))
16173 int used_before
= row
->used
[TEXT_AREA
];
16175 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
16177 #ifdef HAVE_WINDOW_SYSTEM
16178 /* Add a space at the end of the line that is used to
16179 display the cursor there. */
16180 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
16181 append_space_for_newline (it
, 0);
16182 #endif /* HAVE_WINDOW_SYSTEM */
16184 /* Extend the face to the end of the line. */
16185 extend_face_to_end_of_line (it
);
16187 /* Make sure we have the position. */
16188 if (used_before
== 0)
16189 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
16191 /* Consume the line end. This skips over invisible lines. */
16192 set_iterator_to_next (it
, 1);
16193 it
->continuation_lines_width
= 0;
16197 /* Proceed with next display element. Note that this skips
16198 over lines invisible because of selective display. */
16199 set_iterator_to_next (it
, 1);
16201 /* If we truncate lines, we are done when the last displayed
16202 glyphs reach past the right margin of the window. */
16203 if (it
->truncate_lines_p
16204 && (FRAME_WINDOW_P (it
->f
)
16205 ? (it
->current_x
>= it
->last_visible_x
)
16206 : (it
->current_x
> it
->last_visible_x
)))
16208 /* Maybe add truncation glyphs. */
16209 if (!FRAME_WINDOW_P (it
->f
))
16213 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
16214 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
16217 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
16219 row
->used
[TEXT_AREA
] = i
;
16220 produce_special_glyphs (it
, IT_TRUNCATION
);
16223 #ifdef HAVE_WINDOW_SYSTEM
16226 /* Don't truncate if we can overflow newline into fringe. */
16227 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
16229 if (!get_next_display_element (it
))
16231 it
->continuation_lines_width
= 0;
16232 row
->ends_at_zv_p
= 1;
16233 row
->exact_window_width_line_p
= 1;
16236 if (ITERATOR_AT_END_OF_LINE_P (it
))
16238 row
->exact_window_width_line_p
= 1;
16239 goto at_end_of_line
;
16243 #endif /* HAVE_WINDOW_SYSTEM */
16245 row
->truncated_on_right_p
= 1;
16246 it
->continuation_lines_width
= 0;
16247 reseat_at_next_visible_line_start (it
, 0);
16248 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
16249 it
->hpos
= hpos_before
;
16250 it
->current_x
= x_before
;
16255 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16256 at the left window margin. */
16257 if (it
->first_visible_x
16258 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
16260 if (!FRAME_WINDOW_P (it
->f
))
16261 insert_left_trunc_glyphs (it
);
16262 row
->truncated_on_left_p
= 1;
16265 /* If the start of this line is the overlay arrow-position, then
16266 mark this glyph row as the one containing the overlay arrow.
16267 This is clearly a mess with variable size fonts. It would be
16268 better to let it be displayed like cursors under X. */
16269 if ((row
->displays_text_p
|| !overlay_arrow_seen
)
16270 && (overlay_arrow_string
= overlay_arrow_at_row (it
, row
),
16271 !NILP (overlay_arrow_string
)))
16273 /* Overlay arrow in window redisplay is a fringe bitmap. */
16274 if (STRINGP (overlay_arrow_string
))
16276 struct glyph_row
*arrow_row
16277 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
16278 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
16279 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
16280 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
16281 struct glyph
*p2
, *end
;
16283 /* Copy the arrow glyphs. */
16284 while (glyph
< arrow_end
)
16287 /* Throw away padding glyphs. */
16289 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
16290 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
16296 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
16301 xassert (INTEGERP (overlay_arrow_string
));
16302 row
->overlay_arrow_bitmap
= XINT (overlay_arrow_string
);
16304 overlay_arrow_seen
= 1;
16307 /* Compute pixel dimensions of this line. */
16308 compute_line_metrics (it
);
16310 /* Remember the position at which this line ends. */
16311 row
->end
= it
->current
;
16313 /* Record whether this row ends inside an ellipsis. */
16314 row
->ends_in_ellipsis_p
16315 = (it
->method
== GET_FROM_DISPLAY_VECTOR
16316 && it
->ellipsis_p
);
16318 /* Save fringe bitmaps in this row. */
16319 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
16320 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
16321 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
16322 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
16324 it
->left_user_fringe_bitmap
= 0;
16325 it
->left_user_fringe_face_id
= 0;
16326 it
->right_user_fringe_bitmap
= 0;
16327 it
->right_user_fringe_face_id
= 0;
16329 /* Maybe set the cursor. */
16330 if (it
->w
->cursor
.vpos
< 0
16331 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
16332 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
16333 && cursor_row_p (it
->w
, row
))
16334 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
16336 /* Highlight trailing whitespace. */
16337 if (!NILP (Vshow_trailing_whitespace
))
16338 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
16340 /* Prepare for the next line. This line starts horizontally at (X
16341 HPOS) = (0 0). Vertical positions are incremented. As a
16342 convenience for the caller, IT->glyph_row is set to the next
16344 it
->current_x
= it
->hpos
= 0;
16345 it
->current_y
+= row
->height
;
16348 it
->start
= it
->current
;
16349 return row
->displays_text_p
;
16354 /***********************************************************************
16356 ***********************************************************************/
16358 /* Redisplay the menu bar in the frame for window W.
16360 The menu bar of X frames that don't have X toolkit support is
16361 displayed in a special window W->frame->menu_bar_window.
16363 The menu bar of terminal frames is treated specially as far as
16364 glyph matrices are concerned. Menu bar lines are not part of
16365 windows, so the update is done directly on the frame matrix rows
16366 for the menu bar. */
16369 display_menu_bar (w
)
16372 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
16377 /* Don't do all this for graphical frames. */
16379 if (!NILP (Vwindow_system
))
16382 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
16387 if (FRAME_MAC_P (f
))
16391 #ifdef USE_X_TOOLKIT
16392 xassert (!FRAME_WINDOW_P (f
));
16393 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
16394 it
.first_visible_x
= 0;
16395 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
16396 #else /* not USE_X_TOOLKIT */
16397 if (FRAME_WINDOW_P (f
))
16399 /* Menu bar lines are displayed in the desired matrix of the
16400 dummy window menu_bar_window. */
16401 struct window
*menu_w
;
16402 xassert (WINDOWP (f
->menu_bar_window
));
16403 menu_w
= XWINDOW (f
->menu_bar_window
);
16404 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
16406 it
.first_visible_x
= 0;
16407 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
16411 /* This is a TTY frame, i.e. character hpos/vpos are used as
16413 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
16415 it
.first_visible_x
= 0;
16416 it
.last_visible_x
= FRAME_COLS (f
);
16418 #endif /* not USE_X_TOOLKIT */
16420 if (! mode_line_inverse_video
)
16421 /* Force the menu-bar to be displayed in the default face. */
16422 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
16424 /* Clear all rows of the menu bar. */
16425 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
16427 struct glyph_row
*row
= it
.glyph_row
+ i
;
16428 clear_glyph_row (row
);
16429 row
->enabled_p
= 1;
16430 row
->full_width_p
= 1;
16433 /* Display all items of the menu bar. */
16434 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
16435 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
16437 Lisp_Object string
;
16439 /* Stop at nil string. */
16440 string
= AREF (items
, i
+ 1);
16444 /* Remember where item was displayed. */
16445 AREF (items
, i
+ 3) = make_number (it
.hpos
);
16447 /* Display the item, pad with one space. */
16448 if (it
.current_x
< it
.last_visible_x
)
16449 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
16450 SCHARS (string
) + 1, 0, 0, -1);
16453 /* Fill out the line with spaces. */
16454 if (it
.current_x
< it
.last_visible_x
)
16455 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
16457 /* Compute the total height of the lines. */
16458 compute_line_metrics (&it
);
16463 /***********************************************************************
16465 ***********************************************************************/
16467 /* Redisplay mode lines in the window tree whose root is WINDOW. If
16468 FORCE is non-zero, redisplay mode lines unconditionally.
16469 Otherwise, redisplay only mode lines that are garbaged. Value is
16470 the number of windows whose mode lines were redisplayed. */
16473 redisplay_mode_lines (window
, force
)
16474 Lisp_Object window
;
16479 while (!NILP (window
))
16481 struct window
*w
= XWINDOW (window
);
16483 if (WINDOWP (w
->hchild
))
16484 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
16485 else if (WINDOWP (w
->vchild
))
16486 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
16488 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
16489 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
16491 struct text_pos lpoint
;
16492 struct buffer
*old
= current_buffer
;
16494 /* Set the window's buffer for the mode line display. */
16495 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
16496 set_buffer_internal_1 (XBUFFER (w
->buffer
));
16498 /* Point refers normally to the selected window. For any
16499 other window, set up appropriate value. */
16500 if (!EQ (window
, selected_window
))
16502 struct text_pos pt
;
16504 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
16505 if (CHARPOS (pt
) < BEGV
)
16506 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
16507 else if (CHARPOS (pt
) > (ZV
- 1))
16508 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
16510 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
16513 /* Display mode lines. */
16514 clear_glyph_matrix (w
->desired_matrix
);
16515 if (display_mode_lines (w
))
16518 w
->must_be_updated_p
= 1;
16521 /* Restore old settings. */
16522 set_buffer_internal_1 (old
);
16523 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
16533 /* Display the mode and/or top line of window W. Value is the number
16534 of mode lines displayed. */
16537 display_mode_lines (w
)
16540 Lisp_Object old_selected_window
, old_selected_frame
;
16543 old_selected_frame
= selected_frame
;
16544 selected_frame
= w
->frame
;
16545 old_selected_window
= selected_window
;
16546 XSETWINDOW (selected_window
, w
);
16548 /* These will be set while the mode line specs are processed. */
16549 line_number_displayed
= 0;
16550 w
->column_number_displayed
= Qnil
;
16552 if (WINDOW_WANTS_MODELINE_P (w
))
16554 struct window
*sel_w
= XWINDOW (old_selected_window
);
16556 /* Select mode line face based on the real selected window. */
16557 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
16558 current_buffer
->mode_line_format
);
16562 if (WINDOW_WANTS_HEADER_LINE_P (w
))
16564 display_mode_line (w
, HEADER_LINE_FACE_ID
,
16565 current_buffer
->header_line_format
);
16569 selected_frame
= old_selected_frame
;
16570 selected_window
= old_selected_window
;
16575 /* Display mode or top line of window W. FACE_ID specifies which line
16576 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
16577 FORMAT is the mode line format to display. Value is the pixel
16578 height of the mode line displayed. */
16581 display_mode_line (w
, face_id
, format
)
16583 enum face_id face_id
;
16584 Lisp_Object format
;
16588 int count
= SPECPDL_INDEX ();
16590 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
16591 prepare_desired_row (it
.glyph_row
);
16593 it
.glyph_row
->mode_line_p
= 1;
16595 if (! mode_line_inverse_video
)
16596 /* Force the mode-line to be displayed in the default face. */
16597 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
16599 record_unwind_protect (unwind_format_mode_line
,
16600 format_mode_line_unwind_data (NULL
, 0));
16602 mode_line_target
= MODE_LINE_DISPLAY
;
16604 /* Temporarily make frame's keyboard the current kboard so that
16605 kboard-local variables in the mode_line_format will get the right
16607 push_frame_kboard (it
.f
);
16608 record_unwind_save_match_data ();
16609 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
16610 pop_frame_kboard ();
16612 unbind_to (count
, Qnil
);
16614 /* Fill up with spaces. */
16615 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
16617 compute_line_metrics (&it
);
16618 it
.glyph_row
->full_width_p
= 1;
16619 it
.glyph_row
->continued_p
= 0;
16620 it
.glyph_row
->truncated_on_left_p
= 0;
16621 it
.glyph_row
->truncated_on_right_p
= 0;
16623 /* Make a 3D mode-line have a shadow at its right end. */
16624 face
= FACE_FROM_ID (it
.f
, face_id
);
16625 extend_face_to_end_of_line (&it
);
16626 if (face
->box
!= FACE_NO_BOX
)
16628 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
16629 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
16630 last
->right_box_line_p
= 1;
16633 return it
.glyph_row
->height
;
16636 /* Move element ELT in LIST to the front of LIST.
16637 Return the updated list. */
16640 move_elt_to_front (elt
, list
)
16641 Lisp_Object elt
, list
;
16643 register Lisp_Object tail
, prev
;
16644 register Lisp_Object tem
;
16648 while (CONSP (tail
))
16654 /* Splice out the link TAIL. */
16656 list
= XCDR (tail
);
16658 Fsetcdr (prev
, XCDR (tail
));
16660 /* Now make it the first. */
16661 Fsetcdr (tail
, list
);
16666 tail
= XCDR (tail
);
16670 /* Not found--return unchanged LIST. */
16674 /* Contribute ELT to the mode line for window IT->w. How it
16675 translates into text depends on its data type.
16677 IT describes the display environment in which we display, as usual.
16679 DEPTH is the depth in recursion. It is used to prevent
16680 infinite recursion here.
16682 FIELD_WIDTH is the number of characters the display of ELT should
16683 occupy in the mode line, and PRECISION is the maximum number of
16684 characters to display from ELT's representation. See
16685 display_string for details.
16687 Returns the hpos of the end of the text generated by ELT.
16689 PROPS is a property list to add to any string we encounter.
16691 If RISKY is nonzero, remove (disregard) any properties in any string
16692 we encounter, and ignore :eval and :propertize.
16694 The global variable `mode_line_target' determines whether the
16695 output is passed to `store_mode_line_noprop',
16696 `store_mode_line_string', or `display_string'. */
16699 display_mode_element (it
, depth
, field_width
, precision
, elt
, props
, risky
)
16702 int field_width
, precision
;
16703 Lisp_Object elt
, props
;
16706 int n
= 0, field
, prec
;
16711 elt
= build_string ("*too-deep*");
16715 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
16719 /* A string: output it and check for %-constructs within it. */
16723 if (SCHARS (elt
) > 0
16724 && (!NILP (props
) || risky
))
16726 Lisp_Object oprops
, aelt
;
16727 oprops
= Ftext_properties_at (make_number (0), elt
);
16729 /* If the starting string's properties are not what
16730 we want, translate the string. Also, if the string
16731 is risky, do that anyway. */
16733 if (NILP (Fequal (props
, oprops
)) || risky
)
16735 /* If the starting string has properties,
16736 merge the specified ones onto the existing ones. */
16737 if (! NILP (oprops
) && !risky
)
16741 oprops
= Fcopy_sequence (oprops
);
16743 while (CONSP (tem
))
16745 oprops
= Fplist_put (oprops
, XCAR (tem
),
16746 XCAR (XCDR (tem
)));
16747 tem
= XCDR (XCDR (tem
));
16752 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
16753 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
16755 /* AELT is what we want. Move it to the front
16756 without consing. */
16758 mode_line_proptrans_alist
16759 = move_elt_to_front (aelt
, mode_line_proptrans_alist
);
16765 /* If AELT has the wrong props, it is useless.
16766 so get rid of it. */
16768 mode_line_proptrans_alist
16769 = Fdelq (aelt
, mode_line_proptrans_alist
);
16771 elt
= Fcopy_sequence (elt
);
16772 Fset_text_properties (make_number (0), Flength (elt
),
16774 /* Add this item to mode_line_proptrans_alist. */
16775 mode_line_proptrans_alist
16776 = Fcons (Fcons (elt
, props
),
16777 mode_line_proptrans_alist
);
16778 /* Truncate mode_line_proptrans_alist
16779 to at most 50 elements. */
16780 tem
= Fnthcdr (make_number (50),
16781 mode_line_proptrans_alist
);
16783 XSETCDR (tem
, Qnil
);
16792 prec
= precision
- n
;
16793 switch (mode_line_target
)
16795 case MODE_LINE_NOPROP
:
16796 case MODE_LINE_TITLE
:
16797 n
+= store_mode_line_noprop (SDATA (elt
), -1, prec
);
16799 case MODE_LINE_STRING
:
16800 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
16802 case MODE_LINE_DISPLAY
:
16803 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
16804 0, prec
, 0, STRING_MULTIBYTE (elt
));
16811 /* Handle the non-literal case. */
16813 while ((precision
<= 0 || n
< precision
)
16814 && SREF (elt
, offset
) != 0
16815 && (mode_line_target
!= MODE_LINE_DISPLAY
16816 || it
->current_x
< it
->last_visible_x
))
16818 int last_offset
= offset
;
16820 /* Advance to end of string or next format specifier. */
16821 while ((c
= SREF (elt
, offset
++)) != '\0' && c
!= '%')
16824 if (offset
- 1 != last_offset
)
16826 int nchars
, nbytes
;
16828 /* Output to end of string or up to '%'. Field width
16829 is length of string. Don't output more than
16830 PRECISION allows us. */
16833 prec
= c_string_width (SDATA (elt
) + last_offset
,
16834 offset
- last_offset
, precision
- n
,
16837 switch (mode_line_target
)
16839 case MODE_LINE_NOPROP
:
16840 case MODE_LINE_TITLE
:
16841 n
+= store_mode_line_noprop (SDATA (elt
) + last_offset
, 0, prec
);
16843 case MODE_LINE_STRING
:
16845 int bytepos
= last_offset
;
16846 int charpos
= string_byte_to_char (elt
, bytepos
);
16847 int endpos
= (precision
<= 0
16848 ? string_byte_to_char (elt
, offset
)
16849 : charpos
+ nchars
);
16851 n
+= store_mode_line_string (NULL
,
16852 Fsubstring (elt
, make_number (charpos
),
16853 make_number (endpos
)),
16857 case MODE_LINE_DISPLAY
:
16859 int bytepos
= last_offset
;
16860 int charpos
= string_byte_to_char (elt
, bytepos
);
16862 if (precision
<= 0)
16863 nchars
= string_byte_to_char (elt
, offset
) - charpos
;
16864 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
16866 STRING_MULTIBYTE (elt
));
16871 else /* c == '%' */
16873 int percent_position
= offset
;
16875 /* Get the specified minimum width. Zero means
16878 while ((c
= SREF (elt
, offset
++)) >= '0' && c
<= '9')
16879 field
= field
* 10 + c
- '0';
16881 /* Don't pad beyond the total padding allowed. */
16882 if (field_width
- n
> 0 && field
> field_width
- n
)
16883 field
= field_width
- n
;
16885 /* Note that either PRECISION <= 0 or N < PRECISION. */
16886 prec
= precision
- n
;
16889 n
+= display_mode_element (it
, depth
, field
, prec
,
16890 Vglobal_mode_string
, props
,
16895 int bytepos
, charpos
;
16896 unsigned char *spec
;
16898 bytepos
= percent_position
;
16899 charpos
= (STRING_MULTIBYTE (elt
)
16900 ? string_byte_to_char (elt
, bytepos
)
16904 = decode_mode_spec (it
->w
, c
, field
, prec
, &multibyte
);
16906 switch (mode_line_target
)
16908 case MODE_LINE_NOPROP
:
16909 case MODE_LINE_TITLE
:
16910 n
+= store_mode_line_noprop (spec
, field
, prec
);
16912 case MODE_LINE_STRING
:
16914 int len
= strlen (spec
);
16915 Lisp_Object tem
= make_string (spec
, len
);
16916 props
= Ftext_properties_at (make_number (charpos
), elt
);
16917 /* Should only keep face property in props */
16918 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
16921 case MODE_LINE_DISPLAY
:
16923 int nglyphs_before
, nwritten
;
16925 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
16926 nwritten
= display_string (spec
, Qnil
, elt
,
16931 /* Assign to the glyphs written above the
16932 string where the `%x' came from, position
16936 struct glyph
*glyph
16937 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
16941 for (i
= 0; i
< nwritten
; ++i
)
16943 glyph
[i
].object
= elt
;
16944 glyph
[i
].charpos
= charpos
;
16961 /* A symbol: process the value of the symbol recursively
16962 as if it appeared here directly. Avoid error if symbol void.
16963 Special case: if value of symbol is a string, output the string
16966 register Lisp_Object tem
;
16968 /* If the variable is not marked as risky to set
16969 then its contents are risky to use. */
16970 if (NILP (Fget (elt
, Qrisky_local_variable
)))
16973 tem
= Fboundp (elt
);
16976 tem
= Fsymbol_value (elt
);
16977 /* If value is a string, output that string literally:
16978 don't check for % within it. */
16982 if (!EQ (tem
, elt
))
16984 /* Give up right away for nil or t. */
16994 register Lisp_Object car
, tem
;
16996 /* A cons cell: five distinct cases.
16997 If first element is :eval or :propertize, do something special.
16998 If first element is a string or a cons, process all the elements
16999 and effectively concatenate them.
17000 If first element is a negative number, truncate displaying cdr to
17001 at most that many characters. If positive, pad (with spaces)
17002 to at least that many characters.
17003 If first element is a symbol, process the cadr or caddr recursively
17004 according to whether the symbol's value is non-nil or nil. */
17006 if (EQ (car
, QCeval
))
17008 /* An element of the form (:eval FORM) means evaluate FORM
17009 and use the result as mode line elements. */
17014 if (CONSP (XCDR (elt
)))
17017 spec
= safe_eval (XCAR (XCDR (elt
)));
17018 n
+= display_mode_element (it
, depth
, field_width
- n
,
17019 precision
- n
, spec
, props
,
17023 else if (EQ (car
, QCpropertize
))
17025 /* An element of the form (:propertize ELT PROPS...)
17026 means display ELT but applying properties PROPS. */
17031 if (CONSP (XCDR (elt
)))
17032 n
+= display_mode_element (it
, depth
, field_width
- n
,
17033 precision
- n
, XCAR (XCDR (elt
)),
17034 XCDR (XCDR (elt
)), risky
);
17036 else if (SYMBOLP (car
))
17038 tem
= Fboundp (car
);
17042 /* elt is now the cdr, and we know it is a cons cell.
17043 Use its car if CAR has a non-nil value. */
17046 tem
= Fsymbol_value (car
);
17053 /* Symbol's value is nil (or symbol is unbound)
17054 Get the cddr of the original list
17055 and if possible find the caddr and use that. */
17059 else if (!CONSP (elt
))
17064 else if (INTEGERP (car
))
17066 register int lim
= XINT (car
);
17070 /* Negative int means reduce maximum width. */
17071 if (precision
<= 0)
17074 precision
= min (precision
, -lim
);
17078 /* Padding specified. Don't let it be more than
17079 current maximum. */
17081 lim
= min (precision
, lim
);
17083 /* If that's more padding than already wanted, queue it.
17084 But don't reduce padding already specified even if
17085 that is beyond the current truncation point. */
17086 field_width
= max (lim
, field_width
);
17090 else if (STRINGP (car
) || CONSP (car
))
17092 register int limit
= 50;
17093 /* Limit is to protect against circular lists. */
17096 && (precision
<= 0 || n
< precision
))
17098 n
+= display_mode_element (it
, depth
,
17099 /* Do padding only after the last
17100 element in the list. */
17101 (! CONSP (XCDR (elt
))
17104 precision
- n
, XCAR (elt
),
17114 elt
= build_string ("*invalid*");
17118 /* Pad to FIELD_WIDTH. */
17119 if (field_width
> 0 && n
< field_width
)
17121 switch (mode_line_target
)
17123 case MODE_LINE_NOPROP
:
17124 case MODE_LINE_TITLE
:
17125 n
+= store_mode_line_noprop ("", field_width
- n
, 0);
17127 case MODE_LINE_STRING
:
17128 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
17130 case MODE_LINE_DISPLAY
:
17131 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
17140 /* Store a mode-line string element in mode_line_string_list.
17142 If STRING is non-null, display that C string. Otherwise, the Lisp
17143 string LISP_STRING is displayed.
17145 FIELD_WIDTH is the minimum number of output glyphs to produce.
17146 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17147 with spaces. FIELD_WIDTH <= 0 means don't pad.
17149 PRECISION is the maximum number of characters to output from
17150 STRING. PRECISION <= 0 means don't truncate the string.
17152 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17153 properties to the string.
17155 PROPS are the properties to add to the string.
17156 The mode_line_string_face face property is always added to the string.
17160 store_mode_line_string (string
, lisp_string
, copy_string
, field_width
, precision
, props
)
17162 Lisp_Object lisp_string
;
17171 if (string
!= NULL
)
17173 len
= strlen (string
);
17174 if (precision
> 0 && len
> precision
)
17176 lisp_string
= make_string (string
, len
);
17178 props
= mode_line_string_face_prop
;
17179 else if (!NILP (mode_line_string_face
))
17181 Lisp_Object face
= Fplist_get (props
, Qface
);
17182 props
= Fcopy_sequence (props
);
17184 face
= mode_line_string_face
;
17186 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
17187 props
= Fplist_put (props
, Qface
, face
);
17189 Fadd_text_properties (make_number (0), make_number (len
),
17190 props
, lisp_string
);
17194 len
= XFASTINT (Flength (lisp_string
));
17195 if (precision
> 0 && len
> precision
)
17198 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
17201 if (!NILP (mode_line_string_face
))
17205 props
= Ftext_properties_at (make_number (0), lisp_string
);
17206 face
= Fplist_get (props
, Qface
);
17208 face
= mode_line_string_face
;
17210 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
17211 props
= Fcons (Qface
, Fcons (face
, Qnil
));
17213 lisp_string
= Fcopy_sequence (lisp_string
);
17216 Fadd_text_properties (make_number (0), make_number (len
),
17217 props
, lisp_string
);
17222 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
17226 if (field_width
> len
)
17228 field_width
-= len
;
17229 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
17231 Fadd_text_properties (make_number (0), make_number (field_width
),
17232 props
, lisp_string
);
17233 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
17241 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
17243 doc
: /* Format a string out of a mode line format specification.
17244 First arg FORMAT specifies the mode line format (see `mode-line-format'
17245 for details) to use.
17247 Optional second arg FACE specifies the face property to put
17248 on all characters for which no face is specified.
17249 t means whatever face the window's mode line currently uses
17250 \(either `mode-line' or `mode-line-inactive', depending).
17251 nil means the default is no face property.
17252 If FACE is an integer, the value string has no text properties.
17254 Optional third and fourth args WINDOW and BUFFER specify the window
17255 and buffer to use as the context for the formatting (defaults
17256 are the selected window and the window's buffer). */)
17257 (format
, face
, window
, buffer
)
17258 Lisp_Object format
, face
, window
, buffer
;
17263 struct buffer
*old_buffer
= NULL
;
17265 int no_props
= INTEGERP (face
);
17266 int count
= SPECPDL_INDEX ();
17268 int string_start
= 0;
17271 window
= selected_window
;
17272 CHECK_WINDOW (window
);
17273 w
= XWINDOW (window
);
17276 buffer
= w
->buffer
;
17277 CHECK_BUFFER (buffer
);
17280 return build_string ("");
17288 face
= (EQ (window
, selected_window
) ? Qmode_line
: Qmode_line_inactive
);
17289 face_id
= lookup_named_face (XFRAME (WINDOW_FRAME (w
)), face
, 0, 0);
17293 face_id
= DEFAULT_FACE_ID
;
17295 if (XBUFFER (buffer
) != current_buffer
)
17296 old_buffer
= current_buffer
;
17298 /* Save things including mode_line_proptrans_alist,
17299 and set that to nil so that we don't alter the outer value. */
17300 record_unwind_protect (unwind_format_mode_line
,
17301 format_mode_line_unwind_data (old_buffer
, 1));
17302 mode_line_proptrans_alist
= Qnil
;
17305 set_buffer_internal_1 (XBUFFER (buffer
));
17307 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
17311 mode_line_target
= MODE_LINE_NOPROP
;
17312 mode_line_string_face_prop
= Qnil
;
17313 mode_line_string_list
= Qnil
;
17314 string_start
= MODE_LINE_NOPROP_LEN (0);
17318 mode_line_target
= MODE_LINE_STRING
;
17319 mode_line_string_list
= Qnil
;
17320 mode_line_string_face
= face
;
17321 mode_line_string_face_prop
17322 = (NILP (face
) ? Qnil
: Fcons (Qface
, Fcons (face
, Qnil
)));
17325 push_frame_kboard (it
.f
);
17326 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
17327 pop_frame_kboard ();
17331 len
= MODE_LINE_NOPROP_LEN (string_start
);
17332 str
= make_string (mode_line_noprop_buf
+ string_start
, len
);
17336 mode_line_string_list
= Fnreverse (mode_line_string_list
);
17337 str
= Fmapconcat (intern ("identity"), mode_line_string_list
,
17338 make_string ("", 0));
17341 unbind_to (count
, Qnil
);
17345 /* Write a null-terminated, right justified decimal representation of
17346 the positive integer D to BUF using a minimal field width WIDTH. */
17349 pint2str (buf
, width
, d
)
17350 register char *buf
;
17351 register int width
;
17354 register char *p
= buf
;
17362 *p
++ = d
% 10 + '0';
17367 for (width
-= (int) (p
- buf
); width
> 0; --width
)
17378 /* Write a null-terminated, right justified decimal and "human
17379 readable" representation of the nonnegative integer D to BUF using
17380 a minimal field width WIDTH. D should be smaller than 999.5e24. */
17382 static const char power_letter
[] =
17396 pint2hrstr (buf
, width
, d
)
17401 /* We aim to represent the nonnegative integer D as
17402 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
17405 /* -1 means: do not use TENTHS. */
17409 /* Length of QUOTIENT.TENTHS as a string. */
17415 if (1000 <= quotient
)
17417 /* Scale to the appropriate EXPONENT. */
17420 remainder
= quotient
% 1000;
17424 while (1000 <= quotient
);
17426 /* Round to nearest and decide whether to use TENTHS or not. */
17429 tenths
= remainder
/ 100;
17430 if (50 <= remainder
% 100)
17437 if (quotient
== 10)
17445 if (500 <= remainder
)
17447 if (quotient
< 999)
17458 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
17459 if (tenths
== -1 && quotient
<= 99)
17466 p
= psuffix
= buf
+ max (width
, length
);
17468 /* Print EXPONENT. */
17470 *psuffix
++ = power_letter
[exponent
];
17473 /* Print TENTHS. */
17476 *--p
= '0' + tenths
;
17480 /* Print QUOTIENT. */
17483 int digit
= quotient
% 10;
17484 *--p
= '0' + digit
;
17486 while ((quotient
/= 10) != 0);
17488 /* Print leading spaces. */
17493 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
17494 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
17495 type of CODING_SYSTEM. Return updated pointer into BUF. */
17497 static unsigned char invalid_eol_type
[] = "(*invalid*)";
17500 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
17501 Lisp_Object coding_system
;
17502 register char *buf
;
17506 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
17507 const unsigned char *eol_str
;
17509 /* The EOL conversion we are using. */
17510 Lisp_Object eoltype
;
17512 val
= Fget (coding_system
, Qcoding_system
);
17515 if (!VECTORP (val
)) /* Not yet decided. */
17520 eoltype
= eol_mnemonic_undecided
;
17521 /* Don't mention EOL conversion if it isn't decided. */
17525 Lisp_Object eolvalue
;
17527 eolvalue
= Fget (coding_system
, Qeol_type
);
17530 *buf
++ = XFASTINT (AREF (val
, 1));
17534 /* The EOL conversion that is normal on this system. */
17536 if (NILP (eolvalue
)) /* Not yet decided. */
17537 eoltype
= eol_mnemonic_undecided
;
17538 else if (VECTORP (eolvalue
)) /* Not yet decided. */
17539 eoltype
= eol_mnemonic_undecided
;
17540 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
17541 eoltype
= (XFASTINT (eolvalue
) == 0
17542 ? eol_mnemonic_unix
17543 : (XFASTINT (eolvalue
) == 1
17544 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
17550 /* Mention the EOL conversion if it is not the usual one. */
17551 if (STRINGP (eoltype
))
17553 eol_str
= SDATA (eoltype
);
17554 eol_str_len
= SBYTES (eoltype
);
17556 else if (INTEGERP (eoltype
)
17557 && CHAR_VALID_P (XINT (eoltype
), 0))
17559 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
17560 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
17565 eol_str
= invalid_eol_type
;
17566 eol_str_len
= sizeof (invalid_eol_type
) - 1;
17568 bcopy (eol_str
, buf
, eol_str_len
);
17569 buf
+= eol_str_len
;
17575 /* Return a string for the output of a mode line %-spec for window W,
17576 generated by character C. PRECISION >= 0 means don't return a
17577 string longer than that value. FIELD_WIDTH > 0 means pad the
17578 string returned with spaces to that value. Return 1 in *MULTIBYTE
17579 if the result is multibyte text.
17581 Note we operate on the current buffer for most purposes,
17582 the exception being w->base_line_pos. */
17584 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
17587 decode_mode_spec (w
, c
, field_width
, precision
, multibyte
)
17590 int field_width
, precision
;
17594 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
17595 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
17596 struct buffer
*b
= current_buffer
;
17604 if (!NILP (b
->read_only
))
17606 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
17611 /* This differs from %* only for a modified read-only buffer. */
17612 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
17614 if (!NILP (b
->read_only
))
17619 /* This differs from %* in ignoring read-only-ness. */
17620 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
17632 if (command_loop_level
> 5)
17634 p
= decode_mode_spec_buf
;
17635 for (i
= 0; i
< command_loop_level
; i
++)
17638 return decode_mode_spec_buf
;
17646 if (command_loop_level
> 5)
17648 p
= decode_mode_spec_buf
;
17649 for (i
= 0; i
< command_loop_level
; i
++)
17652 return decode_mode_spec_buf
;
17659 /* Let lots_of_dashes be a string of infinite length. */
17660 if (mode_line_target
== MODE_LINE_NOPROP
||
17661 mode_line_target
== MODE_LINE_STRING
)
17663 if (field_width
<= 0
17664 || field_width
> sizeof (lots_of_dashes
))
17666 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
17667 decode_mode_spec_buf
[i
] = '-';
17668 decode_mode_spec_buf
[i
] = '\0';
17669 return decode_mode_spec_buf
;
17672 return lots_of_dashes
;
17681 int col
= (int) current_column (); /* iftc */
17682 w
->column_number_displayed
= make_number (col
);
17683 pint2str (decode_mode_spec_buf
, field_width
, col
);
17684 return decode_mode_spec_buf
;
17688 #ifndef SYSTEM_MALLOC
17690 if (NILP (Vmemory_full
))
17693 return "!MEM FULL! ";
17700 /* %F displays the frame name. */
17701 if (!NILP (f
->title
))
17702 return (char *) SDATA (f
->title
);
17703 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
17704 return (char *) SDATA (f
->name
);
17713 int size
= ZV
- BEGV
;
17714 pint2str (decode_mode_spec_buf
, field_width
, size
);
17715 return decode_mode_spec_buf
;
17720 int size
= ZV
- BEGV
;
17721 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
17722 return decode_mode_spec_buf
;
17727 int startpos
= XMARKER (w
->start
)->charpos
;
17728 int startpos_byte
= marker_byte_position (w
->start
);
17729 int line
, linepos
, linepos_byte
, topline
;
17731 int height
= WINDOW_TOTAL_LINES (w
);
17733 /* If we decided that this buffer isn't suitable for line numbers,
17734 don't forget that too fast. */
17735 if (EQ (w
->base_line_pos
, w
->buffer
))
17737 /* But do forget it, if the window shows a different buffer now. */
17738 else if (BUFFERP (w
->base_line_pos
))
17739 w
->base_line_pos
= Qnil
;
17741 /* If the buffer is very big, don't waste time. */
17742 if (INTEGERP (Vline_number_display_limit
)
17743 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
17745 w
->base_line_pos
= Qnil
;
17746 w
->base_line_number
= Qnil
;
17750 if (!NILP (w
->base_line_number
)
17751 && !NILP (w
->base_line_pos
)
17752 && XFASTINT (w
->base_line_pos
) <= startpos
)
17754 line
= XFASTINT (w
->base_line_number
);
17755 linepos
= XFASTINT (w
->base_line_pos
);
17756 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
17761 linepos
= BUF_BEGV (b
);
17762 linepos_byte
= BUF_BEGV_BYTE (b
);
17765 /* Count lines from base line to window start position. */
17766 nlines
= display_count_lines (linepos
, linepos_byte
,
17770 topline
= nlines
+ line
;
17772 /* Determine a new base line, if the old one is too close
17773 or too far away, or if we did not have one.
17774 "Too close" means it's plausible a scroll-down would
17775 go back past it. */
17776 if (startpos
== BUF_BEGV (b
))
17778 w
->base_line_number
= make_number (topline
);
17779 w
->base_line_pos
= make_number (BUF_BEGV (b
));
17781 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
17782 || linepos
== BUF_BEGV (b
))
17784 int limit
= BUF_BEGV (b
);
17785 int limit_byte
= BUF_BEGV_BYTE (b
);
17787 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
17789 if (startpos
- distance
> limit
)
17791 limit
= startpos
- distance
;
17792 limit_byte
= CHAR_TO_BYTE (limit
);
17795 nlines
= display_count_lines (startpos
, startpos_byte
,
17797 - (height
* 2 + 30),
17799 /* If we couldn't find the lines we wanted within
17800 line_number_display_limit_width chars per line,
17801 give up on line numbers for this window. */
17802 if (position
== limit_byte
&& limit
== startpos
- distance
)
17804 w
->base_line_pos
= w
->buffer
;
17805 w
->base_line_number
= Qnil
;
17809 w
->base_line_number
= make_number (topline
- nlines
);
17810 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
17813 /* Now count lines from the start pos to point. */
17814 nlines
= display_count_lines (startpos
, startpos_byte
,
17815 PT_BYTE
, PT
, &junk
);
17817 /* Record that we did display the line number. */
17818 line_number_displayed
= 1;
17820 /* Make the string to show. */
17821 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
17822 return decode_mode_spec_buf
;
17825 char* p
= decode_mode_spec_buf
;
17826 int pad
= field_width
- 2;
17832 return decode_mode_spec_buf
;
17838 obj
= b
->mode_name
;
17842 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
17848 int pos
= marker_position (w
->start
);
17849 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
17851 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
17853 if (pos
<= BUF_BEGV (b
))
17858 else if (pos
<= BUF_BEGV (b
))
17862 if (total
> 1000000)
17863 /* Do it differently for a large value, to avoid overflow. */
17864 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
17866 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
17867 /* We can't normally display a 3-digit number,
17868 so get us a 2-digit number that is close. */
17871 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
17872 return decode_mode_spec_buf
;
17876 /* Display percentage of size above the bottom of the screen. */
17879 int toppos
= marker_position (w
->start
);
17880 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
17881 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
17883 if (botpos
>= BUF_ZV (b
))
17885 if (toppos
<= BUF_BEGV (b
))
17892 if (total
> 1000000)
17893 /* Do it differently for a large value, to avoid overflow. */
17894 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
17896 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
17897 /* We can't normally display a 3-digit number,
17898 so get us a 2-digit number that is close. */
17901 if (toppos
<= BUF_BEGV (b
))
17902 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
17904 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
17905 return decode_mode_spec_buf
;
17910 /* status of process */
17911 obj
= Fget_buffer_process (Fcurrent_buffer ());
17913 return "no process";
17914 #ifdef subprocesses
17915 obj
= Fsymbol_name (Fprocess_status (obj
));
17919 case 't': /* indicate TEXT or BINARY */
17920 #ifdef MODE_LINE_BINARY_TEXT
17921 return MODE_LINE_BINARY_TEXT (b
);
17927 /* coding-system (not including end-of-line format) */
17929 /* coding-system (including end-of-line type) */
17931 int eol_flag
= (c
== 'Z');
17932 char *p
= decode_mode_spec_buf
;
17934 if (! FRAME_WINDOW_P (f
))
17936 /* No need to mention EOL here--the terminal never needs
17937 to do EOL conversion. */
17938 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
17939 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
17941 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
17944 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
17945 #ifdef subprocesses
17946 obj
= Fget_buffer_process (Fcurrent_buffer ());
17947 if (PROCESSP (obj
))
17949 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
17951 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
17954 #endif /* subprocesses */
17957 return decode_mode_spec_buf
;
17963 *multibyte
= STRING_MULTIBYTE (obj
);
17964 return (char *) SDATA (obj
);
17971 /* Count up to COUNT lines starting from START / START_BYTE.
17972 But don't go beyond LIMIT_BYTE.
17973 Return the number of lines thus found (always nonnegative).
17975 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
17978 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
17979 int start
, start_byte
, limit_byte
, count
;
17982 register unsigned char *cursor
;
17983 unsigned char *base
;
17985 register int ceiling
;
17986 register unsigned char *ceiling_addr
;
17987 int orig_count
= count
;
17989 /* If we are not in selective display mode,
17990 check only for newlines. */
17991 int selective_display
= (!NILP (current_buffer
->selective_display
)
17992 && !INTEGERP (current_buffer
->selective_display
));
17996 while (start_byte
< limit_byte
)
17998 ceiling
= BUFFER_CEILING_OF (start_byte
);
17999 ceiling
= min (limit_byte
- 1, ceiling
);
18000 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
18001 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
18004 if (selective_display
)
18005 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
18008 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
18011 if (cursor
!= ceiling_addr
)
18015 start_byte
+= cursor
- base
+ 1;
18016 *byte_pos_ptr
= start_byte
;
18020 if (++cursor
== ceiling_addr
)
18026 start_byte
+= cursor
- base
;
18031 while (start_byte
> limit_byte
)
18033 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
18034 ceiling
= max (limit_byte
, ceiling
);
18035 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
18036 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
18039 if (selective_display
)
18040 while (--cursor
!= ceiling_addr
18041 && *cursor
!= '\n' && *cursor
!= 015)
18044 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
18047 if (cursor
!= ceiling_addr
)
18051 start_byte
+= cursor
- base
+ 1;
18052 *byte_pos_ptr
= start_byte
;
18053 /* When scanning backwards, we should
18054 not count the newline posterior to which we stop. */
18055 return - orig_count
- 1;
18061 /* Here we add 1 to compensate for the last decrement
18062 of CURSOR, which took it past the valid range. */
18063 start_byte
+= cursor
- base
+ 1;
18067 *byte_pos_ptr
= limit_byte
;
18070 return - orig_count
+ count
;
18071 return orig_count
- count
;
18077 /***********************************************************************
18079 ***********************************************************************/
18081 /* Display a NUL-terminated string, starting with index START.
18083 If STRING is non-null, display that C string. Otherwise, the Lisp
18084 string LISP_STRING is displayed.
18086 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18087 FACE_STRING. Display STRING or LISP_STRING with the face at
18088 FACE_STRING_POS in FACE_STRING:
18090 Display the string in the environment given by IT, but use the
18091 standard display table, temporarily.
18093 FIELD_WIDTH is the minimum number of output glyphs to produce.
18094 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18095 with spaces. If STRING has more characters, more than FIELD_WIDTH
18096 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18098 PRECISION is the maximum number of characters to output from
18099 STRING. PRECISION < 0 means don't truncate the string.
18101 This is roughly equivalent to printf format specifiers:
18103 FIELD_WIDTH PRECISION PRINTF
18104 ----------------------------------------
18110 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18111 display them, and < 0 means obey the current buffer's value of
18112 enable_multibyte_characters.
18114 Value is the number of columns displayed. */
18117 display_string (string
, lisp_string
, face_string
, face_string_pos
,
18118 start
, it
, field_width
, precision
, max_x
, multibyte
)
18119 unsigned char *string
;
18120 Lisp_Object lisp_string
;
18121 Lisp_Object face_string
;
18122 int face_string_pos
;
18125 int field_width
, precision
, max_x
;
18128 int hpos_at_start
= it
->hpos
;
18129 int saved_face_id
= it
->face_id
;
18130 struct glyph_row
*row
= it
->glyph_row
;
18132 /* Initialize the iterator IT for iteration over STRING beginning
18133 with index START. */
18134 reseat_to_string (it
, string
, lisp_string
, start
,
18135 precision
, field_width
, multibyte
);
18137 /* If displaying STRING, set up the face of the iterator
18138 from LISP_STRING, if that's given. */
18139 if (STRINGP (face_string
))
18145 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
18146 0, it
->region_beg_charpos
,
18147 it
->region_end_charpos
,
18148 &endptr
, it
->base_face_id
, 0);
18149 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18150 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
18153 /* Set max_x to the maximum allowed X position. Don't let it go
18154 beyond the right edge of the window. */
18156 max_x
= it
->last_visible_x
;
18158 max_x
= min (max_x
, it
->last_visible_x
);
18160 /* Skip over display elements that are not visible. because IT->w is
18162 if (it
->current_x
< it
->first_visible_x
)
18163 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
18164 MOVE_TO_POS
| MOVE_TO_X
);
18166 row
->ascent
= it
->max_ascent
;
18167 row
->height
= it
->max_ascent
+ it
->max_descent
;
18168 row
->phys_ascent
= it
->max_phys_ascent
;
18169 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
18170 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
18172 /* This condition is for the case that we are called with current_x
18173 past last_visible_x. */
18174 while (it
->current_x
< max_x
)
18176 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
18178 /* Get the next display element. */
18179 if (!get_next_display_element (it
))
18182 /* Produce glyphs. */
18183 x_before
= it
->current_x
;
18184 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
18185 PRODUCE_GLYPHS (it
);
18187 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
18190 while (i
< nglyphs
)
18192 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
18194 if (!it
->truncate_lines_p
18195 && x
+ glyph
->pixel_width
> max_x
)
18197 /* End of continued line or max_x reached. */
18198 if (CHAR_GLYPH_PADDING_P (*glyph
))
18200 /* A wide character is unbreakable. */
18201 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
18202 it
->current_x
= x_before
;
18206 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
18211 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
18213 /* Glyph is at least partially visible. */
18215 if (x
< it
->first_visible_x
)
18216 it
->glyph_row
->x
= x
- it
->first_visible_x
;
18220 /* Glyph is off the left margin of the display area.
18221 Should not happen. */
18225 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
18226 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
18227 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
18228 row
->phys_height
= max (row
->phys_height
,
18229 it
->max_phys_ascent
+ it
->max_phys_descent
);
18230 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
18231 it
->max_extra_line_spacing
);
18232 x
+= glyph
->pixel_width
;
18236 /* Stop if max_x reached. */
18240 /* Stop at line ends. */
18241 if (ITERATOR_AT_END_OF_LINE_P (it
))
18243 it
->continuation_lines_width
= 0;
18247 set_iterator_to_next (it
, 1);
18249 /* Stop if truncating at the right edge. */
18250 if (it
->truncate_lines_p
18251 && it
->current_x
>= it
->last_visible_x
)
18253 /* Add truncation mark, but don't do it if the line is
18254 truncated at a padding space. */
18255 if (IT_CHARPOS (*it
) < it
->string_nchars
)
18257 if (!FRAME_WINDOW_P (it
->f
))
18261 if (it
->current_x
> it
->last_visible_x
)
18263 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
18264 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
18266 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
18268 row
->used
[TEXT_AREA
] = i
;
18269 produce_special_glyphs (it
, IT_TRUNCATION
);
18272 produce_special_glyphs (it
, IT_TRUNCATION
);
18274 it
->glyph_row
->truncated_on_right_p
= 1;
18280 /* Maybe insert a truncation at the left. */
18281 if (it
->first_visible_x
18282 && IT_CHARPOS (*it
) > 0)
18284 if (!FRAME_WINDOW_P (it
->f
))
18285 insert_left_trunc_glyphs (it
);
18286 it
->glyph_row
->truncated_on_left_p
= 1;
18289 it
->face_id
= saved_face_id
;
18291 /* Value is number of columns displayed. */
18292 return it
->hpos
- hpos_at_start
;
18297 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
18298 appears as an element of LIST or as the car of an element of LIST.
18299 If PROPVAL is a list, compare each element against LIST in that
18300 way, and return 1/2 if any element of PROPVAL is found in LIST.
18301 Otherwise return 0. This function cannot quit.
18302 The return value is 2 if the text is invisible but with an ellipsis
18303 and 1 if it's invisible and without an ellipsis. */
18306 invisible_p (propval
, list
)
18307 register Lisp_Object propval
;
18310 register Lisp_Object tail
, proptail
;
18312 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
18314 register Lisp_Object tem
;
18316 if (EQ (propval
, tem
))
18318 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
18319 return NILP (XCDR (tem
)) ? 1 : 2;
18322 if (CONSP (propval
))
18324 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
18326 Lisp_Object propelt
;
18327 propelt
= XCAR (proptail
);
18328 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
18330 register Lisp_Object tem
;
18332 if (EQ (propelt
, tem
))
18334 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
18335 return NILP (XCDR (tem
)) ? 1 : 2;
18343 /* Calculate a width or height in pixels from a specification using
18344 the following elements:
18347 NUM - a (fractional) multiple of the default font width/height
18348 (NUM) - specifies exactly NUM pixels
18349 UNIT - a fixed number of pixels, see below.
18350 ELEMENT - size of a display element in pixels, see below.
18351 (NUM . SPEC) - equals NUM * SPEC
18352 (+ SPEC SPEC ...) - add pixel values
18353 (- SPEC SPEC ...) - subtract pixel values
18354 (- SPEC) - negate pixel value
18357 INT or FLOAT - a number constant
18358 SYMBOL - use symbol's (buffer local) variable binding.
18361 in - pixels per inch *)
18362 mm - pixels per 1/1000 meter *)
18363 cm - pixels per 1/100 meter *)
18364 width - width of current font in pixels.
18365 height - height of current font in pixels.
18367 *) using the ratio(s) defined in display-pixels-per-inch.
18371 left-fringe - left fringe width in pixels
18372 right-fringe - right fringe width in pixels
18374 left-margin - left margin width in pixels
18375 right-margin - right margin width in pixels
18377 scroll-bar - scroll-bar area width in pixels
18381 Pixels corresponding to 5 inches:
18384 Total width of non-text areas on left side of window (if scroll-bar is on left):
18385 '(space :width (+ left-fringe left-margin scroll-bar))
18387 Align to first text column (in header line):
18388 '(space :align-to 0)
18390 Align to middle of text area minus half the width of variable `my-image'
18391 containing a loaded image:
18392 '(space :align-to (0.5 . (- text my-image)))
18394 Width of left margin minus width of 1 character in the default font:
18395 '(space :width (- left-margin 1))
18397 Width of left margin minus width of 2 characters in the current font:
18398 '(space :width (- left-margin (2 . width)))
18400 Center 1 character over left-margin (in header line):
18401 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
18403 Different ways to express width of left fringe plus left margin minus one pixel:
18404 '(space :width (- (+ left-fringe left-margin) (1)))
18405 '(space :width (+ left-fringe left-margin (- (1))))
18406 '(space :width (+ left-fringe left-margin (-1)))
18410 #define NUMVAL(X) \
18411 ((INTEGERP (X) || FLOATP (X)) \
18416 calc_pixel_width_or_height (res
, it
, prop
, font
, width_p
, align_to
)
18421 int width_p
, *align_to
;
18425 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
18426 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
18429 return OK_PIXELS (0);
18431 if (SYMBOLP (prop
))
18433 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
18435 char *unit
= SDATA (SYMBOL_NAME (prop
));
18437 if (unit
[0] == 'i' && unit
[1] == 'n')
18439 else if (unit
[0] == 'm' && unit
[1] == 'm')
18441 else if (unit
[0] == 'c' && unit
[1] == 'm')
18448 #ifdef HAVE_WINDOW_SYSTEM
18449 if (FRAME_WINDOW_P (it
->f
)
18451 ? FRAME_X_DISPLAY_INFO (it
->f
)->resx
18452 : FRAME_X_DISPLAY_INFO (it
->f
)->resy
),
18454 return OK_PIXELS (ppi
/ pixels
);
18457 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
18458 || (CONSP (Vdisplay_pixels_per_inch
)
18460 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
18461 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
18463 return OK_PIXELS (ppi
/ pixels
);
18469 #ifdef HAVE_WINDOW_SYSTEM
18470 if (EQ (prop
, Qheight
))
18471 return OK_PIXELS (font
? FONT_HEIGHT ((XFontStruct
*)font
) : FRAME_LINE_HEIGHT (it
->f
));
18472 if (EQ (prop
, Qwidth
))
18473 return OK_PIXELS (font
? FONT_WIDTH ((XFontStruct
*)font
) : FRAME_COLUMN_WIDTH (it
->f
));
18475 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
18476 return OK_PIXELS (1);
18479 if (EQ (prop
, Qtext
))
18480 return OK_PIXELS (width_p
18481 ? window_box_width (it
->w
, TEXT_AREA
)
18482 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
18484 if (align_to
&& *align_to
< 0)
18487 if (EQ (prop
, Qleft
))
18488 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
18489 if (EQ (prop
, Qright
))
18490 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
18491 if (EQ (prop
, Qcenter
))
18492 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
18493 + window_box_width (it
->w
, TEXT_AREA
) / 2);
18494 if (EQ (prop
, Qleft_fringe
))
18495 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
18496 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
18497 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
18498 if (EQ (prop
, Qright_fringe
))
18499 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
18500 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
18501 : window_box_right_offset (it
->w
, TEXT_AREA
));
18502 if (EQ (prop
, Qleft_margin
))
18503 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
18504 if (EQ (prop
, Qright_margin
))
18505 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
18506 if (EQ (prop
, Qscroll_bar
))
18507 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
18509 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
18510 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
18511 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
18516 if (EQ (prop
, Qleft_fringe
))
18517 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
18518 if (EQ (prop
, Qright_fringe
))
18519 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
18520 if (EQ (prop
, Qleft_margin
))
18521 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
18522 if (EQ (prop
, Qright_margin
))
18523 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
18524 if (EQ (prop
, Qscroll_bar
))
18525 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
18528 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
18531 if (INTEGERP (prop
) || FLOATP (prop
))
18533 int base_unit
= (width_p
18534 ? FRAME_COLUMN_WIDTH (it
->f
)
18535 : FRAME_LINE_HEIGHT (it
->f
));
18536 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
18541 Lisp_Object car
= XCAR (prop
);
18542 Lisp_Object cdr
= XCDR (prop
);
18546 #ifdef HAVE_WINDOW_SYSTEM
18547 if (valid_image_p (prop
))
18549 int id
= lookup_image (it
->f
, prop
);
18550 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
18552 return OK_PIXELS (width_p
? img
->width
: img
->height
);
18555 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
18561 while (CONSP (cdr
))
18563 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
18564 font
, width_p
, align_to
))
18567 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
18572 if (EQ (car
, Qminus
))
18574 return OK_PIXELS (pixels
);
18577 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
18580 if (INTEGERP (car
) || FLOATP (car
))
18583 pixels
= XFLOATINT (car
);
18585 return OK_PIXELS (pixels
);
18586 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
18587 font
, width_p
, align_to
))
18588 return OK_PIXELS (pixels
* fact
);
18599 /***********************************************************************
18601 ***********************************************************************/
18603 #ifdef HAVE_WINDOW_SYSTEM
18608 dump_glyph_string (s
)
18609 struct glyph_string
*s
;
18611 fprintf (stderr
, "glyph string\n");
18612 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
18613 s
->x
, s
->y
, s
->width
, s
->height
);
18614 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
18615 fprintf (stderr
, " hl = %d\n", s
->hl
);
18616 fprintf (stderr
, " left overhang = %d, right = %d\n",
18617 s
->left_overhang
, s
->right_overhang
);
18618 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
18619 fprintf (stderr
, " extends to end of line = %d\n",
18620 s
->extends_to_end_of_line_p
);
18621 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
18622 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
18625 #endif /* GLYPH_DEBUG */
18627 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
18628 of XChar2b structures for S; it can't be allocated in
18629 init_glyph_string because it must be allocated via `alloca'. W
18630 is the window on which S is drawn. ROW and AREA are the glyph row
18631 and area within the row from which S is constructed. START is the
18632 index of the first glyph structure covered by S. HL is a
18633 face-override for drawing S. */
18636 #define OPTIONAL_HDC(hdc) hdc,
18637 #define DECLARE_HDC(hdc) HDC hdc;
18638 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
18639 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
18642 #ifndef OPTIONAL_HDC
18643 #define OPTIONAL_HDC(hdc)
18644 #define DECLARE_HDC(hdc)
18645 #define ALLOCATE_HDC(hdc, f)
18646 #define RELEASE_HDC(hdc, f)
18650 init_glyph_string (s
, OPTIONAL_HDC (hdc
) char2b
, w
, row
, area
, start
, hl
)
18651 struct glyph_string
*s
;
18655 struct glyph_row
*row
;
18656 enum glyph_row_area area
;
18658 enum draw_glyphs_face hl
;
18660 bzero (s
, sizeof *s
);
18662 s
->f
= XFRAME (w
->frame
);
18666 s
->display
= FRAME_X_DISPLAY (s
->f
);
18667 s
->window
= FRAME_X_WINDOW (s
->f
);
18668 s
->char2b
= char2b
;
18672 s
->first_glyph
= row
->glyphs
[area
] + start
;
18673 s
->height
= row
->height
;
18674 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
18676 /* Display the internal border below the tool-bar window. */
18677 if (WINDOWP (s
->f
->tool_bar_window
)
18678 && s
->w
== XWINDOW (s
->f
->tool_bar_window
))
18679 s
->y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
18681 s
->ybase
= s
->y
+ row
->ascent
;
18685 /* Append the list of glyph strings with head H and tail T to the list
18686 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
18689 append_glyph_string_lists (head
, tail
, h
, t
)
18690 struct glyph_string
**head
, **tail
;
18691 struct glyph_string
*h
, *t
;
18705 /* Prepend the list of glyph strings with head H and tail T to the
18706 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
18710 prepend_glyph_string_lists (head
, tail
, h
, t
)
18711 struct glyph_string
**head
, **tail
;
18712 struct glyph_string
*h
, *t
;
18726 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
18727 Set *HEAD and *TAIL to the resulting list. */
18730 append_glyph_string (head
, tail
, s
)
18731 struct glyph_string
**head
, **tail
;
18732 struct glyph_string
*s
;
18734 s
->next
= s
->prev
= NULL
;
18735 append_glyph_string_lists (head
, tail
, s
, s
);
18739 /* Get face and two-byte form of character glyph GLYPH on frame F.
18740 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
18741 a pointer to a realized face that is ready for display. */
18743 static INLINE
struct face
*
18744 get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
18746 struct glyph
*glyph
;
18752 xassert (glyph
->type
== CHAR_GLYPH
);
18753 face
= FACE_FROM_ID (f
, glyph
->face_id
);
18758 if (!glyph
->multibyte_p
)
18760 /* Unibyte case. We don't have to encode, but we have to make
18761 sure to use a face suitable for unibyte. */
18762 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
18764 else if (glyph
->u
.ch
< 128)
18766 /* Case of ASCII in a face known to fit ASCII. */
18767 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
18771 int c1
, c2
, charset
;
18773 /* Split characters into bytes. If c2 is -1 afterwards, C is
18774 really a one-byte character so that byte1 is zero. */
18775 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
18777 STORE_XCHAR2B (char2b
, c1
, c2
);
18779 STORE_XCHAR2B (char2b
, 0, c1
);
18781 /* Maybe encode the character in *CHAR2B. */
18782 if (charset
!= CHARSET_ASCII
)
18784 struct font_info
*font_info
18785 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
18788 = rif
->encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
18792 /* Make sure X resources of the face are allocated. */
18793 xassert (face
!= NULL
);
18794 PREPARE_FACE_FOR_DISPLAY (f
, face
);
18799 /* Fill glyph string S with composition components specified by S->cmp.
18801 FACES is an array of faces for all components of this composition.
18802 S->gidx is the index of the first component for S.
18804 OVERLAPS non-zero means S should draw the foreground only, and use
18805 its physical height for clipping. See also draw_glyphs.
18807 Value is the index of a component not in S. */
18810 fill_composite_glyph_string (s
, faces
, overlaps
)
18811 struct glyph_string
*s
;
18812 struct face
**faces
;
18819 s
->for_overlaps
= overlaps
;
18821 s
->face
= faces
[s
->gidx
];
18822 s
->font
= s
->face
->font
;
18823 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
18825 /* For all glyphs of this composition, starting at the offset
18826 S->gidx, until we reach the end of the definition or encounter a
18827 glyph that requires the different face, add it to S. */
18829 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
18832 /* All glyph strings for the same composition has the same width,
18833 i.e. the width set for the first component of the composition. */
18835 s
->width
= s
->first_glyph
->pixel_width
;
18837 /* If the specified font could not be loaded, use the frame's
18838 default font, but record the fact that we couldn't load it in
18839 the glyph string so that we can draw rectangles for the
18840 characters of the glyph string. */
18841 if (s
->font
== NULL
)
18843 s
->font_not_found_p
= 1;
18844 s
->font
= FRAME_FONT (s
->f
);
18847 /* Adjust base line for subscript/superscript text. */
18848 s
->ybase
+= s
->first_glyph
->voffset
;
18850 xassert (s
->face
&& s
->face
->gc
);
18852 /* This glyph string must always be drawn with 16-bit functions. */
18855 return s
->gidx
+ s
->nchars
;
18859 /* Fill glyph string S from a sequence of character glyphs.
18861 FACE_ID is the face id of the string. START is the index of the
18862 first glyph to consider, END is the index of the last + 1.
18863 OVERLAPS non-zero means S should draw the foreground only, and use
18864 its physical height for clipping. See also draw_glyphs.
18866 Value is the index of the first glyph not in S. */
18869 fill_glyph_string (s
, face_id
, start
, end
, overlaps
)
18870 struct glyph_string
*s
;
18872 int start
, end
, overlaps
;
18874 struct glyph
*glyph
, *last
;
18876 int glyph_not_available_p
;
18878 xassert (s
->f
== XFRAME (s
->w
->frame
));
18879 xassert (s
->nchars
== 0);
18880 xassert (start
>= 0 && end
> start
);
18882 s
->for_overlaps
= overlaps
,
18883 glyph
= s
->row
->glyphs
[s
->area
] + start
;
18884 last
= s
->row
->glyphs
[s
->area
] + end
;
18885 voffset
= glyph
->voffset
;
18887 glyph_not_available_p
= glyph
->glyph_not_available_p
;
18889 while (glyph
< last
18890 && glyph
->type
== CHAR_GLYPH
18891 && glyph
->voffset
== voffset
18892 /* Same face id implies same font, nowadays. */
18893 && glyph
->face_id
== face_id
18894 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
18898 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
18899 s
->char2b
+ s
->nchars
,
18901 s
->two_byte_p
= two_byte_p
;
18903 xassert (s
->nchars
<= end
- start
);
18904 s
->width
+= glyph
->pixel_width
;
18908 s
->font
= s
->face
->font
;
18909 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
18911 /* If the specified font could not be loaded, use the frame's font,
18912 but record the fact that we couldn't load it in
18913 S->font_not_found_p so that we can draw rectangles for the
18914 characters of the glyph string. */
18915 if (s
->font
== NULL
|| glyph_not_available_p
)
18917 s
->font_not_found_p
= 1;
18918 s
->font
= FRAME_FONT (s
->f
);
18921 /* Adjust base line for subscript/superscript text. */
18922 s
->ybase
+= voffset
;
18924 xassert (s
->face
&& s
->face
->gc
);
18925 return glyph
- s
->row
->glyphs
[s
->area
];
18929 /* Fill glyph string S from image glyph S->first_glyph. */
18932 fill_image_glyph_string (s
)
18933 struct glyph_string
*s
;
18935 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
18936 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
18938 s
->slice
= s
->first_glyph
->slice
;
18939 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
18940 s
->font
= s
->face
->font
;
18941 s
->width
= s
->first_glyph
->pixel_width
;
18943 /* Adjust base line for subscript/superscript text. */
18944 s
->ybase
+= s
->first_glyph
->voffset
;
18948 /* Fill glyph string S from a sequence of stretch glyphs.
18950 ROW is the glyph row in which the glyphs are found, AREA is the
18951 area within the row. START is the index of the first glyph to
18952 consider, END is the index of the last + 1.
18954 Value is the index of the first glyph not in S. */
18957 fill_stretch_glyph_string (s
, row
, area
, start
, end
)
18958 struct glyph_string
*s
;
18959 struct glyph_row
*row
;
18960 enum glyph_row_area area
;
18963 struct glyph
*glyph
, *last
;
18964 int voffset
, face_id
;
18966 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
18968 glyph
= s
->row
->glyphs
[s
->area
] + start
;
18969 last
= s
->row
->glyphs
[s
->area
] + end
;
18970 face_id
= glyph
->face_id
;
18971 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
18972 s
->font
= s
->face
->font
;
18973 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
18974 s
->width
= glyph
->pixel_width
;
18976 voffset
= glyph
->voffset
;
18980 && glyph
->type
== STRETCH_GLYPH
18981 && glyph
->voffset
== voffset
18982 && glyph
->face_id
== face_id
);
18984 s
->width
+= glyph
->pixel_width
;
18986 /* Adjust base line for subscript/superscript text. */
18987 s
->ybase
+= voffset
;
18989 /* The case that face->gc == 0 is handled when drawing the glyph
18990 string by calling PREPARE_FACE_FOR_DISPLAY. */
18992 return glyph
- s
->row
->glyphs
[s
->area
];
18997 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
18998 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
18999 assumed to be zero. */
19002 x_get_glyph_overhangs (glyph
, f
, left
, right
)
19003 struct glyph
*glyph
;
19007 *left
= *right
= 0;
19009 if (glyph
->type
== CHAR_GLYPH
)
19013 struct font_info
*font_info
;
19017 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
19019 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
19020 if (font
/* ++KFS: Should this be font_info ? */
19021 && (pcm
= rif
->per_char_metric (font
, &char2b
, glyph
->font_type
)))
19023 if (pcm
->rbearing
> pcm
->width
)
19024 *right
= pcm
->rbearing
- pcm
->width
;
19025 if (pcm
->lbearing
< 0)
19026 *left
= -pcm
->lbearing
;
19032 /* Return the index of the first glyph preceding glyph string S that
19033 is overwritten by S because of S's left overhang. Value is -1
19034 if no glyphs are overwritten. */
19037 left_overwritten (s
)
19038 struct glyph_string
*s
;
19042 if (s
->left_overhang
)
19045 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
19046 int first
= s
->first_glyph
- glyphs
;
19048 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
19049 x
-= glyphs
[i
].pixel_width
;
19060 /* Return the index of the first glyph preceding glyph string S that
19061 is overwriting S because of its right overhang. Value is -1 if no
19062 glyph in front of S overwrites S. */
19065 left_overwriting (s
)
19066 struct glyph_string
*s
;
19069 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
19070 int first
= s
->first_glyph
- glyphs
;
19074 for (i
= first
- 1; i
>= 0; --i
)
19077 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
19080 x
-= glyphs
[i
].pixel_width
;
19087 /* Return the index of the last glyph following glyph string S that is
19088 not overwritten by S because of S's right overhang. Value is -1 if
19089 no such glyph is found. */
19092 right_overwritten (s
)
19093 struct glyph_string
*s
;
19097 if (s
->right_overhang
)
19100 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
19101 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
19102 int end
= s
->row
->used
[s
->area
];
19104 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
19105 x
+= glyphs
[i
].pixel_width
;
19114 /* Return the index of the last glyph following glyph string S that
19115 overwrites S because of its left overhang. Value is negative
19116 if no such glyph is found. */
19119 right_overwriting (s
)
19120 struct glyph_string
*s
;
19123 int end
= s
->row
->used
[s
->area
];
19124 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
19125 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
19129 for (i
= first
; i
< end
; ++i
)
19132 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
19135 x
+= glyphs
[i
].pixel_width
;
19142 /* Get face and two-byte form of character C in face FACE_ID on frame
19143 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19144 means we want to display multibyte text. DISPLAY_P non-zero means
19145 make sure that X resources for the face returned are allocated.
19146 Value is a pointer to a realized face that is ready for display if
19147 DISPLAY_P is non-zero. */
19149 static INLINE
struct face
*
19150 get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
, display_p
)
19154 int multibyte_p
, display_p
;
19156 struct face
*face
= FACE_FROM_ID (f
, face_id
);
19160 /* Unibyte case. We don't have to encode, but we have to make
19161 sure to use a face suitable for unibyte. */
19162 STORE_XCHAR2B (char2b
, 0, c
);
19163 face_id
= FACE_FOR_CHAR (f
, face
, c
);
19164 face
= FACE_FROM_ID (f
, face_id
);
19168 /* Case of ASCII in a face known to fit ASCII. */
19169 STORE_XCHAR2B (char2b
, 0, c
);
19173 int c1
, c2
, charset
;
19175 /* Split characters into bytes. If c2 is -1 afterwards, C is
19176 really a one-byte character so that byte1 is zero. */
19177 SPLIT_CHAR (c
, charset
, c1
, c2
);
19179 STORE_XCHAR2B (char2b
, c1
, c2
);
19181 STORE_XCHAR2B (char2b
, 0, c1
);
19183 /* Maybe encode the character in *CHAR2B. */
19184 if (face
->font
!= NULL
)
19186 struct font_info
*font_info
19187 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
19189 rif
->encode_char (c
, char2b
, font_info
, 0);
19193 /* Make sure X resources of the face are allocated. */
19194 #ifdef HAVE_X_WINDOWS
19198 xassert (face
!= NULL
);
19199 PREPARE_FACE_FOR_DISPLAY (f
, face
);
19206 /* Set background width of glyph string S. START is the index of the
19207 first glyph following S. LAST_X is the right-most x-position + 1
19208 in the drawing area. */
19211 set_glyph_string_background_width (s
, start
, last_x
)
19212 struct glyph_string
*s
;
19216 /* If the face of this glyph string has to be drawn to the end of
19217 the drawing area, set S->extends_to_end_of_line_p. */
19219 if (start
== s
->row
->used
[s
->area
]
19220 && s
->area
== TEXT_AREA
19221 && ((s
->row
->fill_line_p
19222 && (s
->hl
== DRAW_NORMAL_TEXT
19223 || s
->hl
== DRAW_IMAGE_RAISED
19224 || s
->hl
== DRAW_IMAGE_SUNKEN
))
19225 || s
->hl
== DRAW_MOUSE_FACE
))
19226 s
->extends_to_end_of_line_p
= 1;
19228 /* If S extends its face to the end of the line, set its
19229 background_width to the distance to the right edge of the drawing
19231 if (s
->extends_to_end_of_line_p
)
19232 s
->background_width
= last_x
- s
->x
+ 1;
19234 s
->background_width
= s
->width
;
19238 /* Compute overhangs and x-positions for glyph string S and its
19239 predecessors, or successors. X is the starting x-position for S.
19240 BACKWARD_P non-zero means process predecessors. */
19243 compute_overhangs_and_x (s
, x
, backward_p
)
19244 struct glyph_string
*s
;
19252 if (rif
->compute_glyph_string_overhangs
)
19253 rif
->compute_glyph_string_overhangs (s
);
19263 if (rif
->compute_glyph_string_overhangs
)
19264 rif
->compute_glyph_string_overhangs (s
);
19274 /* The following macros are only called from draw_glyphs below.
19275 They reference the following parameters of that function directly:
19276 `w', `row', `area', and `overlap_p'
19277 as well as the following local variables:
19278 `s', `f', and `hdc' (in W32) */
19281 /* On W32, silently add local `hdc' variable to argument list of
19282 init_glyph_string. */
19283 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19284 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
19286 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19287 init_glyph_string (s, char2b, w, row, area, start, hl)
19290 /* Add a glyph string for a stretch glyph to the list of strings
19291 between HEAD and TAIL. START is the index of the stretch glyph in
19292 row area AREA of glyph row ROW. END is the index of the last glyph
19293 in that glyph row area. X is the current output position assigned
19294 to the new glyph string constructed. HL overrides that face of the
19295 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19296 is the right-most x-position of the drawing area. */
19298 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
19299 and below -- keep them on one line. */
19300 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19303 s = (struct glyph_string *) alloca (sizeof *s); \
19304 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19305 START = fill_stretch_glyph_string (s, row, area, START, END); \
19306 append_glyph_string (&HEAD, &TAIL, s); \
19312 /* Add a glyph string for an image glyph to the list of strings
19313 between HEAD and TAIL. START is the index of the image glyph in
19314 row area AREA of glyph row ROW. END is the index of the last glyph
19315 in that glyph row area. X is the current output position assigned
19316 to the new glyph string constructed. HL overrides that face of the
19317 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19318 is the right-most x-position of the drawing area. */
19320 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19323 s = (struct glyph_string *) alloca (sizeof *s); \
19324 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19325 fill_image_glyph_string (s); \
19326 append_glyph_string (&HEAD, &TAIL, s); \
19333 /* Add a glyph string for a sequence of character glyphs to the list
19334 of strings between HEAD and TAIL. START is the index of the first
19335 glyph in row area AREA of glyph row ROW that is part of the new
19336 glyph string. END is the index of the last glyph in that glyph row
19337 area. X is the current output position assigned to the new glyph
19338 string constructed. HL overrides that face of the glyph; e.g. it
19339 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
19340 right-most x-position of the drawing area. */
19342 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19348 c = (row)->glyphs[area][START].u.ch; \
19349 face_id = (row)->glyphs[area][START].face_id; \
19351 s = (struct glyph_string *) alloca (sizeof *s); \
19352 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
19353 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19354 append_glyph_string (&HEAD, &TAIL, s); \
19356 START = fill_glyph_string (s, face_id, START, END, overlaps); \
19361 /* Add a glyph string for a composite sequence to the list of strings
19362 between HEAD and TAIL. START is the index of the first glyph in
19363 row area AREA of glyph row ROW that is part of the new glyph
19364 string. END is the index of the last glyph in that glyph row area.
19365 X is the current output position assigned to the new glyph string
19366 constructed. HL overrides that face of the glyph; e.g. it is
19367 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
19368 x-position of the drawing area. */
19370 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19372 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
19373 int face_id = (row)->glyphs[area][START].face_id; \
19374 struct face *base_face = FACE_FROM_ID (f, face_id); \
19375 struct composition *cmp = composition_table[cmp_id]; \
19376 int glyph_len = cmp->glyph_len; \
19378 struct face **faces; \
19379 struct glyph_string *first_s = NULL; \
19382 base_face = base_face->ascii_face; \
19383 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
19384 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
19385 /* At first, fill in `char2b' and `faces'. */ \
19386 for (n = 0; n < glyph_len; n++) \
19388 int c = COMPOSITION_GLYPH (cmp, n); \
19389 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
19390 faces[n] = FACE_FROM_ID (f, this_face_id); \
19391 get_char_face_and_encoding (f, c, this_face_id, \
19392 char2b + n, 1, 1); \
19395 /* Make glyph_strings for each glyph sequence that is drawable by \
19396 the same face, and append them to HEAD/TAIL. */ \
19397 for (n = 0; n < cmp->glyph_len;) \
19399 s = (struct glyph_string *) alloca (sizeof *s); \
19400 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
19401 append_glyph_string (&(HEAD), &(TAIL), s); \
19409 n = fill_composite_glyph_string (s, faces, overlaps); \
19417 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
19418 of AREA of glyph row ROW on window W between indices START and END.
19419 HL overrides the face for drawing glyph strings, e.g. it is
19420 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
19421 x-positions of the drawing area.
19423 This is an ugly monster macro construct because we must use alloca
19424 to allocate glyph strings (because draw_glyphs can be called
19425 asynchronously). */
19427 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19430 HEAD = TAIL = NULL; \
19431 while (START < END) \
19433 struct glyph *first_glyph = (row)->glyphs[area] + START; \
19434 switch (first_glyph->type) \
19437 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
19441 case COMPOSITE_GLYPH: \
19442 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
19446 case STRETCH_GLYPH: \
19447 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
19451 case IMAGE_GLYPH: \
19452 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
19460 set_glyph_string_background_width (s, START, LAST_X); \
19467 /* Draw glyphs between START and END in AREA of ROW on window W,
19468 starting at x-position X. X is relative to AREA in W. HL is a
19469 face-override with the following meaning:
19471 DRAW_NORMAL_TEXT draw normally
19472 DRAW_CURSOR draw in cursor face
19473 DRAW_MOUSE_FACE draw in mouse face.
19474 DRAW_INVERSE_VIDEO draw in mode line face
19475 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
19476 DRAW_IMAGE_RAISED draw an image with a raised relief around it
19478 If OVERLAPS is non-zero, draw only the foreground of characters and
19479 clip to the physical height of ROW. Non-zero value also defines
19480 the overlapping part to be drawn:
19482 OVERLAPS_PRED overlap with preceding rows
19483 OVERLAPS_SUCC overlap with succeeding rows
19484 OVERLAPS_BOTH overlap with both preceding/succeeding rows
19485 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
19487 Value is the x-position reached, relative to AREA of W. */
19490 draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps
)
19493 struct glyph_row
*row
;
19494 enum glyph_row_area area
;
19496 enum draw_glyphs_face hl
;
19499 struct glyph_string
*head
, *tail
;
19500 struct glyph_string
*s
;
19501 struct glyph_string
*clip_head
= NULL
, *clip_tail
= NULL
;
19502 int last_x
, area_width
;
19505 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
19508 ALLOCATE_HDC (hdc
, f
);
19510 /* Let's rather be paranoid than getting a SEGV. */
19511 end
= min (end
, row
->used
[area
]);
19512 start
= max (0, start
);
19513 start
= min (end
, start
);
19515 /* Translate X to frame coordinates. Set last_x to the right
19516 end of the drawing area. */
19517 if (row
->full_width_p
)
19519 /* X is relative to the left edge of W, without scroll bars
19521 x
+= WINDOW_LEFT_EDGE_X (w
);
19522 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
19526 int area_left
= window_box_left (w
, area
);
19528 area_width
= window_box_width (w
, area
);
19529 last_x
= area_left
+ area_width
;
19532 /* Build a doubly-linked list of glyph_string structures between
19533 head and tail from what we have to draw. Note that the macro
19534 BUILD_GLYPH_STRINGS will modify its start parameter. That's
19535 the reason we use a separate variable `i'. */
19537 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
19539 x_reached
= tail
->x
+ tail
->background_width
;
19543 /* If there are any glyphs with lbearing < 0 or rbearing > width in
19544 the row, redraw some glyphs in front or following the glyph
19545 strings built above. */
19546 if (head
&& !overlaps
&& row
->contains_overlapping_glyphs_p
)
19549 struct glyph_string
*h
, *t
;
19551 /* Compute overhangs for all glyph strings. */
19552 if (rif
->compute_glyph_string_overhangs
)
19553 for (s
= head
; s
; s
= s
->next
)
19554 rif
->compute_glyph_string_overhangs (s
);
19556 /* Prepend glyph strings for glyphs in front of the first glyph
19557 string that are overwritten because of the first glyph
19558 string's left overhang. The background of all strings
19559 prepended must be drawn because the first glyph string
19561 i
= left_overwritten (head
);
19565 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
19566 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
19568 compute_overhangs_and_x (t
, head
->x
, 1);
19569 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
19573 /* Prepend glyph strings for glyphs in front of the first glyph
19574 string that overwrite that glyph string because of their
19575 right overhang. For these strings, only the foreground must
19576 be drawn, because it draws over the glyph string at `head'.
19577 The background must not be drawn because this would overwrite
19578 right overhangs of preceding glyphs for which no glyph
19580 i
= left_overwriting (head
);
19584 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
19585 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
19586 for (s
= h
; s
; s
= s
->next
)
19587 s
->background_filled_p
= 1;
19588 compute_overhangs_and_x (t
, head
->x
, 1);
19589 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
19592 /* Append glyphs strings for glyphs following the last glyph
19593 string tail that are overwritten by tail. The background of
19594 these strings has to be drawn because tail's foreground draws
19596 i
= right_overwritten (tail
);
19599 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
19600 DRAW_NORMAL_TEXT
, x
, last_x
);
19601 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
19602 append_glyph_string_lists (&head
, &tail
, h
, t
);
19606 /* Append glyph strings for glyphs following the last glyph
19607 string tail that overwrite tail. The foreground of such
19608 glyphs has to be drawn because it writes into the background
19609 of tail. The background must not be drawn because it could
19610 paint over the foreground of following glyphs. */
19611 i
= right_overwriting (tail
);
19615 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
19616 DRAW_NORMAL_TEXT
, x
, last_x
);
19617 for (s
= h
; s
; s
= s
->next
)
19618 s
->background_filled_p
= 1;
19619 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
19620 append_glyph_string_lists (&head
, &tail
, h
, t
);
19622 if (clip_head
|| clip_tail
)
19623 for (s
= head
; s
; s
= s
->next
)
19625 s
->clip_head
= clip_head
;
19626 s
->clip_tail
= clip_tail
;
19630 /* Draw all strings. */
19631 for (s
= head
; s
; s
= s
->next
)
19632 rif
->draw_glyph_string (s
);
19634 if (area
== TEXT_AREA
19635 && !row
->full_width_p
19636 /* When drawing overlapping rows, only the glyph strings'
19637 foreground is drawn, which doesn't erase a cursor
19641 int x0
= clip_head
? clip_head
->x
: (head
? head
->x
: x
);
19642 int x1
= (clip_tail
? clip_tail
->x
+ clip_tail
->background_width
19643 : (tail
? tail
->x
+ tail
->background_width
: x
));
19645 int text_left
= window_box_left (w
, TEXT_AREA
);
19649 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
19650 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
19653 /* Value is the x-position up to which drawn, relative to AREA of W.
19654 This doesn't include parts drawn because of overhangs. */
19655 if (row
->full_width_p
)
19656 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
19658 x_reached
-= window_box_left (w
, area
);
19660 RELEASE_HDC (hdc
, f
);
19665 /* Expand row matrix if too narrow. Don't expand if area
19668 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
19670 if (!fonts_changed_p \
19671 && (it->glyph_row->glyphs[area] \
19672 < it->glyph_row->glyphs[area + 1])) \
19674 it->w->ncols_scale_factor++; \
19675 fonts_changed_p = 1; \
19679 /* Store one glyph for IT->char_to_display in IT->glyph_row.
19680 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19686 struct glyph
*glyph
;
19687 enum glyph_row_area area
= it
->area
;
19689 xassert (it
->glyph_row
);
19690 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
19692 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
19693 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
19695 glyph
->charpos
= CHARPOS (it
->position
);
19696 glyph
->object
= it
->object
;
19697 glyph
->pixel_width
= it
->pixel_width
;
19698 glyph
->ascent
= it
->ascent
;
19699 glyph
->descent
= it
->descent
;
19700 glyph
->voffset
= it
->voffset
;
19701 glyph
->type
= CHAR_GLYPH
;
19702 glyph
->multibyte_p
= it
->multibyte_p
;
19703 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
19704 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
19705 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
19706 || it
->phys_descent
> it
->descent
);
19707 glyph
->padding_p
= 0;
19708 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
19709 glyph
->face_id
= it
->face_id
;
19710 glyph
->u
.ch
= it
->char_to_display
;
19711 glyph
->slice
= null_glyph_slice
;
19712 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
19713 ++it
->glyph_row
->used
[area
];
19716 IT_EXPAND_MATRIX_WIDTH (it
, area
);
19719 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
19720 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19723 append_composite_glyph (it
)
19726 struct glyph
*glyph
;
19727 enum glyph_row_area area
= it
->area
;
19729 xassert (it
->glyph_row
);
19731 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
19732 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
19734 glyph
->charpos
= CHARPOS (it
->position
);
19735 glyph
->object
= it
->object
;
19736 glyph
->pixel_width
= it
->pixel_width
;
19737 glyph
->ascent
= it
->ascent
;
19738 glyph
->descent
= it
->descent
;
19739 glyph
->voffset
= it
->voffset
;
19740 glyph
->type
= COMPOSITE_GLYPH
;
19741 glyph
->multibyte_p
= it
->multibyte_p
;
19742 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
19743 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
19744 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
19745 || it
->phys_descent
> it
->descent
);
19746 glyph
->padding_p
= 0;
19747 glyph
->glyph_not_available_p
= 0;
19748 glyph
->face_id
= it
->face_id
;
19749 glyph
->u
.cmp_id
= it
->cmp_id
;
19750 glyph
->slice
= null_glyph_slice
;
19751 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
19752 ++it
->glyph_row
->used
[area
];
19755 IT_EXPAND_MATRIX_WIDTH (it
, area
);
19759 /* Change IT->ascent and IT->height according to the setting of
19763 take_vertical_position_into_account (it
)
19768 if (it
->voffset
< 0)
19769 /* Increase the ascent so that we can display the text higher
19771 it
->ascent
-= it
->voffset
;
19773 /* Increase the descent so that we can display the text lower
19775 it
->descent
+= it
->voffset
;
19780 /* Produce glyphs/get display metrics for the image IT is loaded with.
19781 See the description of struct display_iterator in dispextern.h for
19782 an overview of struct display_iterator. */
19785 produce_image_glyph (it
)
19790 int glyph_ascent
, crop
;
19791 struct glyph_slice slice
;
19793 xassert (it
->what
== IT_IMAGE
);
19795 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19797 /* Make sure X resources of the face is loaded. */
19798 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
19800 if (it
->image_id
< 0)
19802 /* Fringe bitmap. */
19803 it
->ascent
= it
->phys_ascent
= 0;
19804 it
->descent
= it
->phys_descent
= 0;
19805 it
->pixel_width
= 0;
19810 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
19812 /* Make sure X resources of the image is loaded. */
19813 prepare_image_for_display (it
->f
, img
);
19815 slice
.x
= slice
.y
= 0;
19816 slice
.width
= img
->width
;
19817 slice
.height
= img
->height
;
19819 if (INTEGERP (it
->slice
.x
))
19820 slice
.x
= XINT (it
->slice
.x
);
19821 else if (FLOATP (it
->slice
.x
))
19822 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
19824 if (INTEGERP (it
->slice
.y
))
19825 slice
.y
= XINT (it
->slice
.y
);
19826 else if (FLOATP (it
->slice
.y
))
19827 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
19829 if (INTEGERP (it
->slice
.width
))
19830 slice
.width
= XINT (it
->slice
.width
);
19831 else if (FLOATP (it
->slice
.width
))
19832 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
19834 if (INTEGERP (it
->slice
.height
))
19835 slice
.height
= XINT (it
->slice
.height
);
19836 else if (FLOATP (it
->slice
.height
))
19837 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
19839 if (slice
.x
>= img
->width
)
19840 slice
.x
= img
->width
;
19841 if (slice
.y
>= img
->height
)
19842 slice
.y
= img
->height
;
19843 if (slice
.x
+ slice
.width
>= img
->width
)
19844 slice
.width
= img
->width
- slice
.x
;
19845 if (slice
.y
+ slice
.height
> img
->height
)
19846 slice
.height
= img
->height
- slice
.y
;
19848 if (slice
.width
== 0 || slice
.height
== 0)
19851 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
19853 it
->descent
= slice
.height
- glyph_ascent
;
19855 it
->descent
+= img
->vmargin
;
19856 if (slice
.y
+ slice
.height
== img
->height
)
19857 it
->descent
+= img
->vmargin
;
19858 it
->phys_descent
= it
->descent
;
19860 it
->pixel_width
= slice
.width
;
19862 it
->pixel_width
+= img
->hmargin
;
19863 if (slice
.x
+ slice
.width
== img
->width
)
19864 it
->pixel_width
+= img
->hmargin
;
19866 /* It's quite possible for images to have an ascent greater than
19867 their height, so don't get confused in that case. */
19868 if (it
->descent
< 0)
19871 #if 0 /* this breaks image tiling */
19872 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
19873 int face_ascent
= face
->font
? FONT_BASE (face
->font
) : FRAME_BASELINE_OFFSET (it
->f
);
19874 if (face_ascent
> it
->ascent
)
19875 it
->ascent
= it
->phys_ascent
= face_ascent
;
19880 if (face
->box
!= FACE_NO_BOX
)
19882 if (face
->box_line_width
> 0)
19885 it
->ascent
+= face
->box_line_width
;
19886 if (slice
.y
+ slice
.height
== img
->height
)
19887 it
->descent
+= face
->box_line_width
;
19890 if (it
->start_of_box_run_p
&& slice
.x
== 0)
19891 it
->pixel_width
+= abs (face
->box_line_width
);
19892 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
19893 it
->pixel_width
+= abs (face
->box_line_width
);
19896 take_vertical_position_into_account (it
);
19898 /* Automatically crop wide image glyphs at right edge so we can
19899 draw the cursor on same display row. */
19900 if ((crop
= it
->pixel_width
- (it
->last_visible_x
- it
->current_x
), crop
> 0)
19901 && (it
->hpos
== 0 || it
->pixel_width
> it
->last_visible_x
/ 4))
19903 it
->pixel_width
-= crop
;
19904 slice
.width
-= crop
;
19909 struct glyph
*glyph
;
19910 enum glyph_row_area area
= it
->area
;
19912 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
19913 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
19915 glyph
->charpos
= CHARPOS (it
->position
);
19916 glyph
->object
= it
->object
;
19917 glyph
->pixel_width
= it
->pixel_width
;
19918 glyph
->ascent
= glyph_ascent
;
19919 glyph
->descent
= it
->descent
;
19920 glyph
->voffset
= it
->voffset
;
19921 glyph
->type
= IMAGE_GLYPH
;
19922 glyph
->multibyte_p
= it
->multibyte_p
;
19923 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
19924 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
19925 glyph
->overlaps_vertically_p
= 0;
19926 glyph
->padding_p
= 0;
19927 glyph
->glyph_not_available_p
= 0;
19928 glyph
->face_id
= it
->face_id
;
19929 glyph
->u
.img_id
= img
->id
;
19930 glyph
->slice
= slice
;
19931 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
19932 ++it
->glyph_row
->used
[area
];
19935 IT_EXPAND_MATRIX_WIDTH (it
, area
);
19940 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
19941 of the glyph, WIDTH and HEIGHT are the width and height of the
19942 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
19945 append_stretch_glyph (it
, object
, width
, height
, ascent
)
19947 Lisp_Object object
;
19951 struct glyph
*glyph
;
19952 enum glyph_row_area area
= it
->area
;
19954 xassert (ascent
>= 0 && ascent
<= height
);
19956 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
19957 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
19959 glyph
->charpos
= CHARPOS (it
->position
);
19960 glyph
->object
= object
;
19961 glyph
->pixel_width
= width
;
19962 glyph
->ascent
= ascent
;
19963 glyph
->descent
= height
- ascent
;
19964 glyph
->voffset
= it
->voffset
;
19965 glyph
->type
= STRETCH_GLYPH
;
19966 glyph
->multibyte_p
= it
->multibyte_p
;
19967 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
19968 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
19969 glyph
->overlaps_vertically_p
= 0;
19970 glyph
->padding_p
= 0;
19971 glyph
->glyph_not_available_p
= 0;
19972 glyph
->face_id
= it
->face_id
;
19973 glyph
->u
.stretch
.ascent
= ascent
;
19974 glyph
->u
.stretch
.height
= height
;
19975 glyph
->slice
= null_glyph_slice
;
19976 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
19977 ++it
->glyph_row
->used
[area
];
19980 IT_EXPAND_MATRIX_WIDTH (it
, area
);
19984 /* Produce a stretch glyph for iterator IT. IT->object is the value
19985 of the glyph property displayed. The value must be a list
19986 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
19989 1. `:width WIDTH' specifies that the space should be WIDTH *
19990 canonical char width wide. WIDTH may be an integer or floating
19993 2. `:relative-width FACTOR' specifies that the width of the stretch
19994 should be computed from the width of the first character having the
19995 `glyph' property, and should be FACTOR times that width.
19997 3. `:align-to HPOS' specifies that the space should be wide enough
19998 to reach HPOS, a value in canonical character units.
20000 Exactly one of the above pairs must be present.
20002 4. `:height HEIGHT' specifies that the height of the stretch produced
20003 should be HEIGHT, measured in canonical character units.
20005 5. `:relative-height FACTOR' specifies that the height of the
20006 stretch should be FACTOR times the height of the characters having
20007 the glyph property.
20009 Either none or exactly one of 4 or 5 must be present.
20011 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20012 of the stretch should be used for the ascent of the stretch.
20013 ASCENT must be in the range 0 <= ASCENT <= 100. */
20016 produce_stretch_glyph (it
)
20019 /* (space :width WIDTH :height HEIGHT ...) */
20020 Lisp_Object prop
, plist
;
20021 int width
= 0, height
= 0, align_to
= -1;
20022 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
20025 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
20026 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
20028 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
20030 /* List should start with `space'. */
20031 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
20032 plist
= XCDR (it
->object
);
20034 /* Compute the width of the stretch. */
20035 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
20036 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
20038 /* Absolute width `:width WIDTH' specified and valid. */
20039 zero_width_ok_p
= 1;
20042 else if (prop
= Fplist_get (plist
, QCrelative_width
),
20045 /* Relative width `:relative-width FACTOR' specified and valid.
20046 Compute the width of the characters having the `glyph'
20049 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
20052 if (it
->multibyte_p
)
20054 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
20055 - IT_BYTEPOS (*it
));
20056 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
20059 it2
.c
= *p
, it2
.len
= 1;
20061 it2
.glyph_row
= NULL
;
20062 it2
.what
= IT_CHARACTER
;
20063 x_produce_glyphs (&it2
);
20064 width
= NUMVAL (prop
) * it2
.pixel_width
;
20066 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
20067 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
20069 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
20070 align_to
= (align_to
< 0
20072 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
20073 else if (align_to
< 0)
20074 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
20075 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
20076 zero_width_ok_p
= 1;
20079 /* Nothing specified -> width defaults to canonical char width. */
20080 width
= FRAME_COLUMN_WIDTH (it
->f
);
20082 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
20085 /* Compute height. */
20086 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
20087 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
20090 zero_height_ok_p
= 1;
20092 else if (prop
= Fplist_get (plist
, QCrelative_height
),
20094 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
20096 height
= FONT_HEIGHT (font
);
20098 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
20101 /* Compute percentage of height used for ascent. If
20102 `:ascent ASCENT' is present and valid, use that. Otherwise,
20103 derive the ascent from the font in use. */
20104 if (prop
= Fplist_get (plist
, QCascent
),
20105 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
20106 ascent
= height
* NUMVAL (prop
) / 100.0;
20107 else if (!NILP (prop
)
20108 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
20109 ascent
= min (max (0, (int)tem
), height
);
20111 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
20113 if (width
> 0 && !it
->truncate_lines_p
20114 && it
->current_x
+ width
> it
->last_visible_x
)
20115 width
= it
->last_visible_x
- it
->current_x
- 1;
20117 if (width
> 0 && height
> 0 && it
->glyph_row
)
20119 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
20120 if (!STRINGP (object
))
20121 object
= it
->w
->buffer
;
20122 append_stretch_glyph (it
, object
, width
, height
, ascent
);
20125 it
->pixel_width
= width
;
20126 it
->ascent
= it
->phys_ascent
= ascent
;
20127 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
20128 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
20130 take_vertical_position_into_account (it
);
20133 /* Get line-height and line-spacing property at point.
20134 If line-height has format (HEIGHT TOTAL), return TOTAL
20135 in TOTAL_HEIGHT. */
20138 get_line_height_property (it
, prop
)
20142 Lisp_Object position
;
20144 if (STRINGP (it
->object
))
20145 position
= make_number (IT_STRING_CHARPOS (*it
));
20146 else if (BUFFERP (it
->object
))
20147 position
= make_number (IT_CHARPOS (*it
));
20151 return Fget_char_property (position
, prop
, it
->object
);
20154 /* Calculate line-height and line-spacing properties.
20155 An integer value specifies explicit pixel value.
20156 A float value specifies relative value to current face height.
20157 A cons (float . face-name) specifies relative value to
20158 height of specified face font.
20160 Returns height in pixels, or nil. */
20164 calc_line_height_property (it
, val
, font
, boff
, override
)
20168 int boff
, override
;
20170 Lisp_Object face_name
= Qnil
;
20171 int ascent
, descent
, height
;
20173 if (NILP (val
) || INTEGERP (val
) || (override
&& EQ (val
, Qt
)))
20178 face_name
= XCAR (val
);
20180 if (!NUMBERP (val
))
20181 val
= make_number (1);
20182 if (NILP (face_name
))
20184 height
= it
->ascent
+ it
->descent
;
20189 if (NILP (face_name
))
20191 font
= FRAME_FONT (it
->f
);
20192 boff
= FRAME_BASELINE_OFFSET (it
->f
);
20194 else if (EQ (face_name
, Qt
))
20202 struct font_info
*font_info
;
20204 face_id
= lookup_named_face (it
->f
, face_name
, ' ', 0);
20206 return make_number (-1);
20208 face
= FACE_FROM_ID (it
->f
, face_id
);
20211 return make_number (-1);
20213 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
20214 boff
= font_info
->baseline_offset
;
20215 if (font_info
->vertical_centering
)
20216 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
20219 ascent
= FONT_BASE (font
) + boff
;
20220 descent
= FONT_DESCENT (font
) - boff
;
20224 it
->override_ascent
= ascent
;
20225 it
->override_descent
= descent
;
20226 it
->override_boff
= boff
;
20229 height
= ascent
+ descent
;
20233 height
= (int)(XFLOAT_DATA (val
) * height
);
20234 else if (INTEGERP (val
))
20235 height
*= XINT (val
);
20237 return make_number (height
);
20242 Produce glyphs/get display metrics for the display element IT is
20243 loaded with. See the description of struct it in dispextern.h
20244 for an overview of struct it. */
20247 x_produce_glyphs (it
)
20250 int extra_line_spacing
= it
->extra_line_spacing
;
20252 it
->glyph_not_available_p
= 0;
20254 if (it
->what
== IT_CHARACTER
)
20258 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
20260 int font_not_found_p
;
20261 struct font_info
*font_info
;
20262 int boff
; /* baseline offset */
20263 /* We may change it->multibyte_p upon unibyte<->multibyte
20264 conversion. So, save the current value now and restore it
20267 Note: It seems that we don't have to record multibyte_p in
20268 struct glyph because the character code itself tells if or
20269 not the character is multibyte. Thus, in the future, we must
20270 consider eliminating the field `multibyte_p' in the struct
20272 int saved_multibyte_p
= it
->multibyte_p
;
20274 /* Maybe translate single-byte characters to multibyte, or the
20276 it
->char_to_display
= it
->c
;
20277 if (!ASCII_BYTE_P (it
->c
))
20279 if (unibyte_display_via_language_environment
20280 && SINGLE_BYTE_CHAR_P (it
->c
)
20282 || !NILP (Vnonascii_translation_table
)))
20284 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
20285 it
->multibyte_p
= 1;
20286 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
20287 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
20289 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
20290 && !it
->multibyte_p
)
20292 it
->multibyte_p
= 1;
20293 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
20294 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
20298 /* Get font to use. Encode IT->char_to_display. */
20299 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
20300 &char2b
, it
->multibyte_p
, 0);
20303 /* When no suitable font found, use the default font. */
20304 font_not_found_p
= font
== NULL
;
20305 if (font_not_found_p
)
20307 font
= FRAME_FONT (it
->f
);
20308 boff
= FRAME_BASELINE_OFFSET (it
->f
);
20313 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
20314 boff
= font_info
->baseline_offset
;
20315 if (font_info
->vertical_centering
)
20316 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
20319 if (it
->char_to_display
>= ' '
20320 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
20322 /* Either unibyte or ASCII. */
20327 pcm
= rif
->per_char_metric (font
, &char2b
,
20328 FONT_TYPE_FOR_UNIBYTE (font
, it
->char_to_display
));
20330 if (it
->override_ascent
>= 0)
20332 it
->ascent
= it
->override_ascent
;
20333 it
->descent
= it
->override_descent
;
20334 boff
= it
->override_boff
;
20338 it
->ascent
= FONT_BASE (font
) + boff
;
20339 it
->descent
= FONT_DESCENT (font
) - boff
;
20344 it
->phys_ascent
= pcm
->ascent
+ boff
;
20345 it
->phys_descent
= pcm
->descent
- boff
;
20346 it
->pixel_width
= pcm
->width
;
20350 it
->glyph_not_available_p
= 1;
20351 it
->phys_ascent
= it
->ascent
;
20352 it
->phys_descent
= it
->descent
;
20353 it
->pixel_width
= FONT_WIDTH (font
);
20356 if (it
->constrain_row_ascent_descent_p
)
20358 if (it
->descent
> it
->max_descent
)
20360 it
->ascent
+= it
->descent
- it
->max_descent
;
20361 it
->descent
= it
->max_descent
;
20363 if (it
->ascent
> it
->max_ascent
)
20365 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
20366 it
->ascent
= it
->max_ascent
;
20368 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
20369 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
20370 extra_line_spacing
= 0;
20373 /* If this is a space inside a region of text with
20374 `space-width' property, change its width. */
20375 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
20377 it
->pixel_width
*= XFLOATINT (it
->space_width
);
20379 /* If face has a box, add the box thickness to the character
20380 height. If character has a box line to the left and/or
20381 right, add the box line width to the character's width. */
20382 if (face
->box
!= FACE_NO_BOX
)
20384 int thick
= face
->box_line_width
;
20388 it
->ascent
+= thick
;
20389 it
->descent
+= thick
;
20394 if (it
->start_of_box_run_p
)
20395 it
->pixel_width
+= thick
;
20396 if (it
->end_of_box_run_p
)
20397 it
->pixel_width
+= thick
;
20400 /* If face has an overline, add the height of the overline
20401 (1 pixel) and a 1 pixel margin to the character height. */
20402 if (face
->overline_p
)
20403 it
->ascent
+= overline_margin
;
20405 if (it
->constrain_row_ascent_descent_p
)
20407 if (it
->ascent
> it
->max_ascent
)
20408 it
->ascent
= it
->max_ascent
;
20409 if (it
->descent
> it
->max_descent
)
20410 it
->descent
= it
->max_descent
;
20413 take_vertical_position_into_account (it
);
20415 /* If we have to actually produce glyphs, do it. */
20420 /* Translate a space with a `space-width' property
20421 into a stretch glyph. */
20422 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
20423 / FONT_HEIGHT (font
));
20424 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
20425 it
->ascent
+ it
->descent
, ascent
);
20430 /* If characters with lbearing or rbearing are displayed
20431 in this line, record that fact in a flag of the
20432 glyph row. This is used to optimize X output code. */
20433 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
20434 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
20437 else if (it
->char_to_display
== '\n')
20439 /* A newline has no width but we need the height of the line.
20440 But if previous part of the line set a height, don't
20441 increase that height */
20443 Lisp_Object height
;
20444 Lisp_Object total_height
= Qnil
;
20446 it
->override_ascent
= -1;
20447 it
->pixel_width
= 0;
20450 height
= get_line_height_property(it
, Qline_height
);
20451 /* Split (line-height total-height) list */
20453 && CONSP (XCDR (height
))
20454 && NILP (XCDR (XCDR (height
))))
20456 total_height
= XCAR (XCDR (height
));
20457 height
= XCAR (height
);
20459 height
= calc_line_height_property(it
, height
, font
, boff
, 1);
20461 if (it
->override_ascent
>= 0)
20463 it
->ascent
= it
->override_ascent
;
20464 it
->descent
= it
->override_descent
;
20465 boff
= it
->override_boff
;
20469 it
->ascent
= FONT_BASE (font
) + boff
;
20470 it
->descent
= FONT_DESCENT (font
) - boff
;
20473 if (EQ (height
, Qt
))
20475 if (it
->descent
> it
->max_descent
)
20477 it
->ascent
+= it
->descent
- it
->max_descent
;
20478 it
->descent
= it
->max_descent
;
20480 if (it
->ascent
> it
->max_ascent
)
20482 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
20483 it
->ascent
= it
->max_ascent
;
20485 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
20486 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
20487 it
->constrain_row_ascent_descent_p
= 1;
20488 extra_line_spacing
= 0;
20492 Lisp_Object spacing
;
20494 it
->phys_ascent
= it
->ascent
;
20495 it
->phys_descent
= it
->descent
;
20497 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
20498 && face
->box
!= FACE_NO_BOX
20499 && face
->box_line_width
> 0)
20501 it
->ascent
+= face
->box_line_width
;
20502 it
->descent
+= face
->box_line_width
;
20505 && XINT (height
) > it
->ascent
+ it
->descent
)
20506 it
->ascent
= XINT (height
) - it
->descent
;
20508 if (!NILP (total_height
))
20509 spacing
= calc_line_height_property(it
, total_height
, font
, boff
, 0);
20512 spacing
= get_line_height_property(it
, Qline_spacing
);
20513 spacing
= calc_line_height_property(it
, spacing
, font
, boff
, 0);
20515 if (INTEGERP (spacing
))
20517 extra_line_spacing
= XINT (spacing
);
20518 if (!NILP (total_height
))
20519 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
20523 else if (it
->char_to_display
== '\t')
20525 int tab_width
= it
->tab_width
* FRAME_SPACE_WIDTH (it
->f
);
20526 int x
= it
->current_x
+ it
->continuation_lines_width
;
20527 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
20529 /* If the distance from the current position to the next tab
20530 stop is less than a space character width, use the
20531 tab stop after that. */
20532 if (next_tab_x
- x
< FRAME_SPACE_WIDTH (it
->f
))
20533 next_tab_x
+= tab_width
;
20535 it
->pixel_width
= next_tab_x
- x
;
20537 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
20538 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
20542 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
20543 it
->ascent
+ it
->descent
, it
->ascent
);
20548 /* A multi-byte character. Assume that the display width of the
20549 character is the width of the character multiplied by the
20550 width of the font. */
20552 /* If we found a font, this font should give us the right
20553 metrics. If we didn't find a font, use the frame's
20554 default font and calculate the width of the character
20555 from the charset width; this is what old redisplay code
20558 pcm
= rif
->per_char_metric (font
, &char2b
,
20559 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
));
20561 if (font_not_found_p
|| !pcm
)
20563 int charset
= CHAR_CHARSET (it
->char_to_display
);
20565 it
->glyph_not_available_p
= 1;
20566 it
->pixel_width
= (FRAME_COLUMN_WIDTH (it
->f
)
20567 * CHARSET_WIDTH (charset
));
20568 it
->phys_ascent
= FONT_BASE (font
) + boff
;
20569 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
20573 it
->pixel_width
= pcm
->width
;
20574 it
->phys_ascent
= pcm
->ascent
+ boff
;
20575 it
->phys_descent
= pcm
->descent
- boff
;
20577 && (pcm
->lbearing
< 0
20578 || pcm
->rbearing
> pcm
->width
))
20579 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
20582 it
->ascent
= FONT_BASE (font
) + boff
;
20583 it
->descent
= FONT_DESCENT (font
) - boff
;
20584 if (face
->box
!= FACE_NO_BOX
)
20586 int thick
= face
->box_line_width
;
20590 it
->ascent
+= thick
;
20591 it
->descent
+= thick
;
20596 if (it
->start_of_box_run_p
)
20597 it
->pixel_width
+= thick
;
20598 if (it
->end_of_box_run_p
)
20599 it
->pixel_width
+= thick
;
20602 /* If face has an overline, add the height of the overline
20603 (1 pixel) and a 1 pixel margin to the character height. */
20604 if (face
->overline_p
)
20605 it
->ascent
+= overline_margin
;
20607 take_vertical_position_into_account (it
);
20612 it
->multibyte_p
= saved_multibyte_p
;
20614 else if (it
->what
== IT_COMPOSITION
)
20616 /* Note: A composition is represented as one glyph in the
20617 glyph matrix. There are no padding glyphs. */
20620 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
20622 int font_not_found_p
;
20623 struct font_info
*font_info
;
20624 int boff
; /* baseline offset */
20625 struct composition
*cmp
= composition_table
[it
->cmp_id
];
20627 /* Maybe translate single-byte characters to multibyte. */
20628 it
->char_to_display
= it
->c
;
20629 if (unibyte_display_via_language_environment
20630 && SINGLE_BYTE_CHAR_P (it
->c
)
20633 && !NILP (Vnonascii_translation_table
))))
20635 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
20638 /* Get face and font to use. Encode IT->char_to_display. */
20639 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
20640 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
20641 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
20642 &char2b
, it
->multibyte_p
, 0);
20645 /* When no suitable font found, use the default font. */
20646 font_not_found_p
= font
== NULL
;
20647 if (font_not_found_p
)
20649 font
= FRAME_FONT (it
->f
);
20650 boff
= FRAME_BASELINE_OFFSET (it
->f
);
20655 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
20656 boff
= font_info
->baseline_offset
;
20657 if (font_info
->vertical_centering
)
20658 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
20661 /* There are no padding glyphs, so there is only one glyph to
20662 produce for the composition. Important is that pixel_width,
20663 ascent and descent are the values of what is drawn by
20664 draw_glyphs (i.e. the values of the overall glyphs composed). */
20667 /* If we have not yet calculated pixel size data of glyphs of
20668 the composition for the current face font, calculate them
20669 now. Theoretically, we have to check all fonts for the
20670 glyphs, but that requires much time and memory space. So,
20671 here we check only the font of the first glyph. This leads
20672 to incorrect display very rarely, and C-l (recenter) can
20673 correct the display anyway. */
20674 if (cmp
->font
!= (void *) font
)
20676 /* Ascent and descent of the font of the first character of
20677 this composition (adjusted by baseline offset). Ascent
20678 and descent of overall glyphs should not be less than
20679 them respectively. */
20680 int font_ascent
= FONT_BASE (font
) + boff
;
20681 int font_descent
= FONT_DESCENT (font
) - boff
;
20682 /* Bounding box of the overall glyphs. */
20683 int leftmost
, rightmost
, lowest
, highest
;
20684 int i
, width
, ascent
, descent
;
20686 cmp
->font
= (void *) font
;
20688 /* Initialize the bounding box. */
20690 && (pcm
= rif
->per_char_metric (font
, &char2b
,
20691 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
))))
20693 width
= pcm
->width
;
20694 ascent
= pcm
->ascent
;
20695 descent
= pcm
->descent
;
20699 width
= FONT_WIDTH (font
);
20700 ascent
= FONT_BASE (font
);
20701 descent
= FONT_DESCENT (font
);
20705 lowest
= - descent
+ boff
;
20706 highest
= ascent
+ boff
;
20710 && font_info
->default_ascent
20711 && CHAR_TABLE_P (Vuse_default_ascent
)
20712 && !NILP (Faref (Vuse_default_ascent
,
20713 make_number (it
->char_to_display
))))
20714 highest
= font_info
->default_ascent
+ boff
;
20716 /* Draw the first glyph at the normal position. It may be
20717 shifted to right later if some other glyphs are drawn at
20719 cmp
->offsets
[0] = 0;
20720 cmp
->offsets
[1] = boff
;
20722 /* Set cmp->offsets for the remaining glyphs. */
20723 for (i
= 1; i
< cmp
->glyph_len
; i
++)
20725 int left
, right
, btm
, top
;
20726 int ch
= COMPOSITION_GLYPH (cmp
, i
);
20727 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
20729 face
= FACE_FROM_ID (it
->f
, face_id
);
20730 get_char_face_and_encoding (it
->f
, ch
, face
->id
,
20731 &char2b
, it
->multibyte_p
, 0);
20735 font
= FRAME_FONT (it
->f
);
20736 boff
= FRAME_BASELINE_OFFSET (it
->f
);
20742 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
20743 boff
= font_info
->baseline_offset
;
20744 if (font_info
->vertical_centering
)
20745 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
20749 && (pcm
= rif
->per_char_metric (font
, &char2b
,
20750 FONT_TYPE_FOR_MULTIBYTE (font
, ch
))))
20752 width
= pcm
->width
;
20753 ascent
= pcm
->ascent
;
20754 descent
= pcm
->descent
;
20758 width
= FONT_WIDTH (font
);
20763 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
20765 /* Relative composition with or without
20766 alternate chars. */
20767 left
= (leftmost
+ rightmost
- width
) / 2;
20768 btm
= - descent
+ boff
;
20769 if (font_info
&& font_info
->relative_compose
20770 && (! CHAR_TABLE_P (Vignore_relative_composition
)
20771 || NILP (Faref (Vignore_relative_composition
,
20772 make_number (ch
)))))
20775 if (- descent
>= font_info
->relative_compose
)
20776 /* One extra pixel between two glyphs. */
20778 else if (ascent
<= 0)
20779 /* One extra pixel between two glyphs. */
20780 btm
= lowest
- 1 - ascent
- descent
;
20785 /* A composition rule is specified by an integer
20786 value that encodes global and new reference
20787 points (GREF and NREF). GREF and NREF are
20788 specified by numbers as below:
20790 0---1---2 -- ascent
20794 9--10--11 -- center
20796 ---3---4---5--- baseline
20798 6---7---8 -- descent
20800 int rule
= COMPOSITION_RULE (cmp
, i
);
20801 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
20803 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
20804 grefx
= gref
% 3, nrefx
= nref
% 3;
20805 grefy
= gref
/ 3, nrefy
= nref
/ 3;
20808 + grefx
* (rightmost
- leftmost
) / 2
20809 - nrefx
* width
/ 2);
20810 btm
= ((grefy
== 0 ? highest
20812 : grefy
== 2 ? lowest
20813 : (highest
+ lowest
) / 2)
20814 - (nrefy
== 0 ? ascent
+ descent
20815 : nrefy
== 1 ? descent
- boff
20817 : (ascent
+ descent
) / 2));
20820 cmp
->offsets
[i
* 2] = left
;
20821 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
20823 /* Update the bounding box of the overall glyphs. */
20824 right
= left
+ width
;
20825 top
= btm
+ descent
+ ascent
;
20826 if (left
< leftmost
)
20828 if (right
> rightmost
)
20836 /* If there are glyphs whose x-offsets are negative,
20837 shift all glyphs to the right and make all x-offsets
20841 for (i
= 0; i
< cmp
->glyph_len
; i
++)
20842 cmp
->offsets
[i
* 2] -= leftmost
;
20843 rightmost
-= leftmost
;
20846 cmp
->pixel_width
= rightmost
;
20847 cmp
->ascent
= highest
;
20848 cmp
->descent
= - lowest
;
20849 if (cmp
->ascent
< font_ascent
)
20850 cmp
->ascent
= font_ascent
;
20851 if (cmp
->descent
< font_descent
)
20852 cmp
->descent
= font_descent
;
20855 it
->pixel_width
= cmp
->pixel_width
;
20856 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
20857 it
->descent
= it
->phys_descent
= cmp
->descent
;
20859 if (face
->box
!= FACE_NO_BOX
)
20861 int thick
= face
->box_line_width
;
20865 it
->ascent
+= thick
;
20866 it
->descent
+= thick
;
20871 if (it
->start_of_box_run_p
)
20872 it
->pixel_width
+= thick
;
20873 if (it
->end_of_box_run_p
)
20874 it
->pixel_width
+= thick
;
20877 /* If face has an overline, add the height of the overline
20878 (1 pixel) and a 1 pixel margin to the character height. */
20879 if (face
->overline_p
)
20880 it
->ascent
+= overline_margin
;
20882 take_vertical_position_into_account (it
);
20885 append_composite_glyph (it
);
20887 else if (it
->what
== IT_IMAGE
)
20888 produce_image_glyph (it
);
20889 else if (it
->what
== IT_STRETCH
)
20890 produce_stretch_glyph (it
);
20892 /* Accumulate dimensions. Note: can't assume that it->descent > 0
20893 because this isn't true for images with `:ascent 100'. */
20894 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
20895 if (it
->area
== TEXT_AREA
)
20896 it
->current_x
+= it
->pixel_width
;
20898 if (extra_line_spacing
> 0)
20900 it
->descent
+= extra_line_spacing
;
20901 if (extra_line_spacing
> it
->max_extra_line_spacing
)
20902 it
->max_extra_line_spacing
= extra_line_spacing
;
20905 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
20906 it
->max_descent
= max (it
->max_descent
, it
->descent
);
20907 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
20908 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
20912 Output LEN glyphs starting at START at the nominal cursor position.
20913 Advance the nominal cursor over the text. The global variable
20914 updated_window contains the window being updated, updated_row is
20915 the glyph row being updated, and updated_area is the area of that
20916 row being updated. */
20919 x_write_glyphs (start
, len
)
20920 struct glyph
*start
;
20925 xassert (updated_window
&& updated_row
);
20928 /* Write glyphs. */
20930 hpos
= start
- updated_row
->glyphs
[updated_area
];
20931 x
= draw_glyphs (updated_window
, output_cursor
.x
,
20932 updated_row
, updated_area
,
20934 DRAW_NORMAL_TEXT
, 0);
20936 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
20937 if (updated_area
== TEXT_AREA
20938 && updated_window
->phys_cursor_on_p
20939 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
20940 && updated_window
->phys_cursor
.hpos
>= hpos
20941 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
20942 updated_window
->phys_cursor_on_p
= 0;
20946 /* Advance the output cursor. */
20947 output_cursor
.hpos
+= len
;
20948 output_cursor
.x
= x
;
20953 Insert LEN glyphs from START at the nominal cursor position. */
20956 x_insert_glyphs (start
, len
)
20957 struct glyph
*start
;
20962 int line_height
, shift_by_width
, shifted_region_width
;
20963 struct glyph_row
*row
;
20964 struct glyph
*glyph
;
20965 int frame_x
, frame_y
, hpos
;
20967 xassert (updated_window
&& updated_row
);
20969 w
= updated_window
;
20970 f
= XFRAME (WINDOW_FRAME (w
));
20972 /* Get the height of the line we are in. */
20974 line_height
= row
->height
;
20976 /* Get the width of the glyphs to insert. */
20977 shift_by_width
= 0;
20978 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
20979 shift_by_width
+= glyph
->pixel_width
;
20981 /* Get the width of the region to shift right. */
20982 shifted_region_width
= (window_box_width (w
, updated_area
)
20987 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
20988 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
20990 rif
->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
20991 line_height
, shift_by_width
);
20993 /* Write the glyphs. */
20994 hpos
= start
- row
->glyphs
[updated_area
];
20995 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
20997 DRAW_NORMAL_TEXT
, 0);
20999 /* Advance the output cursor. */
21000 output_cursor
.hpos
+= len
;
21001 output_cursor
.x
+= shift_by_width
;
21007 Erase the current text line from the nominal cursor position
21008 (inclusive) to pixel column TO_X (exclusive). The idea is that
21009 everything from TO_X onward is already erased.
21011 TO_X is a pixel position relative to updated_area of
21012 updated_window. TO_X == -1 means clear to the end of this area. */
21015 x_clear_end_of_line (to_x
)
21019 struct window
*w
= updated_window
;
21020 int max_x
, min_y
, max_y
;
21021 int from_x
, from_y
, to_y
;
21023 xassert (updated_window
&& updated_row
);
21024 f
= XFRAME (w
->frame
);
21026 if (updated_row
->full_width_p
)
21027 max_x
= WINDOW_TOTAL_WIDTH (w
);
21029 max_x
= window_box_width (w
, updated_area
);
21030 max_y
= window_text_bottom_y (w
);
21032 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21033 of window. For TO_X > 0, truncate to end of drawing area. */
21039 to_x
= min (to_x
, max_x
);
21041 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
21043 /* Notice if the cursor will be cleared by this operation. */
21044 if (!updated_row
->full_width_p
)
21045 notice_overwritten_cursor (w
, updated_area
,
21046 output_cursor
.x
, -1,
21048 MATRIX_ROW_BOTTOM_Y (updated_row
));
21050 from_x
= output_cursor
.x
;
21052 /* Translate to frame coordinates. */
21053 if (updated_row
->full_width_p
)
21055 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
21056 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
21060 int area_left
= window_box_left (w
, updated_area
);
21061 from_x
+= area_left
;
21065 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
21066 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
21067 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
21069 /* Prevent inadvertently clearing to end of the X window. */
21070 if (to_x
> from_x
&& to_y
> from_y
)
21073 rif
->clear_frame_area (f
, from_x
, from_y
,
21074 to_x
- from_x
, to_y
- from_y
);
21079 #endif /* HAVE_WINDOW_SYSTEM */
21083 /***********************************************************************
21085 ***********************************************************************/
21087 /* Value is the internal representation of the specified cursor type
21088 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
21089 of the bar cursor. */
21091 static enum text_cursor_kinds
21092 get_specified_cursor_type (arg
, width
)
21096 enum text_cursor_kinds type
;
21101 if (EQ (arg
, Qbox
))
21102 return FILLED_BOX_CURSOR
;
21104 if (EQ (arg
, Qhollow
))
21105 return HOLLOW_BOX_CURSOR
;
21107 if (EQ (arg
, Qbar
))
21114 && EQ (XCAR (arg
), Qbar
)
21115 && INTEGERP (XCDR (arg
))
21116 && XINT (XCDR (arg
)) >= 0)
21118 *width
= XINT (XCDR (arg
));
21122 if (EQ (arg
, Qhbar
))
21125 return HBAR_CURSOR
;
21129 && EQ (XCAR (arg
), Qhbar
)
21130 && INTEGERP (XCDR (arg
))
21131 && XINT (XCDR (arg
)) >= 0)
21133 *width
= XINT (XCDR (arg
));
21134 return HBAR_CURSOR
;
21137 /* Treat anything unknown as "hollow box cursor".
21138 It was bad to signal an error; people have trouble fixing
21139 .Xdefaults with Emacs, when it has something bad in it. */
21140 type
= HOLLOW_BOX_CURSOR
;
21145 /* Set the default cursor types for specified frame. */
21147 set_frame_cursor_types (f
, arg
)
21154 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
21155 FRAME_CURSOR_WIDTH (f
) = width
;
21157 /* By default, set up the blink-off state depending on the on-state. */
21159 tem
= Fassoc (arg
, Vblink_cursor_alist
);
21162 FRAME_BLINK_OFF_CURSOR (f
)
21163 = get_specified_cursor_type (XCDR (tem
), &width
);
21164 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
21167 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
21171 /* Return the cursor we want to be displayed in window W. Return
21172 width of bar/hbar cursor through WIDTH arg. Return with
21173 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
21174 (i.e. if the `system caret' should track this cursor).
21176 In a mini-buffer window, we want the cursor only to appear if we
21177 are reading input from this window. For the selected window, we
21178 want the cursor type given by the frame parameter or buffer local
21179 setting of cursor-type. If explicitly marked off, draw no cursor.
21180 In all other cases, we want a hollow box cursor. */
21182 static enum text_cursor_kinds
21183 get_window_cursor_type (w
, glyph
, width
, active_cursor
)
21185 struct glyph
*glyph
;
21187 int *active_cursor
;
21189 struct frame
*f
= XFRAME (w
->frame
);
21190 struct buffer
*b
= XBUFFER (w
->buffer
);
21191 int cursor_type
= DEFAULT_CURSOR
;
21192 Lisp_Object alt_cursor
;
21193 int non_selected
= 0;
21195 *active_cursor
= 1;
21198 if (cursor_in_echo_area
21199 && FRAME_HAS_MINIBUF_P (f
)
21200 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
21202 if (w
== XWINDOW (echo_area_window
))
21204 if (EQ (b
->cursor_type
, Qt
) || NILP (b
->cursor_type
))
21206 *width
= FRAME_CURSOR_WIDTH (f
);
21207 return FRAME_DESIRED_CURSOR (f
);
21210 return get_specified_cursor_type (b
->cursor_type
, width
);
21213 *active_cursor
= 0;
21217 /* Nonselected window or nonselected frame. */
21218 else if (w
!= XWINDOW (f
->selected_window
)
21219 #ifdef HAVE_WINDOW_SYSTEM
21220 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
21224 *active_cursor
= 0;
21226 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
21232 /* Never display a cursor in a window in which cursor-type is nil. */
21233 if (NILP (b
->cursor_type
))
21236 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
21239 alt_cursor
= b
->cursor_in_non_selected_windows
;
21240 return get_specified_cursor_type (alt_cursor
, width
);
21243 /* Get the normal cursor type for this window. */
21244 if (EQ (b
->cursor_type
, Qt
))
21246 cursor_type
= FRAME_DESIRED_CURSOR (f
);
21247 *width
= FRAME_CURSOR_WIDTH (f
);
21250 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
21252 /* Use normal cursor if not blinked off. */
21253 if (!w
->cursor_off_p
)
21255 #ifdef HAVE_WINDOW_SYSTEM
21256 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
21258 if (cursor_type
== FILLED_BOX_CURSOR
)
21260 /* Using a block cursor on large images can be very annoying.
21261 So use a hollow cursor for "large" images.
21262 If image is not transparent (no mask), also use hollow cursor. */
21263 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
21264 if (img
!= NULL
&& IMAGEP (img
->spec
))
21266 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
21267 where N = size of default frame font size.
21268 This should cover most of the "tiny" icons people may use. */
21270 || img
->width
> max (32, WINDOW_FRAME_COLUMN_WIDTH (w
))
21271 || img
->height
> max (32, WINDOW_FRAME_LINE_HEIGHT (w
)))
21272 cursor_type
= HOLLOW_BOX_CURSOR
;
21275 else if (cursor_type
!= NO_CURSOR
)
21277 /* Display current only supports BOX and HOLLOW cursors for images.
21278 So for now, unconditionally use a HOLLOW cursor when cursor is
21279 not a solid box cursor. */
21280 cursor_type
= HOLLOW_BOX_CURSOR
;
21284 return cursor_type
;
21287 /* Cursor is blinked off, so determine how to "toggle" it. */
21289 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
21290 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
21291 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
21293 /* Then see if frame has specified a specific blink off cursor type. */
21294 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
21296 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
21297 return FRAME_BLINK_OFF_CURSOR (f
);
21301 /* Some people liked having a permanently visible blinking cursor,
21302 while others had very strong opinions against it. So it was
21303 decided to remove it. KFS 2003-09-03 */
21305 /* Finally perform built-in cursor blinking:
21306 filled box <-> hollow box
21307 wide [h]bar <-> narrow [h]bar
21308 narrow [h]bar <-> no cursor
21309 other type <-> no cursor */
21311 if (cursor_type
== FILLED_BOX_CURSOR
)
21312 return HOLLOW_BOX_CURSOR
;
21314 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
21317 return cursor_type
;
21325 #ifdef HAVE_WINDOW_SYSTEM
21327 /* Notice when the text cursor of window W has been completely
21328 overwritten by a drawing operation that outputs glyphs in AREA
21329 starting at X0 and ending at X1 in the line starting at Y0 and
21330 ending at Y1. X coordinates are area-relative. X1 < 0 means all
21331 the rest of the line after X0 has been written. Y coordinates
21332 are window-relative. */
21335 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
21337 enum glyph_row_area area
;
21338 int x0
, y0
, x1
, y1
;
21340 int cx0
, cx1
, cy0
, cy1
;
21341 struct glyph_row
*row
;
21343 if (!w
->phys_cursor_on_p
)
21345 if (area
!= TEXT_AREA
)
21348 if (w
->phys_cursor
.vpos
< 0
21349 || w
->phys_cursor
.vpos
>= w
->current_matrix
->nrows
21350 || (row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
,
21351 !(row
->enabled_p
&& row
->displays_text_p
)))
21354 if (row
->cursor_in_fringe_p
)
21356 row
->cursor_in_fringe_p
= 0;
21357 draw_fringe_bitmap (w
, row
, 0);
21358 w
->phys_cursor_on_p
= 0;
21362 cx0
= w
->phys_cursor
.x
;
21363 cx1
= cx0
+ w
->phys_cursor_width
;
21364 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
21367 /* The cursor image will be completely removed from the
21368 screen if the output area intersects the cursor area in
21369 y-direction. When we draw in [y0 y1[, and some part of
21370 the cursor is at y < y0, that part must have been drawn
21371 before. When scrolling, the cursor is erased before
21372 actually scrolling, so we don't come here. When not
21373 scrolling, the rows above the old cursor row must have
21374 changed, and in this case these rows must have written
21375 over the cursor image.
21377 Likewise if part of the cursor is below y1, with the
21378 exception of the cursor being in the first blank row at
21379 the buffer and window end because update_text_area
21380 doesn't draw that row. (Except when it does, but
21381 that's handled in update_text_area.) */
21383 cy0
= w
->phys_cursor
.y
;
21384 cy1
= cy0
+ w
->phys_cursor_height
;
21385 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
21388 w
->phys_cursor_on_p
= 0;
21391 #endif /* HAVE_WINDOW_SYSTEM */
21394 /************************************************************************
21396 ************************************************************************/
21398 #ifdef HAVE_WINDOW_SYSTEM
21401 Fix the display of area AREA of overlapping row ROW in window W
21402 with respect to the overlapping part OVERLAPS. */
21405 x_fix_overlapping_area (w
, row
, area
, overlaps
)
21407 struct glyph_row
*row
;
21408 enum glyph_row_area area
;
21416 for (i
= 0; i
< row
->used
[area
];)
21418 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
21420 int start
= i
, start_x
= x
;
21424 x
+= row
->glyphs
[area
][i
].pixel_width
;
21427 while (i
< row
->used
[area
]
21428 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
21430 draw_glyphs (w
, start_x
, row
, area
,
21432 DRAW_NORMAL_TEXT
, overlaps
);
21436 x
+= row
->glyphs
[area
][i
].pixel_width
;
21446 Draw the cursor glyph of window W in glyph row ROW. See the
21447 comment of draw_glyphs for the meaning of HL. */
21450 draw_phys_cursor_glyph (w
, row
, hl
)
21452 struct glyph_row
*row
;
21453 enum draw_glyphs_face hl
;
21455 /* If cursor hpos is out of bounds, don't draw garbage. This can
21456 happen in mini-buffer windows when switching between echo area
21457 glyphs and mini-buffer. */
21458 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
21460 int on_p
= w
->phys_cursor_on_p
;
21462 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
21463 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
21465 w
->phys_cursor_on_p
= on_p
;
21467 if (hl
== DRAW_CURSOR
)
21468 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
21469 /* When we erase the cursor, and ROW is overlapped by other
21470 rows, make sure that these overlapping parts of other rows
21472 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
21474 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
21476 if (row
> w
->current_matrix
->rows
21477 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
21478 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
,
21479 OVERLAPS_ERASED_CURSOR
);
21481 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
21482 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
21483 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
,
21484 OVERLAPS_ERASED_CURSOR
);
21491 Erase the image of a cursor of window W from the screen. */
21494 erase_phys_cursor (w
)
21497 struct frame
*f
= XFRAME (w
->frame
);
21498 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21499 int hpos
= w
->phys_cursor
.hpos
;
21500 int vpos
= w
->phys_cursor
.vpos
;
21501 int mouse_face_here_p
= 0;
21502 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
21503 struct glyph_row
*cursor_row
;
21504 struct glyph
*cursor_glyph
;
21505 enum draw_glyphs_face hl
;
21507 /* No cursor displayed or row invalidated => nothing to do on the
21509 if (w
->phys_cursor_type
== NO_CURSOR
)
21510 goto mark_cursor_off
;
21512 /* VPOS >= active_glyphs->nrows means that window has been resized.
21513 Don't bother to erase the cursor. */
21514 if (vpos
>= active_glyphs
->nrows
)
21515 goto mark_cursor_off
;
21517 /* If row containing cursor is marked invalid, there is nothing we
21519 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
21520 if (!cursor_row
->enabled_p
)
21521 goto mark_cursor_off
;
21523 /* If line spacing is > 0, old cursor may only be partially visible in
21524 window after split-window. So adjust visible height. */
21525 cursor_row
->visible_height
= min (cursor_row
->visible_height
,
21526 window_text_bottom_y (w
) - cursor_row
->y
);
21528 /* If row is completely invisible, don't attempt to delete a cursor which
21529 isn't there. This can happen if cursor is at top of a window, and
21530 we switch to a buffer with a header line in that window. */
21531 if (cursor_row
->visible_height
<= 0)
21532 goto mark_cursor_off
;
21534 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
21535 if (cursor_row
->cursor_in_fringe_p
)
21537 cursor_row
->cursor_in_fringe_p
= 0;
21538 draw_fringe_bitmap (w
, cursor_row
, 0);
21539 goto mark_cursor_off
;
21542 /* This can happen when the new row is shorter than the old one.
21543 In this case, either draw_glyphs or clear_end_of_line
21544 should have cleared the cursor. Note that we wouldn't be
21545 able to erase the cursor in this case because we don't have a
21546 cursor glyph at hand. */
21547 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
21548 goto mark_cursor_off
;
21550 /* If the cursor is in the mouse face area, redisplay that when
21551 we clear the cursor. */
21552 if (! NILP (dpyinfo
->mouse_face_window
)
21553 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
21554 && (vpos
> dpyinfo
->mouse_face_beg_row
21555 || (vpos
== dpyinfo
->mouse_face_beg_row
21556 && hpos
>= dpyinfo
->mouse_face_beg_col
))
21557 && (vpos
< dpyinfo
->mouse_face_end_row
21558 || (vpos
== dpyinfo
->mouse_face_end_row
21559 && hpos
< dpyinfo
->mouse_face_end_col
))
21560 /* Don't redraw the cursor's spot in mouse face if it is at the
21561 end of a line (on a newline). The cursor appears there, but
21562 mouse highlighting does not. */
21563 && cursor_row
->used
[TEXT_AREA
] > hpos
)
21564 mouse_face_here_p
= 1;
21566 /* Maybe clear the display under the cursor. */
21567 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
21570 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
21573 cursor_glyph
= get_phys_cursor_glyph (w
);
21574 if (cursor_glyph
== NULL
)
21575 goto mark_cursor_off
;
21577 width
= cursor_glyph
->pixel_width
;
21578 left_x
= window_box_left_offset (w
, TEXT_AREA
);
21579 x
= w
->phys_cursor
.x
;
21581 width
-= left_x
- x
;
21582 width
= min (width
, window_box_width (w
, TEXT_AREA
) - x
);
21583 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
21584 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, max (x
, left_x
));
21587 rif
->clear_frame_area (f
, x
, y
, width
, cursor_row
->visible_height
);
21590 /* Erase the cursor by redrawing the character underneath it. */
21591 if (mouse_face_here_p
)
21592 hl
= DRAW_MOUSE_FACE
;
21594 hl
= DRAW_NORMAL_TEXT
;
21595 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
21598 w
->phys_cursor_on_p
= 0;
21599 w
->phys_cursor_type
= NO_CURSOR
;
21604 Display or clear cursor of window W. If ON is zero, clear the
21605 cursor. If it is non-zero, display the cursor. If ON is nonzero,
21606 where to put the cursor is specified by HPOS, VPOS, X and Y. */
21609 display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
21611 int on
, hpos
, vpos
, x
, y
;
21613 struct frame
*f
= XFRAME (w
->frame
);
21614 int new_cursor_type
;
21615 int new_cursor_width
;
21617 struct glyph_row
*glyph_row
;
21618 struct glyph
*glyph
;
21620 /* This is pointless on invisible frames, and dangerous on garbaged
21621 windows and frames; in the latter case, the frame or window may
21622 be in the midst of changing its size, and x and y may be off the
21624 if (! FRAME_VISIBLE_P (f
)
21625 || FRAME_GARBAGED_P (f
)
21626 || vpos
>= w
->current_matrix
->nrows
21627 || hpos
>= w
->current_matrix
->matrix_w
)
21630 /* If cursor is off and we want it off, return quickly. */
21631 if (!on
&& !w
->phys_cursor_on_p
)
21634 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
21635 /* If cursor row is not enabled, we don't really know where to
21636 display the cursor. */
21637 if (!glyph_row
->enabled_p
)
21639 w
->phys_cursor_on_p
= 0;
21644 if (!glyph_row
->exact_window_width_line_p
21645 || hpos
< glyph_row
->used
[TEXT_AREA
])
21646 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
21648 xassert (interrupt_input_blocked
);
21650 /* Set new_cursor_type to the cursor we want to be displayed. */
21651 new_cursor_type
= get_window_cursor_type (w
, glyph
,
21652 &new_cursor_width
, &active_cursor
);
21654 /* If cursor is currently being shown and we don't want it to be or
21655 it is in the wrong place, or the cursor type is not what we want,
21657 if (w
->phys_cursor_on_p
21659 || w
->phys_cursor
.x
!= x
21660 || w
->phys_cursor
.y
!= y
21661 || new_cursor_type
!= w
->phys_cursor_type
21662 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
21663 && new_cursor_width
!= w
->phys_cursor_width
)))
21664 erase_phys_cursor (w
);
21666 /* Don't check phys_cursor_on_p here because that flag is only set
21667 to zero in some cases where we know that the cursor has been
21668 completely erased, to avoid the extra work of erasing the cursor
21669 twice. In other words, phys_cursor_on_p can be 1 and the cursor
21670 still not be visible, or it has only been partly erased. */
21673 w
->phys_cursor_ascent
= glyph_row
->ascent
;
21674 w
->phys_cursor_height
= glyph_row
->height
;
21676 /* Set phys_cursor_.* before x_draw_.* is called because some
21677 of them may need the information. */
21678 w
->phys_cursor
.x
= x
;
21679 w
->phys_cursor
.y
= glyph_row
->y
;
21680 w
->phys_cursor
.hpos
= hpos
;
21681 w
->phys_cursor
.vpos
= vpos
;
21684 rif
->draw_window_cursor (w
, glyph_row
, x
, y
,
21685 new_cursor_type
, new_cursor_width
,
21686 on
, active_cursor
);
21690 /* Switch the display of W's cursor on or off, according to the value
21694 update_window_cursor (w
, on
)
21698 /* Don't update cursor in windows whose frame is in the process
21699 of being deleted. */
21700 if (w
->current_matrix
)
21703 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
21704 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
21710 /* Call update_window_cursor with parameter ON_P on all leaf windows
21711 in the window tree rooted at W. */
21714 update_cursor_in_window_tree (w
, on_p
)
21720 if (!NILP (w
->hchild
))
21721 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
21722 else if (!NILP (w
->vchild
))
21723 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
21725 update_window_cursor (w
, on_p
);
21727 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
21733 Display the cursor on window W, or clear it, according to ON_P.
21734 Don't change the cursor's position. */
21737 x_update_cursor (f
, on_p
)
21741 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
21746 Clear the cursor of window W to background color, and mark the
21747 cursor as not shown. This is used when the text where the cursor
21748 is is about to be rewritten. */
21754 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
21755 update_window_cursor (w
, 0);
21760 Display the active region described by mouse_face_* according to DRAW. */
21763 show_mouse_face (dpyinfo
, draw
)
21764 Display_Info
*dpyinfo
;
21765 enum draw_glyphs_face draw
;
21767 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
21768 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
21770 if (/* If window is in the process of being destroyed, don't bother
21772 w
->current_matrix
!= NULL
21773 /* Don't update mouse highlight if hidden */
21774 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
21775 /* Recognize when we are called to operate on rows that don't exist
21776 anymore. This can happen when a window is split. */
21777 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
21779 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
21780 struct glyph_row
*row
, *first
, *last
;
21782 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
21783 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
21785 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
21787 int start_hpos
, end_hpos
, start_x
;
21789 /* For all but the first row, the highlight starts at column 0. */
21792 start_hpos
= dpyinfo
->mouse_face_beg_col
;
21793 start_x
= dpyinfo
->mouse_face_beg_x
;
21802 end_hpos
= dpyinfo
->mouse_face_end_col
;
21805 end_hpos
= row
->used
[TEXT_AREA
];
21806 if (draw
== DRAW_NORMAL_TEXT
)
21807 row
->fill_line_p
= 1; /* Clear to end of line */
21810 if (end_hpos
> start_hpos
)
21812 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
21813 start_hpos
, end_hpos
,
21817 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
21821 /* When we've written over the cursor, arrange for it to
21822 be displayed again. */
21823 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
21826 display_and_set_cursor (w
, 1,
21827 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
21828 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
21833 /* Change the mouse cursor. */
21834 if (draw
== DRAW_NORMAL_TEXT
)
21835 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
21836 else if (draw
== DRAW_MOUSE_FACE
)
21837 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
21839 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
21843 Clear out the mouse-highlighted active region.
21844 Redraw it un-highlighted first. Value is non-zero if mouse
21845 face was actually drawn unhighlighted. */
21848 clear_mouse_face (dpyinfo
)
21849 Display_Info
*dpyinfo
;
21853 if (!dpyinfo
->mouse_face_hidden
&& !NILP (dpyinfo
->mouse_face_window
))
21855 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
21859 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
21860 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
21861 dpyinfo
->mouse_face_window
= Qnil
;
21862 dpyinfo
->mouse_face_overlay
= Qnil
;
21868 Non-zero if physical cursor of window W is within mouse face. */
21871 cursor_in_mouse_face_p (w
)
21874 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
21875 int in_mouse_face
= 0;
21877 if (WINDOWP (dpyinfo
->mouse_face_window
)
21878 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
21880 int hpos
= w
->phys_cursor
.hpos
;
21881 int vpos
= w
->phys_cursor
.vpos
;
21883 if (vpos
>= dpyinfo
->mouse_face_beg_row
21884 && vpos
<= dpyinfo
->mouse_face_end_row
21885 && (vpos
> dpyinfo
->mouse_face_beg_row
21886 || hpos
>= dpyinfo
->mouse_face_beg_col
)
21887 && (vpos
< dpyinfo
->mouse_face_end_row
21888 || hpos
< dpyinfo
->mouse_face_end_col
21889 || dpyinfo
->mouse_face_past_end
))
21893 return in_mouse_face
;
21899 /* Find the glyph matrix position of buffer position CHARPOS in window
21900 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
21901 current glyphs must be up to date. If CHARPOS is above window
21902 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
21903 of last line in W. In the row containing CHARPOS, stop before glyphs
21904 having STOP as object. */
21906 #if 1 /* This is a version of fast_find_position that's more correct
21907 in the presence of hscrolling, for example. I didn't install
21908 it right away because the problem fixed is minor, it failed
21909 in 20.x as well, and I think it's too risky to install
21910 so near the release of 21.1. 2001-09-25 gerd. */
21913 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
21916 int *hpos
, *vpos
, *x
, *y
;
21919 struct glyph_row
*row
, *first
;
21920 struct glyph
*glyph
, *end
;
21923 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
21924 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
21929 *vpos
= MATRIX_ROW_VPOS (first
, w
->current_matrix
);
21933 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
21936 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
21940 /* If whole rows or last part of a row came from a display overlay,
21941 row_containing_pos will skip over such rows because their end pos
21942 equals the start pos of the overlay or interval.
21944 Move back if we have a STOP object and previous row's
21945 end glyph came from STOP. */
21948 struct glyph_row
*prev
;
21949 while ((prev
= row
- 1, prev
>= first
)
21950 && MATRIX_ROW_END_CHARPOS (prev
) == charpos
21951 && prev
->used
[TEXT_AREA
] > 0)
21953 struct glyph
*beg
= prev
->glyphs
[TEXT_AREA
];
21954 glyph
= beg
+ prev
->used
[TEXT_AREA
];
21955 while (--glyph
>= beg
21956 && INTEGERP (glyph
->object
));
21958 || !EQ (stop
, glyph
->object
))
21966 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
21968 glyph
= row
->glyphs
[TEXT_AREA
];
21969 end
= glyph
+ row
->used
[TEXT_AREA
];
21971 /* Skip over glyphs not having an object at the start of the row.
21972 These are special glyphs like truncation marks on terminal
21974 if (row
->displays_text_p
)
21976 && INTEGERP (glyph
->object
)
21977 && !EQ (stop
, glyph
->object
)
21978 && glyph
->charpos
< 0)
21980 *x
+= glyph
->pixel_width
;
21985 && !INTEGERP (glyph
->object
)
21986 && !EQ (stop
, glyph
->object
)
21987 && (!BUFFERP (glyph
->object
)
21988 || glyph
->charpos
< charpos
))
21990 *x
+= glyph
->pixel_width
;
21994 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
22001 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
22004 int *hpos
, *vpos
, *x
, *y
;
22009 int maybe_next_line_p
= 0;
22010 int line_start_position
;
22011 int yb
= window_text_bottom_y (w
);
22012 struct glyph_row
*row
, *best_row
;
22013 int row_vpos
, best_row_vpos
;
22016 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
22017 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
22019 while (row
->y
< yb
)
22021 if (row
->used
[TEXT_AREA
])
22022 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
22024 line_start_position
= 0;
22026 if (line_start_position
> pos
)
22028 /* If the position sought is the end of the buffer,
22029 don't include the blank lines at the bottom of the window. */
22030 else if (line_start_position
== pos
22031 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
22033 maybe_next_line_p
= 1;
22036 else if (line_start_position
> 0)
22039 best_row_vpos
= row_vpos
;
22042 if (row
->y
+ row
->height
>= yb
)
22049 /* Find the right column within BEST_ROW. */
22051 current_x
= best_row
->x
;
22052 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
22054 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
22055 int charpos
= glyph
->charpos
;
22057 if (BUFFERP (glyph
->object
))
22059 if (charpos
== pos
)
22062 *vpos
= best_row_vpos
;
22067 else if (charpos
> pos
)
22070 else if (EQ (glyph
->object
, stop
))
22075 current_x
+= glyph
->pixel_width
;
22078 /* If we're looking for the end of the buffer,
22079 and we didn't find it in the line we scanned,
22080 use the start of the following line. */
22081 if (maybe_next_line_p
)
22086 current_x
= best_row
->x
;
22089 *vpos
= best_row_vpos
;
22090 *hpos
= lastcol
+ 1;
22099 /* Find the position of the glyph for position POS in OBJECT in
22100 window W's current matrix, and return in *X, *Y the pixel
22101 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
22103 RIGHT_P non-zero means return the position of the right edge of the
22104 glyph, RIGHT_P zero means return the left edge position.
22106 If no glyph for POS exists in the matrix, return the position of
22107 the glyph with the next smaller position that is in the matrix, if
22108 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
22109 exists in the matrix, return the position of the glyph with the
22110 next larger position in OBJECT.
22112 Value is non-zero if a glyph was found. */
22115 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
22118 Lisp_Object object
;
22119 int *hpos
, *vpos
, *x
, *y
;
22122 int yb
= window_text_bottom_y (w
);
22123 struct glyph_row
*r
;
22124 struct glyph
*best_glyph
= NULL
;
22125 struct glyph_row
*best_row
= NULL
;
22128 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
22129 r
->enabled_p
&& r
->y
< yb
;
22132 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
22133 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
22136 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
22137 if (EQ (g
->object
, object
))
22139 if (g
->charpos
== pos
)
22146 else if (best_glyph
== NULL
22147 || ((abs (g
->charpos
- pos
)
22148 < abs (best_glyph
->charpos
- pos
))
22151 : g
->charpos
> pos
)))
22165 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
22169 *x
+= best_glyph
->pixel_width
;
22174 *vpos
= best_row
- w
->current_matrix
->rows
;
22177 return best_glyph
!= NULL
;
22181 /* See if position X, Y is within a hot-spot of an image. */
22184 on_hot_spot_p (hot_spot
, x
, y
)
22185 Lisp_Object hot_spot
;
22188 if (!CONSP (hot_spot
))
22191 if (EQ (XCAR (hot_spot
), Qrect
))
22193 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
22194 Lisp_Object rect
= XCDR (hot_spot
);
22198 if (!CONSP (XCAR (rect
)))
22200 if (!CONSP (XCDR (rect
)))
22202 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
22204 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
22206 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
22208 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
22212 else if (EQ (XCAR (hot_spot
), Qcircle
))
22214 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
22215 Lisp_Object circ
= XCDR (hot_spot
);
22216 Lisp_Object lr
, lx0
, ly0
;
22218 && CONSP (XCAR (circ
))
22219 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
22220 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
22221 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
22223 double r
= XFLOATINT (lr
);
22224 double dx
= XINT (lx0
) - x
;
22225 double dy
= XINT (ly0
) - y
;
22226 return (dx
* dx
+ dy
* dy
<= r
* r
);
22229 else if (EQ (XCAR (hot_spot
), Qpoly
))
22231 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
22232 if (VECTORP (XCDR (hot_spot
)))
22234 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
22235 Lisp_Object
*poly
= v
->contents
;
22239 Lisp_Object lx
, ly
;
22242 /* Need an even number of coordinates, and at least 3 edges. */
22243 if (n
< 6 || n
& 1)
22246 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
22247 If count is odd, we are inside polygon. Pixels on edges
22248 may or may not be included depending on actual geometry of the
22250 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
22251 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
22253 x0
= XINT (lx
), y0
= XINT (ly
);
22254 for (i
= 0; i
< n
; i
+= 2)
22256 int x1
= x0
, y1
= y0
;
22257 if ((lx
= poly
[i
], !INTEGERP (lx
))
22258 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
22260 x0
= XINT (lx
), y0
= XINT (ly
);
22262 /* Does this segment cross the X line? */
22270 if (y
> y0
&& y
> y1
)
22272 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
22278 /* If we don't understand the format, pretend we're not in the hot-spot. */
22283 find_hot_spot (map
, x
, y
)
22287 while (CONSP (map
))
22289 if (CONSP (XCAR (map
))
22290 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
22298 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
22300 doc
: /* Lookup in image map MAP coordinates X and Y.
22301 An image map is an alist where each element has the format (AREA ID PLIST).
22302 An AREA is specified as either a rectangle, a circle, or a polygon:
22303 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
22304 pixel coordinates of the upper left and bottom right corners.
22305 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
22306 and the radius of the circle; r may be a float or integer.
22307 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
22308 vector describes one corner in the polygon.
22309 Returns the alist element for the first matching AREA in MAP. */)
22320 return find_hot_spot (map
, XINT (x
), XINT (y
));
22324 /* Display frame CURSOR, optionally using shape defined by POINTER. */
22326 define_frame_cursor1 (f
, cursor
, pointer
)
22329 Lisp_Object pointer
;
22331 /* Do not change cursor shape while dragging mouse. */
22332 if (!NILP (do_mouse_tracking
))
22335 if (!NILP (pointer
))
22337 if (EQ (pointer
, Qarrow
))
22338 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
22339 else if (EQ (pointer
, Qhand
))
22340 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
22341 else if (EQ (pointer
, Qtext
))
22342 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
22343 else if (EQ (pointer
, intern ("hdrag")))
22344 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
22345 #ifdef HAVE_X_WINDOWS
22346 else if (EQ (pointer
, intern ("vdrag")))
22347 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
22349 else if (EQ (pointer
, intern ("hourglass")))
22350 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
22351 else if (EQ (pointer
, Qmodeline
))
22352 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
22354 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
22357 if (cursor
!= No_Cursor
)
22358 rif
->define_frame_cursor (f
, cursor
);
22361 /* Take proper action when mouse has moved to the mode or header line
22362 or marginal area AREA of window W, x-position X and y-position Y.
22363 X is relative to the start of the text display area of W, so the
22364 width of bitmap areas and scroll bars must be subtracted to get a
22365 position relative to the start of the mode line. */
22368 note_mode_line_or_margin_highlight (window
, x
, y
, area
)
22369 Lisp_Object window
;
22371 enum window_part area
;
22373 struct window
*w
= XWINDOW (window
);
22374 struct frame
*f
= XFRAME (w
->frame
);
22375 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
22376 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
22377 Lisp_Object pointer
= Qnil
;
22378 int charpos
, dx
, dy
, width
, height
;
22379 Lisp_Object string
, object
= Qnil
;
22380 Lisp_Object pos
, help
;
22382 Lisp_Object mouse_face
;
22383 int original_x_pixel
= x
;
22384 struct glyph
* glyph
= NULL
;
22385 struct glyph_row
*row
;
22387 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
22392 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
22393 &object
, &dx
, &dy
, &width
, &height
);
22395 row
= (area
== ON_MODE_LINE
22396 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
22397 : MATRIX_HEADER_LINE_ROW (w
->current_matrix
));
22400 if (row
->mode_line_p
&& row
->enabled_p
)
22402 glyph
= row
->glyphs
[TEXT_AREA
];
22403 end
= glyph
+ row
->used
[TEXT_AREA
];
22405 for (x0
= original_x_pixel
;
22406 glyph
< end
&& x0
>= glyph
->pixel_width
;
22408 x0
-= glyph
->pixel_width
;
22416 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
22417 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
22418 &object
, &dx
, &dy
, &width
, &height
);
22423 if (IMAGEP (object
))
22425 Lisp_Object image_map
, hotspot
;
22426 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
22428 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
22430 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
22432 Lisp_Object area_id
, plist
;
22434 area_id
= XCAR (hotspot
);
22435 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22436 If so, we could look for mouse-enter, mouse-leave
22437 properties in PLIST (and do something...). */
22438 hotspot
= XCDR (hotspot
);
22439 if (CONSP (hotspot
)
22440 && (plist
= XCAR (hotspot
), CONSP (plist
)))
22442 pointer
= Fplist_get (plist
, Qpointer
);
22443 if (NILP (pointer
))
22445 help
= Fplist_get (plist
, Qhelp_echo
);
22448 help_echo_string
= help
;
22449 /* Is this correct? ++kfs */
22450 XSETWINDOW (help_echo_window
, w
);
22451 help_echo_object
= w
->buffer
;
22452 help_echo_pos
= charpos
;
22456 if (NILP (pointer
))
22457 pointer
= Fplist_get (XCDR (object
), QCpointer
);
22460 if (STRINGP (string
))
22462 pos
= make_number (charpos
);
22463 /* If we're on a string with `help-echo' text property, arrange
22464 for the help to be displayed. This is done by setting the
22465 global variable help_echo_string to the help string. */
22468 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
22471 help_echo_string
= help
;
22472 XSETWINDOW (help_echo_window
, w
);
22473 help_echo_object
= string
;
22474 help_echo_pos
= charpos
;
22478 if (NILP (pointer
))
22479 pointer
= Fget_text_property (pos
, Qpointer
, string
);
22481 /* Change the mouse pointer according to what is under X/Y. */
22482 if (NILP (pointer
) && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
22485 map
= Fget_text_property (pos
, Qlocal_map
, string
);
22486 if (!KEYMAPP (map
))
22487 map
= Fget_text_property (pos
, Qkeymap
, string
);
22488 if (!KEYMAPP (map
))
22489 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
22492 /* Change the mouse face according to what is under X/Y. */
22493 mouse_face
= Fget_text_property (pos
, Qmouse_face
, string
);
22494 if (!NILP (mouse_face
)
22495 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
22500 struct glyph
* tmp_glyph
;
22504 int total_pixel_width
;
22509 b
= Fprevious_single_property_change (make_number (charpos
+ 1),
22510 Qmouse_face
, string
, Qnil
);
22512 b
= make_number (0);
22514 e
= Fnext_single_property_change (pos
, Qmouse_face
, string
, Qnil
);
22516 e
= make_number (SCHARS (string
));
22518 /* Calculate the position(glyph position: GPOS) of GLYPH in
22519 displayed string. GPOS is different from CHARPOS.
22521 CHARPOS is the position of glyph in internal string
22522 object. A mode line string format has structures which
22523 is converted to a flatten by emacs lisp interpreter.
22524 The internal string is an element of the structures.
22525 The displayed string is the flatten string. */
22526 for (tmp_glyph
= glyph
- 1, gpos
= 0;
22527 tmp_glyph
->charpos
>= XINT (b
);
22528 tmp_glyph
--, gpos
++)
22530 if (!EQ (tmp_glyph
->object
, glyph
->object
))
22534 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
22535 displayed string holding GLYPH.
22537 GSEQ_LENGTH is different from SCHARS (STRING).
22538 SCHARS (STRING) returns the length of the internal string. */
22539 for (tmp_glyph
= glyph
, gseq_length
= gpos
;
22540 tmp_glyph
->charpos
< XINT (e
);
22541 tmp_glyph
++, gseq_length
++)
22543 if (!EQ (tmp_glyph
->object
, glyph
->object
))
22547 total_pixel_width
= 0;
22548 for (tmp_glyph
= glyph
- gpos
; tmp_glyph
!= glyph
; tmp_glyph
++)
22549 total_pixel_width
+= tmp_glyph
->pixel_width
;
22551 /* Pre calculation of re-rendering position */
22553 hpos
= (area
== ON_MODE_LINE
22554 ? (w
->current_matrix
)->nrows
- 1
22557 /* If the re-rendering position is included in the last
22558 re-rendering area, we should do nothing. */
22559 if ( EQ (window
, dpyinfo
->mouse_face_window
)
22560 && dpyinfo
->mouse_face_beg_col
<= vpos
22561 && vpos
< dpyinfo
->mouse_face_end_col
22562 && dpyinfo
->mouse_face_beg_row
== hpos
)
22565 if (clear_mouse_face (dpyinfo
))
22566 cursor
= No_Cursor
;
22568 dpyinfo
->mouse_face_beg_col
= vpos
;
22569 dpyinfo
->mouse_face_beg_row
= hpos
;
22571 dpyinfo
->mouse_face_beg_x
= original_x_pixel
- (total_pixel_width
+ dx
);
22572 dpyinfo
->mouse_face_beg_y
= 0;
22574 dpyinfo
->mouse_face_end_col
= vpos
+ gseq_length
;
22575 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_beg_row
;
22577 dpyinfo
->mouse_face_end_x
= 0;
22578 dpyinfo
->mouse_face_end_y
= 0;
22580 dpyinfo
->mouse_face_past_end
= 0;
22581 dpyinfo
->mouse_face_window
= window
;
22583 dpyinfo
->mouse_face_face_id
= face_at_string_position (w
, string
,
22586 glyph
->face_id
, 1);
22587 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
22589 if (NILP (pointer
))
22592 else if ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
22593 clear_mouse_face (dpyinfo
);
22595 define_frame_cursor1 (f
, cursor
, pointer
);
22600 Take proper action when the mouse has moved to position X, Y on
22601 frame F as regards highlighting characters that have mouse-face
22602 properties. Also de-highlighting chars where the mouse was before.
22603 X and Y can be negative or out of range. */
22606 note_mouse_highlight (f
, x
, y
)
22610 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
22611 enum window_part part
;
22612 Lisp_Object window
;
22614 Cursor cursor
= No_Cursor
;
22615 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
22618 /* When a menu is active, don't highlight because this looks odd. */
22619 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
22620 if (popup_activated ())
22624 if (NILP (Vmouse_highlight
)
22625 || !f
->glyphs_initialized_p
)
22628 dpyinfo
->mouse_face_mouse_x
= x
;
22629 dpyinfo
->mouse_face_mouse_y
= y
;
22630 dpyinfo
->mouse_face_mouse_frame
= f
;
22632 if (dpyinfo
->mouse_face_defer
)
22635 if (gc_in_progress
)
22637 dpyinfo
->mouse_face_deferred_gc
= 1;
22641 /* Which window is that in? */
22642 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
22644 /* If we were displaying active text in another window, clear that.
22645 Also clear if we move out of text area in same window. */
22646 if (! EQ (window
, dpyinfo
->mouse_face_window
)
22647 || (part
!= ON_TEXT
&& part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
22648 && !NILP (dpyinfo
->mouse_face_window
)))
22649 clear_mouse_face (dpyinfo
);
22651 /* Not on a window -> return. */
22652 if (!WINDOWP (window
))
22655 /* Reset help_echo_string. It will get recomputed below. */
22656 help_echo_string
= Qnil
;
22658 /* Convert to window-relative pixel coordinates. */
22659 w
= XWINDOW (window
);
22660 frame_to_window_pixel_xy (w
, &x
, &y
);
22662 /* Handle tool-bar window differently since it doesn't display a
22664 if (EQ (window
, f
->tool_bar_window
))
22666 note_tool_bar_highlight (f
, x
, y
);
22670 /* Mouse is on the mode, header line or margin? */
22671 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
22672 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
22674 note_mode_line_or_margin_highlight (window
, x
, y
, part
);
22678 if (part
== ON_VERTICAL_BORDER
)
22680 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
22681 help_echo_string
= build_string ("drag-mouse-1: resize");
22683 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
22684 || part
== ON_SCROLL_BAR
)
22685 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
22687 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
22689 /* Are we in a window whose display is up to date?
22690 And verify the buffer's text has not changed. */
22691 b
= XBUFFER (w
->buffer
);
22692 if (part
== ON_TEXT
22693 && EQ (w
->window_end_valid
, w
->buffer
)
22694 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
22695 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
22697 int hpos
, vpos
, pos
, i
, dx
, dy
, area
;
22698 struct glyph
*glyph
;
22699 Lisp_Object object
;
22700 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
22701 Lisp_Object
*overlay_vec
= NULL
;
22703 struct buffer
*obuf
;
22704 int obegv
, ozv
, same_region
;
22706 /* Find the glyph under X/Y. */
22707 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
22709 /* Look for :pointer property on image. */
22710 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
22712 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
22713 if (img
!= NULL
&& IMAGEP (img
->spec
))
22715 Lisp_Object image_map
, hotspot
;
22716 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
22718 && (hotspot
= find_hot_spot (image_map
,
22719 glyph
->slice
.x
+ dx
,
22720 glyph
->slice
.y
+ dy
),
22722 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
22724 Lisp_Object area_id
, plist
;
22726 area_id
= XCAR (hotspot
);
22727 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22728 If so, we could look for mouse-enter, mouse-leave
22729 properties in PLIST (and do something...). */
22730 hotspot
= XCDR (hotspot
);
22731 if (CONSP (hotspot
)
22732 && (plist
= XCAR (hotspot
), CONSP (plist
)))
22734 pointer
= Fplist_get (plist
, Qpointer
);
22735 if (NILP (pointer
))
22737 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
22738 if (!NILP (help_echo_string
))
22740 help_echo_window
= window
;
22741 help_echo_object
= glyph
->object
;
22742 help_echo_pos
= glyph
->charpos
;
22746 if (NILP (pointer
))
22747 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
22751 /* Clear mouse face if X/Y not over text. */
22753 || area
!= TEXT_AREA
22754 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
22756 if (clear_mouse_face (dpyinfo
))
22757 cursor
= No_Cursor
;
22758 if (NILP (pointer
))
22760 if (area
!= TEXT_AREA
)
22761 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
22763 pointer
= Vvoid_text_area_pointer
;
22768 pos
= glyph
->charpos
;
22769 object
= glyph
->object
;
22770 if (!STRINGP (object
) && !BUFFERP (object
))
22773 /* If we get an out-of-range value, return now; avoid an error. */
22774 if (BUFFERP (object
) && pos
> BUF_Z (b
))
22777 /* Make the window's buffer temporarily current for
22778 overlays_at and compute_char_face. */
22779 obuf
= current_buffer
;
22780 current_buffer
= b
;
22786 /* Is this char mouse-active or does it have help-echo? */
22787 position
= make_number (pos
);
22789 if (BUFFERP (object
))
22791 /* Put all the overlays we want in a vector in overlay_vec. */
22792 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
22793 /* Sort overlays into increasing priority order. */
22794 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
22799 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
22800 && vpos
>= dpyinfo
->mouse_face_beg_row
22801 && vpos
<= dpyinfo
->mouse_face_end_row
22802 && (vpos
> dpyinfo
->mouse_face_beg_row
22803 || hpos
>= dpyinfo
->mouse_face_beg_col
)
22804 && (vpos
< dpyinfo
->mouse_face_end_row
22805 || hpos
< dpyinfo
->mouse_face_end_col
22806 || dpyinfo
->mouse_face_past_end
));
22809 cursor
= No_Cursor
;
22811 /* Check mouse-face highlighting. */
22813 /* If there exists an overlay with mouse-face overlapping
22814 the one we are currently highlighting, we have to
22815 check if we enter the overlapping overlay, and then
22816 highlight only that. */
22817 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
22818 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
22820 /* Find the highest priority overlay that has a mouse-face
22823 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
22825 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
22826 if (!NILP (mouse_face
))
22827 overlay
= overlay_vec
[i
];
22830 /* If we're actually highlighting the same overlay as
22831 before, there's no need to do that again. */
22832 if (!NILP (overlay
)
22833 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
22834 goto check_help_echo
;
22836 dpyinfo
->mouse_face_overlay
= overlay
;
22838 /* Clear the display of the old active region, if any. */
22839 if (clear_mouse_face (dpyinfo
))
22840 cursor
= No_Cursor
;
22842 /* If no overlay applies, get a text property. */
22843 if (NILP (overlay
))
22844 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
22846 /* Handle the overlay case. */
22847 if (!NILP (overlay
))
22849 /* Find the range of text around this char that
22850 should be active. */
22851 Lisp_Object before
, after
;
22854 before
= Foverlay_start (overlay
);
22855 after
= Foverlay_end (overlay
);
22856 /* Record this as the current active region. */
22857 fast_find_position (w
, XFASTINT (before
),
22858 &dpyinfo
->mouse_face_beg_col
,
22859 &dpyinfo
->mouse_face_beg_row
,
22860 &dpyinfo
->mouse_face_beg_x
,
22861 &dpyinfo
->mouse_face_beg_y
, Qnil
);
22863 dpyinfo
->mouse_face_past_end
22864 = !fast_find_position (w
, XFASTINT (after
),
22865 &dpyinfo
->mouse_face_end_col
,
22866 &dpyinfo
->mouse_face_end_row
,
22867 &dpyinfo
->mouse_face_end_x
,
22868 &dpyinfo
->mouse_face_end_y
, Qnil
);
22869 dpyinfo
->mouse_face_window
= window
;
22871 dpyinfo
->mouse_face_face_id
22872 = face_at_buffer_position (w
, pos
, 0, 0,
22874 !dpyinfo
->mouse_face_hidden
);
22876 /* Display it as active. */
22877 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
22878 cursor
= No_Cursor
;
22880 /* Handle the text property case. */
22881 else if (!NILP (mouse_face
) && BUFFERP (object
))
22883 /* Find the range of text around this char that
22884 should be active. */
22885 Lisp_Object before
, after
, beginning
, end
;
22888 beginning
= Fmarker_position (w
->start
);
22889 end
= make_number (BUF_Z (XBUFFER (object
))
22890 - XFASTINT (w
->window_end_pos
));
22892 = Fprevious_single_property_change (make_number (pos
+ 1),
22894 object
, beginning
);
22896 = Fnext_single_property_change (position
, Qmouse_face
,
22899 /* Record this as the current active region. */
22900 fast_find_position (w
, XFASTINT (before
),
22901 &dpyinfo
->mouse_face_beg_col
,
22902 &dpyinfo
->mouse_face_beg_row
,
22903 &dpyinfo
->mouse_face_beg_x
,
22904 &dpyinfo
->mouse_face_beg_y
, Qnil
);
22905 dpyinfo
->mouse_face_past_end
22906 = !fast_find_position (w
, XFASTINT (after
),
22907 &dpyinfo
->mouse_face_end_col
,
22908 &dpyinfo
->mouse_face_end_row
,
22909 &dpyinfo
->mouse_face_end_x
,
22910 &dpyinfo
->mouse_face_end_y
, Qnil
);
22911 dpyinfo
->mouse_face_window
= window
;
22913 if (BUFFERP (object
))
22914 dpyinfo
->mouse_face_face_id
22915 = face_at_buffer_position (w
, pos
, 0, 0,
22917 !dpyinfo
->mouse_face_hidden
);
22919 /* Display it as active. */
22920 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
22921 cursor
= No_Cursor
;
22923 else if (!NILP (mouse_face
) && STRINGP (object
))
22928 b
= Fprevious_single_property_change (make_number (pos
+ 1),
22931 e
= Fnext_single_property_change (position
, Qmouse_face
,
22934 b
= make_number (0);
22936 e
= make_number (SCHARS (object
) - 1);
22938 fast_find_string_pos (w
, XINT (b
), object
,
22939 &dpyinfo
->mouse_face_beg_col
,
22940 &dpyinfo
->mouse_face_beg_row
,
22941 &dpyinfo
->mouse_face_beg_x
,
22942 &dpyinfo
->mouse_face_beg_y
, 0);
22943 fast_find_string_pos (w
, XINT (e
), object
,
22944 &dpyinfo
->mouse_face_end_col
,
22945 &dpyinfo
->mouse_face_end_row
,
22946 &dpyinfo
->mouse_face_end_x
,
22947 &dpyinfo
->mouse_face_end_y
, 1);
22948 dpyinfo
->mouse_face_past_end
= 0;
22949 dpyinfo
->mouse_face_window
= window
;
22950 dpyinfo
->mouse_face_face_id
22951 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
22952 glyph
->face_id
, 1);
22953 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
22954 cursor
= No_Cursor
;
22956 else if (STRINGP (object
) && NILP (mouse_face
))
22958 /* A string which doesn't have mouse-face, but
22959 the text ``under'' it might have. */
22960 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
22961 int start
= MATRIX_ROW_START_CHARPOS (r
);
22963 pos
= string_buffer_position (w
, object
, start
);
22965 mouse_face
= get_char_property_and_overlay (make_number (pos
),
22969 if (!NILP (mouse_face
) && !NILP (overlay
))
22971 Lisp_Object before
= Foverlay_start (overlay
);
22972 Lisp_Object after
= Foverlay_end (overlay
);
22975 /* Note that we might not be able to find position
22976 BEFORE in the glyph matrix if the overlay is
22977 entirely covered by a `display' property. In
22978 this case, we overshoot. So let's stop in
22979 the glyph matrix before glyphs for OBJECT. */
22980 fast_find_position (w
, XFASTINT (before
),
22981 &dpyinfo
->mouse_face_beg_col
,
22982 &dpyinfo
->mouse_face_beg_row
,
22983 &dpyinfo
->mouse_face_beg_x
,
22984 &dpyinfo
->mouse_face_beg_y
,
22987 dpyinfo
->mouse_face_past_end
22988 = !fast_find_position (w
, XFASTINT (after
),
22989 &dpyinfo
->mouse_face_end_col
,
22990 &dpyinfo
->mouse_face_end_row
,
22991 &dpyinfo
->mouse_face_end_x
,
22992 &dpyinfo
->mouse_face_end_y
,
22994 dpyinfo
->mouse_face_window
= window
;
22995 dpyinfo
->mouse_face_face_id
22996 = face_at_buffer_position (w
, pos
, 0, 0,
22998 !dpyinfo
->mouse_face_hidden
);
23000 /* Display it as active. */
23001 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
23002 cursor
= No_Cursor
;
23009 /* Look for a `help-echo' property. */
23010 if (NILP (help_echo_string
)) {
23011 Lisp_Object help
, overlay
;
23013 /* Check overlays first. */
23014 help
= overlay
= Qnil
;
23015 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
23017 overlay
= overlay_vec
[i
];
23018 help
= Foverlay_get (overlay
, Qhelp_echo
);
23023 help_echo_string
= help
;
23024 help_echo_window
= window
;
23025 help_echo_object
= overlay
;
23026 help_echo_pos
= pos
;
23030 Lisp_Object object
= glyph
->object
;
23031 int charpos
= glyph
->charpos
;
23033 /* Try text properties. */
23034 if (STRINGP (object
)
23036 && charpos
< SCHARS (object
))
23038 help
= Fget_text_property (make_number (charpos
),
23039 Qhelp_echo
, object
);
23042 /* If the string itself doesn't specify a help-echo,
23043 see if the buffer text ``under'' it does. */
23044 struct glyph_row
*r
23045 = MATRIX_ROW (w
->current_matrix
, vpos
);
23046 int start
= MATRIX_ROW_START_CHARPOS (r
);
23047 int pos
= string_buffer_position (w
, object
, start
);
23050 help
= Fget_char_property (make_number (pos
),
23051 Qhelp_echo
, w
->buffer
);
23055 object
= w
->buffer
;
23060 else if (BUFFERP (object
)
23063 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
23068 help_echo_string
= help
;
23069 help_echo_window
= window
;
23070 help_echo_object
= object
;
23071 help_echo_pos
= charpos
;
23076 /* Look for a `pointer' property. */
23077 if (NILP (pointer
))
23079 /* Check overlays first. */
23080 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
23081 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
23083 if (NILP (pointer
))
23085 Lisp_Object object
= glyph
->object
;
23086 int charpos
= glyph
->charpos
;
23088 /* Try text properties. */
23089 if (STRINGP (object
)
23091 && charpos
< SCHARS (object
))
23093 pointer
= Fget_text_property (make_number (charpos
),
23095 if (NILP (pointer
))
23097 /* If the string itself doesn't specify a pointer,
23098 see if the buffer text ``under'' it does. */
23099 struct glyph_row
*r
23100 = MATRIX_ROW (w
->current_matrix
, vpos
);
23101 int start
= MATRIX_ROW_START_CHARPOS (r
);
23102 int pos
= string_buffer_position (w
, object
, start
);
23104 pointer
= Fget_char_property (make_number (pos
),
23105 Qpointer
, w
->buffer
);
23108 else if (BUFFERP (object
)
23111 pointer
= Fget_text_property (make_number (charpos
),
23118 current_buffer
= obuf
;
23123 define_frame_cursor1 (f
, cursor
, pointer
);
23128 Clear any mouse-face on window W. This function is part of the
23129 redisplay interface, and is called from try_window_id and similar
23130 functions to ensure the mouse-highlight is off. */
23133 x_clear_window_mouse_face (w
)
23136 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
23137 Lisp_Object window
;
23140 XSETWINDOW (window
, w
);
23141 if (EQ (window
, dpyinfo
->mouse_face_window
))
23142 clear_mouse_face (dpyinfo
);
23148 Just discard the mouse face information for frame F, if any.
23149 This is used when the size of F is changed. */
23152 cancel_mouse_face (f
)
23155 Lisp_Object window
;
23156 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
23158 window
= dpyinfo
->mouse_face_window
;
23159 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
23161 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
23162 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
23163 dpyinfo
->mouse_face_window
= Qnil
;
23168 #endif /* HAVE_WINDOW_SYSTEM */
23171 /***********************************************************************
23173 ***********************************************************************/
23175 #ifdef HAVE_WINDOW_SYSTEM
23177 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
23178 which intersects rectangle R. R is in window-relative coordinates. */
23181 expose_area (w
, row
, r
, area
)
23183 struct glyph_row
*row
;
23185 enum glyph_row_area area
;
23187 struct glyph
*first
= row
->glyphs
[area
];
23188 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
23189 struct glyph
*last
;
23190 int first_x
, start_x
, x
;
23192 if (area
== TEXT_AREA
&& row
->fill_line_p
)
23193 /* If row extends face to end of line write the whole line. */
23194 draw_glyphs (w
, 0, row
, area
,
23195 0, row
->used
[area
],
23196 DRAW_NORMAL_TEXT
, 0);
23199 /* Set START_X to the window-relative start position for drawing glyphs of
23200 AREA. The first glyph of the text area can be partially visible.
23201 The first glyphs of other areas cannot. */
23202 start_x
= window_box_left_offset (w
, area
);
23204 if (area
== TEXT_AREA
)
23207 /* Find the first glyph that must be redrawn. */
23209 && x
+ first
->pixel_width
< r
->x
)
23211 x
+= first
->pixel_width
;
23215 /* Find the last one. */
23219 && x
< r
->x
+ r
->width
)
23221 x
+= last
->pixel_width
;
23227 draw_glyphs (w
, first_x
- start_x
, row
, area
,
23228 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
23229 DRAW_NORMAL_TEXT
, 0);
23234 /* Redraw the parts of the glyph row ROW on window W intersecting
23235 rectangle R. R is in window-relative coordinates. Value is
23236 non-zero if mouse-face was overwritten. */
23239 expose_line (w
, row
, r
)
23241 struct glyph_row
*row
;
23244 xassert (row
->enabled_p
);
23246 if (row
->mode_line_p
|| w
->pseudo_window_p
)
23247 draw_glyphs (w
, 0, row
, TEXT_AREA
,
23248 0, row
->used
[TEXT_AREA
],
23249 DRAW_NORMAL_TEXT
, 0);
23252 if (row
->used
[LEFT_MARGIN_AREA
])
23253 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
23254 if (row
->used
[TEXT_AREA
])
23255 expose_area (w
, row
, r
, TEXT_AREA
);
23256 if (row
->used
[RIGHT_MARGIN_AREA
])
23257 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
23258 draw_row_fringe_bitmaps (w
, row
);
23261 return row
->mouse_face_p
;
23265 /* Redraw those parts of glyphs rows during expose event handling that
23266 overlap other rows. Redrawing of an exposed line writes over parts
23267 of lines overlapping that exposed line; this function fixes that.
23269 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
23270 row in W's current matrix that is exposed and overlaps other rows.
23271 LAST_OVERLAPPING_ROW is the last such row. */
23274 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
23276 struct glyph_row
*first_overlapping_row
;
23277 struct glyph_row
*last_overlapping_row
;
23279 struct glyph_row
*row
;
23281 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
23282 if (row
->overlapping_p
)
23284 xassert (row
->enabled_p
&& !row
->mode_line_p
);
23286 if (row
->used
[LEFT_MARGIN_AREA
])
23287 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
, OVERLAPS_BOTH
);
23289 if (row
->used
[TEXT_AREA
])
23290 x_fix_overlapping_area (w
, row
, TEXT_AREA
, OVERLAPS_BOTH
);
23292 if (row
->used
[RIGHT_MARGIN_AREA
])
23293 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
, OVERLAPS_BOTH
);
23298 /* Return non-zero if W's cursor intersects rectangle R. */
23301 phys_cursor_in_rect_p (w
, r
)
23305 XRectangle cr
, result
;
23306 struct glyph
*cursor_glyph
;
23308 cursor_glyph
= get_phys_cursor_glyph (w
);
23311 /* r is relative to W's box, but w->phys_cursor.x is relative
23312 to left edge of W's TEXT area. Adjust it. */
23313 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
23314 cr
.y
= w
->phys_cursor
.y
;
23315 cr
.width
= cursor_glyph
->pixel_width
;
23316 cr
.height
= w
->phys_cursor_height
;
23317 /* ++KFS: W32 version used W32-specific IntersectRect here, but
23318 I assume the effect is the same -- and this is portable. */
23319 return x_intersect_rectangles (&cr
, r
, &result
);
23327 Draw a vertical window border to the right of window W if W doesn't
23328 have vertical scroll bars. */
23331 x_draw_vertical_border (w
)
23334 /* We could do better, if we knew what type of scroll-bar the adjacent
23335 windows (on either side) have... But we don't :-(
23336 However, I think this works ok. ++KFS 2003-04-25 */
23338 /* Redraw borders between horizontally adjacent windows. Don't
23339 do it for frames with vertical scroll bars because either the
23340 right scroll bar of a window, or the left scroll bar of its
23341 neighbor will suffice as a border. */
23342 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w
->frame
)))
23345 if (!WINDOW_RIGHTMOST_P (w
)
23346 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
23348 int x0
, x1
, y0
, y1
;
23350 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
23353 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
23356 rif
->draw_vertical_window_border (w
, x1
, y0
, y1
);
23358 else if (!WINDOW_LEFTMOST_P (w
)
23359 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
23361 int x0
, x1
, y0
, y1
;
23363 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
23366 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
23369 rif
->draw_vertical_window_border (w
, x0
, y0
, y1
);
23374 /* Redraw the part of window W intersection rectangle FR. Pixel
23375 coordinates in FR are frame-relative. Call this function with
23376 input blocked. Value is non-zero if the exposure overwrites
23380 expose_window (w
, fr
)
23384 struct frame
*f
= XFRAME (w
->frame
);
23386 int mouse_face_overwritten_p
= 0;
23388 /* If window is not yet fully initialized, do nothing. This can
23389 happen when toolkit scroll bars are used and a window is split.
23390 Reconfiguring the scroll bar will generate an expose for a newly
23392 if (w
->current_matrix
== NULL
)
23395 /* When we're currently updating the window, display and current
23396 matrix usually don't agree. Arrange for a thorough display
23398 if (w
== updated_window
)
23400 SET_FRAME_GARBAGED (f
);
23404 /* Frame-relative pixel rectangle of W. */
23405 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
23406 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
23407 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
23408 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
23410 if (x_intersect_rectangles (fr
, &wr
, &r
))
23412 int yb
= window_text_bottom_y (w
);
23413 struct glyph_row
*row
;
23414 int cursor_cleared_p
;
23415 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
23417 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
23418 r
.x
, r
.y
, r
.width
, r
.height
));
23420 /* Convert to window coordinates. */
23421 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
23422 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
23424 /* Turn off the cursor. */
23425 if (!w
->pseudo_window_p
23426 && phys_cursor_in_rect_p (w
, &r
))
23428 x_clear_cursor (w
);
23429 cursor_cleared_p
= 1;
23432 cursor_cleared_p
= 0;
23434 /* Update lines intersecting rectangle R. */
23435 first_overlapping_row
= last_overlapping_row
= NULL
;
23436 for (row
= w
->current_matrix
->rows
;
23441 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
23443 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
23444 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
23445 || (r
.y
>= y0
&& r
.y
< y1
)
23446 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
23448 /* A header line may be overlapping, but there is no need
23449 to fix overlapping areas for them. KFS 2005-02-12 */
23450 if (row
->overlapping_p
&& !row
->mode_line_p
)
23452 if (first_overlapping_row
== NULL
)
23453 first_overlapping_row
= row
;
23454 last_overlapping_row
= row
;
23457 if (expose_line (w
, row
, &r
))
23458 mouse_face_overwritten_p
= 1;
23465 /* Display the mode line if there is one. */
23466 if (WINDOW_WANTS_MODELINE_P (w
)
23467 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
23469 && row
->y
< r
.y
+ r
.height
)
23471 if (expose_line (w
, row
, &r
))
23472 mouse_face_overwritten_p
= 1;
23475 if (!w
->pseudo_window_p
)
23477 /* Fix the display of overlapping rows. */
23478 if (first_overlapping_row
)
23479 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
23481 /* Draw border between windows. */
23482 x_draw_vertical_border (w
);
23484 /* Turn the cursor on again. */
23485 if (cursor_cleared_p
)
23486 update_window_cursor (w
, 1);
23490 return mouse_face_overwritten_p
;
23495 /* Redraw (parts) of all windows in the window tree rooted at W that
23496 intersect R. R contains frame pixel coordinates. Value is
23497 non-zero if the exposure overwrites mouse-face. */
23500 expose_window_tree (w
, r
)
23504 struct frame
*f
= XFRAME (w
->frame
);
23505 int mouse_face_overwritten_p
= 0;
23507 while (w
&& !FRAME_GARBAGED_P (f
))
23509 if (!NILP (w
->hchild
))
23510 mouse_face_overwritten_p
23511 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
23512 else if (!NILP (w
->vchild
))
23513 mouse_face_overwritten_p
23514 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
23516 mouse_face_overwritten_p
|= expose_window (w
, r
);
23518 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
23521 return mouse_face_overwritten_p
;
23526 Redisplay an exposed area of frame F. X and Y are the upper-left
23527 corner of the exposed rectangle. W and H are width and height of
23528 the exposed area. All are pixel values. W or H zero means redraw
23529 the entire frame. */
23532 expose_frame (f
, x
, y
, w
, h
)
23537 int mouse_face_overwritten_p
= 0;
23539 TRACE ((stderr
, "expose_frame "));
23541 /* No need to redraw if frame will be redrawn soon. */
23542 if (FRAME_GARBAGED_P (f
))
23544 TRACE ((stderr
, " garbaged\n"));
23548 /* If basic faces haven't been realized yet, there is no point in
23549 trying to redraw anything. This can happen when we get an expose
23550 event while Emacs is starting, e.g. by moving another window. */
23551 if (FRAME_FACE_CACHE (f
) == NULL
23552 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
23554 TRACE ((stderr
, " no faces\n"));
23558 if (w
== 0 || h
== 0)
23561 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
23562 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
23572 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
23573 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
23575 if (WINDOWP (f
->tool_bar_window
))
23576 mouse_face_overwritten_p
23577 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
23579 #ifdef HAVE_X_WINDOWS
23581 #ifndef USE_X_TOOLKIT
23582 if (WINDOWP (f
->menu_bar_window
))
23583 mouse_face_overwritten_p
23584 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
23585 #endif /* not USE_X_TOOLKIT */
23589 /* Some window managers support a focus-follows-mouse style with
23590 delayed raising of frames. Imagine a partially obscured frame,
23591 and moving the mouse into partially obscured mouse-face on that
23592 frame. The visible part of the mouse-face will be highlighted,
23593 then the WM raises the obscured frame. With at least one WM, KDE
23594 2.1, Emacs is not getting any event for the raising of the frame
23595 (even tried with SubstructureRedirectMask), only Expose events.
23596 These expose events will draw text normally, i.e. not
23597 highlighted. Which means we must redo the highlight here.
23598 Subsume it under ``we love X''. --gerd 2001-08-15 */
23599 /* Included in Windows version because Windows most likely does not
23600 do the right thing if any third party tool offers
23601 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
23602 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
23604 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
23605 if (f
== dpyinfo
->mouse_face_mouse_frame
)
23607 int x
= dpyinfo
->mouse_face_mouse_x
;
23608 int y
= dpyinfo
->mouse_face_mouse_y
;
23609 clear_mouse_face (dpyinfo
);
23610 note_mouse_highlight (f
, x
, y
);
23617 Determine the intersection of two rectangles R1 and R2. Return
23618 the intersection in *RESULT. Value is non-zero if RESULT is not
23622 x_intersect_rectangles (r1
, r2
, result
)
23623 XRectangle
*r1
, *r2
, *result
;
23625 XRectangle
*left
, *right
;
23626 XRectangle
*upper
, *lower
;
23627 int intersection_p
= 0;
23629 /* Rearrange so that R1 is the left-most rectangle. */
23631 left
= r1
, right
= r2
;
23633 left
= r2
, right
= r1
;
23635 /* X0 of the intersection is right.x0, if this is inside R1,
23636 otherwise there is no intersection. */
23637 if (right
->x
<= left
->x
+ left
->width
)
23639 result
->x
= right
->x
;
23641 /* The right end of the intersection is the minimum of the
23642 the right ends of left and right. */
23643 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
23646 /* Same game for Y. */
23648 upper
= r1
, lower
= r2
;
23650 upper
= r2
, lower
= r1
;
23652 /* The upper end of the intersection is lower.y0, if this is inside
23653 of upper. Otherwise, there is no intersection. */
23654 if (lower
->y
<= upper
->y
+ upper
->height
)
23656 result
->y
= lower
->y
;
23658 /* The lower end of the intersection is the minimum of the lower
23659 ends of upper and lower. */
23660 result
->height
= (min (lower
->y
+ lower
->height
,
23661 upper
->y
+ upper
->height
)
23663 intersection_p
= 1;
23667 return intersection_p
;
23670 #endif /* HAVE_WINDOW_SYSTEM */
23673 /***********************************************************************
23675 ***********************************************************************/
23680 Vwith_echo_area_save_vector
= Qnil
;
23681 staticpro (&Vwith_echo_area_save_vector
);
23683 Vmessage_stack
= Qnil
;
23684 staticpro (&Vmessage_stack
);
23686 Qinhibit_redisplay
= intern ("inhibit-redisplay");
23687 staticpro (&Qinhibit_redisplay
);
23689 message_dolog_marker1
= Fmake_marker ();
23690 staticpro (&message_dolog_marker1
);
23691 message_dolog_marker2
= Fmake_marker ();
23692 staticpro (&message_dolog_marker2
);
23693 message_dolog_marker3
= Fmake_marker ();
23694 staticpro (&message_dolog_marker3
);
23697 defsubr (&Sdump_frame_glyph_matrix
);
23698 defsubr (&Sdump_glyph_matrix
);
23699 defsubr (&Sdump_glyph_row
);
23700 defsubr (&Sdump_tool_bar_row
);
23701 defsubr (&Strace_redisplay
);
23702 defsubr (&Strace_to_stderr
);
23704 #ifdef HAVE_WINDOW_SYSTEM
23705 defsubr (&Stool_bar_lines_needed
);
23706 defsubr (&Slookup_image_map
);
23708 defsubr (&Sformat_mode_line
);
23710 staticpro (&Qmenu_bar_update_hook
);
23711 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
23713 staticpro (&Qoverriding_terminal_local_map
);
23714 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
23716 staticpro (&Qoverriding_local_map
);
23717 Qoverriding_local_map
= intern ("overriding-local-map");
23719 staticpro (&Qwindow_scroll_functions
);
23720 Qwindow_scroll_functions
= intern ("window-scroll-functions");
23722 staticpro (&Qredisplay_end_trigger_functions
);
23723 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
23725 staticpro (&Qinhibit_point_motion_hooks
);
23726 Qinhibit_point_motion_hooks
= intern ("inhibit-point-motion-hooks");
23728 QCdata
= intern (":data");
23729 staticpro (&QCdata
);
23730 Qdisplay
= intern ("display");
23731 staticpro (&Qdisplay
);
23732 Qspace_width
= intern ("space-width");
23733 staticpro (&Qspace_width
);
23734 Qraise
= intern ("raise");
23735 staticpro (&Qraise
);
23736 Qslice
= intern ("slice");
23737 staticpro (&Qslice
);
23738 Qspace
= intern ("space");
23739 staticpro (&Qspace
);
23740 Qmargin
= intern ("margin");
23741 staticpro (&Qmargin
);
23742 Qpointer
= intern ("pointer");
23743 staticpro (&Qpointer
);
23744 Qleft_margin
= intern ("left-margin");
23745 staticpro (&Qleft_margin
);
23746 Qright_margin
= intern ("right-margin");
23747 staticpro (&Qright_margin
);
23748 Qcenter
= intern ("center");
23749 staticpro (&Qcenter
);
23750 Qline_height
= intern ("line-height");
23751 staticpro (&Qline_height
);
23752 QCalign_to
= intern (":align-to");
23753 staticpro (&QCalign_to
);
23754 QCrelative_width
= intern (":relative-width");
23755 staticpro (&QCrelative_width
);
23756 QCrelative_height
= intern (":relative-height");
23757 staticpro (&QCrelative_height
);
23758 QCeval
= intern (":eval");
23759 staticpro (&QCeval
);
23760 QCpropertize
= intern (":propertize");
23761 staticpro (&QCpropertize
);
23762 QCfile
= intern (":file");
23763 staticpro (&QCfile
);
23764 Qfontified
= intern ("fontified");
23765 staticpro (&Qfontified
);
23766 Qfontification_functions
= intern ("fontification-functions");
23767 staticpro (&Qfontification_functions
);
23768 Qtrailing_whitespace
= intern ("trailing-whitespace");
23769 staticpro (&Qtrailing_whitespace
);
23770 Qescape_glyph
= intern ("escape-glyph");
23771 staticpro (&Qescape_glyph
);
23772 Qnobreak_space
= intern ("nobreak-space");
23773 staticpro (&Qnobreak_space
);
23774 Qimage
= intern ("image");
23775 staticpro (&Qimage
);
23776 QCmap
= intern (":map");
23777 staticpro (&QCmap
);
23778 QCpointer
= intern (":pointer");
23779 staticpro (&QCpointer
);
23780 Qrect
= intern ("rect");
23781 staticpro (&Qrect
);
23782 Qcircle
= intern ("circle");
23783 staticpro (&Qcircle
);
23784 Qpoly
= intern ("poly");
23785 staticpro (&Qpoly
);
23786 Qmessage_truncate_lines
= intern ("message-truncate-lines");
23787 staticpro (&Qmessage_truncate_lines
);
23788 Qgrow_only
= intern ("grow-only");
23789 staticpro (&Qgrow_only
);
23790 Qinhibit_menubar_update
= intern ("inhibit-menubar-update");
23791 staticpro (&Qinhibit_menubar_update
);
23792 Qinhibit_eval_during_redisplay
= intern ("inhibit-eval-during-redisplay");
23793 staticpro (&Qinhibit_eval_during_redisplay
);
23794 Qposition
= intern ("position");
23795 staticpro (&Qposition
);
23796 Qbuffer_position
= intern ("buffer-position");
23797 staticpro (&Qbuffer_position
);
23798 Qobject
= intern ("object");
23799 staticpro (&Qobject
);
23800 Qbar
= intern ("bar");
23802 Qhbar
= intern ("hbar");
23803 staticpro (&Qhbar
);
23804 Qbox
= intern ("box");
23806 Qhollow
= intern ("hollow");
23807 staticpro (&Qhollow
);
23808 Qhand
= intern ("hand");
23809 staticpro (&Qhand
);
23810 Qarrow
= intern ("arrow");
23811 staticpro (&Qarrow
);
23812 Qtext
= intern ("text");
23813 staticpro (&Qtext
);
23814 Qrisky_local_variable
= intern ("risky-local-variable");
23815 staticpro (&Qrisky_local_variable
);
23816 Qinhibit_free_realized_faces
= intern ("inhibit-free-realized-faces");
23817 staticpro (&Qinhibit_free_realized_faces
);
23819 list_of_error
= Fcons (Fcons (intern ("error"),
23820 Fcons (intern ("void-variable"), Qnil
)),
23822 staticpro (&list_of_error
);
23824 Qlast_arrow_position
= intern ("last-arrow-position");
23825 staticpro (&Qlast_arrow_position
);
23826 Qlast_arrow_string
= intern ("last-arrow-string");
23827 staticpro (&Qlast_arrow_string
);
23829 Qoverlay_arrow_string
= intern ("overlay-arrow-string");
23830 staticpro (&Qoverlay_arrow_string
);
23831 Qoverlay_arrow_bitmap
= intern ("overlay-arrow-bitmap");
23832 staticpro (&Qoverlay_arrow_bitmap
);
23834 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
23835 staticpro (&echo_buffer
[0]);
23836 staticpro (&echo_buffer
[1]);
23838 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
23839 staticpro (&echo_area_buffer
[0]);
23840 staticpro (&echo_area_buffer
[1]);
23842 Vmessages_buffer_name
= build_string ("*Messages*");
23843 staticpro (&Vmessages_buffer_name
);
23845 mode_line_proptrans_alist
= Qnil
;
23846 staticpro (&mode_line_proptrans_alist
);
23847 mode_line_string_list
= Qnil
;
23848 staticpro (&mode_line_string_list
);
23849 mode_line_string_face
= Qnil
;
23850 staticpro (&mode_line_string_face
);
23851 mode_line_string_face_prop
= Qnil
;
23852 staticpro (&mode_line_string_face_prop
);
23853 Vmode_line_unwind_vector
= Qnil
;
23854 staticpro (&Vmode_line_unwind_vector
);
23856 help_echo_string
= Qnil
;
23857 staticpro (&help_echo_string
);
23858 help_echo_object
= Qnil
;
23859 staticpro (&help_echo_object
);
23860 help_echo_window
= Qnil
;
23861 staticpro (&help_echo_window
);
23862 previous_help_echo_string
= Qnil
;
23863 staticpro (&previous_help_echo_string
);
23864 help_echo_pos
= -1;
23866 #ifdef HAVE_WINDOW_SYSTEM
23867 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
23868 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
23869 For example, if a block cursor is over a tab, it will be drawn as
23870 wide as that tab on the display. */);
23871 x_stretch_cursor_p
= 0;
23874 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
23875 doc
: /* *Non-nil means highlight trailing whitespace.
23876 The face used for trailing whitespace is `trailing-whitespace'. */);
23877 Vshow_trailing_whitespace
= Qnil
;
23879 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display
,
23880 doc
: /* *Control highlighting of nobreak space and soft hyphen.
23881 A value of t means highlight the character itself (for nobreak space,
23882 use face `nobreak-space').
23883 A value of nil means no highlighting.
23884 Other values mean display the escape glyph followed by an ordinary
23885 space or ordinary hyphen. */);
23886 Vnobreak_char_display
= Qt
;
23888 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer
,
23889 doc
: /* *The pointer shape to show in void text areas.
23890 A value of nil means to show the text pointer. Other options are `arrow',
23891 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
23892 Vvoid_text_area_pointer
= Qarrow
;
23894 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
23895 doc
: /* Non-nil means don't actually do any redisplay.
23896 This is used for internal purposes. */);
23897 Vinhibit_redisplay
= Qnil
;
23899 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
23900 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
23901 Vglobal_mode_string
= Qnil
;
23903 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
23904 doc
: /* Marker for where to display an arrow on top of the buffer text.
23905 This must be the beginning of a line in order to work.
23906 See also `overlay-arrow-string'. */);
23907 Voverlay_arrow_position
= Qnil
;
23909 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
23910 doc
: /* String to display as an arrow in non-window frames.
23911 See also `overlay-arrow-position'. */);
23912 Voverlay_arrow_string
= build_string ("=>");
23914 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list
,
23915 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
23916 The symbols on this list are examined during redisplay to determine
23917 where to display overlay arrows. */);
23918 Voverlay_arrow_variable_list
23919 = Fcons (intern ("overlay-arrow-position"), Qnil
);
23921 DEFVAR_INT ("scroll-step", &scroll_step
,
23922 doc
: /* *The number of lines to try scrolling a window by when point moves out.
23923 If that fails to bring point back on frame, point is centered instead.
23924 If this is zero, point is always centered after it moves off frame.
23925 If you want scrolling to always be a line at a time, you should set
23926 `scroll-conservatively' to a large value rather than set this to 1. */);
23928 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
23929 doc
: /* *Scroll up to this many lines, to bring point back on screen.
23930 A value of zero means to scroll the text to center point vertically
23931 in the window. */);
23932 scroll_conservatively
= 0;
23934 DEFVAR_INT ("scroll-margin", &scroll_margin
,
23935 doc
: /* *Number of lines of margin at the top and bottom of a window.
23936 Recenter the window whenever point gets within this many lines
23937 of the top or bottom of the window. */);
23940 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch
,
23941 doc
: /* Pixels per inch value for non-window system displays.
23942 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
23943 Vdisplay_pixels_per_inch
= make_float (72.0);
23946 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, doc
: /* Don't ask. */);
23949 DEFVAR_BOOL ("truncate-partial-width-windows",
23950 &truncate_partial_width_windows
,
23951 doc
: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
23952 truncate_partial_width_windows
= 1;
23954 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
23955 doc
: /* nil means display the mode-line/header-line/menu-bar in the default face.
23956 Any other value means to use the appropriate face, `mode-line',
23957 `header-line', or `menu' respectively. */);
23958 mode_line_inverse_video
= 1;
23960 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
23961 doc
: /* *Maximum buffer size for which line number should be displayed.
23962 If the buffer is bigger than this, the line number does not appear
23963 in the mode line. A value of nil means no limit. */);
23964 Vline_number_display_limit
= Qnil
;
23966 DEFVAR_INT ("line-number-display-limit-width",
23967 &line_number_display_limit_width
,
23968 doc
: /* *Maximum line width (in characters) for line number display.
23969 If the average length of the lines near point is bigger than this, then the
23970 line number may be omitted from the mode line. */);
23971 line_number_display_limit_width
= 200;
23973 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
23974 doc
: /* *Non-nil means highlight region even in nonselected windows. */);
23975 highlight_nonselected_windows
= 0;
23977 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
23978 doc
: /* Non-nil if more than one frame is visible on this display.
23979 Minibuffer-only frames don't count, but iconified frames do.
23980 This variable is not guaranteed to be accurate except while processing
23981 `frame-title-format' and `icon-title-format'. */);
23983 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
23984 doc
: /* Template for displaying the title bar of visible frames.
23985 \(Assuming the window manager supports this feature.)
23986 This variable has the same structure as `mode-line-format' (which see),
23987 and is used only on frames for which no explicit name has been set
23988 \(see `modify-frame-parameters'). */);
23990 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
23991 doc
: /* Template for displaying the title bar of an iconified frame.
23992 \(Assuming the window manager supports this feature.)
23993 This variable has the same structure as `mode-line-format' (which see),
23994 and is used only on frames for which no explicit name has been set
23995 \(see `modify-frame-parameters'). */);
23997 = Vframe_title_format
23998 = Fcons (intern ("multiple-frames"),
23999 Fcons (build_string ("%b"),
24000 Fcons (Fcons (empty_string
,
24001 Fcons (intern ("invocation-name"),
24002 Fcons (build_string ("@"),
24003 Fcons (intern ("system-name"),
24007 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
24008 doc
: /* Maximum number of lines to keep in the message log buffer.
24009 If nil, disable message logging. If t, log messages but don't truncate
24010 the buffer when it becomes large. */);
24011 Vmessage_log_max
= make_number (50);
24013 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
24014 doc
: /* Functions called before redisplay, if window sizes have changed.
24015 The value should be a list of functions that take one argument.
24016 Just before redisplay, for each frame, if any of its windows have changed
24017 size since the last redisplay, or have been split or deleted,
24018 all the functions in the list are called, with the frame as argument. */);
24019 Vwindow_size_change_functions
= Qnil
;
24021 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
24022 doc
: /* List of functions to call before redisplaying a window with scrolling.
24023 Each function is called with two arguments, the window
24024 and its new display-start position. Note that the value of `window-end'
24025 is not valid when these functions are called. */);
24026 Vwindow_scroll_functions
= Qnil
;
24028 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions
,
24029 doc
: /* Functions called when redisplay of a window reaches the end trigger.
24030 Each function is called with two arguments, the window and the end trigger value.
24031 See `set-window-redisplay-end-trigger'. */);
24032 Vredisplay_end_trigger_functions
= Qnil
;
24034 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window
,
24035 doc
: /* *Non-nil means autoselect window with mouse pointer.
24036 If nil, do not autoselect windows.
24037 A positive number means delay autoselection by that many seconds: a
24038 window is autoselected only after the mouse has remained in that
24039 window for the duration of the delay.
24040 A negative number has a similar effect, but causes windows to be
24041 autoselected only after the mouse has stopped moving. \(Because of
24042 the way Emacs compares mouse events, you will occasionally wait twice
24043 that time before the window gets selected.\)
24044 Any other value means to autoselect window instantaneously when the
24045 mouse pointer enters it.
24047 Autoselection selects the minibuffer only if it is active, and never
24048 unselects the minibuffer if it is active. */);
24049 Vmouse_autoselect_window
= Qnil
;
24051 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p
,
24052 doc
: /* *Non-nil means automatically resize tool-bars.
24053 This increases a tool-bar's height if not all tool-bar items are visible.
24054 It decreases a tool-bar's height when it would display blank lines
24056 auto_resize_tool_bars_p
= 1;
24058 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
24059 doc
: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
24060 auto_raise_tool_bar_buttons_p
= 1;
24062 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p
,
24063 doc
: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
24064 make_cursor_line_fully_visible_p
= 1;
24066 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border
,
24067 doc
: /* *Border below tool-bar in pixels.
24068 If an integer, use it as the height of the border.
24069 If it is one of `internal-border-width' or `border-width', use the
24070 value of the corresponding frame parameter.
24071 Otherwise, no border is added below the tool-bar. */);
24072 Vtool_bar_border
= Qinternal_border_width
;
24074 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin
,
24075 doc
: /* *Margin around tool-bar buttons in pixels.
24076 If an integer, use that for both horizontal and vertical margins.
24077 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
24078 HORZ specifying the horizontal margin, and VERT specifying the
24079 vertical margin. */);
24080 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
24082 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
24083 doc
: /* *Relief thickness of tool-bar buttons. */);
24084 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
24086 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
24087 doc
: /* List of functions to call to fontify regions of text.
24088 Each function is called with one argument POS. Functions must
24089 fontify a region starting at POS in the current buffer, and give
24090 fontified regions the property `fontified'. */);
24091 Vfontification_functions
= Qnil
;
24092 Fmake_variable_buffer_local (Qfontification_functions
);
24094 DEFVAR_BOOL ("unibyte-display-via-language-environment",
24095 &unibyte_display_via_language_environment
,
24096 doc
: /* *Non-nil means display unibyte text according to language environment.
24097 Specifically this means that unibyte non-ASCII characters
24098 are displayed by converting them to the equivalent multibyte characters
24099 according to the current language environment. As a result, they are
24100 displayed according to the current fontset. */);
24101 unibyte_display_via_language_environment
= 0;
24103 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
24104 doc
: /* *Maximum height for resizing mini-windows.
24105 If a float, it specifies a fraction of the mini-window frame's height.
24106 If an integer, it specifies a number of lines. */);
24107 Vmax_mini_window_height
= make_float (0.25);
24109 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
24110 doc
: /* *How to resize mini-windows.
24111 A value of nil means don't automatically resize mini-windows.
24112 A value of t means resize them to fit the text displayed in them.
24113 A value of `grow-only', the default, means let mini-windows grow
24114 only, until their display becomes empty, at which point the windows
24115 go back to their normal size. */);
24116 Vresize_mini_windows
= Qgrow_only
;
24118 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist
,
24119 doc
: /* Alist specifying how to blink the cursor off.
24120 Each element has the form (ON-STATE . OFF-STATE). Whenever the
24121 `cursor-type' frame-parameter or variable equals ON-STATE,
24122 comparing using `equal', Emacs uses OFF-STATE to specify
24123 how to blink it off. ON-STATE and OFF-STATE are values for
24124 the `cursor-type' frame parameter.
24126 If a frame's ON-STATE has no entry in this list,
24127 the frame's other specifications determine how to blink the cursor off. */);
24128 Vblink_cursor_alist
= Qnil
;
24130 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p
,
24131 doc
: /* *Non-nil means scroll the display automatically to make point visible. */);
24132 automatic_hscrolling_p
= 1;
24134 DEFVAR_INT ("hscroll-margin", &hscroll_margin
,
24135 doc
: /* *How many columns away from the window edge point is allowed to get
24136 before automatic hscrolling will horizontally scroll the window. */);
24137 hscroll_margin
= 5;
24139 DEFVAR_LISP ("hscroll-step", &Vhscroll_step
,
24140 doc
: /* *How many columns to scroll the window when point gets too close to the edge.
24141 When point is less than `hscroll-margin' columns from the window
24142 edge, automatic hscrolling will scroll the window by the amount of columns
24143 determined by this variable. If its value is a positive integer, scroll that
24144 many columns. If it's a positive floating-point number, it specifies the
24145 fraction of the window's width to scroll. If it's nil or zero, point will be
24146 centered horizontally after the scroll. Any other value, including negative
24147 numbers, are treated as if the value were zero.
24149 Automatic hscrolling always moves point outside the scroll margin, so if
24150 point was more than scroll step columns inside the margin, the window will
24151 scroll more than the value given by the scroll step.
24153 Note that the lower bound for automatic hscrolling specified by `scroll-left'
24154 and `scroll-right' overrides this variable's effect. */);
24155 Vhscroll_step
= make_number (0);
24157 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
24158 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
24159 Bind this around calls to `message' to let it take effect. */);
24160 message_truncate_lines
= 0;
24162 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
24163 doc
: /* Normal hook run to update the menu bar definitions.
24164 Redisplay runs this hook before it redisplays the menu bar.
24165 This is used to update submenus such as Buffers,
24166 whose contents depend on various data. */);
24167 Vmenu_bar_update_hook
= Qnil
;
24169 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame
,
24170 doc
: /* Frame for which we are updating a menu.
24171 The enable predicate for a menu binding should check this variable. */);
24172 Vmenu_updating_frame
= Qnil
;
24174 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update
,
24175 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
24176 inhibit_menubar_update
= 0;
24178 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay
,
24179 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
24180 inhibit_eval_during_redisplay
= 0;
24182 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces
,
24183 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
24184 inhibit_free_realized_faces
= 0;
24187 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id
,
24188 doc
: /* Inhibit try_window_id display optimization. */);
24189 inhibit_try_window_id
= 0;
24191 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing
,
24192 doc
: /* Inhibit try_window_reusing display optimization. */);
24193 inhibit_try_window_reusing
= 0;
24195 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement
,
24196 doc
: /* Inhibit try_cursor_movement display optimization. */);
24197 inhibit_try_cursor_movement
= 0;
24198 #endif /* GLYPH_DEBUG */
24200 DEFVAR_INT ("overline-margin", &overline_margin
,
24201 doc
: /* *Space between overline and text, in pixels.
24202 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
24203 margin to the caracter height. */);
24204 overline_margin
= 2;
24208 /* Initialize this module when Emacs starts. */
24213 Lisp_Object root_window
;
24214 struct window
*mini_w
;
24216 current_header_line_height
= current_mode_line_height
= -1;
24218 CHARPOS (this_line_start_pos
) = 0;
24220 mini_w
= XWINDOW (minibuf_window
);
24221 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
24223 if (!noninteractive
)
24225 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
24228 XWINDOW (root_window
)->top_line
= make_number (FRAME_TOP_MARGIN (f
));
24229 set_window_height (root_window
,
24230 FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
),
24232 mini_w
->top_line
= make_number (FRAME_LINES (f
) - 1);
24233 set_window_height (minibuf_window
, 1, 0);
24235 XWINDOW (root_window
)->total_cols
= make_number (FRAME_COLS (f
));
24236 mini_w
->total_cols
= make_number (FRAME_COLS (f
));
24238 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
24239 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
24240 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
24242 /* The default ellipsis glyphs `...'. */
24243 for (i
= 0; i
< 3; ++i
)
24244 default_invis_vector
[i
] = make_number ('.');
24248 /* Allocate the buffer for frame titles.
24249 Also used for `format-mode-line'. */
24251 mode_line_noprop_buf
= (char *) xmalloc (size
);
24252 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
24253 mode_line_noprop_ptr
= mode_line_noprop_buf
;
24254 mode_line_target
= MODE_LINE_DISPLAY
;
24257 help_echo_showing_p
= 0;
24261 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
24262 (do not change this comment) */