merge trunk
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2
3 Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
4 Inc.
5
6 This file is part of GNU Emacs.
7
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 3 of the License, or
11 (at your option) any later version.
12
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.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
22
23 Redisplay.
24
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
29
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
35
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa. Under window systems
38 like X, some portions of the redisplay code are also called
39 asynchronously during mouse movement or expose events. It is very
40 important that these code parts do NOT use the C library (malloc,
41 free) because many C libraries under Unix are not reentrant. They
42 may also NOT call functions of the Lisp interpreter which could
43 change the interpreter's state. If you don't follow these rules,
44 you will encounter bugs which are very hard to explain.
45
46 +--------------+ redisplay +----------------+
47 | Lisp machine |---------------->| Redisplay code |<--+
48 +--------------+ (xdisp.c) +----------------+ |
49 ^ | |
50 +----------------------------------+ |
51 Don't use this path when called |
52 asynchronously! |
53 |
54 expose_window (asynchronous) |
55 |
56 X expose events -----+
57
58 What does redisplay do? Obviously, it has to figure out somehow what
59 has been changed since the last time the display has been updated,
60 and to make these changes visible. Preferably it would do that in
61 a moderately intelligent way, i.e. fast.
62
63 Changes in buffer text can be deduced from window and buffer
64 structures, and from some global variables like `beg_unchanged' and
65 `end_unchanged'. The contents of the display are additionally
66 recorded in a `glyph matrix', a two-dimensional matrix of glyph
67 structures. Each row in such a matrix corresponds to a line on the
68 display, and each glyph in a row corresponds to a column displaying
69 a character, an image, or what else. This matrix is called the
70 `current glyph matrix' or `current matrix' in redisplay
71 terminology.
72
73 For buffer parts that have been changed since the last update, a
74 second glyph matrix is constructed, the so called `desired glyph
75 matrix' or short `desired matrix'. Current and desired matrix are
76 then compared to find a cheap way to update the display, e.g. by
77 reusing part of the display by scrolling lines.
78
79 You will find a lot of redisplay optimizations when you start
80 looking at the innards of redisplay. The overall goal of all these
81 optimizations is to make redisplay fast because it is done
82 frequently. Some of these optimizations are implemented by the
83 following functions:
84
85 . try_cursor_movement
86
87 This function tries to update the display if the text in the
88 window did not change and did not scroll, only point moved, and
89 it did not move off the displayed portion of the text.
90
91 . try_window_reusing_current_matrix
92
93 This function reuses the current matrix of a window when text
94 has not changed, but the window start changed (e.g., due to
95 scrolling).
96
97 . try_window_id
98
99 This function attempts to redisplay a window by reusing parts of
100 its existing display. It finds and reuses the part that was not
101 changed, and redraws the rest.
102
103 . try_window
104
105 This function performs the full redisplay of a single window
106 assuming that its fonts were not changed and that the cursor
107 will not end up in the scroll margins. (Loading fonts requires
108 re-adjustment of dimensions of glyph matrices, which makes this
109 method impossible to use.)
110
111 These optimizations are tried in sequence (some can be skipped if
112 it is known that they are not applicable). If none of the
113 optimizations were successful, redisplay calls redisplay_windows,
114 which performs a full redisplay of all windows.
115
116 Desired matrices.
117
118 Desired matrices are always built per Emacs window. The function
119 `display_line' is the central function to look at if you are
120 interested. It constructs one row in a desired matrix given an
121 iterator structure containing both a buffer position and a
122 description of the environment in which the text is to be
123 displayed. But this is too early, read on.
124
125 Characters and pixmaps displayed for a range of buffer text depend
126 on various settings of buffers and windows, on overlays and text
127 properties, on display tables, on selective display. The good news
128 is that all this hairy stuff is hidden behind a small set of
129 interface functions taking an iterator structure (struct it)
130 argument.
131
132 Iteration over things to be displayed is then simple. It is
133 started by initializing an iterator with a call to init_iterator,
134 passing it the buffer position where to start iteration. For
135 iteration over strings, pass -1 as the position to init_iterator,
136 and call reseat_to_string when the string is ready, to initialize
137 the iterator for that string. Thereafter, calls to
138 get_next_display_element fill the iterator structure with relevant
139 information about the next thing to display. Calls to
140 set_iterator_to_next move the iterator to the next thing.
141
142 Besides this, an iterator also contains information about the
143 display environment in which glyphs for display elements are to be
144 produced. It has fields for the width and height of the display,
145 the information whether long lines are truncated or continued, a
146 current X and Y position, and lots of other stuff you can better
147 see in dispextern.h.
148
149 Glyphs in a desired matrix are normally constructed in a loop
150 calling get_next_display_element and then PRODUCE_GLYPHS. The call
151 to PRODUCE_GLYPHS will fill the iterator structure with pixel
152 information about the element being displayed and at the same time
153 produce glyphs for it. If the display element fits on the line
154 being displayed, set_iterator_to_next is called next, otherwise the
155 glyphs produced are discarded. The function display_line is the
156 workhorse of filling glyph rows in the desired matrix with glyphs.
157 In addition to producing glyphs, it also handles line truncation
158 and continuation, word wrap, and cursor positioning (for the
159 latter, see also set_cursor_from_row).
160
161 Frame matrices.
162
163 That just couldn't be all, could it? What about terminal types not
164 supporting operations on sub-windows of the screen? To update the
165 display on such a terminal, window-based glyph matrices are not
166 well suited. To be able to reuse part of the display (scrolling
167 lines up and down), we must instead have a view of the whole
168 screen. This is what `frame matrices' are for. They are a trick.
169
170 Frames on terminals like above have a glyph pool. Windows on such
171 a frame sub-allocate their glyph memory from their frame's glyph
172 pool. The frame itself is given its own glyph matrices. By
173 coincidence---or maybe something else---rows in window glyph
174 matrices are slices of corresponding rows in frame matrices. Thus
175 writing to window matrices implicitly updates a frame matrix which
176 provides us with the view of the whole screen that we originally
177 wanted to have without having to move many bytes around. To be
178 honest, there is a little bit more done, but not much more. If you
179 plan to extend that code, take a look at dispnew.c. The function
180 build_frame_matrix is a good starting point.
181
182 Bidirectional display.
183
184 Bidirectional display adds quite some hair to this already complex
185 design. The good news are that a large portion of that hairy stuff
186 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
187 reordering engine which is called by set_iterator_to_next and
188 returns the next character to display in the visual order. See
189 commentary on bidi.c for more details. As far as redisplay is
190 concerned, the effect of calling bidi_move_to_visually_next, the
191 main interface of the reordering engine, is that the iterator gets
192 magically placed on the buffer or string position that is to be
193 displayed next. In other words, a linear iteration through the
194 buffer/string is replaced with a non-linear one. All the rest of
195 the redisplay is oblivious to the bidi reordering.
196
197 Well, almost oblivious---there are still complications, most of
198 them due to the fact that buffer and string positions no longer
199 change monotonously with glyph indices in a glyph row. Moreover,
200 for continued lines, the buffer positions may not even be
201 monotonously changing with vertical positions. Also, accounting
202 for face changes, overlays, etc. becomes more complex because
203 non-linear iteration could potentially skip many positions with
204 changes, and then cross them again on the way back...
205
206 One other prominent effect of bidirectional display is that some
207 paragraphs of text need to be displayed starting at the right
208 margin of the window---the so-called right-to-left, or R2L
209 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
210 which have their reversed_p flag set. The bidi reordering engine
211 produces characters in such rows starting from the character which
212 should be the rightmost on display. PRODUCE_GLYPHS then reverses
213 the order, when it fills up the glyph row whose reversed_p flag is
214 set, by prepending each new glyph to what is already there, instead
215 of appending it. When the glyph row is complete, the function
216 extend_face_to_end_of_line fills the empty space to the left of the
217 leftmost character with special glyphs, which will display as,
218 well, empty. On text terminals, these special glyphs are simply
219 blank characters. On graphics terminals, there's a single stretch
220 glyph of a suitably computed width. Both the blanks and the
221 stretch glyph are given the face of the background of the line.
222 This way, the terminal-specific back-end can still draw the glyphs
223 left to right, even for R2L lines.
224
225 Bidirectional display and character compositions
226
227 Some scripts cannot be displayed by drawing each character
228 individually, because adjacent characters change each other's shape
229 on display. For example, Arabic and Indic scripts belong to this
230 category.
231
232 Emacs display supports this by providing "character compositions",
233 most of which is implemented in composite.c. During the buffer
234 scan that delivers characters to PRODUCE_GLYPHS, if the next
235 character to be delivered is a composed character, the iteration
236 calls composition_reseat_it and next_element_from_composition. If
237 they succeed to compose the character with one or more of the
238 following characters, the whole sequence of characters that where
239 composed is recorded in the `struct composition_it' object that is
240 part of the buffer iterator. The composed sequence could produce
241 one or more font glyphs (called "grapheme clusters") on the screen.
242 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
243 in the direction corresponding to the current bidi scan direction
244 (recorded in the scan_dir member of the `struct bidi_it' object
245 that is part of the buffer iterator). In particular, if the bidi
246 iterator currently scans the buffer backwards, the grapheme
247 clusters are delivered back to front. This reorders the grapheme
248 clusters as appropriate for the current bidi context. Note that
249 this means that the grapheme clusters are always stored in the
250 LGSTRING object (see composite.c) in the logical order.
251
252 Moving an iterator in bidirectional text
253 without producing glyphs
254
255 Note one important detail mentioned above: that the bidi reordering
256 engine, driven by the iterator, produces characters in R2L rows
257 starting at the character that will be the rightmost on display.
258 As far as the iterator is concerned, the geometry of such rows is
259 still left to right, i.e. the iterator "thinks" the first character
260 is at the leftmost pixel position. The iterator does not know that
261 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
262 delivers. This is important when functions from the move_it_*
263 family are used to get to certain screen position or to match
264 screen coordinates with buffer coordinates: these functions use the
265 iterator geometry, which is left to right even in R2L paragraphs.
266 This works well with most callers of move_it_*, because they need
267 to get to a specific column, and columns are still numbered in the
268 reading order, i.e. the rightmost character in a R2L paragraph is
269 still column zero. But some callers do not get well with this; a
270 notable example is mouse clicks that need to find the character
271 that corresponds to certain pixel coordinates. See
272 buffer_posn_from_coords in dispnew.c for how this is handled. */
273
274 #include <config.h>
275 #include <stdio.h>
276 #include <limits.h>
277
278 #include "lisp.h"
279 #include "atimer.h"
280 #include "keyboard.h"
281 #include "frame.h"
282 #include "window.h"
283 #include "termchar.h"
284 #include "dispextern.h"
285 #include "character.h"
286 #include "buffer.h"
287 #include "charset.h"
288 #include "indent.h"
289 #include "commands.h"
290 #include "keymap.h"
291 #include "macros.h"
292 #include "disptab.h"
293 #include "termhooks.h"
294 #include "termopts.h"
295 #include "intervals.h"
296 #include "coding.h"
297 #include "process.h"
298 #include "region-cache.h"
299 #include "font.h"
300 #include "fontset.h"
301 #include "blockinput.h"
302 #ifdef HAVE_WINDOW_SYSTEM
303 #include TERM_HEADER
304 #endif /* HAVE_WINDOW_SYSTEM */
305
306 #ifndef FRAME_X_OUTPUT
307 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
308 #endif
309
310 #define INFINITY 10000000
311
312 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
313 Lisp_Object Qwindow_scroll_functions;
314 static Lisp_Object Qwindow_text_change_functions;
315 static Lisp_Object Qredisplay_end_trigger_functions;
316 Lisp_Object Qinhibit_point_motion_hooks;
317 static Lisp_Object QCeval, QCpropertize;
318 Lisp_Object QCfile, QCdata;
319 static Lisp_Object Qfontified;
320 static Lisp_Object Qgrow_only;
321 static Lisp_Object Qinhibit_eval_during_redisplay;
322 static Lisp_Object Qbuffer_position, Qposition, Qobject;
323 static Lisp_Object Qright_to_left, Qleft_to_right;
324
325 /* Cursor shapes. */
326 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
327
328 /* Pointer shapes. */
329 static Lisp_Object Qarrow, Qhand;
330 Lisp_Object Qtext;
331
332 /* Holds the list (error). */
333 static Lisp_Object list_of_error;
334
335 static Lisp_Object Qfontification_functions;
336
337 static Lisp_Object Qwrap_prefix;
338 static Lisp_Object Qline_prefix;
339 static Lisp_Object Qredisplay_internal;
340
341 /* Non-nil means don't actually do any redisplay. */
342
343 Lisp_Object Qinhibit_redisplay;
344
345 /* Names of text properties relevant for redisplay. */
346
347 Lisp_Object Qdisplay;
348
349 Lisp_Object Qspace, QCalign_to;
350 static Lisp_Object QCrelative_width, QCrelative_height;
351 Lisp_Object Qleft_margin, Qright_margin;
352 static Lisp_Object Qspace_width, Qraise;
353 static Lisp_Object Qslice;
354 Lisp_Object Qcenter;
355 static Lisp_Object Qmargin, Qpointer;
356 static Lisp_Object Qline_height;
357
358 #ifdef HAVE_WINDOW_SYSTEM
359
360 /* Test if overflow newline into fringe. Called with iterator IT
361 at or past right window margin, and with IT->current_x set. */
362
363 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
364 (!NILP (Voverflow_newline_into_fringe) \
365 && FRAME_WINDOW_P ((IT)->f) \
366 && ((IT)->bidi_it.paragraph_dir == R2L \
367 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
368 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
369 && (IT)->current_x == (IT)->last_visible_x)
370
371 #else /* !HAVE_WINDOW_SYSTEM */
372 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
373 #endif /* HAVE_WINDOW_SYSTEM */
374
375 /* Test if the display element loaded in IT, or the underlying buffer
376 or string character, is a space or a TAB character. This is used
377 to determine where word wrapping can occur. */
378
379 #define IT_DISPLAYING_WHITESPACE(it) \
380 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
381 || ((STRINGP (it->string) \
382 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
383 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
384 || (it->s \
385 && (it->s[IT_BYTEPOS (*it)] == ' ' \
386 || it->s[IT_BYTEPOS (*it)] == '\t')) \
387 || (IT_BYTEPOS (*it) < ZV_BYTE \
388 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
389 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
390
391 /* Name of the face used to highlight trailing whitespace. */
392
393 static Lisp_Object Qtrailing_whitespace;
394
395 /* Name and number of the face used to highlight escape glyphs. */
396
397 static Lisp_Object Qescape_glyph;
398
399 /* Name and number of the face used to highlight non-breaking spaces. */
400
401 static Lisp_Object Qnobreak_space;
402
403 /* The symbol `image' which is the car of the lists used to represent
404 images in Lisp. Also a tool bar style. */
405
406 Lisp_Object Qimage;
407
408 /* The image map types. */
409 Lisp_Object QCmap;
410 static Lisp_Object QCpointer;
411 static Lisp_Object Qrect, Qcircle, Qpoly;
412
413 /* Tool bar styles */
414 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
415
416 /* Non-zero means print newline to stdout before next mini-buffer
417 message. */
418
419 int noninteractive_need_newline;
420
421 /* Non-zero means print newline to message log before next message. */
422
423 static int message_log_need_newline;
424
425 /* Three markers that message_dolog uses.
426 It could allocate them itself, but that causes trouble
427 in handling memory-full errors. */
428 static Lisp_Object message_dolog_marker1;
429 static Lisp_Object message_dolog_marker2;
430 static Lisp_Object message_dolog_marker3;
431 \f
432 /* The buffer position of the first character appearing entirely or
433 partially on the line of the selected window which contains the
434 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
435 redisplay optimization in redisplay_internal. */
436
437 static struct text_pos this_line_start_pos;
438
439 /* Number of characters past the end of the line above, including the
440 terminating newline. */
441
442 static struct text_pos this_line_end_pos;
443
444 /* The vertical positions and the height of this line. */
445
446 static int this_line_vpos;
447 static int this_line_y;
448 static int this_line_pixel_height;
449
450 /* X position at which this display line starts. Usually zero;
451 negative if first character is partially visible. */
452
453 static int this_line_start_x;
454
455 /* The smallest character position seen by move_it_* functions as they
456 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
457 hscrolled lines, see display_line. */
458
459 static struct text_pos this_line_min_pos;
460
461 /* Buffer that this_line_.* variables are referring to. */
462
463 static struct buffer *this_line_buffer;
464
465
466 /* Values of those variables at last redisplay are stored as
467 properties on `overlay-arrow-position' symbol. However, if
468 Voverlay_arrow_position is a marker, last-arrow-position is its
469 numerical position. */
470
471 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
472
473 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
474 properties on a symbol in overlay-arrow-variable-list. */
475
476 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
477
478 Lisp_Object Qmenu_bar_update_hook;
479
480 /* Nonzero if an overlay arrow has been displayed in this window. */
481
482 static int overlay_arrow_seen;
483
484 /* Vector containing glyphs for an ellipsis `...'. */
485
486 static Lisp_Object default_invis_vector[3];
487
488 /* This is the window where the echo area message was displayed. It
489 is always a mini-buffer window, but it may not be the same window
490 currently active as a mini-buffer. */
491
492 Lisp_Object echo_area_window;
493
494 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
495 pushes the current message and the value of
496 message_enable_multibyte on the stack, the function restore_message
497 pops the stack and displays MESSAGE again. */
498
499 static Lisp_Object Vmessage_stack;
500
501 /* Nonzero means multibyte characters were enabled when the echo area
502 message was specified. */
503
504 static int message_enable_multibyte;
505
506 /* Nonzero if we should redraw the mode lines on the next redisplay. */
507
508 int update_mode_lines;
509
510 /* Nonzero if window sizes or contents have changed since last
511 redisplay that finished. */
512
513 int windows_or_buffers_changed;
514
515 /* Nonzero after display_mode_line if %l was used and it displayed a
516 line number. */
517
518 static int line_number_displayed;
519
520 /* The name of the *Messages* buffer, a string. */
521
522 static Lisp_Object Vmessages_buffer_name;
523
524 /* Current, index 0, and last displayed echo area message. Either
525 buffers from echo_buffers, or nil to indicate no message. */
526
527 Lisp_Object echo_area_buffer[2];
528
529 /* The buffers referenced from echo_area_buffer. */
530
531 static Lisp_Object echo_buffer[2];
532
533 /* A vector saved used in with_area_buffer to reduce consing. */
534
535 static Lisp_Object Vwith_echo_area_save_vector;
536
537 /* Non-zero means display_echo_area should display the last echo area
538 message again. Set by redisplay_preserve_echo_area. */
539
540 static int display_last_displayed_message_p;
541
542 /* Nonzero if echo area is being used by print; zero if being used by
543 message. */
544
545 static int message_buf_print;
546
547 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
548
549 static Lisp_Object Qinhibit_menubar_update;
550 static Lisp_Object Qmessage_truncate_lines;
551
552 /* Set to 1 in clear_message to make redisplay_internal aware
553 of an emptied echo area. */
554
555 static int message_cleared_p;
556
557 /* A scratch glyph row with contents used for generating truncation
558 glyphs. Also used in direct_output_for_insert. */
559
560 #define MAX_SCRATCH_GLYPHS 100
561 static struct glyph_row scratch_glyph_row;
562 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
563
564 /* Ascent and height of the last line processed by move_it_to. */
565
566 static int last_height;
567
568 /* Non-zero if there's a help-echo in the echo area. */
569
570 int help_echo_showing_p;
571
572 /* The maximum distance to look ahead for text properties. Values
573 that are too small let us call compute_char_face and similar
574 functions too often which is expensive. Values that are too large
575 let us call compute_char_face and alike too often because we
576 might not be interested in text properties that far away. */
577
578 #define TEXT_PROP_DISTANCE_LIMIT 100
579
580 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
581 iterator state and later restore it. This is needed because the
582 bidi iterator on bidi.c keeps a stacked cache of its states, which
583 is really a singleton. When we use scratch iterator objects to
584 move around the buffer, we can cause the bidi cache to be pushed or
585 popped, and therefore we need to restore the cache state when we
586 return to the original iterator. */
587 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
588 do { \
589 if (CACHE) \
590 bidi_unshelve_cache (CACHE, 1); \
591 ITCOPY = ITORIG; \
592 CACHE = bidi_shelve_cache (); \
593 } while (0)
594
595 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
596 do { \
597 if (pITORIG != pITCOPY) \
598 *(pITORIG) = *(pITCOPY); \
599 bidi_unshelve_cache (CACHE, 0); \
600 CACHE = NULL; \
601 } while (0)
602
603 #ifdef GLYPH_DEBUG
604
605 /* Non-zero means print traces of redisplay if compiled with
606 GLYPH_DEBUG defined. */
607
608 int trace_redisplay_p;
609
610 #endif /* GLYPH_DEBUG */
611
612 #ifdef DEBUG_TRACE_MOVE
613 /* Non-zero means trace with TRACE_MOVE to stderr. */
614 int trace_move;
615
616 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
617 #else
618 #define TRACE_MOVE(x) (void) 0
619 #endif
620
621 static Lisp_Object Qauto_hscroll_mode;
622
623 /* Buffer being redisplayed -- for redisplay_window_error. */
624
625 static struct buffer *displayed_buffer;
626
627 /* Value returned from text property handlers (see below). */
628
629 enum prop_handled
630 {
631 HANDLED_NORMALLY,
632 HANDLED_RECOMPUTE_PROPS,
633 HANDLED_OVERLAY_STRING_CONSUMED,
634 HANDLED_RETURN
635 };
636
637 /* A description of text properties that redisplay is interested
638 in. */
639
640 struct props
641 {
642 /* The name of the property. */
643 Lisp_Object *name;
644
645 /* A unique index for the property. */
646 enum prop_idx idx;
647
648 /* A handler function called to set up iterator IT from the property
649 at IT's current position. Value is used to steer handle_stop. */
650 enum prop_handled (*handler) (struct it *it);
651 };
652
653 static enum prop_handled handle_face_prop (struct it *);
654 static enum prop_handled handle_invisible_prop (struct it *);
655 static enum prop_handled handle_display_prop (struct it *);
656 static enum prop_handled handle_composition_prop (struct it *);
657 static enum prop_handled handle_overlay_change (struct it *);
658 static enum prop_handled handle_fontified_prop (struct it *);
659
660 /* Properties handled by iterators. */
661
662 static struct props it_props[] =
663 {
664 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
665 /* Handle `face' before `display' because some sub-properties of
666 `display' need to know the face. */
667 {&Qface, FACE_PROP_IDX, handle_face_prop},
668 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
669 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
670 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
671 {NULL, 0, NULL}
672 };
673
674 /* Value is the position described by X. If X is a marker, value is
675 the marker_position of X. Otherwise, value is X. */
676
677 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
678
679 /* Enumeration returned by some move_it_.* functions internally. */
680
681 enum move_it_result
682 {
683 /* Not used. Undefined value. */
684 MOVE_UNDEFINED,
685
686 /* Move ended at the requested buffer position or ZV. */
687 MOVE_POS_MATCH_OR_ZV,
688
689 /* Move ended at the requested X pixel position. */
690 MOVE_X_REACHED,
691
692 /* Move within a line ended at the end of a line that must be
693 continued. */
694 MOVE_LINE_CONTINUED,
695
696 /* Move within a line ended at the end of a line that would
697 be displayed truncated. */
698 MOVE_LINE_TRUNCATED,
699
700 /* Move within a line ended at a line end. */
701 MOVE_NEWLINE_OR_CR
702 };
703
704 /* This counter is used to clear the face cache every once in a while
705 in redisplay_internal. It is incremented for each redisplay.
706 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
707 cleared. */
708
709 #define CLEAR_FACE_CACHE_COUNT 500
710 static int clear_face_cache_count;
711
712 /* Similarly for the image cache. */
713
714 #ifdef HAVE_WINDOW_SYSTEM
715 #define CLEAR_IMAGE_CACHE_COUNT 101
716 static int clear_image_cache_count;
717
718 /* Null glyph slice */
719 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
720 #endif
721
722 /* True while redisplay_internal is in progress. */
723
724 bool redisplaying_p;
725
726 static Lisp_Object Qinhibit_free_realized_faces;
727 static Lisp_Object Qmode_line_default_help_echo;
728
729 /* If a string, XTread_socket generates an event to display that string.
730 (The display is done in read_char.) */
731
732 Lisp_Object help_echo_string;
733 Lisp_Object help_echo_window;
734 Lisp_Object help_echo_object;
735 ptrdiff_t help_echo_pos;
736
737 /* Temporary variable for XTread_socket. */
738
739 Lisp_Object previous_help_echo_string;
740
741 /* Platform-independent portion of hourglass implementation. */
742
743 #ifdef HAVE_WINDOW_SYSTEM
744
745 /* Non-zero means an hourglass cursor is currently shown. */
746 int hourglass_shown_p;
747
748 /* If non-null, an asynchronous timer that, when it expires, displays
749 an hourglass cursor on all frames. */
750 struct atimer *hourglass_atimer;
751
752 #endif /* HAVE_WINDOW_SYSTEM */
753
754 /* Name of the face used to display glyphless characters. */
755 Lisp_Object Qglyphless_char;
756
757 /* Symbol for the purpose of Vglyphless_char_display. */
758 static Lisp_Object Qglyphless_char_display;
759
760 /* Method symbols for Vglyphless_char_display. */
761 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
762
763 /* Default number of seconds to wait before displaying an hourglass
764 cursor. */
765 #define DEFAULT_HOURGLASS_DELAY 1
766
767 #ifdef HAVE_WINDOW_SYSTEM
768
769 /* Default pixel width of `thin-space' display method. */
770 #define THIN_SPACE_WIDTH 1
771
772 #endif /* HAVE_WINDOW_SYSTEM */
773
774 /* Function prototypes. */
775
776 static void setup_for_ellipsis (struct it *, int);
777 static void set_iterator_to_next (struct it *, int);
778 static void mark_window_display_accurate_1 (struct window *, int);
779 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
780 static int display_prop_string_p (Lisp_Object, Lisp_Object);
781 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
782 static int cursor_row_p (struct glyph_row *);
783 static int redisplay_mode_lines (Lisp_Object, int);
784 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
785
786 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
787
788 static void handle_line_prefix (struct it *);
789
790 static void pint2str (char *, int, ptrdiff_t);
791 static void pint2hrstr (char *, int, ptrdiff_t);
792 static struct text_pos run_window_scroll_functions (Lisp_Object,
793 struct text_pos);
794 static int text_outside_line_unchanged_p (struct window *,
795 ptrdiff_t, ptrdiff_t);
796 static void store_mode_line_noprop_char (char);
797 static int store_mode_line_noprop (const char *, int, int);
798 static void handle_stop (struct it *);
799 static void handle_stop_backwards (struct it *, ptrdiff_t);
800 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
801 static void ensure_echo_area_buffers (void);
802 static void unwind_with_echo_area_buffer (Lisp_Object);
803 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
804 static int with_echo_area_buffer (struct window *, int,
805 int (*) (ptrdiff_t, Lisp_Object),
806 ptrdiff_t, Lisp_Object);
807 static void clear_garbaged_frames (void);
808 static int current_message_1 (ptrdiff_t, Lisp_Object);
809 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
810 static void set_message (Lisp_Object);
811 static int set_message_1 (ptrdiff_t, Lisp_Object);
812 static int display_echo_area (struct window *);
813 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
814 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
815 static void unwind_redisplay (void);
816 static int string_char_and_length (const unsigned char *, int *);
817 static struct text_pos display_prop_end (struct it *, Lisp_Object,
818 struct text_pos);
819 static int compute_window_start_on_continuation_line (struct window *);
820 static void insert_left_trunc_glyphs (struct it *);
821 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
822 Lisp_Object);
823 static void extend_face_to_end_of_line (struct it *);
824 static int append_space_for_newline (struct it *, int);
825 static int cursor_row_fully_visible_p (struct window *, int, int);
826 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
827 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
828 static int trailing_whitespace_p (ptrdiff_t);
829 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
830 static void push_it (struct it *, struct text_pos *);
831 static void iterate_out_of_display_property (struct it *);
832 static void pop_it (struct it *);
833 static void sync_frame_with_window_matrix_rows (struct window *);
834 static void redisplay_internal (void);
835 static int echo_area_display (int);
836 static void redisplay_windows (Lisp_Object);
837 static void redisplay_window (Lisp_Object, int);
838 static Lisp_Object redisplay_window_error (Lisp_Object);
839 static Lisp_Object redisplay_window_0 (Lisp_Object);
840 static Lisp_Object redisplay_window_1 (Lisp_Object);
841 static int set_cursor_from_row (struct window *, struct glyph_row *,
842 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
843 int, int);
844 static int update_menu_bar (struct frame *, int, int);
845 static int try_window_reusing_current_matrix (struct window *);
846 static int try_window_id (struct window *);
847 static int display_line (struct it *);
848 static int display_mode_lines (struct window *);
849 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
850 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
851 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
852 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
853 static void display_menu_bar (struct window *);
854 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
855 ptrdiff_t *);
856 static int display_string (const char *, Lisp_Object, Lisp_Object,
857 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
858 static void compute_line_metrics (struct it *);
859 static void run_redisplay_end_trigger_hook (struct it *);
860 static int get_overlay_strings (struct it *, ptrdiff_t);
861 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
862 static void next_overlay_string (struct it *);
863 static void reseat (struct it *, struct text_pos, int);
864 static void reseat_1 (struct it *, struct text_pos, int);
865 static void back_to_previous_visible_line_start (struct it *);
866 static void reseat_at_next_visible_line_start (struct it *, int);
867 static int next_element_from_ellipsis (struct it *);
868 static int next_element_from_display_vector (struct it *);
869 static int next_element_from_string (struct it *);
870 static int next_element_from_c_string (struct it *);
871 static int next_element_from_buffer (struct it *);
872 static int next_element_from_composition (struct it *);
873 static int next_element_from_image (struct it *);
874 static int next_element_from_stretch (struct it *);
875 static void load_overlay_strings (struct it *, ptrdiff_t);
876 static int init_from_display_pos (struct it *, struct window *,
877 struct display_pos *);
878 static void reseat_to_string (struct it *, const char *,
879 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
880 static int get_next_display_element (struct it *);
881 static enum move_it_result
882 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
883 enum move_operation_enum);
884 static void get_visually_first_element (struct it *);
885 static void init_to_row_start (struct it *, struct window *,
886 struct glyph_row *);
887 static int init_to_row_end (struct it *, struct window *,
888 struct glyph_row *);
889 static void back_to_previous_line_start (struct it *);
890 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
891 static struct text_pos string_pos_nchars_ahead (struct text_pos,
892 Lisp_Object, ptrdiff_t);
893 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
894 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
895 static ptrdiff_t number_of_chars (const char *, bool);
896 static void compute_stop_pos (struct it *);
897 static void compute_string_pos (struct text_pos *, struct text_pos,
898 Lisp_Object);
899 static int face_before_or_after_it_pos (struct it *, int);
900 static ptrdiff_t next_overlay_change (ptrdiff_t);
901 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
902 Lisp_Object, struct text_pos *, ptrdiff_t, int);
903 static int handle_single_display_spec (struct it *, Lisp_Object,
904 Lisp_Object, Lisp_Object,
905 struct text_pos *, ptrdiff_t, int, int);
906 static int underlying_face_id (struct it *);
907 static int in_ellipses_for_invisible_text_p (struct display_pos *,
908 struct window *);
909
910 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
911 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
912
913 #ifdef HAVE_WINDOW_SYSTEM
914
915 static void x_consider_frame_title (Lisp_Object);
916 static void update_tool_bar (struct frame *, int);
917 static int redisplay_tool_bar (struct frame *);
918 static void notice_overwritten_cursor (struct window *,
919 enum glyph_row_area,
920 int, int, int, int);
921 static void append_stretch_glyph (struct it *, Lisp_Object,
922 int, int, int);
923
924
925 #endif /* HAVE_WINDOW_SYSTEM */
926
927 static void produce_special_glyphs (struct it *, enum display_element_type);
928 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
929 static int coords_in_mouse_face_p (struct window *, int, int);
930
931
932 \f
933 /***********************************************************************
934 Window display dimensions
935 ***********************************************************************/
936
937 /* Return the bottom boundary y-position for text lines in window W.
938 This is the first y position at which a line cannot start.
939 It is relative to the top of the window.
940
941 This is the height of W minus the height of a mode line, if any. */
942
943 int
944 window_text_bottom_y (struct window *w)
945 {
946 int height = WINDOW_TOTAL_HEIGHT (w);
947
948 if (WINDOW_WANTS_MODELINE_P (w))
949 height -= CURRENT_MODE_LINE_HEIGHT (w);
950 return height;
951 }
952
953 /* Return the pixel width of display area AREA of window W.
954 ANY_AREA means return the total width of W, not including
955 fringes to the left and right of the window. */
956
957 int
958 window_box_width (struct window *w, enum glyph_row_area area)
959 {
960 int cols = w->total_cols;
961 int pixels = 0;
962
963 if (!w->pseudo_window_p)
964 {
965 cols -= WINDOW_SCROLL_BAR_COLS (w);
966
967 if (area == TEXT_AREA)
968 {
969 cols -= max (0, w->left_margin_cols);
970 cols -= max (0, w->right_margin_cols);
971 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
972 }
973 else if (area == LEFT_MARGIN_AREA)
974 {
975 cols = max (0, w->left_margin_cols);
976 pixels = 0;
977 }
978 else if (area == RIGHT_MARGIN_AREA)
979 {
980 cols = max (0, w->right_margin_cols);
981 pixels = 0;
982 }
983 }
984
985 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
986 }
987
988
989 /* Return the pixel height of the display area of window W, not
990 including mode lines of W, if any. */
991
992 int
993 window_box_height (struct window *w)
994 {
995 struct frame *f = XFRAME (w->frame);
996 int height = WINDOW_TOTAL_HEIGHT (w);
997
998 eassert (height >= 0);
999
1000 /* Note: the code below that determines the mode-line/header-line
1001 height is essentially the same as that contained in the macro
1002 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1003 the appropriate glyph row has its `mode_line_p' flag set,
1004 and if it doesn't, uses estimate_mode_line_height instead. */
1005
1006 if (WINDOW_WANTS_MODELINE_P (w))
1007 {
1008 struct glyph_row *ml_row
1009 = (w->current_matrix && w->current_matrix->rows
1010 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1011 : 0);
1012 if (ml_row && ml_row->mode_line_p)
1013 height -= ml_row->height;
1014 else
1015 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1016 }
1017
1018 if (WINDOW_WANTS_HEADER_LINE_P (w))
1019 {
1020 struct glyph_row *hl_row
1021 = (w->current_matrix && w->current_matrix->rows
1022 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1023 : 0);
1024 if (hl_row && hl_row->mode_line_p)
1025 height -= hl_row->height;
1026 else
1027 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1028 }
1029
1030 /* With a very small font and a mode-line that's taller than
1031 default, we might end up with a negative height. */
1032 return max (0, height);
1033 }
1034
1035 /* Return the window-relative coordinate of the left edge of display
1036 area AREA of window W. ANY_AREA means return the left edge of the
1037 whole window, to the right of the left fringe of W. */
1038
1039 int
1040 window_box_left_offset (struct window *w, enum glyph_row_area area)
1041 {
1042 int x;
1043
1044 if (w->pseudo_window_p)
1045 return 0;
1046
1047 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1048
1049 if (area == TEXT_AREA)
1050 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1051 + window_box_width (w, LEFT_MARGIN_AREA));
1052 else if (area == RIGHT_MARGIN_AREA)
1053 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1054 + window_box_width (w, LEFT_MARGIN_AREA)
1055 + window_box_width (w, TEXT_AREA)
1056 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1057 ? 0
1058 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1059 else if (area == LEFT_MARGIN_AREA
1060 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1061 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1062
1063 return x;
1064 }
1065
1066
1067 /* Return the window-relative coordinate of the right edge of display
1068 area AREA of window W. ANY_AREA means return the right edge of the
1069 whole window, to the left of the right fringe of W. */
1070
1071 int
1072 window_box_right_offset (struct window *w, enum glyph_row_area area)
1073 {
1074 return window_box_left_offset (w, area) + window_box_width (w, area);
1075 }
1076
1077 /* Return the frame-relative coordinate of the left edge of display
1078 area AREA of window W. ANY_AREA means return the left edge of the
1079 whole window, to the right of the left fringe of W. */
1080
1081 int
1082 window_box_left (struct window *w, enum glyph_row_area area)
1083 {
1084 struct frame *f = XFRAME (w->frame);
1085 int x;
1086
1087 if (w->pseudo_window_p)
1088 return FRAME_INTERNAL_BORDER_WIDTH (f);
1089
1090 x = (WINDOW_LEFT_EDGE_X (w)
1091 + window_box_left_offset (w, area));
1092
1093 return x;
1094 }
1095
1096
1097 /* Return the frame-relative coordinate of the right edge of display
1098 area AREA of window W. ANY_AREA means return the right edge of the
1099 whole window, to the left of the right fringe of W. */
1100
1101 int
1102 window_box_right (struct window *w, enum glyph_row_area area)
1103 {
1104 return window_box_left (w, area) + window_box_width (w, area);
1105 }
1106
1107 /* Get the bounding box of the display area AREA of window W, without
1108 mode lines, in frame-relative coordinates. ANY_AREA means the
1109 whole window, not including the left and right fringes of
1110 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1111 coordinates of the upper-left corner of the box. Return in
1112 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1113
1114 void
1115 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1116 int *box_y, int *box_width, int *box_height)
1117 {
1118 if (box_width)
1119 *box_width = window_box_width (w, area);
1120 if (box_height)
1121 *box_height = window_box_height (w);
1122 if (box_x)
1123 *box_x = window_box_left (w, area);
1124 if (box_y)
1125 {
1126 *box_y = WINDOW_TOP_EDGE_Y (w);
1127 if (WINDOW_WANTS_HEADER_LINE_P (w))
1128 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1129 }
1130 }
1131
1132 #ifdef HAVE_WINDOW_SYSTEM
1133
1134 /* Get the bounding box of the display area AREA of window W, without
1135 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1136 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1137 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1138 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1139 box. */
1140
1141 static void
1142 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1143 int *bottom_right_x, int *bottom_right_y)
1144 {
1145 window_box (w, ANY_AREA, top_left_x, top_left_y,
1146 bottom_right_x, bottom_right_y);
1147 *bottom_right_x += *top_left_x;
1148 *bottom_right_y += *top_left_y;
1149 }
1150
1151 #endif /* HAVE_WINDOW_SYSTEM */
1152
1153 /***********************************************************************
1154 Utilities
1155 ***********************************************************************/
1156
1157 /* Return the bottom y-position of the line the iterator IT is in.
1158 This can modify IT's settings. */
1159
1160 int
1161 line_bottom_y (struct it *it)
1162 {
1163 int line_height = it->max_ascent + it->max_descent;
1164 int line_top_y = it->current_y;
1165
1166 if (line_height == 0)
1167 {
1168 if (last_height)
1169 line_height = last_height;
1170 else if (IT_CHARPOS (*it) < ZV)
1171 {
1172 move_it_by_lines (it, 1);
1173 line_height = (it->max_ascent || it->max_descent
1174 ? it->max_ascent + it->max_descent
1175 : last_height);
1176 }
1177 else
1178 {
1179 struct glyph_row *row = it->glyph_row;
1180
1181 /* Use the default character height. */
1182 it->glyph_row = NULL;
1183 it->what = IT_CHARACTER;
1184 it->c = ' ';
1185 it->len = 1;
1186 PRODUCE_GLYPHS (it);
1187 line_height = it->ascent + it->descent;
1188 it->glyph_row = row;
1189 }
1190 }
1191
1192 return line_top_y + line_height;
1193 }
1194
1195 DEFUN ("line-pixel-height", Fline_pixel_height,
1196 Sline_pixel_height, 0, 0, 0,
1197 doc: /* Return height in pixels of text line in the selected window.
1198
1199 Value is the height in pixels of the line at point. */)
1200 (void)
1201 {
1202 struct it it;
1203 struct text_pos pt;
1204 struct window *w = XWINDOW (selected_window);
1205
1206 SET_TEXT_POS (pt, PT, PT_BYTE);
1207 start_display (&it, w, pt);
1208 it.vpos = it.current_y = 0;
1209 last_height = 0;
1210 return make_number (line_bottom_y (&it));
1211 }
1212
1213 /* Return the default pixel height of text lines in window W. The
1214 value is the canonical height of the W frame's default font, plus
1215 any extra space required by the line-spacing variable or frame
1216 parameter.
1217
1218 Implementation note: this ignores any line-spacing text properties
1219 put on the newline characters. This is because those properties
1220 only affect the _screen_ line ending in the newline (i.e., in a
1221 continued line, only the last screen line will be affected), which
1222 means only a small number of lines in a buffer can ever use this
1223 feature. Since this function is used to compute the default pixel
1224 equivalent of text lines in a window, we can safely ignore those
1225 few lines. For the same reasons, we ignore the line-height
1226 properties. */
1227 int
1228 default_line_pixel_height (struct window *w)
1229 {
1230 struct frame *f = WINDOW_XFRAME (w);
1231 int height = FRAME_LINE_HEIGHT (f);
1232
1233 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1234 {
1235 struct buffer *b = XBUFFER (w->contents);
1236 Lisp_Object val = BVAR (b, extra_line_spacing);
1237
1238 if (NILP (val))
1239 val = BVAR (&buffer_defaults, extra_line_spacing);
1240 if (!NILP (val))
1241 {
1242 if (RANGED_INTEGERP (0, val, INT_MAX))
1243 height += XFASTINT (val);
1244 else if (FLOATP (val))
1245 {
1246 int addon = XFLOAT_DATA (val) * height + 0.5;
1247
1248 if (addon >= 0)
1249 height += addon;
1250 }
1251 }
1252 else
1253 height += f->extra_line_spacing;
1254 }
1255
1256 return height;
1257 }
1258
1259 /* Subroutine of pos_visible_p below. Extracts a display string, if
1260 any, from the display spec given as its argument. */
1261 static Lisp_Object
1262 string_from_display_spec (Lisp_Object spec)
1263 {
1264 if (CONSP (spec))
1265 {
1266 while (CONSP (spec))
1267 {
1268 if (STRINGP (XCAR (spec)))
1269 return XCAR (spec);
1270 spec = XCDR (spec);
1271 }
1272 }
1273 else if (VECTORP (spec))
1274 {
1275 ptrdiff_t i;
1276
1277 for (i = 0; i < ASIZE (spec); i++)
1278 {
1279 if (STRINGP (AREF (spec, i)))
1280 return AREF (spec, i);
1281 }
1282 return Qnil;
1283 }
1284
1285 return spec;
1286 }
1287
1288
1289 /* Limit insanely large values of W->hscroll on frame F to the largest
1290 value that will still prevent first_visible_x and last_visible_x of
1291 'struct it' from overflowing an int. */
1292 static int
1293 window_hscroll_limited (struct window *w, struct frame *f)
1294 {
1295 ptrdiff_t window_hscroll = w->hscroll;
1296 int window_text_width = window_box_width (w, TEXT_AREA);
1297 int colwidth = FRAME_COLUMN_WIDTH (f);
1298
1299 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1300 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1301
1302 return window_hscroll;
1303 }
1304
1305 /* Return 1 if position CHARPOS is visible in window W.
1306 CHARPOS < 0 means return info about WINDOW_END position.
1307 If visible, set *X and *Y to pixel coordinates of top left corner.
1308 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1309 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1310
1311 int
1312 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1313 int *rtop, int *rbot, int *rowh, int *vpos)
1314 {
1315 struct it it;
1316 void *itdata = bidi_shelve_cache ();
1317 struct text_pos top;
1318 int visible_p = 0;
1319 struct buffer *old_buffer = NULL;
1320
1321 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1322 return visible_p;
1323
1324 if (XBUFFER (w->contents) != current_buffer)
1325 {
1326 old_buffer = current_buffer;
1327 set_buffer_internal_1 (XBUFFER (w->contents));
1328 }
1329
1330 SET_TEXT_POS_FROM_MARKER (top, w->start);
1331 /* Scrolling a minibuffer window via scroll bar when the echo area
1332 shows long text sometimes resets the minibuffer contents behind
1333 our backs. */
1334 if (CHARPOS (top) > ZV)
1335 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1336
1337 /* Compute exact mode line heights. */
1338 if (WINDOW_WANTS_MODELINE_P (w))
1339 w->mode_line_height
1340 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1341 BVAR (current_buffer, mode_line_format));
1342
1343 if (WINDOW_WANTS_HEADER_LINE_P (w))
1344 w->header_line_height
1345 = display_mode_line (w, HEADER_LINE_FACE_ID,
1346 BVAR (current_buffer, header_line_format));
1347
1348 start_display (&it, w, top);
1349 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1350 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1351
1352 if (charpos >= 0
1353 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1354 && IT_CHARPOS (it) >= charpos)
1355 /* When scanning backwards under bidi iteration, move_it_to
1356 stops at or _before_ CHARPOS, because it stops at or to
1357 the _right_ of the character at CHARPOS. */
1358 || (it.bidi_p && it.bidi_it.scan_dir == -1
1359 && IT_CHARPOS (it) <= charpos)))
1360 {
1361 /* We have reached CHARPOS, or passed it. How the call to
1362 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1363 or covered by a display property, move_it_to stops at the end
1364 of the invisible text, to the right of CHARPOS. (ii) If
1365 CHARPOS is in a display vector, move_it_to stops on its last
1366 glyph. */
1367 int top_x = it.current_x;
1368 int top_y = it.current_y;
1369 /* Calling line_bottom_y may change it.method, it.position, etc. */
1370 enum it_method it_method = it.method;
1371 int bottom_y = (last_height = 0, line_bottom_y (&it));
1372 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1373
1374 if (top_y < window_top_y)
1375 visible_p = bottom_y > window_top_y;
1376 else if (top_y < it.last_visible_y)
1377 visible_p = 1;
1378 if (bottom_y >= it.last_visible_y
1379 && it.bidi_p && it.bidi_it.scan_dir == -1
1380 && IT_CHARPOS (it) < charpos)
1381 {
1382 /* When the last line of the window is scanned backwards
1383 under bidi iteration, we could be duped into thinking
1384 that we have passed CHARPOS, when in fact move_it_to
1385 simply stopped short of CHARPOS because it reached
1386 last_visible_y. To see if that's what happened, we call
1387 move_it_to again with a slightly larger vertical limit,
1388 and see if it actually moved vertically; if it did, we
1389 didn't really reach CHARPOS, which is beyond window end. */
1390 struct it save_it = it;
1391 /* Why 10? because we don't know how many canonical lines
1392 will the height of the next line(s) be. So we guess. */
1393 int ten_more_lines = 10 * default_line_pixel_height (w);
1394
1395 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1396 MOVE_TO_POS | MOVE_TO_Y);
1397 if (it.current_y > top_y)
1398 visible_p = 0;
1399
1400 it = save_it;
1401 }
1402 if (visible_p)
1403 {
1404 if (it_method == GET_FROM_DISPLAY_VECTOR)
1405 {
1406 /* We stopped on the last glyph of a display vector.
1407 Try and recompute. Hack alert! */
1408 if (charpos < 2 || top.charpos >= charpos)
1409 top_x = it.glyph_row->x;
1410 else
1411 {
1412 struct it it2, it2_prev;
1413 /* The idea is to get to the previous buffer
1414 position, consume the character there, and use
1415 the pixel coordinates we get after that. But if
1416 the previous buffer position is also displayed
1417 from a display vector, we need to consume all of
1418 the glyphs from that display vector. */
1419 start_display (&it2, w, top);
1420 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1421 /* If we didn't get to CHARPOS - 1, there's some
1422 replacing display property at that position, and
1423 we stopped after it. That is exactly the place
1424 whose coordinates we want. */
1425 if (IT_CHARPOS (it2) != charpos - 1)
1426 it2_prev = it2;
1427 else
1428 {
1429 /* Iterate until we get out of the display
1430 vector that displays the character at
1431 CHARPOS - 1. */
1432 do {
1433 get_next_display_element (&it2);
1434 PRODUCE_GLYPHS (&it2);
1435 it2_prev = it2;
1436 set_iterator_to_next (&it2, 1);
1437 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1438 && IT_CHARPOS (it2) < charpos);
1439 }
1440 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1441 || it2_prev.current_x > it2_prev.last_visible_x)
1442 top_x = it.glyph_row->x;
1443 else
1444 {
1445 top_x = it2_prev.current_x;
1446 top_y = it2_prev.current_y;
1447 }
1448 }
1449 }
1450 else if (IT_CHARPOS (it) != charpos)
1451 {
1452 Lisp_Object cpos = make_number (charpos);
1453 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1454 Lisp_Object string = string_from_display_spec (spec);
1455 struct text_pos tpos;
1456 int replacing_spec_p;
1457 bool newline_in_string
1458 = (STRINGP (string)
1459 && memchr (SDATA (string), '\n', SBYTES (string)));
1460
1461 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1462 replacing_spec_p
1463 = (!NILP (spec)
1464 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1465 charpos, FRAME_WINDOW_P (it.f)));
1466 /* The tricky code below is needed because there's a
1467 discrepancy between move_it_to and how we set cursor
1468 when PT is at the beginning of a portion of text
1469 covered by a display property or an overlay with a
1470 display property, or the display line ends in a
1471 newline from a display string. move_it_to will stop
1472 _after_ such display strings, whereas
1473 set_cursor_from_row conspires with cursor_row_p to
1474 place the cursor on the first glyph produced from the
1475 display string. */
1476
1477 /* We have overshoot PT because it is covered by a
1478 display property that replaces the text it covers.
1479 If the string includes embedded newlines, we are also
1480 in the wrong display line. Backtrack to the correct
1481 line, where the display property begins. */
1482 if (replacing_spec_p)
1483 {
1484 Lisp_Object startpos, endpos;
1485 EMACS_INT start, end;
1486 struct it it3;
1487 int it3_moved;
1488
1489 /* Find the first and the last buffer positions
1490 covered by the display string. */
1491 endpos =
1492 Fnext_single_char_property_change (cpos, Qdisplay,
1493 Qnil, Qnil);
1494 startpos =
1495 Fprevious_single_char_property_change (endpos, Qdisplay,
1496 Qnil, Qnil);
1497 start = XFASTINT (startpos);
1498 end = XFASTINT (endpos);
1499 /* Move to the last buffer position before the
1500 display property. */
1501 start_display (&it3, w, top);
1502 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1503 /* Move forward one more line if the position before
1504 the display string is a newline or if it is the
1505 rightmost character on a line that is
1506 continued or word-wrapped. */
1507 if (it3.method == GET_FROM_BUFFER
1508 && (it3.c == '\n'
1509 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1510 move_it_by_lines (&it3, 1);
1511 else if (move_it_in_display_line_to (&it3, -1,
1512 it3.current_x
1513 + it3.pixel_width,
1514 MOVE_TO_X)
1515 == MOVE_LINE_CONTINUED)
1516 {
1517 move_it_by_lines (&it3, 1);
1518 /* When we are under word-wrap, the #$@%!
1519 move_it_by_lines moves 2 lines, so we need to
1520 fix that up. */
1521 if (it3.line_wrap == WORD_WRAP)
1522 move_it_by_lines (&it3, -1);
1523 }
1524
1525 /* Record the vertical coordinate of the display
1526 line where we wound up. */
1527 top_y = it3.current_y;
1528 if (it3.bidi_p)
1529 {
1530 /* When characters are reordered for display,
1531 the character displayed to the left of the
1532 display string could be _after_ the display
1533 property in the logical order. Use the
1534 smallest vertical position of these two. */
1535 start_display (&it3, w, top);
1536 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1537 if (it3.current_y < top_y)
1538 top_y = it3.current_y;
1539 }
1540 /* Move from the top of the window to the beginning
1541 of the display line where the display string
1542 begins. */
1543 start_display (&it3, w, top);
1544 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1545 /* If it3_moved stays zero after the 'while' loop
1546 below, that means we already were at a newline
1547 before the loop (e.g., the display string begins
1548 with a newline), so we don't need to (and cannot)
1549 inspect the glyphs of it3.glyph_row, because
1550 PRODUCE_GLYPHS will not produce anything for a
1551 newline, and thus it3.glyph_row stays at its
1552 stale content it got at top of the window. */
1553 it3_moved = 0;
1554 /* Finally, advance the iterator until we hit the
1555 first display element whose character position is
1556 CHARPOS, or until the first newline from the
1557 display string, which signals the end of the
1558 display line. */
1559 while (get_next_display_element (&it3))
1560 {
1561 PRODUCE_GLYPHS (&it3);
1562 if (IT_CHARPOS (it3) == charpos
1563 || ITERATOR_AT_END_OF_LINE_P (&it3))
1564 break;
1565 it3_moved = 1;
1566 set_iterator_to_next (&it3, 0);
1567 }
1568 top_x = it3.current_x - it3.pixel_width;
1569 /* Normally, we would exit the above loop because we
1570 found the display element whose character
1571 position is CHARPOS. For the contingency that we
1572 didn't, and stopped at the first newline from the
1573 display string, move back over the glyphs
1574 produced from the string, until we find the
1575 rightmost glyph not from the string. */
1576 if (it3_moved
1577 && newline_in_string
1578 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1579 {
1580 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1581 + it3.glyph_row->used[TEXT_AREA];
1582
1583 while (EQ ((g - 1)->object, string))
1584 {
1585 --g;
1586 top_x -= g->pixel_width;
1587 }
1588 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1589 + it3.glyph_row->used[TEXT_AREA]);
1590 }
1591 }
1592 }
1593
1594 *x = top_x;
1595 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1596 *rtop = max (0, window_top_y - top_y);
1597 *rbot = max (0, bottom_y - it.last_visible_y);
1598 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1599 - max (top_y, window_top_y)));
1600 *vpos = it.vpos;
1601 }
1602 }
1603 else
1604 {
1605 /* We were asked to provide info about WINDOW_END. */
1606 struct it it2;
1607 void *it2data = NULL;
1608
1609 SAVE_IT (it2, it, it2data);
1610 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1611 move_it_by_lines (&it, 1);
1612 if (charpos < IT_CHARPOS (it)
1613 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1614 {
1615 visible_p = 1;
1616 RESTORE_IT (&it2, &it2, it2data);
1617 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1618 *x = it2.current_x;
1619 *y = it2.current_y + it2.max_ascent - it2.ascent;
1620 *rtop = max (0, -it2.current_y);
1621 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1622 - it.last_visible_y));
1623 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1624 it.last_visible_y)
1625 - max (it2.current_y,
1626 WINDOW_HEADER_LINE_HEIGHT (w))));
1627 *vpos = it2.vpos;
1628 }
1629 else
1630 bidi_unshelve_cache (it2data, 1);
1631 }
1632 bidi_unshelve_cache (itdata, 0);
1633
1634 if (old_buffer)
1635 set_buffer_internal_1 (old_buffer);
1636
1637 if (visible_p && w->hscroll > 0)
1638 *x -=
1639 window_hscroll_limited (w, WINDOW_XFRAME (w))
1640 * WINDOW_FRAME_COLUMN_WIDTH (w);
1641
1642 #if 0
1643 /* Debugging code. */
1644 if (visible_p)
1645 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1646 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1647 else
1648 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1649 #endif
1650
1651 return visible_p;
1652 }
1653
1654
1655 /* Return the next character from STR. Return in *LEN the length of
1656 the character. This is like STRING_CHAR_AND_LENGTH but never
1657 returns an invalid character. If we find one, we return a `?', but
1658 with the length of the invalid character. */
1659
1660 static int
1661 string_char_and_length (const unsigned char *str, int *len)
1662 {
1663 int c;
1664
1665 c = STRING_CHAR_AND_LENGTH (str, *len);
1666 if (!CHAR_VALID_P (c))
1667 /* We may not change the length here because other places in Emacs
1668 don't use this function, i.e. they silently accept invalid
1669 characters. */
1670 c = '?';
1671
1672 return c;
1673 }
1674
1675
1676
1677 /* Given a position POS containing a valid character and byte position
1678 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1679
1680 static struct text_pos
1681 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1682 {
1683 eassert (STRINGP (string) && nchars >= 0);
1684
1685 if (STRING_MULTIBYTE (string))
1686 {
1687 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1688 int len;
1689
1690 while (nchars--)
1691 {
1692 string_char_and_length (p, &len);
1693 p += len;
1694 CHARPOS (pos) += 1;
1695 BYTEPOS (pos) += len;
1696 }
1697 }
1698 else
1699 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1700
1701 return pos;
1702 }
1703
1704
1705 /* Value is the text position, i.e. character and byte position,
1706 for character position CHARPOS in STRING. */
1707
1708 static struct text_pos
1709 string_pos (ptrdiff_t charpos, Lisp_Object string)
1710 {
1711 struct text_pos pos;
1712 eassert (STRINGP (string));
1713 eassert (charpos >= 0);
1714 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1715 return pos;
1716 }
1717
1718
1719 /* Value is a text position, i.e. character and byte position, for
1720 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1721 means recognize multibyte characters. */
1722
1723 static struct text_pos
1724 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1725 {
1726 struct text_pos pos;
1727
1728 eassert (s != NULL);
1729 eassert (charpos >= 0);
1730
1731 if (multibyte_p)
1732 {
1733 int len;
1734
1735 SET_TEXT_POS (pos, 0, 0);
1736 while (charpos--)
1737 {
1738 string_char_and_length ((const unsigned char *) s, &len);
1739 s += len;
1740 CHARPOS (pos) += 1;
1741 BYTEPOS (pos) += len;
1742 }
1743 }
1744 else
1745 SET_TEXT_POS (pos, charpos, charpos);
1746
1747 return pos;
1748 }
1749
1750
1751 /* Value is the number of characters in C string S. MULTIBYTE_P
1752 non-zero means recognize multibyte characters. */
1753
1754 static ptrdiff_t
1755 number_of_chars (const char *s, bool multibyte_p)
1756 {
1757 ptrdiff_t nchars;
1758
1759 if (multibyte_p)
1760 {
1761 ptrdiff_t rest = strlen (s);
1762 int len;
1763 const unsigned char *p = (const unsigned char *) s;
1764
1765 for (nchars = 0; rest > 0; ++nchars)
1766 {
1767 string_char_and_length (p, &len);
1768 rest -= len, p += len;
1769 }
1770 }
1771 else
1772 nchars = strlen (s);
1773
1774 return nchars;
1775 }
1776
1777
1778 /* Compute byte position NEWPOS->bytepos corresponding to
1779 NEWPOS->charpos. POS is a known position in string STRING.
1780 NEWPOS->charpos must be >= POS.charpos. */
1781
1782 static void
1783 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1784 {
1785 eassert (STRINGP (string));
1786 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1787
1788 if (STRING_MULTIBYTE (string))
1789 *newpos = string_pos_nchars_ahead (pos, string,
1790 CHARPOS (*newpos) - CHARPOS (pos));
1791 else
1792 BYTEPOS (*newpos) = CHARPOS (*newpos);
1793 }
1794
1795 /* EXPORT:
1796 Return an estimation of the pixel height of mode or header lines on
1797 frame F. FACE_ID specifies what line's height to estimate. */
1798
1799 int
1800 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1801 {
1802 #ifdef HAVE_WINDOW_SYSTEM
1803 if (FRAME_WINDOW_P (f))
1804 {
1805 int height = FONT_HEIGHT (FRAME_FONT (f));
1806
1807 /* This function is called so early when Emacs starts that the face
1808 cache and mode line face are not yet initialized. */
1809 if (FRAME_FACE_CACHE (f))
1810 {
1811 struct face *face = FACE_FROM_ID (f, face_id);
1812 if (face)
1813 {
1814 if (face->font)
1815 height = FONT_HEIGHT (face->font);
1816 if (face->box_line_width > 0)
1817 height += 2 * face->box_line_width;
1818 }
1819 }
1820
1821 return height;
1822 }
1823 #endif
1824
1825 return 1;
1826 }
1827
1828 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1829 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1830 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1831 not force the value into range. */
1832
1833 void
1834 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1835 int *x, int *y, NativeRectangle *bounds, int noclip)
1836 {
1837
1838 #ifdef HAVE_WINDOW_SYSTEM
1839 if (FRAME_WINDOW_P (f))
1840 {
1841 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1842 even for negative values. */
1843 if (pix_x < 0)
1844 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1845 if (pix_y < 0)
1846 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1847
1848 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1849 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1850
1851 if (bounds)
1852 STORE_NATIVE_RECT (*bounds,
1853 FRAME_COL_TO_PIXEL_X (f, pix_x),
1854 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1855 FRAME_COLUMN_WIDTH (f) - 1,
1856 FRAME_LINE_HEIGHT (f) - 1);
1857
1858 if (!noclip)
1859 {
1860 if (pix_x < 0)
1861 pix_x = 0;
1862 else if (pix_x > FRAME_TOTAL_COLS (f))
1863 pix_x = FRAME_TOTAL_COLS (f);
1864
1865 if (pix_y < 0)
1866 pix_y = 0;
1867 else if (pix_y > FRAME_LINES (f))
1868 pix_y = FRAME_LINES (f);
1869 }
1870 }
1871 #endif
1872
1873 *x = pix_x;
1874 *y = pix_y;
1875 }
1876
1877
1878 /* Find the glyph under window-relative coordinates X/Y in window W.
1879 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1880 strings. Return in *HPOS and *VPOS the row and column number of
1881 the glyph found. Return in *AREA the glyph area containing X.
1882 Value is a pointer to the glyph found or null if X/Y is not on
1883 text, or we can't tell because W's current matrix is not up to
1884 date. */
1885
1886 static
1887 struct glyph *
1888 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1889 int *dx, int *dy, int *area)
1890 {
1891 struct glyph *glyph, *end;
1892 struct glyph_row *row = NULL;
1893 int x0, i;
1894
1895 /* Find row containing Y. Give up if some row is not enabled. */
1896 for (i = 0; i < w->current_matrix->nrows; ++i)
1897 {
1898 row = MATRIX_ROW (w->current_matrix, i);
1899 if (!row->enabled_p)
1900 return NULL;
1901 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1902 break;
1903 }
1904
1905 *vpos = i;
1906 *hpos = 0;
1907
1908 /* Give up if Y is not in the window. */
1909 if (i == w->current_matrix->nrows)
1910 return NULL;
1911
1912 /* Get the glyph area containing X. */
1913 if (w->pseudo_window_p)
1914 {
1915 *area = TEXT_AREA;
1916 x0 = 0;
1917 }
1918 else
1919 {
1920 if (x < window_box_left_offset (w, TEXT_AREA))
1921 {
1922 *area = LEFT_MARGIN_AREA;
1923 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1924 }
1925 else if (x < window_box_right_offset (w, TEXT_AREA))
1926 {
1927 *area = TEXT_AREA;
1928 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1929 }
1930 else
1931 {
1932 *area = RIGHT_MARGIN_AREA;
1933 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1934 }
1935 }
1936
1937 /* Find glyph containing X. */
1938 glyph = row->glyphs[*area];
1939 end = glyph + row->used[*area];
1940 x -= x0;
1941 while (glyph < end && x >= glyph->pixel_width)
1942 {
1943 x -= glyph->pixel_width;
1944 ++glyph;
1945 }
1946
1947 if (glyph == end)
1948 return NULL;
1949
1950 if (dx)
1951 {
1952 *dx = x;
1953 *dy = y - (row->y + row->ascent - glyph->ascent);
1954 }
1955
1956 *hpos = glyph - row->glyphs[*area];
1957 return glyph;
1958 }
1959
1960 /* Convert frame-relative x/y to coordinates relative to window W.
1961 Takes pseudo-windows into account. */
1962
1963 static void
1964 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1965 {
1966 if (w->pseudo_window_p)
1967 {
1968 /* A pseudo-window is always full-width, and starts at the
1969 left edge of the frame, plus a frame border. */
1970 struct frame *f = XFRAME (w->frame);
1971 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1972 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1973 }
1974 else
1975 {
1976 *x -= WINDOW_LEFT_EDGE_X (w);
1977 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1978 }
1979 }
1980
1981 #ifdef HAVE_WINDOW_SYSTEM
1982
1983 /* EXPORT:
1984 Return in RECTS[] at most N clipping rectangles for glyph string S.
1985 Return the number of stored rectangles. */
1986
1987 int
1988 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1989 {
1990 XRectangle r;
1991
1992 if (n <= 0)
1993 return 0;
1994
1995 if (s->row->full_width_p)
1996 {
1997 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1998 r.x = WINDOW_LEFT_EDGE_X (s->w);
1999 r.width = WINDOW_TOTAL_WIDTH (s->w);
2000
2001 /* Unless displaying a mode or menu bar line, which are always
2002 fully visible, clip to the visible part of the row. */
2003 if (s->w->pseudo_window_p)
2004 r.height = s->row->visible_height;
2005 else
2006 r.height = s->height;
2007 }
2008 else
2009 {
2010 /* This is a text line that may be partially visible. */
2011 r.x = window_box_left (s->w, s->area);
2012 r.width = window_box_width (s->w, s->area);
2013 r.height = s->row->visible_height;
2014 }
2015
2016 if (s->clip_head)
2017 if (r.x < s->clip_head->x)
2018 {
2019 if (r.width >= s->clip_head->x - r.x)
2020 r.width -= s->clip_head->x - r.x;
2021 else
2022 r.width = 0;
2023 r.x = s->clip_head->x;
2024 }
2025 if (s->clip_tail)
2026 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2027 {
2028 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2029 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2030 else
2031 r.width = 0;
2032 }
2033
2034 /* If S draws overlapping rows, it's sufficient to use the top and
2035 bottom of the window for clipping because this glyph string
2036 intentionally draws over other lines. */
2037 if (s->for_overlaps)
2038 {
2039 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2040 r.height = window_text_bottom_y (s->w) - r.y;
2041
2042 /* Alas, the above simple strategy does not work for the
2043 environments with anti-aliased text: if the same text is
2044 drawn onto the same place multiple times, it gets thicker.
2045 If the overlap we are processing is for the erased cursor, we
2046 take the intersection with the rectangle of the cursor. */
2047 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2048 {
2049 XRectangle rc, r_save = r;
2050
2051 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2052 rc.y = s->w->phys_cursor.y;
2053 rc.width = s->w->phys_cursor_width;
2054 rc.height = s->w->phys_cursor_height;
2055
2056 x_intersect_rectangles (&r_save, &rc, &r);
2057 }
2058 }
2059 else
2060 {
2061 /* Don't use S->y for clipping because it doesn't take partially
2062 visible lines into account. For example, it can be negative for
2063 partially visible lines at the top of a window. */
2064 if (!s->row->full_width_p
2065 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2066 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2067 else
2068 r.y = max (0, s->row->y);
2069 }
2070
2071 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2072
2073 /* If drawing the cursor, don't let glyph draw outside its
2074 advertised boundaries. Cleartype does this under some circumstances. */
2075 if (s->hl == DRAW_CURSOR)
2076 {
2077 struct glyph *glyph = s->first_glyph;
2078 int height, max_y;
2079
2080 if (s->x > r.x)
2081 {
2082 r.width -= s->x - r.x;
2083 r.x = s->x;
2084 }
2085 r.width = min (r.width, glyph->pixel_width);
2086
2087 /* If r.y is below window bottom, ensure that we still see a cursor. */
2088 height = min (glyph->ascent + glyph->descent,
2089 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2090 max_y = window_text_bottom_y (s->w) - height;
2091 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2092 if (s->ybase - glyph->ascent > max_y)
2093 {
2094 r.y = max_y;
2095 r.height = height;
2096 }
2097 else
2098 {
2099 /* Don't draw cursor glyph taller than our actual glyph. */
2100 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2101 if (height < r.height)
2102 {
2103 max_y = r.y + r.height;
2104 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2105 r.height = min (max_y - r.y, height);
2106 }
2107 }
2108 }
2109
2110 if (s->row->clip)
2111 {
2112 XRectangle r_save = r;
2113
2114 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2115 r.width = 0;
2116 }
2117
2118 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2119 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2120 {
2121 #ifdef CONVERT_FROM_XRECT
2122 CONVERT_FROM_XRECT (r, *rects);
2123 #else
2124 *rects = r;
2125 #endif
2126 return 1;
2127 }
2128 else
2129 {
2130 /* If we are processing overlapping and allowed to return
2131 multiple clipping rectangles, we exclude the row of the glyph
2132 string from the clipping rectangle. This is to avoid drawing
2133 the same text on the environment with anti-aliasing. */
2134 #ifdef CONVERT_FROM_XRECT
2135 XRectangle rs[2];
2136 #else
2137 XRectangle *rs = rects;
2138 #endif
2139 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2140
2141 if (s->for_overlaps & OVERLAPS_PRED)
2142 {
2143 rs[i] = r;
2144 if (r.y + r.height > row_y)
2145 {
2146 if (r.y < row_y)
2147 rs[i].height = row_y - r.y;
2148 else
2149 rs[i].height = 0;
2150 }
2151 i++;
2152 }
2153 if (s->for_overlaps & OVERLAPS_SUCC)
2154 {
2155 rs[i] = r;
2156 if (r.y < row_y + s->row->visible_height)
2157 {
2158 if (r.y + r.height > row_y + s->row->visible_height)
2159 {
2160 rs[i].y = row_y + s->row->visible_height;
2161 rs[i].height = r.y + r.height - rs[i].y;
2162 }
2163 else
2164 rs[i].height = 0;
2165 }
2166 i++;
2167 }
2168
2169 n = i;
2170 #ifdef CONVERT_FROM_XRECT
2171 for (i = 0; i < n; i++)
2172 CONVERT_FROM_XRECT (rs[i], rects[i]);
2173 #endif
2174 return n;
2175 }
2176 }
2177
2178 /* EXPORT:
2179 Return in *NR the clipping rectangle for glyph string S. */
2180
2181 void
2182 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2183 {
2184 get_glyph_string_clip_rects (s, nr, 1);
2185 }
2186
2187
2188 /* EXPORT:
2189 Return the position and height of the phys cursor in window W.
2190 Set w->phys_cursor_width to width of phys cursor.
2191 */
2192
2193 void
2194 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2195 struct glyph *glyph, int *xp, int *yp, int *heightp)
2196 {
2197 struct frame *f = XFRAME (WINDOW_FRAME (w));
2198 int x, y, wd, h, h0, y0;
2199
2200 /* Compute the width of the rectangle to draw. If on a stretch
2201 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2202 rectangle as wide as the glyph, but use a canonical character
2203 width instead. */
2204 wd = glyph->pixel_width - 1;
2205 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2206 wd++; /* Why? */
2207 #endif
2208
2209 x = w->phys_cursor.x;
2210 if (x < 0)
2211 {
2212 wd += x;
2213 x = 0;
2214 }
2215
2216 if (glyph->type == STRETCH_GLYPH
2217 && !x_stretch_cursor_p)
2218 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2219 w->phys_cursor_width = wd;
2220
2221 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2222
2223 /* If y is below window bottom, ensure that we still see a cursor. */
2224 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2225
2226 h = max (h0, glyph->ascent + glyph->descent);
2227 h0 = min (h0, glyph->ascent + glyph->descent);
2228
2229 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2230 if (y < y0)
2231 {
2232 h = max (h - (y0 - y) + 1, h0);
2233 y = y0 - 1;
2234 }
2235 else
2236 {
2237 y0 = window_text_bottom_y (w) - h0;
2238 if (y > y0)
2239 {
2240 h += y - y0;
2241 y = y0;
2242 }
2243 }
2244
2245 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2246 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2247 *heightp = h;
2248 }
2249
2250 /*
2251 * Remember which glyph the mouse is over.
2252 */
2253
2254 void
2255 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2256 {
2257 Lisp_Object window;
2258 struct window *w;
2259 struct glyph_row *r, *gr, *end_row;
2260 enum window_part part;
2261 enum glyph_row_area area;
2262 int x, y, width, height;
2263
2264 /* Try to determine frame pixel position and size of the glyph under
2265 frame pixel coordinates X/Y on frame F. */
2266
2267 if (!f->glyphs_initialized_p
2268 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2269 NILP (window)))
2270 {
2271 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2272 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2273 goto virtual_glyph;
2274 }
2275
2276 w = XWINDOW (window);
2277 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2278 height = WINDOW_FRAME_LINE_HEIGHT (w);
2279
2280 x = window_relative_x_coord (w, part, gx);
2281 y = gy - WINDOW_TOP_EDGE_Y (w);
2282
2283 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2284 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2285
2286 if (w->pseudo_window_p)
2287 {
2288 area = TEXT_AREA;
2289 part = ON_MODE_LINE; /* Don't adjust margin. */
2290 goto text_glyph;
2291 }
2292
2293 switch (part)
2294 {
2295 case ON_LEFT_MARGIN:
2296 area = LEFT_MARGIN_AREA;
2297 goto text_glyph;
2298
2299 case ON_RIGHT_MARGIN:
2300 area = RIGHT_MARGIN_AREA;
2301 goto text_glyph;
2302
2303 case ON_HEADER_LINE:
2304 case ON_MODE_LINE:
2305 gr = (part == ON_HEADER_LINE
2306 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2307 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2308 gy = gr->y;
2309 area = TEXT_AREA;
2310 goto text_glyph_row_found;
2311
2312 case ON_TEXT:
2313 area = TEXT_AREA;
2314
2315 text_glyph:
2316 gr = 0; gy = 0;
2317 for (; r <= end_row && r->enabled_p; ++r)
2318 if (r->y + r->height > y)
2319 {
2320 gr = r; gy = r->y;
2321 break;
2322 }
2323
2324 text_glyph_row_found:
2325 if (gr && gy <= y)
2326 {
2327 struct glyph *g = gr->glyphs[area];
2328 struct glyph *end = g + gr->used[area];
2329
2330 height = gr->height;
2331 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2332 if (gx + g->pixel_width > x)
2333 break;
2334
2335 if (g < end)
2336 {
2337 if (g->type == IMAGE_GLYPH)
2338 {
2339 /* Don't remember when mouse is over image, as
2340 image may have hot-spots. */
2341 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2342 return;
2343 }
2344 width = g->pixel_width;
2345 }
2346 else
2347 {
2348 /* Use nominal char spacing at end of line. */
2349 x -= gx;
2350 gx += (x / width) * width;
2351 }
2352
2353 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2354 gx += window_box_left_offset (w, area);
2355 }
2356 else
2357 {
2358 /* Use nominal line height at end of window. */
2359 gx = (x / width) * width;
2360 y -= gy;
2361 gy += (y / height) * height;
2362 }
2363 break;
2364
2365 case ON_LEFT_FRINGE:
2366 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2367 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2368 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2369 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2370 goto row_glyph;
2371
2372 case ON_RIGHT_FRINGE:
2373 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2374 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2375 : window_box_right_offset (w, TEXT_AREA));
2376 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2377 goto row_glyph;
2378
2379 case ON_SCROLL_BAR:
2380 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2381 ? 0
2382 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2383 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2384 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2385 : 0)));
2386 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2387
2388 row_glyph:
2389 gr = 0, gy = 0;
2390 for (; r <= end_row && r->enabled_p; ++r)
2391 if (r->y + r->height > y)
2392 {
2393 gr = r; gy = r->y;
2394 break;
2395 }
2396
2397 if (gr && gy <= y)
2398 height = gr->height;
2399 else
2400 {
2401 /* Use nominal line height at end of window. */
2402 y -= gy;
2403 gy += (y / height) * height;
2404 }
2405 break;
2406
2407 default:
2408 ;
2409 virtual_glyph:
2410 /* If there is no glyph under the mouse, then we divide the screen
2411 into a grid of the smallest glyph in the frame, and use that
2412 as our "glyph". */
2413
2414 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2415 round down even for negative values. */
2416 if (gx < 0)
2417 gx -= width - 1;
2418 if (gy < 0)
2419 gy -= height - 1;
2420
2421 gx = (gx / width) * width;
2422 gy = (gy / height) * height;
2423
2424 goto store_rect;
2425 }
2426
2427 gx += WINDOW_LEFT_EDGE_X (w);
2428 gy += WINDOW_TOP_EDGE_Y (w);
2429
2430 store_rect:
2431 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2432
2433 /* Visible feedback for debugging. */
2434 #if 0
2435 #if HAVE_X_WINDOWS
2436 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2437 f->output_data.x->normal_gc,
2438 gx, gy, width, height);
2439 #endif
2440 #endif
2441 }
2442
2443
2444 #endif /* HAVE_WINDOW_SYSTEM */
2445
2446 static void
2447 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2448 {
2449 eassert (w);
2450 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2451 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2452 w->window_end_vpos
2453 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2454 }
2455
2456 /***********************************************************************
2457 Lisp form evaluation
2458 ***********************************************************************/
2459
2460 /* Error handler for safe_eval and safe_call. */
2461
2462 static Lisp_Object
2463 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2464 {
2465 add_to_log ("Error during redisplay: %S signaled %S",
2466 Flist (nargs, args), arg);
2467 return Qnil;
2468 }
2469
2470 /* Call function FUNC with the rest of NARGS - 1 arguments
2471 following. Return the result, or nil if something went
2472 wrong. Prevent redisplay during the evaluation. */
2473
2474 Lisp_Object
2475 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2476 {
2477 Lisp_Object val;
2478
2479 if (inhibit_eval_during_redisplay)
2480 val = Qnil;
2481 else
2482 {
2483 va_list ap;
2484 ptrdiff_t i;
2485 ptrdiff_t count = SPECPDL_INDEX ();
2486 struct gcpro gcpro1;
2487 Lisp_Object *args = alloca (nargs * word_size);
2488
2489 args[0] = func;
2490 va_start (ap, func);
2491 for (i = 1; i < nargs; i++)
2492 args[i] = va_arg (ap, Lisp_Object);
2493 va_end (ap);
2494
2495 GCPRO1 (args[0]);
2496 gcpro1.nvars = nargs;
2497 specbind (Qinhibit_redisplay, Qt);
2498 /* Use Qt to ensure debugger does not run,
2499 so there is no possibility of wanting to redisplay. */
2500 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2501 safe_eval_handler);
2502 UNGCPRO;
2503 val = unbind_to (count, val);
2504 }
2505
2506 return val;
2507 }
2508
2509
2510 /* Call function FN with one argument ARG.
2511 Return the result, or nil if something went wrong. */
2512
2513 Lisp_Object
2514 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2515 {
2516 return safe_call (2, fn, arg);
2517 }
2518
2519 static Lisp_Object Qeval;
2520
2521 Lisp_Object
2522 safe_eval (Lisp_Object sexpr)
2523 {
2524 return safe_call1 (Qeval, sexpr);
2525 }
2526
2527 /* Call function FN with two arguments ARG1 and ARG2.
2528 Return the result, or nil if something went wrong. */
2529
2530 Lisp_Object
2531 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2532 {
2533 return safe_call (3, fn, arg1, arg2);
2534 }
2535
2536
2537 \f
2538 /***********************************************************************
2539 Debugging
2540 ***********************************************************************/
2541
2542 #if 0
2543
2544 /* Define CHECK_IT to perform sanity checks on iterators.
2545 This is for debugging. It is too slow to do unconditionally. */
2546
2547 static void
2548 check_it (struct it *it)
2549 {
2550 if (it->method == GET_FROM_STRING)
2551 {
2552 eassert (STRINGP (it->string));
2553 eassert (IT_STRING_CHARPOS (*it) >= 0);
2554 }
2555 else
2556 {
2557 eassert (IT_STRING_CHARPOS (*it) < 0);
2558 if (it->method == GET_FROM_BUFFER)
2559 {
2560 /* Check that character and byte positions agree. */
2561 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2562 }
2563 }
2564
2565 if (it->dpvec)
2566 eassert (it->current.dpvec_index >= 0);
2567 else
2568 eassert (it->current.dpvec_index < 0);
2569 }
2570
2571 #define CHECK_IT(IT) check_it ((IT))
2572
2573 #else /* not 0 */
2574
2575 #define CHECK_IT(IT) (void) 0
2576
2577 #endif /* not 0 */
2578
2579
2580 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2581
2582 /* Check that the window end of window W is what we expect it
2583 to be---the last row in the current matrix displaying text. */
2584
2585 static void
2586 check_window_end (struct window *w)
2587 {
2588 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2589 {
2590 struct glyph_row *row;
2591 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2592 !row->enabled_p
2593 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2594 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2595 }
2596 }
2597
2598 #define CHECK_WINDOW_END(W) check_window_end ((W))
2599
2600 #else
2601
2602 #define CHECK_WINDOW_END(W) (void) 0
2603
2604 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2605
2606 /* Return mark position if current buffer has the region of non-zero length,
2607 or -1 otherwise. */
2608
2609 static ptrdiff_t
2610 markpos_of_region (void)
2611 {
2612 if (!NILP (Vtransient_mark_mode)
2613 && !NILP (BVAR (current_buffer, mark_active))
2614 && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
2615 {
2616 ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
2617
2618 if (markpos != PT)
2619 return markpos;
2620 }
2621 return -1;
2622 }
2623
2624 /***********************************************************************
2625 Iterator initialization
2626 ***********************************************************************/
2627
2628 /* Initialize IT for displaying current_buffer in window W, starting
2629 at character position CHARPOS. CHARPOS < 0 means that no buffer
2630 position is specified which is useful when the iterator is assigned
2631 a position later. BYTEPOS is the byte position corresponding to
2632 CHARPOS.
2633
2634 If ROW is not null, calls to produce_glyphs with IT as parameter
2635 will produce glyphs in that row.
2636
2637 BASE_FACE_ID is the id of a base face to use. It must be one of
2638 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2639 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2640 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2641
2642 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2643 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2644 will be initialized to use the corresponding mode line glyph row of
2645 the desired matrix of W. */
2646
2647 void
2648 init_iterator (struct it *it, struct window *w,
2649 ptrdiff_t charpos, ptrdiff_t bytepos,
2650 struct glyph_row *row, enum face_id base_face_id)
2651 {
2652 ptrdiff_t markpos;
2653 enum face_id remapped_base_face_id = base_face_id;
2654
2655 /* Some precondition checks. */
2656 eassert (w != NULL && it != NULL);
2657 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2658 && charpos <= ZV));
2659
2660 /* If face attributes have been changed since the last redisplay,
2661 free realized faces now because they depend on face definitions
2662 that might have changed. Don't free faces while there might be
2663 desired matrices pending which reference these faces. */
2664 if (face_change_count && !inhibit_free_realized_faces)
2665 {
2666 face_change_count = 0;
2667 free_all_realized_faces (Qnil);
2668 }
2669
2670 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2671 if (! NILP (Vface_remapping_alist))
2672 remapped_base_face_id
2673 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2674
2675 /* Use one of the mode line rows of W's desired matrix if
2676 appropriate. */
2677 if (row == NULL)
2678 {
2679 if (base_face_id == MODE_LINE_FACE_ID
2680 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2681 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2682 else if (base_face_id == HEADER_LINE_FACE_ID)
2683 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2684 }
2685
2686 /* Clear IT. */
2687 memset (it, 0, sizeof *it);
2688 it->current.overlay_string_index = -1;
2689 it->current.dpvec_index = -1;
2690 it->base_face_id = remapped_base_face_id;
2691 it->string = Qnil;
2692 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2693 it->paragraph_embedding = L2R;
2694 it->bidi_it.string.lstring = Qnil;
2695 it->bidi_it.string.s = NULL;
2696 it->bidi_it.string.bufpos = 0;
2697 it->bidi_it.w = w;
2698
2699 /* The window in which we iterate over current_buffer: */
2700 XSETWINDOW (it->window, w);
2701 it->w = w;
2702 it->f = XFRAME (w->frame);
2703
2704 it->cmp_it.id = -1;
2705
2706 /* Extra space between lines (on window systems only). */
2707 if (base_face_id == DEFAULT_FACE_ID
2708 && FRAME_WINDOW_P (it->f))
2709 {
2710 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2711 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2712 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2713 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2714 * FRAME_LINE_HEIGHT (it->f));
2715 else if (it->f->extra_line_spacing > 0)
2716 it->extra_line_spacing = it->f->extra_line_spacing;
2717 it->max_extra_line_spacing = 0;
2718 }
2719
2720 /* If realized faces have been removed, e.g. because of face
2721 attribute changes of named faces, recompute them. When running
2722 in batch mode, the face cache of the initial frame is null. If
2723 we happen to get called, make a dummy face cache. */
2724 if (FRAME_FACE_CACHE (it->f) == NULL)
2725 init_frame_faces (it->f);
2726 if (FRAME_FACE_CACHE (it->f)->used == 0)
2727 recompute_basic_faces (it->f);
2728
2729 /* Current value of the `slice', `space-width', and 'height' properties. */
2730 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2731 it->space_width = Qnil;
2732 it->font_height = Qnil;
2733 it->override_ascent = -1;
2734
2735 /* Are control characters displayed as `^C'? */
2736 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2737
2738 /* -1 means everything between a CR and the following line end
2739 is invisible. >0 means lines indented more than this value are
2740 invisible. */
2741 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2742 ? (clip_to_bounds
2743 (-1, XINT (BVAR (current_buffer, selective_display)),
2744 PTRDIFF_MAX))
2745 : (!NILP (BVAR (current_buffer, selective_display))
2746 ? -1 : 0));
2747 it->selective_display_ellipsis_p
2748 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2749
2750 /* Display table to use. */
2751 it->dp = window_display_table (w);
2752
2753 /* Are multibyte characters enabled in current_buffer? */
2754 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2755
2756 /* If visible region is of non-zero length, set IT->region_beg_charpos
2757 and IT->region_end_charpos to the start and end of a visible region
2758 in window IT->w. Set both to -1 to indicate no region. */
2759 markpos = markpos_of_region ();
2760 if (markpos >= 0
2761 /* Maybe highlight only in selected window. */
2762 && (/* Either show region everywhere. */
2763 highlight_nonselected_windows
2764 /* Or show region in the selected window. */
2765 || w == XWINDOW (selected_window)
2766 /* Or show the region if we are in the mini-buffer and W is
2767 the window the mini-buffer refers to. */
2768 || (MINI_WINDOW_P (XWINDOW (selected_window))
2769 && WINDOWP (minibuf_selected_window)
2770 && w == XWINDOW (minibuf_selected_window))))
2771 {
2772 it->region_beg_charpos = min (PT, markpos);
2773 it->region_end_charpos = max (PT, markpos);
2774 }
2775 else
2776 it->region_beg_charpos = it->region_end_charpos = -1;
2777
2778 /* Get the position at which the redisplay_end_trigger hook should
2779 be run, if it is to be run at all. */
2780 if (MARKERP (w->redisplay_end_trigger)
2781 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2782 it->redisplay_end_trigger_charpos
2783 = marker_position (w->redisplay_end_trigger);
2784 else if (INTEGERP (w->redisplay_end_trigger))
2785 it->redisplay_end_trigger_charpos =
2786 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2787
2788 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2789
2790 /* Are lines in the display truncated? */
2791 if (base_face_id != DEFAULT_FACE_ID
2792 || it->w->hscroll
2793 || (! WINDOW_FULL_WIDTH_P (it->w)
2794 && ((!NILP (Vtruncate_partial_width_windows)
2795 && !INTEGERP (Vtruncate_partial_width_windows))
2796 || (INTEGERP (Vtruncate_partial_width_windows)
2797 && (WINDOW_TOTAL_COLS (it->w)
2798 < XINT (Vtruncate_partial_width_windows))))))
2799 it->line_wrap = TRUNCATE;
2800 else if (NILP (BVAR (current_buffer, truncate_lines)))
2801 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2802 ? WINDOW_WRAP : WORD_WRAP;
2803 else
2804 it->line_wrap = TRUNCATE;
2805
2806 /* Get dimensions of truncation and continuation glyphs. These are
2807 displayed as fringe bitmaps under X, but we need them for such
2808 frames when the fringes are turned off. But leave the dimensions
2809 zero for tooltip frames, as these glyphs look ugly there and also
2810 sabotage calculations of tooltip dimensions in x-show-tip. */
2811 #ifdef HAVE_WINDOW_SYSTEM
2812 if (!(FRAME_WINDOW_P (it->f)
2813 && FRAMEP (tip_frame)
2814 && it->f == XFRAME (tip_frame)))
2815 #endif
2816 {
2817 if (it->line_wrap == TRUNCATE)
2818 {
2819 /* We will need the truncation glyph. */
2820 eassert (it->glyph_row == NULL);
2821 produce_special_glyphs (it, IT_TRUNCATION);
2822 it->truncation_pixel_width = it->pixel_width;
2823 }
2824 else
2825 {
2826 /* We will need the continuation glyph. */
2827 eassert (it->glyph_row == NULL);
2828 produce_special_glyphs (it, IT_CONTINUATION);
2829 it->continuation_pixel_width = it->pixel_width;
2830 }
2831 }
2832
2833 /* Reset these values to zero because the produce_special_glyphs
2834 above has changed them. */
2835 it->pixel_width = it->ascent = it->descent = 0;
2836 it->phys_ascent = it->phys_descent = 0;
2837
2838 /* Set this after getting the dimensions of truncation and
2839 continuation glyphs, so that we don't produce glyphs when calling
2840 produce_special_glyphs, above. */
2841 it->glyph_row = row;
2842 it->area = TEXT_AREA;
2843
2844 /* Forget any previous info about this row being reversed. */
2845 if (it->glyph_row)
2846 it->glyph_row->reversed_p = 0;
2847
2848 /* Get the dimensions of the display area. The display area
2849 consists of the visible window area plus a horizontally scrolled
2850 part to the left of the window. All x-values are relative to the
2851 start of this total display area. */
2852 if (base_face_id != DEFAULT_FACE_ID)
2853 {
2854 /* Mode lines, menu bar in terminal frames. */
2855 it->first_visible_x = 0;
2856 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2857 }
2858 else
2859 {
2860 it->first_visible_x =
2861 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2862 it->last_visible_x = (it->first_visible_x
2863 + window_box_width (w, TEXT_AREA));
2864
2865 /* If we truncate lines, leave room for the truncation glyph(s) at
2866 the right margin. Otherwise, leave room for the continuation
2867 glyph(s). Done only if the window has no fringes. Since we
2868 don't know at this point whether there will be any R2L lines in
2869 the window, we reserve space for truncation/continuation glyphs
2870 even if only one of the fringes is absent. */
2871 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2872 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2873 {
2874 if (it->line_wrap == TRUNCATE)
2875 it->last_visible_x -= it->truncation_pixel_width;
2876 else
2877 it->last_visible_x -= it->continuation_pixel_width;
2878 }
2879
2880 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2881 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2882 }
2883
2884 /* Leave room for a border glyph. */
2885 if (!FRAME_WINDOW_P (it->f)
2886 && !WINDOW_RIGHTMOST_P (it->w))
2887 it->last_visible_x -= 1;
2888
2889 it->last_visible_y = window_text_bottom_y (w);
2890
2891 /* For mode lines and alike, arrange for the first glyph having a
2892 left box line if the face specifies a box. */
2893 if (base_face_id != DEFAULT_FACE_ID)
2894 {
2895 struct face *face;
2896
2897 it->face_id = remapped_base_face_id;
2898
2899 /* If we have a boxed mode line, make the first character appear
2900 with a left box line. */
2901 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2902 if (face->box != FACE_NO_BOX)
2903 it->start_of_box_run_p = 1;
2904 }
2905
2906 /* If a buffer position was specified, set the iterator there,
2907 getting overlays and face properties from that position. */
2908 if (charpos >= BUF_BEG (current_buffer))
2909 {
2910 it->end_charpos = ZV;
2911 eassert (charpos == BYTE_TO_CHAR (bytepos));
2912 IT_CHARPOS (*it) = charpos;
2913 IT_BYTEPOS (*it) = bytepos;
2914
2915 /* We will rely on `reseat' to set this up properly, via
2916 handle_face_prop. */
2917 it->face_id = it->base_face_id;
2918
2919 it->start = it->current;
2920 /* Do we need to reorder bidirectional text? Not if this is a
2921 unibyte buffer: by definition, none of the single-byte
2922 characters are strong R2L, so no reordering is needed. And
2923 bidi.c doesn't support unibyte buffers anyway. Also, don't
2924 reorder while we are loading loadup.el, since the tables of
2925 character properties needed for reordering are not yet
2926 available. */
2927 it->bidi_p =
2928 NILP (Vpurify_flag)
2929 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2930 && it->multibyte_p;
2931
2932 /* If we are to reorder bidirectional text, init the bidi
2933 iterator. */
2934 if (it->bidi_p)
2935 {
2936 /* Note the paragraph direction that this buffer wants to
2937 use. */
2938 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2939 Qleft_to_right))
2940 it->paragraph_embedding = L2R;
2941 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2942 Qright_to_left))
2943 it->paragraph_embedding = R2L;
2944 else
2945 it->paragraph_embedding = NEUTRAL_DIR;
2946 bidi_unshelve_cache (NULL, 0);
2947 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2948 &it->bidi_it);
2949 }
2950
2951 /* Compute faces etc. */
2952 reseat (it, it->current.pos, 1);
2953 }
2954
2955 CHECK_IT (it);
2956 }
2957
2958
2959 /* Initialize IT for the display of window W with window start POS. */
2960
2961 void
2962 start_display (struct it *it, struct window *w, struct text_pos pos)
2963 {
2964 struct glyph_row *row;
2965 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2966
2967 row = w->desired_matrix->rows + first_vpos;
2968 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2969 it->first_vpos = first_vpos;
2970
2971 /* Don't reseat to previous visible line start if current start
2972 position is in a string or image. */
2973 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2974 {
2975 int start_at_line_beg_p;
2976 int first_y = it->current_y;
2977
2978 /* If window start is not at a line start, skip forward to POS to
2979 get the correct continuation lines width. */
2980 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2981 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2982 if (!start_at_line_beg_p)
2983 {
2984 int new_x;
2985
2986 reseat_at_previous_visible_line_start (it);
2987 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2988
2989 new_x = it->current_x + it->pixel_width;
2990
2991 /* If lines are continued, this line may end in the middle
2992 of a multi-glyph character (e.g. a control character
2993 displayed as \003, or in the middle of an overlay
2994 string). In this case move_it_to above will not have
2995 taken us to the start of the continuation line but to the
2996 end of the continued line. */
2997 if (it->current_x > 0
2998 && it->line_wrap != TRUNCATE /* Lines are continued. */
2999 && (/* And glyph doesn't fit on the line. */
3000 new_x > it->last_visible_x
3001 /* Or it fits exactly and we're on a window
3002 system frame. */
3003 || (new_x == it->last_visible_x
3004 && FRAME_WINDOW_P (it->f)
3005 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3006 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3007 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3008 {
3009 if ((it->current.dpvec_index >= 0
3010 || it->current.overlay_string_index >= 0)
3011 /* If we are on a newline from a display vector or
3012 overlay string, then we are already at the end of
3013 a screen line; no need to go to the next line in
3014 that case, as this line is not really continued.
3015 (If we do go to the next line, C-e will not DTRT.) */
3016 && it->c != '\n')
3017 {
3018 set_iterator_to_next (it, 1);
3019 move_it_in_display_line_to (it, -1, -1, 0);
3020 }
3021
3022 it->continuation_lines_width += it->current_x;
3023 }
3024 /* If the character at POS is displayed via a display
3025 vector, move_it_to above stops at the final glyph of
3026 IT->dpvec. To make the caller redisplay that character
3027 again (a.k.a. start at POS), we need to reset the
3028 dpvec_index to the beginning of IT->dpvec. */
3029 else if (it->current.dpvec_index >= 0)
3030 it->current.dpvec_index = 0;
3031
3032 /* We're starting a new display line, not affected by the
3033 height of the continued line, so clear the appropriate
3034 fields in the iterator structure. */
3035 it->max_ascent = it->max_descent = 0;
3036 it->max_phys_ascent = it->max_phys_descent = 0;
3037
3038 it->current_y = first_y;
3039 it->vpos = 0;
3040 it->current_x = it->hpos = 0;
3041 }
3042 }
3043 }
3044
3045
3046 /* Return 1 if POS is a position in ellipses displayed for invisible
3047 text. W is the window we display, for text property lookup. */
3048
3049 static int
3050 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3051 {
3052 Lisp_Object prop, window;
3053 int ellipses_p = 0;
3054 ptrdiff_t charpos = CHARPOS (pos->pos);
3055
3056 /* If POS specifies a position in a display vector, this might
3057 be for an ellipsis displayed for invisible text. We won't
3058 get the iterator set up for delivering that ellipsis unless
3059 we make sure that it gets aware of the invisible text. */
3060 if (pos->dpvec_index >= 0
3061 && pos->overlay_string_index < 0
3062 && CHARPOS (pos->string_pos) < 0
3063 && charpos > BEGV
3064 && (XSETWINDOW (window, w),
3065 prop = Fget_char_property (make_number (charpos),
3066 Qinvisible, window),
3067 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3068 {
3069 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3070 window);
3071 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3072 }
3073
3074 return ellipses_p;
3075 }
3076
3077
3078 /* Initialize IT for stepping through current_buffer in window W,
3079 starting at position POS that includes overlay string and display
3080 vector/ control character translation position information. Value
3081 is zero if there are overlay strings with newlines at POS. */
3082
3083 static int
3084 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3085 {
3086 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3087 int i, overlay_strings_with_newlines = 0;
3088
3089 /* If POS specifies a position in a display vector, this might
3090 be for an ellipsis displayed for invisible text. We won't
3091 get the iterator set up for delivering that ellipsis unless
3092 we make sure that it gets aware of the invisible text. */
3093 if (in_ellipses_for_invisible_text_p (pos, w))
3094 {
3095 --charpos;
3096 bytepos = 0;
3097 }
3098
3099 /* Keep in mind: the call to reseat in init_iterator skips invisible
3100 text, so we might end up at a position different from POS. This
3101 is only a problem when POS is a row start after a newline and an
3102 overlay starts there with an after-string, and the overlay has an
3103 invisible property. Since we don't skip invisible text in
3104 display_line and elsewhere immediately after consuming the
3105 newline before the row start, such a POS will not be in a string,
3106 but the call to init_iterator below will move us to the
3107 after-string. */
3108 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3109
3110 /* This only scans the current chunk -- it should scan all chunks.
3111 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3112 to 16 in 22.1 to make this a lesser problem. */
3113 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3114 {
3115 const char *s = SSDATA (it->overlay_strings[i]);
3116 const char *e = s + SBYTES (it->overlay_strings[i]);
3117
3118 while (s < e && *s != '\n')
3119 ++s;
3120
3121 if (s < e)
3122 {
3123 overlay_strings_with_newlines = 1;
3124 break;
3125 }
3126 }
3127
3128 /* If position is within an overlay string, set up IT to the right
3129 overlay string. */
3130 if (pos->overlay_string_index >= 0)
3131 {
3132 int relative_index;
3133
3134 /* If the first overlay string happens to have a `display'
3135 property for an image, the iterator will be set up for that
3136 image, and we have to undo that setup first before we can
3137 correct the overlay string index. */
3138 if (it->method == GET_FROM_IMAGE)
3139 pop_it (it);
3140
3141 /* We already have the first chunk of overlay strings in
3142 IT->overlay_strings. Load more until the one for
3143 pos->overlay_string_index is in IT->overlay_strings. */
3144 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3145 {
3146 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3147 it->current.overlay_string_index = 0;
3148 while (n--)
3149 {
3150 load_overlay_strings (it, 0);
3151 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3152 }
3153 }
3154
3155 it->current.overlay_string_index = pos->overlay_string_index;
3156 relative_index = (it->current.overlay_string_index
3157 % OVERLAY_STRING_CHUNK_SIZE);
3158 it->string = it->overlay_strings[relative_index];
3159 eassert (STRINGP (it->string));
3160 it->current.string_pos = pos->string_pos;
3161 it->method = GET_FROM_STRING;
3162 it->end_charpos = SCHARS (it->string);
3163 /* Set up the bidi iterator for this overlay string. */
3164 if (it->bidi_p)
3165 {
3166 it->bidi_it.string.lstring = it->string;
3167 it->bidi_it.string.s = NULL;
3168 it->bidi_it.string.schars = SCHARS (it->string);
3169 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3170 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3171 it->bidi_it.string.unibyte = !it->multibyte_p;
3172 it->bidi_it.w = it->w;
3173 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3174 FRAME_WINDOW_P (it->f), &it->bidi_it);
3175
3176 /* Synchronize the state of the bidi iterator with
3177 pos->string_pos. For any string position other than
3178 zero, this will be done automagically when we resume
3179 iteration over the string and get_visually_first_element
3180 is called. But if string_pos is zero, and the string is
3181 to be reordered for display, we need to resync manually,
3182 since it could be that the iteration state recorded in
3183 pos ended at string_pos of 0 moving backwards in string. */
3184 if (CHARPOS (pos->string_pos) == 0)
3185 {
3186 get_visually_first_element (it);
3187 if (IT_STRING_CHARPOS (*it) != 0)
3188 do {
3189 /* Paranoia. */
3190 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3191 bidi_move_to_visually_next (&it->bidi_it);
3192 } while (it->bidi_it.charpos != 0);
3193 }
3194 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3195 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3196 }
3197 }
3198
3199 if (CHARPOS (pos->string_pos) >= 0)
3200 {
3201 /* Recorded position is not in an overlay string, but in another
3202 string. This can only be a string from a `display' property.
3203 IT should already be filled with that string. */
3204 it->current.string_pos = pos->string_pos;
3205 eassert (STRINGP (it->string));
3206 if (it->bidi_p)
3207 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3208 FRAME_WINDOW_P (it->f), &it->bidi_it);
3209 }
3210
3211 /* Restore position in display vector translations, control
3212 character translations or ellipses. */
3213 if (pos->dpvec_index >= 0)
3214 {
3215 if (it->dpvec == NULL)
3216 get_next_display_element (it);
3217 eassert (it->dpvec && it->current.dpvec_index == 0);
3218 it->current.dpvec_index = pos->dpvec_index;
3219 }
3220
3221 CHECK_IT (it);
3222 return !overlay_strings_with_newlines;
3223 }
3224
3225
3226 /* Initialize IT for stepping through current_buffer in window W
3227 starting at ROW->start. */
3228
3229 static void
3230 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3231 {
3232 init_from_display_pos (it, w, &row->start);
3233 it->start = row->start;
3234 it->continuation_lines_width = row->continuation_lines_width;
3235 CHECK_IT (it);
3236 }
3237
3238
3239 /* Initialize IT for stepping through current_buffer in window W
3240 starting in the line following ROW, i.e. starting at ROW->end.
3241 Value is zero if there are overlay strings with newlines at ROW's
3242 end position. */
3243
3244 static int
3245 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3246 {
3247 int success = 0;
3248
3249 if (init_from_display_pos (it, w, &row->end))
3250 {
3251 if (row->continued_p)
3252 it->continuation_lines_width
3253 = row->continuation_lines_width + row->pixel_width;
3254 CHECK_IT (it);
3255 success = 1;
3256 }
3257
3258 return success;
3259 }
3260
3261
3262
3263 \f
3264 /***********************************************************************
3265 Text properties
3266 ***********************************************************************/
3267
3268 /* Called when IT reaches IT->stop_charpos. Handle text property and
3269 overlay changes. Set IT->stop_charpos to the next position where
3270 to stop. */
3271
3272 static void
3273 handle_stop (struct it *it)
3274 {
3275 enum prop_handled handled;
3276 int handle_overlay_change_p;
3277 struct props *p;
3278
3279 it->dpvec = NULL;
3280 it->current.dpvec_index = -1;
3281 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3282 it->ignore_overlay_strings_at_pos_p = 0;
3283 it->ellipsis_p = 0;
3284
3285 /* Use face of preceding text for ellipsis (if invisible) */
3286 if (it->selective_display_ellipsis_p)
3287 it->saved_face_id = it->face_id;
3288
3289 do
3290 {
3291 handled = HANDLED_NORMALLY;
3292
3293 /* Call text property handlers. */
3294 for (p = it_props; p->handler; ++p)
3295 {
3296 handled = p->handler (it);
3297
3298 if (handled == HANDLED_RECOMPUTE_PROPS)
3299 break;
3300 else if (handled == HANDLED_RETURN)
3301 {
3302 /* We still want to show before and after strings from
3303 overlays even if the actual buffer text is replaced. */
3304 if (!handle_overlay_change_p
3305 || it->sp > 1
3306 /* Don't call get_overlay_strings_1 if we already
3307 have overlay strings loaded, because doing so
3308 will load them again and push the iterator state
3309 onto the stack one more time, which is not
3310 expected by the rest of the code that processes
3311 overlay strings. */
3312 || (it->current.overlay_string_index < 0
3313 ? !get_overlay_strings_1 (it, 0, 0)
3314 : 0))
3315 {
3316 if (it->ellipsis_p)
3317 setup_for_ellipsis (it, 0);
3318 /* When handling a display spec, we might load an
3319 empty string. In that case, discard it here. We
3320 used to discard it in handle_single_display_spec,
3321 but that causes get_overlay_strings_1, above, to
3322 ignore overlay strings that we must check. */
3323 if (STRINGP (it->string) && !SCHARS (it->string))
3324 pop_it (it);
3325 return;
3326 }
3327 else if (STRINGP (it->string) && !SCHARS (it->string))
3328 pop_it (it);
3329 else
3330 {
3331 it->ignore_overlay_strings_at_pos_p = 1;
3332 it->string_from_display_prop_p = 0;
3333 it->from_disp_prop_p = 0;
3334 handle_overlay_change_p = 0;
3335 }
3336 handled = HANDLED_RECOMPUTE_PROPS;
3337 break;
3338 }
3339 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3340 handle_overlay_change_p = 0;
3341 }
3342
3343 if (handled != HANDLED_RECOMPUTE_PROPS)
3344 {
3345 /* Don't check for overlay strings below when set to deliver
3346 characters from a display vector. */
3347 if (it->method == GET_FROM_DISPLAY_VECTOR)
3348 handle_overlay_change_p = 0;
3349
3350 /* Handle overlay changes.
3351 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3352 if it finds overlays. */
3353 if (handle_overlay_change_p)
3354 handled = handle_overlay_change (it);
3355 }
3356
3357 if (it->ellipsis_p)
3358 {
3359 setup_for_ellipsis (it, 0);
3360 break;
3361 }
3362 }
3363 while (handled == HANDLED_RECOMPUTE_PROPS);
3364
3365 /* Determine where to stop next. */
3366 if (handled == HANDLED_NORMALLY)
3367 compute_stop_pos (it);
3368 }
3369
3370
3371 /* Compute IT->stop_charpos from text property and overlay change
3372 information for IT's current position. */
3373
3374 static void
3375 compute_stop_pos (struct it *it)
3376 {
3377 register INTERVAL iv, next_iv;
3378 Lisp_Object object, limit, position;
3379 ptrdiff_t charpos, bytepos;
3380
3381 if (STRINGP (it->string))
3382 {
3383 /* Strings are usually short, so don't limit the search for
3384 properties. */
3385 it->stop_charpos = it->end_charpos;
3386 object = it->string;
3387 limit = Qnil;
3388 charpos = IT_STRING_CHARPOS (*it);
3389 bytepos = IT_STRING_BYTEPOS (*it);
3390 }
3391 else
3392 {
3393 ptrdiff_t pos;
3394
3395 /* If end_charpos is out of range for some reason, such as a
3396 misbehaving display function, rationalize it (Bug#5984). */
3397 if (it->end_charpos > ZV)
3398 it->end_charpos = ZV;
3399 it->stop_charpos = it->end_charpos;
3400
3401 /* If next overlay change is in front of the current stop pos
3402 (which is IT->end_charpos), stop there. Note: value of
3403 next_overlay_change is point-max if no overlay change
3404 follows. */
3405 charpos = IT_CHARPOS (*it);
3406 bytepos = IT_BYTEPOS (*it);
3407 pos = next_overlay_change (charpos);
3408 if (pos < it->stop_charpos)
3409 it->stop_charpos = pos;
3410
3411 /* If showing the region, we have to stop at the region
3412 start or end because the face might change there. */
3413 if (it->region_beg_charpos > 0)
3414 {
3415 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3416 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3417 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3418 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3419 }
3420
3421 /* Set up variables for computing the stop position from text
3422 property changes. */
3423 XSETBUFFER (object, current_buffer);
3424 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3425 }
3426
3427 /* Get the interval containing IT's position. Value is a null
3428 interval if there isn't such an interval. */
3429 position = make_number (charpos);
3430 iv = validate_interval_range (object, &position, &position, 0);
3431 if (iv)
3432 {
3433 Lisp_Object values_here[LAST_PROP_IDX];
3434 struct props *p;
3435
3436 /* Get properties here. */
3437 for (p = it_props; p->handler; ++p)
3438 values_here[p->idx] = textget (iv->plist, *p->name);
3439
3440 /* Look for an interval following iv that has different
3441 properties. */
3442 for (next_iv = next_interval (iv);
3443 (next_iv
3444 && (NILP (limit)
3445 || XFASTINT (limit) > next_iv->position));
3446 next_iv = next_interval (next_iv))
3447 {
3448 for (p = it_props; p->handler; ++p)
3449 {
3450 Lisp_Object new_value;
3451
3452 new_value = textget (next_iv->plist, *p->name);
3453 if (!EQ (values_here[p->idx], new_value))
3454 break;
3455 }
3456
3457 if (p->handler)
3458 break;
3459 }
3460
3461 if (next_iv)
3462 {
3463 if (INTEGERP (limit)
3464 && next_iv->position >= XFASTINT (limit))
3465 /* No text property change up to limit. */
3466 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3467 else
3468 /* Text properties change in next_iv. */
3469 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3470 }
3471 }
3472
3473 if (it->cmp_it.id < 0)
3474 {
3475 ptrdiff_t stoppos = it->end_charpos;
3476
3477 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3478 stoppos = -1;
3479 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3480 stoppos, it->string);
3481 }
3482
3483 eassert (STRINGP (it->string)
3484 || (it->stop_charpos >= BEGV
3485 && it->stop_charpos >= IT_CHARPOS (*it)));
3486 }
3487
3488
3489 /* Return the position of the next overlay change after POS in
3490 current_buffer. Value is point-max if no overlay change
3491 follows. This is like `next-overlay-change' but doesn't use
3492 xmalloc. */
3493
3494 static ptrdiff_t
3495 next_overlay_change (ptrdiff_t pos)
3496 {
3497 ptrdiff_t i, noverlays;
3498 ptrdiff_t endpos;
3499 Lisp_Object *overlays;
3500
3501 /* Get all overlays at the given position. */
3502 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3503
3504 /* If any of these overlays ends before endpos,
3505 use its ending point instead. */
3506 for (i = 0; i < noverlays; ++i)
3507 {
3508 Lisp_Object oend;
3509 ptrdiff_t oendpos;
3510
3511 oend = OVERLAY_END (overlays[i]);
3512 oendpos = OVERLAY_POSITION (oend);
3513 endpos = min (endpos, oendpos);
3514 }
3515
3516 return endpos;
3517 }
3518
3519 /* How many characters forward to search for a display property or
3520 display string. Searching too far forward makes the bidi display
3521 sluggish, especially in small windows. */
3522 #define MAX_DISP_SCAN 250
3523
3524 /* Return the character position of a display string at or after
3525 position specified by POSITION. If no display string exists at or
3526 after POSITION, return ZV. A display string is either an overlay
3527 with `display' property whose value is a string, or a `display'
3528 text property whose value is a string. STRING is data about the
3529 string to iterate; if STRING->lstring is nil, we are iterating a
3530 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3531 on a GUI frame. DISP_PROP is set to zero if we searched
3532 MAX_DISP_SCAN characters forward without finding any display
3533 strings, non-zero otherwise. It is set to 2 if the display string
3534 uses any kind of `(space ...)' spec that will produce a stretch of
3535 white space in the text area. */
3536 ptrdiff_t
3537 compute_display_string_pos (struct text_pos *position,
3538 struct bidi_string_data *string,
3539 struct window *w,
3540 int frame_window_p, int *disp_prop)
3541 {
3542 /* OBJECT = nil means current buffer. */
3543 Lisp_Object object, object1;
3544 Lisp_Object pos, spec, limpos;
3545 int string_p = (string && (STRINGP (string->lstring) || string->s));
3546 ptrdiff_t eob = string_p ? string->schars : ZV;
3547 ptrdiff_t begb = string_p ? 0 : BEGV;
3548 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3549 ptrdiff_t lim =
3550 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3551 struct text_pos tpos;
3552 int rv = 0;
3553
3554 if (string && STRINGP (string->lstring))
3555 object1 = object = string->lstring;
3556 else if (w && !string_p)
3557 {
3558 XSETWINDOW (object, w);
3559 object1 = Qnil;
3560 }
3561 else
3562 object1 = object = Qnil;
3563
3564 *disp_prop = 1;
3565
3566 if (charpos >= eob
3567 /* We don't support display properties whose values are strings
3568 that have display string properties. */
3569 || string->from_disp_str
3570 /* C strings cannot have display properties. */
3571 || (string->s && !STRINGP (object)))
3572 {
3573 *disp_prop = 0;
3574 return eob;
3575 }
3576
3577 /* If the character at CHARPOS is where the display string begins,
3578 return CHARPOS. */
3579 pos = make_number (charpos);
3580 if (STRINGP (object))
3581 bufpos = string->bufpos;
3582 else
3583 bufpos = charpos;
3584 tpos = *position;
3585 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3586 && (charpos <= begb
3587 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3588 object),
3589 spec))
3590 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3591 frame_window_p)))
3592 {
3593 if (rv == 2)
3594 *disp_prop = 2;
3595 return charpos;
3596 }
3597
3598 /* Look forward for the first character with a `display' property
3599 that will replace the underlying text when displayed. */
3600 limpos = make_number (lim);
3601 do {
3602 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3603 CHARPOS (tpos) = XFASTINT (pos);
3604 if (CHARPOS (tpos) >= lim)
3605 {
3606 *disp_prop = 0;
3607 break;
3608 }
3609 if (STRINGP (object))
3610 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3611 else
3612 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3613 spec = Fget_char_property (pos, Qdisplay, object);
3614 if (!STRINGP (object))
3615 bufpos = CHARPOS (tpos);
3616 } while (NILP (spec)
3617 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3618 bufpos, frame_window_p)));
3619 if (rv == 2)
3620 *disp_prop = 2;
3621
3622 return CHARPOS (tpos);
3623 }
3624
3625 /* Return the character position of the end of the display string that
3626 started at CHARPOS. If there's no display string at CHARPOS,
3627 return -1. A display string is either an overlay with `display'
3628 property whose value is a string or a `display' text property whose
3629 value is a string. */
3630 ptrdiff_t
3631 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3632 {
3633 /* OBJECT = nil means current buffer. */
3634 Lisp_Object object =
3635 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3636 Lisp_Object pos = make_number (charpos);
3637 ptrdiff_t eob =
3638 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3639
3640 if (charpos >= eob || (string->s && !STRINGP (object)))
3641 return eob;
3642
3643 /* It could happen that the display property or overlay was removed
3644 since we found it in compute_display_string_pos above. One way
3645 this can happen is if JIT font-lock was called (through
3646 handle_fontified_prop), and jit-lock-functions remove text
3647 properties or overlays from the portion of buffer that includes
3648 CHARPOS. Muse mode is known to do that, for example. In this
3649 case, we return -1 to the caller, to signal that no display
3650 string is actually present at CHARPOS. See bidi_fetch_char for
3651 how this is handled.
3652
3653 An alternative would be to never look for display properties past
3654 it->stop_charpos. But neither compute_display_string_pos nor
3655 bidi_fetch_char that calls it know or care where the next
3656 stop_charpos is. */
3657 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3658 return -1;
3659
3660 /* Look forward for the first character where the `display' property
3661 changes. */
3662 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3663
3664 return XFASTINT (pos);
3665 }
3666
3667
3668 \f
3669 /***********************************************************************
3670 Fontification
3671 ***********************************************************************/
3672
3673 /* Handle changes in the `fontified' property of the current buffer by
3674 calling hook functions from Qfontification_functions to fontify
3675 regions of text. */
3676
3677 static enum prop_handled
3678 handle_fontified_prop (struct it *it)
3679 {
3680 Lisp_Object prop, pos;
3681 enum prop_handled handled = HANDLED_NORMALLY;
3682
3683 if (!NILP (Vmemory_full))
3684 return handled;
3685
3686 /* Get the value of the `fontified' property at IT's current buffer
3687 position. (The `fontified' property doesn't have a special
3688 meaning in strings.) If the value is nil, call functions from
3689 Qfontification_functions. */
3690 if (!STRINGP (it->string)
3691 && it->s == NULL
3692 && !NILP (Vfontification_functions)
3693 && !NILP (Vrun_hooks)
3694 && (pos = make_number (IT_CHARPOS (*it)),
3695 prop = Fget_char_property (pos, Qfontified, Qnil),
3696 /* Ignore the special cased nil value always present at EOB since
3697 no amount of fontifying will be able to change it. */
3698 NILP (prop) && IT_CHARPOS (*it) < Z))
3699 {
3700 ptrdiff_t count = SPECPDL_INDEX ();
3701 Lisp_Object val;
3702 struct buffer *obuf = current_buffer;
3703 int begv = BEGV, zv = ZV;
3704 int old_clip_changed = current_buffer->clip_changed;
3705
3706 val = Vfontification_functions;
3707 specbind (Qfontification_functions, Qnil);
3708
3709 eassert (it->end_charpos == ZV);
3710
3711 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3712 safe_call1 (val, pos);
3713 else
3714 {
3715 Lisp_Object fns, fn;
3716 struct gcpro gcpro1, gcpro2;
3717
3718 fns = Qnil;
3719 GCPRO2 (val, fns);
3720
3721 for (; CONSP (val); val = XCDR (val))
3722 {
3723 fn = XCAR (val);
3724
3725 if (EQ (fn, Qt))
3726 {
3727 /* A value of t indicates this hook has a local
3728 binding; it means to run the global binding too.
3729 In a global value, t should not occur. If it
3730 does, we must ignore it to avoid an endless
3731 loop. */
3732 for (fns = Fdefault_value (Qfontification_functions);
3733 CONSP (fns);
3734 fns = XCDR (fns))
3735 {
3736 fn = XCAR (fns);
3737 if (!EQ (fn, Qt))
3738 safe_call1 (fn, pos);
3739 }
3740 }
3741 else
3742 safe_call1 (fn, pos);
3743 }
3744
3745 UNGCPRO;
3746 }
3747
3748 unbind_to (count, Qnil);
3749
3750 /* Fontification functions routinely call `save-restriction'.
3751 Normally, this tags clip_changed, which can confuse redisplay
3752 (see discussion in Bug#6671). Since we don't perform any
3753 special handling of fontification changes in the case where
3754 `save-restriction' isn't called, there's no point doing so in
3755 this case either. So, if the buffer's restrictions are
3756 actually left unchanged, reset clip_changed. */
3757 if (obuf == current_buffer)
3758 {
3759 if (begv == BEGV && zv == ZV)
3760 current_buffer->clip_changed = old_clip_changed;
3761 }
3762 /* There isn't much we can reasonably do to protect against
3763 misbehaving fontification, but here's a fig leaf. */
3764 else if (BUFFER_LIVE_P (obuf))
3765 set_buffer_internal_1 (obuf);
3766
3767 /* The fontification code may have added/removed text.
3768 It could do even a lot worse, but let's at least protect against
3769 the most obvious case where only the text past `pos' gets changed',
3770 as is/was done in grep.el where some escapes sequences are turned
3771 into face properties (bug#7876). */
3772 it->end_charpos = ZV;
3773
3774 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3775 something. This avoids an endless loop if they failed to
3776 fontify the text for which reason ever. */
3777 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3778 handled = HANDLED_RECOMPUTE_PROPS;
3779 }
3780
3781 return handled;
3782 }
3783
3784
3785 \f
3786 /***********************************************************************
3787 Faces
3788 ***********************************************************************/
3789
3790 /* Set up iterator IT from face properties at its current position.
3791 Called from handle_stop. */
3792
3793 static enum prop_handled
3794 handle_face_prop (struct it *it)
3795 {
3796 int new_face_id;
3797 ptrdiff_t next_stop;
3798
3799 if (!STRINGP (it->string))
3800 {
3801 new_face_id
3802 = face_at_buffer_position (it->w,
3803 IT_CHARPOS (*it),
3804 it->region_beg_charpos,
3805 it->region_end_charpos,
3806 &next_stop,
3807 (IT_CHARPOS (*it)
3808 + TEXT_PROP_DISTANCE_LIMIT),
3809 0, it->base_face_id);
3810
3811 /* Is this a start of a run of characters with box face?
3812 Caveat: this can be called for a freshly initialized
3813 iterator; face_id is -1 in this case. We know that the new
3814 face will not change until limit, i.e. if the new face has a
3815 box, all characters up to limit will have one. But, as
3816 usual, we don't know whether limit is really the end. */
3817 if (new_face_id != it->face_id)
3818 {
3819 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3820 /* If it->face_id is -1, old_face below will be NULL, see
3821 the definition of FACE_FROM_ID. This will happen if this
3822 is the initial call that gets the face. */
3823 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3824
3825 /* If the value of face_id of the iterator is -1, we have to
3826 look in front of IT's position and see whether there is a
3827 face there that's different from new_face_id. */
3828 if (!old_face && IT_CHARPOS (*it) > BEG)
3829 {
3830 int prev_face_id = face_before_it_pos (it);
3831
3832 old_face = FACE_FROM_ID (it->f, prev_face_id);
3833 }
3834
3835 /* If the new face has a box, but the old face does not,
3836 this is the start of a run of characters with box face,
3837 i.e. this character has a shadow on the left side. */
3838 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3839 && (old_face == NULL || !old_face->box));
3840 it->face_box_p = new_face->box != FACE_NO_BOX;
3841 }
3842 }
3843 else
3844 {
3845 int base_face_id;
3846 ptrdiff_t bufpos;
3847 int i;
3848 Lisp_Object from_overlay
3849 = (it->current.overlay_string_index >= 0
3850 ? it->string_overlays[it->current.overlay_string_index
3851 % OVERLAY_STRING_CHUNK_SIZE]
3852 : Qnil);
3853
3854 /* See if we got to this string directly or indirectly from
3855 an overlay property. That includes the before-string or
3856 after-string of an overlay, strings in display properties
3857 provided by an overlay, their text properties, etc.
3858
3859 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3860 if (! NILP (from_overlay))
3861 for (i = it->sp - 1; i >= 0; i--)
3862 {
3863 if (it->stack[i].current.overlay_string_index >= 0)
3864 from_overlay
3865 = it->string_overlays[it->stack[i].current.overlay_string_index
3866 % OVERLAY_STRING_CHUNK_SIZE];
3867 else if (! NILP (it->stack[i].from_overlay))
3868 from_overlay = it->stack[i].from_overlay;
3869
3870 if (!NILP (from_overlay))
3871 break;
3872 }
3873
3874 if (! NILP (from_overlay))
3875 {
3876 bufpos = IT_CHARPOS (*it);
3877 /* For a string from an overlay, the base face depends
3878 only on text properties and ignores overlays. */
3879 base_face_id
3880 = face_for_overlay_string (it->w,
3881 IT_CHARPOS (*it),
3882 it->region_beg_charpos,
3883 it->region_end_charpos,
3884 &next_stop,
3885 (IT_CHARPOS (*it)
3886 + TEXT_PROP_DISTANCE_LIMIT),
3887 0,
3888 from_overlay);
3889 }
3890 else
3891 {
3892 bufpos = 0;
3893
3894 /* For strings from a `display' property, use the face at
3895 IT's current buffer position as the base face to merge
3896 with, so that overlay strings appear in the same face as
3897 surrounding text, unless they specify their own faces.
3898 For strings from wrap-prefix and line-prefix properties,
3899 use the default face, possibly remapped via
3900 Vface_remapping_alist. */
3901 base_face_id = it->string_from_prefix_prop_p
3902 ? (!NILP (Vface_remapping_alist)
3903 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
3904 : DEFAULT_FACE_ID)
3905 : underlying_face_id (it);
3906 }
3907
3908 new_face_id = face_at_string_position (it->w,
3909 it->string,
3910 IT_STRING_CHARPOS (*it),
3911 bufpos,
3912 it->region_beg_charpos,
3913 it->region_end_charpos,
3914 &next_stop,
3915 base_face_id, 0);
3916
3917 /* Is this a start of a run of characters with box? Caveat:
3918 this can be called for a freshly allocated iterator; face_id
3919 is -1 is this case. We know that the new face will not
3920 change until the next check pos, i.e. if the new face has a
3921 box, all characters up to that position will have a
3922 box. But, as usual, we don't know whether that position
3923 is really the end. */
3924 if (new_face_id != it->face_id)
3925 {
3926 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3927 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3928
3929 /* If new face has a box but old face hasn't, this is the
3930 start of a run of characters with box, i.e. it has a
3931 shadow on the left side. */
3932 it->start_of_box_run_p
3933 = new_face->box && (old_face == NULL || !old_face->box);
3934 it->face_box_p = new_face->box != FACE_NO_BOX;
3935 }
3936 }
3937
3938 it->face_id = new_face_id;
3939 return HANDLED_NORMALLY;
3940 }
3941
3942
3943 /* Return the ID of the face ``underlying'' IT's current position,
3944 which is in a string. If the iterator is associated with a
3945 buffer, return the face at IT's current buffer position.
3946 Otherwise, use the iterator's base_face_id. */
3947
3948 static int
3949 underlying_face_id (struct it *it)
3950 {
3951 int face_id = it->base_face_id, i;
3952
3953 eassert (STRINGP (it->string));
3954
3955 for (i = it->sp - 1; i >= 0; --i)
3956 if (NILP (it->stack[i].string))
3957 face_id = it->stack[i].face_id;
3958
3959 return face_id;
3960 }
3961
3962
3963 /* Compute the face one character before or after the current position
3964 of IT, in the visual order. BEFORE_P non-zero means get the face
3965 in front (to the left in L2R paragraphs, to the right in R2L
3966 paragraphs) of IT's screen position. Value is the ID of the face. */
3967
3968 static int
3969 face_before_or_after_it_pos (struct it *it, int before_p)
3970 {
3971 int face_id, limit;
3972 ptrdiff_t next_check_charpos;
3973 struct it it_copy;
3974 void *it_copy_data = NULL;
3975
3976 eassert (it->s == NULL);
3977
3978 if (STRINGP (it->string))
3979 {
3980 ptrdiff_t bufpos, charpos;
3981 int base_face_id;
3982
3983 /* No face change past the end of the string (for the case
3984 we are padding with spaces). No face change before the
3985 string start. */
3986 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3987 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3988 return it->face_id;
3989
3990 if (!it->bidi_p)
3991 {
3992 /* Set charpos to the position before or after IT's current
3993 position, in the logical order, which in the non-bidi
3994 case is the same as the visual order. */
3995 if (before_p)
3996 charpos = IT_STRING_CHARPOS (*it) - 1;
3997 else if (it->what == IT_COMPOSITION)
3998 /* For composition, we must check the character after the
3999 composition. */
4000 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4001 else
4002 charpos = IT_STRING_CHARPOS (*it) + 1;
4003 }
4004 else
4005 {
4006 if (before_p)
4007 {
4008 /* With bidi iteration, the character before the current
4009 in the visual order cannot be found by simple
4010 iteration, because "reverse" reordering is not
4011 supported. Instead, we need to use the move_it_*
4012 family of functions. */
4013 /* Ignore face changes before the first visible
4014 character on this display line. */
4015 if (it->current_x <= it->first_visible_x)
4016 return it->face_id;
4017 SAVE_IT (it_copy, *it, it_copy_data);
4018 /* Implementation note: Since move_it_in_display_line
4019 works in the iterator geometry, and thinks the first
4020 character is always the leftmost, even in R2L lines,
4021 we don't need to distinguish between the R2L and L2R
4022 cases here. */
4023 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4024 it_copy.current_x - 1, MOVE_TO_X);
4025 charpos = IT_STRING_CHARPOS (it_copy);
4026 RESTORE_IT (it, it, it_copy_data);
4027 }
4028 else
4029 {
4030 /* Set charpos to the string position of the character
4031 that comes after IT's current position in the visual
4032 order. */
4033 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4034
4035 it_copy = *it;
4036 while (n--)
4037 bidi_move_to_visually_next (&it_copy.bidi_it);
4038
4039 charpos = it_copy.bidi_it.charpos;
4040 }
4041 }
4042 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4043
4044 if (it->current.overlay_string_index >= 0)
4045 bufpos = IT_CHARPOS (*it);
4046 else
4047 bufpos = 0;
4048
4049 base_face_id = underlying_face_id (it);
4050
4051 /* Get the face for ASCII, or unibyte. */
4052 face_id = face_at_string_position (it->w,
4053 it->string,
4054 charpos,
4055 bufpos,
4056 it->region_beg_charpos,
4057 it->region_end_charpos,
4058 &next_check_charpos,
4059 base_face_id, 0);
4060
4061 /* Correct the face for charsets different from ASCII. Do it
4062 for the multibyte case only. The face returned above is
4063 suitable for unibyte text if IT->string is unibyte. */
4064 if (STRING_MULTIBYTE (it->string))
4065 {
4066 struct text_pos pos1 = string_pos (charpos, it->string);
4067 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4068 int c, len;
4069 struct face *face = FACE_FROM_ID (it->f, face_id);
4070
4071 c = string_char_and_length (p, &len);
4072 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4073 }
4074 }
4075 else
4076 {
4077 struct text_pos pos;
4078
4079 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4080 || (IT_CHARPOS (*it) <= BEGV && before_p))
4081 return it->face_id;
4082
4083 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4084 pos = it->current.pos;
4085
4086 if (!it->bidi_p)
4087 {
4088 if (before_p)
4089 DEC_TEXT_POS (pos, it->multibyte_p);
4090 else
4091 {
4092 if (it->what == IT_COMPOSITION)
4093 {
4094 /* For composition, we must check the position after
4095 the composition. */
4096 pos.charpos += it->cmp_it.nchars;
4097 pos.bytepos += it->len;
4098 }
4099 else
4100 INC_TEXT_POS (pos, it->multibyte_p);
4101 }
4102 }
4103 else
4104 {
4105 if (before_p)
4106 {
4107 /* With bidi iteration, the character before the current
4108 in the visual order cannot be found by simple
4109 iteration, because "reverse" reordering is not
4110 supported. Instead, we need to use the move_it_*
4111 family of functions. */
4112 /* Ignore face changes before the first visible
4113 character on this display line. */
4114 if (it->current_x <= it->first_visible_x)
4115 return it->face_id;
4116 SAVE_IT (it_copy, *it, it_copy_data);
4117 /* Implementation note: Since move_it_in_display_line
4118 works in the iterator geometry, and thinks the first
4119 character is always the leftmost, even in R2L lines,
4120 we don't need to distinguish between the R2L and L2R
4121 cases here. */
4122 move_it_in_display_line (&it_copy, ZV,
4123 it_copy.current_x - 1, MOVE_TO_X);
4124 pos = it_copy.current.pos;
4125 RESTORE_IT (it, it, it_copy_data);
4126 }
4127 else
4128 {
4129 /* Set charpos to the buffer position of the character
4130 that comes after IT's current position in the visual
4131 order. */
4132 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4133
4134 it_copy = *it;
4135 while (n--)
4136 bidi_move_to_visually_next (&it_copy.bidi_it);
4137
4138 SET_TEXT_POS (pos,
4139 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4140 }
4141 }
4142 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4143
4144 /* Determine face for CHARSET_ASCII, or unibyte. */
4145 face_id = face_at_buffer_position (it->w,
4146 CHARPOS (pos),
4147 it->region_beg_charpos,
4148 it->region_end_charpos,
4149 &next_check_charpos,
4150 limit, 0, -1);
4151
4152 /* Correct the face for charsets different from ASCII. Do it
4153 for the multibyte case only. The face returned above is
4154 suitable for unibyte text if current_buffer is unibyte. */
4155 if (it->multibyte_p)
4156 {
4157 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4158 struct face *face = FACE_FROM_ID (it->f, face_id);
4159 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4160 }
4161 }
4162
4163 return face_id;
4164 }
4165
4166
4167 \f
4168 /***********************************************************************
4169 Invisible text
4170 ***********************************************************************/
4171
4172 /* Set up iterator IT from invisible properties at its current
4173 position. Called from handle_stop. */
4174
4175 static enum prop_handled
4176 handle_invisible_prop (struct it *it)
4177 {
4178 enum prop_handled handled = HANDLED_NORMALLY;
4179 int invis_p;
4180 Lisp_Object prop;
4181
4182 if (STRINGP (it->string))
4183 {
4184 Lisp_Object end_charpos, limit, charpos;
4185
4186 /* Get the value of the invisible text property at the
4187 current position. Value will be nil if there is no such
4188 property. */
4189 charpos = make_number (IT_STRING_CHARPOS (*it));
4190 prop = Fget_text_property (charpos, Qinvisible, it->string);
4191 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4192
4193 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4194 {
4195 /* Record whether we have to display an ellipsis for the
4196 invisible text. */
4197 int display_ellipsis_p = (invis_p == 2);
4198 ptrdiff_t len, endpos;
4199
4200 handled = HANDLED_RECOMPUTE_PROPS;
4201
4202 /* Get the position at which the next visible text can be
4203 found in IT->string, if any. */
4204 endpos = len = SCHARS (it->string);
4205 XSETINT (limit, len);
4206 do
4207 {
4208 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4209 it->string, limit);
4210 if (INTEGERP (end_charpos))
4211 {
4212 endpos = XFASTINT (end_charpos);
4213 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4214 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4215 if (invis_p == 2)
4216 display_ellipsis_p = 1;
4217 }
4218 }
4219 while (invis_p && endpos < len);
4220
4221 if (display_ellipsis_p)
4222 it->ellipsis_p = 1;
4223
4224 if (endpos < len)
4225 {
4226 /* Text at END_CHARPOS is visible. Move IT there. */
4227 struct text_pos old;
4228 ptrdiff_t oldpos;
4229
4230 old = it->current.string_pos;
4231 oldpos = CHARPOS (old);
4232 if (it->bidi_p)
4233 {
4234 if (it->bidi_it.first_elt
4235 && it->bidi_it.charpos < SCHARS (it->string))
4236 bidi_paragraph_init (it->paragraph_embedding,
4237 &it->bidi_it, 1);
4238 /* Bidi-iterate out of the invisible text. */
4239 do
4240 {
4241 bidi_move_to_visually_next (&it->bidi_it);
4242 }
4243 while (oldpos <= it->bidi_it.charpos
4244 && it->bidi_it.charpos < endpos);
4245
4246 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4247 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4248 if (IT_CHARPOS (*it) >= endpos)
4249 it->prev_stop = endpos;
4250 }
4251 else
4252 {
4253 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4254 compute_string_pos (&it->current.string_pos, old, it->string);
4255 }
4256 }
4257 else
4258 {
4259 /* The rest of the string is invisible. If this is an
4260 overlay string, proceed with the next overlay string
4261 or whatever comes and return a character from there. */
4262 if (it->current.overlay_string_index >= 0
4263 && !display_ellipsis_p)
4264 {
4265 next_overlay_string (it);
4266 /* Don't check for overlay strings when we just
4267 finished processing them. */
4268 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4269 }
4270 else
4271 {
4272 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4273 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4274 }
4275 }
4276 }
4277 }
4278 else
4279 {
4280 ptrdiff_t newpos, next_stop, start_charpos, tem;
4281 Lisp_Object pos, overlay;
4282
4283 /* First of all, is there invisible text at this position? */
4284 tem = start_charpos = IT_CHARPOS (*it);
4285 pos = make_number (tem);
4286 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4287 &overlay);
4288 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4289
4290 /* If we are on invisible text, skip over it. */
4291 if (invis_p && start_charpos < it->end_charpos)
4292 {
4293 /* Record whether we have to display an ellipsis for the
4294 invisible text. */
4295 int display_ellipsis_p = invis_p == 2;
4296
4297 handled = HANDLED_RECOMPUTE_PROPS;
4298
4299 /* Loop skipping over invisible text. The loop is left at
4300 ZV or with IT on the first char being visible again. */
4301 do
4302 {
4303 /* Try to skip some invisible text. Return value is the
4304 position reached which can be equal to where we start
4305 if there is nothing invisible there. This skips both
4306 over invisible text properties and overlays with
4307 invisible property. */
4308 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4309
4310 /* If we skipped nothing at all we weren't at invisible
4311 text in the first place. If everything to the end of
4312 the buffer was skipped, end the loop. */
4313 if (newpos == tem || newpos >= ZV)
4314 invis_p = 0;
4315 else
4316 {
4317 /* We skipped some characters but not necessarily
4318 all there are. Check if we ended up on visible
4319 text. Fget_char_property returns the property of
4320 the char before the given position, i.e. if we
4321 get invis_p = 0, this means that the char at
4322 newpos is visible. */
4323 pos = make_number (newpos);
4324 prop = Fget_char_property (pos, Qinvisible, it->window);
4325 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4326 }
4327
4328 /* If we ended up on invisible text, proceed to
4329 skip starting with next_stop. */
4330 if (invis_p)
4331 tem = next_stop;
4332
4333 /* If there are adjacent invisible texts, don't lose the
4334 second one's ellipsis. */
4335 if (invis_p == 2)
4336 display_ellipsis_p = 1;
4337 }
4338 while (invis_p);
4339
4340 /* The position newpos is now either ZV or on visible text. */
4341 if (it->bidi_p)
4342 {
4343 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4344 int on_newline =
4345 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4346 int after_newline =
4347 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4348
4349 /* If the invisible text ends on a newline or on a
4350 character after a newline, we can avoid the costly,
4351 character by character, bidi iteration to NEWPOS, and
4352 instead simply reseat the iterator there. That's
4353 because all bidi reordering information is tossed at
4354 the newline. This is a big win for modes that hide
4355 complete lines, like Outline, Org, etc. */
4356 if (on_newline || after_newline)
4357 {
4358 struct text_pos tpos;
4359 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4360
4361 SET_TEXT_POS (tpos, newpos, bpos);
4362 reseat_1 (it, tpos, 0);
4363 /* If we reseat on a newline/ZV, we need to prep the
4364 bidi iterator for advancing to the next character
4365 after the newline/EOB, keeping the current paragraph
4366 direction (so that PRODUCE_GLYPHS does TRT wrt
4367 prepending/appending glyphs to a glyph row). */
4368 if (on_newline)
4369 {
4370 it->bidi_it.first_elt = 0;
4371 it->bidi_it.paragraph_dir = pdir;
4372 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4373 it->bidi_it.nchars = 1;
4374 it->bidi_it.ch_len = 1;
4375 }
4376 }
4377 else /* Must use the slow method. */
4378 {
4379 /* With bidi iteration, the region of invisible text
4380 could start and/or end in the middle of a
4381 non-base embedding level. Therefore, we need to
4382 skip invisible text using the bidi iterator,
4383 starting at IT's current position, until we find
4384 ourselves outside of the invisible text.
4385 Skipping invisible text _after_ bidi iteration
4386 avoids affecting the visual order of the
4387 displayed text when invisible properties are
4388 added or removed. */
4389 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4390 {
4391 /* If we were `reseat'ed to a new paragraph,
4392 determine the paragraph base direction. We
4393 need to do it now because
4394 next_element_from_buffer may not have a
4395 chance to do it, if we are going to skip any
4396 text at the beginning, which resets the
4397 FIRST_ELT flag. */
4398 bidi_paragraph_init (it->paragraph_embedding,
4399 &it->bidi_it, 1);
4400 }
4401 do
4402 {
4403 bidi_move_to_visually_next (&it->bidi_it);
4404 }
4405 while (it->stop_charpos <= it->bidi_it.charpos
4406 && it->bidi_it.charpos < newpos);
4407 IT_CHARPOS (*it) = it->bidi_it.charpos;
4408 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4409 /* If we overstepped NEWPOS, record its position in
4410 the iterator, so that we skip invisible text if
4411 later the bidi iteration lands us in the
4412 invisible region again. */
4413 if (IT_CHARPOS (*it) >= newpos)
4414 it->prev_stop = newpos;
4415 }
4416 }
4417 else
4418 {
4419 IT_CHARPOS (*it) = newpos;
4420 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4421 }
4422
4423 /* If there are before-strings at the start of invisible
4424 text, and the text is invisible because of a text
4425 property, arrange to show before-strings because 20.x did
4426 it that way. (If the text is invisible because of an
4427 overlay property instead of a text property, this is
4428 already handled in the overlay code.) */
4429 if (NILP (overlay)
4430 && get_overlay_strings (it, it->stop_charpos))
4431 {
4432 handled = HANDLED_RECOMPUTE_PROPS;
4433 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4434 }
4435 else if (display_ellipsis_p)
4436 {
4437 /* Make sure that the glyphs of the ellipsis will get
4438 correct `charpos' values. If we would not update
4439 it->position here, the glyphs would belong to the
4440 last visible character _before_ the invisible
4441 text, which confuses `set_cursor_from_row'.
4442
4443 We use the last invisible position instead of the
4444 first because this way the cursor is always drawn on
4445 the first "." of the ellipsis, whenever PT is inside
4446 the invisible text. Otherwise the cursor would be
4447 placed _after_ the ellipsis when the point is after the
4448 first invisible character. */
4449 if (!STRINGP (it->object))
4450 {
4451 it->position.charpos = newpos - 1;
4452 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4453 }
4454 it->ellipsis_p = 1;
4455 /* Let the ellipsis display before
4456 considering any properties of the following char.
4457 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4458 handled = HANDLED_RETURN;
4459 }
4460 }
4461 }
4462
4463 return handled;
4464 }
4465
4466
4467 /* Make iterator IT return `...' next.
4468 Replaces LEN characters from buffer. */
4469
4470 static void
4471 setup_for_ellipsis (struct it *it, int len)
4472 {
4473 /* Use the display table definition for `...'. Invalid glyphs
4474 will be handled by the method returning elements from dpvec. */
4475 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4476 {
4477 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4478 it->dpvec = v->contents;
4479 it->dpend = v->contents + v->header.size;
4480 }
4481 else
4482 {
4483 /* Default `...'. */
4484 it->dpvec = default_invis_vector;
4485 it->dpend = default_invis_vector + 3;
4486 }
4487
4488 it->dpvec_char_len = len;
4489 it->current.dpvec_index = 0;
4490 it->dpvec_face_id = -1;
4491
4492 /* Remember the current face id in case glyphs specify faces.
4493 IT's face is restored in set_iterator_to_next.
4494 saved_face_id was set to preceding char's face in handle_stop. */
4495 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4496 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4497
4498 it->method = GET_FROM_DISPLAY_VECTOR;
4499 it->ellipsis_p = 1;
4500 }
4501
4502
4503 \f
4504 /***********************************************************************
4505 'display' property
4506 ***********************************************************************/
4507
4508 /* Set up iterator IT from `display' property at its current position.
4509 Called from handle_stop.
4510 We return HANDLED_RETURN if some part of the display property
4511 overrides the display of the buffer text itself.
4512 Otherwise we return HANDLED_NORMALLY. */
4513
4514 static enum prop_handled
4515 handle_display_prop (struct it *it)
4516 {
4517 Lisp_Object propval, object, overlay;
4518 struct text_pos *position;
4519 ptrdiff_t bufpos;
4520 /* Nonzero if some property replaces the display of the text itself. */
4521 int display_replaced_p = 0;
4522
4523 if (STRINGP (it->string))
4524 {
4525 object = it->string;
4526 position = &it->current.string_pos;
4527 bufpos = CHARPOS (it->current.pos);
4528 }
4529 else
4530 {
4531 XSETWINDOW (object, it->w);
4532 position = &it->current.pos;
4533 bufpos = CHARPOS (*position);
4534 }
4535
4536 /* Reset those iterator values set from display property values. */
4537 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4538 it->space_width = Qnil;
4539 it->font_height = Qnil;
4540 it->voffset = 0;
4541
4542 /* We don't support recursive `display' properties, i.e. string
4543 values that have a string `display' property, that have a string
4544 `display' property etc. */
4545 if (!it->string_from_display_prop_p)
4546 it->area = TEXT_AREA;
4547
4548 propval = get_char_property_and_overlay (make_number (position->charpos),
4549 Qdisplay, object, &overlay);
4550 if (NILP (propval))
4551 return HANDLED_NORMALLY;
4552 /* Now OVERLAY is the overlay that gave us this property, or nil
4553 if it was a text property. */
4554
4555 if (!STRINGP (it->string))
4556 object = it->w->contents;
4557
4558 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4559 position, bufpos,
4560 FRAME_WINDOW_P (it->f));
4561
4562 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4563 }
4564
4565 /* Subroutine of handle_display_prop. Returns non-zero if the display
4566 specification in SPEC is a replacing specification, i.e. it would
4567 replace the text covered by `display' property with something else,
4568 such as an image or a display string. If SPEC includes any kind or
4569 `(space ...) specification, the value is 2; this is used by
4570 compute_display_string_pos, which see.
4571
4572 See handle_single_display_spec for documentation of arguments.
4573 frame_window_p is non-zero if the window being redisplayed is on a
4574 GUI frame; this argument is used only if IT is NULL, see below.
4575
4576 IT can be NULL, if this is called by the bidi reordering code
4577 through compute_display_string_pos, which see. In that case, this
4578 function only examines SPEC, but does not otherwise "handle" it, in
4579 the sense that it doesn't set up members of IT from the display
4580 spec. */
4581 static int
4582 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4583 Lisp_Object overlay, struct text_pos *position,
4584 ptrdiff_t bufpos, int frame_window_p)
4585 {
4586 int replacing_p = 0;
4587 int rv;
4588
4589 if (CONSP (spec)
4590 /* Simple specifications. */
4591 && !EQ (XCAR (spec), Qimage)
4592 && !EQ (XCAR (spec), Qspace)
4593 && !EQ (XCAR (spec), Qwhen)
4594 && !EQ (XCAR (spec), Qslice)
4595 && !EQ (XCAR (spec), Qspace_width)
4596 && !EQ (XCAR (spec), Qheight)
4597 && !EQ (XCAR (spec), Qraise)
4598 /* Marginal area specifications. */
4599 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4600 && !EQ (XCAR (spec), Qleft_fringe)
4601 && !EQ (XCAR (spec), Qright_fringe)
4602 && !NILP (XCAR (spec)))
4603 {
4604 for (; CONSP (spec); spec = XCDR (spec))
4605 {
4606 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4607 overlay, position, bufpos,
4608 replacing_p, frame_window_p)))
4609 {
4610 replacing_p = rv;
4611 /* If some text in a string is replaced, `position' no
4612 longer points to the position of `object'. */
4613 if (!it || STRINGP (object))
4614 break;
4615 }
4616 }
4617 }
4618 else if (VECTORP (spec))
4619 {
4620 ptrdiff_t i;
4621 for (i = 0; i < ASIZE (spec); ++i)
4622 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4623 overlay, position, bufpos,
4624 replacing_p, frame_window_p)))
4625 {
4626 replacing_p = rv;
4627 /* If some text in a string is replaced, `position' no
4628 longer points to the position of `object'. */
4629 if (!it || STRINGP (object))
4630 break;
4631 }
4632 }
4633 else
4634 {
4635 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4636 position, bufpos, 0,
4637 frame_window_p)))
4638 replacing_p = rv;
4639 }
4640
4641 return replacing_p;
4642 }
4643
4644 /* Value is the position of the end of the `display' property starting
4645 at START_POS in OBJECT. */
4646
4647 static struct text_pos
4648 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4649 {
4650 Lisp_Object end;
4651 struct text_pos end_pos;
4652
4653 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4654 Qdisplay, object, Qnil);
4655 CHARPOS (end_pos) = XFASTINT (end);
4656 if (STRINGP (object))
4657 compute_string_pos (&end_pos, start_pos, it->string);
4658 else
4659 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4660
4661 return end_pos;
4662 }
4663
4664
4665 /* Set up IT from a single `display' property specification SPEC. OBJECT
4666 is the object in which the `display' property was found. *POSITION
4667 is the position in OBJECT at which the `display' property was found.
4668 BUFPOS is the buffer position of OBJECT (different from POSITION if
4669 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4670 previously saw a display specification which already replaced text
4671 display with something else, for example an image; we ignore such
4672 properties after the first one has been processed.
4673
4674 OVERLAY is the overlay this `display' property came from,
4675 or nil if it was a text property.
4676
4677 If SPEC is a `space' or `image' specification, and in some other
4678 cases too, set *POSITION to the position where the `display'
4679 property ends.
4680
4681 If IT is NULL, only examine the property specification in SPEC, but
4682 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4683 is intended to be displayed in a window on a GUI frame.
4684
4685 Value is non-zero if something was found which replaces the display
4686 of buffer or string text. */
4687
4688 static int
4689 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4690 Lisp_Object overlay, struct text_pos *position,
4691 ptrdiff_t bufpos, int display_replaced_p,
4692 int frame_window_p)
4693 {
4694 Lisp_Object form;
4695 Lisp_Object location, value;
4696 struct text_pos start_pos = *position;
4697 int valid_p;
4698
4699 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4700 If the result is non-nil, use VALUE instead of SPEC. */
4701 form = Qt;
4702 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4703 {
4704 spec = XCDR (spec);
4705 if (!CONSP (spec))
4706 return 0;
4707 form = XCAR (spec);
4708 spec = XCDR (spec);
4709 }
4710
4711 if (!NILP (form) && !EQ (form, Qt))
4712 {
4713 ptrdiff_t count = SPECPDL_INDEX ();
4714 struct gcpro gcpro1;
4715
4716 /* Bind `object' to the object having the `display' property, a
4717 buffer or string. Bind `position' to the position in the
4718 object where the property was found, and `buffer-position'
4719 to the current position in the buffer. */
4720
4721 if (NILP (object))
4722 XSETBUFFER (object, current_buffer);
4723 specbind (Qobject, object);
4724 specbind (Qposition, make_number (CHARPOS (*position)));
4725 specbind (Qbuffer_position, make_number (bufpos));
4726 GCPRO1 (form);
4727 form = safe_eval (form);
4728 UNGCPRO;
4729 unbind_to (count, Qnil);
4730 }
4731
4732 if (NILP (form))
4733 return 0;
4734
4735 /* Handle `(height HEIGHT)' specifications. */
4736 if (CONSP (spec)
4737 && EQ (XCAR (spec), Qheight)
4738 && CONSP (XCDR (spec)))
4739 {
4740 if (it)
4741 {
4742 if (!FRAME_WINDOW_P (it->f))
4743 return 0;
4744
4745 it->font_height = XCAR (XCDR (spec));
4746 if (!NILP (it->font_height))
4747 {
4748 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4749 int new_height = -1;
4750
4751 if (CONSP (it->font_height)
4752 && (EQ (XCAR (it->font_height), Qplus)
4753 || EQ (XCAR (it->font_height), Qminus))
4754 && CONSP (XCDR (it->font_height))
4755 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4756 {
4757 /* `(+ N)' or `(- N)' where N is an integer. */
4758 int steps = XINT (XCAR (XCDR (it->font_height)));
4759 if (EQ (XCAR (it->font_height), Qplus))
4760 steps = - steps;
4761 it->face_id = smaller_face (it->f, it->face_id, steps);
4762 }
4763 else if (FUNCTIONP (it->font_height))
4764 {
4765 /* Call function with current height as argument.
4766 Value is the new height. */
4767 Lisp_Object height;
4768 height = safe_call1 (it->font_height,
4769 face->lface[LFACE_HEIGHT_INDEX]);
4770 if (NUMBERP (height))
4771 new_height = XFLOATINT (height);
4772 }
4773 else if (NUMBERP (it->font_height))
4774 {
4775 /* Value is a multiple of the canonical char height. */
4776 struct face *f;
4777
4778 f = FACE_FROM_ID (it->f,
4779 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4780 new_height = (XFLOATINT (it->font_height)
4781 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4782 }
4783 else
4784 {
4785 /* Evaluate IT->font_height with `height' bound to the
4786 current specified height to get the new height. */
4787 ptrdiff_t count = SPECPDL_INDEX ();
4788
4789 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4790 value = safe_eval (it->font_height);
4791 unbind_to (count, Qnil);
4792
4793 if (NUMBERP (value))
4794 new_height = XFLOATINT (value);
4795 }
4796
4797 if (new_height > 0)
4798 it->face_id = face_with_height (it->f, it->face_id, new_height);
4799 }
4800 }
4801
4802 return 0;
4803 }
4804
4805 /* Handle `(space-width WIDTH)'. */
4806 if (CONSP (spec)
4807 && EQ (XCAR (spec), Qspace_width)
4808 && CONSP (XCDR (spec)))
4809 {
4810 if (it)
4811 {
4812 if (!FRAME_WINDOW_P (it->f))
4813 return 0;
4814
4815 value = XCAR (XCDR (spec));
4816 if (NUMBERP (value) && XFLOATINT (value) > 0)
4817 it->space_width = value;
4818 }
4819
4820 return 0;
4821 }
4822
4823 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4824 if (CONSP (spec)
4825 && EQ (XCAR (spec), Qslice))
4826 {
4827 Lisp_Object tem;
4828
4829 if (it)
4830 {
4831 if (!FRAME_WINDOW_P (it->f))
4832 return 0;
4833
4834 if (tem = XCDR (spec), CONSP (tem))
4835 {
4836 it->slice.x = XCAR (tem);
4837 if (tem = XCDR (tem), CONSP (tem))
4838 {
4839 it->slice.y = XCAR (tem);
4840 if (tem = XCDR (tem), CONSP (tem))
4841 {
4842 it->slice.width = XCAR (tem);
4843 if (tem = XCDR (tem), CONSP (tem))
4844 it->slice.height = XCAR (tem);
4845 }
4846 }
4847 }
4848 }
4849
4850 return 0;
4851 }
4852
4853 /* Handle `(raise FACTOR)'. */
4854 if (CONSP (spec)
4855 && EQ (XCAR (spec), Qraise)
4856 && CONSP (XCDR (spec)))
4857 {
4858 if (it)
4859 {
4860 if (!FRAME_WINDOW_P (it->f))
4861 return 0;
4862
4863 #ifdef HAVE_WINDOW_SYSTEM
4864 value = XCAR (XCDR (spec));
4865 if (NUMBERP (value))
4866 {
4867 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4868 it->voffset = - (XFLOATINT (value)
4869 * (FONT_HEIGHT (face->font)));
4870 }
4871 #endif /* HAVE_WINDOW_SYSTEM */
4872 }
4873
4874 return 0;
4875 }
4876
4877 /* Don't handle the other kinds of display specifications
4878 inside a string that we got from a `display' property. */
4879 if (it && it->string_from_display_prop_p)
4880 return 0;
4881
4882 /* Characters having this form of property are not displayed, so
4883 we have to find the end of the property. */
4884 if (it)
4885 {
4886 start_pos = *position;
4887 *position = display_prop_end (it, object, start_pos);
4888 }
4889 value = Qnil;
4890
4891 /* Stop the scan at that end position--we assume that all
4892 text properties change there. */
4893 if (it)
4894 it->stop_charpos = position->charpos;
4895
4896 /* Handle `(left-fringe BITMAP [FACE])'
4897 and `(right-fringe BITMAP [FACE])'. */
4898 if (CONSP (spec)
4899 && (EQ (XCAR (spec), Qleft_fringe)
4900 || EQ (XCAR (spec), Qright_fringe))
4901 && CONSP (XCDR (spec)))
4902 {
4903 int fringe_bitmap;
4904
4905 if (it)
4906 {
4907 if (!FRAME_WINDOW_P (it->f))
4908 /* If we return here, POSITION has been advanced
4909 across the text with this property. */
4910 {
4911 /* Synchronize the bidi iterator with POSITION. This is
4912 needed because we are not going to push the iterator
4913 on behalf of this display property, so there will be
4914 no pop_it call to do this synchronization for us. */
4915 if (it->bidi_p)
4916 {
4917 it->position = *position;
4918 iterate_out_of_display_property (it);
4919 *position = it->position;
4920 }
4921 return 1;
4922 }
4923 }
4924 else if (!frame_window_p)
4925 return 1;
4926
4927 #ifdef HAVE_WINDOW_SYSTEM
4928 value = XCAR (XCDR (spec));
4929 if (!SYMBOLP (value)
4930 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4931 /* If we return here, POSITION has been advanced
4932 across the text with this property. */
4933 {
4934 if (it && it->bidi_p)
4935 {
4936 it->position = *position;
4937 iterate_out_of_display_property (it);
4938 *position = it->position;
4939 }
4940 return 1;
4941 }
4942
4943 if (it)
4944 {
4945 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4946
4947 if (CONSP (XCDR (XCDR (spec))))
4948 {
4949 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4950 int face_id2 = lookup_derived_face (it->f, face_name,
4951 FRINGE_FACE_ID, 0);
4952 if (face_id2 >= 0)
4953 face_id = face_id2;
4954 }
4955
4956 /* Save current settings of IT so that we can restore them
4957 when we are finished with the glyph property value. */
4958 push_it (it, position);
4959
4960 it->area = TEXT_AREA;
4961 it->what = IT_IMAGE;
4962 it->image_id = -1; /* no image */
4963 it->position = start_pos;
4964 it->object = NILP (object) ? it->w->contents : object;
4965 it->method = GET_FROM_IMAGE;
4966 it->from_overlay = Qnil;
4967 it->face_id = face_id;
4968 it->from_disp_prop_p = 1;
4969
4970 /* Say that we haven't consumed the characters with
4971 `display' property yet. The call to pop_it in
4972 set_iterator_to_next will clean this up. */
4973 *position = start_pos;
4974
4975 if (EQ (XCAR (spec), Qleft_fringe))
4976 {
4977 it->left_user_fringe_bitmap = fringe_bitmap;
4978 it->left_user_fringe_face_id = face_id;
4979 }
4980 else
4981 {
4982 it->right_user_fringe_bitmap = fringe_bitmap;
4983 it->right_user_fringe_face_id = face_id;
4984 }
4985 }
4986 #endif /* HAVE_WINDOW_SYSTEM */
4987 return 1;
4988 }
4989
4990 /* Prepare to handle `((margin left-margin) ...)',
4991 `((margin right-margin) ...)' and `((margin nil) ...)'
4992 prefixes for display specifications. */
4993 location = Qunbound;
4994 if (CONSP (spec) && CONSP (XCAR (spec)))
4995 {
4996 Lisp_Object tem;
4997
4998 value = XCDR (spec);
4999 if (CONSP (value))
5000 value = XCAR (value);
5001
5002 tem = XCAR (spec);
5003 if (EQ (XCAR (tem), Qmargin)
5004 && (tem = XCDR (tem),
5005 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5006 (NILP (tem)
5007 || EQ (tem, Qleft_margin)
5008 || EQ (tem, Qright_margin))))
5009 location = tem;
5010 }
5011
5012 if (EQ (location, Qunbound))
5013 {
5014 location = Qnil;
5015 value = spec;
5016 }
5017
5018 /* After this point, VALUE is the property after any
5019 margin prefix has been stripped. It must be a string,
5020 an image specification, or `(space ...)'.
5021
5022 LOCATION specifies where to display: `left-margin',
5023 `right-margin' or nil. */
5024
5025 valid_p = (STRINGP (value)
5026 #ifdef HAVE_WINDOW_SYSTEM
5027 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5028 && valid_image_p (value))
5029 #endif /* not HAVE_WINDOW_SYSTEM */
5030 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5031
5032 if (valid_p && !display_replaced_p)
5033 {
5034 int retval = 1;
5035
5036 if (!it)
5037 {
5038 /* Callers need to know whether the display spec is any kind
5039 of `(space ...)' spec that is about to affect text-area
5040 display. */
5041 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5042 retval = 2;
5043 return retval;
5044 }
5045
5046 /* Save current settings of IT so that we can restore them
5047 when we are finished with the glyph property value. */
5048 push_it (it, position);
5049 it->from_overlay = overlay;
5050 it->from_disp_prop_p = 1;
5051
5052 if (NILP (location))
5053 it->area = TEXT_AREA;
5054 else if (EQ (location, Qleft_margin))
5055 it->area = LEFT_MARGIN_AREA;
5056 else
5057 it->area = RIGHT_MARGIN_AREA;
5058
5059 if (STRINGP (value))
5060 {
5061 it->string = value;
5062 it->multibyte_p = STRING_MULTIBYTE (it->string);
5063 it->current.overlay_string_index = -1;
5064 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5065 it->end_charpos = it->string_nchars = SCHARS (it->string);
5066 it->method = GET_FROM_STRING;
5067 it->stop_charpos = 0;
5068 it->prev_stop = 0;
5069 it->base_level_stop = 0;
5070 it->string_from_display_prop_p = 1;
5071 /* Say that we haven't consumed the characters with
5072 `display' property yet. The call to pop_it in
5073 set_iterator_to_next will clean this up. */
5074 if (BUFFERP (object))
5075 *position = start_pos;
5076
5077 /* Force paragraph direction to be that of the parent
5078 object. If the parent object's paragraph direction is
5079 not yet determined, default to L2R. */
5080 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5081 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5082 else
5083 it->paragraph_embedding = L2R;
5084
5085 /* Set up the bidi iterator for this display string. */
5086 if (it->bidi_p)
5087 {
5088 it->bidi_it.string.lstring = it->string;
5089 it->bidi_it.string.s = NULL;
5090 it->bidi_it.string.schars = it->end_charpos;
5091 it->bidi_it.string.bufpos = bufpos;
5092 it->bidi_it.string.from_disp_str = 1;
5093 it->bidi_it.string.unibyte = !it->multibyte_p;
5094 it->bidi_it.w = it->w;
5095 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5096 }
5097 }
5098 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5099 {
5100 it->method = GET_FROM_STRETCH;
5101 it->object = value;
5102 *position = it->position = start_pos;
5103 retval = 1 + (it->area == TEXT_AREA);
5104 }
5105 #ifdef HAVE_WINDOW_SYSTEM
5106 else
5107 {
5108 it->what = IT_IMAGE;
5109 it->image_id = lookup_image (it->f, value);
5110 it->position = start_pos;
5111 it->object = NILP (object) ? it->w->contents : object;
5112 it->method = GET_FROM_IMAGE;
5113
5114 /* Say that we haven't consumed the characters with
5115 `display' property yet. The call to pop_it in
5116 set_iterator_to_next will clean this up. */
5117 *position = start_pos;
5118 }
5119 #endif /* HAVE_WINDOW_SYSTEM */
5120
5121 return retval;
5122 }
5123
5124 /* Invalid property or property not supported. Restore
5125 POSITION to what it was before. */
5126 *position = start_pos;
5127 return 0;
5128 }
5129
5130 /* Check if PROP is a display property value whose text should be
5131 treated as intangible. OVERLAY is the overlay from which PROP
5132 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5133 specify the buffer position covered by PROP. */
5134
5135 int
5136 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5137 ptrdiff_t charpos, ptrdiff_t bytepos)
5138 {
5139 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5140 struct text_pos position;
5141
5142 SET_TEXT_POS (position, charpos, bytepos);
5143 return handle_display_spec (NULL, prop, Qnil, overlay,
5144 &position, charpos, frame_window_p);
5145 }
5146
5147
5148 /* Return 1 if PROP is a display sub-property value containing STRING.
5149
5150 Implementation note: this and the following function are really
5151 special cases of handle_display_spec and
5152 handle_single_display_spec, and should ideally use the same code.
5153 Until they do, these two pairs must be consistent and must be
5154 modified in sync. */
5155
5156 static int
5157 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5158 {
5159 if (EQ (string, prop))
5160 return 1;
5161
5162 /* Skip over `when FORM'. */
5163 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5164 {
5165 prop = XCDR (prop);
5166 if (!CONSP (prop))
5167 return 0;
5168 /* Actually, the condition following `when' should be eval'ed,
5169 like handle_single_display_spec does, and we should return
5170 zero if it evaluates to nil. However, this function is
5171 called only when the buffer was already displayed and some
5172 glyph in the glyph matrix was found to come from a display
5173 string. Therefore, the condition was already evaluated, and
5174 the result was non-nil, otherwise the display string wouldn't
5175 have been displayed and we would have never been called for
5176 this property. Thus, we can skip the evaluation and assume
5177 its result is non-nil. */
5178 prop = XCDR (prop);
5179 }
5180
5181 if (CONSP (prop))
5182 /* Skip over `margin LOCATION'. */
5183 if (EQ (XCAR (prop), Qmargin))
5184 {
5185 prop = XCDR (prop);
5186 if (!CONSP (prop))
5187 return 0;
5188
5189 prop = XCDR (prop);
5190 if (!CONSP (prop))
5191 return 0;
5192 }
5193
5194 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5195 }
5196
5197
5198 /* Return 1 if STRING appears in the `display' property PROP. */
5199
5200 static int
5201 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5202 {
5203 if (CONSP (prop)
5204 && !EQ (XCAR (prop), Qwhen)
5205 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5206 {
5207 /* A list of sub-properties. */
5208 while (CONSP (prop))
5209 {
5210 if (single_display_spec_string_p (XCAR (prop), string))
5211 return 1;
5212 prop = XCDR (prop);
5213 }
5214 }
5215 else if (VECTORP (prop))
5216 {
5217 /* A vector of sub-properties. */
5218 ptrdiff_t i;
5219 for (i = 0; i < ASIZE (prop); ++i)
5220 if (single_display_spec_string_p (AREF (prop, i), string))
5221 return 1;
5222 }
5223 else
5224 return single_display_spec_string_p (prop, string);
5225
5226 return 0;
5227 }
5228
5229 /* Look for STRING in overlays and text properties in the current
5230 buffer, between character positions FROM and TO (excluding TO).
5231 BACK_P non-zero means look back (in this case, TO is supposed to be
5232 less than FROM).
5233 Value is the first character position where STRING was found, or
5234 zero if it wasn't found before hitting TO.
5235
5236 This function may only use code that doesn't eval because it is
5237 called asynchronously from note_mouse_highlight. */
5238
5239 static ptrdiff_t
5240 string_buffer_position_lim (Lisp_Object string,
5241 ptrdiff_t from, ptrdiff_t to, int back_p)
5242 {
5243 Lisp_Object limit, prop, pos;
5244 int found = 0;
5245
5246 pos = make_number (max (from, BEGV));
5247
5248 if (!back_p) /* looking forward */
5249 {
5250 limit = make_number (min (to, ZV));
5251 while (!found && !EQ (pos, limit))
5252 {
5253 prop = Fget_char_property (pos, Qdisplay, Qnil);
5254 if (!NILP (prop) && display_prop_string_p (prop, string))
5255 found = 1;
5256 else
5257 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5258 limit);
5259 }
5260 }
5261 else /* looking back */
5262 {
5263 limit = make_number (max (to, BEGV));
5264 while (!found && !EQ (pos, limit))
5265 {
5266 prop = Fget_char_property (pos, Qdisplay, Qnil);
5267 if (!NILP (prop) && display_prop_string_p (prop, string))
5268 found = 1;
5269 else
5270 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5271 limit);
5272 }
5273 }
5274
5275 return found ? XINT (pos) : 0;
5276 }
5277
5278 /* Determine which buffer position in current buffer STRING comes from.
5279 AROUND_CHARPOS is an approximate position where it could come from.
5280 Value is the buffer position or 0 if it couldn't be determined.
5281
5282 This function is necessary because we don't record buffer positions
5283 in glyphs generated from strings (to keep struct glyph small).
5284 This function may only use code that doesn't eval because it is
5285 called asynchronously from note_mouse_highlight. */
5286
5287 static ptrdiff_t
5288 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5289 {
5290 const int MAX_DISTANCE = 1000;
5291 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5292 around_charpos + MAX_DISTANCE,
5293 0);
5294
5295 if (!found)
5296 found = string_buffer_position_lim (string, around_charpos,
5297 around_charpos - MAX_DISTANCE, 1);
5298 return found;
5299 }
5300
5301
5302 \f
5303 /***********************************************************************
5304 `composition' property
5305 ***********************************************************************/
5306
5307 /* Set up iterator IT from `composition' property at its current
5308 position. Called from handle_stop. */
5309
5310 static enum prop_handled
5311 handle_composition_prop (struct it *it)
5312 {
5313 Lisp_Object prop, string;
5314 ptrdiff_t pos, pos_byte, start, end;
5315
5316 if (STRINGP (it->string))
5317 {
5318 unsigned char *s;
5319
5320 pos = IT_STRING_CHARPOS (*it);
5321 pos_byte = IT_STRING_BYTEPOS (*it);
5322 string = it->string;
5323 s = SDATA (string) + pos_byte;
5324 it->c = STRING_CHAR (s);
5325 }
5326 else
5327 {
5328 pos = IT_CHARPOS (*it);
5329 pos_byte = IT_BYTEPOS (*it);
5330 string = Qnil;
5331 it->c = FETCH_CHAR (pos_byte);
5332 }
5333
5334 /* If there's a valid composition and point is not inside of the
5335 composition (in the case that the composition is from the current
5336 buffer), draw a glyph composed from the composition components. */
5337 if (find_composition (pos, -1, &start, &end, &prop, string)
5338 && composition_valid_p (start, end, prop)
5339 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5340 {
5341 if (start < pos)
5342 /* As we can't handle this situation (perhaps font-lock added
5343 a new composition), we just return here hoping that next
5344 redisplay will detect this composition much earlier. */
5345 return HANDLED_NORMALLY;
5346 if (start != pos)
5347 {
5348 if (STRINGP (it->string))
5349 pos_byte = string_char_to_byte (it->string, start);
5350 else
5351 pos_byte = CHAR_TO_BYTE (start);
5352 }
5353 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5354 prop, string);
5355
5356 if (it->cmp_it.id >= 0)
5357 {
5358 it->cmp_it.ch = -1;
5359 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5360 it->cmp_it.nglyphs = -1;
5361 }
5362 }
5363
5364 return HANDLED_NORMALLY;
5365 }
5366
5367
5368 \f
5369 /***********************************************************************
5370 Overlay strings
5371 ***********************************************************************/
5372
5373 /* The following structure is used to record overlay strings for
5374 later sorting in load_overlay_strings. */
5375
5376 struct overlay_entry
5377 {
5378 Lisp_Object overlay;
5379 Lisp_Object string;
5380 EMACS_INT priority;
5381 int after_string_p;
5382 };
5383
5384
5385 /* Set up iterator IT from overlay strings at its current position.
5386 Called from handle_stop. */
5387
5388 static enum prop_handled
5389 handle_overlay_change (struct it *it)
5390 {
5391 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5392 return HANDLED_RECOMPUTE_PROPS;
5393 else
5394 return HANDLED_NORMALLY;
5395 }
5396
5397
5398 /* Set up the next overlay string for delivery by IT, if there is an
5399 overlay string to deliver. Called by set_iterator_to_next when the
5400 end of the current overlay string is reached. If there are more
5401 overlay strings to display, IT->string and
5402 IT->current.overlay_string_index are set appropriately here.
5403 Otherwise IT->string is set to nil. */
5404
5405 static void
5406 next_overlay_string (struct it *it)
5407 {
5408 ++it->current.overlay_string_index;
5409 if (it->current.overlay_string_index == it->n_overlay_strings)
5410 {
5411 /* No more overlay strings. Restore IT's settings to what
5412 they were before overlay strings were processed, and
5413 continue to deliver from current_buffer. */
5414
5415 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5416 pop_it (it);
5417 eassert (it->sp > 0
5418 || (NILP (it->string)
5419 && it->method == GET_FROM_BUFFER
5420 && it->stop_charpos >= BEGV
5421 && it->stop_charpos <= it->end_charpos));
5422 it->current.overlay_string_index = -1;
5423 it->n_overlay_strings = 0;
5424 it->overlay_strings_charpos = -1;
5425 /* If there's an empty display string on the stack, pop the
5426 stack, to resync the bidi iterator with IT's position. Such
5427 empty strings are pushed onto the stack in
5428 get_overlay_strings_1. */
5429 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5430 pop_it (it);
5431
5432 /* If we're at the end of the buffer, record that we have
5433 processed the overlay strings there already, so that
5434 next_element_from_buffer doesn't try it again. */
5435 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5436 it->overlay_strings_at_end_processed_p = 1;
5437 }
5438 else
5439 {
5440 /* There are more overlay strings to process. If
5441 IT->current.overlay_string_index has advanced to a position
5442 where we must load IT->overlay_strings with more strings, do
5443 it. We must load at the IT->overlay_strings_charpos where
5444 IT->n_overlay_strings was originally computed; when invisible
5445 text is present, this might not be IT_CHARPOS (Bug#7016). */
5446 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5447
5448 if (it->current.overlay_string_index && i == 0)
5449 load_overlay_strings (it, it->overlay_strings_charpos);
5450
5451 /* Initialize IT to deliver display elements from the overlay
5452 string. */
5453 it->string = it->overlay_strings[i];
5454 it->multibyte_p = STRING_MULTIBYTE (it->string);
5455 SET_TEXT_POS (it->current.string_pos, 0, 0);
5456 it->method = GET_FROM_STRING;
5457 it->stop_charpos = 0;
5458 it->end_charpos = SCHARS (it->string);
5459 if (it->cmp_it.stop_pos >= 0)
5460 it->cmp_it.stop_pos = 0;
5461 it->prev_stop = 0;
5462 it->base_level_stop = 0;
5463
5464 /* Set up the bidi iterator for this overlay string. */
5465 if (it->bidi_p)
5466 {
5467 it->bidi_it.string.lstring = it->string;
5468 it->bidi_it.string.s = NULL;
5469 it->bidi_it.string.schars = SCHARS (it->string);
5470 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5471 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5472 it->bidi_it.string.unibyte = !it->multibyte_p;
5473 it->bidi_it.w = it->w;
5474 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5475 }
5476 }
5477
5478 CHECK_IT (it);
5479 }
5480
5481
5482 /* Compare two overlay_entry structures E1 and E2. Used as a
5483 comparison function for qsort in load_overlay_strings. Overlay
5484 strings for the same position are sorted so that
5485
5486 1. All after-strings come in front of before-strings, except
5487 when they come from the same overlay.
5488
5489 2. Within after-strings, strings are sorted so that overlay strings
5490 from overlays with higher priorities come first.
5491
5492 2. Within before-strings, strings are sorted so that overlay
5493 strings from overlays with higher priorities come last.
5494
5495 Value is analogous to strcmp. */
5496
5497
5498 static int
5499 compare_overlay_entries (const void *e1, const void *e2)
5500 {
5501 struct overlay_entry const *entry1 = e1;
5502 struct overlay_entry const *entry2 = e2;
5503 int result;
5504
5505 if (entry1->after_string_p != entry2->after_string_p)
5506 {
5507 /* Let after-strings appear in front of before-strings if
5508 they come from different overlays. */
5509 if (EQ (entry1->overlay, entry2->overlay))
5510 result = entry1->after_string_p ? 1 : -1;
5511 else
5512 result = entry1->after_string_p ? -1 : 1;
5513 }
5514 else if (entry1->priority != entry2->priority)
5515 {
5516 if (entry1->after_string_p)
5517 /* After-strings sorted in order of decreasing priority. */
5518 result = entry2->priority < entry1->priority ? -1 : 1;
5519 else
5520 /* Before-strings sorted in order of increasing priority. */
5521 result = entry1->priority < entry2->priority ? -1 : 1;
5522 }
5523 else
5524 result = 0;
5525
5526 return result;
5527 }
5528
5529
5530 /* Load the vector IT->overlay_strings with overlay strings from IT's
5531 current buffer position, or from CHARPOS if that is > 0. Set
5532 IT->n_overlays to the total number of overlay strings found.
5533
5534 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5535 a time. On entry into load_overlay_strings,
5536 IT->current.overlay_string_index gives the number of overlay
5537 strings that have already been loaded by previous calls to this
5538 function.
5539
5540 IT->add_overlay_start contains an additional overlay start
5541 position to consider for taking overlay strings from, if non-zero.
5542 This position comes into play when the overlay has an `invisible'
5543 property, and both before and after-strings. When we've skipped to
5544 the end of the overlay, because of its `invisible' property, we
5545 nevertheless want its before-string to appear.
5546 IT->add_overlay_start will contain the overlay start position
5547 in this case.
5548
5549 Overlay strings are sorted so that after-string strings come in
5550 front of before-string strings. Within before and after-strings,
5551 strings are sorted by overlay priority. See also function
5552 compare_overlay_entries. */
5553
5554 static void
5555 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5556 {
5557 Lisp_Object overlay, window, str, invisible;
5558 struct Lisp_Overlay *ov;
5559 ptrdiff_t start, end;
5560 ptrdiff_t size = 20;
5561 ptrdiff_t n = 0, i, j;
5562 int invis_p;
5563 struct overlay_entry *entries = alloca (size * sizeof *entries);
5564 USE_SAFE_ALLOCA;
5565
5566 if (charpos <= 0)
5567 charpos = IT_CHARPOS (*it);
5568
5569 /* Append the overlay string STRING of overlay OVERLAY to vector
5570 `entries' which has size `size' and currently contains `n'
5571 elements. AFTER_P non-zero means STRING is an after-string of
5572 OVERLAY. */
5573 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5574 do \
5575 { \
5576 Lisp_Object priority; \
5577 \
5578 if (n == size) \
5579 { \
5580 struct overlay_entry *old = entries; \
5581 SAFE_NALLOCA (entries, 2, size); \
5582 memcpy (entries, old, size * sizeof *entries); \
5583 size *= 2; \
5584 } \
5585 \
5586 entries[n].string = (STRING); \
5587 entries[n].overlay = (OVERLAY); \
5588 priority = Foverlay_get ((OVERLAY), Qpriority); \
5589 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5590 entries[n].after_string_p = (AFTER_P); \
5591 ++n; \
5592 } \
5593 while (0)
5594
5595 /* Process overlay before the overlay center. */
5596 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5597 {
5598 XSETMISC (overlay, ov);
5599 eassert (OVERLAYP (overlay));
5600 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5601 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5602
5603 if (end < charpos)
5604 break;
5605
5606 /* Skip this overlay if it doesn't start or end at IT's current
5607 position. */
5608 if (end != charpos && start != charpos)
5609 continue;
5610
5611 /* Skip this overlay if it doesn't apply to IT->w. */
5612 window = Foverlay_get (overlay, Qwindow);
5613 if (WINDOWP (window) && XWINDOW (window) != it->w)
5614 continue;
5615
5616 /* If the text ``under'' the overlay is invisible, both before-
5617 and after-strings from this overlay are visible; start and
5618 end position are indistinguishable. */
5619 invisible = Foverlay_get (overlay, Qinvisible);
5620 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5621
5622 /* If overlay has a non-empty before-string, record it. */
5623 if ((start == charpos || (end == charpos && invis_p))
5624 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5625 && SCHARS (str))
5626 RECORD_OVERLAY_STRING (overlay, str, 0);
5627
5628 /* If overlay has a non-empty after-string, record it. */
5629 if ((end == charpos || (start == charpos && invis_p))
5630 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5631 && SCHARS (str))
5632 RECORD_OVERLAY_STRING (overlay, str, 1);
5633 }
5634
5635 /* Process overlays after the overlay center. */
5636 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5637 {
5638 XSETMISC (overlay, ov);
5639 eassert (OVERLAYP (overlay));
5640 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5641 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5642
5643 if (start > charpos)
5644 break;
5645
5646 /* Skip this overlay if it doesn't start or end at IT's current
5647 position. */
5648 if (end != charpos && start != charpos)
5649 continue;
5650
5651 /* Skip this overlay if it doesn't apply to IT->w. */
5652 window = Foverlay_get (overlay, Qwindow);
5653 if (WINDOWP (window) && XWINDOW (window) != it->w)
5654 continue;
5655
5656 /* If the text ``under'' the overlay is invisible, it has a zero
5657 dimension, and both before- and after-strings apply. */
5658 invisible = Foverlay_get (overlay, Qinvisible);
5659 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5660
5661 /* If overlay has a non-empty before-string, record it. */
5662 if ((start == charpos || (end == charpos && invis_p))
5663 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5664 && SCHARS (str))
5665 RECORD_OVERLAY_STRING (overlay, str, 0);
5666
5667 /* If overlay has a non-empty after-string, record it. */
5668 if ((end == charpos || (start == charpos && invis_p))
5669 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5670 && SCHARS (str))
5671 RECORD_OVERLAY_STRING (overlay, str, 1);
5672 }
5673
5674 #undef RECORD_OVERLAY_STRING
5675
5676 /* Sort entries. */
5677 if (n > 1)
5678 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5679
5680 /* Record number of overlay strings, and where we computed it. */
5681 it->n_overlay_strings = n;
5682 it->overlay_strings_charpos = charpos;
5683
5684 /* IT->current.overlay_string_index is the number of overlay strings
5685 that have already been consumed by IT. Copy some of the
5686 remaining overlay strings to IT->overlay_strings. */
5687 i = 0;
5688 j = it->current.overlay_string_index;
5689 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5690 {
5691 it->overlay_strings[i] = entries[j].string;
5692 it->string_overlays[i++] = entries[j++].overlay;
5693 }
5694
5695 CHECK_IT (it);
5696 SAFE_FREE ();
5697 }
5698
5699
5700 /* Get the first chunk of overlay strings at IT's current buffer
5701 position, or at CHARPOS if that is > 0. Value is non-zero if at
5702 least one overlay string was found. */
5703
5704 static int
5705 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5706 {
5707 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5708 process. This fills IT->overlay_strings with strings, and sets
5709 IT->n_overlay_strings to the total number of strings to process.
5710 IT->pos.overlay_string_index has to be set temporarily to zero
5711 because load_overlay_strings needs this; it must be set to -1
5712 when no overlay strings are found because a zero value would
5713 indicate a position in the first overlay string. */
5714 it->current.overlay_string_index = 0;
5715 load_overlay_strings (it, charpos);
5716
5717 /* If we found overlay strings, set up IT to deliver display
5718 elements from the first one. Otherwise set up IT to deliver
5719 from current_buffer. */
5720 if (it->n_overlay_strings)
5721 {
5722 /* Make sure we know settings in current_buffer, so that we can
5723 restore meaningful values when we're done with the overlay
5724 strings. */
5725 if (compute_stop_p)
5726 compute_stop_pos (it);
5727 eassert (it->face_id >= 0);
5728
5729 /* Save IT's settings. They are restored after all overlay
5730 strings have been processed. */
5731 eassert (!compute_stop_p || it->sp == 0);
5732
5733 /* When called from handle_stop, there might be an empty display
5734 string loaded. In that case, don't bother saving it. But
5735 don't use this optimization with the bidi iterator, since we
5736 need the corresponding pop_it call to resync the bidi
5737 iterator's position with IT's position, after we are done
5738 with the overlay strings. (The corresponding call to pop_it
5739 in case of an empty display string is in
5740 next_overlay_string.) */
5741 if (!(!it->bidi_p
5742 && STRINGP (it->string) && !SCHARS (it->string)))
5743 push_it (it, NULL);
5744
5745 /* Set up IT to deliver display elements from the first overlay
5746 string. */
5747 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5748 it->string = it->overlay_strings[0];
5749 it->from_overlay = Qnil;
5750 it->stop_charpos = 0;
5751 eassert (STRINGP (it->string));
5752 it->end_charpos = SCHARS (it->string);
5753 it->prev_stop = 0;
5754 it->base_level_stop = 0;
5755 it->multibyte_p = STRING_MULTIBYTE (it->string);
5756 it->method = GET_FROM_STRING;
5757 it->from_disp_prop_p = 0;
5758
5759 /* Force paragraph direction to be that of the parent
5760 buffer. */
5761 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5762 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5763 else
5764 it->paragraph_embedding = L2R;
5765
5766 /* Set up the bidi iterator for this overlay string. */
5767 if (it->bidi_p)
5768 {
5769 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5770
5771 it->bidi_it.string.lstring = it->string;
5772 it->bidi_it.string.s = NULL;
5773 it->bidi_it.string.schars = SCHARS (it->string);
5774 it->bidi_it.string.bufpos = pos;
5775 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5776 it->bidi_it.string.unibyte = !it->multibyte_p;
5777 it->bidi_it.w = it->w;
5778 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5779 }
5780 return 1;
5781 }
5782
5783 it->current.overlay_string_index = -1;
5784 return 0;
5785 }
5786
5787 static int
5788 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5789 {
5790 it->string = Qnil;
5791 it->method = GET_FROM_BUFFER;
5792
5793 (void) get_overlay_strings_1 (it, charpos, 1);
5794
5795 CHECK_IT (it);
5796
5797 /* Value is non-zero if we found at least one overlay string. */
5798 return STRINGP (it->string);
5799 }
5800
5801
5802 \f
5803 /***********************************************************************
5804 Saving and restoring state
5805 ***********************************************************************/
5806
5807 /* Save current settings of IT on IT->stack. Called, for example,
5808 before setting up IT for an overlay string, to be able to restore
5809 IT's settings to what they were after the overlay string has been
5810 processed. If POSITION is non-NULL, it is the position to save on
5811 the stack instead of IT->position. */
5812
5813 static void
5814 push_it (struct it *it, struct text_pos *position)
5815 {
5816 struct iterator_stack_entry *p;
5817
5818 eassert (it->sp < IT_STACK_SIZE);
5819 p = it->stack + it->sp;
5820
5821 p->stop_charpos = it->stop_charpos;
5822 p->prev_stop = it->prev_stop;
5823 p->base_level_stop = it->base_level_stop;
5824 p->cmp_it = it->cmp_it;
5825 eassert (it->face_id >= 0);
5826 p->face_id = it->face_id;
5827 p->string = it->string;
5828 p->method = it->method;
5829 p->from_overlay = it->from_overlay;
5830 switch (p->method)
5831 {
5832 case GET_FROM_IMAGE:
5833 p->u.image.object = it->object;
5834 p->u.image.image_id = it->image_id;
5835 p->u.image.slice = it->slice;
5836 break;
5837 case GET_FROM_STRETCH:
5838 p->u.stretch.object = it->object;
5839 break;
5840 }
5841 p->position = position ? *position : it->position;
5842 p->current = it->current;
5843 p->end_charpos = it->end_charpos;
5844 p->string_nchars = it->string_nchars;
5845 p->area = it->area;
5846 p->multibyte_p = it->multibyte_p;
5847 p->avoid_cursor_p = it->avoid_cursor_p;
5848 p->space_width = it->space_width;
5849 p->font_height = it->font_height;
5850 p->voffset = it->voffset;
5851 p->string_from_display_prop_p = it->string_from_display_prop_p;
5852 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5853 p->display_ellipsis_p = 0;
5854 p->line_wrap = it->line_wrap;
5855 p->bidi_p = it->bidi_p;
5856 p->paragraph_embedding = it->paragraph_embedding;
5857 p->from_disp_prop_p = it->from_disp_prop_p;
5858 ++it->sp;
5859
5860 /* Save the state of the bidi iterator as well. */
5861 if (it->bidi_p)
5862 bidi_push_it (&it->bidi_it);
5863 }
5864
5865 static void
5866 iterate_out_of_display_property (struct it *it)
5867 {
5868 int buffer_p = !STRINGP (it->string);
5869 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5870 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5871
5872 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5873
5874 /* Maybe initialize paragraph direction. If we are at the beginning
5875 of a new paragraph, next_element_from_buffer may not have a
5876 chance to do that. */
5877 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5878 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5879 /* prev_stop can be zero, so check against BEGV as well. */
5880 while (it->bidi_it.charpos >= bob
5881 && it->prev_stop <= it->bidi_it.charpos
5882 && it->bidi_it.charpos < CHARPOS (it->position)
5883 && it->bidi_it.charpos < eob)
5884 bidi_move_to_visually_next (&it->bidi_it);
5885 /* Record the stop_pos we just crossed, for when we cross it
5886 back, maybe. */
5887 if (it->bidi_it.charpos > CHARPOS (it->position))
5888 it->prev_stop = CHARPOS (it->position);
5889 /* If we ended up not where pop_it put us, resync IT's
5890 positional members with the bidi iterator. */
5891 if (it->bidi_it.charpos != CHARPOS (it->position))
5892 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5893 if (buffer_p)
5894 it->current.pos = it->position;
5895 else
5896 it->current.string_pos = it->position;
5897 }
5898
5899 /* Restore IT's settings from IT->stack. Called, for example, when no
5900 more overlay strings must be processed, and we return to delivering
5901 display elements from a buffer, or when the end of a string from a
5902 `display' property is reached and we return to delivering display
5903 elements from an overlay string, or from a buffer. */
5904
5905 static void
5906 pop_it (struct it *it)
5907 {
5908 struct iterator_stack_entry *p;
5909 int from_display_prop = it->from_disp_prop_p;
5910
5911 eassert (it->sp > 0);
5912 --it->sp;
5913 p = it->stack + it->sp;
5914 it->stop_charpos = p->stop_charpos;
5915 it->prev_stop = p->prev_stop;
5916 it->base_level_stop = p->base_level_stop;
5917 it->cmp_it = p->cmp_it;
5918 it->face_id = p->face_id;
5919 it->current = p->current;
5920 it->position = p->position;
5921 it->string = p->string;
5922 it->from_overlay = p->from_overlay;
5923 if (NILP (it->string))
5924 SET_TEXT_POS (it->current.string_pos, -1, -1);
5925 it->method = p->method;
5926 switch (it->method)
5927 {
5928 case GET_FROM_IMAGE:
5929 it->image_id = p->u.image.image_id;
5930 it->object = p->u.image.object;
5931 it->slice = p->u.image.slice;
5932 break;
5933 case GET_FROM_STRETCH:
5934 it->object = p->u.stretch.object;
5935 break;
5936 case GET_FROM_BUFFER:
5937 it->object = it->w->contents;
5938 break;
5939 case GET_FROM_STRING:
5940 it->object = it->string;
5941 break;
5942 case GET_FROM_DISPLAY_VECTOR:
5943 if (it->s)
5944 it->method = GET_FROM_C_STRING;
5945 else if (STRINGP (it->string))
5946 it->method = GET_FROM_STRING;
5947 else
5948 {
5949 it->method = GET_FROM_BUFFER;
5950 it->object = it->w->contents;
5951 }
5952 }
5953 it->end_charpos = p->end_charpos;
5954 it->string_nchars = p->string_nchars;
5955 it->area = p->area;
5956 it->multibyte_p = p->multibyte_p;
5957 it->avoid_cursor_p = p->avoid_cursor_p;
5958 it->space_width = p->space_width;
5959 it->font_height = p->font_height;
5960 it->voffset = p->voffset;
5961 it->string_from_display_prop_p = p->string_from_display_prop_p;
5962 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5963 it->line_wrap = p->line_wrap;
5964 it->bidi_p = p->bidi_p;
5965 it->paragraph_embedding = p->paragraph_embedding;
5966 it->from_disp_prop_p = p->from_disp_prop_p;
5967 if (it->bidi_p)
5968 {
5969 bidi_pop_it (&it->bidi_it);
5970 /* Bidi-iterate until we get out of the portion of text, if any,
5971 covered by a `display' text property or by an overlay with
5972 `display' property. (We cannot just jump there, because the
5973 internal coherency of the bidi iterator state can not be
5974 preserved across such jumps.) We also must determine the
5975 paragraph base direction if the overlay we just processed is
5976 at the beginning of a new paragraph. */
5977 if (from_display_prop
5978 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5979 iterate_out_of_display_property (it);
5980
5981 eassert ((BUFFERP (it->object)
5982 && IT_CHARPOS (*it) == it->bidi_it.charpos
5983 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5984 || (STRINGP (it->object)
5985 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5986 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5987 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5988 }
5989 }
5990
5991
5992 \f
5993 /***********************************************************************
5994 Moving over lines
5995 ***********************************************************************/
5996
5997 /* Set IT's current position to the previous line start. */
5998
5999 static void
6000 back_to_previous_line_start (struct it *it)
6001 {
6002 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6003
6004 DEC_BOTH (cp, bp);
6005 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6006 }
6007
6008
6009 /* Move IT to the next line start.
6010
6011 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6012 we skipped over part of the text (as opposed to moving the iterator
6013 continuously over the text). Otherwise, don't change the value
6014 of *SKIPPED_P.
6015
6016 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6017 iterator on the newline, if it was found.
6018
6019 Newlines may come from buffer text, overlay strings, or strings
6020 displayed via the `display' property. That's the reason we can't
6021 simply use find_newline_no_quit.
6022
6023 Note that this function may not skip over invisible text that is so
6024 because of text properties and immediately follows a newline. If
6025 it would, function reseat_at_next_visible_line_start, when called
6026 from set_iterator_to_next, would effectively make invisible
6027 characters following a newline part of the wrong glyph row, which
6028 leads to wrong cursor motion. */
6029
6030 static int
6031 forward_to_next_line_start (struct it *it, int *skipped_p,
6032 struct bidi_it *bidi_it_prev)
6033 {
6034 ptrdiff_t old_selective;
6035 int newline_found_p, n;
6036 const int MAX_NEWLINE_DISTANCE = 500;
6037
6038 /* If already on a newline, just consume it to avoid unintended
6039 skipping over invisible text below. */
6040 if (it->what == IT_CHARACTER
6041 && it->c == '\n'
6042 && CHARPOS (it->position) == IT_CHARPOS (*it))
6043 {
6044 if (it->bidi_p && bidi_it_prev)
6045 *bidi_it_prev = it->bidi_it;
6046 set_iterator_to_next (it, 0);
6047 it->c = 0;
6048 return 1;
6049 }
6050
6051 /* Don't handle selective display in the following. It's (a)
6052 unnecessary because it's done by the caller, and (b) leads to an
6053 infinite recursion because next_element_from_ellipsis indirectly
6054 calls this function. */
6055 old_selective = it->selective;
6056 it->selective = 0;
6057
6058 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6059 from buffer text. */
6060 for (n = newline_found_p = 0;
6061 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6062 n += STRINGP (it->string) ? 0 : 1)
6063 {
6064 if (!get_next_display_element (it))
6065 return 0;
6066 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6067 if (newline_found_p && it->bidi_p && bidi_it_prev)
6068 *bidi_it_prev = it->bidi_it;
6069 set_iterator_to_next (it, 0);
6070 }
6071
6072 /* If we didn't find a newline near enough, see if we can use a
6073 short-cut. */
6074 if (!newline_found_p)
6075 {
6076 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6077 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6078 1, &bytepos);
6079 Lisp_Object pos;
6080
6081 eassert (!STRINGP (it->string));
6082
6083 /* If there isn't any `display' property in sight, and no
6084 overlays, we can just use the position of the newline in
6085 buffer text. */
6086 if (it->stop_charpos >= limit
6087 || ((pos = Fnext_single_property_change (make_number (start),
6088 Qdisplay, Qnil,
6089 make_number (limit)),
6090 NILP (pos))
6091 && next_overlay_change (start) == ZV))
6092 {
6093 if (!it->bidi_p)
6094 {
6095 IT_CHARPOS (*it) = limit;
6096 IT_BYTEPOS (*it) = bytepos;
6097 }
6098 else
6099 {
6100 struct bidi_it bprev;
6101
6102 /* Help bidi.c avoid expensive searches for display
6103 properties and overlays, by telling it that there are
6104 none up to `limit'. */
6105 if (it->bidi_it.disp_pos < limit)
6106 {
6107 it->bidi_it.disp_pos = limit;
6108 it->bidi_it.disp_prop = 0;
6109 }
6110 do {
6111 bprev = it->bidi_it;
6112 bidi_move_to_visually_next (&it->bidi_it);
6113 } while (it->bidi_it.charpos != limit);
6114 IT_CHARPOS (*it) = limit;
6115 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6116 if (bidi_it_prev)
6117 *bidi_it_prev = bprev;
6118 }
6119 *skipped_p = newline_found_p = 1;
6120 }
6121 else
6122 {
6123 while (get_next_display_element (it)
6124 && !newline_found_p)
6125 {
6126 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6127 if (newline_found_p && it->bidi_p && bidi_it_prev)
6128 *bidi_it_prev = it->bidi_it;
6129 set_iterator_to_next (it, 0);
6130 }
6131 }
6132 }
6133
6134 it->selective = old_selective;
6135 return newline_found_p;
6136 }
6137
6138
6139 /* Set IT's current position to the previous visible line start. Skip
6140 invisible text that is so either due to text properties or due to
6141 selective display. Caution: this does not change IT->current_x and
6142 IT->hpos. */
6143
6144 static void
6145 back_to_previous_visible_line_start (struct it *it)
6146 {
6147 while (IT_CHARPOS (*it) > BEGV)
6148 {
6149 back_to_previous_line_start (it);
6150
6151 if (IT_CHARPOS (*it) <= BEGV)
6152 break;
6153
6154 /* If selective > 0, then lines indented more than its value are
6155 invisible. */
6156 if (it->selective > 0
6157 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6158 it->selective))
6159 continue;
6160
6161 /* Check the newline before point for invisibility. */
6162 {
6163 Lisp_Object prop;
6164 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6165 Qinvisible, it->window);
6166 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6167 continue;
6168 }
6169
6170 if (IT_CHARPOS (*it) <= BEGV)
6171 break;
6172
6173 {
6174 struct it it2;
6175 void *it2data = NULL;
6176 ptrdiff_t pos;
6177 ptrdiff_t beg, end;
6178 Lisp_Object val, overlay;
6179
6180 SAVE_IT (it2, *it, it2data);
6181
6182 /* If newline is part of a composition, continue from start of composition */
6183 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6184 && beg < IT_CHARPOS (*it))
6185 goto replaced;
6186
6187 /* If newline is replaced by a display property, find start of overlay
6188 or interval and continue search from that point. */
6189 pos = --IT_CHARPOS (it2);
6190 --IT_BYTEPOS (it2);
6191 it2.sp = 0;
6192 bidi_unshelve_cache (NULL, 0);
6193 it2.string_from_display_prop_p = 0;
6194 it2.from_disp_prop_p = 0;
6195 if (handle_display_prop (&it2) == HANDLED_RETURN
6196 && !NILP (val = get_char_property_and_overlay
6197 (make_number (pos), Qdisplay, Qnil, &overlay))
6198 && (OVERLAYP (overlay)
6199 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6200 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6201 {
6202 RESTORE_IT (it, it, it2data);
6203 goto replaced;
6204 }
6205
6206 /* Newline is not replaced by anything -- so we are done. */
6207 RESTORE_IT (it, it, it2data);
6208 break;
6209
6210 replaced:
6211 if (beg < BEGV)
6212 beg = BEGV;
6213 IT_CHARPOS (*it) = beg;
6214 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6215 }
6216 }
6217
6218 it->continuation_lines_width = 0;
6219
6220 eassert (IT_CHARPOS (*it) >= BEGV);
6221 eassert (IT_CHARPOS (*it) == BEGV
6222 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6223 CHECK_IT (it);
6224 }
6225
6226
6227 /* Reseat iterator IT at the previous visible line start. Skip
6228 invisible text that is so either due to text properties or due to
6229 selective display. At the end, update IT's overlay information,
6230 face information etc. */
6231
6232 void
6233 reseat_at_previous_visible_line_start (struct it *it)
6234 {
6235 back_to_previous_visible_line_start (it);
6236 reseat (it, it->current.pos, 1);
6237 CHECK_IT (it);
6238 }
6239
6240
6241 /* Reseat iterator IT on the next visible line start in the current
6242 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6243 preceding the line start. Skip over invisible text that is so
6244 because of selective display. Compute faces, overlays etc at the
6245 new position. Note that this function does not skip over text that
6246 is invisible because of text properties. */
6247
6248 static void
6249 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6250 {
6251 int newline_found_p, skipped_p = 0;
6252 struct bidi_it bidi_it_prev;
6253
6254 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6255
6256 /* Skip over lines that are invisible because they are indented
6257 more than the value of IT->selective. */
6258 if (it->selective > 0)
6259 while (IT_CHARPOS (*it) < ZV
6260 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6261 it->selective))
6262 {
6263 eassert (IT_BYTEPOS (*it) == BEGV
6264 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6265 newline_found_p =
6266 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6267 }
6268
6269 /* Position on the newline if that's what's requested. */
6270 if (on_newline_p && newline_found_p)
6271 {
6272 if (STRINGP (it->string))
6273 {
6274 if (IT_STRING_CHARPOS (*it) > 0)
6275 {
6276 if (!it->bidi_p)
6277 {
6278 --IT_STRING_CHARPOS (*it);
6279 --IT_STRING_BYTEPOS (*it);
6280 }
6281 else
6282 {
6283 /* We need to restore the bidi iterator to the state
6284 it had on the newline, and resync the IT's
6285 position with that. */
6286 it->bidi_it = bidi_it_prev;
6287 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6288 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6289 }
6290 }
6291 }
6292 else if (IT_CHARPOS (*it) > BEGV)
6293 {
6294 if (!it->bidi_p)
6295 {
6296 --IT_CHARPOS (*it);
6297 --IT_BYTEPOS (*it);
6298 }
6299 else
6300 {
6301 /* We need to restore the bidi iterator to the state it
6302 had on the newline and resync IT with that. */
6303 it->bidi_it = bidi_it_prev;
6304 IT_CHARPOS (*it) = it->bidi_it.charpos;
6305 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6306 }
6307 reseat (it, it->current.pos, 0);
6308 }
6309 }
6310 else if (skipped_p)
6311 reseat (it, it->current.pos, 0);
6312
6313 CHECK_IT (it);
6314 }
6315
6316
6317 \f
6318 /***********************************************************************
6319 Changing an iterator's position
6320 ***********************************************************************/
6321
6322 /* Change IT's current position to POS in current_buffer. If FORCE_P
6323 is non-zero, always check for text properties at the new position.
6324 Otherwise, text properties are only looked up if POS >=
6325 IT->check_charpos of a property. */
6326
6327 static void
6328 reseat (struct it *it, struct text_pos pos, int force_p)
6329 {
6330 ptrdiff_t original_pos = IT_CHARPOS (*it);
6331
6332 reseat_1 (it, pos, 0);
6333
6334 /* Determine where to check text properties. Avoid doing it
6335 where possible because text property lookup is very expensive. */
6336 if (force_p
6337 || CHARPOS (pos) > it->stop_charpos
6338 || CHARPOS (pos) < original_pos)
6339 {
6340 if (it->bidi_p)
6341 {
6342 /* For bidi iteration, we need to prime prev_stop and
6343 base_level_stop with our best estimations. */
6344 /* Implementation note: Of course, POS is not necessarily a
6345 stop position, so assigning prev_pos to it is a lie; we
6346 should have called compute_stop_backwards. However, if
6347 the current buffer does not include any R2L characters,
6348 that call would be a waste of cycles, because the
6349 iterator will never move back, and thus never cross this
6350 "fake" stop position. So we delay that backward search
6351 until the time we really need it, in next_element_from_buffer. */
6352 if (CHARPOS (pos) != it->prev_stop)
6353 it->prev_stop = CHARPOS (pos);
6354 if (CHARPOS (pos) < it->base_level_stop)
6355 it->base_level_stop = 0; /* meaning it's unknown */
6356 handle_stop (it);
6357 }
6358 else
6359 {
6360 handle_stop (it);
6361 it->prev_stop = it->base_level_stop = 0;
6362 }
6363
6364 }
6365
6366 CHECK_IT (it);
6367 }
6368
6369
6370 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6371 IT->stop_pos to POS, also. */
6372
6373 static void
6374 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6375 {
6376 /* Don't call this function when scanning a C string. */
6377 eassert (it->s == NULL);
6378
6379 /* POS must be a reasonable value. */
6380 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6381
6382 it->current.pos = it->position = pos;
6383 it->end_charpos = ZV;
6384 it->dpvec = NULL;
6385 it->current.dpvec_index = -1;
6386 it->current.overlay_string_index = -1;
6387 IT_STRING_CHARPOS (*it) = -1;
6388 IT_STRING_BYTEPOS (*it) = -1;
6389 it->string = Qnil;
6390 it->method = GET_FROM_BUFFER;
6391 it->object = it->w->contents;
6392 it->area = TEXT_AREA;
6393 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6394 it->sp = 0;
6395 it->string_from_display_prop_p = 0;
6396 it->string_from_prefix_prop_p = 0;
6397
6398 it->from_disp_prop_p = 0;
6399 it->face_before_selective_p = 0;
6400 if (it->bidi_p)
6401 {
6402 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6403 &it->bidi_it);
6404 bidi_unshelve_cache (NULL, 0);
6405 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6406 it->bidi_it.string.s = NULL;
6407 it->bidi_it.string.lstring = Qnil;
6408 it->bidi_it.string.bufpos = 0;
6409 it->bidi_it.string.unibyte = 0;
6410 it->bidi_it.w = it->w;
6411 }
6412
6413 if (set_stop_p)
6414 {
6415 it->stop_charpos = CHARPOS (pos);
6416 it->base_level_stop = CHARPOS (pos);
6417 }
6418 /* This make the information stored in it->cmp_it invalidate. */
6419 it->cmp_it.id = -1;
6420 }
6421
6422
6423 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6424 If S is non-null, it is a C string to iterate over. Otherwise,
6425 STRING gives a Lisp string to iterate over.
6426
6427 If PRECISION > 0, don't return more then PRECISION number of
6428 characters from the string.
6429
6430 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6431 characters have been returned. FIELD_WIDTH < 0 means an infinite
6432 field width.
6433
6434 MULTIBYTE = 0 means disable processing of multibyte characters,
6435 MULTIBYTE > 0 means enable it,
6436 MULTIBYTE < 0 means use IT->multibyte_p.
6437
6438 IT must be initialized via a prior call to init_iterator before
6439 calling this function. */
6440
6441 static void
6442 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6443 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6444 int multibyte)
6445 {
6446 /* No region in strings. */
6447 it->region_beg_charpos = it->region_end_charpos = -1;
6448
6449 /* No text property checks performed by default, but see below. */
6450 it->stop_charpos = -1;
6451
6452 /* Set iterator position and end position. */
6453 memset (&it->current, 0, sizeof it->current);
6454 it->current.overlay_string_index = -1;
6455 it->current.dpvec_index = -1;
6456 eassert (charpos >= 0);
6457
6458 /* If STRING is specified, use its multibyteness, otherwise use the
6459 setting of MULTIBYTE, if specified. */
6460 if (multibyte >= 0)
6461 it->multibyte_p = multibyte > 0;
6462
6463 /* Bidirectional reordering of strings is controlled by the default
6464 value of bidi-display-reordering. Don't try to reorder while
6465 loading loadup.el, as the necessary character property tables are
6466 not yet available. */
6467 it->bidi_p =
6468 NILP (Vpurify_flag)
6469 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6470
6471 if (s == NULL)
6472 {
6473 eassert (STRINGP (string));
6474 it->string = string;
6475 it->s = NULL;
6476 it->end_charpos = it->string_nchars = SCHARS (string);
6477 it->method = GET_FROM_STRING;
6478 it->current.string_pos = string_pos (charpos, string);
6479
6480 if (it->bidi_p)
6481 {
6482 it->bidi_it.string.lstring = string;
6483 it->bidi_it.string.s = NULL;
6484 it->bidi_it.string.schars = it->end_charpos;
6485 it->bidi_it.string.bufpos = 0;
6486 it->bidi_it.string.from_disp_str = 0;
6487 it->bidi_it.string.unibyte = !it->multibyte_p;
6488 it->bidi_it.w = it->w;
6489 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6490 FRAME_WINDOW_P (it->f), &it->bidi_it);
6491 }
6492 }
6493 else
6494 {
6495 it->s = (const unsigned char *) s;
6496 it->string = Qnil;
6497
6498 /* Note that we use IT->current.pos, not it->current.string_pos,
6499 for displaying C strings. */
6500 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6501 if (it->multibyte_p)
6502 {
6503 it->current.pos = c_string_pos (charpos, s, 1);
6504 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6505 }
6506 else
6507 {
6508 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6509 it->end_charpos = it->string_nchars = strlen (s);
6510 }
6511
6512 if (it->bidi_p)
6513 {
6514 it->bidi_it.string.lstring = Qnil;
6515 it->bidi_it.string.s = (const unsigned char *) s;
6516 it->bidi_it.string.schars = it->end_charpos;
6517 it->bidi_it.string.bufpos = 0;
6518 it->bidi_it.string.from_disp_str = 0;
6519 it->bidi_it.string.unibyte = !it->multibyte_p;
6520 it->bidi_it.w = it->w;
6521 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6522 &it->bidi_it);
6523 }
6524 it->method = GET_FROM_C_STRING;
6525 }
6526
6527 /* PRECISION > 0 means don't return more than PRECISION characters
6528 from the string. */
6529 if (precision > 0 && it->end_charpos - charpos > precision)
6530 {
6531 it->end_charpos = it->string_nchars = charpos + precision;
6532 if (it->bidi_p)
6533 it->bidi_it.string.schars = it->end_charpos;
6534 }
6535
6536 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6537 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6538 FIELD_WIDTH < 0 means infinite field width. This is useful for
6539 padding with `-' at the end of a mode line. */
6540 if (field_width < 0)
6541 field_width = INFINITY;
6542 /* Implementation note: We deliberately don't enlarge
6543 it->bidi_it.string.schars here to fit it->end_charpos, because
6544 the bidi iterator cannot produce characters out of thin air. */
6545 if (field_width > it->end_charpos - charpos)
6546 it->end_charpos = charpos + field_width;
6547
6548 /* Use the standard display table for displaying strings. */
6549 if (DISP_TABLE_P (Vstandard_display_table))
6550 it->dp = XCHAR_TABLE (Vstandard_display_table);
6551
6552 it->stop_charpos = charpos;
6553 it->prev_stop = charpos;
6554 it->base_level_stop = 0;
6555 if (it->bidi_p)
6556 {
6557 it->bidi_it.first_elt = 1;
6558 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6559 it->bidi_it.disp_pos = -1;
6560 }
6561 if (s == NULL && it->multibyte_p)
6562 {
6563 ptrdiff_t endpos = SCHARS (it->string);
6564 if (endpos > it->end_charpos)
6565 endpos = it->end_charpos;
6566 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6567 it->string);
6568 }
6569 CHECK_IT (it);
6570 }
6571
6572
6573 \f
6574 /***********************************************************************
6575 Iteration
6576 ***********************************************************************/
6577
6578 /* Map enum it_method value to corresponding next_element_from_* function. */
6579
6580 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6581 {
6582 next_element_from_buffer,
6583 next_element_from_display_vector,
6584 next_element_from_string,
6585 next_element_from_c_string,
6586 next_element_from_image,
6587 next_element_from_stretch
6588 };
6589
6590 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6591
6592
6593 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6594 (possibly with the following characters). */
6595
6596 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6597 ((IT)->cmp_it.id >= 0 \
6598 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6599 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6600 END_CHARPOS, (IT)->w, \
6601 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6602 (IT)->string)))
6603
6604
6605 /* Lookup the char-table Vglyphless_char_display for character C (-1
6606 if we want information for no-font case), and return the display
6607 method symbol. By side-effect, update it->what and
6608 it->glyphless_method. This function is called from
6609 get_next_display_element for each character element, and from
6610 x_produce_glyphs when no suitable font was found. */
6611
6612 Lisp_Object
6613 lookup_glyphless_char_display (int c, struct it *it)
6614 {
6615 Lisp_Object glyphless_method = Qnil;
6616
6617 if (CHAR_TABLE_P (Vglyphless_char_display)
6618 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6619 {
6620 if (c >= 0)
6621 {
6622 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6623 if (CONSP (glyphless_method))
6624 glyphless_method = FRAME_WINDOW_P (it->f)
6625 ? XCAR (glyphless_method)
6626 : XCDR (glyphless_method);
6627 }
6628 else
6629 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6630 }
6631
6632 retry:
6633 if (NILP (glyphless_method))
6634 {
6635 if (c >= 0)
6636 /* The default is to display the character by a proper font. */
6637 return Qnil;
6638 /* The default for the no-font case is to display an empty box. */
6639 glyphless_method = Qempty_box;
6640 }
6641 if (EQ (glyphless_method, Qzero_width))
6642 {
6643 if (c >= 0)
6644 return glyphless_method;
6645 /* This method can't be used for the no-font case. */
6646 glyphless_method = Qempty_box;
6647 }
6648 if (EQ (glyphless_method, Qthin_space))
6649 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6650 else if (EQ (glyphless_method, Qempty_box))
6651 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6652 else if (EQ (glyphless_method, Qhex_code))
6653 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6654 else if (STRINGP (glyphless_method))
6655 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6656 else
6657 {
6658 /* Invalid value. We use the default method. */
6659 glyphless_method = Qnil;
6660 goto retry;
6661 }
6662 it->what = IT_GLYPHLESS;
6663 return glyphless_method;
6664 }
6665
6666 /* Merge escape glyph face and cache the result. */
6667
6668 static struct frame *last_escape_glyph_frame = NULL;
6669 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6670 static int last_escape_glyph_merged_face_id = 0;
6671
6672 static int
6673 merge_escape_glyph_face (struct it *it)
6674 {
6675 int face_id;
6676
6677 if (it->f == last_escape_glyph_frame
6678 && it->face_id == last_escape_glyph_face_id)
6679 face_id = last_escape_glyph_merged_face_id;
6680 else
6681 {
6682 /* Merge the `escape-glyph' face into the current face. */
6683 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6684 last_escape_glyph_frame = it->f;
6685 last_escape_glyph_face_id = it->face_id;
6686 last_escape_glyph_merged_face_id = face_id;
6687 }
6688 return face_id;
6689 }
6690
6691 /* Likewise for glyphless glyph face. */
6692
6693 static struct frame *last_glyphless_glyph_frame = NULL;
6694 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6695 static int last_glyphless_glyph_merged_face_id = 0;
6696
6697 int
6698 merge_glyphless_glyph_face (struct it *it)
6699 {
6700 int face_id;
6701
6702 if (it->f == last_glyphless_glyph_frame
6703 && it->face_id == last_glyphless_glyph_face_id)
6704 face_id = last_glyphless_glyph_merged_face_id;
6705 else
6706 {
6707 /* Merge the `glyphless-char' face into the current face. */
6708 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6709 last_glyphless_glyph_frame = it->f;
6710 last_glyphless_glyph_face_id = it->face_id;
6711 last_glyphless_glyph_merged_face_id = face_id;
6712 }
6713 return face_id;
6714 }
6715
6716 /* Load IT's display element fields with information about the next
6717 display element from the current position of IT. Value is zero if
6718 end of buffer (or C string) is reached. */
6719
6720 static int
6721 get_next_display_element (struct it *it)
6722 {
6723 /* Non-zero means that we found a display element. Zero means that
6724 we hit the end of what we iterate over. Performance note: the
6725 function pointer `method' used here turns out to be faster than
6726 using a sequence of if-statements. */
6727 int success_p;
6728
6729 get_next:
6730 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6731
6732 if (it->what == IT_CHARACTER)
6733 {
6734 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6735 and only if (a) the resolved directionality of that character
6736 is R..." */
6737 /* FIXME: Do we need an exception for characters from display
6738 tables? */
6739 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6740 it->c = bidi_mirror_char (it->c);
6741 /* Map via display table or translate control characters.
6742 IT->c, IT->len etc. have been set to the next character by
6743 the function call above. If we have a display table, and it
6744 contains an entry for IT->c, translate it. Don't do this if
6745 IT->c itself comes from a display table, otherwise we could
6746 end up in an infinite recursion. (An alternative could be to
6747 count the recursion depth of this function and signal an
6748 error when a certain maximum depth is reached.) Is it worth
6749 it? */
6750 if (success_p && it->dpvec == NULL)
6751 {
6752 Lisp_Object dv;
6753 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6754 int nonascii_space_p = 0;
6755 int nonascii_hyphen_p = 0;
6756 int c = it->c; /* This is the character to display. */
6757
6758 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6759 {
6760 eassert (SINGLE_BYTE_CHAR_P (c));
6761 if (unibyte_display_via_language_environment)
6762 {
6763 c = DECODE_CHAR (unibyte, c);
6764 if (c < 0)
6765 c = BYTE8_TO_CHAR (it->c);
6766 }
6767 else
6768 c = BYTE8_TO_CHAR (it->c);
6769 }
6770
6771 if (it->dp
6772 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6773 VECTORP (dv)))
6774 {
6775 struct Lisp_Vector *v = XVECTOR (dv);
6776
6777 /* Return the first character from the display table
6778 entry, if not empty. If empty, don't display the
6779 current character. */
6780 if (v->header.size)
6781 {
6782 it->dpvec_char_len = it->len;
6783 it->dpvec = v->contents;
6784 it->dpend = v->contents + v->header.size;
6785 it->current.dpvec_index = 0;
6786 it->dpvec_face_id = -1;
6787 it->saved_face_id = it->face_id;
6788 it->method = GET_FROM_DISPLAY_VECTOR;
6789 it->ellipsis_p = 0;
6790 }
6791 else
6792 {
6793 set_iterator_to_next (it, 0);
6794 }
6795 goto get_next;
6796 }
6797
6798 if (! NILP (lookup_glyphless_char_display (c, it)))
6799 {
6800 if (it->what == IT_GLYPHLESS)
6801 goto done;
6802 /* Don't display this character. */
6803 set_iterator_to_next (it, 0);
6804 goto get_next;
6805 }
6806
6807 /* If `nobreak-char-display' is non-nil, we display
6808 non-ASCII spaces and hyphens specially. */
6809 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6810 {
6811 if (c == 0xA0)
6812 nonascii_space_p = 1;
6813 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6814 nonascii_hyphen_p = 1;
6815 }
6816
6817 /* Translate control characters into `\003' or `^C' form.
6818 Control characters coming from a display table entry are
6819 currently not translated because we use IT->dpvec to hold
6820 the translation. This could easily be changed but I
6821 don't believe that it is worth doing.
6822
6823 The characters handled by `nobreak-char-display' must be
6824 translated too.
6825
6826 Non-printable characters and raw-byte characters are also
6827 translated to octal form. */
6828 if (((c < ' ' || c == 127) /* ASCII control chars */
6829 ? (it->area != TEXT_AREA
6830 /* In mode line, treat \n, \t like other crl chars. */
6831 || (c != '\t'
6832 && it->glyph_row
6833 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6834 || (c != '\n' && c != '\t'))
6835 : (nonascii_space_p
6836 || nonascii_hyphen_p
6837 || CHAR_BYTE8_P (c)
6838 || ! CHAR_PRINTABLE_P (c))))
6839 {
6840 /* C is a control character, non-ASCII space/hyphen,
6841 raw-byte, or a non-printable character which must be
6842 displayed either as '\003' or as `^C' where the '\\'
6843 and '^' can be defined in the display table. Fill
6844 IT->ctl_chars with glyphs for what we have to
6845 display. Then, set IT->dpvec to these glyphs. */
6846 Lisp_Object gc;
6847 int ctl_len;
6848 int face_id;
6849 int lface_id = 0;
6850 int escape_glyph;
6851
6852 /* Handle control characters with ^. */
6853
6854 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6855 {
6856 int g;
6857
6858 g = '^'; /* default glyph for Control */
6859 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6860 if (it->dp
6861 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6862 {
6863 g = GLYPH_CODE_CHAR (gc);
6864 lface_id = GLYPH_CODE_FACE (gc);
6865 }
6866
6867 face_id = (lface_id
6868 ? merge_faces (it->f, Qt, lface_id, it->face_id)
6869 : merge_escape_glyph_face (it));
6870
6871 XSETINT (it->ctl_chars[0], g);
6872 XSETINT (it->ctl_chars[1], c ^ 0100);
6873 ctl_len = 2;
6874 goto display_control;
6875 }
6876
6877 /* Handle non-ascii space in the mode where it only gets
6878 highlighting. */
6879
6880 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6881 {
6882 /* Merge `nobreak-space' into the current face. */
6883 face_id = merge_faces (it->f, Qnobreak_space, 0,
6884 it->face_id);
6885 XSETINT (it->ctl_chars[0], ' ');
6886 ctl_len = 1;
6887 goto display_control;
6888 }
6889
6890 /* Handle sequences that start with the "escape glyph". */
6891
6892 /* the default escape glyph is \. */
6893 escape_glyph = '\\';
6894
6895 if (it->dp
6896 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6897 {
6898 escape_glyph = GLYPH_CODE_CHAR (gc);
6899 lface_id = GLYPH_CODE_FACE (gc);
6900 }
6901
6902 face_id = (lface_id
6903 ? merge_faces (it->f, Qt, lface_id, it->face_id)
6904 : merge_escape_glyph_face (it));
6905
6906 /* Draw non-ASCII hyphen with just highlighting: */
6907
6908 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6909 {
6910 XSETINT (it->ctl_chars[0], '-');
6911 ctl_len = 1;
6912 goto display_control;
6913 }
6914
6915 /* Draw non-ASCII space/hyphen with escape glyph: */
6916
6917 if (nonascii_space_p || nonascii_hyphen_p)
6918 {
6919 XSETINT (it->ctl_chars[0], escape_glyph);
6920 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6921 ctl_len = 2;
6922 goto display_control;
6923 }
6924
6925 {
6926 char str[10];
6927 int len, i;
6928
6929 if (CHAR_BYTE8_P (c))
6930 /* Display \200 instead of \17777600. */
6931 c = CHAR_TO_BYTE8 (c);
6932 len = sprintf (str, "%03o", c);
6933
6934 XSETINT (it->ctl_chars[0], escape_glyph);
6935 for (i = 0; i < len; i++)
6936 XSETINT (it->ctl_chars[i + 1], str[i]);
6937 ctl_len = len + 1;
6938 }
6939
6940 display_control:
6941 /* Set up IT->dpvec and return first character from it. */
6942 it->dpvec_char_len = it->len;
6943 it->dpvec = it->ctl_chars;
6944 it->dpend = it->dpvec + ctl_len;
6945 it->current.dpvec_index = 0;
6946 it->dpvec_face_id = face_id;
6947 it->saved_face_id = it->face_id;
6948 it->method = GET_FROM_DISPLAY_VECTOR;
6949 it->ellipsis_p = 0;
6950 goto get_next;
6951 }
6952 it->char_to_display = c;
6953 }
6954 else if (success_p)
6955 {
6956 it->char_to_display = it->c;
6957 }
6958 }
6959
6960 /* Adjust face id for a multibyte character. There are no multibyte
6961 character in unibyte text. */
6962 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6963 && it->multibyte_p
6964 && success_p
6965 && FRAME_WINDOW_P (it->f))
6966 {
6967 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6968
6969 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6970 {
6971 /* Automatic composition with glyph-string. */
6972 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6973
6974 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6975 }
6976 else
6977 {
6978 ptrdiff_t pos = (it->s ? -1
6979 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6980 : IT_CHARPOS (*it));
6981 int c;
6982
6983 if (it->what == IT_CHARACTER)
6984 c = it->char_to_display;
6985 else
6986 {
6987 struct composition *cmp = composition_table[it->cmp_it.id];
6988 int i;
6989
6990 c = ' ';
6991 for (i = 0; i < cmp->glyph_len; i++)
6992 /* TAB in a composition means display glyphs with
6993 padding space on the left or right. */
6994 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6995 break;
6996 }
6997 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6998 }
6999 }
7000
7001 done:
7002 /* Is this character the last one of a run of characters with
7003 box? If yes, set IT->end_of_box_run_p to 1. */
7004 if (it->face_box_p
7005 && it->s == NULL)
7006 {
7007 if (it->method == GET_FROM_STRING && it->sp)
7008 {
7009 int face_id = underlying_face_id (it);
7010 struct face *face = FACE_FROM_ID (it->f, face_id);
7011
7012 if (face)
7013 {
7014 if (face->box == FACE_NO_BOX)
7015 {
7016 /* If the box comes from face properties in a
7017 display string, check faces in that string. */
7018 int string_face_id = face_after_it_pos (it);
7019 it->end_of_box_run_p
7020 = (FACE_FROM_ID (it->f, string_face_id)->box
7021 == FACE_NO_BOX);
7022 }
7023 /* Otherwise, the box comes from the underlying face.
7024 If this is the last string character displayed, check
7025 the next buffer location. */
7026 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7027 && (it->current.overlay_string_index
7028 == it->n_overlay_strings - 1))
7029 {
7030 ptrdiff_t ignore;
7031 int next_face_id;
7032 struct text_pos pos = it->current.pos;
7033 INC_TEXT_POS (pos, it->multibyte_p);
7034
7035 next_face_id = face_at_buffer_position
7036 (it->w, CHARPOS (pos), it->region_beg_charpos,
7037 it->region_end_charpos, &ignore,
7038 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
7039 -1);
7040 it->end_of_box_run_p
7041 = (FACE_FROM_ID (it->f, next_face_id)->box
7042 == FACE_NO_BOX);
7043 }
7044 }
7045 }
7046 /* next_element_from_display_vector sets this flag according to
7047 faces of the display vector glyphs, see there. */
7048 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7049 {
7050 int face_id = face_after_it_pos (it);
7051 it->end_of_box_run_p
7052 = (face_id != it->face_id
7053 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7054 }
7055 }
7056 /* If we reached the end of the object we've been iterating (e.g., a
7057 display string or an overlay string), and there's something on
7058 IT->stack, proceed with what's on the stack. It doesn't make
7059 sense to return zero if there's unprocessed stuff on the stack,
7060 because otherwise that stuff will never be displayed. */
7061 if (!success_p && it->sp > 0)
7062 {
7063 set_iterator_to_next (it, 0);
7064 success_p = get_next_display_element (it);
7065 }
7066
7067 /* Value is 0 if end of buffer or string reached. */
7068 return success_p;
7069 }
7070
7071
7072 /* Move IT to the next display element.
7073
7074 RESEAT_P non-zero means if called on a newline in buffer text,
7075 skip to the next visible line start.
7076
7077 Functions get_next_display_element and set_iterator_to_next are
7078 separate because I find this arrangement easier to handle than a
7079 get_next_display_element function that also increments IT's
7080 position. The way it is we can first look at an iterator's current
7081 display element, decide whether it fits on a line, and if it does,
7082 increment the iterator position. The other way around we probably
7083 would either need a flag indicating whether the iterator has to be
7084 incremented the next time, or we would have to implement a
7085 decrement position function which would not be easy to write. */
7086
7087 void
7088 set_iterator_to_next (struct it *it, int reseat_p)
7089 {
7090 /* Reset flags indicating start and end of a sequence of characters
7091 with box. Reset them at the start of this function because
7092 moving the iterator to a new position might set them. */
7093 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7094
7095 switch (it->method)
7096 {
7097 case GET_FROM_BUFFER:
7098 /* The current display element of IT is a character from
7099 current_buffer. Advance in the buffer, and maybe skip over
7100 invisible lines that are so because of selective display. */
7101 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7102 reseat_at_next_visible_line_start (it, 0);
7103 else if (it->cmp_it.id >= 0)
7104 {
7105 /* We are currently getting glyphs from a composition. */
7106 int i;
7107
7108 if (! it->bidi_p)
7109 {
7110 IT_CHARPOS (*it) += it->cmp_it.nchars;
7111 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7112 if (it->cmp_it.to < it->cmp_it.nglyphs)
7113 {
7114 it->cmp_it.from = it->cmp_it.to;
7115 }
7116 else
7117 {
7118 it->cmp_it.id = -1;
7119 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7120 IT_BYTEPOS (*it),
7121 it->end_charpos, Qnil);
7122 }
7123 }
7124 else if (! it->cmp_it.reversed_p)
7125 {
7126 /* Composition created while scanning forward. */
7127 /* Update IT's char/byte positions to point to the first
7128 character of the next grapheme cluster, or to the
7129 character visually after the current composition. */
7130 for (i = 0; i < it->cmp_it.nchars; i++)
7131 bidi_move_to_visually_next (&it->bidi_it);
7132 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7133 IT_CHARPOS (*it) = it->bidi_it.charpos;
7134
7135 if (it->cmp_it.to < it->cmp_it.nglyphs)
7136 {
7137 /* Proceed to the next grapheme cluster. */
7138 it->cmp_it.from = it->cmp_it.to;
7139 }
7140 else
7141 {
7142 /* No more grapheme clusters in this composition.
7143 Find the next stop position. */
7144 ptrdiff_t stop = it->end_charpos;
7145 if (it->bidi_it.scan_dir < 0)
7146 /* Now we are scanning backward and don't know
7147 where to stop. */
7148 stop = -1;
7149 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7150 IT_BYTEPOS (*it), stop, Qnil);
7151 }
7152 }
7153 else
7154 {
7155 /* Composition created while scanning backward. */
7156 /* Update IT's char/byte positions to point to the last
7157 character of the previous grapheme cluster, or the
7158 character visually after the current composition. */
7159 for (i = 0; i < it->cmp_it.nchars; i++)
7160 bidi_move_to_visually_next (&it->bidi_it);
7161 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7162 IT_CHARPOS (*it) = it->bidi_it.charpos;
7163 if (it->cmp_it.from > 0)
7164 {
7165 /* Proceed to the previous grapheme cluster. */
7166 it->cmp_it.to = it->cmp_it.from;
7167 }
7168 else
7169 {
7170 /* No more grapheme clusters in this composition.
7171 Find the next stop position. */
7172 ptrdiff_t stop = it->end_charpos;
7173 if (it->bidi_it.scan_dir < 0)
7174 /* Now we are scanning backward and don't know
7175 where to stop. */
7176 stop = -1;
7177 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7178 IT_BYTEPOS (*it), stop, Qnil);
7179 }
7180 }
7181 }
7182 else
7183 {
7184 eassert (it->len != 0);
7185
7186 if (!it->bidi_p)
7187 {
7188 IT_BYTEPOS (*it) += it->len;
7189 IT_CHARPOS (*it) += 1;
7190 }
7191 else
7192 {
7193 int prev_scan_dir = it->bidi_it.scan_dir;
7194 /* If this is a new paragraph, determine its base
7195 direction (a.k.a. its base embedding level). */
7196 if (it->bidi_it.new_paragraph)
7197 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7198 bidi_move_to_visually_next (&it->bidi_it);
7199 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7200 IT_CHARPOS (*it) = it->bidi_it.charpos;
7201 if (prev_scan_dir != it->bidi_it.scan_dir)
7202 {
7203 /* As the scan direction was changed, we must
7204 re-compute the stop position for composition. */
7205 ptrdiff_t stop = it->end_charpos;
7206 if (it->bidi_it.scan_dir < 0)
7207 stop = -1;
7208 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7209 IT_BYTEPOS (*it), stop, Qnil);
7210 }
7211 }
7212 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7213 }
7214 break;
7215
7216 case GET_FROM_C_STRING:
7217 /* Current display element of IT is from a C string. */
7218 if (!it->bidi_p
7219 /* If the string position is beyond string's end, it means
7220 next_element_from_c_string is padding the string with
7221 blanks, in which case we bypass the bidi iterator,
7222 because it cannot deal with such virtual characters. */
7223 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7224 {
7225 IT_BYTEPOS (*it) += it->len;
7226 IT_CHARPOS (*it) += 1;
7227 }
7228 else
7229 {
7230 bidi_move_to_visually_next (&it->bidi_it);
7231 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7232 IT_CHARPOS (*it) = it->bidi_it.charpos;
7233 }
7234 break;
7235
7236 case GET_FROM_DISPLAY_VECTOR:
7237 /* Current display element of IT is from a display table entry.
7238 Advance in the display table definition. Reset it to null if
7239 end reached, and continue with characters from buffers/
7240 strings. */
7241 ++it->current.dpvec_index;
7242
7243 /* Restore face of the iterator to what they were before the
7244 display vector entry (these entries may contain faces). */
7245 it->face_id = it->saved_face_id;
7246
7247 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7248 {
7249 int recheck_faces = it->ellipsis_p;
7250
7251 if (it->s)
7252 it->method = GET_FROM_C_STRING;
7253 else if (STRINGP (it->string))
7254 it->method = GET_FROM_STRING;
7255 else
7256 {
7257 it->method = GET_FROM_BUFFER;
7258 it->object = it->w->contents;
7259 }
7260
7261 it->dpvec = NULL;
7262 it->current.dpvec_index = -1;
7263
7264 /* Skip over characters which were displayed via IT->dpvec. */
7265 if (it->dpvec_char_len < 0)
7266 reseat_at_next_visible_line_start (it, 1);
7267 else if (it->dpvec_char_len > 0)
7268 {
7269 if (it->method == GET_FROM_STRING
7270 && it->current.overlay_string_index >= 0
7271 && it->n_overlay_strings > 0)
7272 it->ignore_overlay_strings_at_pos_p = 1;
7273 it->len = it->dpvec_char_len;
7274 set_iterator_to_next (it, reseat_p);
7275 }
7276
7277 /* Maybe recheck faces after display vector */
7278 if (recheck_faces)
7279 it->stop_charpos = IT_CHARPOS (*it);
7280 }
7281 break;
7282
7283 case GET_FROM_STRING:
7284 /* Current display element is a character from a Lisp string. */
7285 eassert (it->s == NULL && STRINGP (it->string));
7286 /* Don't advance past string end. These conditions are true
7287 when set_iterator_to_next is called at the end of
7288 get_next_display_element, in which case the Lisp string is
7289 already exhausted, and all we want is pop the iterator
7290 stack. */
7291 if (it->current.overlay_string_index >= 0)
7292 {
7293 /* This is an overlay string, so there's no padding with
7294 spaces, and the number of characters in the string is
7295 where the string ends. */
7296 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7297 goto consider_string_end;
7298 }
7299 else
7300 {
7301 /* Not an overlay string. There could be padding, so test
7302 against it->end_charpos . */
7303 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7304 goto consider_string_end;
7305 }
7306 if (it->cmp_it.id >= 0)
7307 {
7308 int i;
7309
7310 if (! it->bidi_p)
7311 {
7312 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7313 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7314 if (it->cmp_it.to < it->cmp_it.nglyphs)
7315 it->cmp_it.from = it->cmp_it.to;
7316 else
7317 {
7318 it->cmp_it.id = -1;
7319 composition_compute_stop_pos (&it->cmp_it,
7320 IT_STRING_CHARPOS (*it),
7321 IT_STRING_BYTEPOS (*it),
7322 it->end_charpos, it->string);
7323 }
7324 }
7325 else if (! it->cmp_it.reversed_p)
7326 {
7327 for (i = 0; i < it->cmp_it.nchars; i++)
7328 bidi_move_to_visually_next (&it->bidi_it);
7329 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7330 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7331
7332 if (it->cmp_it.to < it->cmp_it.nglyphs)
7333 it->cmp_it.from = it->cmp_it.to;
7334 else
7335 {
7336 ptrdiff_t stop = it->end_charpos;
7337 if (it->bidi_it.scan_dir < 0)
7338 stop = -1;
7339 composition_compute_stop_pos (&it->cmp_it,
7340 IT_STRING_CHARPOS (*it),
7341 IT_STRING_BYTEPOS (*it), stop,
7342 it->string);
7343 }
7344 }
7345 else
7346 {
7347 for (i = 0; i < it->cmp_it.nchars; i++)
7348 bidi_move_to_visually_next (&it->bidi_it);
7349 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7350 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7351 if (it->cmp_it.from > 0)
7352 it->cmp_it.to = it->cmp_it.from;
7353 else
7354 {
7355 ptrdiff_t stop = it->end_charpos;
7356 if (it->bidi_it.scan_dir < 0)
7357 stop = -1;
7358 composition_compute_stop_pos (&it->cmp_it,
7359 IT_STRING_CHARPOS (*it),
7360 IT_STRING_BYTEPOS (*it), stop,
7361 it->string);
7362 }
7363 }
7364 }
7365 else
7366 {
7367 if (!it->bidi_p
7368 /* If the string position is beyond string's end, it
7369 means next_element_from_string is padding the string
7370 with blanks, in which case we bypass the bidi
7371 iterator, because it cannot deal with such virtual
7372 characters. */
7373 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7374 {
7375 IT_STRING_BYTEPOS (*it) += it->len;
7376 IT_STRING_CHARPOS (*it) += 1;
7377 }
7378 else
7379 {
7380 int prev_scan_dir = it->bidi_it.scan_dir;
7381
7382 bidi_move_to_visually_next (&it->bidi_it);
7383 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7384 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7385 if (prev_scan_dir != it->bidi_it.scan_dir)
7386 {
7387 ptrdiff_t stop = it->end_charpos;
7388
7389 if (it->bidi_it.scan_dir < 0)
7390 stop = -1;
7391 composition_compute_stop_pos (&it->cmp_it,
7392 IT_STRING_CHARPOS (*it),
7393 IT_STRING_BYTEPOS (*it), stop,
7394 it->string);
7395 }
7396 }
7397 }
7398
7399 consider_string_end:
7400
7401 if (it->current.overlay_string_index >= 0)
7402 {
7403 /* IT->string is an overlay string. Advance to the
7404 next, if there is one. */
7405 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7406 {
7407 it->ellipsis_p = 0;
7408 next_overlay_string (it);
7409 if (it->ellipsis_p)
7410 setup_for_ellipsis (it, 0);
7411 }
7412 }
7413 else
7414 {
7415 /* IT->string is not an overlay string. If we reached
7416 its end, and there is something on IT->stack, proceed
7417 with what is on the stack. This can be either another
7418 string, this time an overlay string, or a buffer. */
7419 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7420 && it->sp > 0)
7421 {
7422 pop_it (it);
7423 if (it->method == GET_FROM_STRING)
7424 goto consider_string_end;
7425 }
7426 }
7427 break;
7428
7429 case GET_FROM_IMAGE:
7430 case GET_FROM_STRETCH:
7431 /* The position etc with which we have to proceed are on
7432 the stack. The position may be at the end of a string,
7433 if the `display' property takes up the whole string. */
7434 eassert (it->sp > 0);
7435 pop_it (it);
7436 if (it->method == GET_FROM_STRING)
7437 goto consider_string_end;
7438 break;
7439
7440 default:
7441 /* There are no other methods defined, so this should be a bug. */
7442 emacs_abort ();
7443 }
7444
7445 eassert (it->method != GET_FROM_STRING
7446 || (STRINGP (it->string)
7447 && IT_STRING_CHARPOS (*it) >= 0));
7448 }
7449
7450 /* Load IT's display element fields with information about the next
7451 display element which comes from a display table entry or from the
7452 result of translating a control character to one of the forms `^C'
7453 or `\003'.
7454
7455 IT->dpvec holds the glyphs to return as characters.
7456 IT->saved_face_id holds the face id before the display vector--it
7457 is restored into IT->face_id in set_iterator_to_next. */
7458
7459 static int
7460 next_element_from_display_vector (struct it *it)
7461 {
7462 Lisp_Object gc;
7463 int prev_face_id = it->face_id;
7464 int next_face_id;
7465
7466 /* Precondition. */
7467 eassert (it->dpvec && it->current.dpvec_index >= 0);
7468
7469 it->face_id = it->saved_face_id;
7470
7471 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7472 That seemed totally bogus - so I changed it... */
7473 gc = it->dpvec[it->current.dpvec_index];
7474
7475 if (GLYPH_CODE_P (gc))
7476 {
7477 struct face *this_face, *prev_face, *next_face;
7478
7479 it->c = GLYPH_CODE_CHAR (gc);
7480 it->len = CHAR_BYTES (it->c);
7481
7482 /* The entry may contain a face id to use. Such a face id is
7483 the id of a Lisp face, not a realized face. A face id of
7484 zero means no face is specified. */
7485 if (it->dpvec_face_id >= 0)
7486 it->face_id = it->dpvec_face_id;
7487 else
7488 {
7489 int lface_id = GLYPH_CODE_FACE (gc);
7490 if (lface_id > 0)
7491 it->face_id = merge_faces (it->f, Qt, lface_id,
7492 it->saved_face_id);
7493 }
7494
7495 /* Glyphs in the display vector could have the box face, so we
7496 need to set the related flags in the iterator, as
7497 appropriate. */
7498 this_face = FACE_FROM_ID (it->f, it->face_id);
7499 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7500
7501 /* Is this character the first character of a box-face run? */
7502 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7503 && (!prev_face
7504 || prev_face->box == FACE_NO_BOX));
7505
7506 /* For the last character of the box-face run, we need to look
7507 either at the next glyph from the display vector, or at the
7508 face we saw before the display vector. */
7509 next_face_id = it->saved_face_id;
7510 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7511 {
7512 if (it->dpvec_face_id >= 0)
7513 next_face_id = it->dpvec_face_id;
7514 else
7515 {
7516 int lface_id =
7517 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7518
7519 if (lface_id > 0)
7520 next_face_id = merge_faces (it->f, Qt, lface_id,
7521 it->saved_face_id);
7522 }
7523 }
7524 next_face = FACE_FROM_ID (it->f, next_face_id);
7525 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7526 && (!next_face
7527 || next_face->box == FACE_NO_BOX));
7528 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7529 }
7530 else
7531 /* Display table entry is invalid. Return a space. */
7532 it->c = ' ', it->len = 1;
7533
7534 /* Don't change position and object of the iterator here. They are
7535 still the values of the character that had this display table
7536 entry or was translated, and that's what we want. */
7537 it->what = IT_CHARACTER;
7538 return 1;
7539 }
7540
7541 /* Get the first element of string/buffer in the visual order, after
7542 being reseated to a new position in a string or a buffer. */
7543 static void
7544 get_visually_first_element (struct it *it)
7545 {
7546 int string_p = STRINGP (it->string) || it->s;
7547 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7548 ptrdiff_t bob = (string_p ? 0 : BEGV);
7549
7550 if (STRINGP (it->string))
7551 {
7552 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7553 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7554 }
7555 else
7556 {
7557 it->bidi_it.charpos = IT_CHARPOS (*it);
7558 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7559 }
7560
7561 if (it->bidi_it.charpos == eob)
7562 {
7563 /* Nothing to do, but reset the FIRST_ELT flag, like
7564 bidi_paragraph_init does, because we are not going to
7565 call it. */
7566 it->bidi_it.first_elt = 0;
7567 }
7568 else if (it->bidi_it.charpos == bob
7569 || (!string_p
7570 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7571 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7572 {
7573 /* If we are at the beginning of a line/string, we can produce
7574 the next element right away. */
7575 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7576 bidi_move_to_visually_next (&it->bidi_it);
7577 }
7578 else
7579 {
7580 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7581
7582 /* We need to prime the bidi iterator starting at the line's or
7583 string's beginning, before we will be able to produce the
7584 next element. */
7585 if (string_p)
7586 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7587 else
7588 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7589 IT_BYTEPOS (*it), -1,
7590 &it->bidi_it.bytepos);
7591 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7592 do
7593 {
7594 /* Now return to buffer/string position where we were asked
7595 to get the next display element, and produce that. */
7596 bidi_move_to_visually_next (&it->bidi_it);
7597 }
7598 while (it->bidi_it.bytepos != orig_bytepos
7599 && it->bidi_it.charpos < eob);
7600 }
7601
7602 /* Adjust IT's position information to where we ended up. */
7603 if (STRINGP (it->string))
7604 {
7605 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7606 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7607 }
7608 else
7609 {
7610 IT_CHARPOS (*it) = it->bidi_it.charpos;
7611 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7612 }
7613
7614 if (STRINGP (it->string) || !it->s)
7615 {
7616 ptrdiff_t stop, charpos, bytepos;
7617
7618 if (STRINGP (it->string))
7619 {
7620 eassert (!it->s);
7621 stop = SCHARS (it->string);
7622 if (stop > it->end_charpos)
7623 stop = it->end_charpos;
7624 charpos = IT_STRING_CHARPOS (*it);
7625 bytepos = IT_STRING_BYTEPOS (*it);
7626 }
7627 else
7628 {
7629 stop = it->end_charpos;
7630 charpos = IT_CHARPOS (*it);
7631 bytepos = IT_BYTEPOS (*it);
7632 }
7633 if (it->bidi_it.scan_dir < 0)
7634 stop = -1;
7635 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7636 it->string);
7637 }
7638 }
7639
7640 /* Load IT with the next display element from Lisp string IT->string.
7641 IT->current.string_pos is the current position within the string.
7642 If IT->current.overlay_string_index >= 0, the Lisp string is an
7643 overlay string. */
7644
7645 static int
7646 next_element_from_string (struct it *it)
7647 {
7648 struct text_pos position;
7649
7650 eassert (STRINGP (it->string));
7651 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7652 eassert (IT_STRING_CHARPOS (*it) >= 0);
7653 position = it->current.string_pos;
7654
7655 /* With bidi reordering, the character to display might not be the
7656 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7657 that we were reseat()ed to a new string, whose paragraph
7658 direction is not known. */
7659 if (it->bidi_p && it->bidi_it.first_elt)
7660 {
7661 get_visually_first_element (it);
7662 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7663 }
7664
7665 /* Time to check for invisible text? */
7666 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7667 {
7668 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7669 {
7670 if (!(!it->bidi_p
7671 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7672 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7673 {
7674 /* With bidi non-linear iteration, we could find
7675 ourselves far beyond the last computed stop_charpos,
7676 with several other stop positions in between that we
7677 missed. Scan them all now, in buffer's logical
7678 order, until we find and handle the last stop_charpos
7679 that precedes our current position. */
7680 handle_stop_backwards (it, it->stop_charpos);
7681 return GET_NEXT_DISPLAY_ELEMENT (it);
7682 }
7683 else
7684 {
7685 if (it->bidi_p)
7686 {
7687 /* Take note of the stop position we just moved
7688 across, for when we will move back across it. */
7689 it->prev_stop = it->stop_charpos;
7690 /* If we are at base paragraph embedding level, take
7691 note of the last stop position seen at this
7692 level. */
7693 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7694 it->base_level_stop = it->stop_charpos;
7695 }
7696 handle_stop (it);
7697
7698 /* Since a handler may have changed IT->method, we must
7699 recurse here. */
7700 return GET_NEXT_DISPLAY_ELEMENT (it);
7701 }
7702 }
7703 else if (it->bidi_p
7704 /* If we are before prev_stop, we may have overstepped
7705 on our way backwards a stop_pos, and if so, we need
7706 to handle that stop_pos. */
7707 && IT_STRING_CHARPOS (*it) < it->prev_stop
7708 /* We can sometimes back up for reasons that have nothing
7709 to do with bidi reordering. E.g., compositions. The
7710 code below is only needed when we are above the base
7711 embedding level, so test for that explicitly. */
7712 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7713 {
7714 /* If we lost track of base_level_stop, we have no better
7715 place for handle_stop_backwards to start from than string
7716 beginning. This happens, e.g., when we were reseated to
7717 the previous screenful of text by vertical-motion. */
7718 if (it->base_level_stop <= 0
7719 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7720 it->base_level_stop = 0;
7721 handle_stop_backwards (it, it->base_level_stop);
7722 return GET_NEXT_DISPLAY_ELEMENT (it);
7723 }
7724 }
7725
7726 if (it->current.overlay_string_index >= 0)
7727 {
7728 /* Get the next character from an overlay string. In overlay
7729 strings, there is no field width or padding with spaces to
7730 do. */
7731 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7732 {
7733 it->what = IT_EOB;
7734 return 0;
7735 }
7736 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7737 IT_STRING_BYTEPOS (*it),
7738 it->bidi_it.scan_dir < 0
7739 ? -1
7740 : SCHARS (it->string))
7741 && next_element_from_composition (it))
7742 {
7743 return 1;
7744 }
7745 else if (STRING_MULTIBYTE (it->string))
7746 {
7747 const unsigned char *s = (SDATA (it->string)
7748 + IT_STRING_BYTEPOS (*it));
7749 it->c = string_char_and_length (s, &it->len);
7750 }
7751 else
7752 {
7753 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7754 it->len = 1;
7755 }
7756 }
7757 else
7758 {
7759 /* Get the next character from a Lisp string that is not an
7760 overlay string. Such strings come from the mode line, for
7761 example. We may have to pad with spaces, or truncate the
7762 string. See also next_element_from_c_string. */
7763 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7764 {
7765 it->what = IT_EOB;
7766 return 0;
7767 }
7768 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7769 {
7770 /* Pad with spaces. */
7771 it->c = ' ', it->len = 1;
7772 CHARPOS (position) = BYTEPOS (position) = -1;
7773 }
7774 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7775 IT_STRING_BYTEPOS (*it),
7776 it->bidi_it.scan_dir < 0
7777 ? -1
7778 : it->string_nchars)
7779 && next_element_from_composition (it))
7780 {
7781 return 1;
7782 }
7783 else if (STRING_MULTIBYTE (it->string))
7784 {
7785 const unsigned char *s = (SDATA (it->string)
7786 + IT_STRING_BYTEPOS (*it));
7787 it->c = string_char_and_length (s, &it->len);
7788 }
7789 else
7790 {
7791 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7792 it->len = 1;
7793 }
7794 }
7795
7796 /* Record what we have and where it came from. */
7797 it->what = IT_CHARACTER;
7798 it->object = it->string;
7799 it->position = position;
7800 return 1;
7801 }
7802
7803
7804 /* Load IT with next display element from C string IT->s.
7805 IT->string_nchars is the maximum number of characters to return
7806 from the string. IT->end_charpos may be greater than
7807 IT->string_nchars when this function is called, in which case we
7808 may have to return padding spaces. Value is zero if end of string
7809 reached, including padding spaces. */
7810
7811 static int
7812 next_element_from_c_string (struct it *it)
7813 {
7814 int success_p = 1;
7815
7816 eassert (it->s);
7817 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7818 it->what = IT_CHARACTER;
7819 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7820 it->object = Qnil;
7821
7822 /* With bidi reordering, the character to display might not be the
7823 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7824 we were reseated to a new string, whose paragraph direction is
7825 not known. */
7826 if (it->bidi_p && it->bidi_it.first_elt)
7827 get_visually_first_element (it);
7828
7829 /* IT's position can be greater than IT->string_nchars in case a
7830 field width or precision has been specified when the iterator was
7831 initialized. */
7832 if (IT_CHARPOS (*it) >= it->end_charpos)
7833 {
7834 /* End of the game. */
7835 it->what = IT_EOB;
7836 success_p = 0;
7837 }
7838 else if (IT_CHARPOS (*it) >= it->string_nchars)
7839 {
7840 /* Pad with spaces. */
7841 it->c = ' ', it->len = 1;
7842 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7843 }
7844 else if (it->multibyte_p)
7845 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7846 else
7847 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7848
7849 return success_p;
7850 }
7851
7852
7853 /* Set up IT to return characters from an ellipsis, if appropriate.
7854 The definition of the ellipsis glyphs may come from a display table
7855 entry. This function fills IT with the first glyph from the
7856 ellipsis if an ellipsis is to be displayed. */
7857
7858 static int
7859 next_element_from_ellipsis (struct it *it)
7860 {
7861 if (it->selective_display_ellipsis_p)
7862 setup_for_ellipsis (it, it->len);
7863 else
7864 {
7865 /* The face at the current position may be different from the
7866 face we find after the invisible text. Remember what it
7867 was in IT->saved_face_id, and signal that it's there by
7868 setting face_before_selective_p. */
7869 it->saved_face_id = it->face_id;
7870 it->method = GET_FROM_BUFFER;
7871 it->object = it->w->contents;
7872 reseat_at_next_visible_line_start (it, 1);
7873 it->face_before_selective_p = 1;
7874 }
7875
7876 return GET_NEXT_DISPLAY_ELEMENT (it);
7877 }
7878
7879
7880 /* Deliver an image display element. The iterator IT is already
7881 filled with image information (done in handle_display_prop). Value
7882 is always 1. */
7883
7884
7885 static int
7886 next_element_from_image (struct it *it)
7887 {
7888 it->what = IT_IMAGE;
7889 it->ignore_overlay_strings_at_pos_p = 0;
7890 return 1;
7891 }
7892
7893
7894 /* Fill iterator IT with next display element from a stretch glyph
7895 property. IT->object is the value of the text property. Value is
7896 always 1. */
7897
7898 static int
7899 next_element_from_stretch (struct it *it)
7900 {
7901 it->what = IT_STRETCH;
7902 return 1;
7903 }
7904
7905 /* Scan backwards from IT's current position until we find a stop
7906 position, or until BEGV. This is called when we find ourself
7907 before both the last known prev_stop and base_level_stop while
7908 reordering bidirectional text. */
7909
7910 static void
7911 compute_stop_pos_backwards (struct it *it)
7912 {
7913 const int SCAN_BACK_LIMIT = 1000;
7914 struct text_pos pos;
7915 struct display_pos save_current = it->current;
7916 struct text_pos save_position = it->position;
7917 ptrdiff_t charpos = IT_CHARPOS (*it);
7918 ptrdiff_t where_we_are = charpos;
7919 ptrdiff_t save_stop_pos = it->stop_charpos;
7920 ptrdiff_t save_end_pos = it->end_charpos;
7921
7922 eassert (NILP (it->string) && !it->s);
7923 eassert (it->bidi_p);
7924 it->bidi_p = 0;
7925 do
7926 {
7927 it->end_charpos = min (charpos + 1, ZV);
7928 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7929 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7930 reseat_1 (it, pos, 0);
7931 compute_stop_pos (it);
7932 /* We must advance forward, right? */
7933 if (it->stop_charpos <= charpos)
7934 emacs_abort ();
7935 }
7936 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7937
7938 if (it->stop_charpos <= where_we_are)
7939 it->prev_stop = it->stop_charpos;
7940 else
7941 it->prev_stop = BEGV;
7942 it->bidi_p = 1;
7943 it->current = save_current;
7944 it->position = save_position;
7945 it->stop_charpos = save_stop_pos;
7946 it->end_charpos = save_end_pos;
7947 }
7948
7949 /* Scan forward from CHARPOS in the current buffer/string, until we
7950 find a stop position > current IT's position. Then handle the stop
7951 position before that. This is called when we bump into a stop
7952 position while reordering bidirectional text. CHARPOS should be
7953 the last previously processed stop_pos (or BEGV/0, if none were
7954 processed yet) whose position is less that IT's current
7955 position. */
7956
7957 static void
7958 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7959 {
7960 int bufp = !STRINGP (it->string);
7961 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7962 struct display_pos save_current = it->current;
7963 struct text_pos save_position = it->position;
7964 struct text_pos pos1;
7965 ptrdiff_t next_stop;
7966
7967 /* Scan in strict logical order. */
7968 eassert (it->bidi_p);
7969 it->bidi_p = 0;
7970 do
7971 {
7972 it->prev_stop = charpos;
7973 if (bufp)
7974 {
7975 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7976 reseat_1 (it, pos1, 0);
7977 }
7978 else
7979 it->current.string_pos = string_pos (charpos, it->string);
7980 compute_stop_pos (it);
7981 /* We must advance forward, right? */
7982 if (it->stop_charpos <= it->prev_stop)
7983 emacs_abort ();
7984 charpos = it->stop_charpos;
7985 }
7986 while (charpos <= where_we_are);
7987
7988 it->bidi_p = 1;
7989 it->current = save_current;
7990 it->position = save_position;
7991 next_stop = it->stop_charpos;
7992 it->stop_charpos = it->prev_stop;
7993 handle_stop (it);
7994 it->stop_charpos = next_stop;
7995 }
7996
7997 /* Load IT with the next display element from current_buffer. Value
7998 is zero if end of buffer reached. IT->stop_charpos is the next
7999 position at which to stop and check for text properties or buffer
8000 end. */
8001
8002 static int
8003 next_element_from_buffer (struct it *it)
8004 {
8005 int success_p = 1;
8006
8007 eassert (IT_CHARPOS (*it) >= BEGV);
8008 eassert (NILP (it->string) && !it->s);
8009 eassert (!it->bidi_p
8010 || (EQ (it->bidi_it.string.lstring, Qnil)
8011 && it->bidi_it.string.s == NULL));
8012
8013 /* With bidi reordering, the character to display might not be the
8014 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8015 we were reseat()ed to a new buffer position, which is potentially
8016 a different paragraph. */
8017 if (it->bidi_p && it->bidi_it.first_elt)
8018 {
8019 get_visually_first_element (it);
8020 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8021 }
8022
8023 if (IT_CHARPOS (*it) >= it->stop_charpos)
8024 {
8025 if (IT_CHARPOS (*it) >= it->end_charpos)
8026 {
8027 int overlay_strings_follow_p;
8028
8029 /* End of the game, except when overlay strings follow that
8030 haven't been returned yet. */
8031 if (it->overlay_strings_at_end_processed_p)
8032 overlay_strings_follow_p = 0;
8033 else
8034 {
8035 it->overlay_strings_at_end_processed_p = 1;
8036 overlay_strings_follow_p = get_overlay_strings (it, 0);
8037 }
8038
8039 if (overlay_strings_follow_p)
8040 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8041 else
8042 {
8043 it->what = IT_EOB;
8044 it->position = it->current.pos;
8045 success_p = 0;
8046 }
8047 }
8048 else if (!(!it->bidi_p
8049 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8050 || IT_CHARPOS (*it) == it->stop_charpos))
8051 {
8052 /* With bidi non-linear iteration, we could find ourselves
8053 far beyond the last computed stop_charpos, with several
8054 other stop positions in between that we missed. Scan
8055 them all now, in buffer's logical order, until we find
8056 and handle the last stop_charpos that precedes our
8057 current position. */
8058 handle_stop_backwards (it, it->stop_charpos);
8059 return GET_NEXT_DISPLAY_ELEMENT (it);
8060 }
8061 else
8062 {
8063 if (it->bidi_p)
8064 {
8065 /* Take note of the stop position we just moved across,
8066 for when we will move back across it. */
8067 it->prev_stop = it->stop_charpos;
8068 /* If we are at base paragraph embedding level, take
8069 note of the last stop position seen at this
8070 level. */
8071 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8072 it->base_level_stop = it->stop_charpos;
8073 }
8074 handle_stop (it);
8075 return GET_NEXT_DISPLAY_ELEMENT (it);
8076 }
8077 }
8078 else if (it->bidi_p
8079 /* If we are before prev_stop, we may have overstepped on
8080 our way backwards a stop_pos, and if so, we need to
8081 handle that stop_pos. */
8082 && IT_CHARPOS (*it) < it->prev_stop
8083 /* We can sometimes back up for reasons that have nothing
8084 to do with bidi reordering. E.g., compositions. The
8085 code below is only needed when we are above the base
8086 embedding level, so test for that explicitly. */
8087 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8088 {
8089 if (it->base_level_stop <= 0
8090 || IT_CHARPOS (*it) < it->base_level_stop)
8091 {
8092 /* If we lost track of base_level_stop, we need to find
8093 prev_stop by looking backwards. This happens, e.g., when
8094 we were reseated to the previous screenful of text by
8095 vertical-motion. */
8096 it->base_level_stop = BEGV;
8097 compute_stop_pos_backwards (it);
8098 handle_stop_backwards (it, it->prev_stop);
8099 }
8100 else
8101 handle_stop_backwards (it, it->base_level_stop);
8102 return GET_NEXT_DISPLAY_ELEMENT (it);
8103 }
8104 else
8105 {
8106 /* No face changes, overlays etc. in sight, so just return a
8107 character from current_buffer. */
8108 unsigned char *p;
8109 ptrdiff_t stop;
8110
8111 /* Maybe run the redisplay end trigger hook. Performance note:
8112 This doesn't seem to cost measurable time. */
8113 if (it->redisplay_end_trigger_charpos
8114 && it->glyph_row
8115 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8116 run_redisplay_end_trigger_hook (it);
8117
8118 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8119 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8120 stop)
8121 && next_element_from_composition (it))
8122 {
8123 return 1;
8124 }
8125
8126 /* Get the next character, maybe multibyte. */
8127 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8128 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8129 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8130 else
8131 it->c = *p, it->len = 1;
8132
8133 /* Record what we have and where it came from. */
8134 it->what = IT_CHARACTER;
8135 it->object = it->w->contents;
8136 it->position = it->current.pos;
8137
8138 /* Normally we return the character found above, except when we
8139 really want to return an ellipsis for selective display. */
8140 if (it->selective)
8141 {
8142 if (it->c == '\n')
8143 {
8144 /* A value of selective > 0 means hide lines indented more
8145 than that number of columns. */
8146 if (it->selective > 0
8147 && IT_CHARPOS (*it) + 1 < ZV
8148 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8149 IT_BYTEPOS (*it) + 1,
8150 it->selective))
8151 {
8152 success_p = next_element_from_ellipsis (it);
8153 it->dpvec_char_len = -1;
8154 }
8155 }
8156 else if (it->c == '\r' && it->selective == -1)
8157 {
8158 /* A value of selective == -1 means that everything from the
8159 CR to the end of the line is invisible, with maybe an
8160 ellipsis displayed for it. */
8161 success_p = next_element_from_ellipsis (it);
8162 it->dpvec_char_len = -1;
8163 }
8164 }
8165 }
8166
8167 /* Value is zero if end of buffer reached. */
8168 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8169 return success_p;
8170 }
8171
8172
8173 /* Run the redisplay end trigger hook for IT. */
8174
8175 static void
8176 run_redisplay_end_trigger_hook (struct it *it)
8177 {
8178 Lisp_Object args[3];
8179
8180 /* IT->glyph_row should be non-null, i.e. we should be actually
8181 displaying something, or otherwise we should not run the hook. */
8182 eassert (it->glyph_row);
8183
8184 /* Set up hook arguments. */
8185 args[0] = Qredisplay_end_trigger_functions;
8186 args[1] = it->window;
8187 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8188 it->redisplay_end_trigger_charpos = 0;
8189
8190 /* Since we are *trying* to run these functions, don't try to run
8191 them again, even if they get an error. */
8192 wset_redisplay_end_trigger (it->w, Qnil);
8193 Frun_hook_with_args (3, args);
8194
8195 /* Notice if it changed the face of the character we are on. */
8196 handle_face_prop (it);
8197 }
8198
8199
8200 /* Deliver a composition display element. Unlike the other
8201 next_element_from_XXX, this function is not registered in the array
8202 get_next_element[]. It is called from next_element_from_buffer and
8203 next_element_from_string when necessary. */
8204
8205 static int
8206 next_element_from_composition (struct it *it)
8207 {
8208 it->what = IT_COMPOSITION;
8209 it->len = it->cmp_it.nbytes;
8210 if (STRINGP (it->string))
8211 {
8212 if (it->c < 0)
8213 {
8214 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8215 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8216 return 0;
8217 }
8218 it->position = it->current.string_pos;
8219 it->object = it->string;
8220 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8221 IT_STRING_BYTEPOS (*it), it->string);
8222 }
8223 else
8224 {
8225 if (it->c < 0)
8226 {
8227 IT_CHARPOS (*it) += it->cmp_it.nchars;
8228 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8229 if (it->bidi_p)
8230 {
8231 if (it->bidi_it.new_paragraph)
8232 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8233 /* Resync the bidi iterator with IT's new position.
8234 FIXME: this doesn't support bidirectional text. */
8235 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8236 bidi_move_to_visually_next (&it->bidi_it);
8237 }
8238 return 0;
8239 }
8240 it->position = it->current.pos;
8241 it->object = it->w->contents;
8242 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8243 IT_BYTEPOS (*it), Qnil);
8244 }
8245 return 1;
8246 }
8247
8248
8249 \f
8250 /***********************************************************************
8251 Moving an iterator without producing glyphs
8252 ***********************************************************************/
8253
8254 /* Check if iterator is at a position corresponding to a valid buffer
8255 position after some move_it_ call. */
8256
8257 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8258 ((it)->method == GET_FROM_STRING \
8259 ? IT_STRING_CHARPOS (*it) == 0 \
8260 : 1)
8261
8262
8263 /* Move iterator IT to a specified buffer or X position within one
8264 line on the display without producing glyphs.
8265
8266 OP should be a bit mask including some or all of these bits:
8267 MOVE_TO_X: Stop upon reaching x-position TO_X.
8268 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8269 Regardless of OP's value, stop upon reaching the end of the display line.
8270
8271 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8272 This means, in particular, that TO_X includes window's horizontal
8273 scroll amount.
8274
8275 The return value has several possible values that
8276 say what condition caused the scan to stop:
8277
8278 MOVE_POS_MATCH_OR_ZV
8279 - when TO_POS or ZV was reached.
8280
8281 MOVE_X_REACHED
8282 -when TO_X was reached before TO_POS or ZV were reached.
8283
8284 MOVE_LINE_CONTINUED
8285 - when we reached the end of the display area and the line must
8286 be continued.
8287
8288 MOVE_LINE_TRUNCATED
8289 - when we reached the end of the display area and the line is
8290 truncated.
8291
8292 MOVE_NEWLINE_OR_CR
8293 - when we stopped at a line end, i.e. a newline or a CR and selective
8294 display is on. */
8295
8296 static enum move_it_result
8297 move_it_in_display_line_to (struct it *it,
8298 ptrdiff_t to_charpos, int to_x,
8299 enum move_operation_enum op)
8300 {
8301 enum move_it_result result = MOVE_UNDEFINED;
8302 struct glyph_row *saved_glyph_row;
8303 struct it wrap_it, atpos_it, atx_it, ppos_it;
8304 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8305 void *ppos_data = NULL;
8306 int may_wrap = 0;
8307 enum it_method prev_method = it->method;
8308 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8309 int saw_smaller_pos = prev_pos < to_charpos;
8310
8311 /* Don't produce glyphs in produce_glyphs. */
8312 saved_glyph_row = it->glyph_row;
8313 it->glyph_row = NULL;
8314
8315 /* Use wrap_it to save a copy of IT wherever a word wrap could
8316 occur. Use atpos_it to save a copy of IT at the desired buffer
8317 position, if found, so that we can scan ahead and check if the
8318 word later overshoots the window edge. Use atx_it similarly, for
8319 pixel positions. */
8320 wrap_it.sp = -1;
8321 atpos_it.sp = -1;
8322 atx_it.sp = -1;
8323
8324 /* Use ppos_it under bidi reordering to save a copy of IT for the
8325 position > CHARPOS that is the closest to CHARPOS. We restore
8326 that position in IT when we have scanned the entire display line
8327 without finding a match for CHARPOS and all the character
8328 positions are greater than CHARPOS. */
8329 if (it->bidi_p)
8330 {
8331 SAVE_IT (ppos_it, *it, ppos_data);
8332 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8333 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8334 SAVE_IT (ppos_it, *it, ppos_data);
8335 }
8336
8337 #define BUFFER_POS_REACHED_P() \
8338 ((op & MOVE_TO_POS) != 0 \
8339 && BUFFERP (it->object) \
8340 && (IT_CHARPOS (*it) == to_charpos \
8341 || ((!it->bidi_p \
8342 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8343 && IT_CHARPOS (*it) > to_charpos) \
8344 || (it->what == IT_COMPOSITION \
8345 && ((IT_CHARPOS (*it) > to_charpos \
8346 && to_charpos >= it->cmp_it.charpos) \
8347 || (IT_CHARPOS (*it) < to_charpos \
8348 && to_charpos <= it->cmp_it.charpos)))) \
8349 && (it->method == GET_FROM_BUFFER \
8350 || (it->method == GET_FROM_DISPLAY_VECTOR \
8351 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8352
8353 /* If there's a line-/wrap-prefix, handle it. */
8354 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8355 && it->current_y < it->last_visible_y)
8356 handle_line_prefix (it);
8357
8358 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8359 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8360
8361 while (1)
8362 {
8363 int x, i, ascent = 0, descent = 0;
8364
8365 /* Utility macro to reset an iterator with x, ascent, and descent. */
8366 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8367 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8368 (IT)->max_descent = descent)
8369
8370 /* Stop if we move beyond TO_CHARPOS (after an image or a
8371 display string or stretch glyph). */
8372 if ((op & MOVE_TO_POS) != 0
8373 && BUFFERP (it->object)
8374 && it->method == GET_FROM_BUFFER
8375 && (((!it->bidi_p
8376 /* When the iterator is at base embedding level, we
8377 are guaranteed that characters are delivered for
8378 display in strictly increasing order of their
8379 buffer positions. */
8380 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8381 && IT_CHARPOS (*it) > to_charpos)
8382 || (it->bidi_p
8383 && (prev_method == GET_FROM_IMAGE
8384 || prev_method == GET_FROM_STRETCH
8385 || prev_method == GET_FROM_STRING)
8386 /* Passed TO_CHARPOS from left to right. */
8387 && ((prev_pos < to_charpos
8388 && IT_CHARPOS (*it) > to_charpos)
8389 /* Passed TO_CHARPOS from right to left. */
8390 || (prev_pos > to_charpos
8391 && IT_CHARPOS (*it) < to_charpos)))))
8392 {
8393 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8394 {
8395 result = MOVE_POS_MATCH_OR_ZV;
8396 break;
8397 }
8398 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8399 /* If wrap_it is valid, the current position might be in a
8400 word that is wrapped. So, save the iterator in
8401 atpos_it and continue to see if wrapping happens. */
8402 SAVE_IT (atpos_it, *it, atpos_data);
8403 }
8404
8405 /* Stop when ZV reached.
8406 We used to stop here when TO_CHARPOS reached as well, but that is
8407 too soon if this glyph does not fit on this line. So we handle it
8408 explicitly below. */
8409 if (!get_next_display_element (it))
8410 {
8411 result = MOVE_POS_MATCH_OR_ZV;
8412 break;
8413 }
8414
8415 if (it->line_wrap == TRUNCATE)
8416 {
8417 if (BUFFER_POS_REACHED_P ())
8418 {
8419 result = MOVE_POS_MATCH_OR_ZV;
8420 break;
8421 }
8422 }
8423 else
8424 {
8425 if (it->line_wrap == WORD_WRAP)
8426 {
8427 if (IT_DISPLAYING_WHITESPACE (it))
8428 may_wrap = 1;
8429 else if (may_wrap)
8430 {
8431 /* We have reached a glyph that follows one or more
8432 whitespace characters. If the position is
8433 already found, we are done. */
8434 if (atpos_it.sp >= 0)
8435 {
8436 RESTORE_IT (it, &atpos_it, atpos_data);
8437 result = MOVE_POS_MATCH_OR_ZV;
8438 goto done;
8439 }
8440 if (atx_it.sp >= 0)
8441 {
8442 RESTORE_IT (it, &atx_it, atx_data);
8443 result = MOVE_X_REACHED;
8444 goto done;
8445 }
8446 /* Otherwise, we can wrap here. */
8447 SAVE_IT (wrap_it, *it, wrap_data);
8448 may_wrap = 0;
8449 }
8450 }
8451 }
8452
8453 /* Remember the line height for the current line, in case
8454 the next element doesn't fit on the line. */
8455 ascent = it->max_ascent;
8456 descent = it->max_descent;
8457
8458 /* The call to produce_glyphs will get the metrics of the
8459 display element IT is loaded with. Record the x-position
8460 before this display element, in case it doesn't fit on the
8461 line. */
8462 x = it->current_x;
8463
8464 PRODUCE_GLYPHS (it);
8465
8466 if (it->area != TEXT_AREA)
8467 {
8468 prev_method = it->method;
8469 if (it->method == GET_FROM_BUFFER)
8470 prev_pos = IT_CHARPOS (*it);
8471 set_iterator_to_next (it, 1);
8472 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8473 SET_TEXT_POS (this_line_min_pos,
8474 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8475 if (it->bidi_p
8476 && (op & MOVE_TO_POS)
8477 && IT_CHARPOS (*it) > to_charpos
8478 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8479 SAVE_IT (ppos_it, *it, ppos_data);
8480 continue;
8481 }
8482
8483 /* The number of glyphs we get back in IT->nglyphs will normally
8484 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8485 character on a terminal frame, or (iii) a line end. For the
8486 second case, IT->nglyphs - 1 padding glyphs will be present.
8487 (On X frames, there is only one glyph produced for a
8488 composite character.)
8489
8490 The behavior implemented below means, for continuation lines,
8491 that as many spaces of a TAB as fit on the current line are
8492 displayed there. For terminal frames, as many glyphs of a
8493 multi-glyph character are displayed in the current line, too.
8494 This is what the old redisplay code did, and we keep it that
8495 way. Under X, the whole shape of a complex character must
8496 fit on the line or it will be completely displayed in the
8497 next line.
8498
8499 Note that both for tabs and padding glyphs, all glyphs have
8500 the same width. */
8501 if (it->nglyphs)
8502 {
8503 /* More than one glyph or glyph doesn't fit on line. All
8504 glyphs have the same width. */
8505 int single_glyph_width = it->pixel_width / it->nglyphs;
8506 int new_x;
8507 int x_before_this_char = x;
8508 int hpos_before_this_char = it->hpos;
8509
8510 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8511 {
8512 new_x = x + single_glyph_width;
8513
8514 /* We want to leave anything reaching TO_X to the caller. */
8515 if ((op & MOVE_TO_X) && new_x > to_x)
8516 {
8517 if (BUFFER_POS_REACHED_P ())
8518 {
8519 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8520 goto buffer_pos_reached;
8521 if (atpos_it.sp < 0)
8522 {
8523 SAVE_IT (atpos_it, *it, atpos_data);
8524 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8525 }
8526 }
8527 else
8528 {
8529 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8530 {
8531 it->current_x = x;
8532 result = MOVE_X_REACHED;
8533 break;
8534 }
8535 if (atx_it.sp < 0)
8536 {
8537 SAVE_IT (atx_it, *it, atx_data);
8538 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8539 }
8540 }
8541 }
8542
8543 if (/* Lines are continued. */
8544 it->line_wrap != TRUNCATE
8545 && (/* And glyph doesn't fit on the line. */
8546 new_x > it->last_visible_x
8547 /* Or it fits exactly and we're on a window
8548 system frame. */
8549 || (new_x == it->last_visible_x
8550 && FRAME_WINDOW_P (it->f)
8551 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8552 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8553 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8554 {
8555 if (/* IT->hpos == 0 means the very first glyph
8556 doesn't fit on the line, e.g. a wide image. */
8557 it->hpos == 0
8558 || (new_x == it->last_visible_x
8559 && FRAME_WINDOW_P (it->f)))
8560 {
8561 ++it->hpos;
8562 it->current_x = new_x;
8563
8564 /* The character's last glyph just barely fits
8565 in this row. */
8566 if (i == it->nglyphs - 1)
8567 {
8568 /* If this is the destination position,
8569 return a position *before* it in this row,
8570 now that we know it fits in this row. */
8571 if (BUFFER_POS_REACHED_P ())
8572 {
8573 if (it->line_wrap != WORD_WRAP
8574 || wrap_it.sp < 0)
8575 {
8576 it->hpos = hpos_before_this_char;
8577 it->current_x = x_before_this_char;
8578 result = MOVE_POS_MATCH_OR_ZV;
8579 break;
8580 }
8581 if (it->line_wrap == WORD_WRAP
8582 && atpos_it.sp < 0)
8583 {
8584 SAVE_IT (atpos_it, *it, atpos_data);
8585 atpos_it.current_x = x_before_this_char;
8586 atpos_it.hpos = hpos_before_this_char;
8587 }
8588 }
8589
8590 prev_method = it->method;
8591 if (it->method == GET_FROM_BUFFER)
8592 prev_pos = IT_CHARPOS (*it);
8593 set_iterator_to_next (it, 1);
8594 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8595 SET_TEXT_POS (this_line_min_pos,
8596 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8597 /* On graphical terminals, newlines may
8598 "overflow" into the fringe if
8599 overflow-newline-into-fringe is non-nil.
8600 On text terminals, and on graphical
8601 terminals with no right margin, newlines
8602 may overflow into the last glyph on the
8603 display line.*/
8604 if (!FRAME_WINDOW_P (it->f)
8605 || ((it->bidi_p
8606 && it->bidi_it.paragraph_dir == R2L)
8607 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8608 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8609 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8610 {
8611 if (!get_next_display_element (it))
8612 {
8613 result = MOVE_POS_MATCH_OR_ZV;
8614 break;
8615 }
8616 if (BUFFER_POS_REACHED_P ())
8617 {
8618 if (ITERATOR_AT_END_OF_LINE_P (it))
8619 result = MOVE_POS_MATCH_OR_ZV;
8620 else
8621 result = MOVE_LINE_CONTINUED;
8622 break;
8623 }
8624 if (ITERATOR_AT_END_OF_LINE_P (it)
8625 && (it->line_wrap != WORD_WRAP
8626 || wrap_it.sp < 0))
8627 {
8628 result = MOVE_NEWLINE_OR_CR;
8629 break;
8630 }
8631 }
8632 }
8633 }
8634 else
8635 IT_RESET_X_ASCENT_DESCENT (it);
8636
8637 if (wrap_it.sp >= 0)
8638 {
8639 RESTORE_IT (it, &wrap_it, wrap_data);
8640 atpos_it.sp = -1;
8641 atx_it.sp = -1;
8642 }
8643
8644 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8645 IT_CHARPOS (*it)));
8646 result = MOVE_LINE_CONTINUED;
8647 break;
8648 }
8649
8650 if (BUFFER_POS_REACHED_P ())
8651 {
8652 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8653 goto buffer_pos_reached;
8654 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8655 {
8656 SAVE_IT (atpos_it, *it, atpos_data);
8657 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8658 }
8659 }
8660
8661 if (new_x > it->first_visible_x)
8662 {
8663 /* Glyph is visible. Increment number of glyphs that
8664 would be displayed. */
8665 ++it->hpos;
8666 }
8667 }
8668
8669 if (result != MOVE_UNDEFINED)
8670 break;
8671 }
8672 else if (BUFFER_POS_REACHED_P ())
8673 {
8674 buffer_pos_reached:
8675 IT_RESET_X_ASCENT_DESCENT (it);
8676 result = MOVE_POS_MATCH_OR_ZV;
8677 break;
8678 }
8679 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8680 {
8681 /* Stop when TO_X specified and reached. This check is
8682 necessary here because of lines consisting of a line end,
8683 only. The line end will not produce any glyphs and we
8684 would never get MOVE_X_REACHED. */
8685 eassert (it->nglyphs == 0);
8686 result = MOVE_X_REACHED;
8687 break;
8688 }
8689
8690 /* Is this a line end? If yes, we're done. */
8691 if (ITERATOR_AT_END_OF_LINE_P (it))
8692 {
8693 /* If we are past TO_CHARPOS, but never saw any character
8694 positions smaller than TO_CHARPOS, return
8695 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8696 did. */
8697 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8698 {
8699 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8700 {
8701 if (IT_CHARPOS (ppos_it) < ZV)
8702 {
8703 RESTORE_IT (it, &ppos_it, ppos_data);
8704 result = MOVE_POS_MATCH_OR_ZV;
8705 }
8706 else
8707 goto buffer_pos_reached;
8708 }
8709 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8710 && IT_CHARPOS (*it) > to_charpos)
8711 goto buffer_pos_reached;
8712 else
8713 result = MOVE_NEWLINE_OR_CR;
8714 }
8715 else
8716 result = MOVE_NEWLINE_OR_CR;
8717 break;
8718 }
8719
8720 prev_method = it->method;
8721 if (it->method == GET_FROM_BUFFER)
8722 prev_pos = IT_CHARPOS (*it);
8723 /* The current display element has been consumed. Advance
8724 to the next. */
8725 set_iterator_to_next (it, 1);
8726 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8727 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8728 if (IT_CHARPOS (*it) < to_charpos)
8729 saw_smaller_pos = 1;
8730 if (it->bidi_p
8731 && (op & MOVE_TO_POS)
8732 && IT_CHARPOS (*it) >= to_charpos
8733 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8734 SAVE_IT (ppos_it, *it, ppos_data);
8735
8736 /* Stop if lines are truncated and IT's current x-position is
8737 past the right edge of the window now. */
8738 if (it->line_wrap == TRUNCATE
8739 && it->current_x >= it->last_visible_x)
8740 {
8741 if (!FRAME_WINDOW_P (it->f)
8742 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8743 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8744 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8745 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8746 {
8747 int at_eob_p = 0;
8748
8749 if ((at_eob_p = !get_next_display_element (it))
8750 || BUFFER_POS_REACHED_P ()
8751 /* If we are past TO_CHARPOS, but never saw any
8752 character positions smaller than TO_CHARPOS,
8753 return MOVE_POS_MATCH_OR_ZV, like the
8754 unidirectional display did. */
8755 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8756 && !saw_smaller_pos
8757 && IT_CHARPOS (*it) > to_charpos))
8758 {
8759 if (it->bidi_p
8760 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8761 RESTORE_IT (it, &ppos_it, ppos_data);
8762 result = MOVE_POS_MATCH_OR_ZV;
8763 break;
8764 }
8765 if (ITERATOR_AT_END_OF_LINE_P (it))
8766 {
8767 result = MOVE_NEWLINE_OR_CR;
8768 break;
8769 }
8770 }
8771 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8772 && !saw_smaller_pos
8773 && IT_CHARPOS (*it) > to_charpos)
8774 {
8775 if (IT_CHARPOS (ppos_it) < ZV)
8776 RESTORE_IT (it, &ppos_it, ppos_data);
8777 result = MOVE_POS_MATCH_OR_ZV;
8778 break;
8779 }
8780 result = MOVE_LINE_TRUNCATED;
8781 break;
8782 }
8783 #undef IT_RESET_X_ASCENT_DESCENT
8784 }
8785
8786 #undef BUFFER_POS_REACHED_P
8787
8788 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8789 restore the saved iterator. */
8790 if (atpos_it.sp >= 0)
8791 RESTORE_IT (it, &atpos_it, atpos_data);
8792 else if (atx_it.sp >= 0)
8793 RESTORE_IT (it, &atx_it, atx_data);
8794
8795 done:
8796
8797 if (atpos_data)
8798 bidi_unshelve_cache (atpos_data, 1);
8799 if (atx_data)
8800 bidi_unshelve_cache (atx_data, 1);
8801 if (wrap_data)
8802 bidi_unshelve_cache (wrap_data, 1);
8803 if (ppos_data)
8804 bidi_unshelve_cache (ppos_data, 1);
8805
8806 /* Restore the iterator settings altered at the beginning of this
8807 function. */
8808 it->glyph_row = saved_glyph_row;
8809 return result;
8810 }
8811
8812 /* For external use. */
8813 void
8814 move_it_in_display_line (struct it *it,
8815 ptrdiff_t to_charpos, int to_x,
8816 enum move_operation_enum op)
8817 {
8818 if (it->line_wrap == WORD_WRAP
8819 && (op & MOVE_TO_X))
8820 {
8821 struct it save_it;
8822 void *save_data = NULL;
8823 int skip;
8824
8825 SAVE_IT (save_it, *it, save_data);
8826 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8827 /* When word-wrap is on, TO_X may lie past the end
8828 of a wrapped line. Then it->current is the
8829 character on the next line, so backtrack to the
8830 space before the wrap point. */
8831 if (skip == MOVE_LINE_CONTINUED)
8832 {
8833 int prev_x = max (it->current_x - 1, 0);
8834 RESTORE_IT (it, &save_it, save_data);
8835 move_it_in_display_line_to
8836 (it, -1, prev_x, MOVE_TO_X);
8837 }
8838 else
8839 bidi_unshelve_cache (save_data, 1);
8840 }
8841 else
8842 move_it_in_display_line_to (it, to_charpos, to_x, op);
8843 }
8844
8845
8846 /* Move IT forward until it satisfies one or more of the criteria in
8847 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8848
8849 OP is a bit-mask that specifies where to stop, and in particular,
8850 which of those four position arguments makes a difference. See the
8851 description of enum move_operation_enum.
8852
8853 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8854 screen line, this function will set IT to the next position that is
8855 displayed to the right of TO_CHARPOS on the screen. */
8856
8857 void
8858 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8859 {
8860 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8861 int line_height, line_start_x = 0, reached = 0;
8862 void *backup_data = NULL;
8863
8864 for (;;)
8865 {
8866 if (op & MOVE_TO_VPOS)
8867 {
8868 /* If no TO_CHARPOS and no TO_X specified, stop at the
8869 start of the line TO_VPOS. */
8870 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8871 {
8872 if (it->vpos == to_vpos)
8873 {
8874 reached = 1;
8875 break;
8876 }
8877 else
8878 skip = move_it_in_display_line_to (it, -1, -1, 0);
8879 }
8880 else
8881 {
8882 /* TO_VPOS >= 0 means stop at TO_X in the line at
8883 TO_VPOS, or at TO_POS, whichever comes first. */
8884 if (it->vpos == to_vpos)
8885 {
8886 reached = 2;
8887 break;
8888 }
8889
8890 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8891
8892 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8893 {
8894 reached = 3;
8895 break;
8896 }
8897 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8898 {
8899 /* We have reached TO_X but not in the line we want. */
8900 skip = move_it_in_display_line_to (it, to_charpos,
8901 -1, MOVE_TO_POS);
8902 if (skip == MOVE_POS_MATCH_OR_ZV)
8903 {
8904 reached = 4;
8905 break;
8906 }
8907 }
8908 }
8909 }
8910 else if (op & MOVE_TO_Y)
8911 {
8912 struct it it_backup;
8913
8914 if (it->line_wrap == WORD_WRAP)
8915 SAVE_IT (it_backup, *it, backup_data);
8916
8917 /* TO_Y specified means stop at TO_X in the line containing
8918 TO_Y---or at TO_CHARPOS if this is reached first. The
8919 problem is that we can't really tell whether the line
8920 contains TO_Y before we have completely scanned it, and
8921 this may skip past TO_X. What we do is to first scan to
8922 TO_X.
8923
8924 If TO_X is not specified, use a TO_X of zero. The reason
8925 is to make the outcome of this function more predictable.
8926 If we didn't use TO_X == 0, we would stop at the end of
8927 the line which is probably not what a caller would expect
8928 to happen. */
8929 skip = move_it_in_display_line_to
8930 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8931 (MOVE_TO_X | (op & MOVE_TO_POS)));
8932
8933 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8934 if (skip == MOVE_POS_MATCH_OR_ZV)
8935 reached = 5;
8936 else if (skip == MOVE_X_REACHED)
8937 {
8938 /* If TO_X was reached, we want to know whether TO_Y is
8939 in the line. We know this is the case if the already
8940 scanned glyphs make the line tall enough. Otherwise,
8941 we must check by scanning the rest of the line. */
8942 line_height = it->max_ascent + it->max_descent;
8943 if (to_y >= it->current_y
8944 && to_y < it->current_y + line_height)
8945 {
8946 reached = 6;
8947 break;
8948 }
8949 SAVE_IT (it_backup, *it, backup_data);
8950 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8951 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8952 op & MOVE_TO_POS);
8953 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8954 line_height = it->max_ascent + it->max_descent;
8955 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8956
8957 if (to_y >= it->current_y
8958 && to_y < it->current_y + line_height)
8959 {
8960 /* If TO_Y is in this line and TO_X was reached
8961 above, we scanned too far. We have to restore
8962 IT's settings to the ones before skipping. But
8963 keep the more accurate values of max_ascent and
8964 max_descent we've found while skipping the rest
8965 of the line, for the sake of callers, such as
8966 pos_visible_p, that need to know the line
8967 height. */
8968 int max_ascent = it->max_ascent;
8969 int max_descent = it->max_descent;
8970
8971 RESTORE_IT (it, &it_backup, backup_data);
8972 it->max_ascent = max_ascent;
8973 it->max_descent = max_descent;
8974 reached = 6;
8975 }
8976 else
8977 {
8978 skip = skip2;
8979 if (skip == MOVE_POS_MATCH_OR_ZV)
8980 reached = 7;
8981 }
8982 }
8983 else
8984 {
8985 /* Check whether TO_Y is in this line. */
8986 line_height = it->max_ascent + it->max_descent;
8987 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8988
8989 if (to_y >= it->current_y
8990 && to_y < it->current_y + line_height)
8991 {
8992 /* When word-wrap is on, TO_X may lie past the end
8993 of a wrapped line. Then it->current is the
8994 character on the next line, so backtrack to the
8995 space before the wrap point. */
8996 if (skip == MOVE_LINE_CONTINUED
8997 && it->line_wrap == WORD_WRAP)
8998 {
8999 int prev_x = max (it->current_x - 1, 0);
9000 RESTORE_IT (it, &it_backup, backup_data);
9001 skip = move_it_in_display_line_to
9002 (it, -1, prev_x, MOVE_TO_X);
9003 }
9004 reached = 6;
9005 }
9006 }
9007
9008 if (reached)
9009 break;
9010 }
9011 else if (BUFFERP (it->object)
9012 && (it->method == GET_FROM_BUFFER
9013 || it->method == GET_FROM_STRETCH)
9014 && IT_CHARPOS (*it) >= to_charpos
9015 /* Under bidi iteration, a call to set_iterator_to_next
9016 can scan far beyond to_charpos if the initial
9017 portion of the next line needs to be reordered. In
9018 that case, give move_it_in_display_line_to another
9019 chance below. */
9020 && !(it->bidi_p
9021 && it->bidi_it.scan_dir == -1))
9022 skip = MOVE_POS_MATCH_OR_ZV;
9023 else
9024 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9025
9026 switch (skip)
9027 {
9028 case MOVE_POS_MATCH_OR_ZV:
9029 reached = 8;
9030 goto out;
9031
9032 case MOVE_NEWLINE_OR_CR:
9033 set_iterator_to_next (it, 1);
9034 it->continuation_lines_width = 0;
9035 break;
9036
9037 case MOVE_LINE_TRUNCATED:
9038 it->continuation_lines_width = 0;
9039 reseat_at_next_visible_line_start (it, 0);
9040 if ((op & MOVE_TO_POS) != 0
9041 && IT_CHARPOS (*it) > to_charpos)
9042 {
9043 reached = 9;
9044 goto out;
9045 }
9046 break;
9047
9048 case MOVE_LINE_CONTINUED:
9049 /* For continued lines ending in a tab, some of the glyphs
9050 associated with the tab are displayed on the current
9051 line. Since it->current_x does not include these glyphs,
9052 we use it->last_visible_x instead. */
9053 if (it->c == '\t')
9054 {
9055 it->continuation_lines_width += it->last_visible_x;
9056 /* When moving by vpos, ensure that the iterator really
9057 advances to the next line (bug#847, bug#969). Fixme:
9058 do we need to do this in other circumstances? */
9059 if (it->current_x != it->last_visible_x
9060 && (op & MOVE_TO_VPOS)
9061 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9062 {
9063 line_start_x = it->current_x + it->pixel_width
9064 - it->last_visible_x;
9065 set_iterator_to_next (it, 0);
9066 }
9067 }
9068 else
9069 it->continuation_lines_width += it->current_x;
9070 break;
9071
9072 default:
9073 emacs_abort ();
9074 }
9075
9076 /* Reset/increment for the next run. */
9077 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9078 it->current_x = line_start_x;
9079 line_start_x = 0;
9080 it->hpos = 0;
9081 it->current_y += it->max_ascent + it->max_descent;
9082 ++it->vpos;
9083 last_height = it->max_ascent + it->max_descent;
9084 it->max_ascent = it->max_descent = 0;
9085 }
9086
9087 out:
9088
9089 /* On text terminals, we may stop at the end of a line in the middle
9090 of a multi-character glyph. If the glyph itself is continued,
9091 i.e. it is actually displayed on the next line, don't treat this
9092 stopping point as valid; move to the next line instead (unless
9093 that brings us offscreen). */
9094 if (!FRAME_WINDOW_P (it->f)
9095 && op & MOVE_TO_POS
9096 && IT_CHARPOS (*it) == to_charpos
9097 && it->what == IT_CHARACTER
9098 && it->nglyphs > 1
9099 && it->line_wrap == WINDOW_WRAP
9100 && it->current_x == it->last_visible_x - 1
9101 && it->c != '\n'
9102 && it->c != '\t'
9103 && it->vpos < it->w->window_end_vpos)
9104 {
9105 it->continuation_lines_width += it->current_x;
9106 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9107 it->current_y += it->max_ascent + it->max_descent;
9108 ++it->vpos;
9109 last_height = it->max_ascent + it->max_descent;
9110 }
9111
9112 if (backup_data)
9113 bidi_unshelve_cache (backup_data, 1);
9114
9115 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9116 }
9117
9118
9119 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9120
9121 If DY > 0, move IT backward at least that many pixels. DY = 0
9122 means move IT backward to the preceding line start or BEGV. This
9123 function may move over more than DY pixels if IT->current_y - DY
9124 ends up in the middle of a line; in this case IT->current_y will be
9125 set to the top of the line moved to. */
9126
9127 void
9128 move_it_vertically_backward (struct it *it, int dy)
9129 {
9130 int nlines, h;
9131 struct it it2, it3;
9132 void *it2data = NULL, *it3data = NULL;
9133 ptrdiff_t start_pos;
9134 int nchars_per_row
9135 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9136 ptrdiff_t pos_limit;
9137
9138 move_further_back:
9139 eassert (dy >= 0);
9140
9141 start_pos = IT_CHARPOS (*it);
9142
9143 /* Estimate how many newlines we must move back. */
9144 nlines = max (1, dy / default_line_pixel_height (it->w));
9145 if (it->line_wrap == TRUNCATE)
9146 pos_limit = BEGV;
9147 else
9148 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9149
9150 /* Set the iterator's position that many lines back. But don't go
9151 back more than NLINES full screen lines -- this wins a day with
9152 buffers which have very long lines. */
9153 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9154 back_to_previous_visible_line_start (it);
9155
9156 /* Reseat the iterator here. When moving backward, we don't want
9157 reseat to skip forward over invisible text, set up the iterator
9158 to deliver from overlay strings at the new position etc. So,
9159 use reseat_1 here. */
9160 reseat_1 (it, it->current.pos, 1);
9161
9162 /* We are now surely at a line start. */
9163 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9164 reordering is in effect. */
9165 it->continuation_lines_width = 0;
9166
9167 /* Move forward and see what y-distance we moved. First move to the
9168 start of the next line so that we get its height. We need this
9169 height to be able to tell whether we reached the specified
9170 y-distance. */
9171 SAVE_IT (it2, *it, it2data);
9172 it2.max_ascent = it2.max_descent = 0;
9173 do
9174 {
9175 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9176 MOVE_TO_POS | MOVE_TO_VPOS);
9177 }
9178 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9179 /* If we are in a display string which starts at START_POS,
9180 and that display string includes a newline, and we are
9181 right after that newline (i.e. at the beginning of a
9182 display line), exit the loop, because otherwise we will
9183 infloop, since move_it_to will see that it is already at
9184 START_POS and will not move. */
9185 || (it2.method == GET_FROM_STRING
9186 && IT_CHARPOS (it2) == start_pos
9187 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9188 eassert (IT_CHARPOS (*it) >= BEGV);
9189 SAVE_IT (it3, it2, it3data);
9190
9191 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9192 eassert (IT_CHARPOS (*it) >= BEGV);
9193 /* H is the actual vertical distance from the position in *IT
9194 and the starting position. */
9195 h = it2.current_y - it->current_y;
9196 /* NLINES is the distance in number of lines. */
9197 nlines = it2.vpos - it->vpos;
9198
9199 /* Correct IT's y and vpos position
9200 so that they are relative to the starting point. */
9201 it->vpos -= nlines;
9202 it->current_y -= h;
9203
9204 if (dy == 0)
9205 {
9206 /* DY == 0 means move to the start of the screen line. The
9207 value of nlines is > 0 if continuation lines were involved,
9208 or if the original IT position was at start of a line. */
9209 RESTORE_IT (it, it, it2data);
9210 if (nlines > 0)
9211 move_it_by_lines (it, nlines);
9212 /* The above code moves us to some position NLINES down,
9213 usually to its first glyph (leftmost in an L2R line), but
9214 that's not necessarily the start of the line, under bidi
9215 reordering. We want to get to the character position
9216 that is immediately after the newline of the previous
9217 line. */
9218 if (it->bidi_p
9219 && !it->continuation_lines_width
9220 && !STRINGP (it->string)
9221 && IT_CHARPOS (*it) > BEGV
9222 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9223 {
9224 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9225
9226 DEC_BOTH (cp, bp);
9227 cp = find_newline_no_quit (cp, bp, -1, NULL);
9228 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9229 }
9230 bidi_unshelve_cache (it3data, 1);
9231 }
9232 else
9233 {
9234 /* The y-position we try to reach, relative to *IT.
9235 Note that H has been subtracted in front of the if-statement. */
9236 int target_y = it->current_y + h - dy;
9237 int y0 = it3.current_y;
9238 int y1;
9239 int line_height;
9240
9241 RESTORE_IT (&it3, &it3, it3data);
9242 y1 = line_bottom_y (&it3);
9243 line_height = y1 - y0;
9244 RESTORE_IT (it, it, it2data);
9245 /* If we did not reach target_y, try to move further backward if
9246 we can. If we moved too far backward, try to move forward. */
9247 if (target_y < it->current_y
9248 /* This is heuristic. In a window that's 3 lines high, with
9249 a line height of 13 pixels each, recentering with point
9250 on the bottom line will try to move -39/2 = 19 pixels
9251 backward. Try to avoid moving into the first line. */
9252 && (it->current_y - target_y
9253 > min (window_box_height (it->w), line_height * 2 / 3))
9254 && IT_CHARPOS (*it) > BEGV)
9255 {
9256 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9257 target_y - it->current_y));
9258 dy = it->current_y - target_y;
9259 goto move_further_back;
9260 }
9261 else if (target_y >= it->current_y + line_height
9262 && IT_CHARPOS (*it) < ZV)
9263 {
9264 /* Should move forward by at least one line, maybe more.
9265
9266 Note: Calling move_it_by_lines can be expensive on
9267 terminal frames, where compute_motion is used (via
9268 vmotion) to do the job, when there are very long lines
9269 and truncate-lines is nil. That's the reason for
9270 treating terminal frames specially here. */
9271
9272 if (!FRAME_WINDOW_P (it->f))
9273 move_it_vertically (it, target_y - (it->current_y + line_height));
9274 else
9275 {
9276 do
9277 {
9278 move_it_by_lines (it, 1);
9279 }
9280 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9281 }
9282 }
9283 }
9284 }
9285
9286
9287 /* Move IT by a specified amount of pixel lines DY. DY negative means
9288 move backwards. DY = 0 means move to start of screen line. At the
9289 end, IT will be on the start of a screen line. */
9290
9291 void
9292 move_it_vertically (struct it *it, int dy)
9293 {
9294 if (dy <= 0)
9295 move_it_vertically_backward (it, -dy);
9296 else
9297 {
9298 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9299 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9300 MOVE_TO_POS | MOVE_TO_Y);
9301 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9302
9303 /* If buffer ends in ZV without a newline, move to the start of
9304 the line to satisfy the post-condition. */
9305 if (IT_CHARPOS (*it) == ZV
9306 && ZV > BEGV
9307 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9308 move_it_by_lines (it, 0);
9309 }
9310 }
9311
9312
9313 /* Move iterator IT past the end of the text line it is in. */
9314
9315 void
9316 move_it_past_eol (struct it *it)
9317 {
9318 enum move_it_result rc;
9319
9320 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9321 if (rc == MOVE_NEWLINE_OR_CR)
9322 set_iterator_to_next (it, 0);
9323 }
9324
9325
9326 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9327 negative means move up. DVPOS == 0 means move to the start of the
9328 screen line.
9329
9330 Optimization idea: If we would know that IT->f doesn't use
9331 a face with proportional font, we could be faster for
9332 truncate-lines nil. */
9333
9334 void
9335 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9336 {
9337
9338 /* The commented-out optimization uses vmotion on terminals. This
9339 gives bad results, because elements like it->what, on which
9340 callers such as pos_visible_p rely, aren't updated. */
9341 /* struct position pos;
9342 if (!FRAME_WINDOW_P (it->f))
9343 {
9344 struct text_pos textpos;
9345
9346 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9347 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9348 reseat (it, textpos, 1);
9349 it->vpos += pos.vpos;
9350 it->current_y += pos.vpos;
9351 }
9352 else */
9353
9354 if (dvpos == 0)
9355 {
9356 /* DVPOS == 0 means move to the start of the screen line. */
9357 move_it_vertically_backward (it, 0);
9358 /* Let next call to line_bottom_y calculate real line height */
9359 last_height = 0;
9360 }
9361 else if (dvpos > 0)
9362 {
9363 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9364 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9365 {
9366 /* Only move to the next buffer position if we ended up in a
9367 string from display property, not in an overlay string
9368 (before-string or after-string). That is because the
9369 latter don't conceal the underlying buffer position, so
9370 we can ask to move the iterator to the exact position we
9371 are interested in. Note that, even if we are already at
9372 IT_CHARPOS (*it), the call below is not a no-op, as it
9373 will detect that we are at the end of the string, pop the
9374 iterator, and compute it->current_x and it->hpos
9375 correctly. */
9376 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9377 -1, -1, -1, MOVE_TO_POS);
9378 }
9379 }
9380 else
9381 {
9382 struct it it2;
9383 void *it2data = NULL;
9384 ptrdiff_t start_charpos, i;
9385 int nchars_per_row
9386 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9387 ptrdiff_t pos_limit;
9388
9389 /* Start at the beginning of the screen line containing IT's
9390 position. This may actually move vertically backwards,
9391 in case of overlays, so adjust dvpos accordingly. */
9392 dvpos += it->vpos;
9393 move_it_vertically_backward (it, 0);
9394 dvpos -= it->vpos;
9395
9396 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9397 screen lines, and reseat the iterator there. */
9398 start_charpos = IT_CHARPOS (*it);
9399 if (it->line_wrap == TRUNCATE)
9400 pos_limit = BEGV;
9401 else
9402 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9403 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9404 back_to_previous_visible_line_start (it);
9405 reseat (it, it->current.pos, 1);
9406
9407 /* Move further back if we end up in a string or an image. */
9408 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9409 {
9410 /* First try to move to start of display line. */
9411 dvpos += it->vpos;
9412 move_it_vertically_backward (it, 0);
9413 dvpos -= it->vpos;
9414 if (IT_POS_VALID_AFTER_MOVE_P (it))
9415 break;
9416 /* If start of line is still in string or image,
9417 move further back. */
9418 back_to_previous_visible_line_start (it);
9419 reseat (it, it->current.pos, 1);
9420 dvpos--;
9421 }
9422
9423 it->current_x = it->hpos = 0;
9424
9425 /* Above call may have moved too far if continuation lines
9426 are involved. Scan forward and see if it did. */
9427 SAVE_IT (it2, *it, it2data);
9428 it2.vpos = it2.current_y = 0;
9429 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9430 it->vpos -= it2.vpos;
9431 it->current_y -= it2.current_y;
9432 it->current_x = it->hpos = 0;
9433
9434 /* If we moved too far back, move IT some lines forward. */
9435 if (it2.vpos > -dvpos)
9436 {
9437 int delta = it2.vpos + dvpos;
9438
9439 RESTORE_IT (&it2, &it2, it2data);
9440 SAVE_IT (it2, *it, it2data);
9441 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9442 /* Move back again if we got too far ahead. */
9443 if (IT_CHARPOS (*it) >= start_charpos)
9444 RESTORE_IT (it, &it2, it2data);
9445 else
9446 bidi_unshelve_cache (it2data, 1);
9447 }
9448 else
9449 RESTORE_IT (it, it, it2data);
9450 }
9451 }
9452
9453 /* Return 1 if IT points into the middle of a display vector. */
9454
9455 int
9456 in_display_vector_p (struct it *it)
9457 {
9458 return (it->method == GET_FROM_DISPLAY_VECTOR
9459 && it->current.dpvec_index > 0
9460 && it->dpvec + it->current.dpvec_index != it->dpend);
9461 }
9462
9463 \f
9464 /***********************************************************************
9465 Messages
9466 ***********************************************************************/
9467
9468
9469 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9470 to *Messages*. */
9471
9472 void
9473 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9474 {
9475 Lisp_Object args[3];
9476 Lisp_Object msg, fmt;
9477 char *buffer;
9478 ptrdiff_t len;
9479 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9480 USE_SAFE_ALLOCA;
9481
9482 fmt = msg = Qnil;
9483 GCPRO4 (fmt, msg, arg1, arg2);
9484
9485 args[0] = fmt = build_string (format);
9486 args[1] = arg1;
9487 args[2] = arg2;
9488 msg = Fformat (3, args);
9489
9490 len = SBYTES (msg) + 1;
9491 buffer = SAFE_ALLOCA (len);
9492 memcpy (buffer, SDATA (msg), len);
9493
9494 message_dolog (buffer, len - 1, 1, 0);
9495 SAFE_FREE ();
9496
9497 UNGCPRO;
9498 }
9499
9500
9501 /* Output a newline in the *Messages* buffer if "needs" one. */
9502
9503 void
9504 message_log_maybe_newline (void)
9505 {
9506 if (message_log_need_newline)
9507 message_dolog ("", 0, 1, 0);
9508 }
9509
9510
9511 /* Add a string M of length NBYTES to the message log, optionally
9512 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9513 true, means interpret the contents of M as multibyte. This
9514 function calls low-level routines in order to bypass text property
9515 hooks, etc. which might not be safe to run.
9516
9517 This may GC (insert may run before/after change hooks),
9518 so the buffer M must NOT point to a Lisp string. */
9519
9520 void
9521 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9522 {
9523 const unsigned char *msg = (const unsigned char *) m;
9524
9525 if (!NILP (Vmemory_full))
9526 return;
9527
9528 if (!NILP (Vmessage_log_max))
9529 {
9530 struct buffer *oldbuf;
9531 Lisp_Object oldpoint, oldbegv, oldzv;
9532 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9533 ptrdiff_t point_at_end = 0;
9534 ptrdiff_t zv_at_end = 0;
9535 Lisp_Object old_deactivate_mark;
9536 bool shown;
9537 struct gcpro gcpro1;
9538
9539 old_deactivate_mark = Vdeactivate_mark;
9540 oldbuf = current_buffer;
9541 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9542 bset_undo_list (current_buffer, Qt);
9543
9544 oldpoint = message_dolog_marker1;
9545 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9546 oldbegv = message_dolog_marker2;
9547 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9548 oldzv = message_dolog_marker3;
9549 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9550 GCPRO1 (old_deactivate_mark);
9551
9552 if (PT == Z)
9553 point_at_end = 1;
9554 if (ZV == Z)
9555 zv_at_end = 1;
9556
9557 BEGV = BEG;
9558 BEGV_BYTE = BEG_BYTE;
9559 ZV = Z;
9560 ZV_BYTE = Z_BYTE;
9561 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9562
9563 /* Insert the string--maybe converting multibyte to single byte
9564 or vice versa, so that all the text fits the buffer. */
9565 if (multibyte
9566 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9567 {
9568 ptrdiff_t i;
9569 int c, char_bytes;
9570 char work[1];
9571
9572 /* Convert a multibyte string to single-byte
9573 for the *Message* buffer. */
9574 for (i = 0; i < nbytes; i += char_bytes)
9575 {
9576 c = string_char_and_length (msg + i, &char_bytes);
9577 work[0] = (ASCII_CHAR_P (c)
9578 ? c
9579 : multibyte_char_to_unibyte (c));
9580 insert_1_both (work, 1, 1, 1, 0, 0);
9581 }
9582 }
9583 else if (! multibyte
9584 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9585 {
9586 ptrdiff_t i;
9587 int c, char_bytes;
9588 unsigned char str[MAX_MULTIBYTE_LENGTH];
9589 /* Convert a single-byte string to multibyte
9590 for the *Message* buffer. */
9591 for (i = 0; i < nbytes; i++)
9592 {
9593 c = msg[i];
9594 MAKE_CHAR_MULTIBYTE (c);
9595 char_bytes = CHAR_STRING (c, str);
9596 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9597 }
9598 }
9599 else if (nbytes)
9600 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9601
9602 if (nlflag)
9603 {
9604 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9605 printmax_t dups;
9606
9607 insert_1_both ("\n", 1, 1, 1, 0, 0);
9608
9609 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9610 this_bol = PT;
9611 this_bol_byte = PT_BYTE;
9612
9613 /* See if this line duplicates the previous one.
9614 If so, combine duplicates. */
9615 if (this_bol > BEG)
9616 {
9617 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9618 prev_bol = PT;
9619 prev_bol_byte = PT_BYTE;
9620
9621 dups = message_log_check_duplicate (prev_bol_byte,
9622 this_bol_byte);
9623 if (dups)
9624 {
9625 del_range_both (prev_bol, prev_bol_byte,
9626 this_bol, this_bol_byte, 0);
9627 if (dups > 1)
9628 {
9629 char dupstr[sizeof " [ times]"
9630 + INT_STRLEN_BOUND (printmax_t)];
9631
9632 /* If you change this format, don't forget to also
9633 change message_log_check_duplicate. */
9634 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9635 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9636 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9637 }
9638 }
9639 }
9640
9641 /* If we have more than the desired maximum number of lines
9642 in the *Messages* buffer now, delete the oldest ones.
9643 This is safe because we don't have undo in this buffer. */
9644
9645 if (NATNUMP (Vmessage_log_max))
9646 {
9647 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9648 -XFASTINT (Vmessage_log_max) - 1, 0);
9649 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9650 }
9651 }
9652 BEGV = marker_position (oldbegv);
9653 BEGV_BYTE = marker_byte_position (oldbegv);
9654
9655 if (zv_at_end)
9656 {
9657 ZV = Z;
9658 ZV_BYTE = Z_BYTE;
9659 }
9660 else
9661 {
9662 ZV = marker_position (oldzv);
9663 ZV_BYTE = marker_byte_position (oldzv);
9664 }
9665
9666 if (point_at_end)
9667 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9668 else
9669 /* We can't do Fgoto_char (oldpoint) because it will run some
9670 Lisp code. */
9671 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9672 marker_byte_position (oldpoint));
9673
9674 UNGCPRO;
9675 unchain_marker (XMARKER (oldpoint));
9676 unchain_marker (XMARKER (oldbegv));
9677 unchain_marker (XMARKER (oldzv));
9678
9679 shown = buffer_window_count (current_buffer) > 0;
9680 set_buffer_internal (oldbuf);
9681 /* We called insert_1_both above with its 5th argument (PREPARE)
9682 zero, which prevents insert_1_both from calling
9683 prepare_to_modify_buffer, which in turns prevents us from
9684 incrementing windows_or_buffers_changed even if *Messages* is
9685 shown in some window. So we must manually incrementing
9686 windows_or_buffers_changed here to make up for that. */
9687 if (shown)
9688 windows_or_buffers_changed++;
9689 else
9690 windows_or_buffers_changed = old_windows_or_buffers_changed;
9691 message_log_need_newline = !nlflag;
9692 Vdeactivate_mark = old_deactivate_mark;
9693 }
9694 }
9695
9696
9697 /* We are at the end of the buffer after just having inserted a newline.
9698 (Note: We depend on the fact we won't be crossing the gap.)
9699 Check to see if the most recent message looks a lot like the previous one.
9700 Return 0 if different, 1 if the new one should just replace it, or a
9701 value N > 1 if we should also append " [N times]". */
9702
9703 static intmax_t
9704 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9705 {
9706 ptrdiff_t i;
9707 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9708 int seen_dots = 0;
9709 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9710 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9711
9712 for (i = 0; i < len; i++)
9713 {
9714 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9715 seen_dots = 1;
9716 if (p1[i] != p2[i])
9717 return seen_dots;
9718 }
9719 p1 += len;
9720 if (*p1 == '\n')
9721 return 2;
9722 if (*p1++ == ' ' && *p1++ == '[')
9723 {
9724 char *pend;
9725 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9726 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9727 return n + 1;
9728 }
9729 return 0;
9730 }
9731 \f
9732
9733 /* Display an echo area message M with a specified length of NBYTES
9734 bytes. The string may include null characters. If M is not a
9735 string, clear out any existing message, and let the mini-buffer
9736 text show through.
9737
9738 This function cancels echoing. */
9739
9740 void
9741 message3 (Lisp_Object m)
9742 {
9743 struct gcpro gcpro1;
9744
9745 GCPRO1 (m);
9746 clear_message (1,1);
9747 cancel_echoing ();
9748
9749 /* First flush out any partial line written with print. */
9750 message_log_maybe_newline ();
9751 if (STRINGP (m))
9752 {
9753 ptrdiff_t nbytes = SBYTES (m);
9754 bool multibyte = STRING_MULTIBYTE (m);
9755 USE_SAFE_ALLOCA;
9756 char *buffer = SAFE_ALLOCA (nbytes);
9757 memcpy (buffer, SDATA (m), nbytes);
9758 message_dolog (buffer, nbytes, 1, multibyte);
9759 SAFE_FREE ();
9760 }
9761 message3_nolog (m);
9762
9763 UNGCPRO;
9764 }
9765
9766
9767 /* The non-logging version of message3.
9768 This does not cancel echoing, because it is used for echoing.
9769 Perhaps we need to make a separate function for echoing
9770 and make this cancel echoing. */
9771
9772 void
9773 message3_nolog (Lisp_Object m)
9774 {
9775 struct frame *sf = SELECTED_FRAME ();
9776
9777 if (FRAME_INITIAL_P (sf))
9778 {
9779 if (noninteractive_need_newline)
9780 putc ('\n', stderr);
9781 noninteractive_need_newline = 0;
9782 if (STRINGP (m))
9783 fwrite (SDATA (m), SBYTES (m), 1, stderr);
9784 if (cursor_in_echo_area == 0)
9785 fprintf (stderr, "\n");
9786 fflush (stderr);
9787 }
9788 /* Error messages get reported properly by cmd_error, so this must be just an
9789 informative message; if the frame hasn't really been initialized yet, just
9790 toss it. */
9791 else if (INTERACTIVE && sf->glyphs_initialized_p)
9792 {
9793 /* Get the frame containing the mini-buffer
9794 that the selected frame is using. */
9795 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9796 Lisp_Object frame = XWINDOW (mini_window)->frame;
9797 struct frame *f = XFRAME (frame);
9798
9799 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9800 Fmake_frame_visible (frame);
9801
9802 if (STRINGP (m) && SCHARS (m) > 0)
9803 {
9804 set_message (m);
9805 if (minibuffer_auto_raise)
9806 Fraise_frame (frame);
9807 /* Assume we are not echoing.
9808 (If we are, echo_now will override this.) */
9809 echo_message_buffer = Qnil;
9810 }
9811 else
9812 clear_message (1, 1);
9813
9814 do_pending_window_change (0);
9815 echo_area_display (1);
9816 do_pending_window_change (0);
9817 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9818 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9819 }
9820 }
9821
9822
9823 /* Display a null-terminated echo area message M. If M is 0, clear
9824 out any existing message, and let the mini-buffer text show through.
9825
9826 The buffer M must continue to exist until after the echo area gets
9827 cleared or some other message gets displayed there. Do not pass
9828 text that is stored in a Lisp string. Do not pass text in a buffer
9829 that was alloca'd. */
9830
9831 void
9832 message1 (const char *m)
9833 {
9834 message3 (m ? build_unibyte_string (m) : Qnil);
9835 }
9836
9837
9838 /* The non-logging counterpart of message1. */
9839
9840 void
9841 message1_nolog (const char *m)
9842 {
9843 message3_nolog (m ? build_unibyte_string (m) : Qnil);
9844 }
9845
9846 /* Display a message M which contains a single %s
9847 which gets replaced with STRING. */
9848
9849 void
9850 message_with_string (const char *m, Lisp_Object string, int log)
9851 {
9852 CHECK_STRING (string);
9853
9854 if (noninteractive)
9855 {
9856 if (m)
9857 {
9858 if (noninteractive_need_newline)
9859 putc ('\n', stderr);
9860 noninteractive_need_newline = 0;
9861 fprintf (stderr, m, SDATA (string));
9862 if (!cursor_in_echo_area)
9863 fprintf (stderr, "\n");
9864 fflush (stderr);
9865 }
9866 }
9867 else if (INTERACTIVE)
9868 {
9869 /* The frame whose minibuffer we're going to display the message on.
9870 It may be larger than the selected frame, so we need
9871 to use its buffer, not the selected frame's buffer. */
9872 Lisp_Object mini_window;
9873 struct frame *f, *sf = SELECTED_FRAME ();
9874
9875 /* Get the frame containing the minibuffer
9876 that the selected frame is using. */
9877 mini_window = FRAME_MINIBUF_WINDOW (sf);
9878 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9879
9880 /* Error messages get reported properly by cmd_error, so this must be
9881 just an informative message; if the frame hasn't really been
9882 initialized yet, just toss it. */
9883 if (f->glyphs_initialized_p)
9884 {
9885 Lisp_Object args[2], msg;
9886 struct gcpro gcpro1, gcpro2;
9887
9888 args[0] = build_string (m);
9889 args[1] = msg = string;
9890 GCPRO2 (args[0], msg);
9891 gcpro1.nvars = 2;
9892
9893 msg = Fformat (2, args);
9894
9895 if (log)
9896 message3 (msg);
9897 else
9898 message3_nolog (msg);
9899
9900 UNGCPRO;
9901
9902 /* Print should start at the beginning of the message
9903 buffer next time. */
9904 message_buf_print = 0;
9905 }
9906 }
9907 }
9908
9909
9910 /* Dump an informative message to the minibuf. If M is 0, clear out
9911 any existing message, and let the mini-buffer text show through. */
9912
9913 static void
9914 vmessage (const char *m, va_list ap)
9915 {
9916 if (noninteractive)
9917 {
9918 if (m)
9919 {
9920 if (noninteractive_need_newline)
9921 putc ('\n', stderr);
9922 noninteractive_need_newline = 0;
9923 vfprintf (stderr, m, ap);
9924 if (cursor_in_echo_area == 0)
9925 fprintf (stderr, "\n");
9926 fflush (stderr);
9927 }
9928 }
9929 else if (INTERACTIVE)
9930 {
9931 /* The frame whose mini-buffer we're going to display the message
9932 on. It may be larger than the selected frame, so we need to
9933 use its buffer, not the selected frame's buffer. */
9934 Lisp_Object mini_window;
9935 struct frame *f, *sf = SELECTED_FRAME ();
9936
9937 /* Get the frame containing the mini-buffer
9938 that the selected frame is using. */
9939 mini_window = FRAME_MINIBUF_WINDOW (sf);
9940 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9941
9942 /* Error messages get reported properly by cmd_error, so this must be
9943 just an informative message; if the frame hasn't really been
9944 initialized yet, just toss it. */
9945 if (f->glyphs_initialized_p)
9946 {
9947 if (m)
9948 {
9949 ptrdiff_t len;
9950 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9951 char *message_buf = alloca (maxsize + 1);
9952
9953 len = doprnt (message_buf, maxsize, m, 0, ap);
9954
9955 message3 (make_string (message_buf, len));
9956 }
9957 else
9958 message1 (0);
9959
9960 /* Print should start at the beginning of the message
9961 buffer next time. */
9962 message_buf_print = 0;
9963 }
9964 }
9965 }
9966
9967 void
9968 message (const char *m, ...)
9969 {
9970 va_list ap;
9971 va_start (ap, m);
9972 vmessage (m, ap);
9973 va_end (ap);
9974 }
9975
9976
9977 #if 0
9978 /* The non-logging version of message. */
9979
9980 void
9981 message_nolog (const char *m, ...)
9982 {
9983 Lisp_Object old_log_max;
9984 va_list ap;
9985 va_start (ap, m);
9986 old_log_max = Vmessage_log_max;
9987 Vmessage_log_max = Qnil;
9988 vmessage (m, ap);
9989 Vmessage_log_max = old_log_max;
9990 va_end (ap);
9991 }
9992 #endif
9993
9994
9995 /* Display the current message in the current mini-buffer. This is
9996 only called from error handlers in process.c, and is not time
9997 critical. */
9998
9999 void
10000 update_echo_area (void)
10001 {
10002 if (!NILP (echo_area_buffer[0]))
10003 {
10004 Lisp_Object string;
10005 string = Fcurrent_message ();
10006 message3 (string);
10007 }
10008 }
10009
10010
10011 /* Make sure echo area buffers in `echo_buffers' are live.
10012 If they aren't, make new ones. */
10013
10014 static void
10015 ensure_echo_area_buffers (void)
10016 {
10017 int i;
10018
10019 for (i = 0; i < 2; ++i)
10020 if (!BUFFERP (echo_buffer[i])
10021 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10022 {
10023 char name[30];
10024 Lisp_Object old_buffer;
10025 int j;
10026
10027 old_buffer = echo_buffer[i];
10028 echo_buffer[i] = Fget_buffer_create
10029 (make_formatted_string (name, " *Echo Area %d*", i));
10030 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10031 /* to force word wrap in echo area -
10032 it was decided to postpone this*/
10033 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10034
10035 for (j = 0; j < 2; ++j)
10036 if (EQ (old_buffer, echo_area_buffer[j]))
10037 echo_area_buffer[j] = echo_buffer[i];
10038 }
10039 }
10040
10041
10042 /* Call FN with args A1..A2 with either the current or last displayed
10043 echo_area_buffer as current buffer.
10044
10045 WHICH zero means use the current message buffer
10046 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10047 from echo_buffer[] and clear it.
10048
10049 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10050 suitable buffer from echo_buffer[] and clear it.
10051
10052 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10053 that the current message becomes the last displayed one, make
10054 choose a suitable buffer for echo_area_buffer[0], and clear it.
10055
10056 Value is what FN returns. */
10057
10058 static int
10059 with_echo_area_buffer (struct window *w, int which,
10060 int (*fn) (ptrdiff_t, Lisp_Object),
10061 ptrdiff_t a1, Lisp_Object a2)
10062 {
10063 Lisp_Object buffer;
10064 int this_one, the_other, clear_buffer_p, rc;
10065 ptrdiff_t count = SPECPDL_INDEX ();
10066
10067 /* If buffers aren't live, make new ones. */
10068 ensure_echo_area_buffers ();
10069
10070 clear_buffer_p = 0;
10071
10072 if (which == 0)
10073 this_one = 0, the_other = 1;
10074 else if (which > 0)
10075 this_one = 1, the_other = 0;
10076 else
10077 {
10078 this_one = 0, the_other = 1;
10079 clear_buffer_p = 1;
10080
10081 /* We need a fresh one in case the current echo buffer equals
10082 the one containing the last displayed echo area message. */
10083 if (!NILP (echo_area_buffer[this_one])
10084 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10085 echo_area_buffer[this_one] = Qnil;
10086 }
10087
10088 /* Choose a suitable buffer from echo_buffer[] is we don't
10089 have one. */
10090 if (NILP (echo_area_buffer[this_one]))
10091 {
10092 echo_area_buffer[this_one]
10093 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10094 ? echo_buffer[the_other]
10095 : echo_buffer[this_one]);
10096 clear_buffer_p = 1;
10097 }
10098
10099 buffer = echo_area_buffer[this_one];
10100
10101 /* Don't get confused by reusing the buffer used for echoing
10102 for a different purpose. */
10103 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10104 cancel_echoing ();
10105
10106 record_unwind_protect (unwind_with_echo_area_buffer,
10107 with_echo_area_buffer_unwind_data (w));
10108
10109 /* Make the echo area buffer current. Note that for display
10110 purposes, it is not necessary that the displayed window's buffer
10111 == current_buffer, except for text property lookup. So, let's
10112 only set that buffer temporarily here without doing a full
10113 Fset_window_buffer. We must also change w->pointm, though,
10114 because otherwise an assertions in unshow_buffer fails, and Emacs
10115 aborts. */
10116 set_buffer_internal_1 (XBUFFER (buffer));
10117 if (w)
10118 {
10119 wset_buffer (w, buffer);
10120 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10121 }
10122
10123 bset_undo_list (current_buffer, Qt);
10124 bset_read_only (current_buffer, Qnil);
10125 specbind (Qinhibit_read_only, Qt);
10126 specbind (Qinhibit_modification_hooks, Qt);
10127
10128 if (clear_buffer_p && Z > BEG)
10129 del_range (BEG, Z);
10130
10131 eassert (BEGV >= BEG);
10132 eassert (ZV <= Z && ZV >= BEGV);
10133
10134 rc = fn (a1, a2);
10135
10136 eassert (BEGV >= BEG);
10137 eassert (ZV <= Z && ZV >= BEGV);
10138
10139 unbind_to (count, Qnil);
10140 return rc;
10141 }
10142
10143
10144 /* Save state that should be preserved around the call to the function
10145 FN called in with_echo_area_buffer. */
10146
10147 static Lisp_Object
10148 with_echo_area_buffer_unwind_data (struct window *w)
10149 {
10150 int i = 0;
10151 Lisp_Object vector, tmp;
10152
10153 /* Reduce consing by keeping one vector in
10154 Vwith_echo_area_save_vector. */
10155 vector = Vwith_echo_area_save_vector;
10156 Vwith_echo_area_save_vector = Qnil;
10157
10158 if (NILP (vector))
10159 vector = Fmake_vector (make_number (9), Qnil);
10160
10161 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10162 ASET (vector, i, Vdeactivate_mark); ++i;
10163 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10164
10165 if (w)
10166 {
10167 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10168 ASET (vector, i, w->contents); ++i;
10169 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10170 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10171 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10172 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10173 }
10174 else
10175 {
10176 int end = i + 6;
10177 for (; i < end; ++i)
10178 ASET (vector, i, Qnil);
10179 }
10180
10181 eassert (i == ASIZE (vector));
10182 return vector;
10183 }
10184
10185
10186 /* Restore global state from VECTOR which was created by
10187 with_echo_area_buffer_unwind_data. */
10188
10189 static void
10190 unwind_with_echo_area_buffer (Lisp_Object vector)
10191 {
10192 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10193 Vdeactivate_mark = AREF (vector, 1);
10194 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10195
10196 if (WINDOWP (AREF (vector, 3)))
10197 {
10198 struct window *w;
10199 Lisp_Object buffer;
10200
10201 w = XWINDOW (AREF (vector, 3));
10202 buffer = AREF (vector, 4);
10203
10204 wset_buffer (w, buffer);
10205 set_marker_both (w->pointm, buffer,
10206 XFASTINT (AREF (vector, 5)),
10207 XFASTINT (AREF (vector, 6)));
10208 set_marker_both (w->start, buffer,
10209 XFASTINT (AREF (vector, 7)),
10210 XFASTINT (AREF (vector, 8)));
10211 }
10212
10213 Vwith_echo_area_save_vector = vector;
10214 }
10215
10216
10217 /* Set up the echo area for use by print functions. MULTIBYTE_P
10218 non-zero means we will print multibyte. */
10219
10220 void
10221 setup_echo_area_for_printing (int multibyte_p)
10222 {
10223 /* If we can't find an echo area any more, exit. */
10224 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10225 Fkill_emacs (Qnil);
10226
10227 ensure_echo_area_buffers ();
10228
10229 if (!message_buf_print)
10230 {
10231 /* A message has been output since the last time we printed.
10232 Choose a fresh echo area buffer. */
10233 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10234 echo_area_buffer[0] = echo_buffer[1];
10235 else
10236 echo_area_buffer[0] = echo_buffer[0];
10237
10238 /* Switch to that buffer and clear it. */
10239 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10240 bset_truncate_lines (current_buffer, Qnil);
10241
10242 if (Z > BEG)
10243 {
10244 ptrdiff_t count = SPECPDL_INDEX ();
10245 specbind (Qinhibit_read_only, Qt);
10246 /* Note that undo recording is always disabled. */
10247 del_range (BEG, Z);
10248 unbind_to (count, Qnil);
10249 }
10250 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10251
10252 /* Set up the buffer for the multibyteness we need. */
10253 if (multibyte_p
10254 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10255 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10256
10257 /* Raise the frame containing the echo area. */
10258 if (minibuffer_auto_raise)
10259 {
10260 struct frame *sf = SELECTED_FRAME ();
10261 Lisp_Object mini_window;
10262 mini_window = FRAME_MINIBUF_WINDOW (sf);
10263 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10264 }
10265
10266 message_log_maybe_newline ();
10267 message_buf_print = 1;
10268 }
10269 else
10270 {
10271 if (NILP (echo_area_buffer[0]))
10272 {
10273 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10274 echo_area_buffer[0] = echo_buffer[1];
10275 else
10276 echo_area_buffer[0] = echo_buffer[0];
10277 }
10278
10279 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10280 {
10281 /* Someone switched buffers between print requests. */
10282 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10283 bset_truncate_lines (current_buffer, Qnil);
10284 }
10285 }
10286 }
10287
10288
10289 /* Display an echo area message in window W. Value is non-zero if W's
10290 height is changed. If display_last_displayed_message_p is
10291 non-zero, display the message that was last displayed, otherwise
10292 display the current message. */
10293
10294 static int
10295 display_echo_area (struct window *w)
10296 {
10297 int i, no_message_p, window_height_changed_p;
10298
10299 /* Temporarily disable garbage collections while displaying the echo
10300 area. This is done because a GC can print a message itself.
10301 That message would modify the echo area buffer's contents while a
10302 redisplay of the buffer is going on, and seriously confuse
10303 redisplay. */
10304 ptrdiff_t count = inhibit_garbage_collection ();
10305
10306 /* If there is no message, we must call display_echo_area_1
10307 nevertheless because it resizes the window. But we will have to
10308 reset the echo_area_buffer in question to nil at the end because
10309 with_echo_area_buffer will sets it to an empty buffer. */
10310 i = display_last_displayed_message_p ? 1 : 0;
10311 no_message_p = NILP (echo_area_buffer[i]);
10312
10313 window_height_changed_p
10314 = with_echo_area_buffer (w, display_last_displayed_message_p,
10315 display_echo_area_1,
10316 (intptr_t) w, Qnil);
10317
10318 if (no_message_p)
10319 echo_area_buffer[i] = Qnil;
10320
10321 unbind_to (count, Qnil);
10322 return window_height_changed_p;
10323 }
10324
10325
10326 /* Helper for display_echo_area. Display the current buffer which
10327 contains the current echo area message in window W, a mini-window,
10328 a pointer to which is passed in A1. A2..A4 are currently not used.
10329 Change the height of W so that all of the message is displayed.
10330 Value is non-zero if height of W was changed. */
10331
10332 static int
10333 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10334 {
10335 intptr_t i1 = a1;
10336 struct window *w = (struct window *) i1;
10337 Lisp_Object window;
10338 struct text_pos start;
10339 int window_height_changed_p = 0;
10340
10341 /* Do this before displaying, so that we have a large enough glyph
10342 matrix for the display. If we can't get enough space for the
10343 whole text, display the last N lines. That works by setting w->start. */
10344 window_height_changed_p = resize_mini_window (w, 0);
10345
10346 /* Use the starting position chosen by resize_mini_window. */
10347 SET_TEXT_POS_FROM_MARKER (start, w->start);
10348
10349 /* Display. */
10350 clear_glyph_matrix (w->desired_matrix);
10351 XSETWINDOW (window, w);
10352 try_window (window, start, 0);
10353
10354 return window_height_changed_p;
10355 }
10356
10357
10358 /* Resize the echo area window to exactly the size needed for the
10359 currently displayed message, if there is one. If a mini-buffer
10360 is active, don't shrink it. */
10361
10362 void
10363 resize_echo_area_exactly (void)
10364 {
10365 if (BUFFERP (echo_area_buffer[0])
10366 && WINDOWP (echo_area_window))
10367 {
10368 struct window *w = XWINDOW (echo_area_window);
10369 int resized_p;
10370 Lisp_Object resize_exactly;
10371
10372 if (minibuf_level == 0)
10373 resize_exactly = Qt;
10374 else
10375 resize_exactly = Qnil;
10376
10377 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10378 (intptr_t) w, resize_exactly);
10379 if (resized_p)
10380 {
10381 ++windows_or_buffers_changed;
10382 ++update_mode_lines;
10383 redisplay_internal ();
10384 }
10385 }
10386 }
10387
10388
10389 /* Callback function for with_echo_area_buffer, when used from
10390 resize_echo_area_exactly. A1 contains a pointer to the window to
10391 resize, EXACTLY non-nil means resize the mini-window exactly to the
10392 size of the text displayed. A3 and A4 are not used. Value is what
10393 resize_mini_window returns. */
10394
10395 static int
10396 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10397 {
10398 intptr_t i1 = a1;
10399 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10400 }
10401
10402
10403 /* Resize mini-window W to fit the size of its contents. EXACT_P
10404 means size the window exactly to the size needed. Otherwise, it's
10405 only enlarged until W's buffer is empty.
10406
10407 Set W->start to the right place to begin display. If the whole
10408 contents fit, start at the beginning. Otherwise, start so as
10409 to make the end of the contents appear. This is particularly
10410 important for y-or-n-p, but seems desirable generally.
10411
10412 Value is non-zero if the window height has been changed. */
10413
10414 int
10415 resize_mini_window (struct window *w, int exact_p)
10416 {
10417 struct frame *f = XFRAME (w->frame);
10418 int window_height_changed_p = 0;
10419
10420 eassert (MINI_WINDOW_P (w));
10421
10422 /* By default, start display at the beginning. */
10423 set_marker_both (w->start, w->contents,
10424 BUF_BEGV (XBUFFER (w->contents)),
10425 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10426
10427 /* Don't resize windows while redisplaying a window; it would
10428 confuse redisplay functions when the size of the window they are
10429 displaying changes from under them. Such a resizing can happen,
10430 for instance, when which-func prints a long message while
10431 we are running fontification-functions. We're running these
10432 functions with safe_call which binds inhibit-redisplay to t. */
10433 if (!NILP (Vinhibit_redisplay))
10434 return 0;
10435
10436 /* Nil means don't try to resize. */
10437 if (NILP (Vresize_mini_windows)
10438 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10439 return 0;
10440
10441 if (!FRAME_MINIBUF_ONLY_P (f))
10442 {
10443 struct it it;
10444 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10445 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10446 int height;
10447 EMACS_INT max_height;
10448 int unit = FRAME_LINE_HEIGHT (f);
10449 struct text_pos start;
10450 struct buffer *old_current_buffer = NULL;
10451
10452 if (current_buffer != XBUFFER (w->contents))
10453 {
10454 old_current_buffer = current_buffer;
10455 set_buffer_internal (XBUFFER (w->contents));
10456 }
10457
10458 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10459
10460 /* Compute the max. number of lines specified by the user. */
10461 if (FLOATP (Vmax_mini_window_height))
10462 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10463 else if (INTEGERP (Vmax_mini_window_height))
10464 max_height = XINT (Vmax_mini_window_height);
10465 else
10466 max_height = total_height / 4;
10467
10468 /* Correct that max. height if it's bogus. */
10469 max_height = clip_to_bounds (1, max_height, total_height);
10470
10471 /* Find out the height of the text in the window. */
10472 if (it.line_wrap == TRUNCATE)
10473 height = 1;
10474 else
10475 {
10476 last_height = 0;
10477 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10478 if (it.max_ascent == 0 && it.max_descent == 0)
10479 height = it.current_y + last_height;
10480 else
10481 height = it.current_y + it.max_ascent + it.max_descent;
10482 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10483 height = (height + unit - 1) / unit;
10484 }
10485
10486 /* Compute a suitable window start. */
10487 if (height > max_height)
10488 {
10489 height = max_height;
10490 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10491 move_it_vertically_backward (&it, (height - 1) * unit);
10492 start = it.current.pos;
10493 }
10494 else
10495 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10496 SET_MARKER_FROM_TEXT_POS (w->start, start);
10497
10498 if (EQ (Vresize_mini_windows, Qgrow_only))
10499 {
10500 /* Let it grow only, until we display an empty message, in which
10501 case the window shrinks again. */
10502 if (height > WINDOW_TOTAL_LINES (w))
10503 {
10504 int old_height = WINDOW_TOTAL_LINES (w);
10505
10506 FRAME_WINDOWS_FROZEN (f) = 1;
10507 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10508 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10509 }
10510 else if (height < WINDOW_TOTAL_LINES (w)
10511 && (exact_p || BEGV == ZV))
10512 {
10513 int old_height = WINDOW_TOTAL_LINES (w);
10514
10515 FRAME_WINDOWS_FROZEN (f) = 0;
10516 shrink_mini_window (w);
10517 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10518 }
10519 }
10520 else
10521 {
10522 /* Always resize to exact size needed. */
10523 if (height > WINDOW_TOTAL_LINES (w))
10524 {
10525 int old_height = WINDOW_TOTAL_LINES (w);
10526
10527 FRAME_WINDOWS_FROZEN (f) = 1;
10528 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10529 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10530 }
10531 else if (height < WINDOW_TOTAL_LINES (w))
10532 {
10533 int old_height = WINDOW_TOTAL_LINES (w);
10534
10535 FRAME_WINDOWS_FROZEN (f) = 0;
10536 shrink_mini_window (w);
10537
10538 if (height)
10539 {
10540 FRAME_WINDOWS_FROZEN (f) = 1;
10541 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10542 }
10543
10544 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10545 }
10546 }
10547
10548 if (old_current_buffer)
10549 set_buffer_internal (old_current_buffer);
10550 }
10551
10552 return window_height_changed_p;
10553 }
10554
10555
10556 /* Value is the current message, a string, or nil if there is no
10557 current message. */
10558
10559 Lisp_Object
10560 current_message (void)
10561 {
10562 Lisp_Object msg;
10563
10564 if (!BUFFERP (echo_area_buffer[0]))
10565 msg = Qnil;
10566 else
10567 {
10568 with_echo_area_buffer (0, 0, current_message_1,
10569 (intptr_t) &msg, Qnil);
10570 if (NILP (msg))
10571 echo_area_buffer[0] = Qnil;
10572 }
10573
10574 return msg;
10575 }
10576
10577
10578 static int
10579 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10580 {
10581 intptr_t i1 = a1;
10582 Lisp_Object *msg = (Lisp_Object *) i1;
10583
10584 if (Z > BEG)
10585 *msg = make_buffer_string (BEG, Z, 1);
10586 else
10587 *msg = Qnil;
10588 return 0;
10589 }
10590
10591
10592 /* Push the current message on Vmessage_stack for later restoration
10593 by restore_message. Value is non-zero if the current message isn't
10594 empty. This is a relatively infrequent operation, so it's not
10595 worth optimizing. */
10596
10597 bool
10598 push_message (void)
10599 {
10600 Lisp_Object msg = current_message ();
10601 Vmessage_stack = Fcons (msg, Vmessage_stack);
10602 return STRINGP (msg);
10603 }
10604
10605
10606 /* Restore message display from the top of Vmessage_stack. */
10607
10608 void
10609 restore_message (void)
10610 {
10611 eassert (CONSP (Vmessage_stack));
10612 message3_nolog (XCAR (Vmessage_stack));
10613 }
10614
10615
10616 /* Handler for unwind-protect calling pop_message. */
10617
10618 void
10619 pop_message_unwind (void)
10620 {
10621 /* Pop the top-most entry off Vmessage_stack. */
10622 eassert (CONSP (Vmessage_stack));
10623 Vmessage_stack = XCDR (Vmessage_stack);
10624 }
10625
10626
10627 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10628 exits. If the stack is not empty, we have a missing pop_message
10629 somewhere. */
10630
10631 void
10632 check_message_stack (void)
10633 {
10634 if (!NILP (Vmessage_stack))
10635 emacs_abort ();
10636 }
10637
10638
10639 /* Truncate to NCHARS what will be displayed in the echo area the next
10640 time we display it---but don't redisplay it now. */
10641
10642 void
10643 truncate_echo_area (ptrdiff_t nchars)
10644 {
10645 if (nchars == 0)
10646 echo_area_buffer[0] = Qnil;
10647 else if (!noninteractive
10648 && INTERACTIVE
10649 && !NILP (echo_area_buffer[0]))
10650 {
10651 struct frame *sf = SELECTED_FRAME ();
10652 /* Error messages get reported properly by cmd_error, so this must be
10653 just an informative message; if the frame hasn't really been
10654 initialized yet, just toss it. */
10655 if (sf->glyphs_initialized_p)
10656 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10657 }
10658 }
10659
10660
10661 /* Helper function for truncate_echo_area. Truncate the current
10662 message to at most NCHARS characters. */
10663
10664 static int
10665 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10666 {
10667 if (BEG + nchars < Z)
10668 del_range (BEG + nchars, Z);
10669 if (Z == BEG)
10670 echo_area_buffer[0] = Qnil;
10671 return 0;
10672 }
10673
10674 /* Set the current message to STRING. */
10675
10676 static void
10677 set_message (Lisp_Object string)
10678 {
10679 eassert (STRINGP (string));
10680
10681 message_enable_multibyte = STRING_MULTIBYTE (string);
10682
10683 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10684 message_buf_print = 0;
10685 help_echo_showing_p = 0;
10686
10687 if (STRINGP (Vdebug_on_message)
10688 && STRINGP (string)
10689 && fast_string_match (Vdebug_on_message, string) >= 0)
10690 call_debugger (list2 (Qerror, string));
10691 }
10692
10693
10694 /* Helper function for set_message. First argument is ignored and second
10695 argument has the same meaning as for set_message.
10696 This function is called with the echo area buffer being current. */
10697
10698 static int
10699 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10700 {
10701 eassert (STRINGP (string));
10702
10703 /* Change multibyteness of the echo buffer appropriately. */
10704 if (message_enable_multibyte
10705 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10706 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10707
10708 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10709 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10710 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10711
10712 /* Insert new message at BEG. */
10713 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10714
10715 /* This function takes care of single/multibyte conversion.
10716 We just have to ensure that the echo area buffer has the right
10717 setting of enable_multibyte_characters. */
10718 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10719
10720 return 0;
10721 }
10722
10723
10724 /* Clear messages. CURRENT_P non-zero means clear the current
10725 message. LAST_DISPLAYED_P non-zero means clear the message
10726 last displayed. */
10727
10728 void
10729 clear_message (int current_p, int last_displayed_p)
10730 {
10731 if (current_p)
10732 {
10733 echo_area_buffer[0] = Qnil;
10734 message_cleared_p = 1;
10735 }
10736
10737 if (last_displayed_p)
10738 echo_area_buffer[1] = Qnil;
10739
10740 message_buf_print = 0;
10741 }
10742
10743 /* Clear garbaged frames.
10744
10745 This function is used where the old redisplay called
10746 redraw_garbaged_frames which in turn called redraw_frame which in
10747 turn called clear_frame. The call to clear_frame was a source of
10748 flickering. I believe a clear_frame is not necessary. It should
10749 suffice in the new redisplay to invalidate all current matrices,
10750 and ensure a complete redisplay of all windows. */
10751
10752 static void
10753 clear_garbaged_frames (void)
10754 {
10755 if (frame_garbaged)
10756 {
10757 Lisp_Object tail, frame;
10758 int changed_count = 0;
10759
10760 FOR_EACH_FRAME (tail, frame)
10761 {
10762 struct frame *f = XFRAME (frame);
10763
10764 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10765 {
10766 if (f->resized_p)
10767 redraw_frame (f);
10768 else
10769 clear_current_matrices (f);
10770 changed_count++;
10771 f->garbaged = 0;
10772 f->resized_p = 0;
10773 }
10774 }
10775
10776 frame_garbaged = 0;
10777 if (changed_count)
10778 ++windows_or_buffers_changed;
10779 }
10780 }
10781
10782
10783 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10784 is non-zero update selected_frame. Value is non-zero if the
10785 mini-windows height has been changed. */
10786
10787 static int
10788 echo_area_display (int update_frame_p)
10789 {
10790 Lisp_Object mini_window;
10791 struct window *w;
10792 struct frame *f;
10793 int window_height_changed_p = 0;
10794 struct frame *sf = SELECTED_FRAME ();
10795
10796 mini_window = FRAME_MINIBUF_WINDOW (sf);
10797 w = XWINDOW (mini_window);
10798 f = XFRAME (WINDOW_FRAME (w));
10799
10800 /* Don't display if frame is invisible or not yet initialized. */
10801 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10802 return 0;
10803
10804 #ifdef HAVE_WINDOW_SYSTEM
10805 /* When Emacs starts, selected_frame may be the initial terminal
10806 frame. If we let this through, a message would be displayed on
10807 the terminal. */
10808 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10809 return 0;
10810 #endif /* HAVE_WINDOW_SYSTEM */
10811
10812 /* Redraw garbaged frames. */
10813 clear_garbaged_frames ();
10814
10815 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10816 {
10817 echo_area_window = mini_window;
10818 window_height_changed_p = display_echo_area (w);
10819 w->must_be_updated_p = 1;
10820
10821 /* Update the display, unless called from redisplay_internal.
10822 Also don't update the screen during redisplay itself. The
10823 update will happen at the end of redisplay, and an update
10824 here could cause confusion. */
10825 if (update_frame_p && !redisplaying_p)
10826 {
10827 int n = 0;
10828
10829 /* If the display update has been interrupted by pending
10830 input, update mode lines in the frame. Due to the
10831 pending input, it might have been that redisplay hasn't
10832 been called, so that mode lines above the echo area are
10833 garbaged. This looks odd, so we prevent it here. */
10834 if (!display_completed)
10835 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10836
10837 if (window_height_changed_p
10838 /* Don't do this if Emacs is shutting down. Redisplay
10839 needs to run hooks. */
10840 && !NILP (Vrun_hooks))
10841 {
10842 /* Must update other windows. Likewise as in other
10843 cases, don't let this update be interrupted by
10844 pending input. */
10845 ptrdiff_t count = SPECPDL_INDEX ();
10846 specbind (Qredisplay_dont_pause, Qt);
10847 windows_or_buffers_changed = 1;
10848 redisplay_internal ();
10849 unbind_to (count, Qnil);
10850 }
10851 else if (FRAME_WINDOW_P (f) && n == 0)
10852 {
10853 /* Window configuration is the same as before.
10854 Can do with a display update of the echo area,
10855 unless we displayed some mode lines. */
10856 update_single_window (w, 1);
10857 flush_frame (f);
10858 }
10859 else
10860 update_frame (f, 1, 1);
10861
10862 /* If cursor is in the echo area, make sure that the next
10863 redisplay displays the minibuffer, so that the cursor will
10864 be replaced with what the minibuffer wants. */
10865 if (cursor_in_echo_area)
10866 ++windows_or_buffers_changed;
10867 }
10868 }
10869 else if (!EQ (mini_window, selected_window))
10870 windows_or_buffers_changed++;
10871
10872 /* Last displayed message is now the current message. */
10873 echo_area_buffer[1] = echo_area_buffer[0];
10874 /* Inform read_char that we're not echoing. */
10875 echo_message_buffer = Qnil;
10876
10877 /* Prevent redisplay optimization in redisplay_internal by resetting
10878 this_line_start_pos. This is done because the mini-buffer now
10879 displays the message instead of its buffer text. */
10880 if (EQ (mini_window, selected_window))
10881 CHARPOS (this_line_start_pos) = 0;
10882
10883 return window_height_changed_p;
10884 }
10885
10886 /* Nonzero if the current window's buffer is shown in more than one
10887 window and was modified since last redisplay. */
10888
10889 static int
10890 buffer_shared_and_changed (void)
10891 {
10892 return (buffer_window_count (current_buffer) > 1
10893 && UNCHANGED_MODIFIED < MODIFF);
10894 }
10895
10896 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10897 is enabled and mark of W's buffer was changed since last W's update. */
10898
10899 static int
10900 window_buffer_changed (struct window *w)
10901 {
10902 struct buffer *b = XBUFFER (w->contents);
10903
10904 eassert (BUFFER_LIVE_P (b));
10905
10906 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10907 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10908 != (w->region_showing != 0)));
10909 }
10910
10911 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10912
10913 static int
10914 mode_line_update_needed (struct window *w)
10915 {
10916 return (w->column_number_displayed != -1
10917 && !(PT == w->last_point && !window_outdated (w))
10918 && (w->column_number_displayed != current_column ()));
10919 }
10920
10921 /* Nonzero if window start of W is frozen and may not be changed during
10922 redisplay. */
10923
10924 static bool
10925 window_frozen_p (struct window *w)
10926 {
10927 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
10928 {
10929 Lisp_Object window;
10930
10931 XSETWINDOW (window, w);
10932 if (MINI_WINDOW_P (w))
10933 return 0;
10934 else if (EQ (window, selected_window))
10935 return 0;
10936 else if (MINI_WINDOW_P (XWINDOW (selected_window))
10937 && EQ (window, Vminibuf_scroll_window))
10938 /* This special window can't be frozen too. */
10939 return 0;
10940 else
10941 return 1;
10942 }
10943 return 0;
10944 }
10945
10946 /***********************************************************************
10947 Mode Lines and Frame Titles
10948 ***********************************************************************/
10949
10950 /* A buffer for constructing non-propertized mode-line strings and
10951 frame titles in it; allocated from the heap in init_xdisp and
10952 resized as needed in store_mode_line_noprop_char. */
10953
10954 static char *mode_line_noprop_buf;
10955
10956 /* The buffer's end, and a current output position in it. */
10957
10958 static char *mode_line_noprop_buf_end;
10959 static char *mode_line_noprop_ptr;
10960
10961 #define MODE_LINE_NOPROP_LEN(start) \
10962 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10963
10964 static enum {
10965 MODE_LINE_DISPLAY = 0,
10966 MODE_LINE_TITLE,
10967 MODE_LINE_NOPROP,
10968 MODE_LINE_STRING
10969 } mode_line_target;
10970
10971 /* Alist that caches the results of :propertize.
10972 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10973 static Lisp_Object mode_line_proptrans_alist;
10974
10975 /* List of strings making up the mode-line. */
10976 static Lisp_Object mode_line_string_list;
10977
10978 /* Base face property when building propertized mode line string. */
10979 static Lisp_Object mode_line_string_face;
10980 static Lisp_Object mode_line_string_face_prop;
10981
10982
10983 /* Unwind data for mode line strings */
10984
10985 static Lisp_Object Vmode_line_unwind_vector;
10986
10987 static Lisp_Object
10988 format_mode_line_unwind_data (struct frame *target_frame,
10989 struct buffer *obuf,
10990 Lisp_Object owin,
10991 int save_proptrans)
10992 {
10993 Lisp_Object vector, tmp;
10994
10995 /* Reduce consing by keeping one vector in
10996 Vwith_echo_area_save_vector. */
10997 vector = Vmode_line_unwind_vector;
10998 Vmode_line_unwind_vector = Qnil;
10999
11000 if (NILP (vector))
11001 vector = Fmake_vector (make_number (10), Qnil);
11002
11003 ASET (vector, 0, make_number (mode_line_target));
11004 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11005 ASET (vector, 2, mode_line_string_list);
11006 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11007 ASET (vector, 4, mode_line_string_face);
11008 ASET (vector, 5, mode_line_string_face_prop);
11009
11010 if (obuf)
11011 XSETBUFFER (tmp, obuf);
11012 else
11013 tmp = Qnil;
11014 ASET (vector, 6, tmp);
11015 ASET (vector, 7, owin);
11016 if (target_frame)
11017 {
11018 /* Similarly to `with-selected-window', if the operation selects
11019 a window on another frame, we must restore that frame's
11020 selected window, and (for a tty) the top-frame. */
11021 ASET (vector, 8, target_frame->selected_window);
11022 if (FRAME_TERMCAP_P (target_frame))
11023 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11024 }
11025
11026 return vector;
11027 }
11028
11029 static void
11030 unwind_format_mode_line (Lisp_Object vector)
11031 {
11032 Lisp_Object old_window = AREF (vector, 7);
11033 Lisp_Object target_frame_window = AREF (vector, 8);
11034 Lisp_Object old_top_frame = AREF (vector, 9);
11035
11036 mode_line_target = XINT (AREF (vector, 0));
11037 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11038 mode_line_string_list = AREF (vector, 2);
11039 if (! EQ (AREF (vector, 3), Qt))
11040 mode_line_proptrans_alist = AREF (vector, 3);
11041 mode_line_string_face = AREF (vector, 4);
11042 mode_line_string_face_prop = AREF (vector, 5);
11043
11044 /* Select window before buffer, since it may change the buffer. */
11045 if (!NILP (old_window))
11046 {
11047 /* If the operation that we are unwinding had selected a window
11048 on a different frame, reset its frame-selected-window. For a
11049 text terminal, reset its top-frame if necessary. */
11050 if (!NILP (target_frame_window))
11051 {
11052 Lisp_Object frame
11053 = WINDOW_FRAME (XWINDOW (target_frame_window));
11054
11055 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11056 Fselect_window (target_frame_window, Qt);
11057
11058 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11059 Fselect_frame (old_top_frame, Qt);
11060 }
11061
11062 Fselect_window (old_window, Qt);
11063 }
11064
11065 if (!NILP (AREF (vector, 6)))
11066 {
11067 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11068 ASET (vector, 6, Qnil);
11069 }
11070
11071 Vmode_line_unwind_vector = vector;
11072 }
11073
11074
11075 /* Store a single character C for the frame title in mode_line_noprop_buf.
11076 Re-allocate mode_line_noprop_buf if necessary. */
11077
11078 static void
11079 store_mode_line_noprop_char (char c)
11080 {
11081 /* If output position has reached the end of the allocated buffer,
11082 increase the buffer's size. */
11083 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11084 {
11085 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11086 ptrdiff_t size = len;
11087 mode_line_noprop_buf =
11088 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11089 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11090 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11091 }
11092
11093 *mode_line_noprop_ptr++ = c;
11094 }
11095
11096
11097 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11098 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11099 characters that yield more columns than PRECISION; PRECISION <= 0
11100 means copy the whole string. Pad with spaces until FIELD_WIDTH
11101 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11102 pad. Called from display_mode_element when it is used to build a
11103 frame title. */
11104
11105 static int
11106 store_mode_line_noprop (const char *string, int field_width, int precision)
11107 {
11108 const unsigned char *str = (const unsigned char *) string;
11109 int n = 0;
11110 ptrdiff_t dummy, nbytes;
11111
11112 /* Copy at most PRECISION chars from STR. */
11113 nbytes = strlen (string);
11114 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11115 while (nbytes--)
11116 store_mode_line_noprop_char (*str++);
11117
11118 /* Fill up with spaces until FIELD_WIDTH reached. */
11119 while (field_width > 0
11120 && n < field_width)
11121 {
11122 store_mode_line_noprop_char (' ');
11123 ++n;
11124 }
11125
11126 return n;
11127 }
11128
11129 /***********************************************************************
11130 Frame Titles
11131 ***********************************************************************/
11132
11133 #ifdef HAVE_WINDOW_SYSTEM
11134
11135 /* Set the title of FRAME, if it has changed. The title format is
11136 Vicon_title_format if FRAME is iconified, otherwise it is
11137 frame_title_format. */
11138
11139 static void
11140 x_consider_frame_title (Lisp_Object frame)
11141 {
11142 struct frame *f = XFRAME (frame);
11143
11144 if (FRAME_WINDOW_P (f)
11145 || FRAME_MINIBUF_ONLY_P (f)
11146 || f->explicit_name)
11147 {
11148 /* Do we have more than one visible frame on this X display? */
11149 Lisp_Object tail, other_frame, fmt;
11150 ptrdiff_t title_start;
11151 char *title;
11152 ptrdiff_t len;
11153 struct it it;
11154 ptrdiff_t count = SPECPDL_INDEX ();
11155
11156 FOR_EACH_FRAME (tail, other_frame)
11157 {
11158 struct frame *tf = XFRAME (other_frame);
11159
11160 if (tf != f
11161 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11162 && !FRAME_MINIBUF_ONLY_P (tf)
11163 && !EQ (other_frame, tip_frame)
11164 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11165 break;
11166 }
11167
11168 /* Set global variable indicating that multiple frames exist. */
11169 multiple_frames = CONSP (tail);
11170
11171 /* Switch to the buffer of selected window of the frame. Set up
11172 mode_line_target so that display_mode_element will output into
11173 mode_line_noprop_buf; then display the title. */
11174 record_unwind_protect (unwind_format_mode_line,
11175 format_mode_line_unwind_data
11176 (f, current_buffer, selected_window, 0));
11177
11178 Fselect_window (f->selected_window, Qt);
11179 set_buffer_internal_1
11180 (XBUFFER (XWINDOW (f->selected_window)->contents));
11181 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11182
11183 mode_line_target = MODE_LINE_TITLE;
11184 title_start = MODE_LINE_NOPROP_LEN (0);
11185 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11186 NULL, DEFAULT_FACE_ID);
11187 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11188 len = MODE_LINE_NOPROP_LEN (title_start);
11189 title = mode_line_noprop_buf + title_start;
11190 unbind_to (count, Qnil);
11191
11192 /* Set the title only if it's changed. This avoids consing in
11193 the common case where it hasn't. (If it turns out that we've
11194 already wasted too much time by walking through the list with
11195 display_mode_element, then we might need to optimize at a
11196 higher level than this.) */
11197 if (! STRINGP (f->name)
11198 || SBYTES (f->name) != len
11199 || memcmp (title, SDATA (f->name), len) != 0)
11200 x_implicitly_set_name (f, make_string (title, len), Qnil);
11201 }
11202 }
11203
11204 #endif /* not HAVE_WINDOW_SYSTEM */
11205
11206 \f
11207 /***********************************************************************
11208 Menu Bars
11209 ***********************************************************************/
11210
11211
11212 /* Prepare for redisplay by updating menu-bar item lists when
11213 appropriate. This can call eval. */
11214
11215 void
11216 prepare_menu_bars (void)
11217 {
11218 int all_windows;
11219 struct gcpro gcpro1, gcpro2;
11220 struct frame *f;
11221 Lisp_Object tooltip_frame;
11222
11223 #ifdef HAVE_WINDOW_SYSTEM
11224 tooltip_frame = tip_frame;
11225 #else
11226 tooltip_frame = Qnil;
11227 #endif
11228
11229 /* Update all frame titles based on their buffer names, etc. We do
11230 this before the menu bars so that the buffer-menu will show the
11231 up-to-date frame titles. */
11232 #ifdef HAVE_WINDOW_SYSTEM
11233 if (windows_or_buffers_changed || update_mode_lines)
11234 {
11235 Lisp_Object tail, frame;
11236
11237 FOR_EACH_FRAME (tail, frame)
11238 {
11239 f = XFRAME (frame);
11240 if (!EQ (frame, tooltip_frame)
11241 && (FRAME_ICONIFIED_P (f)
11242 || FRAME_VISIBLE_P (f) == 1
11243 /* Exclude TTY frames that are obscured because they
11244 are not the top frame on their console. This is
11245 because x_consider_frame_title actually switches
11246 to the frame, which for TTY frames means it is
11247 marked as garbaged, and will be completely
11248 redrawn on the next redisplay cycle. This causes
11249 TTY frames to be completely redrawn, when there
11250 are more than one of them, even though nothing
11251 should be changed on display. */
11252 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11253 x_consider_frame_title (frame);
11254 }
11255 }
11256 #endif /* HAVE_WINDOW_SYSTEM */
11257
11258 /* Update the menu bar item lists, if appropriate. This has to be
11259 done before any actual redisplay or generation of display lines. */
11260 all_windows = (update_mode_lines
11261 || buffer_shared_and_changed ()
11262 || windows_or_buffers_changed);
11263 if (all_windows)
11264 {
11265 Lisp_Object tail, frame;
11266 ptrdiff_t count = SPECPDL_INDEX ();
11267 /* 1 means that update_menu_bar has run its hooks
11268 so any further calls to update_menu_bar shouldn't do so again. */
11269 int menu_bar_hooks_run = 0;
11270
11271 record_unwind_save_match_data ();
11272
11273 FOR_EACH_FRAME (tail, frame)
11274 {
11275 f = XFRAME (frame);
11276
11277 /* Ignore tooltip frame. */
11278 if (EQ (frame, tooltip_frame))
11279 continue;
11280
11281 /* If a window on this frame changed size, report that to
11282 the user and clear the size-change flag. */
11283 if (FRAME_WINDOW_SIZES_CHANGED (f))
11284 {
11285 Lisp_Object functions;
11286
11287 /* Clear flag first in case we get an error below. */
11288 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11289 functions = Vwindow_size_change_functions;
11290 GCPRO2 (tail, functions);
11291
11292 while (CONSP (functions))
11293 {
11294 if (!EQ (XCAR (functions), Qt))
11295 call1 (XCAR (functions), frame);
11296 functions = XCDR (functions);
11297 }
11298 UNGCPRO;
11299 }
11300
11301 GCPRO1 (tail);
11302 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11303 #ifdef HAVE_WINDOW_SYSTEM
11304 update_tool_bar (f, 0);
11305 #endif
11306 #ifdef HAVE_NS
11307 if (windows_or_buffers_changed
11308 && FRAME_NS_P (f))
11309 ns_set_doc_edited
11310 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11311 #endif
11312 UNGCPRO;
11313 }
11314
11315 unbind_to (count, Qnil);
11316 }
11317 else
11318 {
11319 struct frame *sf = SELECTED_FRAME ();
11320 update_menu_bar (sf, 1, 0);
11321 #ifdef HAVE_WINDOW_SYSTEM
11322 update_tool_bar (sf, 1);
11323 #endif
11324 }
11325 }
11326
11327
11328 /* Update the menu bar item list for frame F. This has to be done
11329 before we start to fill in any display lines, because it can call
11330 eval.
11331
11332 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11333
11334 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11335 already ran the menu bar hooks for this redisplay, so there
11336 is no need to run them again. The return value is the
11337 updated value of this flag, to pass to the next call. */
11338
11339 static int
11340 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11341 {
11342 Lisp_Object window;
11343 register struct window *w;
11344
11345 /* If called recursively during a menu update, do nothing. This can
11346 happen when, for instance, an activate-menubar-hook causes a
11347 redisplay. */
11348 if (inhibit_menubar_update)
11349 return hooks_run;
11350
11351 window = FRAME_SELECTED_WINDOW (f);
11352 w = XWINDOW (window);
11353
11354 if (FRAME_WINDOW_P (f)
11355 ?
11356 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11357 || defined (HAVE_NS) || defined (USE_GTK)
11358 FRAME_EXTERNAL_MENU_BAR (f)
11359 #else
11360 FRAME_MENU_BAR_LINES (f) > 0
11361 #endif
11362 : FRAME_MENU_BAR_LINES (f) > 0)
11363 {
11364 /* If the user has switched buffers or windows, we need to
11365 recompute to reflect the new bindings. But we'll
11366 recompute when update_mode_lines is set too; that means
11367 that people can use force-mode-line-update to request
11368 that the menu bar be recomputed. The adverse effect on
11369 the rest of the redisplay algorithm is about the same as
11370 windows_or_buffers_changed anyway. */
11371 if (windows_or_buffers_changed
11372 /* This used to test w->update_mode_line, but we believe
11373 there is no need to recompute the menu in that case. */
11374 || update_mode_lines
11375 || window_buffer_changed (w))
11376 {
11377 struct buffer *prev = current_buffer;
11378 ptrdiff_t count = SPECPDL_INDEX ();
11379
11380 specbind (Qinhibit_menubar_update, Qt);
11381
11382 set_buffer_internal_1 (XBUFFER (w->contents));
11383 if (save_match_data)
11384 record_unwind_save_match_data ();
11385 if (NILP (Voverriding_local_map_menu_flag))
11386 {
11387 specbind (Qoverriding_terminal_local_map, Qnil);
11388 specbind (Qoverriding_local_map, Qnil);
11389 }
11390
11391 if (!hooks_run)
11392 {
11393 /* Run the Lucid hook. */
11394 safe_run_hooks (Qactivate_menubar_hook);
11395
11396 /* If it has changed current-menubar from previous value,
11397 really recompute the menu-bar from the value. */
11398 if (! NILP (Vlucid_menu_bar_dirty_flag))
11399 call0 (Qrecompute_lucid_menubar);
11400
11401 safe_run_hooks (Qmenu_bar_update_hook);
11402
11403 hooks_run = 1;
11404 }
11405
11406 XSETFRAME (Vmenu_updating_frame, f);
11407 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11408
11409 /* Redisplay the menu bar in case we changed it. */
11410 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11411 || defined (HAVE_NS) || defined (USE_GTK)
11412 if (FRAME_WINDOW_P (f))
11413 {
11414 #if defined (HAVE_NS)
11415 /* All frames on Mac OS share the same menubar. So only
11416 the selected frame should be allowed to set it. */
11417 if (f == SELECTED_FRAME ())
11418 #endif
11419 set_frame_menubar (f, 0, 0);
11420 }
11421 else
11422 /* On a terminal screen, the menu bar is an ordinary screen
11423 line, and this makes it get updated. */
11424 w->update_mode_line = 1;
11425 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11426 /* In the non-toolkit version, the menu bar is an ordinary screen
11427 line, and this makes it get updated. */
11428 w->update_mode_line = 1;
11429 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11430
11431 unbind_to (count, Qnil);
11432 set_buffer_internal_1 (prev);
11433 }
11434 }
11435
11436 return hooks_run;
11437 }
11438
11439 /***********************************************************************
11440 Tool-bars
11441 ***********************************************************************/
11442
11443 #ifdef HAVE_WINDOW_SYSTEM
11444
11445 /* Where the mouse was last time we reported a mouse event. */
11446
11447 struct frame *last_mouse_frame;
11448
11449 /* Tool-bar item index of the item on which a mouse button was pressed
11450 or -1. */
11451
11452 int last_tool_bar_item;
11453
11454 /* Select `frame' temporarily without running all the code in
11455 do_switch_frame.
11456 FIXME: Maybe do_switch_frame should be trimmed down similarly
11457 when `norecord' is set. */
11458 static void
11459 fast_set_selected_frame (Lisp_Object frame)
11460 {
11461 if (!EQ (selected_frame, frame))
11462 {
11463 selected_frame = frame;
11464 selected_window = XFRAME (frame)->selected_window;
11465 }
11466 }
11467
11468 /* Update the tool-bar item list for frame F. This has to be done
11469 before we start to fill in any display lines. Called from
11470 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11471 and restore it here. */
11472
11473 static void
11474 update_tool_bar (struct frame *f, int save_match_data)
11475 {
11476 #if defined (USE_GTK) || defined (HAVE_NS)
11477 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11478 #else
11479 int do_update = WINDOWP (f->tool_bar_window)
11480 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11481 #endif
11482
11483 if (do_update)
11484 {
11485 Lisp_Object window;
11486 struct window *w;
11487
11488 window = FRAME_SELECTED_WINDOW (f);
11489 w = XWINDOW (window);
11490
11491 /* If the user has switched buffers or windows, we need to
11492 recompute to reflect the new bindings. But we'll
11493 recompute when update_mode_lines is set too; that means
11494 that people can use force-mode-line-update to request
11495 that the menu bar be recomputed. The adverse effect on
11496 the rest of the redisplay algorithm is about the same as
11497 windows_or_buffers_changed anyway. */
11498 if (windows_or_buffers_changed
11499 || w->update_mode_line
11500 || update_mode_lines
11501 || window_buffer_changed (w))
11502 {
11503 struct buffer *prev = current_buffer;
11504 ptrdiff_t count = SPECPDL_INDEX ();
11505 Lisp_Object frame, new_tool_bar;
11506 int new_n_tool_bar;
11507 struct gcpro gcpro1;
11508
11509 /* Set current_buffer to the buffer of the selected
11510 window of the frame, so that we get the right local
11511 keymaps. */
11512 set_buffer_internal_1 (XBUFFER (w->contents));
11513
11514 /* Save match data, if we must. */
11515 if (save_match_data)
11516 record_unwind_save_match_data ();
11517
11518 /* Make sure that we don't accidentally use bogus keymaps. */
11519 if (NILP (Voverriding_local_map_menu_flag))
11520 {
11521 specbind (Qoverriding_terminal_local_map, Qnil);
11522 specbind (Qoverriding_local_map, Qnil);
11523 }
11524
11525 GCPRO1 (new_tool_bar);
11526
11527 /* We must temporarily set the selected frame to this frame
11528 before calling tool_bar_items, because the calculation of
11529 the tool-bar keymap uses the selected frame (see
11530 `tool-bar-make-keymap' in tool-bar.el). */
11531 eassert (EQ (selected_window,
11532 /* Since we only explicitly preserve selected_frame,
11533 check that selected_window would be redundant. */
11534 XFRAME (selected_frame)->selected_window));
11535 record_unwind_protect (fast_set_selected_frame, selected_frame);
11536 XSETFRAME (frame, f);
11537 fast_set_selected_frame (frame);
11538
11539 /* Build desired tool-bar items from keymaps. */
11540 new_tool_bar
11541 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11542 &new_n_tool_bar);
11543
11544 /* Redisplay the tool-bar if we changed it. */
11545 if (new_n_tool_bar != f->n_tool_bar_items
11546 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11547 {
11548 /* Redisplay that happens asynchronously due to an expose event
11549 may access f->tool_bar_items. Make sure we update both
11550 variables within BLOCK_INPUT so no such event interrupts. */
11551 block_input ();
11552 fset_tool_bar_items (f, new_tool_bar);
11553 f->n_tool_bar_items = new_n_tool_bar;
11554 w->update_mode_line = 1;
11555 unblock_input ();
11556 }
11557
11558 UNGCPRO;
11559
11560 unbind_to (count, Qnil);
11561 set_buffer_internal_1 (prev);
11562 }
11563 }
11564 }
11565
11566 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11567
11568 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11569 F's desired tool-bar contents. F->tool_bar_items must have
11570 been set up previously by calling prepare_menu_bars. */
11571
11572 static void
11573 build_desired_tool_bar_string (struct frame *f)
11574 {
11575 int i, size, size_needed;
11576 struct gcpro gcpro1, gcpro2, gcpro3;
11577 Lisp_Object image, plist, props;
11578
11579 image = plist = props = Qnil;
11580 GCPRO3 (image, plist, props);
11581
11582 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11583 Otherwise, make a new string. */
11584
11585 /* The size of the string we might be able to reuse. */
11586 size = (STRINGP (f->desired_tool_bar_string)
11587 ? SCHARS (f->desired_tool_bar_string)
11588 : 0);
11589
11590 /* We need one space in the string for each image. */
11591 size_needed = f->n_tool_bar_items;
11592
11593 /* Reuse f->desired_tool_bar_string, if possible. */
11594 if (size < size_needed || NILP (f->desired_tool_bar_string))
11595 fset_desired_tool_bar_string
11596 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11597 else
11598 {
11599 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11600 Fremove_text_properties (make_number (0), make_number (size),
11601 props, f->desired_tool_bar_string);
11602 }
11603
11604 /* Put a `display' property on the string for the images to display,
11605 put a `menu_item' property on tool-bar items with a value that
11606 is the index of the item in F's tool-bar item vector. */
11607 for (i = 0; i < f->n_tool_bar_items; ++i)
11608 {
11609 #define PROP(IDX) \
11610 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11611
11612 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11613 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11614 int hmargin, vmargin, relief, idx, end;
11615
11616 /* If image is a vector, choose the image according to the
11617 button state. */
11618 image = PROP (TOOL_BAR_ITEM_IMAGES);
11619 if (VECTORP (image))
11620 {
11621 if (enabled_p)
11622 idx = (selected_p
11623 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11624 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11625 else
11626 idx = (selected_p
11627 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11628 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11629
11630 eassert (ASIZE (image) >= idx);
11631 image = AREF (image, idx);
11632 }
11633 else
11634 idx = -1;
11635
11636 /* Ignore invalid image specifications. */
11637 if (!valid_image_p (image))
11638 continue;
11639
11640 /* Display the tool-bar button pressed, or depressed. */
11641 plist = Fcopy_sequence (XCDR (image));
11642
11643 /* Compute margin and relief to draw. */
11644 relief = (tool_bar_button_relief >= 0
11645 ? tool_bar_button_relief
11646 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11647 hmargin = vmargin = relief;
11648
11649 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11650 INT_MAX - max (hmargin, vmargin)))
11651 {
11652 hmargin += XFASTINT (Vtool_bar_button_margin);
11653 vmargin += XFASTINT (Vtool_bar_button_margin);
11654 }
11655 else if (CONSP (Vtool_bar_button_margin))
11656 {
11657 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11658 INT_MAX - hmargin))
11659 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11660
11661 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11662 INT_MAX - vmargin))
11663 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11664 }
11665
11666 if (auto_raise_tool_bar_buttons_p)
11667 {
11668 /* Add a `:relief' property to the image spec if the item is
11669 selected. */
11670 if (selected_p)
11671 {
11672 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11673 hmargin -= relief;
11674 vmargin -= relief;
11675 }
11676 }
11677 else
11678 {
11679 /* If image is selected, display it pressed, i.e. with a
11680 negative relief. If it's not selected, display it with a
11681 raised relief. */
11682 plist = Fplist_put (plist, QCrelief,
11683 (selected_p
11684 ? make_number (-relief)
11685 : make_number (relief)));
11686 hmargin -= relief;
11687 vmargin -= relief;
11688 }
11689
11690 /* Put a margin around the image. */
11691 if (hmargin || vmargin)
11692 {
11693 if (hmargin == vmargin)
11694 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11695 else
11696 plist = Fplist_put (plist, QCmargin,
11697 Fcons (make_number (hmargin),
11698 make_number (vmargin)));
11699 }
11700
11701 /* If button is not enabled, and we don't have special images
11702 for the disabled state, make the image appear disabled by
11703 applying an appropriate algorithm to it. */
11704 if (!enabled_p && idx < 0)
11705 plist = Fplist_put (plist, QCconversion, Qdisabled);
11706
11707 /* Put a `display' text property on the string for the image to
11708 display. Put a `menu-item' property on the string that gives
11709 the start of this item's properties in the tool-bar items
11710 vector. */
11711 image = Fcons (Qimage, plist);
11712 props = list4 (Qdisplay, image,
11713 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11714
11715 /* Let the last image hide all remaining spaces in the tool bar
11716 string. The string can be longer than needed when we reuse a
11717 previous string. */
11718 if (i + 1 == f->n_tool_bar_items)
11719 end = SCHARS (f->desired_tool_bar_string);
11720 else
11721 end = i + 1;
11722 Fadd_text_properties (make_number (i), make_number (end),
11723 props, f->desired_tool_bar_string);
11724 #undef PROP
11725 }
11726
11727 UNGCPRO;
11728 }
11729
11730
11731 /* Display one line of the tool-bar of frame IT->f.
11732
11733 HEIGHT specifies the desired height of the tool-bar line.
11734 If the actual height of the glyph row is less than HEIGHT, the
11735 row's height is increased to HEIGHT, and the icons are centered
11736 vertically in the new height.
11737
11738 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11739 count a final empty row in case the tool-bar width exactly matches
11740 the window width.
11741 */
11742
11743 static void
11744 display_tool_bar_line (struct it *it, int height)
11745 {
11746 struct glyph_row *row = it->glyph_row;
11747 int max_x = it->last_visible_x;
11748 struct glyph *last;
11749
11750 prepare_desired_row (row);
11751 row->y = it->current_y;
11752
11753 /* Note that this isn't made use of if the face hasn't a box,
11754 so there's no need to check the face here. */
11755 it->start_of_box_run_p = 1;
11756
11757 while (it->current_x < max_x)
11758 {
11759 int x, n_glyphs_before, i, nglyphs;
11760 struct it it_before;
11761
11762 /* Get the next display element. */
11763 if (!get_next_display_element (it))
11764 {
11765 /* Don't count empty row if we are counting needed tool-bar lines. */
11766 if (height < 0 && !it->hpos)
11767 return;
11768 break;
11769 }
11770
11771 /* Produce glyphs. */
11772 n_glyphs_before = row->used[TEXT_AREA];
11773 it_before = *it;
11774
11775 PRODUCE_GLYPHS (it);
11776
11777 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11778 i = 0;
11779 x = it_before.current_x;
11780 while (i < nglyphs)
11781 {
11782 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11783
11784 if (x + glyph->pixel_width > max_x)
11785 {
11786 /* Glyph doesn't fit on line. Backtrack. */
11787 row->used[TEXT_AREA] = n_glyphs_before;
11788 *it = it_before;
11789 /* If this is the only glyph on this line, it will never fit on the
11790 tool-bar, so skip it. But ensure there is at least one glyph,
11791 so we don't accidentally disable the tool-bar. */
11792 if (n_glyphs_before == 0
11793 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11794 break;
11795 goto out;
11796 }
11797
11798 ++it->hpos;
11799 x += glyph->pixel_width;
11800 ++i;
11801 }
11802
11803 /* Stop at line end. */
11804 if (ITERATOR_AT_END_OF_LINE_P (it))
11805 break;
11806
11807 set_iterator_to_next (it, 1);
11808 }
11809
11810 out:;
11811
11812 row->displays_text_p = row->used[TEXT_AREA] != 0;
11813
11814 /* Use default face for the border below the tool bar.
11815
11816 FIXME: When auto-resize-tool-bars is grow-only, there is
11817 no additional border below the possibly empty tool-bar lines.
11818 So to make the extra empty lines look "normal", we have to
11819 use the tool-bar face for the border too. */
11820 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11821 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11822 it->face_id = DEFAULT_FACE_ID;
11823
11824 extend_face_to_end_of_line (it);
11825 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11826 last->right_box_line_p = 1;
11827 if (last == row->glyphs[TEXT_AREA])
11828 last->left_box_line_p = 1;
11829
11830 /* Make line the desired height and center it vertically. */
11831 if ((height -= it->max_ascent + it->max_descent) > 0)
11832 {
11833 /* Don't add more than one line height. */
11834 height %= FRAME_LINE_HEIGHT (it->f);
11835 it->max_ascent += height / 2;
11836 it->max_descent += (height + 1) / 2;
11837 }
11838
11839 compute_line_metrics (it);
11840
11841 /* If line is empty, make it occupy the rest of the tool-bar. */
11842 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11843 {
11844 row->height = row->phys_height = it->last_visible_y - row->y;
11845 row->visible_height = row->height;
11846 row->ascent = row->phys_ascent = 0;
11847 row->extra_line_spacing = 0;
11848 }
11849
11850 row->full_width_p = 1;
11851 row->continued_p = 0;
11852 row->truncated_on_left_p = 0;
11853 row->truncated_on_right_p = 0;
11854
11855 it->current_x = it->hpos = 0;
11856 it->current_y += row->height;
11857 ++it->vpos;
11858 ++it->glyph_row;
11859 }
11860
11861
11862 /* Max tool-bar height. */
11863
11864 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11865 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11866
11867 /* Value is the number of screen lines needed to make all tool-bar
11868 items of frame F visible. The number of actual rows needed is
11869 returned in *N_ROWS if non-NULL. */
11870
11871 static int
11872 tool_bar_lines_needed (struct frame *f, int *n_rows)
11873 {
11874 struct window *w = XWINDOW (f->tool_bar_window);
11875 struct it it;
11876 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11877 the desired matrix, so use (unused) mode-line row as temporary row to
11878 avoid destroying the first tool-bar row. */
11879 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11880
11881 /* Initialize an iterator for iteration over
11882 F->desired_tool_bar_string in the tool-bar window of frame F. */
11883 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11884 it.first_visible_x = 0;
11885 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11886 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11887 it.paragraph_embedding = L2R;
11888
11889 while (!ITERATOR_AT_END_P (&it))
11890 {
11891 clear_glyph_row (temp_row);
11892 it.glyph_row = temp_row;
11893 display_tool_bar_line (&it, -1);
11894 }
11895 clear_glyph_row (temp_row);
11896
11897 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11898 if (n_rows)
11899 *n_rows = it.vpos > 0 ? it.vpos : -1;
11900
11901 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11902 }
11903
11904 #endif /* !USE_GTK && !HAVE_NS */
11905
11906 #if defined USE_GTK || defined HAVE_NS
11907 EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
11908 #endif
11909
11910 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11911 0, 1, 0,
11912 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11913 If FRAME is nil or omitted, use the selected frame. */)
11914 (Lisp_Object frame)
11915 {
11916 int nlines = 0;
11917 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11918 struct frame *f = decode_any_frame (frame);
11919 struct window *w;
11920
11921 if (WINDOWP (f->tool_bar_window)
11922 && (w = XWINDOW (f->tool_bar_window),
11923 WINDOW_TOTAL_LINES (w) > 0))
11924 {
11925 update_tool_bar (f, 1);
11926 if (f->n_tool_bar_items)
11927 {
11928 build_desired_tool_bar_string (f);
11929 nlines = tool_bar_lines_needed (f, NULL);
11930 }
11931 }
11932 #endif
11933 return make_number (nlines);
11934 }
11935
11936
11937 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11938 height should be changed. */
11939
11940 static int
11941 redisplay_tool_bar (struct frame *f)
11942 {
11943 #if defined (USE_GTK) || defined (HAVE_NS)
11944
11945 if (FRAME_EXTERNAL_TOOL_BAR (f))
11946 update_frame_tool_bar (f);
11947 return 0;
11948
11949 #else /* !USE_GTK && !HAVE_NS */
11950
11951 struct window *w;
11952 struct it it;
11953 struct glyph_row *row;
11954
11955 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11956 do anything. This means you must start with tool-bar-lines
11957 non-zero to get the auto-sizing effect. Or in other words, you
11958 can turn off tool-bars by specifying tool-bar-lines zero. */
11959 if (!WINDOWP (f->tool_bar_window)
11960 || (w = XWINDOW (f->tool_bar_window),
11961 WINDOW_TOTAL_LINES (w) == 0))
11962 return 0;
11963
11964 /* Set up an iterator for the tool-bar window. */
11965 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11966 it.first_visible_x = 0;
11967 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11968 row = it.glyph_row;
11969
11970 /* Build a string that represents the contents of the tool-bar. */
11971 build_desired_tool_bar_string (f);
11972 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11973 /* FIXME: This should be controlled by a user option. But it
11974 doesn't make sense to have an R2L tool bar if the menu bar cannot
11975 be drawn also R2L, and making the menu bar R2L is tricky due
11976 toolkit-specific code that implements it. If an R2L tool bar is
11977 ever supported, display_tool_bar_line should also be augmented to
11978 call unproduce_glyphs like display_line and display_string
11979 do. */
11980 it.paragraph_embedding = L2R;
11981
11982 if (f->n_tool_bar_rows == 0)
11983 {
11984 int nlines;
11985
11986 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11987 nlines != WINDOW_TOTAL_LINES (w)))
11988 {
11989 Lisp_Object frame;
11990 int old_height = WINDOW_TOTAL_LINES (w);
11991
11992 XSETFRAME (frame, f);
11993 Fmodify_frame_parameters (frame,
11994 list1 (Fcons (Qtool_bar_lines,
11995 make_number (nlines))));
11996 if (WINDOW_TOTAL_LINES (w) != old_height)
11997 {
11998 clear_glyph_matrix (w->desired_matrix);
11999 f->fonts_changed = 1;
12000 return 1;
12001 }
12002 }
12003 }
12004
12005 /* Display as many lines as needed to display all tool-bar items. */
12006
12007 if (f->n_tool_bar_rows > 0)
12008 {
12009 int border, rows, height, extra;
12010
12011 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12012 border = XINT (Vtool_bar_border);
12013 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12014 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12015 else if (EQ (Vtool_bar_border, Qborder_width))
12016 border = f->border_width;
12017 else
12018 border = 0;
12019 if (border < 0)
12020 border = 0;
12021
12022 rows = f->n_tool_bar_rows;
12023 height = max (1, (it.last_visible_y - border) / rows);
12024 extra = it.last_visible_y - border - height * rows;
12025
12026 while (it.current_y < it.last_visible_y)
12027 {
12028 int h = 0;
12029 if (extra > 0 && rows-- > 0)
12030 {
12031 h = (extra + rows - 1) / rows;
12032 extra -= h;
12033 }
12034 display_tool_bar_line (&it, height + h);
12035 }
12036 }
12037 else
12038 {
12039 while (it.current_y < it.last_visible_y)
12040 display_tool_bar_line (&it, 0);
12041 }
12042
12043 /* It doesn't make much sense to try scrolling in the tool-bar
12044 window, so don't do it. */
12045 w->desired_matrix->no_scrolling_p = 1;
12046 w->must_be_updated_p = 1;
12047
12048 if (!NILP (Vauto_resize_tool_bars))
12049 {
12050 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12051 int change_height_p = 0;
12052
12053 /* If we couldn't display everything, change the tool-bar's
12054 height if there is room for more. */
12055 if (IT_STRING_CHARPOS (it) < it.end_charpos
12056 && it.current_y < max_tool_bar_height)
12057 change_height_p = 1;
12058
12059 row = it.glyph_row - 1;
12060
12061 /* If there are blank lines at the end, except for a partially
12062 visible blank line at the end that is smaller than
12063 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12064 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12065 && row->height >= FRAME_LINE_HEIGHT (f))
12066 change_height_p = 1;
12067
12068 /* If row displays tool-bar items, but is partially visible,
12069 change the tool-bar's height. */
12070 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12071 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12072 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12073 change_height_p = 1;
12074
12075 /* Resize windows as needed by changing the `tool-bar-lines'
12076 frame parameter. */
12077 if (change_height_p)
12078 {
12079 Lisp_Object frame;
12080 int old_height = WINDOW_TOTAL_LINES (w);
12081 int nrows;
12082 int nlines = tool_bar_lines_needed (f, &nrows);
12083
12084 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12085 && !f->minimize_tool_bar_window_p)
12086 ? (nlines > old_height)
12087 : (nlines != old_height));
12088 f->minimize_tool_bar_window_p = 0;
12089
12090 if (change_height_p)
12091 {
12092 XSETFRAME (frame, f);
12093 Fmodify_frame_parameters (frame,
12094 list1 (Fcons (Qtool_bar_lines,
12095 make_number (nlines))));
12096 if (WINDOW_TOTAL_LINES (w) != old_height)
12097 {
12098 clear_glyph_matrix (w->desired_matrix);
12099 f->n_tool_bar_rows = nrows;
12100 f->fonts_changed = 1;
12101 return 1;
12102 }
12103 }
12104 }
12105 }
12106
12107 f->minimize_tool_bar_window_p = 0;
12108 return 0;
12109
12110 #endif /* USE_GTK || HAVE_NS */
12111 }
12112
12113 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12114
12115 /* Get information about the tool-bar item which is displayed in GLYPH
12116 on frame F. Return in *PROP_IDX the index where tool-bar item
12117 properties start in F->tool_bar_items. Value is zero if
12118 GLYPH doesn't display a tool-bar item. */
12119
12120 static int
12121 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12122 {
12123 Lisp_Object prop;
12124 int success_p;
12125 int charpos;
12126
12127 /* This function can be called asynchronously, which means we must
12128 exclude any possibility that Fget_text_property signals an
12129 error. */
12130 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12131 charpos = max (0, charpos);
12132
12133 /* Get the text property `menu-item' at pos. The value of that
12134 property is the start index of this item's properties in
12135 F->tool_bar_items. */
12136 prop = Fget_text_property (make_number (charpos),
12137 Qmenu_item, f->current_tool_bar_string);
12138 if (INTEGERP (prop))
12139 {
12140 *prop_idx = XINT (prop);
12141 success_p = 1;
12142 }
12143 else
12144 success_p = 0;
12145
12146 return success_p;
12147 }
12148
12149 \f
12150 /* Get information about the tool-bar item at position X/Y on frame F.
12151 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12152 the current matrix of the tool-bar window of F, or NULL if not
12153 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12154 item in F->tool_bar_items. Value is
12155
12156 -1 if X/Y is not on a tool-bar item
12157 0 if X/Y is on the same item that was highlighted before.
12158 1 otherwise. */
12159
12160 static int
12161 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12162 int *hpos, int *vpos, int *prop_idx)
12163 {
12164 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12165 struct window *w = XWINDOW (f->tool_bar_window);
12166 int area;
12167
12168 /* Find the glyph under X/Y. */
12169 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12170 if (*glyph == NULL)
12171 return -1;
12172
12173 /* Get the start of this tool-bar item's properties in
12174 f->tool_bar_items. */
12175 if (!tool_bar_item_info (f, *glyph, prop_idx))
12176 return -1;
12177
12178 /* Is mouse on the highlighted item? */
12179 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12180 && *vpos >= hlinfo->mouse_face_beg_row
12181 && *vpos <= hlinfo->mouse_face_end_row
12182 && (*vpos > hlinfo->mouse_face_beg_row
12183 || *hpos >= hlinfo->mouse_face_beg_col)
12184 && (*vpos < hlinfo->mouse_face_end_row
12185 || *hpos < hlinfo->mouse_face_end_col
12186 || hlinfo->mouse_face_past_end))
12187 return 0;
12188
12189 return 1;
12190 }
12191
12192
12193 /* EXPORT:
12194 Handle mouse button event on the tool-bar of frame F, at
12195 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12196 0 for button release. MODIFIERS is event modifiers for button
12197 release. */
12198
12199 void
12200 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12201 int modifiers)
12202 {
12203 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12204 struct window *w = XWINDOW (f->tool_bar_window);
12205 int hpos, vpos, prop_idx;
12206 struct glyph *glyph;
12207 Lisp_Object enabled_p;
12208 int ts;
12209
12210 /* If not on the highlighted tool-bar item, and mouse-highlight is
12211 non-nil, return. This is so we generate the tool-bar button
12212 click only when the mouse button is released on the same item as
12213 where it was pressed. However, when mouse-highlight is disabled,
12214 generate the click when the button is released regardless of the
12215 highlight, since tool-bar items are not highlighted in that
12216 case. */
12217 frame_to_window_pixel_xy (w, &x, &y);
12218 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12219 if (ts == -1
12220 || (ts != 0 && !NILP (Vmouse_highlight)))
12221 return;
12222
12223 /* When mouse-highlight is off, generate the click for the item
12224 where the button was pressed, disregarding where it was
12225 released. */
12226 if (NILP (Vmouse_highlight) && !down_p)
12227 prop_idx = last_tool_bar_item;
12228
12229 /* If item is disabled, do nothing. */
12230 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12231 if (NILP (enabled_p))
12232 return;
12233
12234 if (down_p)
12235 {
12236 /* Show item in pressed state. */
12237 if (!NILP (Vmouse_highlight))
12238 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12239 last_tool_bar_item = prop_idx;
12240 }
12241 else
12242 {
12243 Lisp_Object key, frame;
12244 struct input_event event;
12245 EVENT_INIT (event);
12246
12247 /* Show item in released state. */
12248 if (!NILP (Vmouse_highlight))
12249 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12250
12251 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12252
12253 XSETFRAME (frame, f);
12254 event.kind = TOOL_BAR_EVENT;
12255 event.frame_or_window = frame;
12256 event.arg = frame;
12257 kbd_buffer_store_event (&event);
12258
12259 event.kind = TOOL_BAR_EVENT;
12260 event.frame_or_window = frame;
12261 event.arg = key;
12262 event.modifiers = modifiers;
12263 kbd_buffer_store_event (&event);
12264 last_tool_bar_item = -1;
12265 }
12266 }
12267
12268
12269 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12270 tool-bar window-relative coordinates X/Y. Called from
12271 note_mouse_highlight. */
12272
12273 static void
12274 note_tool_bar_highlight (struct frame *f, int x, int y)
12275 {
12276 Lisp_Object window = f->tool_bar_window;
12277 struct window *w = XWINDOW (window);
12278 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12279 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12280 int hpos, vpos;
12281 struct glyph *glyph;
12282 struct glyph_row *row;
12283 int i;
12284 Lisp_Object enabled_p;
12285 int prop_idx;
12286 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12287 int mouse_down_p, rc;
12288
12289 /* Function note_mouse_highlight is called with negative X/Y
12290 values when mouse moves outside of the frame. */
12291 if (x <= 0 || y <= 0)
12292 {
12293 clear_mouse_face (hlinfo);
12294 return;
12295 }
12296
12297 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12298 if (rc < 0)
12299 {
12300 /* Not on tool-bar item. */
12301 clear_mouse_face (hlinfo);
12302 return;
12303 }
12304 else if (rc == 0)
12305 /* On same tool-bar item as before. */
12306 goto set_help_echo;
12307
12308 clear_mouse_face (hlinfo);
12309
12310 /* Mouse is down, but on different tool-bar item? */
12311 mouse_down_p = (dpyinfo->grabbed
12312 && f == last_mouse_frame
12313 && FRAME_LIVE_P (f));
12314 if (mouse_down_p
12315 && last_tool_bar_item != prop_idx)
12316 return;
12317
12318 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12319
12320 /* If tool-bar item is not enabled, don't highlight it. */
12321 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12322 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12323 {
12324 /* Compute the x-position of the glyph. In front and past the
12325 image is a space. We include this in the highlighted area. */
12326 row = MATRIX_ROW (w->current_matrix, vpos);
12327 for (i = x = 0; i < hpos; ++i)
12328 x += row->glyphs[TEXT_AREA][i].pixel_width;
12329
12330 /* Record this as the current active region. */
12331 hlinfo->mouse_face_beg_col = hpos;
12332 hlinfo->mouse_face_beg_row = vpos;
12333 hlinfo->mouse_face_beg_x = x;
12334 hlinfo->mouse_face_past_end = 0;
12335
12336 hlinfo->mouse_face_end_col = hpos + 1;
12337 hlinfo->mouse_face_end_row = vpos;
12338 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12339 hlinfo->mouse_face_window = window;
12340 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12341
12342 /* Display it as active. */
12343 show_mouse_face (hlinfo, draw);
12344 }
12345
12346 set_help_echo:
12347
12348 /* Set help_echo_string to a help string to display for this tool-bar item.
12349 XTread_socket does the rest. */
12350 help_echo_object = help_echo_window = Qnil;
12351 help_echo_pos = -1;
12352 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12353 if (NILP (help_echo_string))
12354 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12355 }
12356
12357 #endif /* !USE_GTK && !HAVE_NS */
12358
12359 #endif /* HAVE_WINDOW_SYSTEM */
12360
12361
12362 \f
12363 /************************************************************************
12364 Horizontal scrolling
12365 ************************************************************************/
12366
12367 static int hscroll_window_tree (Lisp_Object);
12368 static int hscroll_windows (Lisp_Object);
12369
12370 /* For all leaf windows in the window tree rooted at WINDOW, set their
12371 hscroll value so that PT is (i) visible in the window, and (ii) so
12372 that it is not within a certain margin at the window's left and
12373 right border. Value is non-zero if any window's hscroll has been
12374 changed. */
12375
12376 static int
12377 hscroll_window_tree (Lisp_Object window)
12378 {
12379 int hscrolled_p = 0;
12380 int hscroll_relative_p = FLOATP (Vhscroll_step);
12381 int hscroll_step_abs = 0;
12382 double hscroll_step_rel = 0;
12383
12384 if (hscroll_relative_p)
12385 {
12386 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12387 if (hscroll_step_rel < 0)
12388 {
12389 hscroll_relative_p = 0;
12390 hscroll_step_abs = 0;
12391 }
12392 }
12393 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12394 {
12395 hscroll_step_abs = XINT (Vhscroll_step);
12396 if (hscroll_step_abs < 0)
12397 hscroll_step_abs = 0;
12398 }
12399 else
12400 hscroll_step_abs = 0;
12401
12402 while (WINDOWP (window))
12403 {
12404 struct window *w = XWINDOW (window);
12405
12406 if (WINDOWP (w->contents))
12407 hscrolled_p |= hscroll_window_tree (w->contents);
12408 else if (w->cursor.vpos >= 0)
12409 {
12410 int h_margin;
12411 int text_area_width;
12412 struct glyph_row *current_cursor_row
12413 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12414 struct glyph_row *desired_cursor_row
12415 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12416 struct glyph_row *cursor_row
12417 = (desired_cursor_row->enabled_p
12418 ? desired_cursor_row
12419 : current_cursor_row);
12420 int row_r2l_p = cursor_row->reversed_p;
12421
12422 text_area_width = window_box_width (w, TEXT_AREA);
12423
12424 /* Scroll when cursor is inside this scroll margin. */
12425 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12426
12427 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12428 /* For left-to-right rows, hscroll when cursor is either
12429 (i) inside the right hscroll margin, or (ii) if it is
12430 inside the left margin and the window is already
12431 hscrolled. */
12432 && ((!row_r2l_p
12433 && ((w->hscroll
12434 && w->cursor.x <= h_margin)
12435 || (cursor_row->enabled_p
12436 && cursor_row->truncated_on_right_p
12437 && (w->cursor.x >= text_area_width - h_margin))))
12438 /* For right-to-left rows, the logic is similar,
12439 except that rules for scrolling to left and right
12440 are reversed. E.g., if cursor.x <= h_margin, we
12441 need to hscroll "to the right" unconditionally,
12442 and that will scroll the screen to the left so as
12443 to reveal the next portion of the row. */
12444 || (row_r2l_p
12445 && ((cursor_row->enabled_p
12446 /* FIXME: It is confusing to set the
12447 truncated_on_right_p flag when R2L rows
12448 are actually truncated on the left. */
12449 && cursor_row->truncated_on_right_p
12450 && w->cursor.x <= h_margin)
12451 || (w->hscroll
12452 && (w->cursor.x >= text_area_width - h_margin))))))
12453 {
12454 struct it it;
12455 ptrdiff_t hscroll;
12456 struct buffer *saved_current_buffer;
12457 ptrdiff_t pt;
12458 int wanted_x;
12459
12460 /* Find point in a display of infinite width. */
12461 saved_current_buffer = current_buffer;
12462 current_buffer = XBUFFER (w->contents);
12463
12464 if (w == XWINDOW (selected_window))
12465 pt = PT;
12466 else
12467 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12468
12469 /* Move iterator to pt starting at cursor_row->start in
12470 a line with infinite width. */
12471 init_to_row_start (&it, w, cursor_row);
12472 it.last_visible_x = INFINITY;
12473 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12474 current_buffer = saved_current_buffer;
12475
12476 /* Position cursor in window. */
12477 if (!hscroll_relative_p && hscroll_step_abs == 0)
12478 hscroll = max (0, (it.current_x
12479 - (ITERATOR_AT_END_OF_LINE_P (&it)
12480 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12481 : (text_area_width / 2))))
12482 / FRAME_COLUMN_WIDTH (it.f);
12483 else if ((!row_r2l_p
12484 && w->cursor.x >= text_area_width - h_margin)
12485 || (row_r2l_p && w->cursor.x <= h_margin))
12486 {
12487 if (hscroll_relative_p)
12488 wanted_x = text_area_width * (1 - hscroll_step_rel)
12489 - h_margin;
12490 else
12491 wanted_x = text_area_width
12492 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12493 - h_margin;
12494 hscroll
12495 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12496 }
12497 else
12498 {
12499 if (hscroll_relative_p)
12500 wanted_x = text_area_width * hscroll_step_rel
12501 + h_margin;
12502 else
12503 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12504 + h_margin;
12505 hscroll
12506 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12507 }
12508 hscroll = max (hscroll, w->min_hscroll);
12509
12510 /* Don't prevent redisplay optimizations if hscroll
12511 hasn't changed, as it will unnecessarily slow down
12512 redisplay. */
12513 if (w->hscroll != hscroll)
12514 {
12515 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12516 w->hscroll = hscroll;
12517 hscrolled_p = 1;
12518 }
12519 }
12520 }
12521
12522 window = w->next;
12523 }
12524
12525 /* Value is non-zero if hscroll of any leaf window has been changed. */
12526 return hscrolled_p;
12527 }
12528
12529
12530 /* Set hscroll so that cursor is visible and not inside horizontal
12531 scroll margins for all windows in the tree rooted at WINDOW. See
12532 also hscroll_window_tree above. Value is non-zero if any window's
12533 hscroll has been changed. If it has, desired matrices on the frame
12534 of WINDOW are cleared. */
12535
12536 static int
12537 hscroll_windows (Lisp_Object window)
12538 {
12539 int hscrolled_p = hscroll_window_tree (window);
12540 if (hscrolled_p)
12541 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12542 return hscrolled_p;
12543 }
12544
12545
12546 \f
12547 /************************************************************************
12548 Redisplay
12549 ************************************************************************/
12550
12551 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12552 to a non-zero value. This is sometimes handy to have in a debugger
12553 session. */
12554
12555 #ifdef GLYPH_DEBUG
12556
12557 /* First and last unchanged row for try_window_id. */
12558
12559 static int debug_first_unchanged_at_end_vpos;
12560 static int debug_last_unchanged_at_beg_vpos;
12561
12562 /* Delta vpos and y. */
12563
12564 static int debug_dvpos, debug_dy;
12565
12566 /* Delta in characters and bytes for try_window_id. */
12567
12568 static ptrdiff_t debug_delta, debug_delta_bytes;
12569
12570 /* Values of window_end_pos and window_end_vpos at the end of
12571 try_window_id. */
12572
12573 static ptrdiff_t debug_end_vpos;
12574
12575 /* Append a string to W->desired_matrix->method. FMT is a printf
12576 format string. If trace_redisplay_p is non-zero also printf the
12577 resulting string to stderr. */
12578
12579 static void debug_method_add (struct window *, char const *, ...)
12580 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12581
12582 static void
12583 debug_method_add (struct window *w, char const *fmt, ...)
12584 {
12585 void *ptr = w;
12586 char *method = w->desired_matrix->method;
12587 int len = strlen (method);
12588 int size = sizeof w->desired_matrix->method;
12589 int remaining = size - len - 1;
12590 va_list ap;
12591
12592 if (len && remaining)
12593 {
12594 method[len] = '|';
12595 --remaining, ++len;
12596 }
12597
12598 va_start (ap, fmt);
12599 vsnprintf (method + len, remaining + 1, fmt, ap);
12600 va_end (ap);
12601
12602 if (trace_redisplay_p)
12603 fprintf (stderr, "%p (%s): %s\n",
12604 ptr,
12605 ((BUFFERP (w->contents)
12606 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12607 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12608 : "no buffer"),
12609 method + len);
12610 }
12611
12612 #endif /* GLYPH_DEBUG */
12613
12614
12615 /* Value is non-zero if all changes in window W, which displays
12616 current_buffer, are in the text between START and END. START is a
12617 buffer position, END is given as a distance from Z. Used in
12618 redisplay_internal for display optimization. */
12619
12620 static int
12621 text_outside_line_unchanged_p (struct window *w,
12622 ptrdiff_t start, ptrdiff_t end)
12623 {
12624 int unchanged_p = 1;
12625
12626 /* If text or overlays have changed, see where. */
12627 if (window_outdated (w))
12628 {
12629 /* Gap in the line? */
12630 if (GPT < start || Z - GPT < end)
12631 unchanged_p = 0;
12632
12633 /* Changes start in front of the line, or end after it? */
12634 if (unchanged_p
12635 && (BEG_UNCHANGED < start - 1
12636 || END_UNCHANGED < end))
12637 unchanged_p = 0;
12638
12639 /* If selective display, can't optimize if changes start at the
12640 beginning of the line. */
12641 if (unchanged_p
12642 && INTEGERP (BVAR (current_buffer, selective_display))
12643 && XINT (BVAR (current_buffer, selective_display)) > 0
12644 && (BEG_UNCHANGED < start || GPT <= start))
12645 unchanged_p = 0;
12646
12647 /* If there are overlays at the start or end of the line, these
12648 may have overlay strings with newlines in them. A change at
12649 START, for instance, may actually concern the display of such
12650 overlay strings as well, and they are displayed on different
12651 lines. So, quickly rule out this case. (For the future, it
12652 might be desirable to implement something more telling than
12653 just BEG/END_UNCHANGED.) */
12654 if (unchanged_p)
12655 {
12656 if (BEG + BEG_UNCHANGED == start
12657 && overlay_touches_p (start))
12658 unchanged_p = 0;
12659 if (END_UNCHANGED == end
12660 && overlay_touches_p (Z - end))
12661 unchanged_p = 0;
12662 }
12663
12664 /* Under bidi reordering, adding or deleting a character in the
12665 beginning of a paragraph, before the first strong directional
12666 character, can change the base direction of the paragraph (unless
12667 the buffer specifies a fixed paragraph direction), which will
12668 require to redisplay the whole paragraph. It might be worthwhile
12669 to find the paragraph limits and widen the range of redisplayed
12670 lines to that, but for now just give up this optimization. */
12671 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12672 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12673 unchanged_p = 0;
12674 }
12675
12676 return unchanged_p;
12677 }
12678
12679
12680 /* Do a frame update, taking possible shortcuts into account. This is
12681 the main external entry point for redisplay.
12682
12683 If the last redisplay displayed an echo area message and that message
12684 is no longer requested, we clear the echo area or bring back the
12685 mini-buffer if that is in use. */
12686
12687 void
12688 redisplay (void)
12689 {
12690 redisplay_internal ();
12691 }
12692
12693
12694 static Lisp_Object
12695 overlay_arrow_string_or_property (Lisp_Object var)
12696 {
12697 Lisp_Object val;
12698
12699 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12700 return val;
12701
12702 return Voverlay_arrow_string;
12703 }
12704
12705 /* Return 1 if there are any overlay-arrows in current_buffer. */
12706 static int
12707 overlay_arrow_in_current_buffer_p (void)
12708 {
12709 Lisp_Object vlist;
12710
12711 for (vlist = Voverlay_arrow_variable_list;
12712 CONSP (vlist);
12713 vlist = XCDR (vlist))
12714 {
12715 Lisp_Object var = XCAR (vlist);
12716 Lisp_Object val;
12717
12718 if (!SYMBOLP (var))
12719 continue;
12720 val = find_symbol_value (var);
12721 if (MARKERP (val)
12722 && current_buffer == XMARKER (val)->buffer)
12723 return 1;
12724 }
12725 return 0;
12726 }
12727
12728
12729 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12730 has changed. */
12731
12732 static int
12733 overlay_arrows_changed_p (void)
12734 {
12735 Lisp_Object vlist;
12736
12737 for (vlist = Voverlay_arrow_variable_list;
12738 CONSP (vlist);
12739 vlist = XCDR (vlist))
12740 {
12741 Lisp_Object var = XCAR (vlist);
12742 Lisp_Object val, pstr;
12743
12744 if (!SYMBOLP (var))
12745 continue;
12746 val = find_symbol_value (var);
12747 if (!MARKERP (val))
12748 continue;
12749 if (! EQ (COERCE_MARKER (val),
12750 Fget (var, Qlast_arrow_position))
12751 || ! (pstr = overlay_arrow_string_or_property (var),
12752 EQ (pstr, Fget (var, Qlast_arrow_string))))
12753 return 1;
12754 }
12755 return 0;
12756 }
12757
12758 /* Mark overlay arrows to be updated on next redisplay. */
12759
12760 static void
12761 update_overlay_arrows (int up_to_date)
12762 {
12763 Lisp_Object vlist;
12764
12765 for (vlist = Voverlay_arrow_variable_list;
12766 CONSP (vlist);
12767 vlist = XCDR (vlist))
12768 {
12769 Lisp_Object var = XCAR (vlist);
12770
12771 if (!SYMBOLP (var))
12772 continue;
12773
12774 if (up_to_date > 0)
12775 {
12776 Lisp_Object val = find_symbol_value (var);
12777 Fput (var, Qlast_arrow_position,
12778 COERCE_MARKER (val));
12779 Fput (var, Qlast_arrow_string,
12780 overlay_arrow_string_or_property (var));
12781 }
12782 else if (up_to_date < 0
12783 || !NILP (Fget (var, Qlast_arrow_position)))
12784 {
12785 Fput (var, Qlast_arrow_position, Qt);
12786 Fput (var, Qlast_arrow_string, Qt);
12787 }
12788 }
12789 }
12790
12791
12792 /* Return overlay arrow string to display at row.
12793 Return integer (bitmap number) for arrow bitmap in left fringe.
12794 Return nil if no overlay arrow. */
12795
12796 static Lisp_Object
12797 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12798 {
12799 Lisp_Object vlist;
12800
12801 for (vlist = Voverlay_arrow_variable_list;
12802 CONSP (vlist);
12803 vlist = XCDR (vlist))
12804 {
12805 Lisp_Object var = XCAR (vlist);
12806 Lisp_Object val;
12807
12808 if (!SYMBOLP (var))
12809 continue;
12810
12811 val = find_symbol_value (var);
12812
12813 if (MARKERP (val)
12814 && current_buffer == XMARKER (val)->buffer
12815 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12816 {
12817 if (FRAME_WINDOW_P (it->f)
12818 /* FIXME: if ROW->reversed_p is set, this should test
12819 the right fringe, not the left one. */
12820 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12821 {
12822 #ifdef HAVE_WINDOW_SYSTEM
12823 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12824 {
12825 int fringe_bitmap;
12826 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12827 return make_number (fringe_bitmap);
12828 }
12829 #endif
12830 return make_number (-1); /* Use default arrow bitmap. */
12831 }
12832 return overlay_arrow_string_or_property (var);
12833 }
12834 }
12835
12836 return Qnil;
12837 }
12838
12839 /* Return 1 if point moved out of or into a composition. Otherwise
12840 return 0. PREV_BUF and PREV_PT are the last point buffer and
12841 position. BUF and PT are the current point buffer and position. */
12842
12843 static int
12844 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12845 struct buffer *buf, ptrdiff_t pt)
12846 {
12847 ptrdiff_t start, end;
12848 Lisp_Object prop;
12849 Lisp_Object buffer;
12850
12851 XSETBUFFER (buffer, buf);
12852 /* Check a composition at the last point if point moved within the
12853 same buffer. */
12854 if (prev_buf == buf)
12855 {
12856 if (prev_pt == pt)
12857 /* Point didn't move. */
12858 return 0;
12859
12860 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12861 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12862 && composition_valid_p (start, end, prop)
12863 && start < prev_pt && end > prev_pt)
12864 /* The last point was within the composition. Return 1 iff
12865 point moved out of the composition. */
12866 return (pt <= start || pt >= end);
12867 }
12868
12869 /* Check a composition at the current point. */
12870 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12871 && find_composition (pt, -1, &start, &end, &prop, buffer)
12872 && composition_valid_p (start, end, prop)
12873 && start < pt && end > pt);
12874 }
12875
12876 /* Reconsider the clip changes of buffer which is displayed in W. */
12877
12878 static void
12879 reconsider_clip_changes (struct window *w)
12880 {
12881 struct buffer *b = XBUFFER (w->contents);
12882
12883 if (b->clip_changed
12884 && w->window_end_valid
12885 && w->current_matrix->buffer == b
12886 && w->current_matrix->zv == BUF_ZV (b)
12887 && w->current_matrix->begv == BUF_BEGV (b))
12888 b->clip_changed = 0;
12889
12890 /* If display wasn't paused, and W is not a tool bar window, see if
12891 point has been moved into or out of a composition. In that case,
12892 we set b->clip_changed to 1 to force updating the screen. If
12893 b->clip_changed has already been set to 1, we can skip this
12894 check. */
12895 if (!b->clip_changed && w->window_end_valid)
12896 {
12897 ptrdiff_t pt = (w == XWINDOW (selected_window)
12898 ? PT : marker_position (w->pointm));
12899
12900 if ((w->current_matrix->buffer != b || pt != w->last_point)
12901 && check_point_in_composition (w->current_matrix->buffer,
12902 w->last_point, b, pt))
12903 b->clip_changed = 1;
12904 }
12905 }
12906
12907 #define STOP_POLLING \
12908 do { if (! polling_stopped_here) stop_polling (); \
12909 polling_stopped_here = 1; } while (0)
12910
12911 #define RESUME_POLLING \
12912 do { if (polling_stopped_here) start_polling (); \
12913 polling_stopped_here = 0; } while (0)
12914
12915
12916 /* Perhaps in the future avoid recentering windows if it
12917 is not necessary; currently that causes some problems. */
12918
12919 static void
12920 redisplay_internal (void)
12921 {
12922 struct window *w = XWINDOW (selected_window);
12923 struct window *sw;
12924 struct frame *fr;
12925 int pending;
12926 bool must_finish = 0, match_p;
12927 struct text_pos tlbufpos, tlendpos;
12928 int number_of_visible_frames;
12929 ptrdiff_t count;
12930 struct frame *sf;
12931 int polling_stopped_here = 0;
12932 Lisp_Object tail, frame;
12933
12934 /* Non-zero means redisplay has to consider all windows on all
12935 frames. Zero means, only selected_window is considered. */
12936 int consider_all_windows_p;
12937
12938 /* Non-zero means redisplay has to redisplay the miniwindow. */
12939 int update_miniwindow_p = 0;
12940
12941 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12942
12943 /* No redisplay if running in batch mode or frame is not yet fully
12944 initialized, or redisplay is explicitly turned off by setting
12945 Vinhibit_redisplay. */
12946 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12947 || !NILP (Vinhibit_redisplay))
12948 return;
12949
12950 /* Don't examine these until after testing Vinhibit_redisplay.
12951 When Emacs is shutting down, perhaps because its connection to
12952 X has dropped, we should not look at them at all. */
12953 fr = XFRAME (w->frame);
12954 sf = SELECTED_FRAME ();
12955
12956 if (!fr->glyphs_initialized_p)
12957 return;
12958
12959 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12960 if (popup_activated ())
12961 return;
12962 #endif
12963
12964 /* I don't think this happens but let's be paranoid. */
12965 if (redisplaying_p)
12966 return;
12967
12968 /* Record a function that clears redisplaying_p
12969 when we leave this function. */
12970 count = SPECPDL_INDEX ();
12971 record_unwind_protect_void (unwind_redisplay);
12972 redisplaying_p = 1;
12973 specbind (Qinhibit_free_realized_faces, Qnil);
12974
12975 /* Record this function, so it appears on the profiler's backtraces. */
12976 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
12977
12978 FOR_EACH_FRAME (tail, frame)
12979 XFRAME (frame)->already_hscrolled_p = 0;
12980
12981 retry:
12982 /* Remember the currently selected window. */
12983 sw = w;
12984
12985 pending = 0;
12986 last_escape_glyph_frame = NULL;
12987 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12988 last_glyphless_glyph_frame = NULL;
12989 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12990
12991 /* If face_change_count is non-zero, init_iterator will free all
12992 realized faces, which includes the faces referenced from current
12993 matrices. So, we can't reuse current matrices in this case. */
12994 if (face_change_count)
12995 ++windows_or_buffers_changed;
12996
12997 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12998 && FRAME_TTY (sf)->previous_frame != sf)
12999 {
13000 /* Since frames on a single ASCII terminal share the same
13001 display area, displaying a different frame means redisplay
13002 the whole thing. */
13003 windows_or_buffers_changed++;
13004 SET_FRAME_GARBAGED (sf);
13005 #ifndef DOS_NT
13006 set_tty_color_mode (FRAME_TTY (sf), sf);
13007 #endif
13008 FRAME_TTY (sf)->previous_frame = sf;
13009 }
13010
13011 /* Set the visible flags for all frames. Do this before checking for
13012 resized or garbaged frames; they want to know if their frames are
13013 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13014 number_of_visible_frames = 0;
13015
13016 FOR_EACH_FRAME (tail, frame)
13017 {
13018 struct frame *f = XFRAME (frame);
13019
13020 if (FRAME_VISIBLE_P (f))
13021 {
13022 ++number_of_visible_frames;
13023 /* Adjust matrices for visible frames only. */
13024 if (f->fonts_changed)
13025 {
13026 adjust_frame_glyphs (f);
13027 f->fonts_changed = 0;
13028 }
13029 /* If cursor type has been changed on the frame
13030 other than selected, consider all frames. */
13031 if (f != sf && f->cursor_type_changed)
13032 update_mode_lines++;
13033 }
13034 clear_desired_matrices (f);
13035 }
13036
13037 /* Notice any pending interrupt request to change frame size. */
13038 do_pending_window_change (1);
13039
13040 /* do_pending_window_change could change the selected_window due to
13041 frame resizing which makes the selected window too small. */
13042 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13043 sw = w;
13044
13045 /* Clear frames marked as garbaged. */
13046 clear_garbaged_frames ();
13047
13048 /* Build menubar and tool-bar items. */
13049 if (NILP (Vmemory_full))
13050 prepare_menu_bars ();
13051
13052 if (windows_or_buffers_changed)
13053 update_mode_lines++;
13054
13055 reconsider_clip_changes (w);
13056
13057 /* In most cases selected window displays current buffer. */
13058 match_p = XBUFFER (w->contents) == current_buffer;
13059 if (match_p)
13060 {
13061 ptrdiff_t count1;
13062
13063 /* Detect case that we need to write or remove a star in the mode line. */
13064 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13065 {
13066 w->update_mode_line = 1;
13067 if (buffer_shared_and_changed ())
13068 update_mode_lines++;
13069 }
13070
13071 /* Avoid invocation of point motion hooks by `current_column' below. */
13072 count1 = SPECPDL_INDEX ();
13073 specbind (Qinhibit_point_motion_hooks, Qt);
13074
13075 if (mode_line_update_needed (w))
13076 w->update_mode_line = 1;
13077
13078 unbind_to (count1, Qnil);
13079 }
13080
13081 consider_all_windows_p = (update_mode_lines
13082 || buffer_shared_and_changed ());
13083
13084 /* If specs for an arrow have changed, do thorough redisplay
13085 to ensure we remove any arrow that should no longer exist. */
13086 if (overlay_arrows_changed_p ())
13087 consider_all_windows_p = windows_or_buffers_changed = 1;
13088
13089 /* Normally the message* functions will have already displayed and
13090 updated the echo area, but the frame may have been trashed, or
13091 the update may have been preempted, so display the echo area
13092 again here. Checking message_cleared_p captures the case that
13093 the echo area should be cleared. */
13094 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13095 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13096 || (message_cleared_p
13097 && minibuf_level == 0
13098 /* If the mini-window is currently selected, this means the
13099 echo-area doesn't show through. */
13100 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13101 {
13102 int window_height_changed_p = echo_area_display (0);
13103
13104 if (message_cleared_p)
13105 update_miniwindow_p = 1;
13106
13107 must_finish = 1;
13108
13109 /* If we don't display the current message, don't clear the
13110 message_cleared_p flag, because, if we did, we wouldn't clear
13111 the echo area in the next redisplay which doesn't preserve
13112 the echo area. */
13113 if (!display_last_displayed_message_p)
13114 message_cleared_p = 0;
13115
13116 if (window_height_changed_p)
13117 {
13118 consider_all_windows_p = 1;
13119 ++update_mode_lines;
13120 ++windows_or_buffers_changed;
13121
13122 /* If window configuration was changed, frames may have been
13123 marked garbaged. Clear them or we will experience
13124 surprises wrt scrolling. */
13125 clear_garbaged_frames ();
13126 }
13127 }
13128 else if (EQ (selected_window, minibuf_window)
13129 && (current_buffer->clip_changed || window_outdated (w))
13130 && resize_mini_window (w, 0))
13131 {
13132 /* Resized active mini-window to fit the size of what it is
13133 showing if its contents might have changed. */
13134 must_finish = 1;
13135 /* FIXME: this causes all frames to be updated, which seems unnecessary
13136 since only the current frame needs to be considered. This function
13137 needs to be rewritten with two variables, consider_all_windows and
13138 consider_all_frames. */
13139 consider_all_windows_p = 1;
13140 ++windows_or_buffers_changed;
13141 ++update_mode_lines;
13142
13143 /* If window configuration was changed, frames may have been
13144 marked garbaged. Clear them or we will experience
13145 surprises wrt scrolling. */
13146 clear_garbaged_frames ();
13147 }
13148
13149 /* If showing the region, and mark has changed, we must redisplay
13150 the whole window. The assignment to this_line_start_pos prevents
13151 the optimization directly below this if-statement. */
13152 if (((!NILP (Vtransient_mark_mode)
13153 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13154 != (w->region_showing > 0))
13155 || (w->region_showing
13156 && w->region_showing
13157 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13158 CHARPOS (this_line_start_pos) = 0;
13159
13160 /* Optimize the case that only the line containing the cursor in the
13161 selected window has changed. Variables starting with this_ are
13162 set in display_line and record information about the line
13163 containing the cursor. */
13164 tlbufpos = this_line_start_pos;
13165 tlendpos = this_line_end_pos;
13166 if (!consider_all_windows_p
13167 && CHARPOS (tlbufpos) > 0
13168 && !w->update_mode_line
13169 && !current_buffer->clip_changed
13170 && !current_buffer->prevent_redisplay_optimizations_p
13171 && FRAME_VISIBLE_P (XFRAME (w->frame))
13172 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13173 && !XFRAME (w->frame)->cursor_type_changed
13174 /* Make sure recorded data applies to current buffer, etc. */
13175 && this_line_buffer == current_buffer
13176 && match_p
13177 && !w->force_start
13178 && !w->optional_new_start
13179 /* Point must be on the line that we have info recorded about. */
13180 && PT >= CHARPOS (tlbufpos)
13181 && PT <= Z - CHARPOS (tlendpos)
13182 /* All text outside that line, including its final newline,
13183 must be unchanged. */
13184 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13185 CHARPOS (tlendpos)))
13186 {
13187 if (CHARPOS (tlbufpos) > BEGV
13188 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13189 && (CHARPOS (tlbufpos) == ZV
13190 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13191 /* Former continuation line has disappeared by becoming empty. */
13192 goto cancel;
13193 else if (window_outdated (w) || MINI_WINDOW_P (w))
13194 {
13195 /* We have to handle the case of continuation around a
13196 wide-column character (see the comment in indent.c around
13197 line 1340).
13198
13199 For instance, in the following case:
13200
13201 -------- Insert --------
13202 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13203 J_I_ ==> J_I_ `^^' are cursors.
13204 ^^ ^^
13205 -------- --------
13206
13207 As we have to redraw the line above, we cannot use this
13208 optimization. */
13209
13210 struct it it;
13211 int line_height_before = this_line_pixel_height;
13212
13213 /* Note that start_display will handle the case that the
13214 line starting at tlbufpos is a continuation line. */
13215 start_display (&it, w, tlbufpos);
13216
13217 /* Implementation note: It this still necessary? */
13218 if (it.current_x != this_line_start_x)
13219 goto cancel;
13220
13221 TRACE ((stderr, "trying display optimization 1\n"));
13222 w->cursor.vpos = -1;
13223 overlay_arrow_seen = 0;
13224 it.vpos = this_line_vpos;
13225 it.current_y = this_line_y;
13226 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13227 display_line (&it);
13228
13229 /* If line contains point, is not continued,
13230 and ends at same distance from eob as before, we win. */
13231 if (w->cursor.vpos >= 0
13232 /* Line is not continued, otherwise this_line_start_pos
13233 would have been set to 0 in display_line. */
13234 && CHARPOS (this_line_start_pos)
13235 /* Line ends as before. */
13236 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13237 /* Line has same height as before. Otherwise other lines
13238 would have to be shifted up or down. */
13239 && this_line_pixel_height == line_height_before)
13240 {
13241 /* If this is not the window's last line, we must adjust
13242 the charstarts of the lines below. */
13243 if (it.current_y < it.last_visible_y)
13244 {
13245 struct glyph_row *row
13246 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13247 ptrdiff_t delta, delta_bytes;
13248
13249 /* We used to distinguish between two cases here,
13250 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13251 when the line ends in a newline or the end of the
13252 buffer's accessible portion. But both cases did
13253 the same, so they were collapsed. */
13254 delta = (Z
13255 - CHARPOS (tlendpos)
13256 - MATRIX_ROW_START_CHARPOS (row));
13257 delta_bytes = (Z_BYTE
13258 - BYTEPOS (tlendpos)
13259 - MATRIX_ROW_START_BYTEPOS (row));
13260
13261 increment_matrix_positions (w->current_matrix,
13262 this_line_vpos + 1,
13263 w->current_matrix->nrows,
13264 delta, delta_bytes);
13265 }
13266
13267 /* If this row displays text now but previously didn't,
13268 or vice versa, w->window_end_vpos may have to be
13269 adjusted. */
13270 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13271 {
13272 if (w->window_end_vpos < this_line_vpos)
13273 w->window_end_vpos = this_line_vpos;
13274 }
13275 else if (w->window_end_vpos == this_line_vpos
13276 && this_line_vpos > 0)
13277 w->window_end_vpos = this_line_vpos - 1;
13278 w->window_end_valid = 0;
13279
13280 /* Update hint: No need to try to scroll in update_window. */
13281 w->desired_matrix->no_scrolling_p = 1;
13282
13283 #ifdef GLYPH_DEBUG
13284 *w->desired_matrix->method = 0;
13285 debug_method_add (w, "optimization 1");
13286 #endif
13287 #ifdef HAVE_WINDOW_SYSTEM
13288 update_window_fringes (w, 0);
13289 #endif
13290 goto update;
13291 }
13292 else
13293 goto cancel;
13294 }
13295 else if (/* Cursor position hasn't changed. */
13296 PT == w->last_point
13297 /* Make sure the cursor was last displayed
13298 in this window. Otherwise we have to reposition it. */
13299 && 0 <= w->cursor.vpos
13300 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13301 {
13302 if (!must_finish)
13303 {
13304 do_pending_window_change (1);
13305 /* If selected_window changed, redisplay again. */
13306 if (WINDOWP (selected_window)
13307 && (w = XWINDOW (selected_window)) != sw)
13308 goto retry;
13309
13310 /* We used to always goto end_of_redisplay here, but this
13311 isn't enough if we have a blinking cursor. */
13312 if (w->cursor_off_p == w->last_cursor_off_p)
13313 goto end_of_redisplay;
13314 }
13315 goto update;
13316 }
13317 /* If highlighting the region, or if the cursor is in the echo area,
13318 then we can't just move the cursor. */
13319 else if (! (!NILP (Vtransient_mark_mode)
13320 && !NILP (BVAR (current_buffer, mark_active)))
13321 && (EQ (selected_window,
13322 BVAR (current_buffer, last_selected_window))
13323 || highlight_nonselected_windows)
13324 && !w->region_showing
13325 && NILP (Vshow_trailing_whitespace)
13326 && !cursor_in_echo_area)
13327 {
13328 struct it it;
13329 struct glyph_row *row;
13330
13331 /* Skip from tlbufpos to PT and see where it is. Note that
13332 PT may be in invisible text. If so, we will end at the
13333 next visible position. */
13334 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13335 NULL, DEFAULT_FACE_ID);
13336 it.current_x = this_line_start_x;
13337 it.current_y = this_line_y;
13338 it.vpos = this_line_vpos;
13339
13340 /* The call to move_it_to stops in front of PT, but
13341 moves over before-strings. */
13342 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13343
13344 if (it.vpos == this_line_vpos
13345 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13346 row->enabled_p))
13347 {
13348 eassert (this_line_vpos == it.vpos);
13349 eassert (this_line_y == it.current_y);
13350 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13351 #ifdef GLYPH_DEBUG
13352 *w->desired_matrix->method = 0;
13353 debug_method_add (w, "optimization 3");
13354 #endif
13355 goto update;
13356 }
13357 else
13358 goto cancel;
13359 }
13360
13361 cancel:
13362 /* Text changed drastically or point moved off of line. */
13363 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13364 }
13365
13366 CHARPOS (this_line_start_pos) = 0;
13367 consider_all_windows_p |= buffer_shared_and_changed ();
13368 ++clear_face_cache_count;
13369 #ifdef HAVE_WINDOW_SYSTEM
13370 ++clear_image_cache_count;
13371 #endif
13372
13373 /* Build desired matrices, and update the display. If
13374 consider_all_windows_p is non-zero, do it for all windows on all
13375 frames. Otherwise do it for selected_window, only. */
13376
13377 if (consider_all_windows_p)
13378 {
13379 FOR_EACH_FRAME (tail, frame)
13380 XFRAME (frame)->updated_p = 0;
13381
13382 FOR_EACH_FRAME (tail, frame)
13383 {
13384 struct frame *f = XFRAME (frame);
13385
13386 /* We don't have to do anything for unselected terminal
13387 frames. */
13388 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13389 && !EQ (FRAME_TTY (f)->top_frame, frame))
13390 continue;
13391
13392 retry_frame:
13393
13394 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13395 {
13396 /* Mark all the scroll bars to be removed; we'll redeem
13397 the ones we want when we redisplay their windows. */
13398 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13399 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13400
13401 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13402 redisplay_windows (FRAME_ROOT_WINDOW (f));
13403
13404 /* The X error handler may have deleted that frame. */
13405 if (!FRAME_LIVE_P (f))
13406 continue;
13407
13408 /* Any scroll bars which redisplay_windows should have
13409 nuked should now go away. */
13410 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13411 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13412
13413 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13414 {
13415 /* If fonts changed on visible frame, display again. */
13416 if (f->fonts_changed)
13417 {
13418 adjust_frame_glyphs (f);
13419 f->fonts_changed = 0;
13420 goto retry_frame;
13421 }
13422
13423 /* See if we have to hscroll. */
13424 if (!f->already_hscrolled_p)
13425 {
13426 f->already_hscrolled_p = 1;
13427 if (hscroll_windows (f->root_window))
13428 goto retry_frame;
13429 }
13430
13431 /* Prevent various kinds of signals during display
13432 update. stdio is not robust about handling
13433 signals, which can cause an apparent I/O
13434 error. */
13435 if (interrupt_input)
13436 unrequest_sigio ();
13437 STOP_POLLING;
13438
13439 /* Update the display. */
13440 set_window_update_flags (XWINDOW (f->root_window), 1);
13441 pending |= update_frame (f, 0, 0);
13442 f->cursor_type_changed = 0;
13443 f->updated_p = 1;
13444 }
13445 }
13446 }
13447
13448 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13449
13450 if (!pending)
13451 {
13452 /* Do the mark_window_display_accurate after all windows have
13453 been redisplayed because this call resets flags in buffers
13454 which are needed for proper redisplay. */
13455 FOR_EACH_FRAME (tail, frame)
13456 {
13457 struct frame *f = XFRAME (frame);
13458 if (f->updated_p)
13459 {
13460 mark_window_display_accurate (f->root_window, 1);
13461 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13462 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13463 }
13464 }
13465 }
13466 }
13467 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13468 {
13469 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13470 struct frame *mini_frame;
13471
13472 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13473 /* Use list_of_error, not Qerror, so that
13474 we catch only errors and don't run the debugger. */
13475 internal_condition_case_1 (redisplay_window_1, selected_window,
13476 list_of_error,
13477 redisplay_window_error);
13478 if (update_miniwindow_p)
13479 internal_condition_case_1 (redisplay_window_1, mini_window,
13480 list_of_error,
13481 redisplay_window_error);
13482
13483 /* Compare desired and current matrices, perform output. */
13484
13485 update:
13486 /* If fonts changed, display again. */
13487 if (sf->fonts_changed)
13488 goto retry;
13489
13490 /* Prevent various kinds of signals during display update.
13491 stdio is not robust about handling signals,
13492 which can cause an apparent I/O error. */
13493 if (interrupt_input)
13494 unrequest_sigio ();
13495 STOP_POLLING;
13496
13497 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13498 {
13499 if (hscroll_windows (selected_window))
13500 goto retry;
13501
13502 XWINDOW (selected_window)->must_be_updated_p = 1;
13503 pending = update_frame (sf, 0, 0);
13504 sf->cursor_type_changed = 0;
13505 }
13506
13507 /* We may have called echo_area_display at the top of this
13508 function. If the echo area is on another frame, that may
13509 have put text on a frame other than the selected one, so the
13510 above call to update_frame would not have caught it. Catch
13511 it here. */
13512 mini_window = FRAME_MINIBUF_WINDOW (sf);
13513 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13514
13515 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13516 {
13517 XWINDOW (mini_window)->must_be_updated_p = 1;
13518 pending |= update_frame (mini_frame, 0, 0);
13519 mini_frame->cursor_type_changed = 0;
13520 if (!pending && hscroll_windows (mini_window))
13521 goto retry;
13522 }
13523 }
13524
13525 /* If display was paused because of pending input, make sure we do a
13526 thorough update the next time. */
13527 if (pending)
13528 {
13529 /* Prevent the optimization at the beginning of
13530 redisplay_internal that tries a single-line update of the
13531 line containing the cursor in the selected window. */
13532 CHARPOS (this_line_start_pos) = 0;
13533
13534 /* Let the overlay arrow be updated the next time. */
13535 update_overlay_arrows (0);
13536
13537 /* If we pause after scrolling, some rows in the current
13538 matrices of some windows are not valid. */
13539 if (!WINDOW_FULL_WIDTH_P (w)
13540 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13541 update_mode_lines = 1;
13542 }
13543 else
13544 {
13545 if (!consider_all_windows_p)
13546 {
13547 /* This has already been done above if
13548 consider_all_windows_p is set. */
13549 mark_window_display_accurate_1 (w, 1);
13550
13551 /* Say overlay arrows are up to date. */
13552 update_overlay_arrows (1);
13553
13554 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13555 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13556 }
13557
13558 update_mode_lines = 0;
13559 windows_or_buffers_changed = 0;
13560 }
13561
13562 /* Start SIGIO interrupts coming again. Having them off during the
13563 code above makes it less likely one will discard output, but not
13564 impossible, since there might be stuff in the system buffer here.
13565 But it is much hairier to try to do anything about that. */
13566 if (interrupt_input)
13567 request_sigio ();
13568 RESUME_POLLING;
13569
13570 /* If a frame has become visible which was not before, redisplay
13571 again, so that we display it. Expose events for such a frame
13572 (which it gets when becoming visible) don't call the parts of
13573 redisplay constructing glyphs, so simply exposing a frame won't
13574 display anything in this case. So, we have to display these
13575 frames here explicitly. */
13576 if (!pending)
13577 {
13578 int new_count = 0;
13579
13580 FOR_EACH_FRAME (tail, frame)
13581 {
13582 int this_is_visible = 0;
13583
13584 if (XFRAME (frame)->visible)
13585 this_is_visible = 1;
13586
13587 if (this_is_visible)
13588 new_count++;
13589 }
13590
13591 if (new_count != number_of_visible_frames)
13592 windows_or_buffers_changed++;
13593 }
13594
13595 /* Change frame size now if a change is pending. */
13596 do_pending_window_change (1);
13597
13598 /* If we just did a pending size change, or have additional
13599 visible frames, or selected_window changed, redisplay again. */
13600 if ((windows_or_buffers_changed && !pending)
13601 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13602 goto retry;
13603
13604 /* Clear the face and image caches.
13605
13606 We used to do this only if consider_all_windows_p. But the cache
13607 needs to be cleared if a timer creates images in the current
13608 buffer (e.g. the test case in Bug#6230). */
13609
13610 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13611 {
13612 clear_face_cache (0);
13613 clear_face_cache_count = 0;
13614 }
13615
13616 #ifdef HAVE_WINDOW_SYSTEM
13617 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13618 {
13619 clear_image_caches (Qnil);
13620 clear_image_cache_count = 0;
13621 }
13622 #endif /* HAVE_WINDOW_SYSTEM */
13623
13624 end_of_redisplay:
13625 unbind_to (count, Qnil);
13626 RESUME_POLLING;
13627 }
13628
13629
13630 /* Redisplay, but leave alone any recent echo area message unless
13631 another message has been requested in its place.
13632
13633 This is useful in situations where you need to redisplay but no
13634 user action has occurred, making it inappropriate for the message
13635 area to be cleared. See tracking_off and
13636 wait_reading_process_output for examples of these situations.
13637
13638 FROM_WHERE is an integer saying from where this function was
13639 called. This is useful for debugging. */
13640
13641 void
13642 redisplay_preserve_echo_area (int from_where)
13643 {
13644 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13645
13646 if (!NILP (echo_area_buffer[1]))
13647 {
13648 /* We have a previously displayed message, but no current
13649 message. Redisplay the previous message. */
13650 display_last_displayed_message_p = 1;
13651 redisplay_internal ();
13652 display_last_displayed_message_p = 0;
13653 }
13654 else
13655 redisplay_internal ();
13656
13657 flush_frame (SELECTED_FRAME ());
13658 }
13659
13660
13661 /* Function registered with record_unwind_protect in redisplay_internal. */
13662
13663 static void
13664 unwind_redisplay (void)
13665 {
13666 redisplaying_p = 0;
13667 }
13668
13669
13670 /* Mark the display of leaf window W as accurate or inaccurate.
13671 If ACCURATE_P is non-zero mark display of W as accurate. If
13672 ACCURATE_P is zero, arrange for W to be redisplayed the next
13673 time redisplay_internal is called. */
13674
13675 static void
13676 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13677 {
13678 struct buffer *b = XBUFFER (w->contents);
13679
13680 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13681 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13682 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13683
13684 if (accurate_p)
13685 {
13686 b->clip_changed = 0;
13687 b->prevent_redisplay_optimizations_p = 0;
13688
13689 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13690 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13691 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13692 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13693
13694 w->current_matrix->buffer = b;
13695 w->current_matrix->begv = BUF_BEGV (b);
13696 w->current_matrix->zv = BUF_ZV (b);
13697
13698 w->last_cursor_vpos = w->cursor.vpos;
13699 w->last_cursor_off_p = w->cursor_off_p;
13700
13701 if (w == XWINDOW (selected_window))
13702 w->last_point = BUF_PT (b);
13703 else
13704 w->last_point = marker_position (w->pointm);
13705
13706 w->window_end_valid = 1;
13707 w->update_mode_line = 0;
13708 }
13709 }
13710
13711
13712 /* Mark the display of windows in the window tree rooted at WINDOW as
13713 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13714 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13715 be redisplayed the next time redisplay_internal is called. */
13716
13717 void
13718 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13719 {
13720 struct window *w;
13721
13722 for (; !NILP (window); window = w->next)
13723 {
13724 w = XWINDOW (window);
13725 if (WINDOWP (w->contents))
13726 mark_window_display_accurate (w->contents, accurate_p);
13727 else
13728 mark_window_display_accurate_1 (w, accurate_p);
13729 }
13730
13731 if (accurate_p)
13732 update_overlay_arrows (1);
13733 else
13734 /* Force a thorough redisplay the next time by setting
13735 last_arrow_position and last_arrow_string to t, which is
13736 unequal to any useful value of Voverlay_arrow_... */
13737 update_overlay_arrows (-1);
13738 }
13739
13740
13741 /* Return value in display table DP (Lisp_Char_Table *) for character
13742 C. Since a display table doesn't have any parent, we don't have to
13743 follow parent. Do not call this function directly but use the
13744 macro DISP_CHAR_VECTOR. */
13745
13746 Lisp_Object
13747 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13748 {
13749 Lisp_Object val;
13750
13751 if (ASCII_CHAR_P (c))
13752 {
13753 val = dp->ascii;
13754 if (SUB_CHAR_TABLE_P (val))
13755 val = XSUB_CHAR_TABLE (val)->contents[c];
13756 }
13757 else
13758 {
13759 Lisp_Object table;
13760
13761 XSETCHAR_TABLE (table, dp);
13762 val = char_table_ref (table, c);
13763 }
13764 if (NILP (val))
13765 val = dp->defalt;
13766 return val;
13767 }
13768
13769
13770 \f
13771 /***********************************************************************
13772 Window Redisplay
13773 ***********************************************************************/
13774
13775 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13776
13777 static void
13778 redisplay_windows (Lisp_Object window)
13779 {
13780 while (!NILP (window))
13781 {
13782 struct window *w = XWINDOW (window);
13783
13784 if (WINDOWP (w->contents))
13785 redisplay_windows (w->contents);
13786 else if (BUFFERP (w->contents))
13787 {
13788 displayed_buffer = XBUFFER (w->contents);
13789 /* Use list_of_error, not Qerror, so that
13790 we catch only errors and don't run the debugger. */
13791 internal_condition_case_1 (redisplay_window_0, window,
13792 list_of_error,
13793 redisplay_window_error);
13794 }
13795
13796 window = w->next;
13797 }
13798 }
13799
13800 static Lisp_Object
13801 redisplay_window_error (Lisp_Object ignore)
13802 {
13803 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13804 return Qnil;
13805 }
13806
13807 static Lisp_Object
13808 redisplay_window_0 (Lisp_Object window)
13809 {
13810 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13811 redisplay_window (window, 0);
13812 return Qnil;
13813 }
13814
13815 static Lisp_Object
13816 redisplay_window_1 (Lisp_Object window)
13817 {
13818 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13819 redisplay_window (window, 1);
13820 return Qnil;
13821 }
13822 \f
13823
13824 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13825 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13826 which positions recorded in ROW differ from current buffer
13827 positions.
13828
13829 Return 0 if cursor is not on this row, 1 otherwise. */
13830
13831 static int
13832 set_cursor_from_row (struct window *w, struct glyph_row *row,
13833 struct glyph_matrix *matrix,
13834 ptrdiff_t delta, ptrdiff_t delta_bytes,
13835 int dy, int dvpos)
13836 {
13837 struct glyph *glyph = row->glyphs[TEXT_AREA];
13838 struct glyph *end = glyph + row->used[TEXT_AREA];
13839 struct glyph *cursor = NULL;
13840 /* The last known character position in row. */
13841 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13842 int x = row->x;
13843 ptrdiff_t pt_old = PT - delta;
13844 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13845 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13846 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13847 /* A glyph beyond the edge of TEXT_AREA which we should never
13848 touch. */
13849 struct glyph *glyphs_end = end;
13850 /* Non-zero means we've found a match for cursor position, but that
13851 glyph has the avoid_cursor_p flag set. */
13852 int match_with_avoid_cursor = 0;
13853 /* Non-zero means we've seen at least one glyph that came from a
13854 display string. */
13855 int string_seen = 0;
13856 /* Largest and smallest buffer positions seen so far during scan of
13857 glyph row. */
13858 ptrdiff_t bpos_max = pos_before;
13859 ptrdiff_t bpos_min = pos_after;
13860 /* Last buffer position covered by an overlay string with an integer
13861 `cursor' property. */
13862 ptrdiff_t bpos_covered = 0;
13863 /* Non-zero means the display string on which to display the cursor
13864 comes from a text property, not from an overlay. */
13865 int string_from_text_prop = 0;
13866
13867 /* Don't even try doing anything if called for a mode-line or
13868 header-line row, since the rest of the code isn't prepared to
13869 deal with such calamities. */
13870 eassert (!row->mode_line_p);
13871 if (row->mode_line_p)
13872 return 0;
13873
13874 /* Skip over glyphs not having an object at the start and the end of
13875 the row. These are special glyphs like truncation marks on
13876 terminal frames. */
13877 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13878 {
13879 if (!row->reversed_p)
13880 {
13881 while (glyph < end
13882 && INTEGERP (glyph->object)
13883 && glyph->charpos < 0)
13884 {
13885 x += glyph->pixel_width;
13886 ++glyph;
13887 }
13888 while (end > glyph
13889 && INTEGERP ((end - 1)->object)
13890 /* CHARPOS is zero for blanks and stretch glyphs
13891 inserted by extend_face_to_end_of_line. */
13892 && (end - 1)->charpos <= 0)
13893 --end;
13894 glyph_before = glyph - 1;
13895 glyph_after = end;
13896 }
13897 else
13898 {
13899 struct glyph *g;
13900
13901 /* If the glyph row is reversed, we need to process it from back
13902 to front, so swap the edge pointers. */
13903 glyphs_end = end = glyph - 1;
13904 glyph += row->used[TEXT_AREA] - 1;
13905
13906 while (glyph > end + 1
13907 && INTEGERP (glyph->object)
13908 && glyph->charpos < 0)
13909 {
13910 --glyph;
13911 x -= glyph->pixel_width;
13912 }
13913 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13914 --glyph;
13915 /* By default, in reversed rows we put the cursor on the
13916 rightmost (first in the reading order) glyph. */
13917 for (g = end + 1; g < glyph; g++)
13918 x += g->pixel_width;
13919 while (end < glyph
13920 && INTEGERP ((end + 1)->object)
13921 && (end + 1)->charpos <= 0)
13922 ++end;
13923 glyph_before = glyph + 1;
13924 glyph_after = end;
13925 }
13926 }
13927 else if (row->reversed_p)
13928 {
13929 /* In R2L rows that don't display text, put the cursor on the
13930 rightmost glyph. Case in point: an empty last line that is
13931 part of an R2L paragraph. */
13932 cursor = end - 1;
13933 /* Avoid placing the cursor on the last glyph of the row, where
13934 on terminal frames we hold the vertical border between
13935 adjacent windows. */
13936 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13937 && !WINDOW_RIGHTMOST_P (w)
13938 && cursor == row->glyphs[LAST_AREA] - 1)
13939 cursor--;
13940 x = -1; /* will be computed below, at label compute_x */
13941 }
13942
13943 /* Step 1: Try to find the glyph whose character position
13944 corresponds to point. If that's not possible, find 2 glyphs
13945 whose character positions are the closest to point, one before
13946 point, the other after it. */
13947 if (!row->reversed_p)
13948 while (/* not marched to end of glyph row */
13949 glyph < end
13950 /* glyph was not inserted by redisplay for internal purposes */
13951 && !INTEGERP (glyph->object))
13952 {
13953 if (BUFFERP (glyph->object))
13954 {
13955 ptrdiff_t dpos = glyph->charpos - pt_old;
13956
13957 if (glyph->charpos > bpos_max)
13958 bpos_max = glyph->charpos;
13959 if (glyph->charpos < bpos_min)
13960 bpos_min = glyph->charpos;
13961 if (!glyph->avoid_cursor_p)
13962 {
13963 /* If we hit point, we've found the glyph on which to
13964 display the cursor. */
13965 if (dpos == 0)
13966 {
13967 match_with_avoid_cursor = 0;
13968 break;
13969 }
13970 /* See if we've found a better approximation to
13971 POS_BEFORE or to POS_AFTER. */
13972 if (0 > dpos && dpos > pos_before - pt_old)
13973 {
13974 pos_before = glyph->charpos;
13975 glyph_before = glyph;
13976 }
13977 else if (0 < dpos && dpos < pos_after - pt_old)
13978 {
13979 pos_after = glyph->charpos;
13980 glyph_after = glyph;
13981 }
13982 }
13983 else if (dpos == 0)
13984 match_with_avoid_cursor = 1;
13985 }
13986 else if (STRINGP (glyph->object))
13987 {
13988 Lisp_Object chprop;
13989 ptrdiff_t glyph_pos = glyph->charpos;
13990
13991 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13992 glyph->object);
13993 if (!NILP (chprop))
13994 {
13995 /* If the string came from a `display' text property,
13996 look up the buffer position of that property and
13997 use that position to update bpos_max, as if we
13998 actually saw such a position in one of the row's
13999 glyphs. This helps with supporting integer values
14000 of `cursor' property on the display string in
14001 situations where most or all of the row's buffer
14002 text is completely covered by display properties,
14003 so that no glyph with valid buffer positions is
14004 ever seen in the row. */
14005 ptrdiff_t prop_pos =
14006 string_buffer_position_lim (glyph->object, pos_before,
14007 pos_after, 0);
14008
14009 if (prop_pos >= pos_before)
14010 bpos_max = prop_pos - 1;
14011 }
14012 if (INTEGERP (chprop))
14013 {
14014 bpos_covered = bpos_max + XINT (chprop);
14015 /* If the `cursor' property covers buffer positions up
14016 to and including point, we should display cursor on
14017 this glyph. Note that, if a `cursor' property on one
14018 of the string's characters has an integer value, we
14019 will break out of the loop below _before_ we get to
14020 the position match above. IOW, integer values of
14021 the `cursor' property override the "exact match for
14022 point" strategy of positioning the cursor. */
14023 /* Implementation note: bpos_max == pt_old when, e.g.,
14024 we are in an empty line, where bpos_max is set to
14025 MATRIX_ROW_START_CHARPOS, see above. */
14026 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14027 {
14028 cursor = glyph;
14029 break;
14030 }
14031 }
14032
14033 string_seen = 1;
14034 }
14035 x += glyph->pixel_width;
14036 ++glyph;
14037 }
14038 else if (glyph > end) /* row is reversed */
14039 while (!INTEGERP (glyph->object))
14040 {
14041 if (BUFFERP (glyph->object))
14042 {
14043 ptrdiff_t dpos = glyph->charpos - pt_old;
14044
14045 if (glyph->charpos > bpos_max)
14046 bpos_max = glyph->charpos;
14047 if (glyph->charpos < bpos_min)
14048 bpos_min = glyph->charpos;
14049 if (!glyph->avoid_cursor_p)
14050 {
14051 if (dpos == 0)
14052 {
14053 match_with_avoid_cursor = 0;
14054 break;
14055 }
14056 if (0 > dpos && dpos > pos_before - pt_old)
14057 {
14058 pos_before = glyph->charpos;
14059 glyph_before = glyph;
14060 }
14061 else if (0 < dpos && dpos < pos_after - pt_old)
14062 {
14063 pos_after = glyph->charpos;
14064 glyph_after = glyph;
14065 }
14066 }
14067 else if (dpos == 0)
14068 match_with_avoid_cursor = 1;
14069 }
14070 else if (STRINGP (glyph->object))
14071 {
14072 Lisp_Object chprop;
14073 ptrdiff_t glyph_pos = glyph->charpos;
14074
14075 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14076 glyph->object);
14077 if (!NILP (chprop))
14078 {
14079 ptrdiff_t prop_pos =
14080 string_buffer_position_lim (glyph->object, pos_before,
14081 pos_after, 0);
14082
14083 if (prop_pos >= pos_before)
14084 bpos_max = prop_pos - 1;
14085 }
14086 if (INTEGERP (chprop))
14087 {
14088 bpos_covered = bpos_max + XINT (chprop);
14089 /* If the `cursor' property covers buffer positions up
14090 to and including point, we should display cursor on
14091 this glyph. */
14092 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14093 {
14094 cursor = glyph;
14095 break;
14096 }
14097 }
14098 string_seen = 1;
14099 }
14100 --glyph;
14101 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14102 {
14103 x--; /* can't use any pixel_width */
14104 break;
14105 }
14106 x -= glyph->pixel_width;
14107 }
14108
14109 /* Step 2: If we didn't find an exact match for point, we need to
14110 look for a proper place to put the cursor among glyphs between
14111 GLYPH_BEFORE and GLYPH_AFTER. */
14112 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14113 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14114 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14115 {
14116 /* An empty line has a single glyph whose OBJECT is zero and
14117 whose CHARPOS is the position of a newline on that line.
14118 Note that on a TTY, there are more glyphs after that, which
14119 were produced by extend_face_to_end_of_line, but their
14120 CHARPOS is zero or negative. */
14121 int empty_line_p =
14122 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14123 && INTEGERP (glyph->object) && glyph->charpos > 0
14124 /* On a TTY, continued and truncated rows also have a glyph at
14125 their end whose OBJECT is zero and whose CHARPOS is
14126 positive (the continuation and truncation glyphs), but such
14127 rows are obviously not "empty". */
14128 && !(row->continued_p || row->truncated_on_right_p);
14129
14130 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14131 {
14132 ptrdiff_t ellipsis_pos;
14133
14134 /* Scan back over the ellipsis glyphs. */
14135 if (!row->reversed_p)
14136 {
14137 ellipsis_pos = (glyph - 1)->charpos;
14138 while (glyph > row->glyphs[TEXT_AREA]
14139 && (glyph - 1)->charpos == ellipsis_pos)
14140 glyph--, x -= glyph->pixel_width;
14141 /* That loop always goes one position too far, including
14142 the glyph before the ellipsis. So scan forward over
14143 that one. */
14144 x += glyph->pixel_width;
14145 glyph++;
14146 }
14147 else /* row is reversed */
14148 {
14149 ellipsis_pos = (glyph + 1)->charpos;
14150 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14151 && (glyph + 1)->charpos == ellipsis_pos)
14152 glyph++, x += glyph->pixel_width;
14153 x -= glyph->pixel_width;
14154 glyph--;
14155 }
14156 }
14157 else if (match_with_avoid_cursor)
14158 {
14159 cursor = glyph_after;
14160 x = -1;
14161 }
14162 else if (string_seen)
14163 {
14164 int incr = row->reversed_p ? -1 : +1;
14165
14166 /* Need to find the glyph that came out of a string which is
14167 present at point. That glyph is somewhere between
14168 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14169 positioned between POS_BEFORE and POS_AFTER in the
14170 buffer. */
14171 struct glyph *start, *stop;
14172 ptrdiff_t pos = pos_before;
14173
14174 x = -1;
14175
14176 /* If the row ends in a newline from a display string,
14177 reordering could have moved the glyphs belonging to the
14178 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14179 in this case we extend the search to the last glyph in
14180 the row that was not inserted by redisplay. */
14181 if (row->ends_in_newline_from_string_p)
14182 {
14183 glyph_after = end;
14184 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14185 }
14186
14187 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14188 correspond to POS_BEFORE and POS_AFTER, respectively. We
14189 need START and STOP in the order that corresponds to the
14190 row's direction as given by its reversed_p flag. If the
14191 directionality of characters between POS_BEFORE and
14192 POS_AFTER is the opposite of the row's base direction,
14193 these characters will have been reordered for display,
14194 and we need to reverse START and STOP. */
14195 if (!row->reversed_p)
14196 {
14197 start = min (glyph_before, glyph_after);
14198 stop = max (glyph_before, glyph_after);
14199 }
14200 else
14201 {
14202 start = max (glyph_before, glyph_after);
14203 stop = min (glyph_before, glyph_after);
14204 }
14205 for (glyph = start + incr;
14206 row->reversed_p ? glyph > stop : glyph < stop; )
14207 {
14208
14209 /* Any glyphs that come from the buffer are here because
14210 of bidi reordering. Skip them, and only pay
14211 attention to glyphs that came from some string. */
14212 if (STRINGP (glyph->object))
14213 {
14214 Lisp_Object str;
14215 ptrdiff_t tem;
14216 /* If the display property covers the newline, we
14217 need to search for it one position farther. */
14218 ptrdiff_t lim = pos_after
14219 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14220
14221 string_from_text_prop = 0;
14222 str = glyph->object;
14223 tem = string_buffer_position_lim (str, pos, lim, 0);
14224 if (tem == 0 /* from overlay */
14225 || pos <= tem)
14226 {
14227 /* If the string from which this glyph came is
14228 found in the buffer at point, or at position
14229 that is closer to point than pos_after, then
14230 we've found the glyph we've been looking for.
14231 If it comes from an overlay (tem == 0), and
14232 it has the `cursor' property on one of its
14233 glyphs, record that glyph as a candidate for
14234 displaying the cursor. (As in the
14235 unidirectional version, we will display the
14236 cursor on the last candidate we find.) */
14237 if (tem == 0
14238 || tem == pt_old
14239 || (tem - pt_old > 0 && tem < pos_after))
14240 {
14241 /* The glyphs from this string could have
14242 been reordered. Find the one with the
14243 smallest string position. Or there could
14244 be a character in the string with the
14245 `cursor' property, which means display
14246 cursor on that character's glyph. */
14247 ptrdiff_t strpos = glyph->charpos;
14248
14249 if (tem)
14250 {
14251 cursor = glyph;
14252 string_from_text_prop = 1;
14253 }
14254 for ( ;
14255 (row->reversed_p ? glyph > stop : glyph < stop)
14256 && EQ (glyph->object, str);
14257 glyph += incr)
14258 {
14259 Lisp_Object cprop;
14260 ptrdiff_t gpos = glyph->charpos;
14261
14262 cprop = Fget_char_property (make_number (gpos),
14263 Qcursor,
14264 glyph->object);
14265 if (!NILP (cprop))
14266 {
14267 cursor = glyph;
14268 break;
14269 }
14270 if (tem && glyph->charpos < strpos)
14271 {
14272 strpos = glyph->charpos;
14273 cursor = glyph;
14274 }
14275 }
14276
14277 if (tem == pt_old
14278 || (tem - pt_old > 0 && tem < pos_after))
14279 goto compute_x;
14280 }
14281 if (tem)
14282 pos = tem + 1; /* don't find previous instances */
14283 }
14284 /* This string is not what we want; skip all of the
14285 glyphs that came from it. */
14286 while ((row->reversed_p ? glyph > stop : glyph < stop)
14287 && EQ (glyph->object, str))
14288 glyph += incr;
14289 }
14290 else
14291 glyph += incr;
14292 }
14293
14294 /* If we reached the end of the line, and END was from a string,
14295 the cursor is not on this line. */
14296 if (cursor == NULL
14297 && (row->reversed_p ? glyph <= end : glyph >= end)
14298 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14299 && STRINGP (end->object)
14300 && row->continued_p)
14301 return 0;
14302 }
14303 /* A truncated row may not include PT among its character positions.
14304 Setting the cursor inside the scroll margin will trigger
14305 recalculation of hscroll in hscroll_window_tree. But if a
14306 display string covers point, defer to the string-handling
14307 code below to figure this out. */
14308 else if (row->truncated_on_left_p && pt_old < bpos_min)
14309 {
14310 cursor = glyph_before;
14311 x = -1;
14312 }
14313 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14314 /* Zero-width characters produce no glyphs. */
14315 || (!empty_line_p
14316 && (row->reversed_p
14317 ? glyph_after > glyphs_end
14318 : glyph_after < glyphs_end)))
14319 {
14320 cursor = glyph_after;
14321 x = -1;
14322 }
14323 }
14324
14325 compute_x:
14326 if (cursor != NULL)
14327 glyph = cursor;
14328 else if (glyph == glyphs_end
14329 && pos_before == pos_after
14330 && STRINGP ((row->reversed_p
14331 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14332 : row->glyphs[TEXT_AREA])->object))
14333 {
14334 /* If all the glyphs of this row came from strings, put the
14335 cursor on the first glyph of the row. This avoids having the
14336 cursor outside of the text area in this very rare and hard
14337 use case. */
14338 glyph =
14339 row->reversed_p
14340 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14341 : row->glyphs[TEXT_AREA];
14342 }
14343 if (x < 0)
14344 {
14345 struct glyph *g;
14346
14347 /* Need to compute x that corresponds to GLYPH. */
14348 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14349 {
14350 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14351 emacs_abort ();
14352 x += g->pixel_width;
14353 }
14354 }
14355
14356 /* ROW could be part of a continued line, which, under bidi
14357 reordering, might have other rows whose start and end charpos
14358 occlude point. Only set w->cursor if we found a better
14359 approximation to the cursor position than we have from previously
14360 examined candidate rows belonging to the same continued line. */
14361 if (/* we already have a candidate row */
14362 w->cursor.vpos >= 0
14363 /* that candidate is not the row we are processing */
14364 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14365 /* Make sure cursor.vpos specifies a row whose start and end
14366 charpos occlude point, and it is valid candidate for being a
14367 cursor-row. This is because some callers of this function
14368 leave cursor.vpos at the row where the cursor was displayed
14369 during the last redisplay cycle. */
14370 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14371 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14372 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14373 {
14374 struct glyph *g1 =
14375 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14376
14377 /* Don't consider glyphs that are outside TEXT_AREA. */
14378 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14379 return 0;
14380 /* Keep the candidate whose buffer position is the closest to
14381 point or has the `cursor' property. */
14382 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14383 w->cursor.hpos >= 0
14384 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14385 && ((BUFFERP (g1->object)
14386 && (g1->charpos == pt_old /* an exact match always wins */
14387 || (BUFFERP (glyph->object)
14388 && eabs (g1->charpos - pt_old)
14389 < eabs (glyph->charpos - pt_old))))
14390 /* previous candidate is a glyph from a string that has
14391 a non-nil `cursor' property */
14392 || (STRINGP (g1->object)
14393 && (!NILP (Fget_char_property (make_number (g1->charpos),
14394 Qcursor, g1->object))
14395 /* previous candidate is from the same display
14396 string as this one, and the display string
14397 came from a text property */
14398 || (EQ (g1->object, glyph->object)
14399 && string_from_text_prop)
14400 /* this candidate is from newline and its
14401 position is not an exact match */
14402 || (INTEGERP (glyph->object)
14403 && glyph->charpos != pt_old)))))
14404 return 0;
14405 /* If this candidate gives an exact match, use that. */
14406 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14407 /* If this candidate is a glyph created for the
14408 terminating newline of a line, and point is on that
14409 newline, it wins because it's an exact match. */
14410 || (!row->continued_p
14411 && INTEGERP (glyph->object)
14412 && glyph->charpos == 0
14413 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14414 /* Otherwise, keep the candidate that comes from a row
14415 spanning less buffer positions. This may win when one or
14416 both candidate positions are on glyphs that came from
14417 display strings, for which we cannot compare buffer
14418 positions. */
14419 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14420 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14421 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14422 return 0;
14423 }
14424 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14425 w->cursor.x = x;
14426 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14427 w->cursor.y = row->y + dy;
14428
14429 if (w == XWINDOW (selected_window))
14430 {
14431 if (!row->continued_p
14432 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14433 && row->x == 0)
14434 {
14435 this_line_buffer = XBUFFER (w->contents);
14436
14437 CHARPOS (this_line_start_pos)
14438 = MATRIX_ROW_START_CHARPOS (row) + delta;
14439 BYTEPOS (this_line_start_pos)
14440 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14441
14442 CHARPOS (this_line_end_pos)
14443 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14444 BYTEPOS (this_line_end_pos)
14445 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14446
14447 this_line_y = w->cursor.y;
14448 this_line_pixel_height = row->height;
14449 this_line_vpos = w->cursor.vpos;
14450 this_line_start_x = row->x;
14451 }
14452 else
14453 CHARPOS (this_line_start_pos) = 0;
14454 }
14455
14456 return 1;
14457 }
14458
14459
14460 /* Run window scroll functions, if any, for WINDOW with new window
14461 start STARTP. Sets the window start of WINDOW to that position.
14462
14463 We assume that the window's buffer is really current. */
14464
14465 static struct text_pos
14466 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14467 {
14468 struct window *w = XWINDOW (window);
14469 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14470
14471 eassert (current_buffer == XBUFFER (w->contents));
14472
14473 if (!NILP (Vwindow_scroll_functions))
14474 {
14475 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14476 make_number (CHARPOS (startp)));
14477 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14478 /* In case the hook functions switch buffers. */
14479 set_buffer_internal (XBUFFER (w->contents));
14480 }
14481
14482 return startp;
14483 }
14484
14485
14486 /* Make sure the line containing the cursor is fully visible.
14487 A value of 1 means there is nothing to be done.
14488 (Either the line is fully visible, or it cannot be made so,
14489 or we cannot tell.)
14490
14491 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14492 is higher than window.
14493
14494 A value of 0 means the caller should do scrolling
14495 as if point had gone off the screen. */
14496
14497 static int
14498 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14499 {
14500 struct glyph_matrix *matrix;
14501 struct glyph_row *row;
14502 int window_height;
14503
14504 if (!make_cursor_line_fully_visible_p)
14505 return 1;
14506
14507 /* It's not always possible to find the cursor, e.g, when a window
14508 is full of overlay strings. Don't do anything in that case. */
14509 if (w->cursor.vpos < 0)
14510 return 1;
14511
14512 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14513 row = MATRIX_ROW (matrix, w->cursor.vpos);
14514
14515 /* If the cursor row is not partially visible, there's nothing to do. */
14516 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14517 return 1;
14518
14519 /* If the row the cursor is in is taller than the window's height,
14520 it's not clear what to do, so do nothing. */
14521 window_height = window_box_height (w);
14522 if (row->height >= window_height)
14523 {
14524 if (!force_p || MINI_WINDOW_P (w)
14525 || w->vscroll || w->cursor.vpos == 0)
14526 return 1;
14527 }
14528 return 0;
14529 }
14530
14531
14532 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14533 non-zero means only WINDOW is redisplayed in redisplay_internal.
14534 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14535 in redisplay_window to bring a partially visible line into view in
14536 the case that only the cursor has moved.
14537
14538 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14539 last screen line's vertical height extends past the end of the screen.
14540
14541 Value is
14542
14543 1 if scrolling succeeded
14544
14545 0 if scrolling didn't find point.
14546
14547 -1 if new fonts have been loaded so that we must interrupt
14548 redisplay, adjust glyph matrices, and try again. */
14549
14550 enum
14551 {
14552 SCROLLING_SUCCESS,
14553 SCROLLING_FAILED,
14554 SCROLLING_NEED_LARGER_MATRICES
14555 };
14556
14557 /* If scroll-conservatively is more than this, never recenter.
14558
14559 If you change this, don't forget to update the doc string of
14560 `scroll-conservatively' and the Emacs manual. */
14561 #define SCROLL_LIMIT 100
14562
14563 static int
14564 try_scrolling (Lisp_Object window, int just_this_one_p,
14565 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14566 int temp_scroll_step, int last_line_misfit)
14567 {
14568 struct window *w = XWINDOW (window);
14569 struct frame *f = XFRAME (w->frame);
14570 struct text_pos pos, startp;
14571 struct it it;
14572 int this_scroll_margin, scroll_max, rc, height;
14573 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14574 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14575 Lisp_Object aggressive;
14576 /* We will never try scrolling more than this number of lines. */
14577 int scroll_limit = SCROLL_LIMIT;
14578 int frame_line_height = default_line_pixel_height (w);
14579 int window_total_lines
14580 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
14581
14582 #ifdef GLYPH_DEBUG
14583 debug_method_add (w, "try_scrolling");
14584 #endif
14585
14586 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14587
14588 /* Compute scroll margin height in pixels. We scroll when point is
14589 within this distance from the top or bottom of the window. */
14590 if (scroll_margin > 0)
14591 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
14592 * frame_line_height;
14593 else
14594 this_scroll_margin = 0;
14595
14596 /* Force arg_scroll_conservatively to have a reasonable value, to
14597 avoid scrolling too far away with slow move_it_* functions. Note
14598 that the user can supply scroll-conservatively equal to
14599 `most-positive-fixnum', which can be larger than INT_MAX. */
14600 if (arg_scroll_conservatively > scroll_limit)
14601 {
14602 arg_scroll_conservatively = scroll_limit + 1;
14603 scroll_max = scroll_limit * frame_line_height;
14604 }
14605 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14606 /* Compute how much we should try to scroll maximally to bring
14607 point into view. */
14608 scroll_max = (max (scroll_step,
14609 max (arg_scroll_conservatively, temp_scroll_step))
14610 * frame_line_height);
14611 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14612 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14613 /* We're trying to scroll because of aggressive scrolling but no
14614 scroll_step is set. Choose an arbitrary one. */
14615 scroll_max = 10 * frame_line_height;
14616 else
14617 scroll_max = 0;
14618
14619 too_near_end:
14620
14621 /* Decide whether to scroll down. */
14622 if (PT > CHARPOS (startp))
14623 {
14624 int scroll_margin_y;
14625
14626 /* Compute the pixel ypos of the scroll margin, then move IT to
14627 either that ypos or PT, whichever comes first. */
14628 start_display (&it, w, startp);
14629 scroll_margin_y = it.last_visible_y - this_scroll_margin
14630 - frame_line_height * extra_scroll_margin_lines;
14631 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14632 (MOVE_TO_POS | MOVE_TO_Y));
14633
14634 if (PT > CHARPOS (it.current.pos))
14635 {
14636 int y0 = line_bottom_y (&it);
14637 /* Compute how many pixels below window bottom to stop searching
14638 for PT. This avoids costly search for PT that is far away if
14639 the user limited scrolling by a small number of lines, but
14640 always finds PT if scroll_conservatively is set to a large
14641 number, such as most-positive-fixnum. */
14642 int slack = max (scroll_max, 10 * frame_line_height);
14643 int y_to_move = it.last_visible_y + slack;
14644
14645 /* Compute the distance from the scroll margin to PT or to
14646 the scroll limit, whichever comes first. This should
14647 include the height of the cursor line, to make that line
14648 fully visible. */
14649 move_it_to (&it, PT, -1, y_to_move,
14650 -1, MOVE_TO_POS | MOVE_TO_Y);
14651 dy = line_bottom_y (&it) - y0;
14652
14653 if (dy > scroll_max)
14654 return SCROLLING_FAILED;
14655
14656 if (dy > 0)
14657 scroll_down_p = 1;
14658 }
14659 }
14660
14661 if (scroll_down_p)
14662 {
14663 /* Point is in or below the bottom scroll margin, so move the
14664 window start down. If scrolling conservatively, move it just
14665 enough down to make point visible. If scroll_step is set,
14666 move it down by scroll_step. */
14667 if (arg_scroll_conservatively)
14668 amount_to_scroll
14669 = min (max (dy, frame_line_height),
14670 frame_line_height * arg_scroll_conservatively);
14671 else if (scroll_step || temp_scroll_step)
14672 amount_to_scroll = scroll_max;
14673 else
14674 {
14675 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14676 height = WINDOW_BOX_TEXT_HEIGHT (w);
14677 if (NUMBERP (aggressive))
14678 {
14679 double float_amount = XFLOATINT (aggressive) * height;
14680 int aggressive_scroll = float_amount;
14681 if (aggressive_scroll == 0 && float_amount > 0)
14682 aggressive_scroll = 1;
14683 /* Don't let point enter the scroll margin near top of
14684 the window. This could happen if the value of
14685 scroll_up_aggressively is too large and there are
14686 non-zero margins, because scroll_up_aggressively
14687 means put point that fraction of window height
14688 _from_the_bottom_margin_. */
14689 if (aggressive_scroll + 2*this_scroll_margin > height)
14690 aggressive_scroll = height - 2*this_scroll_margin;
14691 amount_to_scroll = dy + aggressive_scroll;
14692 }
14693 }
14694
14695 if (amount_to_scroll <= 0)
14696 return SCROLLING_FAILED;
14697
14698 start_display (&it, w, startp);
14699 if (arg_scroll_conservatively <= scroll_limit)
14700 move_it_vertically (&it, amount_to_scroll);
14701 else
14702 {
14703 /* Extra precision for users who set scroll-conservatively
14704 to a large number: make sure the amount we scroll
14705 the window start is never less than amount_to_scroll,
14706 which was computed as distance from window bottom to
14707 point. This matters when lines at window top and lines
14708 below window bottom have different height. */
14709 struct it it1;
14710 void *it1data = NULL;
14711 /* We use a temporary it1 because line_bottom_y can modify
14712 its argument, if it moves one line down; see there. */
14713 int start_y;
14714
14715 SAVE_IT (it1, it, it1data);
14716 start_y = line_bottom_y (&it1);
14717 do {
14718 RESTORE_IT (&it, &it, it1data);
14719 move_it_by_lines (&it, 1);
14720 SAVE_IT (it1, it, it1data);
14721 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14722 }
14723
14724 /* If STARTP is unchanged, move it down another screen line. */
14725 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14726 move_it_by_lines (&it, 1);
14727 startp = it.current.pos;
14728 }
14729 else
14730 {
14731 struct text_pos scroll_margin_pos = startp;
14732 int y_offset = 0;
14733
14734 /* See if point is inside the scroll margin at the top of the
14735 window. */
14736 if (this_scroll_margin)
14737 {
14738 int y_start;
14739
14740 start_display (&it, w, startp);
14741 y_start = it.current_y;
14742 move_it_vertically (&it, this_scroll_margin);
14743 scroll_margin_pos = it.current.pos;
14744 /* If we didn't move enough before hitting ZV, request
14745 additional amount of scroll, to move point out of the
14746 scroll margin. */
14747 if (IT_CHARPOS (it) == ZV
14748 && it.current_y - y_start < this_scroll_margin)
14749 y_offset = this_scroll_margin - (it.current_y - y_start);
14750 }
14751
14752 if (PT < CHARPOS (scroll_margin_pos))
14753 {
14754 /* Point is in the scroll margin at the top of the window or
14755 above what is displayed in the window. */
14756 int y0, y_to_move;
14757
14758 /* Compute the vertical distance from PT to the scroll
14759 margin position. Move as far as scroll_max allows, or
14760 one screenful, or 10 screen lines, whichever is largest.
14761 Give up if distance is greater than scroll_max or if we
14762 didn't reach the scroll margin position. */
14763 SET_TEXT_POS (pos, PT, PT_BYTE);
14764 start_display (&it, w, pos);
14765 y0 = it.current_y;
14766 y_to_move = max (it.last_visible_y,
14767 max (scroll_max, 10 * frame_line_height));
14768 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14769 y_to_move, -1,
14770 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14771 dy = it.current_y - y0;
14772 if (dy > scroll_max
14773 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14774 return SCROLLING_FAILED;
14775
14776 /* Additional scroll for when ZV was too close to point. */
14777 dy += y_offset;
14778
14779 /* Compute new window start. */
14780 start_display (&it, w, startp);
14781
14782 if (arg_scroll_conservatively)
14783 amount_to_scroll = max (dy, frame_line_height *
14784 max (scroll_step, temp_scroll_step));
14785 else if (scroll_step || temp_scroll_step)
14786 amount_to_scroll = scroll_max;
14787 else
14788 {
14789 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14790 height = WINDOW_BOX_TEXT_HEIGHT (w);
14791 if (NUMBERP (aggressive))
14792 {
14793 double float_amount = XFLOATINT (aggressive) * height;
14794 int aggressive_scroll = float_amount;
14795 if (aggressive_scroll == 0 && float_amount > 0)
14796 aggressive_scroll = 1;
14797 /* Don't let point enter the scroll margin near
14798 bottom of the window, if the value of
14799 scroll_down_aggressively happens to be too
14800 large. */
14801 if (aggressive_scroll + 2*this_scroll_margin > height)
14802 aggressive_scroll = height - 2*this_scroll_margin;
14803 amount_to_scroll = dy + aggressive_scroll;
14804 }
14805 }
14806
14807 if (amount_to_scroll <= 0)
14808 return SCROLLING_FAILED;
14809
14810 move_it_vertically_backward (&it, amount_to_scroll);
14811 startp = it.current.pos;
14812 }
14813 }
14814
14815 /* Run window scroll functions. */
14816 startp = run_window_scroll_functions (window, startp);
14817
14818 /* Display the window. Give up if new fonts are loaded, or if point
14819 doesn't appear. */
14820 if (!try_window (window, startp, 0))
14821 rc = SCROLLING_NEED_LARGER_MATRICES;
14822 else if (w->cursor.vpos < 0)
14823 {
14824 clear_glyph_matrix (w->desired_matrix);
14825 rc = SCROLLING_FAILED;
14826 }
14827 else
14828 {
14829 /* Maybe forget recorded base line for line number display. */
14830 if (!just_this_one_p
14831 || current_buffer->clip_changed
14832 || BEG_UNCHANGED < CHARPOS (startp))
14833 w->base_line_number = 0;
14834
14835 /* If cursor ends up on a partially visible line,
14836 treat that as being off the bottom of the screen. */
14837 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14838 /* It's possible that the cursor is on the first line of the
14839 buffer, which is partially obscured due to a vscroll
14840 (Bug#7537). In that case, avoid looping forever . */
14841 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14842 {
14843 clear_glyph_matrix (w->desired_matrix);
14844 ++extra_scroll_margin_lines;
14845 goto too_near_end;
14846 }
14847 rc = SCROLLING_SUCCESS;
14848 }
14849
14850 return rc;
14851 }
14852
14853
14854 /* Compute a suitable window start for window W if display of W starts
14855 on a continuation line. Value is non-zero if a new window start
14856 was computed.
14857
14858 The new window start will be computed, based on W's width, starting
14859 from the start of the continued line. It is the start of the
14860 screen line with the minimum distance from the old start W->start. */
14861
14862 static int
14863 compute_window_start_on_continuation_line (struct window *w)
14864 {
14865 struct text_pos pos, start_pos;
14866 int window_start_changed_p = 0;
14867
14868 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14869
14870 /* If window start is on a continuation line... Window start may be
14871 < BEGV in case there's invisible text at the start of the
14872 buffer (M-x rmail, for example). */
14873 if (CHARPOS (start_pos) > BEGV
14874 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14875 {
14876 struct it it;
14877 struct glyph_row *row;
14878
14879 /* Handle the case that the window start is out of range. */
14880 if (CHARPOS (start_pos) < BEGV)
14881 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14882 else if (CHARPOS (start_pos) > ZV)
14883 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14884
14885 /* Find the start of the continued line. This should be fast
14886 because find_newline is fast (newline cache). */
14887 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14888 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14889 row, DEFAULT_FACE_ID);
14890 reseat_at_previous_visible_line_start (&it);
14891
14892 /* If the line start is "too far" away from the window start,
14893 say it takes too much time to compute a new window start. */
14894 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14895 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14896 {
14897 int min_distance, distance;
14898
14899 /* Move forward by display lines to find the new window
14900 start. If window width was enlarged, the new start can
14901 be expected to be > the old start. If window width was
14902 decreased, the new window start will be < the old start.
14903 So, we're looking for the display line start with the
14904 minimum distance from the old window start. */
14905 pos = it.current.pos;
14906 min_distance = INFINITY;
14907 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14908 distance < min_distance)
14909 {
14910 min_distance = distance;
14911 pos = it.current.pos;
14912 if (it.line_wrap == WORD_WRAP)
14913 {
14914 /* Under WORD_WRAP, move_it_by_lines is likely to
14915 overshoot and stop not at the first, but the
14916 second character from the left margin. So in
14917 that case, we need a more tight control on the X
14918 coordinate of the iterator than move_it_by_lines
14919 promises in its contract. The method is to first
14920 go to the last (rightmost) visible character of a
14921 line, then move to the leftmost character on the
14922 next line in a separate call. */
14923 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
14924 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14925 move_it_to (&it, ZV, 0,
14926 it.current_y + it.max_ascent + it.max_descent, -1,
14927 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14928 }
14929 else
14930 move_it_by_lines (&it, 1);
14931 }
14932
14933 /* Set the window start there. */
14934 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14935 window_start_changed_p = 1;
14936 }
14937 }
14938
14939 return window_start_changed_p;
14940 }
14941
14942
14943 /* Try cursor movement in case text has not changed in window WINDOW,
14944 with window start STARTP. Value is
14945
14946 CURSOR_MOVEMENT_SUCCESS if successful
14947
14948 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14949
14950 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14951 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14952 we want to scroll as if scroll-step were set to 1. See the code.
14953
14954 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14955 which case we have to abort this redisplay, and adjust matrices
14956 first. */
14957
14958 enum
14959 {
14960 CURSOR_MOVEMENT_SUCCESS,
14961 CURSOR_MOVEMENT_CANNOT_BE_USED,
14962 CURSOR_MOVEMENT_MUST_SCROLL,
14963 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14964 };
14965
14966 static int
14967 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14968 {
14969 struct window *w = XWINDOW (window);
14970 struct frame *f = XFRAME (w->frame);
14971 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14972
14973 #ifdef GLYPH_DEBUG
14974 if (inhibit_try_cursor_movement)
14975 return rc;
14976 #endif
14977
14978 /* Previously, there was a check for Lisp integer in the
14979 if-statement below. Now, this field is converted to
14980 ptrdiff_t, thus zero means invalid position in a buffer. */
14981 eassert (w->last_point > 0);
14982 /* Likewise there was a check whether window_end_vpos is nil or larger
14983 than the window. Now window_end_vpos is int and so never nil, but
14984 let's leave eassert to check whether it fits in the window. */
14985 eassert (w->window_end_vpos < w->current_matrix->nrows);
14986
14987 /* Handle case where text has not changed, only point, and it has
14988 not moved off the frame. */
14989 if (/* Point may be in this window. */
14990 PT >= CHARPOS (startp)
14991 /* Selective display hasn't changed. */
14992 && !current_buffer->clip_changed
14993 /* Function force-mode-line-update is used to force a thorough
14994 redisplay. It sets either windows_or_buffers_changed or
14995 update_mode_lines. So don't take a shortcut here for these
14996 cases. */
14997 && !update_mode_lines
14998 && !windows_or_buffers_changed
14999 && !f->cursor_type_changed
15000 /* Can't use this case if highlighting a region. When a
15001 region exists, cursor movement has to do more than just
15002 set the cursor. */
15003 && markpos_of_region () < 0
15004 && !w->region_showing
15005 && NILP (Vshow_trailing_whitespace)
15006 /* This code is not used for mini-buffer for the sake of the case
15007 of redisplaying to replace an echo area message; since in
15008 that case the mini-buffer contents per se are usually
15009 unchanged. This code is of no real use in the mini-buffer
15010 since the handling of this_line_start_pos, etc., in redisplay
15011 handles the same cases. */
15012 && !EQ (window, minibuf_window)
15013 && (FRAME_WINDOW_P (f)
15014 || !overlay_arrow_in_current_buffer_p ()))
15015 {
15016 int this_scroll_margin, top_scroll_margin;
15017 struct glyph_row *row = NULL;
15018 int frame_line_height = default_line_pixel_height (w);
15019 int window_total_lines
15020 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15021
15022 #ifdef GLYPH_DEBUG
15023 debug_method_add (w, "cursor movement");
15024 #endif
15025
15026 /* Scroll if point within this distance from the top or bottom
15027 of the window. This is a pixel value. */
15028 if (scroll_margin > 0)
15029 {
15030 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15031 this_scroll_margin *= frame_line_height;
15032 }
15033 else
15034 this_scroll_margin = 0;
15035
15036 top_scroll_margin = this_scroll_margin;
15037 if (WINDOW_WANTS_HEADER_LINE_P (w))
15038 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15039
15040 /* Start with the row the cursor was displayed during the last
15041 not paused redisplay. Give up if that row is not valid. */
15042 if (w->last_cursor_vpos < 0
15043 || w->last_cursor_vpos >= w->current_matrix->nrows)
15044 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15045 else
15046 {
15047 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15048 if (row->mode_line_p)
15049 ++row;
15050 if (!row->enabled_p)
15051 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15052 }
15053
15054 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15055 {
15056 int scroll_p = 0, must_scroll = 0;
15057 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15058
15059 if (PT > w->last_point)
15060 {
15061 /* Point has moved forward. */
15062 while (MATRIX_ROW_END_CHARPOS (row) < PT
15063 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15064 {
15065 eassert (row->enabled_p);
15066 ++row;
15067 }
15068
15069 /* If the end position of a row equals the start
15070 position of the next row, and PT is at that position,
15071 we would rather display cursor in the next line. */
15072 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15073 && MATRIX_ROW_END_CHARPOS (row) == PT
15074 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15075 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15076 && !cursor_row_p (row))
15077 ++row;
15078
15079 /* If within the scroll margin, scroll. Note that
15080 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15081 the next line would be drawn, and that
15082 this_scroll_margin can be zero. */
15083 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15084 || PT > MATRIX_ROW_END_CHARPOS (row)
15085 /* Line is completely visible last line in window
15086 and PT is to be set in the next line. */
15087 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15088 && PT == MATRIX_ROW_END_CHARPOS (row)
15089 && !row->ends_at_zv_p
15090 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15091 scroll_p = 1;
15092 }
15093 else if (PT < w->last_point)
15094 {
15095 /* Cursor has to be moved backward. Note that PT >=
15096 CHARPOS (startp) because of the outer if-statement. */
15097 while (!row->mode_line_p
15098 && (MATRIX_ROW_START_CHARPOS (row) > PT
15099 || (MATRIX_ROW_START_CHARPOS (row) == PT
15100 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15101 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15102 row > w->current_matrix->rows
15103 && (row-1)->ends_in_newline_from_string_p))))
15104 && (row->y > top_scroll_margin
15105 || CHARPOS (startp) == BEGV))
15106 {
15107 eassert (row->enabled_p);
15108 --row;
15109 }
15110
15111 /* Consider the following case: Window starts at BEGV,
15112 there is invisible, intangible text at BEGV, so that
15113 display starts at some point START > BEGV. It can
15114 happen that we are called with PT somewhere between
15115 BEGV and START. Try to handle that case. */
15116 if (row < w->current_matrix->rows
15117 || row->mode_line_p)
15118 {
15119 row = w->current_matrix->rows;
15120 if (row->mode_line_p)
15121 ++row;
15122 }
15123
15124 /* Due to newlines in overlay strings, we may have to
15125 skip forward over overlay strings. */
15126 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15127 && MATRIX_ROW_END_CHARPOS (row) == PT
15128 && !cursor_row_p (row))
15129 ++row;
15130
15131 /* If within the scroll margin, scroll. */
15132 if (row->y < top_scroll_margin
15133 && CHARPOS (startp) != BEGV)
15134 scroll_p = 1;
15135 }
15136 else
15137 {
15138 /* Cursor did not move. So don't scroll even if cursor line
15139 is partially visible, as it was so before. */
15140 rc = CURSOR_MOVEMENT_SUCCESS;
15141 }
15142
15143 if (PT < MATRIX_ROW_START_CHARPOS (row)
15144 || PT > MATRIX_ROW_END_CHARPOS (row))
15145 {
15146 /* if PT is not in the glyph row, give up. */
15147 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15148 must_scroll = 1;
15149 }
15150 else if (rc != CURSOR_MOVEMENT_SUCCESS
15151 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15152 {
15153 struct glyph_row *row1;
15154
15155 /* If rows are bidi-reordered and point moved, back up
15156 until we find a row that does not belong to a
15157 continuation line. This is because we must consider
15158 all rows of a continued line as candidates for the
15159 new cursor positioning, since row start and end
15160 positions change non-linearly with vertical position
15161 in such rows. */
15162 /* FIXME: Revisit this when glyph ``spilling'' in
15163 continuation lines' rows is implemented for
15164 bidi-reordered rows. */
15165 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15166 MATRIX_ROW_CONTINUATION_LINE_P (row);
15167 --row)
15168 {
15169 /* If we hit the beginning of the displayed portion
15170 without finding the first row of a continued
15171 line, give up. */
15172 if (row <= row1)
15173 {
15174 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15175 break;
15176 }
15177 eassert (row->enabled_p);
15178 }
15179 }
15180 if (must_scroll)
15181 ;
15182 else if (rc != CURSOR_MOVEMENT_SUCCESS
15183 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15184 /* Make sure this isn't a header line by any chance, since
15185 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15186 && !row->mode_line_p
15187 && make_cursor_line_fully_visible_p)
15188 {
15189 if (PT == MATRIX_ROW_END_CHARPOS (row)
15190 && !row->ends_at_zv_p
15191 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15192 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15193 else if (row->height > window_box_height (w))
15194 {
15195 /* If we end up in a partially visible line, let's
15196 make it fully visible, except when it's taller
15197 than the window, in which case we can't do much
15198 about it. */
15199 *scroll_step = 1;
15200 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15201 }
15202 else
15203 {
15204 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15205 if (!cursor_row_fully_visible_p (w, 0, 1))
15206 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15207 else
15208 rc = CURSOR_MOVEMENT_SUCCESS;
15209 }
15210 }
15211 else if (scroll_p)
15212 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15213 else if (rc != CURSOR_MOVEMENT_SUCCESS
15214 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15215 {
15216 /* With bidi-reordered rows, there could be more than
15217 one candidate row whose start and end positions
15218 occlude point. We need to let set_cursor_from_row
15219 find the best candidate. */
15220 /* FIXME: Revisit this when glyph ``spilling'' in
15221 continuation lines' rows is implemented for
15222 bidi-reordered rows. */
15223 int rv = 0;
15224
15225 do
15226 {
15227 int at_zv_p = 0, exact_match_p = 0;
15228
15229 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15230 && PT <= MATRIX_ROW_END_CHARPOS (row)
15231 && cursor_row_p (row))
15232 rv |= set_cursor_from_row (w, row, w->current_matrix,
15233 0, 0, 0, 0);
15234 /* As soon as we've found the exact match for point,
15235 or the first suitable row whose ends_at_zv_p flag
15236 is set, we are done. */
15237 at_zv_p =
15238 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15239 if (rv && !at_zv_p
15240 && w->cursor.hpos >= 0
15241 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15242 w->cursor.vpos))
15243 {
15244 struct glyph_row *candidate =
15245 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15246 struct glyph *g =
15247 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15248 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15249
15250 exact_match_p =
15251 (BUFFERP (g->object) && g->charpos == PT)
15252 || (INTEGERP (g->object)
15253 && (g->charpos == PT
15254 || (g->charpos == 0 && endpos - 1 == PT)));
15255 }
15256 if (rv && (at_zv_p || exact_match_p))
15257 {
15258 rc = CURSOR_MOVEMENT_SUCCESS;
15259 break;
15260 }
15261 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15262 break;
15263 ++row;
15264 }
15265 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15266 || row->continued_p)
15267 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15268 || (MATRIX_ROW_START_CHARPOS (row) == PT
15269 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15270 /* If we didn't find any candidate rows, or exited the
15271 loop before all the candidates were examined, signal
15272 to the caller that this method failed. */
15273 if (rc != CURSOR_MOVEMENT_SUCCESS
15274 && !(rv
15275 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15276 && !row->continued_p))
15277 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15278 else if (rv)
15279 rc = CURSOR_MOVEMENT_SUCCESS;
15280 }
15281 else
15282 {
15283 do
15284 {
15285 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15286 {
15287 rc = CURSOR_MOVEMENT_SUCCESS;
15288 break;
15289 }
15290 ++row;
15291 }
15292 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15293 && MATRIX_ROW_START_CHARPOS (row) == PT
15294 && cursor_row_p (row));
15295 }
15296 }
15297 }
15298
15299 return rc;
15300 }
15301
15302 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15303 static
15304 #endif
15305 void
15306 set_vertical_scroll_bar (struct window *w)
15307 {
15308 ptrdiff_t start, end, whole;
15309
15310 /* Calculate the start and end positions for the current window.
15311 At some point, it would be nice to choose between scrollbars
15312 which reflect the whole buffer size, with special markers
15313 indicating narrowing, and scrollbars which reflect only the
15314 visible region.
15315
15316 Note that mini-buffers sometimes aren't displaying any text. */
15317 if (!MINI_WINDOW_P (w)
15318 || (w == XWINDOW (minibuf_window)
15319 && NILP (echo_area_buffer[0])))
15320 {
15321 struct buffer *buf = XBUFFER (w->contents);
15322 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15323 start = marker_position (w->start) - BUF_BEGV (buf);
15324 /* I don't think this is guaranteed to be right. For the
15325 moment, we'll pretend it is. */
15326 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15327
15328 if (end < start)
15329 end = start;
15330 if (whole < (end - start))
15331 whole = end - start;
15332 }
15333 else
15334 start = end = whole = 0;
15335
15336 /* Indicate what this scroll bar ought to be displaying now. */
15337 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15338 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15339 (w, end - start, whole, start);
15340 }
15341
15342
15343 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15344 selected_window is redisplayed.
15345
15346 We can return without actually redisplaying the window if fonts has been
15347 changed on window's frame. In that case, redisplay_internal will retry. */
15348
15349 static void
15350 redisplay_window (Lisp_Object window, int just_this_one_p)
15351 {
15352 struct window *w = XWINDOW (window);
15353 struct frame *f = XFRAME (w->frame);
15354 struct buffer *buffer = XBUFFER (w->contents);
15355 struct buffer *old = current_buffer;
15356 struct text_pos lpoint, opoint, startp;
15357 int update_mode_line;
15358 int tem;
15359 struct it it;
15360 /* Record it now because it's overwritten. */
15361 int current_matrix_up_to_date_p = 0;
15362 int used_current_matrix_p = 0;
15363 /* This is less strict than current_matrix_up_to_date_p.
15364 It indicates that the buffer contents and narrowing are unchanged. */
15365 int buffer_unchanged_p = 0;
15366 int temp_scroll_step = 0;
15367 ptrdiff_t count = SPECPDL_INDEX ();
15368 int rc;
15369 int centering_position = -1;
15370 int last_line_misfit = 0;
15371 ptrdiff_t beg_unchanged, end_unchanged;
15372 int frame_line_height;
15373
15374 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15375 opoint = lpoint;
15376
15377 #ifdef GLYPH_DEBUG
15378 *w->desired_matrix->method = 0;
15379 #endif
15380
15381 /* Make sure that both W's markers are valid. */
15382 eassert (XMARKER (w->start)->buffer == buffer);
15383 eassert (XMARKER (w->pointm)->buffer == buffer);
15384
15385 restart:
15386 reconsider_clip_changes (w);
15387 frame_line_height = default_line_pixel_height (w);
15388
15389 /* Has the mode line to be updated? */
15390 update_mode_line = (w->update_mode_line
15391 || update_mode_lines
15392 || buffer->clip_changed
15393 || buffer->prevent_redisplay_optimizations_p);
15394
15395 if (MINI_WINDOW_P (w))
15396 {
15397 if (w == XWINDOW (echo_area_window)
15398 && !NILP (echo_area_buffer[0]))
15399 {
15400 if (update_mode_line)
15401 /* We may have to update a tty frame's menu bar or a
15402 tool-bar. Example `M-x C-h C-h C-g'. */
15403 goto finish_menu_bars;
15404 else
15405 /* We've already displayed the echo area glyphs in this window. */
15406 goto finish_scroll_bars;
15407 }
15408 else if ((w != XWINDOW (minibuf_window)
15409 || minibuf_level == 0)
15410 /* When buffer is nonempty, redisplay window normally. */
15411 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15412 /* Quail displays non-mini buffers in minibuffer window.
15413 In that case, redisplay the window normally. */
15414 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15415 {
15416 /* W is a mini-buffer window, but it's not active, so clear
15417 it. */
15418 int yb = window_text_bottom_y (w);
15419 struct glyph_row *row;
15420 int y;
15421
15422 for (y = 0, row = w->desired_matrix->rows;
15423 y < yb;
15424 y += row->height, ++row)
15425 blank_row (w, row, y);
15426 goto finish_scroll_bars;
15427 }
15428
15429 clear_glyph_matrix (w->desired_matrix);
15430 }
15431
15432 /* Otherwise set up data on this window; select its buffer and point
15433 value. */
15434 /* Really select the buffer, for the sake of buffer-local
15435 variables. */
15436 set_buffer_internal_1 (XBUFFER (w->contents));
15437
15438 current_matrix_up_to_date_p
15439 = (w->window_end_valid
15440 && !current_buffer->clip_changed
15441 && !current_buffer->prevent_redisplay_optimizations_p
15442 && !window_outdated (w));
15443
15444 /* Run the window-bottom-change-functions
15445 if it is possible that the text on the screen has changed
15446 (either due to modification of the text, or any other reason). */
15447 if (!current_matrix_up_to_date_p
15448 && !NILP (Vwindow_text_change_functions))
15449 {
15450 safe_run_hooks (Qwindow_text_change_functions);
15451 goto restart;
15452 }
15453
15454 beg_unchanged = BEG_UNCHANGED;
15455 end_unchanged = END_UNCHANGED;
15456
15457 SET_TEXT_POS (opoint, PT, PT_BYTE);
15458
15459 specbind (Qinhibit_point_motion_hooks, Qt);
15460
15461 buffer_unchanged_p
15462 = (w->window_end_valid
15463 && !current_buffer->clip_changed
15464 && !window_outdated (w));
15465
15466 /* When windows_or_buffers_changed is non-zero, we can't rely
15467 on the window end being valid, so set it to zero there. */
15468 if (windows_or_buffers_changed)
15469 {
15470 /* If window starts on a continuation line, maybe adjust the
15471 window start in case the window's width changed. */
15472 if (XMARKER (w->start)->buffer == current_buffer)
15473 compute_window_start_on_continuation_line (w);
15474
15475 w->window_end_valid = 0;
15476 /* If so, we also can't rely on current matrix
15477 and should not fool try_cursor_movement below. */
15478 current_matrix_up_to_date_p = 0;
15479 }
15480
15481 /* Some sanity checks. */
15482 CHECK_WINDOW_END (w);
15483 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15484 emacs_abort ();
15485 if (BYTEPOS (opoint) < CHARPOS (opoint))
15486 emacs_abort ();
15487
15488 if (mode_line_update_needed (w))
15489 update_mode_line = 1;
15490
15491 /* Point refers normally to the selected window. For any other
15492 window, set up appropriate value. */
15493 if (!EQ (window, selected_window))
15494 {
15495 ptrdiff_t new_pt = marker_position (w->pointm);
15496 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15497 if (new_pt < BEGV)
15498 {
15499 new_pt = BEGV;
15500 new_pt_byte = BEGV_BYTE;
15501 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15502 }
15503 else if (new_pt > (ZV - 1))
15504 {
15505 new_pt = ZV;
15506 new_pt_byte = ZV_BYTE;
15507 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15508 }
15509
15510 /* We don't use SET_PT so that the point-motion hooks don't run. */
15511 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15512 }
15513
15514 /* If any of the character widths specified in the display table
15515 have changed, invalidate the width run cache. It's true that
15516 this may be a bit late to catch such changes, but the rest of
15517 redisplay goes (non-fatally) haywire when the display table is
15518 changed, so why should we worry about doing any better? */
15519 if (current_buffer->width_run_cache)
15520 {
15521 struct Lisp_Char_Table *disptab = buffer_display_table ();
15522
15523 if (! disptab_matches_widthtab
15524 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15525 {
15526 invalidate_region_cache (current_buffer,
15527 current_buffer->width_run_cache,
15528 BEG, Z);
15529 recompute_width_table (current_buffer, disptab);
15530 }
15531 }
15532
15533 /* If window-start is screwed up, choose a new one. */
15534 if (XMARKER (w->start)->buffer != current_buffer)
15535 goto recenter;
15536
15537 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15538
15539 /* If someone specified a new starting point but did not insist,
15540 check whether it can be used. */
15541 if (w->optional_new_start
15542 && CHARPOS (startp) >= BEGV
15543 && CHARPOS (startp) <= ZV)
15544 {
15545 w->optional_new_start = 0;
15546 start_display (&it, w, startp);
15547 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15548 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15549 if (IT_CHARPOS (it) == PT)
15550 w->force_start = 1;
15551 /* IT may overshoot PT if text at PT is invisible. */
15552 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15553 w->force_start = 1;
15554 }
15555
15556 force_start:
15557
15558 /* Handle case where place to start displaying has been specified,
15559 unless the specified location is outside the accessible range. */
15560 if (w->force_start || window_frozen_p (w))
15561 {
15562 /* We set this later on if we have to adjust point. */
15563 int new_vpos = -1;
15564
15565 w->force_start = 0;
15566 w->vscroll = 0;
15567 w->window_end_valid = 0;
15568
15569 /* Forget any recorded base line for line number display. */
15570 if (!buffer_unchanged_p)
15571 w->base_line_number = 0;
15572
15573 /* Redisplay the mode line. Select the buffer properly for that.
15574 Also, run the hook window-scroll-functions
15575 because we have scrolled. */
15576 /* Note, we do this after clearing force_start because
15577 if there's an error, it is better to forget about force_start
15578 than to get into an infinite loop calling the hook functions
15579 and having them get more errors. */
15580 if (!update_mode_line
15581 || ! NILP (Vwindow_scroll_functions))
15582 {
15583 update_mode_line = 1;
15584 w->update_mode_line = 1;
15585 startp = run_window_scroll_functions (window, startp);
15586 }
15587
15588 if (CHARPOS (startp) < BEGV)
15589 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15590 else if (CHARPOS (startp) > ZV)
15591 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15592
15593 /* Redisplay, then check if cursor has been set during the
15594 redisplay. Give up if new fonts were loaded. */
15595 /* We used to issue a CHECK_MARGINS argument to try_window here,
15596 but this causes scrolling to fail when point begins inside
15597 the scroll margin (bug#148) -- cyd */
15598 if (!try_window (window, startp, 0))
15599 {
15600 w->force_start = 1;
15601 clear_glyph_matrix (w->desired_matrix);
15602 goto need_larger_matrices;
15603 }
15604
15605 if (w->cursor.vpos < 0 && !window_frozen_p (w))
15606 {
15607 /* If point does not appear, try to move point so it does
15608 appear. The desired matrix has been built above, so we
15609 can use it here. */
15610 new_vpos = window_box_height (w) / 2;
15611 }
15612
15613 if (!cursor_row_fully_visible_p (w, 0, 0))
15614 {
15615 /* Point does appear, but on a line partly visible at end of window.
15616 Move it back to a fully-visible line. */
15617 new_vpos = window_box_height (w);
15618 }
15619 else if (w->cursor.vpos >=0)
15620 {
15621 /* Some people insist on not letting point enter the scroll
15622 margin, even though this part handles windows that didn't
15623 scroll at all. */
15624 int window_total_lines
15625 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15626 int margin = min (scroll_margin, window_total_lines / 4);
15627 int pixel_margin = margin * frame_line_height;
15628 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15629
15630 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15631 below, which finds the row to move point to, advances by
15632 the Y coordinate of the _next_ row, see the definition of
15633 MATRIX_ROW_BOTTOM_Y. */
15634 if (w->cursor.vpos < margin + header_line)
15635 {
15636 w->cursor.vpos = -1;
15637 clear_glyph_matrix (w->desired_matrix);
15638 goto try_to_scroll;
15639 }
15640 else
15641 {
15642 int window_height = window_box_height (w);
15643
15644 if (header_line)
15645 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15646 if (w->cursor.y >= window_height - pixel_margin)
15647 {
15648 w->cursor.vpos = -1;
15649 clear_glyph_matrix (w->desired_matrix);
15650 goto try_to_scroll;
15651 }
15652 }
15653 }
15654
15655 /* If we need to move point for either of the above reasons,
15656 now actually do it. */
15657 if (new_vpos >= 0)
15658 {
15659 struct glyph_row *row;
15660
15661 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15662 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15663 ++row;
15664
15665 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15666 MATRIX_ROW_START_BYTEPOS (row));
15667
15668 if (w != XWINDOW (selected_window))
15669 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15670 else if (current_buffer == old)
15671 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15672
15673 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15674
15675 /* If we are highlighting the region, then we just changed
15676 the region, so redisplay to show it. */
15677 if (markpos_of_region () >= 0)
15678 {
15679 clear_glyph_matrix (w->desired_matrix);
15680 if (!try_window (window, startp, 0))
15681 goto need_larger_matrices;
15682 }
15683 }
15684
15685 #ifdef GLYPH_DEBUG
15686 debug_method_add (w, "forced window start");
15687 #endif
15688 goto done;
15689 }
15690
15691 /* Handle case where text has not changed, only point, and it has
15692 not moved off the frame, and we are not retrying after hscroll.
15693 (current_matrix_up_to_date_p is nonzero when retrying.) */
15694 if (current_matrix_up_to_date_p
15695 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15696 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15697 {
15698 switch (rc)
15699 {
15700 case CURSOR_MOVEMENT_SUCCESS:
15701 used_current_matrix_p = 1;
15702 goto done;
15703
15704 case CURSOR_MOVEMENT_MUST_SCROLL:
15705 goto try_to_scroll;
15706
15707 default:
15708 emacs_abort ();
15709 }
15710 }
15711 /* If current starting point was originally the beginning of a line
15712 but no longer is, find a new starting point. */
15713 else if (w->start_at_line_beg
15714 && !(CHARPOS (startp) <= BEGV
15715 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15716 {
15717 #ifdef GLYPH_DEBUG
15718 debug_method_add (w, "recenter 1");
15719 #endif
15720 goto recenter;
15721 }
15722
15723 /* Try scrolling with try_window_id. Value is > 0 if update has
15724 been done, it is -1 if we know that the same window start will
15725 not work. It is 0 if unsuccessful for some other reason. */
15726 else if ((tem = try_window_id (w)) != 0)
15727 {
15728 #ifdef GLYPH_DEBUG
15729 debug_method_add (w, "try_window_id %d", tem);
15730 #endif
15731
15732 if (f->fonts_changed)
15733 goto need_larger_matrices;
15734 if (tem > 0)
15735 goto done;
15736
15737 /* Otherwise try_window_id has returned -1 which means that we
15738 don't want the alternative below this comment to execute. */
15739 }
15740 else if (CHARPOS (startp) >= BEGV
15741 && CHARPOS (startp) <= ZV
15742 && PT >= CHARPOS (startp)
15743 && (CHARPOS (startp) < ZV
15744 /* Avoid starting at end of buffer. */
15745 || CHARPOS (startp) == BEGV
15746 || !window_outdated (w)))
15747 {
15748 int d1, d2, d3, d4, d5, d6;
15749
15750 /* If first window line is a continuation line, and window start
15751 is inside the modified region, but the first change is before
15752 current window start, we must select a new window start.
15753
15754 However, if this is the result of a down-mouse event (e.g. by
15755 extending the mouse-drag-overlay), we don't want to select a
15756 new window start, since that would change the position under
15757 the mouse, resulting in an unwanted mouse-movement rather
15758 than a simple mouse-click. */
15759 if (!w->start_at_line_beg
15760 && NILP (do_mouse_tracking)
15761 && CHARPOS (startp) > BEGV
15762 && CHARPOS (startp) > BEG + beg_unchanged
15763 && CHARPOS (startp) <= Z - end_unchanged
15764 /* Even if w->start_at_line_beg is nil, a new window may
15765 start at a line_beg, since that's how set_buffer_window
15766 sets it. So, we need to check the return value of
15767 compute_window_start_on_continuation_line. (See also
15768 bug#197). */
15769 && XMARKER (w->start)->buffer == current_buffer
15770 && compute_window_start_on_continuation_line (w)
15771 /* It doesn't make sense to force the window start like we
15772 do at label force_start if it is already known that point
15773 will not be visible in the resulting window, because
15774 doing so will move point from its correct position
15775 instead of scrolling the window to bring point into view.
15776 See bug#9324. */
15777 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15778 {
15779 w->force_start = 1;
15780 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15781 goto force_start;
15782 }
15783
15784 #ifdef GLYPH_DEBUG
15785 debug_method_add (w, "same window start");
15786 #endif
15787
15788 /* Try to redisplay starting at same place as before.
15789 If point has not moved off frame, accept the results. */
15790 if (!current_matrix_up_to_date_p
15791 /* Don't use try_window_reusing_current_matrix in this case
15792 because a window scroll function can have changed the
15793 buffer. */
15794 || !NILP (Vwindow_scroll_functions)
15795 || MINI_WINDOW_P (w)
15796 || !(used_current_matrix_p
15797 = try_window_reusing_current_matrix (w)))
15798 {
15799 IF_DEBUG (debug_method_add (w, "1"));
15800 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15801 /* -1 means we need to scroll.
15802 0 means we need new matrices, but fonts_changed
15803 is set in that case, so we will detect it below. */
15804 goto try_to_scroll;
15805 }
15806
15807 if (f->fonts_changed)
15808 goto need_larger_matrices;
15809
15810 if (w->cursor.vpos >= 0)
15811 {
15812 if (!just_this_one_p
15813 || current_buffer->clip_changed
15814 || BEG_UNCHANGED < CHARPOS (startp))
15815 /* Forget any recorded base line for line number display. */
15816 w->base_line_number = 0;
15817
15818 if (!cursor_row_fully_visible_p (w, 1, 0))
15819 {
15820 clear_glyph_matrix (w->desired_matrix);
15821 last_line_misfit = 1;
15822 }
15823 /* Drop through and scroll. */
15824 else
15825 goto done;
15826 }
15827 else
15828 clear_glyph_matrix (w->desired_matrix);
15829 }
15830
15831 try_to_scroll:
15832
15833 /* Redisplay the mode line. Select the buffer properly for that. */
15834 if (!update_mode_line)
15835 {
15836 update_mode_line = 1;
15837 w->update_mode_line = 1;
15838 }
15839
15840 /* Try to scroll by specified few lines. */
15841 if ((scroll_conservatively
15842 || emacs_scroll_step
15843 || temp_scroll_step
15844 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15845 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15846 && CHARPOS (startp) >= BEGV
15847 && CHARPOS (startp) <= ZV)
15848 {
15849 /* The function returns -1 if new fonts were loaded, 1 if
15850 successful, 0 if not successful. */
15851 int ss = try_scrolling (window, just_this_one_p,
15852 scroll_conservatively,
15853 emacs_scroll_step,
15854 temp_scroll_step, last_line_misfit);
15855 switch (ss)
15856 {
15857 case SCROLLING_SUCCESS:
15858 goto done;
15859
15860 case SCROLLING_NEED_LARGER_MATRICES:
15861 goto need_larger_matrices;
15862
15863 case SCROLLING_FAILED:
15864 break;
15865
15866 default:
15867 emacs_abort ();
15868 }
15869 }
15870
15871 /* Finally, just choose a place to start which positions point
15872 according to user preferences. */
15873
15874 recenter:
15875
15876 #ifdef GLYPH_DEBUG
15877 debug_method_add (w, "recenter");
15878 #endif
15879
15880 /* Forget any previously recorded base line for line number display. */
15881 if (!buffer_unchanged_p)
15882 w->base_line_number = 0;
15883
15884 /* Determine the window start relative to point. */
15885 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15886 it.current_y = it.last_visible_y;
15887 if (centering_position < 0)
15888 {
15889 int window_total_lines
15890 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15891 int margin =
15892 scroll_margin > 0
15893 ? min (scroll_margin, window_total_lines / 4)
15894 : 0;
15895 ptrdiff_t margin_pos = CHARPOS (startp);
15896 Lisp_Object aggressive;
15897 int scrolling_up;
15898
15899 /* If there is a scroll margin at the top of the window, find
15900 its character position. */
15901 if (margin
15902 /* Cannot call start_display if startp is not in the
15903 accessible region of the buffer. This can happen when we
15904 have just switched to a different buffer and/or changed
15905 its restriction. In that case, startp is initialized to
15906 the character position 1 (BEGV) because we did not yet
15907 have chance to display the buffer even once. */
15908 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15909 {
15910 struct it it1;
15911 void *it1data = NULL;
15912
15913 SAVE_IT (it1, it, it1data);
15914 start_display (&it1, w, startp);
15915 move_it_vertically (&it1, margin * frame_line_height);
15916 margin_pos = IT_CHARPOS (it1);
15917 RESTORE_IT (&it, &it, it1data);
15918 }
15919 scrolling_up = PT > margin_pos;
15920 aggressive =
15921 scrolling_up
15922 ? BVAR (current_buffer, scroll_up_aggressively)
15923 : BVAR (current_buffer, scroll_down_aggressively);
15924
15925 if (!MINI_WINDOW_P (w)
15926 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15927 {
15928 int pt_offset = 0;
15929
15930 /* Setting scroll-conservatively overrides
15931 scroll-*-aggressively. */
15932 if (!scroll_conservatively && NUMBERP (aggressive))
15933 {
15934 double float_amount = XFLOATINT (aggressive);
15935
15936 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15937 if (pt_offset == 0 && float_amount > 0)
15938 pt_offset = 1;
15939 if (pt_offset && margin > 0)
15940 margin -= 1;
15941 }
15942 /* Compute how much to move the window start backward from
15943 point so that point will be displayed where the user
15944 wants it. */
15945 if (scrolling_up)
15946 {
15947 centering_position = it.last_visible_y;
15948 if (pt_offset)
15949 centering_position -= pt_offset;
15950 centering_position -=
15951 frame_line_height * (1 + margin + (last_line_misfit != 0))
15952 + WINDOW_HEADER_LINE_HEIGHT (w);
15953 /* Don't let point enter the scroll margin near top of
15954 the window. */
15955 if (centering_position < margin * frame_line_height)
15956 centering_position = margin * frame_line_height;
15957 }
15958 else
15959 centering_position = margin * frame_line_height + pt_offset;
15960 }
15961 else
15962 /* Set the window start half the height of the window backward
15963 from point. */
15964 centering_position = window_box_height (w) / 2;
15965 }
15966 move_it_vertically_backward (&it, centering_position);
15967
15968 eassert (IT_CHARPOS (it) >= BEGV);
15969
15970 /* The function move_it_vertically_backward may move over more
15971 than the specified y-distance. If it->w is small, e.g. a
15972 mini-buffer window, we may end up in front of the window's
15973 display area. Start displaying at the start of the line
15974 containing PT in this case. */
15975 if (it.current_y <= 0)
15976 {
15977 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15978 move_it_vertically_backward (&it, 0);
15979 it.current_y = 0;
15980 }
15981
15982 it.current_x = it.hpos = 0;
15983
15984 /* Set the window start position here explicitly, to avoid an
15985 infinite loop in case the functions in window-scroll-functions
15986 get errors. */
15987 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15988
15989 /* Run scroll hooks. */
15990 startp = run_window_scroll_functions (window, it.current.pos);
15991
15992 /* Redisplay the window. */
15993 if (!current_matrix_up_to_date_p
15994 || windows_or_buffers_changed
15995 || f->cursor_type_changed
15996 /* Don't use try_window_reusing_current_matrix in this case
15997 because it can have changed the buffer. */
15998 || !NILP (Vwindow_scroll_functions)
15999 || !just_this_one_p
16000 || MINI_WINDOW_P (w)
16001 || !(used_current_matrix_p
16002 = try_window_reusing_current_matrix (w)))
16003 try_window (window, startp, 0);
16004
16005 /* If new fonts have been loaded (due to fontsets), give up. We
16006 have to start a new redisplay since we need to re-adjust glyph
16007 matrices. */
16008 if (f->fonts_changed)
16009 goto need_larger_matrices;
16010
16011 /* If cursor did not appear assume that the middle of the window is
16012 in the first line of the window. Do it again with the next line.
16013 (Imagine a window of height 100, displaying two lines of height
16014 60. Moving back 50 from it->last_visible_y will end in the first
16015 line.) */
16016 if (w->cursor.vpos < 0)
16017 {
16018 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16019 {
16020 clear_glyph_matrix (w->desired_matrix);
16021 move_it_by_lines (&it, 1);
16022 try_window (window, it.current.pos, 0);
16023 }
16024 else if (PT < IT_CHARPOS (it))
16025 {
16026 clear_glyph_matrix (w->desired_matrix);
16027 move_it_by_lines (&it, -1);
16028 try_window (window, it.current.pos, 0);
16029 }
16030 else
16031 {
16032 /* Not much we can do about it. */
16033 }
16034 }
16035
16036 /* Consider the following case: Window starts at BEGV, there is
16037 invisible, intangible text at BEGV, so that display starts at
16038 some point START > BEGV. It can happen that we are called with
16039 PT somewhere between BEGV and START. Try to handle that case. */
16040 if (w->cursor.vpos < 0)
16041 {
16042 struct glyph_row *row = w->current_matrix->rows;
16043 if (row->mode_line_p)
16044 ++row;
16045 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16046 }
16047
16048 if (!cursor_row_fully_visible_p (w, 0, 0))
16049 {
16050 /* If vscroll is enabled, disable it and try again. */
16051 if (w->vscroll)
16052 {
16053 w->vscroll = 0;
16054 clear_glyph_matrix (w->desired_matrix);
16055 goto recenter;
16056 }
16057
16058 /* Users who set scroll-conservatively to a large number want
16059 point just above/below the scroll margin. If we ended up
16060 with point's row partially visible, move the window start to
16061 make that row fully visible and out of the margin. */
16062 if (scroll_conservatively > SCROLL_LIMIT)
16063 {
16064 int window_total_lines
16065 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16066 int margin =
16067 scroll_margin > 0
16068 ? min (scroll_margin, window_total_lines / 4)
16069 : 0;
16070 int move_down = w->cursor.vpos >= window_total_lines / 2;
16071
16072 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16073 clear_glyph_matrix (w->desired_matrix);
16074 if (1 == try_window (window, it.current.pos,
16075 TRY_WINDOW_CHECK_MARGINS))
16076 goto done;
16077 }
16078
16079 /* If centering point failed to make the whole line visible,
16080 put point at the top instead. That has to make the whole line
16081 visible, if it can be done. */
16082 if (centering_position == 0)
16083 goto done;
16084
16085 clear_glyph_matrix (w->desired_matrix);
16086 centering_position = 0;
16087 goto recenter;
16088 }
16089
16090 done:
16091
16092 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16093 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16094 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16095
16096 /* Display the mode line, if we must. */
16097 if ((update_mode_line
16098 /* If window not full width, must redo its mode line
16099 if (a) the window to its side is being redone and
16100 (b) we do a frame-based redisplay. This is a consequence
16101 of how inverted lines are drawn in frame-based redisplay. */
16102 || (!just_this_one_p
16103 && !FRAME_WINDOW_P (f)
16104 && !WINDOW_FULL_WIDTH_P (w))
16105 /* Line number to display. */
16106 || w->base_line_pos > 0
16107 /* Column number is displayed and different from the one displayed. */
16108 || (w->column_number_displayed != -1
16109 && (w->column_number_displayed != current_column ())))
16110 /* This means that the window has a mode line. */
16111 && (WINDOW_WANTS_MODELINE_P (w)
16112 || WINDOW_WANTS_HEADER_LINE_P (w)))
16113 {
16114 display_mode_lines (w);
16115
16116 /* If mode line height has changed, arrange for a thorough
16117 immediate redisplay using the correct mode line height. */
16118 if (WINDOW_WANTS_MODELINE_P (w)
16119 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16120 {
16121 f->fonts_changed = 1;
16122 w->mode_line_height = -1;
16123 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16124 = DESIRED_MODE_LINE_HEIGHT (w);
16125 }
16126
16127 /* If header line height has changed, arrange for a thorough
16128 immediate redisplay using the correct header line height. */
16129 if (WINDOW_WANTS_HEADER_LINE_P (w)
16130 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16131 {
16132 f->fonts_changed = 1;
16133 w->header_line_height = -1;
16134 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16135 = DESIRED_HEADER_LINE_HEIGHT (w);
16136 }
16137
16138 if (f->fonts_changed)
16139 goto need_larger_matrices;
16140 }
16141
16142 if (!line_number_displayed && w->base_line_pos != -1)
16143 {
16144 w->base_line_pos = 0;
16145 w->base_line_number = 0;
16146 }
16147
16148 finish_menu_bars:
16149
16150 /* When we reach a frame's selected window, redo the frame's menu bar. */
16151 if (update_mode_line
16152 && EQ (FRAME_SELECTED_WINDOW (f), window))
16153 {
16154 int redisplay_menu_p = 0;
16155
16156 if (FRAME_WINDOW_P (f))
16157 {
16158 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16159 || defined (HAVE_NS) || defined (USE_GTK)
16160 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16161 #else
16162 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16163 #endif
16164 }
16165 else
16166 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16167
16168 if (redisplay_menu_p)
16169 display_menu_bar (w);
16170
16171 #ifdef HAVE_WINDOW_SYSTEM
16172 if (FRAME_WINDOW_P (f))
16173 {
16174 #if defined (USE_GTK) || defined (HAVE_NS)
16175 if (FRAME_EXTERNAL_TOOL_BAR (f))
16176 redisplay_tool_bar (f);
16177 #else
16178 if (WINDOWP (f->tool_bar_window)
16179 && (FRAME_TOOL_BAR_LINES (f) > 0
16180 || !NILP (Vauto_resize_tool_bars))
16181 && redisplay_tool_bar (f))
16182 ignore_mouse_drag_p = 1;
16183 #endif
16184 }
16185 #endif
16186 }
16187
16188 #ifdef HAVE_WINDOW_SYSTEM
16189 if (FRAME_WINDOW_P (f)
16190 && update_window_fringes (w, (just_this_one_p
16191 || (!used_current_matrix_p && !overlay_arrow_seen)
16192 || w->pseudo_window_p)))
16193 {
16194 update_begin (f);
16195 block_input ();
16196 if (draw_window_fringes (w, 1))
16197 x_draw_vertical_border (w);
16198 unblock_input ();
16199 update_end (f);
16200 }
16201 #endif /* HAVE_WINDOW_SYSTEM */
16202
16203 /* We go to this label, with fonts_changed set, if it is
16204 necessary to try again using larger glyph matrices.
16205 We have to redeem the scroll bar even in this case,
16206 because the loop in redisplay_internal expects that. */
16207 need_larger_matrices:
16208 ;
16209 finish_scroll_bars:
16210
16211 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16212 {
16213 /* Set the thumb's position and size. */
16214 set_vertical_scroll_bar (w);
16215
16216 /* Note that we actually used the scroll bar attached to this
16217 window, so it shouldn't be deleted at the end of redisplay. */
16218 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16219 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16220 }
16221
16222 /* Restore current_buffer and value of point in it. The window
16223 update may have changed the buffer, so first make sure `opoint'
16224 is still valid (Bug#6177). */
16225 if (CHARPOS (opoint) < BEGV)
16226 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16227 else if (CHARPOS (opoint) > ZV)
16228 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16229 else
16230 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16231
16232 set_buffer_internal_1 (old);
16233 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16234 shorter. This can be caused by log truncation in *Messages*. */
16235 if (CHARPOS (lpoint) <= ZV)
16236 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16237
16238 unbind_to (count, Qnil);
16239 }
16240
16241
16242 /* Build the complete desired matrix of WINDOW with a window start
16243 buffer position POS.
16244
16245 Value is 1 if successful. It is zero if fonts were loaded during
16246 redisplay which makes re-adjusting glyph matrices necessary, and -1
16247 if point would appear in the scroll margins.
16248 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16249 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16250 set in FLAGS.) */
16251
16252 int
16253 try_window (Lisp_Object window, struct text_pos pos, int flags)
16254 {
16255 struct window *w = XWINDOW (window);
16256 struct it it;
16257 struct glyph_row *last_text_row = NULL;
16258 struct frame *f = XFRAME (w->frame);
16259 int frame_line_height = default_line_pixel_height (w);
16260
16261 /* Make POS the new window start. */
16262 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16263
16264 /* Mark cursor position as unknown. No overlay arrow seen. */
16265 w->cursor.vpos = -1;
16266 overlay_arrow_seen = 0;
16267
16268 /* Initialize iterator and info to start at POS. */
16269 start_display (&it, w, pos);
16270
16271 /* Display all lines of W. */
16272 while (it.current_y < it.last_visible_y)
16273 {
16274 if (display_line (&it))
16275 last_text_row = it.glyph_row - 1;
16276 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16277 return 0;
16278 }
16279
16280 /* Don't let the cursor end in the scroll margins. */
16281 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16282 && !MINI_WINDOW_P (w))
16283 {
16284 int this_scroll_margin;
16285 int window_total_lines
16286 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16287
16288 if (scroll_margin > 0)
16289 {
16290 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16291 this_scroll_margin *= frame_line_height;
16292 }
16293 else
16294 this_scroll_margin = 0;
16295
16296 if ((w->cursor.y >= 0 /* not vscrolled */
16297 && w->cursor.y < this_scroll_margin
16298 && CHARPOS (pos) > BEGV
16299 && IT_CHARPOS (it) < ZV)
16300 /* rms: considering make_cursor_line_fully_visible_p here
16301 seems to give wrong results. We don't want to recenter
16302 when the last line is partly visible, we want to allow
16303 that case to be handled in the usual way. */
16304 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16305 {
16306 w->cursor.vpos = -1;
16307 clear_glyph_matrix (w->desired_matrix);
16308 return -1;
16309 }
16310 }
16311
16312 /* If bottom moved off end of frame, change mode line percentage. */
16313 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
16314 w->update_mode_line = 1;
16315
16316 /* Set window_end_pos to the offset of the last character displayed
16317 on the window from the end of current_buffer. Set
16318 window_end_vpos to its row number. */
16319 if (last_text_row)
16320 {
16321 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16322 adjust_window_ends (w, last_text_row, 0);
16323 eassert
16324 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16325 w->window_end_vpos)));
16326 }
16327 else
16328 {
16329 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16330 w->window_end_pos = Z - ZV;
16331 w->window_end_vpos = 0;
16332 }
16333
16334 /* But that is not valid info until redisplay finishes. */
16335 w->window_end_valid = 0;
16336 return 1;
16337 }
16338
16339
16340 \f
16341 /************************************************************************
16342 Window redisplay reusing current matrix when buffer has not changed
16343 ************************************************************************/
16344
16345 /* Try redisplay of window W showing an unchanged buffer with a
16346 different window start than the last time it was displayed by
16347 reusing its current matrix. Value is non-zero if successful.
16348 W->start is the new window start. */
16349
16350 static int
16351 try_window_reusing_current_matrix (struct window *w)
16352 {
16353 struct frame *f = XFRAME (w->frame);
16354 struct glyph_row *bottom_row;
16355 struct it it;
16356 struct run run;
16357 struct text_pos start, new_start;
16358 int nrows_scrolled, i;
16359 struct glyph_row *last_text_row;
16360 struct glyph_row *last_reused_text_row;
16361 struct glyph_row *start_row;
16362 int start_vpos, min_y, max_y;
16363
16364 #ifdef GLYPH_DEBUG
16365 if (inhibit_try_window_reusing)
16366 return 0;
16367 #endif
16368
16369 if (/* This function doesn't handle terminal frames. */
16370 !FRAME_WINDOW_P (f)
16371 /* Don't try to reuse the display if windows have been split
16372 or such. */
16373 || windows_or_buffers_changed
16374 || f->cursor_type_changed)
16375 return 0;
16376
16377 /* Can't do this if region may have changed. */
16378 if (markpos_of_region () >= 0
16379 || w->region_showing
16380 || !NILP (Vshow_trailing_whitespace))
16381 return 0;
16382
16383 /* If top-line visibility has changed, give up. */
16384 if (WINDOW_WANTS_HEADER_LINE_P (w)
16385 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16386 return 0;
16387
16388 /* Give up if old or new display is scrolled vertically. We could
16389 make this function handle this, but right now it doesn't. */
16390 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16391 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16392 return 0;
16393
16394 /* The variable new_start now holds the new window start. The old
16395 start `start' can be determined from the current matrix. */
16396 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16397 start = start_row->minpos;
16398 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16399
16400 /* Clear the desired matrix for the display below. */
16401 clear_glyph_matrix (w->desired_matrix);
16402
16403 if (CHARPOS (new_start) <= CHARPOS (start))
16404 {
16405 /* Don't use this method if the display starts with an ellipsis
16406 displayed for invisible text. It's not easy to handle that case
16407 below, and it's certainly not worth the effort since this is
16408 not a frequent case. */
16409 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16410 return 0;
16411
16412 IF_DEBUG (debug_method_add (w, "twu1"));
16413
16414 /* Display up to a row that can be reused. The variable
16415 last_text_row is set to the last row displayed that displays
16416 text. Note that it.vpos == 0 if or if not there is a
16417 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16418 start_display (&it, w, new_start);
16419 w->cursor.vpos = -1;
16420 last_text_row = last_reused_text_row = NULL;
16421
16422 while (it.current_y < it.last_visible_y && !f->fonts_changed)
16423 {
16424 /* If we have reached into the characters in the START row,
16425 that means the line boundaries have changed. So we
16426 can't start copying with the row START. Maybe it will
16427 work to start copying with the following row. */
16428 while (IT_CHARPOS (it) > CHARPOS (start))
16429 {
16430 /* Advance to the next row as the "start". */
16431 start_row++;
16432 start = start_row->minpos;
16433 /* If there are no more rows to try, or just one, give up. */
16434 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16435 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16436 || CHARPOS (start) == ZV)
16437 {
16438 clear_glyph_matrix (w->desired_matrix);
16439 return 0;
16440 }
16441
16442 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16443 }
16444 /* If we have reached alignment, we can copy the rest of the
16445 rows. */
16446 if (IT_CHARPOS (it) == CHARPOS (start)
16447 /* Don't accept "alignment" inside a display vector,
16448 since start_row could have started in the middle of
16449 that same display vector (thus their character
16450 positions match), and we have no way of telling if
16451 that is the case. */
16452 && it.current.dpvec_index < 0)
16453 break;
16454
16455 if (display_line (&it))
16456 last_text_row = it.glyph_row - 1;
16457
16458 }
16459
16460 /* A value of current_y < last_visible_y means that we stopped
16461 at the previous window start, which in turn means that we
16462 have at least one reusable row. */
16463 if (it.current_y < it.last_visible_y)
16464 {
16465 struct glyph_row *row;
16466
16467 /* IT.vpos always starts from 0; it counts text lines. */
16468 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16469
16470 /* Find PT if not already found in the lines displayed. */
16471 if (w->cursor.vpos < 0)
16472 {
16473 int dy = it.current_y - start_row->y;
16474
16475 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16476 row = row_containing_pos (w, PT, row, NULL, dy);
16477 if (row)
16478 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16479 dy, nrows_scrolled);
16480 else
16481 {
16482 clear_glyph_matrix (w->desired_matrix);
16483 return 0;
16484 }
16485 }
16486
16487 /* Scroll the display. Do it before the current matrix is
16488 changed. The problem here is that update has not yet
16489 run, i.e. part of the current matrix is not up to date.
16490 scroll_run_hook will clear the cursor, and use the
16491 current matrix to get the height of the row the cursor is
16492 in. */
16493 run.current_y = start_row->y;
16494 run.desired_y = it.current_y;
16495 run.height = it.last_visible_y - it.current_y;
16496
16497 if (run.height > 0 && run.current_y != run.desired_y)
16498 {
16499 update_begin (f);
16500 FRAME_RIF (f)->update_window_begin_hook (w);
16501 FRAME_RIF (f)->clear_window_mouse_face (w);
16502 FRAME_RIF (f)->scroll_run_hook (w, &run);
16503 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16504 update_end (f);
16505 }
16506
16507 /* Shift current matrix down by nrows_scrolled lines. */
16508 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16509 rotate_matrix (w->current_matrix,
16510 start_vpos,
16511 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16512 nrows_scrolled);
16513
16514 /* Disable lines that must be updated. */
16515 for (i = 0; i < nrows_scrolled; ++i)
16516 (start_row + i)->enabled_p = 0;
16517
16518 /* Re-compute Y positions. */
16519 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16520 max_y = it.last_visible_y;
16521 for (row = start_row + nrows_scrolled;
16522 row < bottom_row;
16523 ++row)
16524 {
16525 row->y = it.current_y;
16526 row->visible_height = row->height;
16527
16528 if (row->y < min_y)
16529 row->visible_height -= min_y - row->y;
16530 if (row->y + row->height > max_y)
16531 row->visible_height -= row->y + row->height - max_y;
16532 if (row->fringe_bitmap_periodic_p)
16533 row->redraw_fringe_bitmaps_p = 1;
16534
16535 it.current_y += row->height;
16536
16537 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16538 last_reused_text_row = row;
16539 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16540 break;
16541 }
16542
16543 /* Disable lines in the current matrix which are now
16544 below the window. */
16545 for (++row; row < bottom_row; ++row)
16546 row->enabled_p = row->mode_line_p = 0;
16547 }
16548
16549 /* Update window_end_pos etc.; last_reused_text_row is the last
16550 reused row from the current matrix containing text, if any.
16551 The value of last_text_row is the last displayed line
16552 containing text. */
16553 if (last_reused_text_row)
16554 adjust_window_ends (w, last_reused_text_row, 1);
16555 else if (last_text_row)
16556 adjust_window_ends (w, last_text_row, 0);
16557 else
16558 {
16559 /* This window must be completely empty. */
16560 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16561 w->window_end_pos = Z - ZV;
16562 w->window_end_vpos = 0;
16563 }
16564 w->window_end_valid = 0;
16565
16566 /* Update hint: don't try scrolling again in update_window. */
16567 w->desired_matrix->no_scrolling_p = 1;
16568
16569 #ifdef GLYPH_DEBUG
16570 debug_method_add (w, "try_window_reusing_current_matrix 1");
16571 #endif
16572 return 1;
16573 }
16574 else if (CHARPOS (new_start) > CHARPOS (start))
16575 {
16576 struct glyph_row *pt_row, *row;
16577 struct glyph_row *first_reusable_row;
16578 struct glyph_row *first_row_to_display;
16579 int dy;
16580 int yb = window_text_bottom_y (w);
16581
16582 /* Find the row starting at new_start, if there is one. Don't
16583 reuse a partially visible line at the end. */
16584 first_reusable_row = start_row;
16585 while (first_reusable_row->enabled_p
16586 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16587 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16588 < CHARPOS (new_start)))
16589 ++first_reusable_row;
16590
16591 /* Give up if there is no row to reuse. */
16592 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16593 || !first_reusable_row->enabled_p
16594 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16595 != CHARPOS (new_start)))
16596 return 0;
16597
16598 /* We can reuse fully visible rows beginning with
16599 first_reusable_row to the end of the window. Set
16600 first_row_to_display to the first row that cannot be reused.
16601 Set pt_row to the row containing point, if there is any. */
16602 pt_row = NULL;
16603 for (first_row_to_display = first_reusable_row;
16604 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16605 ++first_row_to_display)
16606 {
16607 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16608 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16609 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16610 && first_row_to_display->ends_at_zv_p
16611 && pt_row == NULL)))
16612 pt_row = first_row_to_display;
16613 }
16614
16615 /* Start displaying at the start of first_row_to_display. */
16616 eassert (first_row_to_display->y < yb);
16617 init_to_row_start (&it, w, first_row_to_display);
16618
16619 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16620 - start_vpos);
16621 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16622 - nrows_scrolled);
16623 it.current_y = (first_row_to_display->y - first_reusable_row->y
16624 + WINDOW_HEADER_LINE_HEIGHT (w));
16625
16626 /* Display lines beginning with first_row_to_display in the
16627 desired matrix. Set last_text_row to the last row displayed
16628 that displays text. */
16629 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16630 if (pt_row == NULL)
16631 w->cursor.vpos = -1;
16632 last_text_row = NULL;
16633 while (it.current_y < it.last_visible_y && !f->fonts_changed)
16634 if (display_line (&it))
16635 last_text_row = it.glyph_row - 1;
16636
16637 /* If point is in a reused row, adjust y and vpos of the cursor
16638 position. */
16639 if (pt_row)
16640 {
16641 w->cursor.vpos -= nrows_scrolled;
16642 w->cursor.y -= first_reusable_row->y - start_row->y;
16643 }
16644
16645 /* Give up if point isn't in a row displayed or reused. (This
16646 also handles the case where w->cursor.vpos < nrows_scrolled
16647 after the calls to display_line, which can happen with scroll
16648 margins. See bug#1295.) */
16649 if (w->cursor.vpos < 0)
16650 {
16651 clear_glyph_matrix (w->desired_matrix);
16652 return 0;
16653 }
16654
16655 /* Scroll the display. */
16656 run.current_y = first_reusable_row->y;
16657 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16658 run.height = it.last_visible_y - run.current_y;
16659 dy = run.current_y - run.desired_y;
16660
16661 if (run.height)
16662 {
16663 update_begin (f);
16664 FRAME_RIF (f)->update_window_begin_hook (w);
16665 FRAME_RIF (f)->clear_window_mouse_face (w);
16666 FRAME_RIF (f)->scroll_run_hook (w, &run);
16667 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16668 update_end (f);
16669 }
16670
16671 /* Adjust Y positions of reused rows. */
16672 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16673 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16674 max_y = it.last_visible_y;
16675 for (row = first_reusable_row; row < first_row_to_display; ++row)
16676 {
16677 row->y -= dy;
16678 row->visible_height = row->height;
16679 if (row->y < min_y)
16680 row->visible_height -= min_y - row->y;
16681 if (row->y + row->height > max_y)
16682 row->visible_height -= row->y + row->height - max_y;
16683 if (row->fringe_bitmap_periodic_p)
16684 row->redraw_fringe_bitmaps_p = 1;
16685 }
16686
16687 /* Scroll the current matrix. */
16688 eassert (nrows_scrolled > 0);
16689 rotate_matrix (w->current_matrix,
16690 start_vpos,
16691 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16692 -nrows_scrolled);
16693
16694 /* Disable rows not reused. */
16695 for (row -= nrows_scrolled; row < bottom_row; ++row)
16696 row->enabled_p = 0;
16697
16698 /* Point may have moved to a different line, so we cannot assume that
16699 the previous cursor position is valid; locate the correct row. */
16700 if (pt_row)
16701 {
16702 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16703 row < bottom_row
16704 && PT >= MATRIX_ROW_END_CHARPOS (row)
16705 && !row->ends_at_zv_p;
16706 row++)
16707 {
16708 w->cursor.vpos++;
16709 w->cursor.y = row->y;
16710 }
16711 if (row < bottom_row)
16712 {
16713 /* Can't simply scan the row for point with
16714 bidi-reordered glyph rows. Let set_cursor_from_row
16715 figure out where to put the cursor, and if it fails,
16716 give up. */
16717 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16718 {
16719 if (!set_cursor_from_row (w, row, w->current_matrix,
16720 0, 0, 0, 0))
16721 {
16722 clear_glyph_matrix (w->desired_matrix);
16723 return 0;
16724 }
16725 }
16726 else
16727 {
16728 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16729 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16730
16731 for (; glyph < end
16732 && (!BUFFERP (glyph->object)
16733 || glyph->charpos < PT);
16734 glyph++)
16735 {
16736 w->cursor.hpos++;
16737 w->cursor.x += glyph->pixel_width;
16738 }
16739 }
16740 }
16741 }
16742
16743 /* Adjust window end. A null value of last_text_row means that
16744 the window end is in reused rows which in turn means that
16745 only its vpos can have changed. */
16746 if (last_text_row)
16747 adjust_window_ends (w, last_text_row, 0);
16748 else
16749 w->window_end_vpos -= nrows_scrolled;
16750
16751 w->window_end_valid = 0;
16752 w->desired_matrix->no_scrolling_p = 1;
16753
16754 #ifdef GLYPH_DEBUG
16755 debug_method_add (w, "try_window_reusing_current_matrix 2");
16756 #endif
16757 return 1;
16758 }
16759
16760 return 0;
16761 }
16762
16763
16764 \f
16765 /************************************************************************
16766 Window redisplay reusing current matrix when buffer has changed
16767 ************************************************************************/
16768
16769 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16770 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16771 ptrdiff_t *, ptrdiff_t *);
16772 static struct glyph_row *
16773 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16774 struct glyph_row *);
16775
16776
16777 /* Return the last row in MATRIX displaying text. If row START is
16778 non-null, start searching with that row. IT gives the dimensions
16779 of the display. Value is null if matrix is empty; otherwise it is
16780 a pointer to the row found. */
16781
16782 static struct glyph_row *
16783 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16784 struct glyph_row *start)
16785 {
16786 struct glyph_row *row, *row_found;
16787
16788 /* Set row_found to the last row in IT->w's current matrix
16789 displaying text. The loop looks funny but think of partially
16790 visible lines. */
16791 row_found = NULL;
16792 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16793 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16794 {
16795 eassert (row->enabled_p);
16796 row_found = row;
16797 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16798 break;
16799 ++row;
16800 }
16801
16802 return row_found;
16803 }
16804
16805
16806 /* Return the last row in the current matrix of W that is not affected
16807 by changes at the start of current_buffer that occurred since W's
16808 current matrix was built. Value is null if no such row exists.
16809
16810 BEG_UNCHANGED us the number of characters unchanged at the start of
16811 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16812 first changed character in current_buffer. Characters at positions <
16813 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16814 when the current matrix was built. */
16815
16816 static struct glyph_row *
16817 find_last_unchanged_at_beg_row (struct window *w)
16818 {
16819 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16820 struct glyph_row *row;
16821 struct glyph_row *row_found = NULL;
16822 int yb = window_text_bottom_y (w);
16823
16824 /* Find the last row displaying unchanged text. */
16825 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16826 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16827 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16828 ++row)
16829 {
16830 if (/* If row ends before first_changed_pos, it is unchanged,
16831 except in some case. */
16832 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16833 /* When row ends in ZV and we write at ZV it is not
16834 unchanged. */
16835 && !row->ends_at_zv_p
16836 /* When first_changed_pos is the end of a continued line,
16837 row is not unchanged because it may be no longer
16838 continued. */
16839 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16840 && (row->continued_p
16841 || row->exact_window_width_line_p))
16842 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16843 needs to be recomputed, so don't consider this row as
16844 unchanged. This happens when the last line was
16845 bidi-reordered and was killed immediately before this
16846 redisplay cycle. In that case, ROW->end stores the
16847 buffer position of the first visual-order character of
16848 the killed text, which is now beyond ZV. */
16849 && CHARPOS (row->end.pos) <= ZV)
16850 row_found = row;
16851
16852 /* Stop if last visible row. */
16853 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16854 break;
16855 }
16856
16857 return row_found;
16858 }
16859
16860
16861 /* Find the first glyph row in the current matrix of W that is not
16862 affected by changes at the end of current_buffer since the
16863 time W's current matrix was built.
16864
16865 Return in *DELTA the number of chars by which buffer positions in
16866 unchanged text at the end of current_buffer must be adjusted.
16867
16868 Return in *DELTA_BYTES the corresponding number of bytes.
16869
16870 Value is null if no such row exists, i.e. all rows are affected by
16871 changes. */
16872
16873 static struct glyph_row *
16874 find_first_unchanged_at_end_row (struct window *w,
16875 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16876 {
16877 struct glyph_row *row;
16878 struct glyph_row *row_found = NULL;
16879
16880 *delta = *delta_bytes = 0;
16881
16882 /* Display must not have been paused, otherwise the current matrix
16883 is not up to date. */
16884 eassert (w->window_end_valid);
16885
16886 /* A value of window_end_pos >= END_UNCHANGED means that the window
16887 end is in the range of changed text. If so, there is no
16888 unchanged row at the end of W's current matrix. */
16889 if (w->window_end_pos >= END_UNCHANGED)
16890 return NULL;
16891
16892 /* Set row to the last row in W's current matrix displaying text. */
16893 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
16894
16895 /* If matrix is entirely empty, no unchanged row exists. */
16896 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16897 {
16898 /* The value of row is the last glyph row in the matrix having a
16899 meaningful buffer position in it. The end position of row
16900 corresponds to window_end_pos. This allows us to translate
16901 buffer positions in the current matrix to current buffer
16902 positions for characters not in changed text. */
16903 ptrdiff_t Z_old =
16904 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
16905 ptrdiff_t Z_BYTE_old =
16906 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16907 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16908 struct glyph_row *first_text_row
16909 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16910
16911 *delta = Z - Z_old;
16912 *delta_bytes = Z_BYTE - Z_BYTE_old;
16913
16914 /* Set last_unchanged_pos to the buffer position of the last
16915 character in the buffer that has not been changed. Z is the
16916 index + 1 of the last character in current_buffer, i.e. by
16917 subtracting END_UNCHANGED we get the index of the last
16918 unchanged character, and we have to add BEG to get its buffer
16919 position. */
16920 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16921 last_unchanged_pos_old = last_unchanged_pos - *delta;
16922
16923 /* Search backward from ROW for a row displaying a line that
16924 starts at a minimum position >= last_unchanged_pos_old. */
16925 for (; row > first_text_row; --row)
16926 {
16927 /* This used to abort, but it can happen.
16928 It is ok to just stop the search instead here. KFS. */
16929 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16930 break;
16931
16932 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16933 row_found = row;
16934 }
16935 }
16936
16937 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16938
16939 return row_found;
16940 }
16941
16942
16943 /* Make sure that glyph rows in the current matrix of window W
16944 reference the same glyph memory as corresponding rows in the
16945 frame's frame matrix. This function is called after scrolling W's
16946 current matrix on a terminal frame in try_window_id and
16947 try_window_reusing_current_matrix. */
16948
16949 static void
16950 sync_frame_with_window_matrix_rows (struct window *w)
16951 {
16952 struct frame *f = XFRAME (w->frame);
16953 struct glyph_row *window_row, *window_row_end, *frame_row;
16954
16955 /* Preconditions: W must be a leaf window and full-width. Its frame
16956 must have a frame matrix. */
16957 eassert (BUFFERP (w->contents));
16958 eassert (WINDOW_FULL_WIDTH_P (w));
16959 eassert (!FRAME_WINDOW_P (f));
16960
16961 /* If W is a full-width window, glyph pointers in W's current matrix
16962 have, by definition, to be the same as glyph pointers in the
16963 corresponding frame matrix. Note that frame matrices have no
16964 marginal areas (see build_frame_matrix). */
16965 window_row = w->current_matrix->rows;
16966 window_row_end = window_row + w->current_matrix->nrows;
16967 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16968 while (window_row < window_row_end)
16969 {
16970 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16971 struct glyph *end = window_row->glyphs[LAST_AREA];
16972
16973 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16974 frame_row->glyphs[TEXT_AREA] = start;
16975 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16976 frame_row->glyphs[LAST_AREA] = end;
16977
16978 /* Disable frame rows whose corresponding window rows have
16979 been disabled in try_window_id. */
16980 if (!window_row->enabled_p)
16981 frame_row->enabled_p = 0;
16982
16983 ++window_row, ++frame_row;
16984 }
16985 }
16986
16987
16988 /* Find the glyph row in window W containing CHARPOS. Consider all
16989 rows between START and END (not inclusive). END null means search
16990 all rows to the end of the display area of W. Value is the row
16991 containing CHARPOS or null. */
16992
16993 struct glyph_row *
16994 row_containing_pos (struct window *w, ptrdiff_t charpos,
16995 struct glyph_row *start, struct glyph_row *end, int dy)
16996 {
16997 struct glyph_row *row = start;
16998 struct glyph_row *best_row = NULL;
16999 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17000 int last_y;
17001
17002 /* If we happen to start on a header-line, skip that. */
17003 if (row->mode_line_p)
17004 ++row;
17005
17006 if ((end && row >= end) || !row->enabled_p)
17007 return NULL;
17008
17009 last_y = window_text_bottom_y (w) - dy;
17010
17011 while (1)
17012 {
17013 /* Give up if we have gone too far. */
17014 if (end && row >= end)
17015 return NULL;
17016 /* This formerly returned if they were equal.
17017 I think that both quantities are of a "last plus one" type;
17018 if so, when they are equal, the row is within the screen. -- rms. */
17019 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17020 return NULL;
17021
17022 /* If it is in this row, return this row. */
17023 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17024 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17025 /* The end position of a row equals the start
17026 position of the next row. If CHARPOS is there, we
17027 would rather consider it displayed in the next
17028 line, except when this line ends in ZV. */
17029 && !row_for_charpos_p (row, charpos)))
17030 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17031 {
17032 struct glyph *g;
17033
17034 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17035 || (!best_row && !row->continued_p))
17036 return row;
17037 /* In bidi-reordered rows, there could be several rows whose
17038 edges surround CHARPOS, all of these rows belonging to
17039 the same continued line. We need to find the row which
17040 fits CHARPOS the best. */
17041 for (g = row->glyphs[TEXT_AREA];
17042 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17043 g++)
17044 {
17045 if (!STRINGP (g->object))
17046 {
17047 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17048 {
17049 mindif = eabs (g->charpos - charpos);
17050 best_row = row;
17051 /* Exact match always wins. */
17052 if (mindif == 0)
17053 return best_row;
17054 }
17055 }
17056 }
17057 }
17058 else if (best_row && !row->continued_p)
17059 return best_row;
17060 ++row;
17061 }
17062 }
17063
17064
17065 /* Try to redisplay window W by reusing its existing display. W's
17066 current matrix must be up to date when this function is called,
17067 i.e. window_end_valid must be nonzero.
17068
17069 Value is
17070
17071 1 if display has been updated
17072 0 if otherwise unsuccessful
17073 -1 if redisplay with same window start is known not to succeed
17074
17075 The following steps are performed:
17076
17077 1. Find the last row in the current matrix of W that is not
17078 affected by changes at the start of current_buffer. If no such row
17079 is found, give up.
17080
17081 2. Find the first row in W's current matrix that is not affected by
17082 changes at the end of current_buffer. Maybe there is no such row.
17083
17084 3. Display lines beginning with the row + 1 found in step 1 to the
17085 row found in step 2 or, if step 2 didn't find a row, to the end of
17086 the window.
17087
17088 4. If cursor is not known to appear on the window, give up.
17089
17090 5. If display stopped at the row found in step 2, scroll the
17091 display and current matrix as needed.
17092
17093 6. Maybe display some lines at the end of W, if we must. This can
17094 happen under various circumstances, like a partially visible line
17095 becoming fully visible, or because newly displayed lines are displayed
17096 in smaller font sizes.
17097
17098 7. Update W's window end information. */
17099
17100 static int
17101 try_window_id (struct window *w)
17102 {
17103 struct frame *f = XFRAME (w->frame);
17104 struct glyph_matrix *current_matrix = w->current_matrix;
17105 struct glyph_matrix *desired_matrix = w->desired_matrix;
17106 struct glyph_row *last_unchanged_at_beg_row;
17107 struct glyph_row *first_unchanged_at_end_row;
17108 struct glyph_row *row;
17109 struct glyph_row *bottom_row;
17110 int bottom_vpos;
17111 struct it it;
17112 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17113 int dvpos, dy;
17114 struct text_pos start_pos;
17115 struct run run;
17116 int first_unchanged_at_end_vpos = 0;
17117 struct glyph_row *last_text_row, *last_text_row_at_end;
17118 struct text_pos start;
17119 ptrdiff_t first_changed_charpos, last_changed_charpos;
17120
17121 #ifdef GLYPH_DEBUG
17122 if (inhibit_try_window_id)
17123 return 0;
17124 #endif
17125
17126 /* This is handy for debugging. */
17127 #if 0
17128 #define GIVE_UP(X) \
17129 do { \
17130 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17131 return 0; \
17132 } while (0)
17133 #else
17134 #define GIVE_UP(X) return 0
17135 #endif
17136
17137 SET_TEXT_POS_FROM_MARKER (start, w->start);
17138
17139 /* Don't use this for mini-windows because these can show
17140 messages and mini-buffers, and we don't handle that here. */
17141 if (MINI_WINDOW_P (w))
17142 GIVE_UP (1);
17143
17144 /* This flag is used to prevent redisplay optimizations. */
17145 if (windows_or_buffers_changed || f->cursor_type_changed)
17146 GIVE_UP (2);
17147
17148 /* Verify that narrowing has not changed.
17149 Also verify that we were not told to prevent redisplay optimizations.
17150 It would be nice to further
17151 reduce the number of cases where this prevents try_window_id. */
17152 if (current_buffer->clip_changed
17153 || current_buffer->prevent_redisplay_optimizations_p)
17154 GIVE_UP (3);
17155
17156 /* Window must either use window-based redisplay or be full width. */
17157 if (!FRAME_WINDOW_P (f)
17158 && (!FRAME_LINE_INS_DEL_OK (f)
17159 || !WINDOW_FULL_WIDTH_P (w)))
17160 GIVE_UP (4);
17161
17162 /* Give up if point is known NOT to appear in W. */
17163 if (PT < CHARPOS (start))
17164 GIVE_UP (5);
17165
17166 /* Another way to prevent redisplay optimizations. */
17167 if (w->last_modified == 0)
17168 GIVE_UP (6);
17169
17170 /* Verify that window is not hscrolled. */
17171 if (w->hscroll != 0)
17172 GIVE_UP (7);
17173
17174 /* Verify that display wasn't paused. */
17175 if (!w->window_end_valid)
17176 GIVE_UP (8);
17177
17178 /* Can't use this if highlighting a region because a cursor movement
17179 will do more than just set the cursor. */
17180 if (markpos_of_region () >= 0)
17181 GIVE_UP (9);
17182
17183 /* Likewise if highlighting trailing whitespace. */
17184 if (!NILP (Vshow_trailing_whitespace))
17185 GIVE_UP (11);
17186
17187 /* Likewise if showing a region. */
17188 if (w->region_showing)
17189 GIVE_UP (10);
17190
17191 /* Can't use this if overlay arrow position and/or string have
17192 changed. */
17193 if (overlay_arrows_changed_p ())
17194 GIVE_UP (12);
17195
17196 /* When word-wrap is on, adding a space to the first word of a
17197 wrapped line can change the wrap position, altering the line
17198 above it. It might be worthwhile to handle this more
17199 intelligently, but for now just redisplay from scratch. */
17200 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17201 GIVE_UP (21);
17202
17203 /* Under bidi reordering, adding or deleting a character in the
17204 beginning of a paragraph, before the first strong directional
17205 character, can change the base direction of the paragraph (unless
17206 the buffer specifies a fixed paragraph direction), which will
17207 require to redisplay the whole paragraph. It might be worthwhile
17208 to find the paragraph limits and widen the range of redisplayed
17209 lines to that, but for now just give up this optimization and
17210 redisplay from scratch. */
17211 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17212 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17213 GIVE_UP (22);
17214
17215 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17216 only if buffer has really changed. The reason is that the gap is
17217 initially at Z for freshly visited files. The code below would
17218 set end_unchanged to 0 in that case. */
17219 if (MODIFF > SAVE_MODIFF
17220 /* This seems to happen sometimes after saving a buffer. */
17221 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17222 {
17223 if (GPT - BEG < BEG_UNCHANGED)
17224 BEG_UNCHANGED = GPT - BEG;
17225 if (Z - GPT < END_UNCHANGED)
17226 END_UNCHANGED = Z - GPT;
17227 }
17228
17229 /* The position of the first and last character that has been changed. */
17230 first_changed_charpos = BEG + BEG_UNCHANGED;
17231 last_changed_charpos = Z - END_UNCHANGED;
17232
17233 /* If window starts after a line end, and the last change is in
17234 front of that newline, then changes don't affect the display.
17235 This case happens with stealth-fontification. Note that although
17236 the display is unchanged, glyph positions in the matrix have to
17237 be adjusted, of course. */
17238 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17239 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17240 && ((last_changed_charpos < CHARPOS (start)
17241 && CHARPOS (start) == BEGV)
17242 || (last_changed_charpos < CHARPOS (start) - 1
17243 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17244 {
17245 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17246 struct glyph_row *r0;
17247
17248 /* Compute how many chars/bytes have been added to or removed
17249 from the buffer. */
17250 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17251 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17252 Z_delta = Z - Z_old;
17253 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17254
17255 /* Give up if PT is not in the window. Note that it already has
17256 been checked at the start of try_window_id that PT is not in
17257 front of the window start. */
17258 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17259 GIVE_UP (13);
17260
17261 /* If window start is unchanged, we can reuse the whole matrix
17262 as is, after adjusting glyph positions. No need to compute
17263 the window end again, since its offset from Z hasn't changed. */
17264 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17265 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17266 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17267 /* PT must not be in a partially visible line. */
17268 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17269 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17270 {
17271 /* Adjust positions in the glyph matrix. */
17272 if (Z_delta || Z_delta_bytes)
17273 {
17274 struct glyph_row *r1
17275 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17276 increment_matrix_positions (w->current_matrix,
17277 MATRIX_ROW_VPOS (r0, current_matrix),
17278 MATRIX_ROW_VPOS (r1, current_matrix),
17279 Z_delta, Z_delta_bytes);
17280 }
17281
17282 /* Set the cursor. */
17283 row = row_containing_pos (w, PT, r0, NULL, 0);
17284 if (row)
17285 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17286 else
17287 emacs_abort ();
17288 return 1;
17289 }
17290 }
17291
17292 /* Handle the case that changes are all below what is displayed in
17293 the window, and that PT is in the window. This shortcut cannot
17294 be taken if ZV is visible in the window, and text has been added
17295 there that is visible in the window. */
17296 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17297 /* ZV is not visible in the window, or there are no
17298 changes at ZV, actually. */
17299 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17300 || first_changed_charpos == last_changed_charpos))
17301 {
17302 struct glyph_row *r0;
17303
17304 /* Give up if PT is not in the window. Note that it already has
17305 been checked at the start of try_window_id that PT is not in
17306 front of the window start. */
17307 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17308 GIVE_UP (14);
17309
17310 /* If window start is unchanged, we can reuse the whole matrix
17311 as is, without changing glyph positions since no text has
17312 been added/removed in front of the window end. */
17313 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17314 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17315 /* PT must not be in a partially visible line. */
17316 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17317 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17318 {
17319 /* We have to compute the window end anew since text
17320 could have been added/removed after it. */
17321 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17322 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17323
17324 /* Set the cursor. */
17325 row = row_containing_pos (w, PT, r0, NULL, 0);
17326 if (row)
17327 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17328 else
17329 emacs_abort ();
17330 return 2;
17331 }
17332 }
17333
17334 /* Give up if window start is in the changed area.
17335
17336 The condition used to read
17337
17338 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17339
17340 but why that was tested escapes me at the moment. */
17341 if (CHARPOS (start) >= first_changed_charpos
17342 && CHARPOS (start) <= last_changed_charpos)
17343 GIVE_UP (15);
17344
17345 /* Check that window start agrees with the start of the first glyph
17346 row in its current matrix. Check this after we know the window
17347 start is not in changed text, otherwise positions would not be
17348 comparable. */
17349 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17350 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17351 GIVE_UP (16);
17352
17353 /* Give up if the window ends in strings. Overlay strings
17354 at the end are difficult to handle, so don't try. */
17355 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
17356 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17357 GIVE_UP (20);
17358
17359 /* Compute the position at which we have to start displaying new
17360 lines. Some of the lines at the top of the window might be
17361 reusable because they are not displaying changed text. Find the
17362 last row in W's current matrix not affected by changes at the
17363 start of current_buffer. Value is null if changes start in the
17364 first line of window. */
17365 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17366 if (last_unchanged_at_beg_row)
17367 {
17368 /* Avoid starting to display in the middle of a character, a TAB
17369 for instance. This is easier than to set up the iterator
17370 exactly, and it's not a frequent case, so the additional
17371 effort wouldn't really pay off. */
17372 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17373 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17374 && last_unchanged_at_beg_row > w->current_matrix->rows)
17375 --last_unchanged_at_beg_row;
17376
17377 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17378 GIVE_UP (17);
17379
17380 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17381 GIVE_UP (18);
17382 start_pos = it.current.pos;
17383
17384 /* Start displaying new lines in the desired matrix at the same
17385 vpos we would use in the current matrix, i.e. below
17386 last_unchanged_at_beg_row. */
17387 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17388 current_matrix);
17389 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17390 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17391
17392 eassert (it.hpos == 0 && it.current_x == 0);
17393 }
17394 else
17395 {
17396 /* There are no reusable lines at the start of the window.
17397 Start displaying in the first text line. */
17398 start_display (&it, w, start);
17399 it.vpos = it.first_vpos;
17400 start_pos = it.current.pos;
17401 }
17402
17403 /* Find the first row that is not affected by changes at the end of
17404 the buffer. Value will be null if there is no unchanged row, in
17405 which case we must redisplay to the end of the window. delta
17406 will be set to the value by which buffer positions beginning with
17407 first_unchanged_at_end_row have to be adjusted due to text
17408 changes. */
17409 first_unchanged_at_end_row
17410 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17411 IF_DEBUG (debug_delta = delta);
17412 IF_DEBUG (debug_delta_bytes = delta_bytes);
17413
17414 /* Set stop_pos to the buffer position up to which we will have to
17415 display new lines. If first_unchanged_at_end_row != NULL, this
17416 is the buffer position of the start of the line displayed in that
17417 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17418 that we don't stop at a buffer position. */
17419 stop_pos = 0;
17420 if (first_unchanged_at_end_row)
17421 {
17422 eassert (last_unchanged_at_beg_row == NULL
17423 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17424
17425 /* If this is a continuation line, move forward to the next one
17426 that isn't. Changes in lines above affect this line.
17427 Caution: this may move first_unchanged_at_end_row to a row
17428 not displaying text. */
17429 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17430 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17431 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17432 < it.last_visible_y))
17433 ++first_unchanged_at_end_row;
17434
17435 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17436 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17437 >= it.last_visible_y))
17438 first_unchanged_at_end_row = NULL;
17439 else
17440 {
17441 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17442 + delta);
17443 first_unchanged_at_end_vpos
17444 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17445 eassert (stop_pos >= Z - END_UNCHANGED);
17446 }
17447 }
17448 else if (last_unchanged_at_beg_row == NULL)
17449 GIVE_UP (19);
17450
17451
17452 #ifdef GLYPH_DEBUG
17453
17454 /* Either there is no unchanged row at the end, or the one we have
17455 now displays text. This is a necessary condition for the window
17456 end pos calculation at the end of this function. */
17457 eassert (first_unchanged_at_end_row == NULL
17458 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17459
17460 debug_last_unchanged_at_beg_vpos
17461 = (last_unchanged_at_beg_row
17462 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17463 : -1);
17464 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17465
17466 #endif /* GLYPH_DEBUG */
17467
17468
17469 /* Display new lines. Set last_text_row to the last new line
17470 displayed which has text on it, i.e. might end up as being the
17471 line where the window_end_vpos is. */
17472 w->cursor.vpos = -1;
17473 last_text_row = NULL;
17474 overlay_arrow_seen = 0;
17475 while (it.current_y < it.last_visible_y
17476 && !f->fonts_changed
17477 && (first_unchanged_at_end_row == NULL
17478 || IT_CHARPOS (it) < stop_pos))
17479 {
17480 if (display_line (&it))
17481 last_text_row = it.glyph_row - 1;
17482 }
17483
17484 if (f->fonts_changed)
17485 return -1;
17486
17487
17488 /* Compute differences in buffer positions, y-positions etc. for
17489 lines reused at the bottom of the window. Compute what we can
17490 scroll. */
17491 if (first_unchanged_at_end_row
17492 /* No lines reused because we displayed everything up to the
17493 bottom of the window. */
17494 && it.current_y < it.last_visible_y)
17495 {
17496 dvpos = (it.vpos
17497 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17498 current_matrix));
17499 dy = it.current_y - first_unchanged_at_end_row->y;
17500 run.current_y = first_unchanged_at_end_row->y;
17501 run.desired_y = run.current_y + dy;
17502 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17503 }
17504 else
17505 {
17506 delta = delta_bytes = dvpos = dy
17507 = run.current_y = run.desired_y = run.height = 0;
17508 first_unchanged_at_end_row = NULL;
17509 }
17510 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17511
17512
17513 /* Find the cursor if not already found. We have to decide whether
17514 PT will appear on this window (it sometimes doesn't, but this is
17515 not a very frequent case.) This decision has to be made before
17516 the current matrix is altered. A value of cursor.vpos < 0 means
17517 that PT is either in one of the lines beginning at
17518 first_unchanged_at_end_row or below the window. Don't care for
17519 lines that might be displayed later at the window end; as
17520 mentioned, this is not a frequent case. */
17521 if (w->cursor.vpos < 0)
17522 {
17523 /* Cursor in unchanged rows at the top? */
17524 if (PT < CHARPOS (start_pos)
17525 && last_unchanged_at_beg_row)
17526 {
17527 row = row_containing_pos (w, PT,
17528 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17529 last_unchanged_at_beg_row + 1, 0);
17530 if (row)
17531 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17532 }
17533
17534 /* Start from first_unchanged_at_end_row looking for PT. */
17535 else if (first_unchanged_at_end_row)
17536 {
17537 row = row_containing_pos (w, PT - delta,
17538 first_unchanged_at_end_row, NULL, 0);
17539 if (row)
17540 set_cursor_from_row (w, row, w->current_matrix, delta,
17541 delta_bytes, dy, dvpos);
17542 }
17543
17544 /* Give up if cursor was not found. */
17545 if (w->cursor.vpos < 0)
17546 {
17547 clear_glyph_matrix (w->desired_matrix);
17548 return -1;
17549 }
17550 }
17551
17552 /* Don't let the cursor end in the scroll margins. */
17553 {
17554 int this_scroll_margin, cursor_height;
17555 int frame_line_height = default_line_pixel_height (w);
17556 int window_total_lines
17557 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
17558
17559 this_scroll_margin =
17560 max (0, min (scroll_margin, window_total_lines / 4));
17561 this_scroll_margin *= frame_line_height;
17562 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17563
17564 if ((w->cursor.y < this_scroll_margin
17565 && CHARPOS (start) > BEGV)
17566 /* Old redisplay didn't take scroll margin into account at the bottom,
17567 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17568 || (w->cursor.y + (make_cursor_line_fully_visible_p
17569 ? cursor_height + this_scroll_margin
17570 : 1)) > it.last_visible_y)
17571 {
17572 w->cursor.vpos = -1;
17573 clear_glyph_matrix (w->desired_matrix);
17574 return -1;
17575 }
17576 }
17577
17578 /* Scroll the display. Do it before changing the current matrix so
17579 that xterm.c doesn't get confused about where the cursor glyph is
17580 found. */
17581 if (dy && run.height)
17582 {
17583 update_begin (f);
17584
17585 if (FRAME_WINDOW_P (f))
17586 {
17587 FRAME_RIF (f)->update_window_begin_hook (w);
17588 FRAME_RIF (f)->clear_window_mouse_face (w);
17589 FRAME_RIF (f)->scroll_run_hook (w, &run);
17590 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17591 }
17592 else
17593 {
17594 /* Terminal frame. In this case, dvpos gives the number of
17595 lines to scroll by; dvpos < 0 means scroll up. */
17596 int from_vpos
17597 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17598 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17599 int end = (WINDOW_TOP_EDGE_LINE (w)
17600 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17601 + window_internal_height (w));
17602
17603 #if defined (HAVE_GPM) || defined (MSDOS)
17604 x_clear_window_mouse_face (w);
17605 #endif
17606 /* Perform the operation on the screen. */
17607 if (dvpos > 0)
17608 {
17609 /* Scroll last_unchanged_at_beg_row to the end of the
17610 window down dvpos lines. */
17611 set_terminal_window (f, end);
17612
17613 /* On dumb terminals delete dvpos lines at the end
17614 before inserting dvpos empty lines. */
17615 if (!FRAME_SCROLL_REGION_OK (f))
17616 ins_del_lines (f, end - dvpos, -dvpos);
17617
17618 /* Insert dvpos empty lines in front of
17619 last_unchanged_at_beg_row. */
17620 ins_del_lines (f, from, dvpos);
17621 }
17622 else if (dvpos < 0)
17623 {
17624 /* Scroll up last_unchanged_at_beg_vpos to the end of
17625 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17626 set_terminal_window (f, end);
17627
17628 /* Delete dvpos lines in front of
17629 last_unchanged_at_beg_vpos. ins_del_lines will set
17630 the cursor to the given vpos and emit |dvpos| delete
17631 line sequences. */
17632 ins_del_lines (f, from + dvpos, dvpos);
17633
17634 /* On a dumb terminal insert dvpos empty lines at the
17635 end. */
17636 if (!FRAME_SCROLL_REGION_OK (f))
17637 ins_del_lines (f, end + dvpos, -dvpos);
17638 }
17639
17640 set_terminal_window (f, 0);
17641 }
17642
17643 update_end (f);
17644 }
17645
17646 /* Shift reused rows of the current matrix to the right position.
17647 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17648 text. */
17649 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17650 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17651 if (dvpos < 0)
17652 {
17653 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17654 bottom_vpos, dvpos);
17655 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17656 bottom_vpos);
17657 }
17658 else if (dvpos > 0)
17659 {
17660 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17661 bottom_vpos, dvpos);
17662 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17663 first_unchanged_at_end_vpos + dvpos);
17664 }
17665
17666 /* For frame-based redisplay, make sure that current frame and window
17667 matrix are in sync with respect to glyph memory. */
17668 if (!FRAME_WINDOW_P (f))
17669 sync_frame_with_window_matrix_rows (w);
17670
17671 /* Adjust buffer positions in reused rows. */
17672 if (delta || delta_bytes)
17673 increment_matrix_positions (current_matrix,
17674 first_unchanged_at_end_vpos + dvpos,
17675 bottom_vpos, delta, delta_bytes);
17676
17677 /* Adjust Y positions. */
17678 if (dy)
17679 shift_glyph_matrix (w, current_matrix,
17680 first_unchanged_at_end_vpos + dvpos,
17681 bottom_vpos, dy);
17682
17683 if (first_unchanged_at_end_row)
17684 {
17685 first_unchanged_at_end_row += dvpos;
17686 if (first_unchanged_at_end_row->y >= it.last_visible_y
17687 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17688 first_unchanged_at_end_row = NULL;
17689 }
17690
17691 /* If scrolling up, there may be some lines to display at the end of
17692 the window. */
17693 last_text_row_at_end = NULL;
17694 if (dy < 0)
17695 {
17696 /* Scrolling up can leave for example a partially visible line
17697 at the end of the window to be redisplayed. */
17698 /* Set last_row to the glyph row in the current matrix where the
17699 window end line is found. It has been moved up or down in
17700 the matrix by dvpos. */
17701 int last_vpos = w->window_end_vpos + dvpos;
17702 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17703
17704 /* If last_row is the window end line, it should display text. */
17705 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17706
17707 /* If window end line was partially visible before, begin
17708 displaying at that line. Otherwise begin displaying with the
17709 line following it. */
17710 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17711 {
17712 init_to_row_start (&it, w, last_row);
17713 it.vpos = last_vpos;
17714 it.current_y = last_row->y;
17715 }
17716 else
17717 {
17718 init_to_row_end (&it, w, last_row);
17719 it.vpos = 1 + last_vpos;
17720 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17721 ++last_row;
17722 }
17723
17724 /* We may start in a continuation line. If so, we have to
17725 get the right continuation_lines_width and current_x. */
17726 it.continuation_lines_width = last_row->continuation_lines_width;
17727 it.hpos = it.current_x = 0;
17728
17729 /* Display the rest of the lines at the window end. */
17730 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17731 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17732 {
17733 /* Is it always sure that the display agrees with lines in
17734 the current matrix? I don't think so, so we mark rows
17735 displayed invalid in the current matrix by setting their
17736 enabled_p flag to zero. */
17737 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17738 if (display_line (&it))
17739 last_text_row_at_end = it.glyph_row - 1;
17740 }
17741 }
17742
17743 /* Update window_end_pos and window_end_vpos. */
17744 if (first_unchanged_at_end_row && !last_text_row_at_end)
17745 {
17746 /* Window end line if one of the preserved rows from the current
17747 matrix. Set row to the last row displaying text in current
17748 matrix starting at first_unchanged_at_end_row, after
17749 scrolling. */
17750 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17751 row = find_last_row_displaying_text (w->current_matrix, &it,
17752 first_unchanged_at_end_row);
17753 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17754 adjust_window_ends (w, row, 1);
17755 eassert (w->window_end_bytepos >= 0);
17756 IF_DEBUG (debug_method_add (w, "A"));
17757 }
17758 else if (last_text_row_at_end)
17759 {
17760 adjust_window_ends (w, last_text_row_at_end, 0);
17761 eassert (w->window_end_bytepos >= 0);
17762 IF_DEBUG (debug_method_add (w, "B"));
17763 }
17764 else if (last_text_row)
17765 {
17766 /* We have displayed either to the end of the window or at the
17767 end of the window, i.e. the last row with text is to be found
17768 in the desired matrix. */
17769 adjust_window_ends (w, last_text_row, 0);
17770 eassert (w->window_end_bytepos >= 0);
17771 }
17772 else if (first_unchanged_at_end_row == NULL
17773 && last_text_row == NULL
17774 && last_text_row_at_end == NULL)
17775 {
17776 /* Displayed to end of window, but no line containing text was
17777 displayed. Lines were deleted at the end of the window. */
17778 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17779 int vpos = w->window_end_vpos;
17780 struct glyph_row *current_row = current_matrix->rows + vpos;
17781 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17782
17783 for (row = NULL;
17784 row == NULL && vpos >= first_vpos;
17785 --vpos, --current_row, --desired_row)
17786 {
17787 if (desired_row->enabled_p)
17788 {
17789 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17790 row = desired_row;
17791 }
17792 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17793 row = current_row;
17794 }
17795
17796 eassert (row != NULL);
17797 w->window_end_vpos = vpos + 1;
17798 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17799 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17800 eassert (w->window_end_bytepos >= 0);
17801 IF_DEBUG (debug_method_add (w, "C"));
17802 }
17803 else
17804 emacs_abort ();
17805
17806 IF_DEBUG (debug_end_pos = w->window_end_pos;
17807 debug_end_vpos = w->window_end_vpos);
17808
17809 /* Record that display has not been completed. */
17810 w->window_end_valid = 0;
17811 w->desired_matrix->no_scrolling_p = 1;
17812 return 3;
17813
17814 #undef GIVE_UP
17815 }
17816
17817
17818 \f
17819 /***********************************************************************
17820 More debugging support
17821 ***********************************************************************/
17822
17823 #ifdef GLYPH_DEBUG
17824
17825 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17826 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17827 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17828
17829
17830 /* Dump the contents of glyph matrix MATRIX on stderr.
17831
17832 GLYPHS 0 means don't show glyph contents.
17833 GLYPHS 1 means show glyphs in short form
17834 GLYPHS > 1 means show glyphs in long form. */
17835
17836 void
17837 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17838 {
17839 int i;
17840 for (i = 0; i < matrix->nrows; ++i)
17841 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17842 }
17843
17844
17845 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17846 the glyph row and area where the glyph comes from. */
17847
17848 void
17849 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17850 {
17851 if (glyph->type == CHAR_GLYPH
17852 || glyph->type == GLYPHLESS_GLYPH)
17853 {
17854 fprintf (stderr,
17855 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17856 glyph - row->glyphs[TEXT_AREA],
17857 (glyph->type == CHAR_GLYPH
17858 ? 'C'
17859 : 'G'),
17860 glyph->charpos,
17861 (BUFFERP (glyph->object)
17862 ? 'B'
17863 : (STRINGP (glyph->object)
17864 ? 'S'
17865 : (INTEGERP (glyph->object)
17866 ? '0'
17867 : '-'))),
17868 glyph->pixel_width,
17869 glyph->u.ch,
17870 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17871 ? glyph->u.ch
17872 : '.'),
17873 glyph->face_id,
17874 glyph->left_box_line_p,
17875 glyph->right_box_line_p);
17876 }
17877 else if (glyph->type == STRETCH_GLYPH)
17878 {
17879 fprintf (stderr,
17880 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17881 glyph - row->glyphs[TEXT_AREA],
17882 'S',
17883 glyph->charpos,
17884 (BUFFERP (glyph->object)
17885 ? 'B'
17886 : (STRINGP (glyph->object)
17887 ? 'S'
17888 : (INTEGERP (glyph->object)
17889 ? '0'
17890 : '-'))),
17891 glyph->pixel_width,
17892 0,
17893 ' ',
17894 glyph->face_id,
17895 glyph->left_box_line_p,
17896 glyph->right_box_line_p);
17897 }
17898 else if (glyph->type == IMAGE_GLYPH)
17899 {
17900 fprintf (stderr,
17901 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17902 glyph - row->glyphs[TEXT_AREA],
17903 'I',
17904 glyph->charpos,
17905 (BUFFERP (glyph->object)
17906 ? 'B'
17907 : (STRINGP (glyph->object)
17908 ? 'S'
17909 : (INTEGERP (glyph->object)
17910 ? '0'
17911 : '-'))),
17912 glyph->pixel_width,
17913 glyph->u.img_id,
17914 '.',
17915 glyph->face_id,
17916 glyph->left_box_line_p,
17917 glyph->right_box_line_p);
17918 }
17919 else if (glyph->type == COMPOSITE_GLYPH)
17920 {
17921 fprintf (stderr,
17922 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17923 glyph - row->glyphs[TEXT_AREA],
17924 '+',
17925 glyph->charpos,
17926 (BUFFERP (glyph->object)
17927 ? 'B'
17928 : (STRINGP (glyph->object)
17929 ? 'S'
17930 : (INTEGERP (glyph->object)
17931 ? '0'
17932 : '-'))),
17933 glyph->pixel_width,
17934 glyph->u.cmp.id);
17935 if (glyph->u.cmp.automatic)
17936 fprintf (stderr,
17937 "[%d-%d]",
17938 glyph->slice.cmp.from, glyph->slice.cmp.to);
17939 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17940 glyph->face_id,
17941 glyph->left_box_line_p,
17942 glyph->right_box_line_p);
17943 }
17944 }
17945
17946
17947 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17948 GLYPHS 0 means don't show glyph contents.
17949 GLYPHS 1 means show glyphs in short form
17950 GLYPHS > 1 means show glyphs in long form. */
17951
17952 void
17953 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17954 {
17955 if (glyphs != 1)
17956 {
17957 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17958 fprintf (stderr, "==============================================================================\n");
17959
17960 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17961 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17962 vpos,
17963 MATRIX_ROW_START_CHARPOS (row),
17964 MATRIX_ROW_END_CHARPOS (row),
17965 row->used[TEXT_AREA],
17966 row->contains_overlapping_glyphs_p,
17967 row->enabled_p,
17968 row->truncated_on_left_p,
17969 row->truncated_on_right_p,
17970 row->continued_p,
17971 MATRIX_ROW_CONTINUATION_LINE_P (row),
17972 MATRIX_ROW_DISPLAYS_TEXT_P (row),
17973 row->ends_at_zv_p,
17974 row->fill_line_p,
17975 row->ends_in_middle_of_char_p,
17976 row->starts_in_middle_of_char_p,
17977 row->mouse_face_p,
17978 row->x,
17979 row->y,
17980 row->pixel_width,
17981 row->height,
17982 row->visible_height,
17983 row->ascent,
17984 row->phys_ascent);
17985 /* The next 3 lines should align to "Start" in the header. */
17986 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
17987 row->end.overlay_string_index,
17988 row->continuation_lines_width);
17989 fprintf (stderr, " %9"pI"d %9"pI"d\n",
17990 CHARPOS (row->start.string_pos),
17991 CHARPOS (row->end.string_pos));
17992 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
17993 row->end.dpvec_index);
17994 }
17995
17996 if (glyphs > 1)
17997 {
17998 int area;
17999
18000 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18001 {
18002 struct glyph *glyph = row->glyphs[area];
18003 struct glyph *glyph_end = glyph + row->used[area];
18004
18005 /* Glyph for a line end in text. */
18006 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18007 ++glyph_end;
18008
18009 if (glyph < glyph_end)
18010 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18011
18012 for (; glyph < glyph_end; ++glyph)
18013 dump_glyph (row, glyph, area);
18014 }
18015 }
18016 else if (glyphs == 1)
18017 {
18018 int area;
18019
18020 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18021 {
18022 char *s = alloca (row->used[area] + 4);
18023 int i;
18024
18025 for (i = 0; i < row->used[area]; ++i)
18026 {
18027 struct glyph *glyph = row->glyphs[area] + i;
18028 if (i == row->used[area] - 1
18029 && area == TEXT_AREA
18030 && INTEGERP (glyph->object)
18031 && glyph->type == CHAR_GLYPH
18032 && glyph->u.ch == ' ')
18033 {
18034 strcpy (&s[i], "[\\n]");
18035 i += 4;
18036 }
18037 else if (glyph->type == CHAR_GLYPH
18038 && glyph->u.ch < 0x80
18039 && glyph->u.ch >= ' ')
18040 s[i] = glyph->u.ch;
18041 else
18042 s[i] = '.';
18043 }
18044
18045 s[i] = '\0';
18046 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18047 }
18048 }
18049 }
18050
18051
18052 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18053 Sdump_glyph_matrix, 0, 1, "p",
18054 doc: /* Dump the current matrix of the selected window to stderr.
18055 Shows contents of glyph row structures. With non-nil
18056 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18057 glyphs in short form, otherwise show glyphs in long form. */)
18058 (Lisp_Object glyphs)
18059 {
18060 struct window *w = XWINDOW (selected_window);
18061 struct buffer *buffer = XBUFFER (w->contents);
18062
18063 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18064 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18065 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18066 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18067 fprintf (stderr, "=============================================\n");
18068 dump_glyph_matrix (w->current_matrix,
18069 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18070 return Qnil;
18071 }
18072
18073
18074 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18075 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18076 (void)
18077 {
18078 struct frame *f = XFRAME (selected_frame);
18079 dump_glyph_matrix (f->current_matrix, 1);
18080 return Qnil;
18081 }
18082
18083
18084 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18085 doc: /* Dump glyph row ROW to stderr.
18086 GLYPH 0 means don't dump glyphs.
18087 GLYPH 1 means dump glyphs in short form.
18088 GLYPH > 1 or omitted means dump glyphs in long form. */)
18089 (Lisp_Object row, Lisp_Object glyphs)
18090 {
18091 struct glyph_matrix *matrix;
18092 EMACS_INT vpos;
18093
18094 CHECK_NUMBER (row);
18095 matrix = XWINDOW (selected_window)->current_matrix;
18096 vpos = XINT (row);
18097 if (vpos >= 0 && vpos < matrix->nrows)
18098 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18099 vpos,
18100 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18101 return Qnil;
18102 }
18103
18104
18105 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18106 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18107 GLYPH 0 means don't dump glyphs.
18108 GLYPH 1 means dump glyphs in short form.
18109 GLYPH > 1 or omitted means dump glyphs in long form. */)
18110 (Lisp_Object row, Lisp_Object glyphs)
18111 {
18112 struct frame *sf = SELECTED_FRAME ();
18113 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18114 EMACS_INT vpos;
18115
18116 CHECK_NUMBER (row);
18117 vpos = XINT (row);
18118 if (vpos >= 0 && vpos < m->nrows)
18119 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18120 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18121 return Qnil;
18122 }
18123
18124
18125 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18126 doc: /* Toggle tracing of redisplay.
18127 With ARG, turn tracing on if and only if ARG is positive. */)
18128 (Lisp_Object arg)
18129 {
18130 if (NILP (arg))
18131 trace_redisplay_p = !trace_redisplay_p;
18132 else
18133 {
18134 arg = Fprefix_numeric_value (arg);
18135 trace_redisplay_p = XINT (arg) > 0;
18136 }
18137
18138 return Qnil;
18139 }
18140
18141
18142 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18143 doc: /* Like `format', but print result to stderr.
18144 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18145 (ptrdiff_t nargs, Lisp_Object *args)
18146 {
18147 Lisp_Object s = Fformat (nargs, args);
18148 fprintf (stderr, "%s", SDATA (s));
18149 return Qnil;
18150 }
18151
18152 #endif /* GLYPH_DEBUG */
18153
18154
18155 \f
18156 /***********************************************************************
18157 Building Desired Matrix Rows
18158 ***********************************************************************/
18159
18160 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18161 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18162
18163 static struct glyph_row *
18164 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18165 {
18166 struct frame *f = XFRAME (WINDOW_FRAME (w));
18167 struct buffer *buffer = XBUFFER (w->contents);
18168 struct buffer *old = current_buffer;
18169 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18170 int arrow_len = SCHARS (overlay_arrow_string);
18171 const unsigned char *arrow_end = arrow_string + arrow_len;
18172 const unsigned char *p;
18173 struct it it;
18174 bool multibyte_p;
18175 int n_glyphs_before;
18176
18177 set_buffer_temp (buffer);
18178 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18179 it.glyph_row->used[TEXT_AREA] = 0;
18180 SET_TEXT_POS (it.position, 0, 0);
18181
18182 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18183 p = arrow_string;
18184 while (p < arrow_end)
18185 {
18186 Lisp_Object face, ilisp;
18187
18188 /* Get the next character. */
18189 if (multibyte_p)
18190 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18191 else
18192 {
18193 it.c = it.char_to_display = *p, it.len = 1;
18194 if (! ASCII_CHAR_P (it.c))
18195 it.char_to_display = BYTE8_TO_CHAR (it.c);
18196 }
18197 p += it.len;
18198
18199 /* Get its face. */
18200 ilisp = make_number (p - arrow_string);
18201 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18202 it.face_id = compute_char_face (f, it.char_to_display, face);
18203
18204 /* Compute its width, get its glyphs. */
18205 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18206 SET_TEXT_POS (it.position, -1, -1);
18207 PRODUCE_GLYPHS (&it);
18208
18209 /* If this character doesn't fit any more in the line, we have
18210 to remove some glyphs. */
18211 if (it.current_x > it.last_visible_x)
18212 {
18213 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18214 break;
18215 }
18216 }
18217
18218 set_buffer_temp (old);
18219 return it.glyph_row;
18220 }
18221
18222
18223 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18224 glyphs to insert is determined by produce_special_glyphs. */
18225
18226 static void
18227 insert_left_trunc_glyphs (struct it *it)
18228 {
18229 struct it truncate_it;
18230 struct glyph *from, *end, *to, *toend;
18231
18232 eassert (!FRAME_WINDOW_P (it->f)
18233 || (!it->glyph_row->reversed_p
18234 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18235 || (it->glyph_row->reversed_p
18236 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18237
18238 /* Get the truncation glyphs. */
18239 truncate_it = *it;
18240 truncate_it.current_x = 0;
18241 truncate_it.face_id = DEFAULT_FACE_ID;
18242 truncate_it.glyph_row = &scratch_glyph_row;
18243 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18244 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18245 truncate_it.object = make_number (0);
18246 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18247
18248 /* Overwrite glyphs from IT with truncation glyphs. */
18249 if (!it->glyph_row->reversed_p)
18250 {
18251 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18252
18253 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18254 end = from + tused;
18255 to = it->glyph_row->glyphs[TEXT_AREA];
18256 toend = to + it->glyph_row->used[TEXT_AREA];
18257 if (FRAME_WINDOW_P (it->f))
18258 {
18259 /* On GUI frames, when variable-size fonts are displayed,
18260 the truncation glyphs may need more pixels than the row's
18261 glyphs they overwrite. We overwrite more glyphs to free
18262 enough screen real estate, and enlarge the stretch glyph
18263 on the right (see display_line), if there is one, to
18264 preserve the screen position of the truncation glyphs on
18265 the right. */
18266 int w = 0;
18267 struct glyph *g = to;
18268 short used;
18269
18270 /* The first glyph could be partially visible, in which case
18271 it->glyph_row->x will be negative. But we want the left
18272 truncation glyphs to be aligned at the left margin of the
18273 window, so we override the x coordinate at which the row
18274 will begin. */
18275 it->glyph_row->x = 0;
18276 while (g < toend && w < it->truncation_pixel_width)
18277 {
18278 w += g->pixel_width;
18279 ++g;
18280 }
18281 if (g - to - tused > 0)
18282 {
18283 memmove (to + tused, g, (toend - g) * sizeof(*g));
18284 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18285 }
18286 used = it->glyph_row->used[TEXT_AREA];
18287 if (it->glyph_row->truncated_on_right_p
18288 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18289 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18290 == STRETCH_GLYPH)
18291 {
18292 int extra = w - it->truncation_pixel_width;
18293
18294 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18295 }
18296 }
18297
18298 while (from < end)
18299 *to++ = *from++;
18300
18301 /* There may be padding glyphs left over. Overwrite them too. */
18302 if (!FRAME_WINDOW_P (it->f))
18303 {
18304 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18305 {
18306 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18307 while (from < end)
18308 *to++ = *from++;
18309 }
18310 }
18311
18312 if (to > toend)
18313 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18314 }
18315 else
18316 {
18317 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18318
18319 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18320 that back to front. */
18321 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18322 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18323 toend = it->glyph_row->glyphs[TEXT_AREA];
18324 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18325 if (FRAME_WINDOW_P (it->f))
18326 {
18327 int w = 0;
18328 struct glyph *g = to;
18329
18330 while (g >= toend && w < it->truncation_pixel_width)
18331 {
18332 w += g->pixel_width;
18333 --g;
18334 }
18335 if (to - g - tused > 0)
18336 to = g + tused;
18337 if (it->glyph_row->truncated_on_right_p
18338 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18339 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18340 {
18341 int extra = w - it->truncation_pixel_width;
18342
18343 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18344 }
18345 }
18346
18347 while (from >= end && to >= toend)
18348 *to-- = *from--;
18349 if (!FRAME_WINDOW_P (it->f))
18350 {
18351 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18352 {
18353 from =
18354 truncate_it.glyph_row->glyphs[TEXT_AREA]
18355 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18356 while (from >= end && to >= toend)
18357 *to-- = *from--;
18358 }
18359 }
18360 if (from >= end)
18361 {
18362 /* Need to free some room before prepending additional
18363 glyphs. */
18364 int move_by = from - end + 1;
18365 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18366 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18367
18368 for ( ; g >= g0; g--)
18369 g[move_by] = *g;
18370 while (from >= end)
18371 *to-- = *from--;
18372 it->glyph_row->used[TEXT_AREA] += move_by;
18373 }
18374 }
18375 }
18376
18377 /* Compute the hash code for ROW. */
18378 unsigned
18379 row_hash (struct glyph_row *row)
18380 {
18381 int area, k;
18382 unsigned hashval = 0;
18383
18384 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18385 for (k = 0; k < row->used[area]; ++k)
18386 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18387 + row->glyphs[area][k].u.val
18388 + row->glyphs[area][k].face_id
18389 + row->glyphs[area][k].padding_p
18390 + (row->glyphs[area][k].type << 2));
18391
18392 return hashval;
18393 }
18394
18395 /* Compute the pixel height and width of IT->glyph_row.
18396
18397 Most of the time, ascent and height of a display line will be equal
18398 to the max_ascent and max_height values of the display iterator
18399 structure. This is not the case if
18400
18401 1. We hit ZV without displaying anything. In this case, max_ascent
18402 and max_height will be zero.
18403
18404 2. We have some glyphs that don't contribute to the line height.
18405 (The glyph row flag contributes_to_line_height_p is for future
18406 pixmap extensions).
18407
18408 The first case is easily covered by using default values because in
18409 these cases, the line height does not really matter, except that it
18410 must not be zero. */
18411
18412 static void
18413 compute_line_metrics (struct it *it)
18414 {
18415 struct glyph_row *row = it->glyph_row;
18416
18417 if (FRAME_WINDOW_P (it->f))
18418 {
18419 int i, min_y, max_y;
18420
18421 /* The line may consist of one space only, that was added to
18422 place the cursor on it. If so, the row's height hasn't been
18423 computed yet. */
18424 if (row->height == 0)
18425 {
18426 if (it->max_ascent + it->max_descent == 0)
18427 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18428 row->ascent = it->max_ascent;
18429 row->height = it->max_ascent + it->max_descent;
18430 row->phys_ascent = it->max_phys_ascent;
18431 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18432 row->extra_line_spacing = it->max_extra_line_spacing;
18433 }
18434
18435 /* Compute the width of this line. */
18436 row->pixel_width = row->x;
18437 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18438 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18439
18440 eassert (row->pixel_width >= 0);
18441 eassert (row->ascent >= 0 && row->height > 0);
18442
18443 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18444 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18445
18446 /* If first line's physical ascent is larger than its logical
18447 ascent, use the physical ascent, and make the row taller.
18448 This makes accented characters fully visible. */
18449 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18450 && row->phys_ascent > row->ascent)
18451 {
18452 row->height += row->phys_ascent - row->ascent;
18453 row->ascent = row->phys_ascent;
18454 }
18455
18456 /* Compute how much of the line is visible. */
18457 row->visible_height = row->height;
18458
18459 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18460 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18461
18462 if (row->y < min_y)
18463 row->visible_height -= min_y - row->y;
18464 if (row->y + row->height > max_y)
18465 row->visible_height -= row->y + row->height - max_y;
18466 }
18467 else
18468 {
18469 row->pixel_width = row->used[TEXT_AREA];
18470 if (row->continued_p)
18471 row->pixel_width -= it->continuation_pixel_width;
18472 else if (row->truncated_on_right_p)
18473 row->pixel_width -= it->truncation_pixel_width;
18474 row->ascent = row->phys_ascent = 0;
18475 row->height = row->phys_height = row->visible_height = 1;
18476 row->extra_line_spacing = 0;
18477 }
18478
18479 /* Compute a hash code for this row. */
18480 row->hash = row_hash (row);
18481
18482 it->max_ascent = it->max_descent = 0;
18483 it->max_phys_ascent = it->max_phys_descent = 0;
18484 }
18485
18486
18487 /* Append one space to the glyph row of iterator IT if doing a
18488 window-based redisplay. The space has the same face as
18489 IT->face_id. Value is non-zero if a space was added.
18490
18491 This function is called to make sure that there is always one glyph
18492 at the end of a glyph row that the cursor can be set on under
18493 window-systems. (If there weren't such a glyph we would not know
18494 how wide and tall a box cursor should be displayed).
18495
18496 At the same time this space let's a nicely handle clearing to the
18497 end of the line if the row ends in italic text. */
18498
18499 static int
18500 append_space_for_newline (struct it *it, int default_face_p)
18501 {
18502 if (FRAME_WINDOW_P (it->f))
18503 {
18504 int n = it->glyph_row->used[TEXT_AREA];
18505
18506 if (it->glyph_row->glyphs[TEXT_AREA] + n
18507 < it->glyph_row->glyphs[1 + TEXT_AREA])
18508 {
18509 /* Save some values that must not be changed.
18510 Must save IT->c and IT->len because otherwise
18511 ITERATOR_AT_END_P wouldn't work anymore after
18512 append_space_for_newline has been called. */
18513 enum display_element_type saved_what = it->what;
18514 int saved_c = it->c, saved_len = it->len;
18515 int saved_char_to_display = it->char_to_display;
18516 int saved_x = it->current_x;
18517 int saved_face_id = it->face_id;
18518 int saved_box_end = it->end_of_box_run_p;
18519 struct text_pos saved_pos;
18520 Lisp_Object saved_object;
18521 struct face *face;
18522
18523 saved_object = it->object;
18524 saved_pos = it->position;
18525
18526 it->what = IT_CHARACTER;
18527 memset (&it->position, 0, sizeof it->position);
18528 it->object = make_number (0);
18529 it->c = it->char_to_display = ' ';
18530 it->len = 1;
18531
18532 /* If the default face was remapped, be sure to use the
18533 remapped face for the appended newline. */
18534 if (default_face_p)
18535 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18536 else if (it->face_before_selective_p)
18537 it->face_id = it->saved_face_id;
18538 face = FACE_FROM_ID (it->f, it->face_id);
18539 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18540 /* In R2L rows, we will prepend a stretch glyph that will
18541 have the end_of_box_run_p flag set for it, so there's no
18542 need for the appended newline glyph to have that flag
18543 set. */
18544 if (it->glyph_row->reversed_p
18545 /* But if the appended newline glyph goes all the way to
18546 the end of the row, there will be no stretch glyph,
18547 so leave the box flag set. */
18548 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18549 it->end_of_box_run_p = 0;
18550
18551 PRODUCE_GLYPHS (it);
18552
18553 it->override_ascent = -1;
18554 it->constrain_row_ascent_descent_p = 0;
18555 it->current_x = saved_x;
18556 it->object = saved_object;
18557 it->position = saved_pos;
18558 it->what = saved_what;
18559 it->face_id = saved_face_id;
18560 it->len = saved_len;
18561 it->c = saved_c;
18562 it->char_to_display = saved_char_to_display;
18563 it->end_of_box_run_p = saved_box_end;
18564 return 1;
18565 }
18566 }
18567
18568 return 0;
18569 }
18570
18571
18572 /* Extend the face of the last glyph in the text area of IT->glyph_row
18573 to the end of the display line. Called from display_line. If the
18574 glyph row is empty, add a space glyph to it so that we know the
18575 face to draw. Set the glyph row flag fill_line_p. If the glyph
18576 row is R2L, prepend a stretch glyph to cover the empty space to the
18577 left of the leftmost glyph. */
18578
18579 static void
18580 extend_face_to_end_of_line (struct it *it)
18581 {
18582 struct face *face, *default_face;
18583 struct frame *f = it->f;
18584
18585 /* If line is already filled, do nothing. Non window-system frames
18586 get a grace of one more ``pixel'' because their characters are
18587 1-``pixel'' wide, so they hit the equality too early. This grace
18588 is needed only for R2L rows that are not continued, to produce
18589 one extra blank where we could display the cursor. */
18590 if (it->current_x >= it->last_visible_x
18591 + (!FRAME_WINDOW_P (f)
18592 && it->glyph_row->reversed_p
18593 && !it->glyph_row->continued_p))
18594 return;
18595
18596 /* The default face, possibly remapped. */
18597 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18598
18599 /* Face extension extends the background and box of IT->face_id
18600 to the end of the line. If the background equals the background
18601 of the frame, we don't have to do anything. */
18602 if (it->face_before_selective_p)
18603 face = FACE_FROM_ID (f, it->saved_face_id);
18604 else
18605 face = FACE_FROM_ID (f, it->face_id);
18606
18607 if (FRAME_WINDOW_P (f)
18608 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18609 && face->box == FACE_NO_BOX
18610 && face->background == FRAME_BACKGROUND_PIXEL (f)
18611 && !face->stipple
18612 && !it->glyph_row->reversed_p)
18613 return;
18614
18615 /* Set the glyph row flag indicating that the face of the last glyph
18616 in the text area has to be drawn to the end of the text area. */
18617 it->glyph_row->fill_line_p = 1;
18618
18619 /* If current character of IT is not ASCII, make sure we have the
18620 ASCII face. This will be automatically undone the next time
18621 get_next_display_element returns a multibyte character. Note
18622 that the character will always be single byte in unibyte
18623 text. */
18624 if (!ASCII_CHAR_P (it->c))
18625 {
18626 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18627 }
18628
18629 if (FRAME_WINDOW_P (f))
18630 {
18631 /* If the row is empty, add a space with the current face of IT,
18632 so that we know which face to draw. */
18633 if (it->glyph_row->used[TEXT_AREA] == 0)
18634 {
18635 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18636 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18637 it->glyph_row->used[TEXT_AREA] = 1;
18638 }
18639 #ifdef HAVE_WINDOW_SYSTEM
18640 if (it->glyph_row->reversed_p)
18641 {
18642 /* Prepend a stretch glyph to the row, such that the
18643 rightmost glyph will be drawn flushed all the way to the
18644 right margin of the window. The stretch glyph that will
18645 occupy the empty space, if any, to the left of the
18646 glyphs. */
18647 struct font *font = face->font ? face->font : FRAME_FONT (f);
18648 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18649 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18650 struct glyph *g;
18651 int row_width, stretch_ascent, stretch_width;
18652 struct text_pos saved_pos;
18653 int saved_face_id, saved_avoid_cursor, saved_box_start;
18654
18655 for (row_width = 0, g = row_start; g < row_end; g++)
18656 row_width += g->pixel_width;
18657 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18658 if (stretch_width > 0)
18659 {
18660 stretch_ascent =
18661 (((it->ascent + it->descent)
18662 * FONT_BASE (font)) / FONT_HEIGHT (font));
18663 saved_pos = it->position;
18664 memset (&it->position, 0, sizeof it->position);
18665 saved_avoid_cursor = it->avoid_cursor_p;
18666 it->avoid_cursor_p = 1;
18667 saved_face_id = it->face_id;
18668 saved_box_start = it->start_of_box_run_p;
18669 /* The last row's stretch glyph should get the default
18670 face, to avoid painting the rest of the window with
18671 the region face, if the region ends at ZV. */
18672 if (it->glyph_row->ends_at_zv_p)
18673 it->face_id = default_face->id;
18674 else
18675 it->face_id = face->id;
18676 it->start_of_box_run_p = 0;
18677 append_stretch_glyph (it, make_number (0), stretch_width,
18678 it->ascent + it->descent, stretch_ascent);
18679 it->position = saved_pos;
18680 it->avoid_cursor_p = saved_avoid_cursor;
18681 it->face_id = saved_face_id;
18682 it->start_of_box_run_p = saved_box_start;
18683 }
18684 }
18685 #endif /* HAVE_WINDOW_SYSTEM */
18686 }
18687 else
18688 {
18689 /* Save some values that must not be changed. */
18690 int saved_x = it->current_x;
18691 struct text_pos saved_pos;
18692 Lisp_Object saved_object;
18693 enum display_element_type saved_what = it->what;
18694 int saved_face_id = it->face_id;
18695
18696 saved_object = it->object;
18697 saved_pos = it->position;
18698
18699 it->what = IT_CHARACTER;
18700 memset (&it->position, 0, sizeof it->position);
18701 it->object = make_number (0);
18702 it->c = it->char_to_display = ' ';
18703 it->len = 1;
18704 /* The last row's blank glyphs should get the default face, to
18705 avoid painting the rest of the window with the region face,
18706 if the region ends at ZV. */
18707 if (it->glyph_row->ends_at_zv_p)
18708 it->face_id = default_face->id;
18709 else
18710 it->face_id = face->id;
18711
18712 PRODUCE_GLYPHS (it);
18713
18714 while (it->current_x <= it->last_visible_x)
18715 PRODUCE_GLYPHS (it);
18716
18717 /* Don't count these blanks really. It would let us insert a left
18718 truncation glyph below and make us set the cursor on them, maybe. */
18719 it->current_x = saved_x;
18720 it->object = saved_object;
18721 it->position = saved_pos;
18722 it->what = saved_what;
18723 it->face_id = saved_face_id;
18724 }
18725 }
18726
18727
18728 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18729 trailing whitespace. */
18730
18731 static int
18732 trailing_whitespace_p (ptrdiff_t charpos)
18733 {
18734 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18735 int c = 0;
18736
18737 while (bytepos < ZV_BYTE
18738 && (c = FETCH_CHAR (bytepos),
18739 c == ' ' || c == '\t'))
18740 ++bytepos;
18741
18742 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18743 {
18744 if (bytepos != PT_BYTE)
18745 return 1;
18746 }
18747 return 0;
18748 }
18749
18750
18751 /* Highlight trailing whitespace, if any, in ROW. */
18752
18753 static void
18754 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18755 {
18756 int used = row->used[TEXT_AREA];
18757
18758 if (used)
18759 {
18760 struct glyph *start = row->glyphs[TEXT_AREA];
18761 struct glyph *glyph = start + used - 1;
18762
18763 if (row->reversed_p)
18764 {
18765 /* Right-to-left rows need to be processed in the opposite
18766 direction, so swap the edge pointers. */
18767 glyph = start;
18768 start = row->glyphs[TEXT_AREA] + used - 1;
18769 }
18770
18771 /* Skip over glyphs inserted to display the cursor at the
18772 end of a line, for extending the face of the last glyph
18773 to the end of the line on terminals, and for truncation
18774 and continuation glyphs. */
18775 if (!row->reversed_p)
18776 {
18777 while (glyph >= start
18778 && glyph->type == CHAR_GLYPH
18779 && INTEGERP (glyph->object))
18780 --glyph;
18781 }
18782 else
18783 {
18784 while (glyph <= start
18785 && glyph->type == CHAR_GLYPH
18786 && INTEGERP (glyph->object))
18787 ++glyph;
18788 }
18789
18790 /* If last glyph is a space or stretch, and it's trailing
18791 whitespace, set the face of all trailing whitespace glyphs in
18792 IT->glyph_row to `trailing-whitespace'. */
18793 if ((row->reversed_p ? glyph <= start : glyph >= start)
18794 && BUFFERP (glyph->object)
18795 && (glyph->type == STRETCH_GLYPH
18796 || (glyph->type == CHAR_GLYPH
18797 && glyph->u.ch == ' '))
18798 && trailing_whitespace_p (glyph->charpos))
18799 {
18800 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18801 if (face_id < 0)
18802 return;
18803
18804 if (!row->reversed_p)
18805 {
18806 while (glyph >= start
18807 && BUFFERP (glyph->object)
18808 && (glyph->type == STRETCH_GLYPH
18809 || (glyph->type == CHAR_GLYPH
18810 && glyph->u.ch == ' ')))
18811 (glyph--)->face_id = face_id;
18812 }
18813 else
18814 {
18815 while (glyph <= start
18816 && BUFFERP (glyph->object)
18817 && (glyph->type == STRETCH_GLYPH
18818 || (glyph->type == CHAR_GLYPH
18819 && glyph->u.ch == ' ')))
18820 (glyph++)->face_id = face_id;
18821 }
18822 }
18823 }
18824 }
18825
18826
18827 /* Value is non-zero if glyph row ROW should be
18828 considered to hold the buffer position CHARPOS. */
18829
18830 static int
18831 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18832 {
18833 int result = 1;
18834
18835 if (charpos == CHARPOS (row->end.pos)
18836 || charpos == MATRIX_ROW_END_CHARPOS (row))
18837 {
18838 /* Suppose the row ends on a string.
18839 Unless the row is continued, that means it ends on a newline
18840 in the string. If it's anything other than a display string
18841 (e.g., a before-string from an overlay), we don't want the
18842 cursor there. (This heuristic seems to give the optimal
18843 behavior for the various types of multi-line strings.)
18844 One exception: if the string has `cursor' property on one of
18845 its characters, we _do_ want the cursor there. */
18846 if (CHARPOS (row->end.string_pos) >= 0)
18847 {
18848 if (row->continued_p)
18849 result = 1;
18850 else
18851 {
18852 /* Check for `display' property. */
18853 struct glyph *beg = row->glyphs[TEXT_AREA];
18854 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18855 struct glyph *glyph;
18856
18857 result = 0;
18858 for (glyph = end; glyph >= beg; --glyph)
18859 if (STRINGP (glyph->object))
18860 {
18861 Lisp_Object prop
18862 = Fget_char_property (make_number (charpos),
18863 Qdisplay, Qnil);
18864 result =
18865 (!NILP (prop)
18866 && display_prop_string_p (prop, glyph->object));
18867 /* If there's a `cursor' property on one of the
18868 string's characters, this row is a cursor row,
18869 even though this is not a display string. */
18870 if (!result)
18871 {
18872 Lisp_Object s = glyph->object;
18873
18874 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18875 {
18876 ptrdiff_t gpos = glyph->charpos;
18877
18878 if (!NILP (Fget_char_property (make_number (gpos),
18879 Qcursor, s)))
18880 {
18881 result = 1;
18882 break;
18883 }
18884 }
18885 }
18886 break;
18887 }
18888 }
18889 }
18890 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18891 {
18892 /* If the row ends in middle of a real character,
18893 and the line is continued, we want the cursor here.
18894 That's because CHARPOS (ROW->end.pos) would equal
18895 PT if PT is before the character. */
18896 if (!row->ends_in_ellipsis_p)
18897 result = row->continued_p;
18898 else
18899 /* If the row ends in an ellipsis, then
18900 CHARPOS (ROW->end.pos) will equal point after the
18901 invisible text. We want that position to be displayed
18902 after the ellipsis. */
18903 result = 0;
18904 }
18905 /* If the row ends at ZV, display the cursor at the end of that
18906 row instead of at the start of the row below. */
18907 else if (row->ends_at_zv_p)
18908 result = 1;
18909 else
18910 result = 0;
18911 }
18912
18913 return result;
18914 }
18915
18916 /* Value is non-zero if glyph row ROW should be
18917 used to hold the cursor. */
18918
18919 static int
18920 cursor_row_p (struct glyph_row *row)
18921 {
18922 return row_for_charpos_p (row, PT);
18923 }
18924
18925 \f
18926
18927 /* Push the property PROP so that it will be rendered at the current
18928 position in IT. Return 1 if PROP was successfully pushed, 0
18929 otherwise. Called from handle_line_prefix to handle the
18930 `line-prefix' and `wrap-prefix' properties. */
18931
18932 static int
18933 push_prefix_prop (struct it *it, Lisp_Object prop)
18934 {
18935 struct text_pos pos =
18936 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18937
18938 eassert (it->method == GET_FROM_BUFFER
18939 || it->method == GET_FROM_DISPLAY_VECTOR
18940 || it->method == GET_FROM_STRING);
18941
18942 /* We need to save the current buffer/string position, so it will be
18943 restored by pop_it, because iterate_out_of_display_property
18944 depends on that being set correctly, but some situations leave
18945 it->position not yet set when this function is called. */
18946 push_it (it, &pos);
18947
18948 if (STRINGP (prop))
18949 {
18950 if (SCHARS (prop) == 0)
18951 {
18952 pop_it (it);
18953 return 0;
18954 }
18955
18956 it->string = prop;
18957 it->string_from_prefix_prop_p = 1;
18958 it->multibyte_p = STRING_MULTIBYTE (it->string);
18959 it->current.overlay_string_index = -1;
18960 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18961 it->end_charpos = it->string_nchars = SCHARS (it->string);
18962 it->method = GET_FROM_STRING;
18963 it->stop_charpos = 0;
18964 it->prev_stop = 0;
18965 it->base_level_stop = 0;
18966
18967 /* Force paragraph direction to be that of the parent
18968 buffer/string. */
18969 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18970 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18971 else
18972 it->paragraph_embedding = L2R;
18973
18974 /* Set up the bidi iterator for this display string. */
18975 if (it->bidi_p)
18976 {
18977 it->bidi_it.string.lstring = it->string;
18978 it->bidi_it.string.s = NULL;
18979 it->bidi_it.string.schars = it->end_charpos;
18980 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18981 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18982 it->bidi_it.string.unibyte = !it->multibyte_p;
18983 it->bidi_it.w = it->w;
18984 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18985 }
18986 }
18987 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18988 {
18989 it->method = GET_FROM_STRETCH;
18990 it->object = prop;
18991 }
18992 #ifdef HAVE_WINDOW_SYSTEM
18993 else if (IMAGEP (prop))
18994 {
18995 it->what = IT_IMAGE;
18996 it->image_id = lookup_image (it->f, prop);
18997 it->method = GET_FROM_IMAGE;
18998 }
18999 #endif /* HAVE_WINDOW_SYSTEM */
19000 else
19001 {
19002 pop_it (it); /* bogus display property, give up */
19003 return 0;
19004 }
19005
19006 return 1;
19007 }
19008
19009 /* Return the character-property PROP at the current position in IT. */
19010
19011 static Lisp_Object
19012 get_it_property (struct it *it, Lisp_Object prop)
19013 {
19014 Lisp_Object position, object = it->object;
19015
19016 if (STRINGP (object))
19017 position = make_number (IT_STRING_CHARPOS (*it));
19018 else if (BUFFERP (object))
19019 {
19020 position = make_number (IT_CHARPOS (*it));
19021 object = it->window;
19022 }
19023 else
19024 return Qnil;
19025
19026 return Fget_char_property (position, prop, object);
19027 }
19028
19029 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19030
19031 static void
19032 handle_line_prefix (struct it *it)
19033 {
19034 Lisp_Object prefix;
19035
19036 if (it->continuation_lines_width > 0)
19037 {
19038 prefix = get_it_property (it, Qwrap_prefix);
19039 if (NILP (prefix))
19040 prefix = Vwrap_prefix;
19041 }
19042 else
19043 {
19044 prefix = get_it_property (it, Qline_prefix);
19045 if (NILP (prefix))
19046 prefix = Vline_prefix;
19047 }
19048 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19049 {
19050 /* If the prefix is wider than the window, and we try to wrap
19051 it, it would acquire its own wrap prefix, and so on till the
19052 iterator stack overflows. So, don't wrap the prefix. */
19053 it->line_wrap = TRUNCATE;
19054 it->avoid_cursor_p = 1;
19055 }
19056 }
19057
19058 \f
19059
19060 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19061 only for R2L lines from display_line and display_string, when they
19062 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19063 the line/string needs to be continued on the next glyph row. */
19064 static void
19065 unproduce_glyphs (struct it *it, int n)
19066 {
19067 struct glyph *glyph, *end;
19068
19069 eassert (it->glyph_row);
19070 eassert (it->glyph_row->reversed_p);
19071 eassert (it->area == TEXT_AREA);
19072 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19073
19074 if (n > it->glyph_row->used[TEXT_AREA])
19075 n = it->glyph_row->used[TEXT_AREA];
19076 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19077 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19078 for ( ; glyph < end; glyph++)
19079 glyph[-n] = *glyph;
19080 }
19081
19082 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19083 and ROW->maxpos. */
19084 static void
19085 find_row_edges (struct it *it, struct glyph_row *row,
19086 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19087 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19088 {
19089 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19090 lines' rows is implemented for bidi-reordered rows. */
19091
19092 /* ROW->minpos is the value of min_pos, the minimal buffer position
19093 we have in ROW, or ROW->start.pos if that is smaller. */
19094 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19095 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19096 else
19097 /* We didn't find buffer positions smaller than ROW->start, or
19098 didn't find _any_ valid buffer positions in any of the glyphs,
19099 so we must trust the iterator's computed positions. */
19100 row->minpos = row->start.pos;
19101 if (max_pos <= 0)
19102 {
19103 max_pos = CHARPOS (it->current.pos);
19104 max_bpos = BYTEPOS (it->current.pos);
19105 }
19106
19107 /* Here are the various use-cases for ending the row, and the
19108 corresponding values for ROW->maxpos:
19109
19110 Line ends in a newline from buffer eol_pos + 1
19111 Line is continued from buffer max_pos + 1
19112 Line is truncated on right it->current.pos
19113 Line ends in a newline from string max_pos + 1(*)
19114 (*) + 1 only when line ends in a forward scan
19115 Line is continued from string max_pos
19116 Line is continued from display vector max_pos
19117 Line is entirely from a string min_pos == max_pos
19118 Line is entirely from a display vector min_pos == max_pos
19119 Line that ends at ZV ZV
19120
19121 If you discover other use-cases, please add them here as
19122 appropriate. */
19123 if (row->ends_at_zv_p)
19124 row->maxpos = it->current.pos;
19125 else if (row->used[TEXT_AREA])
19126 {
19127 int seen_this_string = 0;
19128 struct glyph_row *r1 = row - 1;
19129
19130 /* Did we see the same display string on the previous row? */
19131 if (STRINGP (it->object)
19132 /* this is not the first row */
19133 && row > it->w->desired_matrix->rows
19134 /* previous row is not the header line */
19135 && !r1->mode_line_p
19136 /* previous row also ends in a newline from a string */
19137 && r1->ends_in_newline_from_string_p)
19138 {
19139 struct glyph *start, *end;
19140
19141 /* Search for the last glyph of the previous row that came
19142 from buffer or string. Depending on whether the row is
19143 L2R or R2L, we need to process it front to back or the
19144 other way round. */
19145 if (!r1->reversed_p)
19146 {
19147 start = r1->glyphs[TEXT_AREA];
19148 end = start + r1->used[TEXT_AREA];
19149 /* Glyphs inserted by redisplay have an integer (zero)
19150 as their object. */
19151 while (end > start
19152 && INTEGERP ((end - 1)->object)
19153 && (end - 1)->charpos <= 0)
19154 --end;
19155 if (end > start)
19156 {
19157 if (EQ ((end - 1)->object, it->object))
19158 seen_this_string = 1;
19159 }
19160 else
19161 /* If all the glyphs of the previous row were inserted
19162 by redisplay, it means the previous row was
19163 produced from a single newline, which is only
19164 possible if that newline came from the same string
19165 as the one which produced this ROW. */
19166 seen_this_string = 1;
19167 }
19168 else
19169 {
19170 end = r1->glyphs[TEXT_AREA] - 1;
19171 start = end + r1->used[TEXT_AREA];
19172 while (end < start
19173 && INTEGERP ((end + 1)->object)
19174 && (end + 1)->charpos <= 0)
19175 ++end;
19176 if (end < start)
19177 {
19178 if (EQ ((end + 1)->object, it->object))
19179 seen_this_string = 1;
19180 }
19181 else
19182 seen_this_string = 1;
19183 }
19184 }
19185 /* Take note of each display string that covers a newline only
19186 once, the first time we see it. This is for when a display
19187 string includes more than one newline in it. */
19188 if (row->ends_in_newline_from_string_p && !seen_this_string)
19189 {
19190 /* If we were scanning the buffer forward when we displayed
19191 the string, we want to account for at least one buffer
19192 position that belongs to this row (position covered by
19193 the display string), so that cursor positioning will
19194 consider this row as a candidate when point is at the end
19195 of the visual line represented by this row. This is not
19196 required when scanning back, because max_pos will already
19197 have a much larger value. */
19198 if (CHARPOS (row->end.pos) > max_pos)
19199 INC_BOTH (max_pos, max_bpos);
19200 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19201 }
19202 else if (CHARPOS (it->eol_pos) > 0)
19203 SET_TEXT_POS (row->maxpos,
19204 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19205 else if (row->continued_p)
19206 {
19207 /* If max_pos is different from IT's current position, it
19208 means IT->method does not belong to the display element
19209 at max_pos. However, it also means that the display
19210 element at max_pos was displayed in its entirety on this
19211 line, which is equivalent to saying that the next line
19212 starts at the next buffer position. */
19213 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19214 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19215 else
19216 {
19217 INC_BOTH (max_pos, max_bpos);
19218 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19219 }
19220 }
19221 else if (row->truncated_on_right_p)
19222 /* display_line already called reseat_at_next_visible_line_start,
19223 which puts the iterator at the beginning of the next line, in
19224 the logical order. */
19225 row->maxpos = it->current.pos;
19226 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19227 /* A line that is entirely from a string/image/stretch... */
19228 row->maxpos = row->minpos;
19229 else
19230 emacs_abort ();
19231 }
19232 else
19233 row->maxpos = it->current.pos;
19234 }
19235
19236 /* Construct the glyph row IT->glyph_row in the desired matrix of
19237 IT->w from text at the current position of IT. See dispextern.h
19238 for an overview of struct it. Value is non-zero if
19239 IT->glyph_row displays text, as opposed to a line displaying ZV
19240 only. */
19241
19242 static int
19243 display_line (struct it *it)
19244 {
19245 struct glyph_row *row = it->glyph_row;
19246 Lisp_Object overlay_arrow_string;
19247 struct it wrap_it;
19248 void *wrap_data = NULL;
19249 int may_wrap = 0, wrap_x IF_LINT (= 0);
19250 int wrap_row_used = -1;
19251 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19252 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19253 int wrap_row_extra_line_spacing IF_LINT (= 0);
19254 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19255 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19256 int cvpos;
19257 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19258 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19259
19260 /* We always start displaying at hpos zero even if hscrolled. */
19261 eassert (it->hpos == 0 && it->current_x == 0);
19262
19263 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19264 >= it->w->desired_matrix->nrows)
19265 {
19266 it->w->nrows_scale_factor++;
19267 it->f->fonts_changed = 1;
19268 return 0;
19269 }
19270
19271 /* Is IT->w showing the region? */
19272 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19273
19274 /* Clear the result glyph row and enable it. */
19275 prepare_desired_row (row);
19276
19277 row->y = it->current_y;
19278 row->start = it->start;
19279 row->continuation_lines_width = it->continuation_lines_width;
19280 row->displays_text_p = 1;
19281 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19282 it->starts_in_middle_of_char_p = 0;
19283
19284 /* Arrange the overlays nicely for our purposes. Usually, we call
19285 display_line on only one line at a time, in which case this
19286 can't really hurt too much, or we call it on lines which appear
19287 one after another in the buffer, in which case all calls to
19288 recenter_overlay_lists but the first will be pretty cheap. */
19289 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19290
19291 /* Move over display elements that are not visible because we are
19292 hscrolled. This may stop at an x-position < IT->first_visible_x
19293 if the first glyph is partially visible or if we hit a line end. */
19294 if (it->current_x < it->first_visible_x)
19295 {
19296 enum move_it_result move_result;
19297
19298 this_line_min_pos = row->start.pos;
19299 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19300 MOVE_TO_POS | MOVE_TO_X);
19301 /* If we are under a large hscroll, move_it_in_display_line_to
19302 could hit the end of the line without reaching
19303 it->first_visible_x. Pretend that we did reach it. This is
19304 especially important on a TTY, where we will call
19305 extend_face_to_end_of_line, which needs to know how many
19306 blank glyphs to produce. */
19307 if (it->current_x < it->first_visible_x
19308 && (move_result == MOVE_NEWLINE_OR_CR
19309 || move_result == MOVE_POS_MATCH_OR_ZV))
19310 it->current_x = it->first_visible_x;
19311
19312 /* Record the smallest positions seen while we moved over
19313 display elements that are not visible. This is needed by
19314 redisplay_internal for optimizing the case where the cursor
19315 stays inside the same line. The rest of this function only
19316 considers positions that are actually displayed, so
19317 RECORD_MAX_MIN_POS will not otherwise record positions that
19318 are hscrolled to the left of the left edge of the window. */
19319 min_pos = CHARPOS (this_line_min_pos);
19320 min_bpos = BYTEPOS (this_line_min_pos);
19321 }
19322 else
19323 {
19324 /* We only do this when not calling `move_it_in_display_line_to'
19325 above, because move_it_in_display_line_to calls
19326 handle_line_prefix itself. */
19327 handle_line_prefix (it);
19328 }
19329
19330 /* Get the initial row height. This is either the height of the
19331 text hscrolled, if there is any, or zero. */
19332 row->ascent = it->max_ascent;
19333 row->height = it->max_ascent + it->max_descent;
19334 row->phys_ascent = it->max_phys_ascent;
19335 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19336 row->extra_line_spacing = it->max_extra_line_spacing;
19337
19338 /* Utility macro to record max and min buffer positions seen until now. */
19339 #define RECORD_MAX_MIN_POS(IT) \
19340 do \
19341 { \
19342 int composition_p = !STRINGP ((IT)->string) \
19343 && ((IT)->what == IT_COMPOSITION); \
19344 ptrdiff_t current_pos = \
19345 composition_p ? (IT)->cmp_it.charpos \
19346 : IT_CHARPOS (*(IT)); \
19347 ptrdiff_t current_bpos = \
19348 composition_p ? CHAR_TO_BYTE (current_pos) \
19349 : IT_BYTEPOS (*(IT)); \
19350 if (current_pos < min_pos) \
19351 { \
19352 min_pos = current_pos; \
19353 min_bpos = current_bpos; \
19354 } \
19355 if (IT_CHARPOS (*it) > max_pos) \
19356 { \
19357 max_pos = IT_CHARPOS (*it); \
19358 max_bpos = IT_BYTEPOS (*it); \
19359 } \
19360 } \
19361 while (0)
19362
19363 /* Loop generating characters. The loop is left with IT on the next
19364 character to display. */
19365 while (1)
19366 {
19367 int n_glyphs_before, hpos_before, x_before;
19368 int x, nglyphs;
19369 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19370
19371 /* Retrieve the next thing to display. Value is zero if end of
19372 buffer reached. */
19373 if (!get_next_display_element (it))
19374 {
19375 /* Maybe add a space at the end of this line that is used to
19376 display the cursor there under X. Set the charpos of the
19377 first glyph of blank lines not corresponding to any text
19378 to -1. */
19379 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19380 row->exact_window_width_line_p = 1;
19381 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19382 || row->used[TEXT_AREA] == 0)
19383 {
19384 row->glyphs[TEXT_AREA]->charpos = -1;
19385 row->displays_text_p = 0;
19386
19387 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19388 && (!MINI_WINDOW_P (it->w)
19389 || (minibuf_level && EQ (it->window, minibuf_window))))
19390 row->indicate_empty_line_p = 1;
19391 }
19392
19393 it->continuation_lines_width = 0;
19394 row->ends_at_zv_p = 1;
19395 /* A row that displays right-to-left text must always have
19396 its last face extended all the way to the end of line,
19397 even if this row ends in ZV, because we still write to
19398 the screen left to right. We also need to extend the
19399 last face if the default face is remapped to some
19400 different face, otherwise the functions that clear
19401 portions of the screen will clear with the default face's
19402 background color. */
19403 if (row->reversed_p
19404 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19405 extend_face_to_end_of_line (it);
19406 break;
19407 }
19408
19409 /* Now, get the metrics of what we want to display. This also
19410 generates glyphs in `row' (which is IT->glyph_row). */
19411 n_glyphs_before = row->used[TEXT_AREA];
19412 x = it->current_x;
19413
19414 /* Remember the line height so far in case the next element doesn't
19415 fit on the line. */
19416 if (it->line_wrap != TRUNCATE)
19417 {
19418 ascent = it->max_ascent;
19419 descent = it->max_descent;
19420 phys_ascent = it->max_phys_ascent;
19421 phys_descent = it->max_phys_descent;
19422
19423 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19424 {
19425 if (IT_DISPLAYING_WHITESPACE (it))
19426 may_wrap = 1;
19427 else if (may_wrap)
19428 {
19429 SAVE_IT (wrap_it, *it, wrap_data);
19430 wrap_x = x;
19431 wrap_row_used = row->used[TEXT_AREA];
19432 wrap_row_ascent = row->ascent;
19433 wrap_row_height = row->height;
19434 wrap_row_phys_ascent = row->phys_ascent;
19435 wrap_row_phys_height = row->phys_height;
19436 wrap_row_extra_line_spacing = row->extra_line_spacing;
19437 wrap_row_min_pos = min_pos;
19438 wrap_row_min_bpos = min_bpos;
19439 wrap_row_max_pos = max_pos;
19440 wrap_row_max_bpos = max_bpos;
19441 may_wrap = 0;
19442 }
19443 }
19444 }
19445
19446 PRODUCE_GLYPHS (it);
19447
19448 /* If this display element was in marginal areas, continue with
19449 the next one. */
19450 if (it->area != TEXT_AREA)
19451 {
19452 row->ascent = max (row->ascent, it->max_ascent);
19453 row->height = max (row->height, it->max_ascent + it->max_descent);
19454 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19455 row->phys_height = max (row->phys_height,
19456 it->max_phys_ascent + it->max_phys_descent);
19457 row->extra_line_spacing = max (row->extra_line_spacing,
19458 it->max_extra_line_spacing);
19459 set_iterator_to_next (it, 1);
19460 continue;
19461 }
19462
19463 /* Does the display element fit on the line? If we truncate
19464 lines, we should draw past the right edge of the window. If
19465 we don't truncate, we want to stop so that we can display the
19466 continuation glyph before the right margin. If lines are
19467 continued, there are two possible strategies for characters
19468 resulting in more than 1 glyph (e.g. tabs): Display as many
19469 glyphs as possible in this line and leave the rest for the
19470 continuation line, or display the whole element in the next
19471 line. Original redisplay did the former, so we do it also. */
19472 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19473 hpos_before = it->hpos;
19474 x_before = x;
19475
19476 if (/* Not a newline. */
19477 nglyphs > 0
19478 /* Glyphs produced fit entirely in the line. */
19479 && it->current_x < it->last_visible_x)
19480 {
19481 it->hpos += nglyphs;
19482 row->ascent = max (row->ascent, it->max_ascent);
19483 row->height = max (row->height, it->max_ascent + it->max_descent);
19484 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19485 row->phys_height = max (row->phys_height,
19486 it->max_phys_ascent + it->max_phys_descent);
19487 row->extra_line_spacing = max (row->extra_line_spacing,
19488 it->max_extra_line_spacing);
19489 if (it->current_x - it->pixel_width < it->first_visible_x)
19490 row->x = x - it->first_visible_x;
19491 /* Record the maximum and minimum buffer positions seen so
19492 far in glyphs that will be displayed by this row. */
19493 if (it->bidi_p)
19494 RECORD_MAX_MIN_POS (it);
19495 }
19496 else
19497 {
19498 int i, new_x;
19499 struct glyph *glyph;
19500
19501 for (i = 0; i < nglyphs; ++i, x = new_x)
19502 {
19503 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19504 new_x = x + glyph->pixel_width;
19505
19506 if (/* Lines are continued. */
19507 it->line_wrap != TRUNCATE
19508 && (/* Glyph doesn't fit on the line. */
19509 new_x > it->last_visible_x
19510 /* Or it fits exactly on a window system frame. */
19511 || (new_x == it->last_visible_x
19512 && FRAME_WINDOW_P (it->f)
19513 && (row->reversed_p
19514 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19515 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19516 {
19517 /* End of a continued line. */
19518
19519 if (it->hpos == 0
19520 || (new_x == it->last_visible_x
19521 && FRAME_WINDOW_P (it->f)
19522 && (row->reversed_p
19523 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19524 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19525 {
19526 /* Current glyph is the only one on the line or
19527 fits exactly on the line. We must continue
19528 the line because we can't draw the cursor
19529 after the glyph. */
19530 row->continued_p = 1;
19531 it->current_x = new_x;
19532 it->continuation_lines_width += new_x;
19533 ++it->hpos;
19534 if (i == nglyphs - 1)
19535 {
19536 /* If line-wrap is on, check if a previous
19537 wrap point was found. */
19538 if (wrap_row_used > 0
19539 /* Even if there is a previous wrap
19540 point, continue the line here as
19541 usual, if (i) the previous character
19542 was a space or tab AND (ii) the
19543 current character is not. */
19544 && (!may_wrap
19545 || IT_DISPLAYING_WHITESPACE (it)))
19546 goto back_to_wrap;
19547
19548 /* Record the maximum and minimum buffer
19549 positions seen so far in glyphs that will be
19550 displayed by this row. */
19551 if (it->bidi_p)
19552 RECORD_MAX_MIN_POS (it);
19553 set_iterator_to_next (it, 1);
19554 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19555 {
19556 if (!get_next_display_element (it))
19557 {
19558 row->exact_window_width_line_p = 1;
19559 it->continuation_lines_width = 0;
19560 row->continued_p = 0;
19561 row->ends_at_zv_p = 1;
19562 }
19563 else if (ITERATOR_AT_END_OF_LINE_P (it))
19564 {
19565 row->continued_p = 0;
19566 row->exact_window_width_line_p = 1;
19567 }
19568 }
19569 }
19570 else if (it->bidi_p)
19571 RECORD_MAX_MIN_POS (it);
19572 }
19573 else if (CHAR_GLYPH_PADDING_P (*glyph)
19574 && !FRAME_WINDOW_P (it->f))
19575 {
19576 /* A padding glyph that doesn't fit on this line.
19577 This means the whole character doesn't fit
19578 on the line. */
19579 if (row->reversed_p)
19580 unproduce_glyphs (it, row->used[TEXT_AREA]
19581 - n_glyphs_before);
19582 row->used[TEXT_AREA] = n_glyphs_before;
19583
19584 /* Fill the rest of the row with continuation
19585 glyphs like in 20.x. */
19586 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19587 < row->glyphs[1 + TEXT_AREA])
19588 produce_special_glyphs (it, IT_CONTINUATION);
19589
19590 row->continued_p = 1;
19591 it->current_x = x_before;
19592 it->continuation_lines_width += x_before;
19593
19594 /* Restore the height to what it was before the
19595 element not fitting on the line. */
19596 it->max_ascent = ascent;
19597 it->max_descent = descent;
19598 it->max_phys_ascent = phys_ascent;
19599 it->max_phys_descent = phys_descent;
19600 }
19601 else if (wrap_row_used > 0)
19602 {
19603 back_to_wrap:
19604 if (row->reversed_p)
19605 unproduce_glyphs (it,
19606 row->used[TEXT_AREA] - wrap_row_used);
19607 RESTORE_IT (it, &wrap_it, wrap_data);
19608 it->continuation_lines_width += wrap_x;
19609 row->used[TEXT_AREA] = wrap_row_used;
19610 row->ascent = wrap_row_ascent;
19611 row->height = wrap_row_height;
19612 row->phys_ascent = wrap_row_phys_ascent;
19613 row->phys_height = wrap_row_phys_height;
19614 row->extra_line_spacing = wrap_row_extra_line_spacing;
19615 min_pos = wrap_row_min_pos;
19616 min_bpos = wrap_row_min_bpos;
19617 max_pos = wrap_row_max_pos;
19618 max_bpos = wrap_row_max_bpos;
19619 row->continued_p = 1;
19620 row->ends_at_zv_p = 0;
19621 row->exact_window_width_line_p = 0;
19622 it->continuation_lines_width += x;
19623
19624 /* Make sure that a non-default face is extended
19625 up to the right margin of the window. */
19626 extend_face_to_end_of_line (it);
19627 }
19628 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19629 {
19630 /* A TAB that extends past the right edge of the
19631 window. This produces a single glyph on
19632 window system frames. We leave the glyph in
19633 this row and let it fill the row, but don't
19634 consume the TAB. */
19635 if ((row->reversed_p
19636 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19637 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19638 produce_special_glyphs (it, IT_CONTINUATION);
19639 it->continuation_lines_width += it->last_visible_x;
19640 row->ends_in_middle_of_char_p = 1;
19641 row->continued_p = 1;
19642 glyph->pixel_width = it->last_visible_x - x;
19643 it->starts_in_middle_of_char_p = 1;
19644 }
19645 else
19646 {
19647 /* Something other than a TAB that draws past
19648 the right edge of the window. Restore
19649 positions to values before the element. */
19650 if (row->reversed_p)
19651 unproduce_glyphs (it, row->used[TEXT_AREA]
19652 - (n_glyphs_before + i));
19653 row->used[TEXT_AREA] = n_glyphs_before + i;
19654
19655 /* Display continuation glyphs. */
19656 it->current_x = x_before;
19657 it->continuation_lines_width += x;
19658 if (!FRAME_WINDOW_P (it->f)
19659 || (row->reversed_p
19660 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19661 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19662 produce_special_glyphs (it, IT_CONTINUATION);
19663 row->continued_p = 1;
19664
19665 extend_face_to_end_of_line (it);
19666
19667 if (nglyphs > 1 && i > 0)
19668 {
19669 row->ends_in_middle_of_char_p = 1;
19670 it->starts_in_middle_of_char_p = 1;
19671 }
19672
19673 /* Restore the height to what it was before the
19674 element not fitting on the line. */
19675 it->max_ascent = ascent;
19676 it->max_descent = descent;
19677 it->max_phys_ascent = phys_ascent;
19678 it->max_phys_descent = phys_descent;
19679 }
19680
19681 break;
19682 }
19683 else if (new_x > it->first_visible_x)
19684 {
19685 /* Increment number of glyphs actually displayed. */
19686 ++it->hpos;
19687
19688 /* Record the maximum and minimum buffer positions
19689 seen so far in glyphs that will be displayed by
19690 this row. */
19691 if (it->bidi_p)
19692 RECORD_MAX_MIN_POS (it);
19693
19694 if (x < it->first_visible_x)
19695 /* Glyph is partially visible, i.e. row starts at
19696 negative X position. */
19697 row->x = x - it->first_visible_x;
19698 }
19699 else
19700 {
19701 /* Glyph is completely off the left margin of the
19702 window. This should not happen because of the
19703 move_it_in_display_line at the start of this
19704 function, unless the text display area of the
19705 window is empty. */
19706 eassert (it->first_visible_x <= it->last_visible_x);
19707 }
19708 }
19709 /* Even if this display element produced no glyphs at all,
19710 we want to record its position. */
19711 if (it->bidi_p && nglyphs == 0)
19712 RECORD_MAX_MIN_POS (it);
19713
19714 row->ascent = max (row->ascent, it->max_ascent);
19715 row->height = max (row->height, it->max_ascent + it->max_descent);
19716 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19717 row->phys_height = max (row->phys_height,
19718 it->max_phys_ascent + it->max_phys_descent);
19719 row->extra_line_spacing = max (row->extra_line_spacing,
19720 it->max_extra_line_spacing);
19721
19722 /* End of this display line if row is continued. */
19723 if (row->continued_p || row->ends_at_zv_p)
19724 break;
19725 }
19726
19727 at_end_of_line:
19728 /* Is this a line end? If yes, we're also done, after making
19729 sure that a non-default face is extended up to the right
19730 margin of the window. */
19731 if (ITERATOR_AT_END_OF_LINE_P (it))
19732 {
19733 int used_before = row->used[TEXT_AREA];
19734
19735 row->ends_in_newline_from_string_p = STRINGP (it->object);
19736
19737 /* Add a space at the end of the line that is used to
19738 display the cursor there. */
19739 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19740 append_space_for_newline (it, 0);
19741
19742 /* Extend the face to the end of the line. */
19743 extend_face_to_end_of_line (it);
19744
19745 /* Make sure we have the position. */
19746 if (used_before == 0)
19747 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19748
19749 /* Record the position of the newline, for use in
19750 find_row_edges. */
19751 it->eol_pos = it->current.pos;
19752
19753 /* Consume the line end. This skips over invisible lines. */
19754 set_iterator_to_next (it, 1);
19755 it->continuation_lines_width = 0;
19756 break;
19757 }
19758
19759 /* Proceed with next display element. Note that this skips
19760 over lines invisible because of selective display. */
19761 set_iterator_to_next (it, 1);
19762
19763 /* If we truncate lines, we are done when the last displayed
19764 glyphs reach past the right margin of the window. */
19765 if (it->line_wrap == TRUNCATE
19766 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19767 ? (it->current_x >= it->last_visible_x)
19768 : (it->current_x > it->last_visible_x)))
19769 {
19770 /* Maybe add truncation glyphs. */
19771 if (!FRAME_WINDOW_P (it->f)
19772 || (row->reversed_p
19773 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19774 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19775 {
19776 int i, n;
19777
19778 if (!row->reversed_p)
19779 {
19780 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19781 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19782 break;
19783 }
19784 else
19785 {
19786 for (i = 0; i < row->used[TEXT_AREA]; i++)
19787 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19788 break;
19789 /* Remove any padding glyphs at the front of ROW, to
19790 make room for the truncation glyphs we will be
19791 adding below. The loop below always inserts at
19792 least one truncation glyph, so also remove the
19793 last glyph added to ROW. */
19794 unproduce_glyphs (it, i + 1);
19795 /* Adjust i for the loop below. */
19796 i = row->used[TEXT_AREA] - (i + 1);
19797 }
19798
19799 it->current_x = x_before;
19800 if (!FRAME_WINDOW_P (it->f))
19801 {
19802 for (n = row->used[TEXT_AREA]; i < n; ++i)
19803 {
19804 row->used[TEXT_AREA] = i;
19805 produce_special_glyphs (it, IT_TRUNCATION);
19806 }
19807 }
19808 else
19809 {
19810 row->used[TEXT_AREA] = i;
19811 produce_special_glyphs (it, IT_TRUNCATION);
19812 }
19813 }
19814 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19815 {
19816 /* Don't truncate if we can overflow newline into fringe. */
19817 if (!get_next_display_element (it))
19818 {
19819 it->continuation_lines_width = 0;
19820 row->ends_at_zv_p = 1;
19821 row->exact_window_width_line_p = 1;
19822 break;
19823 }
19824 if (ITERATOR_AT_END_OF_LINE_P (it))
19825 {
19826 row->exact_window_width_line_p = 1;
19827 goto at_end_of_line;
19828 }
19829 it->current_x = x_before;
19830 }
19831
19832 row->truncated_on_right_p = 1;
19833 it->continuation_lines_width = 0;
19834 reseat_at_next_visible_line_start (it, 0);
19835 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19836 it->hpos = hpos_before;
19837 break;
19838 }
19839 }
19840
19841 if (wrap_data)
19842 bidi_unshelve_cache (wrap_data, 1);
19843
19844 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19845 at the left window margin. */
19846 if (it->first_visible_x
19847 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19848 {
19849 if (!FRAME_WINDOW_P (it->f)
19850 || (row->reversed_p
19851 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19852 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19853 insert_left_trunc_glyphs (it);
19854 row->truncated_on_left_p = 1;
19855 }
19856
19857 /* Remember the position at which this line ends.
19858
19859 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19860 cannot be before the call to find_row_edges below, since that is
19861 where these positions are determined. */
19862 row->end = it->current;
19863 if (!it->bidi_p)
19864 {
19865 row->minpos = row->start.pos;
19866 row->maxpos = row->end.pos;
19867 }
19868 else
19869 {
19870 /* ROW->minpos and ROW->maxpos must be the smallest and
19871 `1 + the largest' buffer positions in ROW. But if ROW was
19872 bidi-reordered, these two positions can be anywhere in the
19873 row, so we must determine them now. */
19874 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19875 }
19876
19877 /* If the start of this line is the overlay arrow-position, then
19878 mark this glyph row as the one containing the overlay arrow.
19879 This is clearly a mess with variable size fonts. It would be
19880 better to let it be displayed like cursors under X. */
19881 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19882 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19883 !NILP (overlay_arrow_string)))
19884 {
19885 /* Overlay arrow in window redisplay is a fringe bitmap. */
19886 if (STRINGP (overlay_arrow_string))
19887 {
19888 struct glyph_row *arrow_row
19889 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19890 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19891 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19892 struct glyph *p = row->glyphs[TEXT_AREA];
19893 struct glyph *p2, *end;
19894
19895 /* Copy the arrow glyphs. */
19896 while (glyph < arrow_end)
19897 *p++ = *glyph++;
19898
19899 /* Throw away padding glyphs. */
19900 p2 = p;
19901 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19902 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19903 ++p2;
19904 if (p2 > p)
19905 {
19906 while (p2 < end)
19907 *p++ = *p2++;
19908 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19909 }
19910 }
19911 else
19912 {
19913 eassert (INTEGERP (overlay_arrow_string));
19914 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19915 }
19916 overlay_arrow_seen = 1;
19917 }
19918
19919 /* Highlight trailing whitespace. */
19920 if (!NILP (Vshow_trailing_whitespace))
19921 highlight_trailing_whitespace (it->f, it->glyph_row);
19922
19923 /* Compute pixel dimensions of this line. */
19924 compute_line_metrics (it);
19925
19926 /* Implementation note: No changes in the glyphs of ROW or in their
19927 faces can be done past this point, because compute_line_metrics
19928 computes ROW's hash value and stores it within the glyph_row
19929 structure. */
19930
19931 /* Record whether this row ends inside an ellipsis. */
19932 row->ends_in_ellipsis_p
19933 = (it->method == GET_FROM_DISPLAY_VECTOR
19934 && it->ellipsis_p);
19935
19936 /* Save fringe bitmaps in this row. */
19937 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19938 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19939 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19940 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19941
19942 it->left_user_fringe_bitmap = 0;
19943 it->left_user_fringe_face_id = 0;
19944 it->right_user_fringe_bitmap = 0;
19945 it->right_user_fringe_face_id = 0;
19946
19947 /* Maybe set the cursor. */
19948 cvpos = it->w->cursor.vpos;
19949 if ((cvpos < 0
19950 /* In bidi-reordered rows, keep checking for proper cursor
19951 position even if one has been found already, because buffer
19952 positions in such rows change non-linearly with ROW->VPOS,
19953 when a line is continued. One exception: when we are at ZV,
19954 display cursor on the first suitable glyph row, since all
19955 the empty rows after that also have their position set to ZV. */
19956 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19957 lines' rows is implemented for bidi-reordered rows. */
19958 || (it->bidi_p
19959 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19960 && PT >= MATRIX_ROW_START_CHARPOS (row)
19961 && PT <= MATRIX_ROW_END_CHARPOS (row)
19962 && cursor_row_p (row))
19963 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19964
19965 /* Prepare for the next line. This line starts horizontally at (X
19966 HPOS) = (0 0). Vertical positions are incremented. As a
19967 convenience for the caller, IT->glyph_row is set to the next
19968 row to be used. */
19969 it->current_x = it->hpos = 0;
19970 it->current_y += row->height;
19971 SET_TEXT_POS (it->eol_pos, 0, 0);
19972 ++it->vpos;
19973 ++it->glyph_row;
19974 /* The next row should by default use the same value of the
19975 reversed_p flag as this one. set_iterator_to_next decides when
19976 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19977 the flag accordingly. */
19978 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19979 it->glyph_row->reversed_p = row->reversed_p;
19980 it->start = row->end;
19981 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
19982
19983 #undef RECORD_MAX_MIN_POS
19984 }
19985
19986 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19987 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19988 doc: /* Return paragraph direction at point in BUFFER.
19989 Value is either `left-to-right' or `right-to-left'.
19990 If BUFFER is omitted or nil, it defaults to the current buffer.
19991
19992 Paragraph direction determines how the text in the paragraph is displayed.
19993 In left-to-right paragraphs, text begins at the left margin of the window
19994 and the reading direction is generally left to right. In right-to-left
19995 paragraphs, text begins at the right margin and is read from right to left.
19996
19997 See also `bidi-paragraph-direction'. */)
19998 (Lisp_Object buffer)
19999 {
20000 struct buffer *buf = current_buffer;
20001 struct buffer *old = buf;
20002
20003 if (! NILP (buffer))
20004 {
20005 CHECK_BUFFER (buffer);
20006 buf = XBUFFER (buffer);
20007 }
20008
20009 if (NILP (BVAR (buf, bidi_display_reordering))
20010 || NILP (BVAR (buf, enable_multibyte_characters))
20011 /* When we are loading loadup.el, the character property tables
20012 needed for bidi iteration are not yet available. */
20013 || !NILP (Vpurify_flag))
20014 return Qleft_to_right;
20015 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20016 return BVAR (buf, bidi_paragraph_direction);
20017 else
20018 {
20019 /* Determine the direction from buffer text. We could try to
20020 use current_matrix if it is up to date, but this seems fast
20021 enough as it is. */
20022 struct bidi_it itb;
20023 ptrdiff_t pos = BUF_PT (buf);
20024 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20025 int c;
20026 void *itb_data = bidi_shelve_cache ();
20027
20028 set_buffer_temp (buf);
20029 /* bidi_paragraph_init finds the base direction of the paragraph
20030 by searching forward from paragraph start. We need the base
20031 direction of the current or _previous_ paragraph, so we need
20032 to make sure we are within that paragraph. To that end, find
20033 the previous non-empty line. */
20034 if (pos >= ZV && pos > BEGV)
20035 DEC_BOTH (pos, bytepos);
20036 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20037 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20038 {
20039 while ((c = FETCH_BYTE (bytepos)) == '\n'
20040 || c == ' ' || c == '\t' || c == '\f')
20041 {
20042 if (bytepos <= BEGV_BYTE)
20043 break;
20044 bytepos--;
20045 pos--;
20046 }
20047 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20048 bytepos--;
20049 }
20050 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20051 itb.paragraph_dir = NEUTRAL_DIR;
20052 itb.string.s = NULL;
20053 itb.string.lstring = Qnil;
20054 itb.string.bufpos = 0;
20055 itb.string.unibyte = 0;
20056 /* We have no window to use here for ignoring window-specific
20057 overlays. Using NULL for window pointer will cause
20058 compute_display_string_pos to use the current buffer. */
20059 itb.w = NULL;
20060 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20061 bidi_unshelve_cache (itb_data, 0);
20062 set_buffer_temp (old);
20063 switch (itb.paragraph_dir)
20064 {
20065 case L2R:
20066 return Qleft_to_right;
20067 break;
20068 case R2L:
20069 return Qright_to_left;
20070 break;
20071 default:
20072 emacs_abort ();
20073 }
20074 }
20075 }
20076
20077 DEFUN ("move-point-visually", Fmove_point_visually,
20078 Smove_point_visually, 1, 1, 0,
20079 doc: /* Move point in the visual order in the specified DIRECTION.
20080 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20081 left.
20082
20083 Value is the new character position of point. */)
20084 (Lisp_Object direction)
20085 {
20086 struct window *w = XWINDOW (selected_window);
20087 struct buffer *b = XBUFFER (w->contents);
20088 struct glyph_row *row;
20089 int dir;
20090 Lisp_Object paragraph_dir;
20091
20092 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20093 (!(ROW)->continued_p \
20094 && INTEGERP ((GLYPH)->object) \
20095 && (GLYPH)->type == CHAR_GLYPH \
20096 && (GLYPH)->u.ch == ' ' \
20097 && (GLYPH)->charpos >= 0 \
20098 && !(GLYPH)->avoid_cursor_p)
20099
20100 CHECK_NUMBER (direction);
20101 dir = XINT (direction);
20102 if (dir > 0)
20103 dir = 1;
20104 else
20105 dir = -1;
20106
20107 /* If current matrix is up-to-date, we can use the information
20108 recorded in the glyphs, at least as long as the goal is on the
20109 screen. */
20110 if (w->window_end_valid
20111 && !windows_or_buffers_changed
20112 && b
20113 && !b->clip_changed
20114 && !b->prevent_redisplay_optimizations_p
20115 && !window_outdated (w)
20116 && w->cursor.vpos >= 0
20117 && w->cursor.vpos < w->current_matrix->nrows
20118 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20119 {
20120 struct glyph *g = row->glyphs[TEXT_AREA];
20121 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20122 struct glyph *gpt = g + w->cursor.hpos;
20123
20124 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20125 {
20126 if (BUFFERP (g->object) && g->charpos != PT)
20127 {
20128 SET_PT (g->charpos);
20129 w->cursor.vpos = -1;
20130 return make_number (PT);
20131 }
20132 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20133 {
20134 ptrdiff_t new_pos;
20135
20136 if (BUFFERP (gpt->object))
20137 {
20138 new_pos = PT;
20139 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20140 new_pos += (row->reversed_p ? -dir : dir);
20141 else
20142 new_pos -= (row->reversed_p ? -dir : dir);;
20143 }
20144 else if (BUFFERP (g->object))
20145 new_pos = g->charpos;
20146 else
20147 break;
20148 SET_PT (new_pos);
20149 w->cursor.vpos = -1;
20150 return make_number (PT);
20151 }
20152 else if (ROW_GLYPH_NEWLINE_P (row, g))
20153 {
20154 /* Glyphs inserted at the end of a non-empty line for
20155 positioning the cursor have zero charpos, so we must
20156 deduce the value of point by other means. */
20157 if (g->charpos > 0)
20158 SET_PT (g->charpos);
20159 else if (row->ends_at_zv_p && PT != ZV)
20160 SET_PT (ZV);
20161 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20162 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20163 else
20164 break;
20165 w->cursor.vpos = -1;
20166 return make_number (PT);
20167 }
20168 }
20169 if (g == e || INTEGERP (g->object))
20170 {
20171 if (row->truncated_on_left_p || row->truncated_on_right_p)
20172 goto simulate_display;
20173 if (!row->reversed_p)
20174 row += dir;
20175 else
20176 row -= dir;
20177 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20178 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20179 goto simulate_display;
20180
20181 if (dir > 0)
20182 {
20183 if (row->reversed_p && !row->continued_p)
20184 {
20185 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20186 w->cursor.vpos = -1;
20187 return make_number (PT);
20188 }
20189 g = row->glyphs[TEXT_AREA];
20190 e = g + row->used[TEXT_AREA];
20191 for ( ; g < e; g++)
20192 {
20193 if (BUFFERP (g->object)
20194 /* Empty lines have only one glyph, which stands
20195 for the newline, and whose charpos is the
20196 buffer position of the newline. */
20197 || ROW_GLYPH_NEWLINE_P (row, g)
20198 /* When the buffer ends in a newline, the line at
20199 EOB also has one glyph, but its charpos is -1. */
20200 || (row->ends_at_zv_p
20201 && !row->reversed_p
20202 && INTEGERP (g->object)
20203 && g->type == CHAR_GLYPH
20204 && g->u.ch == ' '))
20205 {
20206 if (g->charpos > 0)
20207 SET_PT (g->charpos);
20208 else if (!row->reversed_p
20209 && row->ends_at_zv_p
20210 && PT != ZV)
20211 SET_PT (ZV);
20212 else
20213 continue;
20214 w->cursor.vpos = -1;
20215 return make_number (PT);
20216 }
20217 }
20218 }
20219 else
20220 {
20221 if (!row->reversed_p && !row->continued_p)
20222 {
20223 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20224 w->cursor.vpos = -1;
20225 return make_number (PT);
20226 }
20227 e = row->glyphs[TEXT_AREA];
20228 g = e + row->used[TEXT_AREA] - 1;
20229 for ( ; g >= e; g--)
20230 {
20231 if (BUFFERP (g->object)
20232 || (ROW_GLYPH_NEWLINE_P (row, g)
20233 && g->charpos > 0)
20234 /* Empty R2L lines on GUI frames have the buffer
20235 position of the newline stored in the stretch
20236 glyph. */
20237 || g->type == STRETCH_GLYPH
20238 || (row->ends_at_zv_p
20239 && row->reversed_p
20240 && INTEGERP (g->object)
20241 && g->type == CHAR_GLYPH
20242 && g->u.ch == ' '))
20243 {
20244 if (g->charpos > 0)
20245 SET_PT (g->charpos);
20246 else if (row->reversed_p
20247 && row->ends_at_zv_p
20248 && PT != ZV)
20249 SET_PT (ZV);
20250 else
20251 continue;
20252 w->cursor.vpos = -1;
20253 return make_number (PT);
20254 }
20255 }
20256 }
20257 }
20258 }
20259
20260 simulate_display:
20261
20262 /* If we wind up here, we failed to move by using the glyphs, so we
20263 need to simulate display instead. */
20264
20265 if (b)
20266 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
20267 else
20268 paragraph_dir = Qleft_to_right;
20269 if (EQ (paragraph_dir, Qright_to_left))
20270 dir = -dir;
20271 if (PT <= BEGV && dir < 0)
20272 xsignal0 (Qbeginning_of_buffer);
20273 else if (PT >= ZV && dir > 0)
20274 xsignal0 (Qend_of_buffer);
20275 else
20276 {
20277 struct text_pos pt;
20278 struct it it;
20279 int pt_x, target_x, pixel_width, pt_vpos;
20280 bool at_eol_p;
20281 bool overshoot_expected = false;
20282 bool target_is_eol_p = false;
20283
20284 /* Setup the arena. */
20285 SET_TEXT_POS (pt, PT, PT_BYTE);
20286 start_display (&it, w, pt);
20287
20288 if (it.cmp_it.id < 0
20289 && it.method == GET_FROM_STRING
20290 && it.area == TEXT_AREA
20291 && it.string_from_display_prop_p
20292 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
20293 overshoot_expected = true;
20294
20295 /* Find the X coordinate of point. We start from the beginning
20296 of this or previous line to make sure we are before point in
20297 the logical order (since the move_it_* functions can only
20298 move forward). */
20299 reseat_at_previous_visible_line_start (&it);
20300 it.current_x = it.hpos = it.current_y = it.vpos = 0;
20301 if (IT_CHARPOS (it) != PT)
20302 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
20303 -1, -1, -1, MOVE_TO_POS);
20304 pt_x = it.current_x;
20305 pt_vpos = it.vpos;
20306 if (dir > 0 || overshoot_expected)
20307 {
20308 struct glyph_row *row = it.glyph_row;
20309
20310 /* When point is at beginning of line, we don't have
20311 information about the glyph there loaded into struct
20312 it. Calling get_next_display_element fixes that. */
20313 if (pt_x == 0)
20314 get_next_display_element (&it);
20315 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20316 it.glyph_row = NULL;
20317 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
20318 it.glyph_row = row;
20319 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20320 it, lest it will become out of sync with it's buffer
20321 position. */
20322 it.current_x = pt_x;
20323 }
20324 else
20325 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20326 pixel_width = it.pixel_width;
20327 if (overshoot_expected && at_eol_p)
20328 pixel_width = 0;
20329 else if (pixel_width <= 0)
20330 pixel_width = 1;
20331
20332 /* If there's a display string at point, we are actually at the
20333 glyph to the left of point, so we need to correct the X
20334 coordinate. */
20335 if (overshoot_expected)
20336 pt_x += pixel_width;
20337
20338 /* Compute target X coordinate, either to the left or to the
20339 right of point. On TTY frames, all characters have the same
20340 pixel width of 1, so we can use that. On GUI frames we don't
20341 have an easy way of getting at the pixel width of the
20342 character to the left of point, so we use a different method
20343 of getting to that place. */
20344 if (dir > 0)
20345 target_x = pt_x + pixel_width;
20346 else
20347 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
20348
20349 /* Target X coordinate could be one line above or below the line
20350 of point, in which case we need to adjust the target X
20351 coordinate. Also, if moving to the left, we need to begin at
20352 the left edge of the point's screen line. */
20353 if (dir < 0)
20354 {
20355 if (pt_x > 0)
20356 {
20357 start_display (&it, w, pt);
20358 reseat_at_previous_visible_line_start (&it);
20359 it.current_x = it.current_y = it.hpos = 0;
20360 if (pt_vpos != 0)
20361 move_it_by_lines (&it, pt_vpos);
20362 }
20363 else
20364 {
20365 move_it_by_lines (&it, -1);
20366 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
20367 target_is_eol_p = true;
20368 }
20369 }
20370 else
20371 {
20372 if (at_eol_p
20373 || (target_x >= it.last_visible_x
20374 && it.line_wrap != TRUNCATE))
20375 {
20376 if (pt_x > 0)
20377 move_it_by_lines (&it, 0);
20378 move_it_by_lines (&it, 1);
20379 target_x = 0;
20380 }
20381 }
20382
20383 /* Move to the target X coordinate. */
20384 #ifdef HAVE_WINDOW_SYSTEM
20385 /* On GUI frames, as we don't know the X coordinate of the
20386 character to the left of point, moving point to the left
20387 requires walking, one grapheme cluster at a time, until we
20388 find ourself at a place immediately to the left of the
20389 character at point. */
20390 if (FRAME_WINDOW_P (it.f) && dir < 0)
20391 {
20392 struct text_pos new_pos = it.current.pos;
20393 enum move_it_result rc = MOVE_X_REACHED;
20394
20395 while (it.current_x + it.pixel_width <= target_x
20396 && rc == MOVE_X_REACHED)
20397 {
20398 int new_x = it.current_x + it.pixel_width;
20399
20400 new_pos = it.current.pos;
20401 if (new_x == it.current_x)
20402 new_x++;
20403 rc = move_it_in_display_line_to (&it, ZV, new_x,
20404 MOVE_TO_POS | MOVE_TO_X);
20405 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
20406 break;
20407 }
20408 /* If we ended up on a composed character inside
20409 bidi-reordered text (e.g., Hebrew text with diacritics),
20410 the iterator gives us the buffer position of the last (in
20411 logical order) character of the composed grapheme cluster,
20412 which is not what we want. So we cheat: we compute the
20413 character position of the character that follows (in the
20414 logical order) the one where the above loop stopped. That
20415 character will appear on display to the left of point. */
20416 if (it.bidi_p
20417 && it.bidi_it.scan_dir == -1
20418 && new_pos.charpos - IT_CHARPOS (it) > 1)
20419 {
20420 new_pos.charpos = IT_CHARPOS (it) + 1;
20421 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
20422 }
20423 it.current.pos = new_pos;
20424 }
20425 else
20426 #endif
20427 if (it.current_x != target_x)
20428 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
20429
20430 /* When lines are truncated, the above loop will stop at the
20431 window edge. But we want to get to the end of line, even if
20432 it is beyond the window edge; automatic hscroll will then
20433 scroll the window to show point as appropriate. */
20434 if (target_is_eol_p && it.line_wrap == TRUNCATE
20435 && get_next_display_element (&it))
20436 {
20437 struct text_pos new_pos = it.current.pos;
20438
20439 while (!ITERATOR_AT_END_OF_LINE_P (&it))
20440 {
20441 set_iterator_to_next (&it, 0);
20442 if (it.method == GET_FROM_BUFFER)
20443 new_pos = it.current.pos;
20444 if (!get_next_display_element (&it))
20445 break;
20446 }
20447
20448 it.current.pos = new_pos;
20449 }
20450
20451 /* If we ended up in a display string that covers point, move to
20452 buffer position to the right in the visual order. */
20453 if (dir > 0)
20454 {
20455 while (IT_CHARPOS (it) == PT)
20456 {
20457 set_iterator_to_next (&it, 0);
20458 if (!get_next_display_element (&it))
20459 break;
20460 }
20461 }
20462
20463 /* Move point to that position. */
20464 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
20465 }
20466
20467 return make_number (PT);
20468
20469 #undef ROW_GLYPH_NEWLINE_P
20470 }
20471
20472 \f
20473 /***********************************************************************
20474 Menu Bar
20475 ***********************************************************************/
20476
20477 /* Redisplay the menu bar in the frame for window W.
20478
20479 The menu bar of X frames that don't have X toolkit support is
20480 displayed in a special window W->frame->menu_bar_window.
20481
20482 The menu bar of terminal frames is treated specially as far as
20483 glyph matrices are concerned. Menu bar lines are not part of
20484 windows, so the update is done directly on the frame matrix rows
20485 for the menu bar. */
20486
20487 static void
20488 display_menu_bar (struct window *w)
20489 {
20490 struct frame *f = XFRAME (WINDOW_FRAME (w));
20491 struct it it;
20492 Lisp_Object items;
20493 int i;
20494
20495 /* Don't do all this for graphical frames. */
20496 #ifdef HAVE_NTGUI
20497 if (FRAME_W32_P (f))
20498 return;
20499 #endif
20500 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20501 if (FRAME_X_P (f))
20502 return;
20503 #endif
20504
20505 #ifdef HAVE_NS
20506 if (FRAME_NS_P (f))
20507 return;
20508 #endif /* HAVE_NS */
20509
20510 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20511 eassert (!FRAME_WINDOW_P (f));
20512 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20513 it.first_visible_x = 0;
20514 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20515 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20516 if (FRAME_WINDOW_P (f))
20517 {
20518 /* Menu bar lines are displayed in the desired matrix of the
20519 dummy window menu_bar_window. */
20520 struct window *menu_w;
20521 menu_w = XWINDOW (f->menu_bar_window);
20522 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20523 MENU_FACE_ID);
20524 it.first_visible_x = 0;
20525 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20526 }
20527 else
20528 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20529 {
20530 /* This is a TTY frame, i.e. character hpos/vpos are used as
20531 pixel x/y. */
20532 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20533 MENU_FACE_ID);
20534 it.first_visible_x = 0;
20535 it.last_visible_x = FRAME_COLS (f);
20536 }
20537
20538 /* FIXME: This should be controlled by a user option. See the
20539 comments in redisplay_tool_bar and display_mode_line about
20540 this. */
20541 it.paragraph_embedding = L2R;
20542
20543 /* Clear all rows of the menu bar. */
20544 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20545 {
20546 struct glyph_row *row = it.glyph_row + i;
20547 clear_glyph_row (row);
20548 row->enabled_p = 1;
20549 row->full_width_p = 1;
20550 }
20551
20552 /* Display all items of the menu bar. */
20553 items = FRAME_MENU_BAR_ITEMS (it.f);
20554 for (i = 0; i < ASIZE (items); i += 4)
20555 {
20556 Lisp_Object string;
20557
20558 /* Stop at nil string. */
20559 string = AREF (items, i + 1);
20560 if (NILP (string))
20561 break;
20562
20563 /* Remember where item was displayed. */
20564 ASET (items, i + 3, make_number (it.hpos));
20565
20566 /* Display the item, pad with one space. */
20567 if (it.current_x < it.last_visible_x)
20568 display_string (NULL, string, Qnil, 0, 0, &it,
20569 SCHARS (string) + 1, 0, 0, -1);
20570 }
20571
20572 /* Fill out the line with spaces. */
20573 if (it.current_x < it.last_visible_x)
20574 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20575
20576 /* Compute the total height of the lines. */
20577 compute_line_metrics (&it);
20578 }
20579
20580
20581 \f
20582 /***********************************************************************
20583 Mode Line
20584 ***********************************************************************/
20585
20586 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20587 FORCE is non-zero, redisplay mode lines unconditionally.
20588 Otherwise, redisplay only mode lines that are garbaged. Value is
20589 the number of windows whose mode lines were redisplayed. */
20590
20591 static int
20592 redisplay_mode_lines (Lisp_Object window, int force)
20593 {
20594 int nwindows = 0;
20595
20596 while (!NILP (window))
20597 {
20598 struct window *w = XWINDOW (window);
20599
20600 if (WINDOWP (w->contents))
20601 nwindows += redisplay_mode_lines (w->contents, force);
20602 else if (force
20603 || FRAME_GARBAGED_P (XFRAME (w->frame))
20604 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20605 {
20606 struct text_pos lpoint;
20607 struct buffer *old = current_buffer;
20608
20609 /* Set the window's buffer for the mode line display. */
20610 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20611 set_buffer_internal_1 (XBUFFER (w->contents));
20612
20613 /* Point refers normally to the selected window. For any
20614 other window, set up appropriate value. */
20615 if (!EQ (window, selected_window))
20616 {
20617 struct text_pos pt;
20618
20619 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
20620 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20621 }
20622
20623 /* Display mode lines. */
20624 clear_glyph_matrix (w->desired_matrix);
20625 if (display_mode_lines (w))
20626 {
20627 ++nwindows;
20628 w->must_be_updated_p = 1;
20629 }
20630
20631 /* Restore old settings. */
20632 set_buffer_internal_1 (old);
20633 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20634 }
20635
20636 window = w->next;
20637 }
20638
20639 return nwindows;
20640 }
20641
20642
20643 /* Display the mode and/or header line of window W. Value is the
20644 sum number of mode lines and header lines displayed. */
20645
20646 static int
20647 display_mode_lines (struct window *w)
20648 {
20649 Lisp_Object old_selected_window = selected_window;
20650 Lisp_Object old_selected_frame = selected_frame;
20651 Lisp_Object new_frame = w->frame;
20652 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20653 int n = 0;
20654
20655 selected_frame = new_frame;
20656 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20657 or window's point, then we'd need select_window_1 here as well. */
20658 XSETWINDOW (selected_window, w);
20659 XFRAME (new_frame)->selected_window = selected_window;
20660
20661 /* These will be set while the mode line specs are processed. */
20662 line_number_displayed = 0;
20663 w->column_number_displayed = -1;
20664
20665 if (WINDOW_WANTS_MODELINE_P (w))
20666 {
20667 struct window *sel_w = XWINDOW (old_selected_window);
20668
20669 /* Select mode line face based on the real selected window. */
20670 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20671 BVAR (current_buffer, mode_line_format));
20672 ++n;
20673 }
20674
20675 if (WINDOW_WANTS_HEADER_LINE_P (w))
20676 {
20677 display_mode_line (w, HEADER_LINE_FACE_ID,
20678 BVAR (current_buffer, header_line_format));
20679 ++n;
20680 }
20681
20682 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20683 selected_frame = old_selected_frame;
20684 selected_window = old_selected_window;
20685 return n;
20686 }
20687
20688
20689 /* Display mode or header line of window W. FACE_ID specifies which
20690 line to display; it is either MODE_LINE_FACE_ID or
20691 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20692 display. Value is the pixel height of the mode/header line
20693 displayed. */
20694
20695 static int
20696 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20697 {
20698 struct it it;
20699 struct face *face;
20700 ptrdiff_t count = SPECPDL_INDEX ();
20701
20702 init_iterator (&it, w, -1, -1, NULL, face_id);
20703 /* Don't extend on a previously drawn mode-line.
20704 This may happen if called from pos_visible_p. */
20705 it.glyph_row->enabled_p = 0;
20706 prepare_desired_row (it.glyph_row);
20707
20708 it.glyph_row->mode_line_p = 1;
20709
20710 /* FIXME: This should be controlled by a user option. But
20711 supporting such an option is not trivial, since the mode line is
20712 made up of many separate strings. */
20713 it.paragraph_embedding = L2R;
20714
20715 record_unwind_protect (unwind_format_mode_line,
20716 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20717
20718 mode_line_target = MODE_LINE_DISPLAY;
20719
20720 /* Temporarily make frame's keyboard the current kboard so that
20721 kboard-local variables in the mode_line_format will get the right
20722 values. */
20723 push_kboard (FRAME_KBOARD (it.f));
20724 record_unwind_save_match_data ();
20725 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20726 pop_kboard ();
20727
20728 unbind_to (count, Qnil);
20729
20730 /* Fill up with spaces. */
20731 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20732
20733 compute_line_metrics (&it);
20734 it.glyph_row->full_width_p = 1;
20735 it.glyph_row->continued_p = 0;
20736 it.glyph_row->truncated_on_left_p = 0;
20737 it.glyph_row->truncated_on_right_p = 0;
20738
20739 /* Make a 3D mode-line have a shadow at its right end. */
20740 face = FACE_FROM_ID (it.f, face_id);
20741 extend_face_to_end_of_line (&it);
20742 if (face->box != FACE_NO_BOX)
20743 {
20744 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20745 + it.glyph_row->used[TEXT_AREA] - 1);
20746 last->right_box_line_p = 1;
20747 }
20748
20749 return it.glyph_row->height;
20750 }
20751
20752 /* Move element ELT in LIST to the front of LIST.
20753 Return the updated list. */
20754
20755 static Lisp_Object
20756 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20757 {
20758 register Lisp_Object tail, prev;
20759 register Lisp_Object tem;
20760
20761 tail = list;
20762 prev = Qnil;
20763 while (CONSP (tail))
20764 {
20765 tem = XCAR (tail);
20766
20767 if (EQ (elt, tem))
20768 {
20769 /* Splice out the link TAIL. */
20770 if (NILP (prev))
20771 list = XCDR (tail);
20772 else
20773 Fsetcdr (prev, XCDR (tail));
20774
20775 /* Now make it the first. */
20776 Fsetcdr (tail, list);
20777 return tail;
20778 }
20779 else
20780 prev = tail;
20781 tail = XCDR (tail);
20782 QUIT;
20783 }
20784
20785 /* Not found--return unchanged LIST. */
20786 return list;
20787 }
20788
20789 /* Contribute ELT to the mode line for window IT->w. How it
20790 translates into text depends on its data type.
20791
20792 IT describes the display environment in which we display, as usual.
20793
20794 DEPTH is the depth in recursion. It is used to prevent
20795 infinite recursion here.
20796
20797 FIELD_WIDTH is the number of characters the display of ELT should
20798 occupy in the mode line, and PRECISION is the maximum number of
20799 characters to display from ELT's representation. See
20800 display_string for details.
20801
20802 Returns the hpos of the end of the text generated by ELT.
20803
20804 PROPS is a property list to add to any string we encounter.
20805
20806 If RISKY is nonzero, remove (disregard) any properties in any string
20807 we encounter, and ignore :eval and :propertize.
20808
20809 The global variable `mode_line_target' determines whether the
20810 output is passed to `store_mode_line_noprop',
20811 `store_mode_line_string', or `display_string'. */
20812
20813 static int
20814 display_mode_element (struct it *it, int depth, int field_width, int precision,
20815 Lisp_Object elt, Lisp_Object props, int risky)
20816 {
20817 int n = 0, field, prec;
20818 int literal = 0;
20819
20820 tail_recurse:
20821 if (depth > 100)
20822 elt = build_string ("*too-deep*");
20823
20824 depth++;
20825
20826 switch (XTYPE (elt))
20827 {
20828 case Lisp_String:
20829 {
20830 /* A string: output it and check for %-constructs within it. */
20831 unsigned char c;
20832 ptrdiff_t offset = 0;
20833
20834 if (SCHARS (elt) > 0
20835 && (!NILP (props) || risky))
20836 {
20837 Lisp_Object oprops, aelt;
20838 oprops = Ftext_properties_at (make_number (0), elt);
20839
20840 /* If the starting string's properties are not what
20841 we want, translate the string. Also, if the string
20842 is risky, do that anyway. */
20843
20844 if (NILP (Fequal (props, oprops)) || risky)
20845 {
20846 /* If the starting string has properties,
20847 merge the specified ones onto the existing ones. */
20848 if (! NILP (oprops) && !risky)
20849 {
20850 Lisp_Object tem;
20851
20852 oprops = Fcopy_sequence (oprops);
20853 tem = props;
20854 while (CONSP (tem))
20855 {
20856 oprops = Fplist_put (oprops, XCAR (tem),
20857 XCAR (XCDR (tem)));
20858 tem = XCDR (XCDR (tem));
20859 }
20860 props = oprops;
20861 }
20862
20863 aelt = Fassoc (elt, mode_line_proptrans_alist);
20864 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20865 {
20866 /* AELT is what we want. Move it to the front
20867 without consing. */
20868 elt = XCAR (aelt);
20869 mode_line_proptrans_alist
20870 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20871 }
20872 else
20873 {
20874 Lisp_Object tem;
20875
20876 /* If AELT has the wrong props, it is useless.
20877 so get rid of it. */
20878 if (! NILP (aelt))
20879 mode_line_proptrans_alist
20880 = Fdelq (aelt, mode_line_proptrans_alist);
20881
20882 elt = Fcopy_sequence (elt);
20883 Fset_text_properties (make_number (0), Flength (elt),
20884 props, elt);
20885 /* Add this item to mode_line_proptrans_alist. */
20886 mode_line_proptrans_alist
20887 = Fcons (Fcons (elt, props),
20888 mode_line_proptrans_alist);
20889 /* Truncate mode_line_proptrans_alist
20890 to at most 50 elements. */
20891 tem = Fnthcdr (make_number (50),
20892 mode_line_proptrans_alist);
20893 if (! NILP (tem))
20894 XSETCDR (tem, Qnil);
20895 }
20896 }
20897 }
20898
20899 offset = 0;
20900
20901 if (literal)
20902 {
20903 prec = precision - n;
20904 switch (mode_line_target)
20905 {
20906 case MODE_LINE_NOPROP:
20907 case MODE_LINE_TITLE:
20908 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20909 break;
20910 case MODE_LINE_STRING:
20911 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20912 break;
20913 case MODE_LINE_DISPLAY:
20914 n += display_string (NULL, elt, Qnil, 0, 0, it,
20915 0, prec, 0, STRING_MULTIBYTE (elt));
20916 break;
20917 }
20918
20919 break;
20920 }
20921
20922 /* Handle the non-literal case. */
20923
20924 while ((precision <= 0 || n < precision)
20925 && SREF (elt, offset) != 0
20926 && (mode_line_target != MODE_LINE_DISPLAY
20927 || it->current_x < it->last_visible_x))
20928 {
20929 ptrdiff_t last_offset = offset;
20930
20931 /* Advance to end of string or next format specifier. */
20932 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20933 ;
20934
20935 if (offset - 1 != last_offset)
20936 {
20937 ptrdiff_t nchars, nbytes;
20938
20939 /* Output to end of string or up to '%'. Field width
20940 is length of string. Don't output more than
20941 PRECISION allows us. */
20942 offset--;
20943
20944 prec = c_string_width (SDATA (elt) + last_offset,
20945 offset - last_offset, precision - n,
20946 &nchars, &nbytes);
20947
20948 switch (mode_line_target)
20949 {
20950 case MODE_LINE_NOPROP:
20951 case MODE_LINE_TITLE:
20952 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20953 break;
20954 case MODE_LINE_STRING:
20955 {
20956 ptrdiff_t bytepos = last_offset;
20957 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20958 ptrdiff_t endpos = (precision <= 0
20959 ? string_byte_to_char (elt, offset)
20960 : charpos + nchars);
20961
20962 n += store_mode_line_string (NULL,
20963 Fsubstring (elt, make_number (charpos),
20964 make_number (endpos)),
20965 0, 0, 0, Qnil);
20966 }
20967 break;
20968 case MODE_LINE_DISPLAY:
20969 {
20970 ptrdiff_t bytepos = last_offset;
20971 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20972
20973 if (precision <= 0)
20974 nchars = string_byte_to_char (elt, offset) - charpos;
20975 n += display_string (NULL, elt, Qnil, 0, charpos,
20976 it, 0, nchars, 0,
20977 STRING_MULTIBYTE (elt));
20978 }
20979 break;
20980 }
20981 }
20982 else /* c == '%' */
20983 {
20984 ptrdiff_t percent_position = offset;
20985
20986 /* Get the specified minimum width. Zero means
20987 don't pad. */
20988 field = 0;
20989 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20990 field = field * 10 + c - '0';
20991
20992 /* Don't pad beyond the total padding allowed. */
20993 if (field_width - n > 0 && field > field_width - n)
20994 field = field_width - n;
20995
20996 /* Note that either PRECISION <= 0 or N < PRECISION. */
20997 prec = precision - n;
20998
20999 if (c == 'M')
21000 n += display_mode_element (it, depth, field, prec,
21001 Vglobal_mode_string, props,
21002 risky);
21003 else if (c != 0)
21004 {
21005 bool multibyte;
21006 ptrdiff_t bytepos, charpos;
21007 const char *spec;
21008 Lisp_Object string;
21009
21010 bytepos = percent_position;
21011 charpos = (STRING_MULTIBYTE (elt)
21012 ? string_byte_to_char (elt, bytepos)
21013 : bytepos);
21014 spec = decode_mode_spec (it->w, c, field, &string);
21015 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
21016
21017 switch (mode_line_target)
21018 {
21019 case MODE_LINE_NOPROP:
21020 case MODE_LINE_TITLE:
21021 n += store_mode_line_noprop (spec, field, prec);
21022 break;
21023 case MODE_LINE_STRING:
21024 {
21025 Lisp_Object tem = build_string (spec);
21026 props = Ftext_properties_at (make_number (charpos), elt);
21027 /* Should only keep face property in props */
21028 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21029 }
21030 break;
21031 case MODE_LINE_DISPLAY:
21032 {
21033 int nglyphs_before, nwritten;
21034
21035 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21036 nwritten = display_string (spec, string, elt,
21037 charpos, 0, it,
21038 field, prec, 0,
21039 multibyte);
21040
21041 /* Assign to the glyphs written above the
21042 string where the `%x' came from, position
21043 of the `%'. */
21044 if (nwritten > 0)
21045 {
21046 struct glyph *glyph
21047 = (it->glyph_row->glyphs[TEXT_AREA]
21048 + nglyphs_before);
21049 int i;
21050
21051 for (i = 0; i < nwritten; ++i)
21052 {
21053 glyph[i].object = elt;
21054 glyph[i].charpos = charpos;
21055 }
21056
21057 n += nwritten;
21058 }
21059 }
21060 break;
21061 }
21062 }
21063 else /* c == 0 */
21064 break;
21065 }
21066 }
21067 }
21068 break;
21069
21070 case Lisp_Symbol:
21071 /* A symbol: process the value of the symbol recursively
21072 as if it appeared here directly. Avoid error if symbol void.
21073 Special case: if value of symbol is a string, output the string
21074 literally. */
21075 {
21076 register Lisp_Object tem;
21077
21078 /* If the variable is not marked as risky to set
21079 then its contents are risky to use. */
21080 if (NILP (Fget (elt, Qrisky_local_variable)))
21081 risky = 1;
21082
21083 tem = Fboundp (elt);
21084 if (!NILP (tem))
21085 {
21086 tem = Fsymbol_value (elt);
21087 /* If value is a string, output that string literally:
21088 don't check for % within it. */
21089 if (STRINGP (tem))
21090 literal = 1;
21091
21092 if (!EQ (tem, elt))
21093 {
21094 /* Give up right away for nil or t. */
21095 elt = tem;
21096 goto tail_recurse;
21097 }
21098 }
21099 }
21100 break;
21101
21102 case Lisp_Cons:
21103 {
21104 register Lisp_Object car, tem;
21105
21106 /* A cons cell: five distinct cases.
21107 If first element is :eval or :propertize, do something special.
21108 If first element is a string or a cons, process all the elements
21109 and effectively concatenate them.
21110 If first element is a negative number, truncate displaying cdr to
21111 at most that many characters. If positive, pad (with spaces)
21112 to at least that many characters.
21113 If first element is a symbol, process the cadr or caddr recursively
21114 according to whether the symbol's value is non-nil or nil. */
21115 car = XCAR (elt);
21116 if (EQ (car, QCeval))
21117 {
21118 /* An element of the form (:eval FORM) means evaluate FORM
21119 and use the result as mode line elements. */
21120
21121 if (risky)
21122 break;
21123
21124 if (CONSP (XCDR (elt)))
21125 {
21126 Lisp_Object spec;
21127 spec = safe_eval (XCAR (XCDR (elt)));
21128 n += display_mode_element (it, depth, field_width - n,
21129 precision - n, spec, props,
21130 risky);
21131 }
21132 }
21133 else if (EQ (car, QCpropertize))
21134 {
21135 /* An element of the form (:propertize ELT PROPS...)
21136 means display ELT but applying properties PROPS. */
21137
21138 if (risky)
21139 break;
21140
21141 if (CONSP (XCDR (elt)))
21142 n += display_mode_element (it, depth, field_width - n,
21143 precision - n, XCAR (XCDR (elt)),
21144 XCDR (XCDR (elt)), risky);
21145 }
21146 else if (SYMBOLP (car))
21147 {
21148 tem = Fboundp (car);
21149 elt = XCDR (elt);
21150 if (!CONSP (elt))
21151 goto invalid;
21152 /* elt is now the cdr, and we know it is a cons cell.
21153 Use its car if CAR has a non-nil value. */
21154 if (!NILP (tem))
21155 {
21156 tem = Fsymbol_value (car);
21157 if (!NILP (tem))
21158 {
21159 elt = XCAR (elt);
21160 goto tail_recurse;
21161 }
21162 }
21163 /* Symbol's value is nil (or symbol is unbound)
21164 Get the cddr of the original list
21165 and if possible find the caddr and use that. */
21166 elt = XCDR (elt);
21167 if (NILP (elt))
21168 break;
21169 else if (!CONSP (elt))
21170 goto invalid;
21171 elt = XCAR (elt);
21172 goto tail_recurse;
21173 }
21174 else if (INTEGERP (car))
21175 {
21176 register int lim = XINT (car);
21177 elt = XCDR (elt);
21178 if (lim < 0)
21179 {
21180 /* Negative int means reduce maximum width. */
21181 if (precision <= 0)
21182 precision = -lim;
21183 else
21184 precision = min (precision, -lim);
21185 }
21186 else if (lim > 0)
21187 {
21188 /* Padding specified. Don't let it be more than
21189 current maximum. */
21190 if (precision > 0)
21191 lim = min (precision, lim);
21192
21193 /* If that's more padding than already wanted, queue it.
21194 But don't reduce padding already specified even if
21195 that is beyond the current truncation point. */
21196 field_width = max (lim, field_width);
21197 }
21198 goto tail_recurse;
21199 }
21200 else if (STRINGP (car) || CONSP (car))
21201 {
21202 Lisp_Object halftail = elt;
21203 int len = 0;
21204
21205 while (CONSP (elt)
21206 && (precision <= 0 || n < precision))
21207 {
21208 n += display_mode_element (it, depth,
21209 /* Do padding only after the last
21210 element in the list. */
21211 (! CONSP (XCDR (elt))
21212 ? field_width - n
21213 : 0),
21214 precision - n, XCAR (elt),
21215 props, risky);
21216 elt = XCDR (elt);
21217 len++;
21218 if ((len & 1) == 0)
21219 halftail = XCDR (halftail);
21220 /* Check for cycle. */
21221 if (EQ (halftail, elt))
21222 break;
21223 }
21224 }
21225 }
21226 break;
21227
21228 default:
21229 invalid:
21230 elt = build_string ("*invalid*");
21231 goto tail_recurse;
21232 }
21233
21234 /* Pad to FIELD_WIDTH. */
21235 if (field_width > 0 && n < field_width)
21236 {
21237 switch (mode_line_target)
21238 {
21239 case MODE_LINE_NOPROP:
21240 case MODE_LINE_TITLE:
21241 n += store_mode_line_noprop ("", field_width - n, 0);
21242 break;
21243 case MODE_LINE_STRING:
21244 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
21245 break;
21246 case MODE_LINE_DISPLAY:
21247 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
21248 0, 0, 0);
21249 break;
21250 }
21251 }
21252
21253 return n;
21254 }
21255
21256 /* Store a mode-line string element in mode_line_string_list.
21257
21258 If STRING is non-null, display that C string. Otherwise, the Lisp
21259 string LISP_STRING is displayed.
21260
21261 FIELD_WIDTH is the minimum number of output glyphs to produce.
21262 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21263 with spaces. FIELD_WIDTH <= 0 means don't pad.
21264
21265 PRECISION is the maximum number of characters to output from
21266 STRING. PRECISION <= 0 means don't truncate the string.
21267
21268 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21269 properties to the string.
21270
21271 PROPS are the properties to add to the string.
21272 The mode_line_string_face face property is always added to the string.
21273 */
21274
21275 static int
21276 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21277 int field_width, int precision, Lisp_Object props)
21278 {
21279 ptrdiff_t len;
21280 int n = 0;
21281
21282 if (string != NULL)
21283 {
21284 len = strlen (string);
21285 if (precision > 0 && len > precision)
21286 len = precision;
21287 lisp_string = make_string (string, len);
21288 if (NILP (props))
21289 props = mode_line_string_face_prop;
21290 else if (!NILP (mode_line_string_face))
21291 {
21292 Lisp_Object face = Fplist_get (props, Qface);
21293 props = Fcopy_sequence (props);
21294 if (NILP (face))
21295 face = mode_line_string_face;
21296 else
21297 face = list2 (face, mode_line_string_face);
21298 props = Fplist_put (props, Qface, face);
21299 }
21300 Fadd_text_properties (make_number (0), make_number (len),
21301 props, lisp_string);
21302 }
21303 else
21304 {
21305 len = XFASTINT (Flength (lisp_string));
21306 if (precision > 0 && len > precision)
21307 {
21308 len = precision;
21309 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21310 precision = -1;
21311 }
21312 if (!NILP (mode_line_string_face))
21313 {
21314 Lisp_Object face;
21315 if (NILP (props))
21316 props = Ftext_properties_at (make_number (0), lisp_string);
21317 face = Fplist_get (props, Qface);
21318 if (NILP (face))
21319 face = mode_line_string_face;
21320 else
21321 face = list2 (face, mode_line_string_face);
21322 props = list2 (Qface, face);
21323 if (copy_string)
21324 lisp_string = Fcopy_sequence (lisp_string);
21325 }
21326 if (!NILP (props))
21327 Fadd_text_properties (make_number (0), make_number (len),
21328 props, lisp_string);
21329 }
21330
21331 if (len > 0)
21332 {
21333 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21334 n += len;
21335 }
21336
21337 if (field_width > len)
21338 {
21339 field_width -= len;
21340 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21341 if (!NILP (props))
21342 Fadd_text_properties (make_number (0), make_number (field_width),
21343 props, lisp_string);
21344 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21345 n += field_width;
21346 }
21347
21348 return n;
21349 }
21350
21351
21352 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21353 1, 4, 0,
21354 doc: /* Format a string out of a mode line format specification.
21355 First arg FORMAT specifies the mode line format (see `mode-line-format'
21356 for details) to use.
21357
21358 By default, the format is evaluated for the currently selected window.
21359
21360 Optional second arg FACE specifies the face property to put on all
21361 characters for which no face is specified. The value nil means the
21362 default face. The value t means whatever face the window's mode line
21363 currently uses (either `mode-line' or `mode-line-inactive',
21364 depending on whether the window is the selected window or not).
21365 An integer value means the value string has no text
21366 properties.
21367
21368 Optional third and fourth args WINDOW and BUFFER specify the window
21369 and buffer to use as the context for the formatting (defaults
21370 are the selected window and the WINDOW's buffer). */)
21371 (Lisp_Object format, Lisp_Object face,
21372 Lisp_Object window, Lisp_Object buffer)
21373 {
21374 struct it it;
21375 int len;
21376 struct window *w;
21377 struct buffer *old_buffer = NULL;
21378 int face_id;
21379 int no_props = INTEGERP (face);
21380 ptrdiff_t count = SPECPDL_INDEX ();
21381 Lisp_Object str;
21382 int string_start = 0;
21383
21384 w = decode_any_window (window);
21385 XSETWINDOW (window, w);
21386
21387 if (NILP (buffer))
21388 buffer = w->contents;
21389 CHECK_BUFFER (buffer);
21390
21391 /* Make formatting the modeline a non-op when noninteractive, otherwise
21392 there will be problems later caused by a partially initialized frame. */
21393 if (NILP (format) || noninteractive)
21394 return empty_unibyte_string;
21395
21396 if (no_props)
21397 face = Qnil;
21398
21399 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21400 : EQ (face, Qt) ? (EQ (window, selected_window)
21401 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21402 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21403 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21404 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21405 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21406 : DEFAULT_FACE_ID;
21407
21408 old_buffer = current_buffer;
21409
21410 /* Save things including mode_line_proptrans_alist,
21411 and set that to nil so that we don't alter the outer value. */
21412 record_unwind_protect (unwind_format_mode_line,
21413 format_mode_line_unwind_data
21414 (XFRAME (WINDOW_FRAME (w)),
21415 old_buffer, selected_window, 1));
21416 mode_line_proptrans_alist = Qnil;
21417
21418 Fselect_window (window, Qt);
21419 set_buffer_internal_1 (XBUFFER (buffer));
21420
21421 init_iterator (&it, w, -1, -1, NULL, face_id);
21422
21423 if (no_props)
21424 {
21425 mode_line_target = MODE_LINE_NOPROP;
21426 mode_line_string_face_prop = Qnil;
21427 mode_line_string_list = Qnil;
21428 string_start = MODE_LINE_NOPROP_LEN (0);
21429 }
21430 else
21431 {
21432 mode_line_target = MODE_LINE_STRING;
21433 mode_line_string_list = Qnil;
21434 mode_line_string_face = face;
21435 mode_line_string_face_prop
21436 = NILP (face) ? Qnil : list2 (Qface, face);
21437 }
21438
21439 push_kboard (FRAME_KBOARD (it.f));
21440 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21441 pop_kboard ();
21442
21443 if (no_props)
21444 {
21445 len = MODE_LINE_NOPROP_LEN (string_start);
21446 str = make_string (mode_line_noprop_buf + string_start, len);
21447 }
21448 else
21449 {
21450 mode_line_string_list = Fnreverse (mode_line_string_list);
21451 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21452 empty_unibyte_string);
21453 }
21454
21455 unbind_to (count, Qnil);
21456 return str;
21457 }
21458
21459 /* Write a null-terminated, right justified decimal representation of
21460 the positive integer D to BUF using a minimal field width WIDTH. */
21461
21462 static void
21463 pint2str (register char *buf, register int width, register ptrdiff_t d)
21464 {
21465 register char *p = buf;
21466
21467 if (d <= 0)
21468 *p++ = '0';
21469 else
21470 {
21471 while (d > 0)
21472 {
21473 *p++ = d % 10 + '0';
21474 d /= 10;
21475 }
21476 }
21477
21478 for (width -= (int) (p - buf); width > 0; --width)
21479 *p++ = ' ';
21480 *p-- = '\0';
21481 while (p > buf)
21482 {
21483 d = *buf;
21484 *buf++ = *p;
21485 *p-- = d;
21486 }
21487 }
21488
21489 /* Write a null-terminated, right justified decimal and "human
21490 readable" representation of the nonnegative integer D to BUF using
21491 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21492
21493 static const char power_letter[] =
21494 {
21495 0, /* no letter */
21496 'k', /* kilo */
21497 'M', /* mega */
21498 'G', /* giga */
21499 'T', /* tera */
21500 'P', /* peta */
21501 'E', /* exa */
21502 'Z', /* zetta */
21503 'Y' /* yotta */
21504 };
21505
21506 static void
21507 pint2hrstr (char *buf, int width, ptrdiff_t d)
21508 {
21509 /* We aim to represent the nonnegative integer D as
21510 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21511 ptrdiff_t quotient = d;
21512 int remainder = 0;
21513 /* -1 means: do not use TENTHS. */
21514 int tenths = -1;
21515 int exponent = 0;
21516
21517 /* Length of QUOTIENT.TENTHS as a string. */
21518 int length;
21519
21520 char * psuffix;
21521 char * p;
21522
21523 if (quotient >= 1000)
21524 {
21525 /* Scale to the appropriate EXPONENT. */
21526 do
21527 {
21528 remainder = quotient % 1000;
21529 quotient /= 1000;
21530 exponent++;
21531 }
21532 while (quotient >= 1000);
21533
21534 /* Round to nearest and decide whether to use TENTHS or not. */
21535 if (quotient <= 9)
21536 {
21537 tenths = remainder / 100;
21538 if (remainder % 100 >= 50)
21539 {
21540 if (tenths < 9)
21541 tenths++;
21542 else
21543 {
21544 quotient++;
21545 if (quotient == 10)
21546 tenths = -1;
21547 else
21548 tenths = 0;
21549 }
21550 }
21551 }
21552 else
21553 if (remainder >= 500)
21554 {
21555 if (quotient < 999)
21556 quotient++;
21557 else
21558 {
21559 quotient = 1;
21560 exponent++;
21561 tenths = 0;
21562 }
21563 }
21564 }
21565
21566 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21567 if (tenths == -1 && quotient <= 99)
21568 if (quotient <= 9)
21569 length = 1;
21570 else
21571 length = 2;
21572 else
21573 length = 3;
21574 p = psuffix = buf + max (width, length);
21575
21576 /* Print EXPONENT. */
21577 *psuffix++ = power_letter[exponent];
21578 *psuffix = '\0';
21579
21580 /* Print TENTHS. */
21581 if (tenths >= 0)
21582 {
21583 *--p = '0' + tenths;
21584 *--p = '.';
21585 }
21586
21587 /* Print QUOTIENT. */
21588 do
21589 {
21590 int digit = quotient % 10;
21591 *--p = '0' + digit;
21592 }
21593 while ((quotient /= 10) != 0);
21594
21595 /* Print leading spaces. */
21596 while (buf < p)
21597 *--p = ' ';
21598 }
21599
21600 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21601 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21602 type of CODING_SYSTEM. Return updated pointer into BUF. */
21603
21604 static unsigned char invalid_eol_type[] = "(*invalid*)";
21605
21606 static char *
21607 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21608 {
21609 Lisp_Object val;
21610 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21611 const unsigned char *eol_str;
21612 int eol_str_len;
21613 /* The EOL conversion we are using. */
21614 Lisp_Object eoltype;
21615
21616 val = CODING_SYSTEM_SPEC (coding_system);
21617 eoltype = Qnil;
21618
21619 if (!VECTORP (val)) /* Not yet decided. */
21620 {
21621 *buf++ = multibyte ? '-' : ' ';
21622 if (eol_flag)
21623 eoltype = eol_mnemonic_undecided;
21624 /* Don't mention EOL conversion if it isn't decided. */
21625 }
21626 else
21627 {
21628 Lisp_Object attrs;
21629 Lisp_Object eolvalue;
21630
21631 attrs = AREF (val, 0);
21632 eolvalue = AREF (val, 2);
21633
21634 *buf++ = multibyte
21635 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21636 : ' ';
21637
21638 if (eol_flag)
21639 {
21640 /* The EOL conversion that is normal on this system. */
21641
21642 if (NILP (eolvalue)) /* Not yet decided. */
21643 eoltype = eol_mnemonic_undecided;
21644 else if (VECTORP (eolvalue)) /* Not yet decided. */
21645 eoltype = eol_mnemonic_undecided;
21646 else /* eolvalue is Qunix, Qdos, or Qmac. */
21647 eoltype = (EQ (eolvalue, Qunix)
21648 ? eol_mnemonic_unix
21649 : (EQ (eolvalue, Qdos) == 1
21650 ? eol_mnemonic_dos : eol_mnemonic_mac));
21651 }
21652 }
21653
21654 if (eol_flag)
21655 {
21656 /* Mention the EOL conversion if it is not the usual one. */
21657 if (STRINGP (eoltype))
21658 {
21659 eol_str = SDATA (eoltype);
21660 eol_str_len = SBYTES (eoltype);
21661 }
21662 else if (CHARACTERP (eoltype))
21663 {
21664 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21665 int c = XFASTINT (eoltype);
21666 eol_str_len = CHAR_STRING (c, tmp);
21667 eol_str = tmp;
21668 }
21669 else
21670 {
21671 eol_str = invalid_eol_type;
21672 eol_str_len = sizeof (invalid_eol_type) - 1;
21673 }
21674 memcpy (buf, eol_str, eol_str_len);
21675 buf += eol_str_len;
21676 }
21677
21678 return buf;
21679 }
21680
21681 /* Return a string for the output of a mode line %-spec for window W,
21682 generated by character C. FIELD_WIDTH > 0 means pad the string
21683 returned with spaces to that value. Return a Lisp string in
21684 *STRING if the resulting string is taken from that Lisp string.
21685
21686 Note we operate on the current buffer for most purposes. */
21687
21688 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21689
21690 static const char *
21691 decode_mode_spec (struct window *w, register int c, int field_width,
21692 Lisp_Object *string)
21693 {
21694 Lisp_Object obj;
21695 struct frame *f = XFRAME (WINDOW_FRAME (w));
21696 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21697 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21698 produce strings from numerical values, so limit preposterously
21699 large values of FIELD_WIDTH to avoid overrunning the buffer's
21700 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21701 bytes plus the terminating null. */
21702 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21703 struct buffer *b = current_buffer;
21704
21705 obj = Qnil;
21706 *string = Qnil;
21707
21708 switch (c)
21709 {
21710 case '*':
21711 if (!NILP (BVAR (b, read_only)))
21712 return "%";
21713 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21714 return "*";
21715 return "-";
21716
21717 case '+':
21718 /* This differs from %* only for a modified read-only buffer. */
21719 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21720 return "*";
21721 if (!NILP (BVAR (b, read_only)))
21722 return "%";
21723 return "-";
21724
21725 case '&':
21726 /* This differs from %* in ignoring read-only-ness. */
21727 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21728 return "*";
21729 return "-";
21730
21731 case '%':
21732 return "%";
21733
21734 case '[':
21735 {
21736 int i;
21737 char *p;
21738
21739 if (command_loop_level > 5)
21740 return "[[[... ";
21741 p = decode_mode_spec_buf;
21742 for (i = 0; i < command_loop_level; i++)
21743 *p++ = '[';
21744 *p = 0;
21745 return decode_mode_spec_buf;
21746 }
21747
21748 case ']':
21749 {
21750 int i;
21751 char *p;
21752
21753 if (command_loop_level > 5)
21754 return " ...]]]";
21755 p = decode_mode_spec_buf;
21756 for (i = 0; i < command_loop_level; i++)
21757 *p++ = ']';
21758 *p = 0;
21759 return decode_mode_spec_buf;
21760 }
21761
21762 case '-':
21763 {
21764 register int i;
21765
21766 /* Let lots_of_dashes be a string of infinite length. */
21767 if (mode_line_target == MODE_LINE_NOPROP
21768 || mode_line_target == MODE_LINE_STRING)
21769 return "--";
21770 if (field_width <= 0
21771 || field_width > sizeof (lots_of_dashes))
21772 {
21773 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21774 decode_mode_spec_buf[i] = '-';
21775 decode_mode_spec_buf[i] = '\0';
21776 return decode_mode_spec_buf;
21777 }
21778 else
21779 return lots_of_dashes;
21780 }
21781
21782 case 'b':
21783 obj = BVAR (b, name);
21784 break;
21785
21786 case 'c':
21787 /* %c and %l are ignored in `frame-title-format'.
21788 (In redisplay_internal, the frame title is drawn _before_ the
21789 windows are updated, so the stuff which depends on actual
21790 window contents (such as %l) may fail to render properly, or
21791 even crash emacs.) */
21792 if (mode_line_target == MODE_LINE_TITLE)
21793 return "";
21794 else
21795 {
21796 ptrdiff_t col = current_column ();
21797 w->column_number_displayed = col;
21798 pint2str (decode_mode_spec_buf, width, col);
21799 return decode_mode_spec_buf;
21800 }
21801
21802 case 'e':
21803 #ifndef SYSTEM_MALLOC
21804 {
21805 if (NILP (Vmemory_full))
21806 return "";
21807 else
21808 return "!MEM FULL! ";
21809 }
21810 #else
21811 return "";
21812 #endif
21813
21814 case 'F':
21815 /* %F displays the frame name. */
21816 if (!NILP (f->title))
21817 return SSDATA (f->title);
21818 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21819 return SSDATA (f->name);
21820 return "Emacs";
21821
21822 case 'f':
21823 obj = BVAR (b, filename);
21824 break;
21825
21826 case 'i':
21827 {
21828 ptrdiff_t size = ZV - BEGV;
21829 pint2str (decode_mode_spec_buf, width, size);
21830 return decode_mode_spec_buf;
21831 }
21832
21833 case 'I':
21834 {
21835 ptrdiff_t size = ZV - BEGV;
21836 pint2hrstr (decode_mode_spec_buf, width, size);
21837 return decode_mode_spec_buf;
21838 }
21839
21840 case 'l':
21841 {
21842 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21843 ptrdiff_t topline, nlines, height;
21844 ptrdiff_t junk;
21845
21846 /* %c and %l are ignored in `frame-title-format'. */
21847 if (mode_line_target == MODE_LINE_TITLE)
21848 return "";
21849
21850 startpos = marker_position (w->start);
21851 startpos_byte = marker_byte_position (w->start);
21852 height = WINDOW_TOTAL_LINES (w);
21853
21854 /* If we decided that this buffer isn't suitable for line numbers,
21855 don't forget that too fast. */
21856 if (w->base_line_pos == -1)
21857 goto no_value;
21858
21859 /* If the buffer is very big, don't waste time. */
21860 if (INTEGERP (Vline_number_display_limit)
21861 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21862 {
21863 w->base_line_pos = 0;
21864 w->base_line_number = 0;
21865 goto no_value;
21866 }
21867
21868 if (w->base_line_number > 0
21869 && w->base_line_pos > 0
21870 && w->base_line_pos <= startpos)
21871 {
21872 line = w->base_line_number;
21873 linepos = w->base_line_pos;
21874 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21875 }
21876 else
21877 {
21878 line = 1;
21879 linepos = BUF_BEGV (b);
21880 linepos_byte = BUF_BEGV_BYTE (b);
21881 }
21882
21883 /* Count lines from base line to window start position. */
21884 nlines = display_count_lines (linepos_byte,
21885 startpos_byte,
21886 startpos, &junk);
21887
21888 topline = nlines + line;
21889
21890 /* Determine a new base line, if the old one is too close
21891 or too far away, or if we did not have one.
21892 "Too close" means it's plausible a scroll-down would
21893 go back past it. */
21894 if (startpos == BUF_BEGV (b))
21895 {
21896 w->base_line_number = topline;
21897 w->base_line_pos = BUF_BEGV (b);
21898 }
21899 else if (nlines < height + 25 || nlines > height * 3 + 50
21900 || linepos == BUF_BEGV (b))
21901 {
21902 ptrdiff_t limit = BUF_BEGV (b);
21903 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21904 ptrdiff_t position;
21905 ptrdiff_t distance =
21906 (height * 2 + 30) * line_number_display_limit_width;
21907
21908 if (startpos - distance > limit)
21909 {
21910 limit = startpos - distance;
21911 limit_byte = CHAR_TO_BYTE (limit);
21912 }
21913
21914 nlines = display_count_lines (startpos_byte,
21915 limit_byte,
21916 - (height * 2 + 30),
21917 &position);
21918 /* If we couldn't find the lines we wanted within
21919 line_number_display_limit_width chars per line,
21920 give up on line numbers for this window. */
21921 if (position == limit_byte && limit == startpos - distance)
21922 {
21923 w->base_line_pos = -1;
21924 w->base_line_number = 0;
21925 goto no_value;
21926 }
21927
21928 w->base_line_number = topline - nlines;
21929 w->base_line_pos = BYTE_TO_CHAR (position);
21930 }
21931
21932 /* Now count lines from the start pos to point. */
21933 nlines = display_count_lines (startpos_byte,
21934 PT_BYTE, PT, &junk);
21935
21936 /* Record that we did display the line number. */
21937 line_number_displayed = 1;
21938
21939 /* Make the string to show. */
21940 pint2str (decode_mode_spec_buf, width, topline + nlines);
21941 return decode_mode_spec_buf;
21942 no_value:
21943 {
21944 char* p = decode_mode_spec_buf;
21945 int pad = width - 2;
21946 while (pad-- > 0)
21947 *p++ = ' ';
21948 *p++ = '?';
21949 *p++ = '?';
21950 *p = '\0';
21951 return decode_mode_spec_buf;
21952 }
21953 }
21954 break;
21955
21956 case 'm':
21957 obj = BVAR (b, mode_name);
21958 break;
21959
21960 case 'n':
21961 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21962 return " Narrow";
21963 break;
21964
21965 case 'p':
21966 {
21967 ptrdiff_t pos = marker_position (w->start);
21968 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21969
21970 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
21971 {
21972 if (pos <= BUF_BEGV (b))
21973 return "All";
21974 else
21975 return "Bottom";
21976 }
21977 else if (pos <= BUF_BEGV (b))
21978 return "Top";
21979 else
21980 {
21981 if (total > 1000000)
21982 /* Do it differently for a large value, to avoid overflow. */
21983 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21984 else
21985 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21986 /* We can't normally display a 3-digit number,
21987 so get us a 2-digit number that is close. */
21988 if (total == 100)
21989 total = 99;
21990 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21991 return decode_mode_spec_buf;
21992 }
21993 }
21994
21995 /* Display percentage of size above the bottom of the screen. */
21996 case 'P':
21997 {
21998 ptrdiff_t toppos = marker_position (w->start);
21999 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
22000 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22001
22002 if (botpos >= BUF_ZV (b))
22003 {
22004 if (toppos <= BUF_BEGV (b))
22005 return "All";
22006 else
22007 return "Bottom";
22008 }
22009 else
22010 {
22011 if (total > 1000000)
22012 /* Do it differently for a large value, to avoid overflow. */
22013 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22014 else
22015 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
22016 /* We can't normally display a 3-digit number,
22017 so get us a 2-digit number that is close. */
22018 if (total == 100)
22019 total = 99;
22020 if (toppos <= BUF_BEGV (b))
22021 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22022 else
22023 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22024 return decode_mode_spec_buf;
22025 }
22026 }
22027
22028 case 's':
22029 /* status of process */
22030 obj = Fget_buffer_process (Fcurrent_buffer ());
22031 if (NILP (obj))
22032 return "no process";
22033 #ifndef MSDOS
22034 obj = Fsymbol_name (Fprocess_status (obj));
22035 #endif
22036 break;
22037
22038 case '@':
22039 {
22040 ptrdiff_t count = inhibit_garbage_collection ();
22041 Lisp_Object val = call1 (intern ("file-remote-p"),
22042 BVAR (current_buffer, directory));
22043 unbind_to (count, Qnil);
22044
22045 if (NILP (val))
22046 return "-";
22047 else
22048 return "@";
22049 }
22050
22051 case 'z':
22052 /* coding-system (not including end-of-line format) */
22053 case 'Z':
22054 /* coding-system (including end-of-line type) */
22055 {
22056 int eol_flag = (c == 'Z');
22057 char *p = decode_mode_spec_buf;
22058
22059 if (! FRAME_WINDOW_P (f))
22060 {
22061 /* No need to mention EOL here--the terminal never needs
22062 to do EOL conversion. */
22063 p = decode_mode_spec_coding (CODING_ID_NAME
22064 (FRAME_KEYBOARD_CODING (f)->id),
22065 p, 0);
22066 p = decode_mode_spec_coding (CODING_ID_NAME
22067 (FRAME_TERMINAL_CODING (f)->id),
22068 p, 0);
22069 }
22070 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
22071 p, eol_flag);
22072
22073 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22074 #ifdef subprocesses
22075 obj = Fget_buffer_process (Fcurrent_buffer ());
22076 if (PROCESSP (obj))
22077 {
22078 p = decode_mode_spec_coding
22079 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
22080 p = decode_mode_spec_coding
22081 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
22082 }
22083 #endif /* subprocesses */
22084 #endif /* 0 */
22085 *p = 0;
22086 return decode_mode_spec_buf;
22087 }
22088 }
22089
22090 if (STRINGP (obj))
22091 {
22092 *string = obj;
22093 return SSDATA (obj);
22094 }
22095 else
22096 return "";
22097 }
22098
22099
22100 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22101 means count lines back from START_BYTE. But don't go beyond
22102 LIMIT_BYTE. Return the number of lines thus found (always
22103 nonnegative).
22104
22105 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22106 either the position COUNT lines after/before START_BYTE, if we
22107 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22108 COUNT lines. */
22109
22110 static ptrdiff_t
22111 display_count_lines (ptrdiff_t start_byte,
22112 ptrdiff_t limit_byte, ptrdiff_t count,
22113 ptrdiff_t *byte_pos_ptr)
22114 {
22115 register unsigned char *cursor;
22116 unsigned char *base;
22117
22118 register ptrdiff_t ceiling;
22119 register unsigned char *ceiling_addr;
22120 ptrdiff_t orig_count = count;
22121
22122 /* If we are not in selective display mode,
22123 check only for newlines. */
22124 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
22125 && !INTEGERP (BVAR (current_buffer, selective_display)));
22126
22127 if (count > 0)
22128 {
22129 while (start_byte < limit_byte)
22130 {
22131 ceiling = BUFFER_CEILING_OF (start_byte);
22132 ceiling = min (limit_byte - 1, ceiling);
22133 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
22134 base = (cursor = BYTE_POS_ADDR (start_byte));
22135
22136 do
22137 {
22138 if (selective_display)
22139 {
22140 while (*cursor != '\n' && *cursor != 015
22141 && ++cursor != ceiling_addr)
22142 continue;
22143 if (cursor == ceiling_addr)
22144 break;
22145 }
22146 else
22147 {
22148 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
22149 if (! cursor)
22150 break;
22151 }
22152
22153 cursor++;
22154
22155 if (--count == 0)
22156 {
22157 start_byte += cursor - base;
22158 *byte_pos_ptr = start_byte;
22159 return orig_count;
22160 }
22161 }
22162 while (cursor < ceiling_addr);
22163
22164 start_byte += ceiling_addr - base;
22165 }
22166 }
22167 else
22168 {
22169 while (start_byte > limit_byte)
22170 {
22171 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
22172 ceiling = max (limit_byte, ceiling);
22173 ceiling_addr = BYTE_POS_ADDR (ceiling);
22174 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
22175 while (1)
22176 {
22177 if (selective_display)
22178 {
22179 while (--cursor >= ceiling_addr
22180 && *cursor != '\n' && *cursor != 015)
22181 continue;
22182 if (cursor < ceiling_addr)
22183 break;
22184 }
22185 else
22186 {
22187 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
22188 if (! cursor)
22189 break;
22190 }
22191
22192 if (++count == 0)
22193 {
22194 start_byte += cursor - base + 1;
22195 *byte_pos_ptr = start_byte;
22196 /* When scanning backwards, we should
22197 not count the newline posterior to which we stop. */
22198 return - orig_count - 1;
22199 }
22200 }
22201 start_byte += ceiling_addr - base;
22202 }
22203 }
22204
22205 *byte_pos_ptr = limit_byte;
22206
22207 if (count < 0)
22208 return - orig_count + count;
22209 return orig_count - count;
22210
22211 }
22212
22213
22214 \f
22215 /***********************************************************************
22216 Displaying strings
22217 ***********************************************************************/
22218
22219 /* Display a NUL-terminated string, starting with index START.
22220
22221 If STRING is non-null, display that C string. Otherwise, the Lisp
22222 string LISP_STRING is displayed. There's a case that STRING is
22223 non-null and LISP_STRING is not nil. It means STRING is a string
22224 data of LISP_STRING. In that case, we display LISP_STRING while
22225 ignoring its text properties.
22226
22227 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22228 FACE_STRING. Display STRING or LISP_STRING with the face at
22229 FACE_STRING_POS in FACE_STRING:
22230
22231 Display the string in the environment given by IT, but use the
22232 standard display table, temporarily.
22233
22234 FIELD_WIDTH is the minimum number of output glyphs to produce.
22235 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22236 with spaces. If STRING has more characters, more than FIELD_WIDTH
22237 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22238
22239 PRECISION is the maximum number of characters to output from
22240 STRING. PRECISION < 0 means don't truncate the string.
22241
22242 This is roughly equivalent to printf format specifiers:
22243
22244 FIELD_WIDTH PRECISION PRINTF
22245 ----------------------------------------
22246 -1 -1 %s
22247 -1 10 %.10s
22248 10 -1 %10s
22249 20 10 %20.10s
22250
22251 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22252 display them, and < 0 means obey the current buffer's value of
22253 enable_multibyte_characters.
22254
22255 Value is the number of columns displayed. */
22256
22257 static int
22258 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
22259 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
22260 int field_width, int precision, int max_x, int multibyte)
22261 {
22262 int hpos_at_start = it->hpos;
22263 int saved_face_id = it->face_id;
22264 struct glyph_row *row = it->glyph_row;
22265 ptrdiff_t it_charpos;
22266
22267 /* Initialize the iterator IT for iteration over STRING beginning
22268 with index START. */
22269 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22270 precision, field_width, multibyte);
22271 if (string && STRINGP (lisp_string))
22272 /* LISP_STRING is the one returned by decode_mode_spec. We should
22273 ignore its text properties. */
22274 it->stop_charpos = it->end_charpos;
22275
22276 /* If displaying STRING, set up the face of the iterator from
22277 FACE_STRING, if that's given. */
22278 if (STRINGP (face_string))
22279 {
22280 ptrdiff_t endptr;
22281 struct face *face;
22282
22283 it->face_id
22284 = face_at_string_position (it->w, face_string, face_string_pos,
22285 0, it->region_beg_charpos,
22286 it->region_end_charpos,
22287 &endptr, it->base_face_id, 0);
22288 face = FACE_FROM_ID (it->f, it->face_id);
22289 it->face_box_p = face->box != FACE_NO_BOX;
22290 }
22291
22292 /* Set max_x to the maximum allowed X position. Don't let it go
22293 beyond the right edge of the window. */
22294 if (max_x <= 0)
22295 max_x = it->last_visible_x;
22296 else
22297 max_x = min (max_x, it->last_visible_x);
22298
22299 /* Skip over display elements that are not visible. because IT->w is
22300 hscrolled. */
22301 if (it->current_x < it->first_visible_x)
22302 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22303 MOVE_TO_POS | MOVE_TO_X);
22304
22305 row->ascent = it->max_ascent;
22306 row->height = it->max_ascent + it->max_descent;
22307 row->phys_ascent = it->max_phys_ascent;
22308 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22309 row->extra_line_spacing = it->max_extra_line_spacing;
22310
22311 if (STRINGP (it->string))
22312 it_charpos = IT_STRING_CHARPOS (*it);
22313 else
22314 it_charpos = IT_CHARPOS (*it);
22315
22316 /* This condition is for the case that we are called with current_x
22317 past last_visible_x. */
22318 while (it->current_x < max_x)
22319 {
22320 int x_before, x, n_glyphs_before, i, nglyphs;
22321
22322 /* Get the next display element. */
22323 if (!get_next_display_element (it))
22324 break;
22325
22326 /* Produce glyphs. */
22327 x_before = it->current_x;
22328 n_glyphs_before = row->used[TEXT_AREA];
22329 PRODUCE_GLYPHS (it);
22330
22331 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22332 i = 0;
22333 x = x_before;
22334 while (i < nglyphs)
22335 {
22336 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22337
22338 if (it->line_wrap != TRUNCATE
22339 && x + glyph->pixel_width > max_x)
22340 {
22341 /* End of continued line or max_x reached. */
22342 if (CHAR_GLYPH_PADDING_P (*glyph))
22343 {
22344 /* A wide character is unbreakable. */
22345 if (row->reversed_p)
22346 unproduce_glyphs (it, row->used[TEXT_AREA]
22347 - n_glyphs_before);
22348 row->used[TEXT_AREA] = n_glyphs_before;
22349 it->current_x = x_before;
22350 }
22351 else
22352 {
22353 if (row->reversed_p)
22354 unproduce_glyphs (it, row->used[TEXT_AREA]
22355 - (n_glyphs_before + i));
22356 row->used[TEXT_AREA] = n_glyphs_before + i;
22357 it->current_x = x;
22358 }
22359 break;
22360 }
22361 else if (x + glyph->pixel_width >= it->first_visible_x)
22362 {
22363 /* Glyph is at least partially visible. */
22364 ++it->hpos;
22365 if (x < it->first_visible_x)
22366 row->x = x - it->first_visible_x;
22367 }
22368 else
22369 {
22370 /* Glyph is off the left margin of the display area.
22371 Should not happen. */
22372 emacs_abort ();
22373 }
22374
22375 row->ascent = max (row->ascent, it->max_ascent);
22376 row->height = max (row->height, it->max_ascent + it->max_descent);
22377 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22378 row->phys_height = max (row->phys_height,
22379 it->max_phys_ascent + it->max_phys_descent);
22380 row->extra_line_spacing = max (row->extra_line_spacing,
22381 it->max_extra_line_spacing);
22382 x += glyph->pixel_width;
22383 ++i;
22384 }
22385
22386 /* Stop if max_x reached. */
22387 if (i < nglyphs)
22388 break;
22389
22390 /* Stop at line ends. */
22391 if (ITERATOR_AT_END_OF_LINE_P (it))
22392 {
22393 it->continuation_lines_width = 0;
22394 break;
22395 }
22396
22397 set_iterator_to_next (it, 1);
22398 if (STRINGP (it->string))
22399 it_charpos = IT_STRING_CHARPOS (*it);
22400 else
22401 it_charpos = IT_CHARPOS (*it);
22402
22403 /* Stop if truncating at the right edge. */
22404 if (it->line_wrap == TRUNCATE
22405 && it->current_x >= it->last_visible_x)
22406 {
22407 /* Add truncation mark, but don't do it if the line is
22408 truncated at a padding space. */
22409 if (it_charpos < it->string_nchars)
22410 {
22411 if (!FRAME_WINDOW_P (it->f))
22412 {
22413 int ii, n;
22414
22415 if (it->current_x > it->last_visible_x)
22416 {
22417 if (!row->reversed_p)
22418 {
22419 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22420 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22421 break;
22422 }
22423 else
22424 {
22425 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22426 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22427 break;
22428 unproduce_glyphs (it, ii + 1);
22429 ii = row->used[TEXT_AREA] - (ii + 1);
22430 }
22431 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22432 {
22433 row->used[TEXT_AREA] = ii;
22434 produce_special_glyphs (it, IT_TRUNCATION);
22435 }
22436 }
22437 produce_special_glyphs (it, IT_TRUNCATION);
22438 }
22439 row->truncated_on_right_p = 1;
22440 }
22441 break;
22442 }
22443 }
22444
22445 /* Maybe insert a truncation at the left. */
22446 if (it->first_visible_x
22447 && it_charpos > 0)
22448 {
22449 if (!FRAME_WINDOW_P (it->f)
22450 || (row->reversed_p
22451 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22452 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22453 insert_left_trunc_glyphs (it);
22454 row->truncated_on_left_p = 1;
22455 }
22456
22457 it->face_id = saved_face_id;
22458
22459 /* Value is number of columns displayed. */
22460 return it->hpos - hpos_at_start;
22461 }
22462
22463
22464 \f
22465 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22466 appears as an element of LIST or as the car of an element of LIST.
22467 If PROPVAL is a list, compare each element against LIST in that
22468 way, and return 1/2 if any element of PROPVAL is found in LIST.
22469 Otherwise return 0. This function cannot quit.
22470 The return value is 2 if the text is invisible but with an ellipsis
22471 and 1 if it's invisible and without an ellipsis. */
22472
22473 int
22474 invisible_p (register Lisp_Object propval, Lisp_Object list)
22475 {
22476 register Lisp_Object tail, proptail;
22477
22478 for (tail = list; CONSP (tail); tail = XCDR (tail))
22479 {
22480 register Lisp_Object tem;
22481 tem = XCAR (tail);
22482 if (EQ (propval, tem))
22483 return 1;
22484 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22485 return NILP (XCDR (tem)) ? 1 : 2;
22486 }
22487
22488 if (CONSP (propval))
22489 {
22490 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22491 {
22492 Lisp_Object propelt;
22493 propelt = XCAR (proptail);
22494 for (tail = list; CONSP (tail); tail = XCDR (tail))
22495 {
22496 register Lisp_Object tem;
22497 tem = XCAR (tail);
22498 if (EQ (propelt, tem))
22499 return 1;
22500 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22501 return NILP (XCDR (tem)) ? 1 : 2;
22502 }
22503 }
22504 }
22505
22506 return 0;
22507 }
22508
22509 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22510 doc: /* Non-nil if the property makes the text invisible.
22511 POS-OR-PROP can be a marker or number, in which case it is taken to be
22512 a position in the current buffer and the value of the `invisible' property
22513 is checked; or it can be some other value, which is then presumed to be the
22514 value of the `invisible' property of the text of interest.
22515 The non-nil value returned can be t for truly invisible text or something
22516 else if the text is replaced by an ellipsis. */)
22517 (Lisp_Object pos_or_prop)
22518 {
22519 Lisp_Object prop
22520 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22521 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22522 : pos_or_prop);
22523 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22524 return (invis == 0 ? Qnil
22525 : invis == 1 ? Qt
22526 : make_number (invis));
22527 }
22528
22529 /* Calculate a width or height in pixels from a specification using
22530 the following elements:
22531
22532 SPEC ::=
22533 NUM - a (fractional) multiple of the default font width/height
22534 (NUM) - specifies exactly NUM pixels
22535 UNIT - a fixed number of pixels, see below.
22536 ELEMENT - size of a display element in pixels, see below.
22537 (NUM . SPEC) - equals NUM * SPEC
22538 (+ SPEC SPEC ...) - add pixel values
22539 (- SPEC SPEC ...) - subtract pixel values
22540 (- SPEC) - negate pixel value
22541
22542 NUM ::=
22543 INT or FLOAT - a number constant
22544 SYMBOL - use symbol's (buffer local) variable binding.
22545
22546 UNIT ::=
22547 in - pixels per inch *)
22548 mm - pixels per 1/1000 meter *)
22549 cm - pixels per 1/100 meter *)
22550 width - width of current font in pixels.
22551 height - height of current font in pixels.
22552
22553 *) using the ratio(s) defined in display-pixels-per-inch.
22554
22555 ELEMENT ::=
22556
22557 left-fringe - left fringe width in pixels
22558 right-fringe - right fringe width in pixels
22559
22560 left-margin - left margin width in pixels
22561 right-margin - right margin width in pixels
22562
22563 scroll-bar - scroll-bar area width in pixels
22564
22565 Examples:
22566
22567 Pixels corresponding to 5 inches:
22568 (5 . in)
22569
22570 Total width of non-text areas on left side of window (if scroll-bar is on left):
22571 '(space :width (+ left-fringe left-margin scroll-bar))
22572
22573 Align to first text column (in header line):
22574 '(space :align-to 0)
22575
22576 Align to middle of text area minus half the width of variable `my-image'
22577 containing a loaded image:
22578 '(space :align-to (0.5 . (- text my-image)))
22579
22580 Width of left margin minus width of 1 character in the default font:
22581 '(space :width (- left-margin 1))
22582
22583 Width of left margin minus width of 2 characters in the current font:
22584 '(space :width (- left-margin (2 . width)))
22585
22586 Center 1 character over left-margin (in header line):
22587 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22588
22589 Different ways to express width of left fringe plus left margin minus one pixel:
22590 '(space :width (- (+ left-fringe left-margin) (1)))
22591 '(space :width (+ left-fringe left-margin (- (1))))
22592 '(space :width (+ left-fringe left-margin (-1)))
22593
22594 */
22595
22596 static int
22597 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22598 struct font *font, int width_p, int *align_to)
22599 {
22600 double pixels;
22601
22602 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22603 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22604
22605 if (NILP (prop))
22606 return OK_PIXELS (0);
22607
22608 eassert (FRAME_LIVE_P (it->f));
22609
22610 if (SYMBOLP (prop))
22611 {
22612 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22613 {
22614 char *unit = SSDATA (SYMBOL_NAME (prop));
22615
22616 if (unit[0] == 'i' && unit[1] == 'n')
22617 pixels = 1.0;
22618 else if (unit[0] == 'm' && unit[1] == 'm')
22619 pixels = 25.4;
22620 else if (unit[0] == 'c' && unit[1] == 'm')
22621 pixels = 2.54;
22622 else
22623 pixels = 0;
22624 if (pixels > 0)
22625 {
22626 double ppi = (width_p ? FRAME_RES_X (it->f)
22627 : FRAME_RES_Y (it->f));
22628
22629 if (ppi > 0)
22630 return OK_PIXELS (ppi / pixels);
22631 return 0;
22632 }
22633 }
22634
22635 #ifdef HAVE_WINDOW_SYSTEM
22636 if (EQ (prop, Qheight))
22637 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22638 if (EQ (prop, Qwidth))
22639 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22640 #else
22641 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22642 return OK_PIXELS (1);
22643 #endif
22644
22645 if (EQ (prop, Qtext))
22646 return OK_PIXELS (width_p
22647 ? window_box_width (it->w, TEXT_AREA)
22648 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22649
22650 if (align_to && *align_to < 0)
22651 {
22652 *res = 0;
22653 if (EQ (prop, Qleft))
22654 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22655 if (EQ (prop, Qright))
22656 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22657 if (EQ (prop, Qcenter))
22658 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22659 + window_box_width (it->w, TEXT_AREA) / 2);
22660 if (EQ (prop, Qleft_fringe))
22661 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22662 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22663 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22664 if (EQ (prop, Qright_fringe))
22665 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22666 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22667 : window_box_right_offset (it->w, TEXT_AREA));
22668 if (EQ (prop, Qleft_margin))
22669 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22670 if (EQ (prop, Qright_margin))
22671 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22672 if (EQ (prop, Qscroll_bar))
22673 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22674 ? 0
22675 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22676 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22677 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22678 : 0)));
22679 }
22680 else
22681 {
22682 if (EQ (prop, Qleft_fringe))
22683 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22684 if (EQ (prop, Qright_fringe))
22685 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22686 if (EQ (prop, Qleft_margin))
22687 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22688 if (EQ (prop, Qright_margin))
22689 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22690 if (EQ (prop, Qscroll_bar))
22691 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22692 }
22693
22694 prop = buffer_local_value_1 (prop, it->w->contents);
22695 if (EQ (prop, Qunbound))
22696 prop = Qnil;
22697 }
22698
22699 if (INTEGERP (prop) || FLOATP (prop))
22700 {
22701 int base_unit = (width_p
22702 ? FRAME_COLUMN_WIDTH (it->f)
22703 : FRAME_LINE_HEIGHT (it->f));
22704 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22705 }
22706
22707 if (CONSP (prop))
22708 {
22709 Lisp_Object car = XCAR (prop);
22710 Lisp_Object cdr = XCDR (prop);
22711
22712 if (SYMBOLP (car))
22713 {
22714 #ifdef HAVE_WINDOW_SYSTEM
22715 if (FRAME_WINDOW_P (it->f)
22716 && valid_image_p (prop))
22717 {
22718 ptrdiff_t id = lookup_image (it->f, prop);
22719 struct image *img = IMAGE_FROM_ID (it->f, id);
22720
22721 return OK_PIXELS (width_p ? img->width : img->height);
22722 }
22723 #endif
22724 if (EQ (car, Qplus) || EQ (car, Qminus))
22725 {
22726 int first = 1;
22727 double px;
22728
22729 pixels = 0;
22730 while (CONSP (cdr))
22731 {
22732 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22733 font, width_p, align_to))
22734 return 0;
22735 if (first)
22736 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22737 else
22738 pixels += px;
22739 cdr = XCDR (cdr);
22740 }
22741 if (EQ (car, Qminus))
22742 pixels = -pixels;
22743 return OK_PIXELS (pixels);
22744 }
22745
22746 car = buffer_local_value_1 (car, it->w->contents);
22747 if (EQ (car, Qunbound))
22748 car = Qnil;
22749 }
22750
22751 if (INTEGERP (car) || FLOATP (car))
22752 {
22753 double fact;
22754 pixels = XFLOATINT (car);
22755 if (NILP (cdr))
22756 return OK_PIXELS (pixels);
22757 if (calc_pixel_width_or_height (&fact, it, cdr,
22758 font, width_p, align_to))
22759 return OK_PIXELS (pixels * fact);
22760 return 0;
22761 }
22762
22763 return 0;
22764 }
22765
22766 return 0;
22767 }
22768
22769 \f
22770 /***********************************************************************
22771 Glyph Display
22772 ***********************************************************************/
22773
22774 #ifdef HAVE_WINDOW_SYSTEM
22775
22776 #ifdef GLYPH_DEBUG
22777
22778 void
22779 dump_glyph_string (struct glyph_string *s)
22780 {
22781 fprintf (stderr, "glyph string\n");
22782 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22783 s->x, s->y, s->width, s->height);
22784 fprintf (stderr, " ybase = %d\n", s->ybase);
22785 fprintf (stderr, " hl = %d\n", s->hl);
22786 fprintf (stderr, " left overhang = %d, right = %d\n",
22787 s->left_overhang, s->right_overhang);
22788 fprintf (stderr, " nchars = %d\n", s->nchars);
22789 fprintf (stderr, " extends to end of line = %d\n",
22790 s->extends_to_end_of_line_p);
22791 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22792 fprintf (stderr, " bg width = %d\n", s->background_width);
22793 }
22794
22795 #endif /* GLYPH_DEBUG */
22796
22797 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22798 of XChar2b structures for S; it can't be allocated in
22799 init_glyph_string because it must be allocated via `alloca'. W
22800 is the window on which S is drawn. ROW and AREA are the glyph row
22801 and area within the row from which S is constructed. START is the
22802 index of the first glyph structure covered by S. HL is a
22803 face-override for drawing S. */
22804
22805 #ifdef HAVE_NTGUI
22806 #define OPTIONAL_HDC(hdc) HDC hdc,
22807 #define DECLARE_HDC(hdc) HDC hdc;
22808 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22809 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22810 #endif
22811
22812 #ifndef OPTIONAL_HDC
22813 #define OPTIONAL_HDC(hdc)
22814 #define DECLARE_HDC(hdc)
22815 #define ALLOCATE_HDC(hdc, f)
22816 #define RELEASE_HDC(hdc, f)
22817 #endif
22818
22819 static void
22820 init_glyph_string (struct glyph_string *s,
22821 OPTIONAL_HDC (hdc)
22822 XChar2b *char2b, struct window *w, struct glyph_row *row,
22823 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22824 {
22825 memset (s, 0, sizeof *s);
22826 s->w = w;
22827 s->f = XFRAME (w->frame);
22828 #ifdef HAVE_NTGUI
22829 s->hdc = hdc;
22830 #endif
22831 s->display = FRAME_X_DISPLAY (s->f);
22832 s->window = FRAME_X_WINDOW (s->f);
22833 s->char2b = char2b;
22834 s->hl = hl;
22835 s->row = row;
22836 s->area = area;
22837 s->first_glyph = row->glyphs[area] + start;
22838 s->height = row->height;
22839 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22840 s->ybase = s->y + row->ascent;
22841 }
22842
22843
22844 /* Append the list of glyph strings with head H and tail T to the list
22845 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22846
22847 static void
22848 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22849 struct glyph_string *h, struct glyph_string *t)
22850 {
22851 if (h)
22852 {
22853 if (*head)
22854 (*tail)->next = h;
22855 else
22856 *head = h;
22857 h->prev = *tail;
22858 *tail = t;
22859 }
22860 }
22861
22862
22863 /* Prepend the list of glyph strings with head H and tail T to the
22864 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22865 result. */
22866
22867 static void
22868 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22869 struct glyph_string *h, struct glyph_string *t)
22870 {
22871 if (h)
22872 {
22873 if (*head)
22874 (*head)->prev = t;
22875 else
22876 *tail = t;
22877 t->next = *head;
22878 *head = h;
22879 }
22880 }
22881
22882
22883 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22884 Set *HEAD and *TAIL to the resulting list. */
22885
22886 static void
22887 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22888 struct glyph_string *s)
22889 {
22890 s->next = s->prev = NULL;
22891 append_glyph_string_lists (head, tail, s, s);
22892 }
22893
22894
22895 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22896 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22897 make sure that X resources for the face returned are allocated.
22898 Value is a pointer to a realized face that is ready for display if
22899 DISPLAY_P is non-zero. */
22900
22901 static struct face *
22902 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22903 XChar2b *char2b, int display_p)
22904 {
22905 struct face *face = FACE_FROM_ID (f, face_id);
22906 unsigned code = 0;
22907
22908 if (face->font)
22909 {
22910 code = face->font->driver->encode_char (face->font, c);
22911
22912 if (code == FONT_INVALID_CODE)
22913 code = 0;
22914 }
22915 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22916
22917 /* Make sure X resources of the face are allocated. */
22918 #ifdef HAVE_X_WINDOWS
22919 if (display_p)
22920 #endif
22921 {
22922 eassert (face != NULL);
22923 PREPARE_FACE_FOR_DISPLAY (f, face);
22924 }
22925
22926 return face;
22927 }
22928
22929
22930 /* Get face and two-byte form of character glyph GLYPH on frame F.
22931 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22932 a pointer to a realized face that is ready for display. */
22933
22934 static struct face *
22935 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22936 XChar2b *char2b, int *two_byte_p)
22937 {
22938 struct face *face;
22939 unsigned code = 0;
22940
22941 eassert (glyph->type == CHAR_GLYPH);
22942 face = FACE_FROM_ID (f, glyph->face_id);
22943
22944 /* Make sure X resources of the face are allocated. */
22945 eassert (face != NULL);
22946 PREPARE_FACE_FOR_DISPLAY (f, face);
22947
22948 if (two_byte_p)
22949 *two_byte_p = 0;
22950
22951 if (face->font)
22952 {
22953 if (CHAR_BYTE8_P (glyph->u.ch))
22954 code = CHAR_TO_BYTE8 (glyph->u.ch);
22955 else
22956 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22957
22958 if (code == FONT_INVALID_CODE)
22959 code = 0;
22960 }
22961
22962 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22963 return face;
22964 }
22965
22966
22967 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22968 Return 1 if FONT has a glyph for C, otherwise return 0. */
22969
22970 static int
22971 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22972 {
22973 unsigned code;
22974
22975 if (CHAR_BYTE8_P (c))
22976 code = CHAR_TO_BYTE8 (c);
22977 else
22978 code = font->driver->encode_char (font, c);
22979
22980 if (code == FONT_INVALID_CODE)
22981 return 0;
22982 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22983 return 1;
22984 }
22985
22986
22987 /* Fill glyph string S with composition components specified by S->cmp.
22988
22989 BASE_FACE is the base face of the composition.
22990 S->cmp_from is the index of the first component for S.
22991
22992 OVERLAPS non-zero means S should draw the foreground only, and use
22993 its physical height for clipping. See also draw_glyphs.
22994
22995 Value is the index of a component not in S. */
22996
22997 static int
22998 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22999 int overlaps)
23000 {
23001 int i;
23002 /* For all glyphs of this composition, starting at the offset
23003 S->cmp_from, until we reach the end of the definition or encounter a
23004 glyph that requires the different face, add it to S. */
23005 struct face *face;
23006
23007 eassert (s);
23008
23009 s->for_overlaps = overlaps;
23010 s->face = NULL;
23011 s->font = NULL;
23012 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
23013 {
23014 int c = COMPOSITION_GLYPH (s->cmp, i);
23015
23016 /* TAB in a composition means display glyphs with padding space
23017 on the left or right. */
23018 if (c != '\t')
23019 {
23020 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23021 -1, Qnil);
23022
23023 face = get_char_face_and_encoding (s->f, c, face_id,
23024 s->char2b + i, 1);
23025 if (face)
23026 {
23027 if (! s->face)
23028 {
23029 s->face = face;
23030 s->font = s->face->font;
23031 }
23032 else if (s->face != face)
23033 break;
23034 }
23035 }
23036 ++s->nchars;
23037 }
23038 s->cmp_to = i;
23039
23040 if (s->face == NULL)
23041 {
23042 s->face = base_face->ascii_face;
23043 s->font = s->face->font;
23044 }
23045
23046 /* All glyph strings for the same composition has the same width,
23047 i.e. the width set for the first component of the composition. */
23048 s->width = s->first_glyph->pixel_width;
23049
23050 /* If the specified font could not be loaded, use the frame's
23051 default font, but record the fact that we couldn't load it in
23052 the glyph string so that we can draw rectangles for the
23053 characters of the glyph string. */
23054 if (s->font == NULL)
23055 {
23056 s->font_not_found_p = 1;
23057 s->font = FRAME_FONT (s->f);
23058 }
23059
23060 /* Adjust base line for subscript/superscript text. */
23061 s->ybase += s->first_glyph->voffset;
23062
23063 /* This glyph string must always be drawn with 16-bit functions. */
23064 s->two_byte_p = 1;
23065
23066 return s->cmp_to;
23067 }
23068
23069 static int
23070 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
23071 int start, int end, int overlaps)
23072 {
23073 struct glyph *glyph, *last;
23074 Lisp_Object lgstring;
23075 int i;
23076
23077 s->for_overlaps = overlaps;
23078 glyph = s->row->glyphs[s->area] + start;
23079 last = s->row->glyphs[s->area] + end;
23080 s->cmp_id = glyph->u.cmp.id;
23081 s->cmp_from = glyph->slice.cmp.from;
23082 s->cmp_to = glyph->slice.cmp.to + 1;
23083 s->face = FACE_FROM_ID (s->f, face_id);
23084 lgstring = composition_gstring_from_id (s->cmp_id);
23085 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
23086 glyph++;
23087 while (glyph < last
23088 && glyph->u.cmp.automatic
23089 && glyph->u.cmp.id == s->cmp_id
23090 && s->cmp_to == glyph->slice.cmp.from)
23091 s->cmp_to = (glyph++)->slice.cmp.to + 1;
23092
23093 for (i = s->cmp_from; i < s->cmp_to; i++)
23094 {
23095 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
23096 unsigned code = LGLYPH_CODE (lglyph);
23097
23098 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
23099 }
23100 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
23101 return glyph - s->row->glyphs[s->area];
23102 }
23103
23104
23105 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23106 See the comment of fill_glyph_string for arguments.
23107 Value is the index of the first glyph not in S. */
23108
23109
23110 static int
23111 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
23112 int start, int end, int overlaps)
23113 {
23114 struct glyph *glyph, *last;
23115 int voffset;
23116
23117 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
23118 s->for_overlaps = overlaps;
23119 glyph = s->row->glyphs[s->area] + start;
23120 last = s->row->glyphs[s->area] + end;
23121 voffset = glyph->voffset;
23122 s->face = FACE_FROM_ID (s->f, face_id);
23123 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
23124 s->nchars = 1;
23125 s->width = glyph->pixel_width;
23126 glyph++;
23127 while (glyph < last
23128 && glyph->type == GLYPHLESS_GLYPH
23129 && glyph->voffset == voffset
23130 && glyph->face_id == face_id)
23131 {
23132 s->nchars++;
23133 s->width += glyph->pixel_width;
23134 glyph++;
23135 }
23136 s->ybase += voffset;
23137 return glyph - s->row->glyphs[s->area];
23138 }
23139
23140
23141 /* Fill glyph string S from a sequence of character glyphs.
23142
23143 FACE_ID is the face id of the string. START is the index of the
23144 first glyph to consider, END is the index of the last + 1.
23145 OVERLAPS non-zero means S should draw the foreground only, and use
23146 its physical height for clipping. See also draw_glyphs.
23147
23148 Value is the index of the first glyph not in S. */
23149
23150 static int
23151 fill_glyph_string (struct glyph_string *s, int face_id,
23152 int start, int end, int overlaps)
23153 {
23154 struct glyph *glyph, *last;
23155 int voffset;
23156 int glyph_not_available_p;
23157
23158 eassert (s->f == XFRAME (s->w->frame));
23159 eassert (s->nchars == 0);
23160 eassert (start >= 0 && end > start);
23161
23162 s->for_overlaps = overlaps;
23163 glyph = s->row->glyphs[s->area] + start;
23164 last = s->row->glyphs[s->area] + end;
23165 voffset = glyph->voffset;
23166 s->padding_p = glyph->padding_p;
23167 glyph_not_available_p = glyph->glyph_not_available_p;
23168
23169 while (glyph < last
23170 && glyph->type == CHAR_GLYPH
23171 && glyph->voffset == voffset
23172 /* Same face id implies same font, nowadays. */
23173 && glyph->face_id == face_id
23174 && glyph->glyph_not_available_p == glyph_not_available_p)
23175 {
23176 int two_byte_p;
23177
23178 s->face = get_glyph_face_and_encoding (s->f, glyph,
23179 s->char2b + s->nchars,
23180 &two_byte_p);
23181 s->two_byte_p = two_byte_p;
23182 ++s->nchars;
23183 eassert (s->nchars <= end - start);
23184 s->width += glyph->pixel_width;
23185 if (glyph++->padding_p != s->padding_p)
23186 break;
23187 }
23188
23189 s->font = s->face->font;
23190
23191 /* If the specified font could not be loaded, use the frame's font,
23192 but record the fact that we couldn't load it in
23193 S->font_not_found_p so that we can draw rectangles for the
23194 characters of the glyph string. */
23195 if (s->font == NULL || glyph_not_available_p)
23196 {
23197 s->font_not_found_p = 1;
23198 s->font = FRAME_FONT (s->f);
23199 }
23200
23201 /* Adjust base line for subscript/superscript text. */
23202 s->ybase += voffset;
23203
23204 eassert (s->face && s->face->gc);
23205 return glyph - s->row->glyphs[s->area];
23206 }
23207
23208
23209 /* Fill glyph string S from image glyph S->first_glyph. */
23210
23211 static void
23212 fill_image_glyph_string (struct glyph_string *s)
23213 {
23214 eassert (s->first_glyph->type == IMAGE_GLYPH);
23215 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
23216 eassert (s->img);
23217 s->slice = s->first_glyph->slice.img;
23218 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
23219 s->font = s->face->font;
23220 s->width = s->first_glyph->pixel_width;
23221
23222 /* Adjust base line for subscript/superscript text. */
23223 s->ybase += s->first_glyph->voffset;
23224 }
23225
23226
23227 /* Fill glyph string S from a sequence of stretch glyphs.
23228
23229 START is the index of the first glyph to consider,
23230 END is the index of the last + 1.
23231
23232 Value is the index of the first glyph not in S. */
23233
23234 static int
23235 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23236 {
23237 struct glyph *glyph, *last;
23238 int voffset, face_id;
23239
23240 eassert (s->first_glyph->type == STRETCH_GLYPH);
23241
23242 glyph = s->row->glyphs[s->area] + start;
23243 last = s->row->glyphs[s->area] + end;
23244 face_id = glyph->face_id;
23245 s->face = FACE_FROM_ID (s->f, face_id);
23246 s->font = s->face->font;
23247 s->width = glyph->pixel_width;
23248 s->nchars = 1;
23249 voffset = glyph->voffset;
23250
23251 for (++glyph;
23252 (glyph < last
23253 && glyph->type == STRETCH_GLYPH
23254 && glyph->voffset == voffset
23255 && glyph->face_id == face_id);
23256 ++glyph)
23257 s->width += glyph->pixel_width;
23258
23259 /* Adjust base line for subscript/superscript text. */
23260 s->ybase += voffset;
23261
23262 /* The case that face->gc == 0 is handled when drawing the glyph
23263 string by calling PREPARE_FACE_FOR_DISPLAY. */
23264 eassert (s->face);
23265 return glyph - s->row->glyphs[s->area];
23266 }
23267
23268 static struct font_metrics *
23269 get_per_char_metric (struct font *font, XChar2b *char2b)
23270 {
23271 static struct font_metrics metrics;
23272 unsigned code;
23273
23274 if (! font)
23275 return NULL;
23276 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23277 if (code == FONT_INVALID_CODE)
23278 return NULL;
23279 font->driver->text_extents (font, &code, 1, &metrics);
23280 return &metrics;
23281 }
23282
23283 /* EXPORT for RIF:
23284 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23285 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23286 assumed to be zero. */
23287
23288 void
23289 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23290 {
23291 *left = *right = 0;
23292
23293 if (glyph->type == CHAR_GLYPH)
23294 {
23295 struct face *face;
23296 XChar2b char2b;
23297 struct font_metrics *pcm;
23298
23299 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23300 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23301 {
23302 if (pcm->rbearing > pcm->width)
23303 *right = pcm->rbearing - pcm->width;
23304 if (pcm->lbearing < 0)
23305 *left = -pcm->lbearing;
23306 }
23307 }
23308 else if (glyph->type == COMPOSITE_GLYPH)
23309 {
23310 if (! glyph->u.cmp.automatic)
23311 {
23312 struct composition *cmp = composition_table[glyph->u.cmp.id];
23313
23314 if (cmp->rbearing > cmp->pixel_width)
23315 *right = cmp->rbearing - cmp->pixel_width;
23316 if (cmp->lbearing < 0)
23317 *left = - cmp->lbearing;
23318 }
23319 else
23320 {
23321 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23322 struct font_metrics metrics;
23323
23324 composition_gstring_width (gstring, glyph->slice.cmp.from,
23325 glyph->slice.cmp.to + 1, &metrics);
23326 if (metrics.rbearing > metrics.width)
23327 *right = metrics.rbearing - metrics.width;
23328 if (metrics.lbearing < 0)
23329 *left = - metrics.lbearing;
23330 }
23331 }
23332 }
23333
23334
23335 /* Return the index of the first glyph preceding glyph string S that
23336 is overwritten by S because of S's left overhang. Value is -1
23337 if no glyphs are overwritten. */
23338
23339 static int
23340 left_overwritten (struct glyph_string *s)
23341 {
23342 int k;
23343
23344 if (s->left_overhang)
23345 {
23346 int x = 0, i;
23347 struct glyph *glyphs = s->row->glyphs[s->area];
23348 int first = s->first_glyph - glyphs;
23349
23350 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23351 x -= glyphs[i].pixel_width;
23352
23353 k = i + 1;
23354 }
23355 else
23356 k = -1;
23357
23358 return k;
23359 }
23360
23361
23362 /* Return the index of the first glyph preceding glyph string S that
23363 is overwriting S because of its right overhang. Value is -1 if no
23364 glyph in front of S overwrites S. */
23365
23366 static int
23367 left_overwriting (struct glyph_string *s)
23368 {
23369 int i, k, x;
23370 struct glyph *glyphs = s->row->glyphs[s->area];
23371 int first = s->first_glyph - glyphs;
23372
23373 k = -1;
23374 x = 0;
23375 for (i = first - 1; i >= 0; --i)
23376 {
23377 int left, right;
23378 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23379 if (x + right > 0)
23380 k = i;
23381 x -= glyphs[i].pixel_width;
23382 }
23383
23384 return k;
23385 }
23386
23387
23388 /* Return the index of the last glyph following glyph string S that is
23389 overwritten by S because of S's right overhang. Value is -1 if
23390 no such glyph is found. */
23391
23392 static int
23393 right_overwritten (struct glyph_string *s)
23394 {
23395 int k = -1;
23396
23397 if (s->right_overhang)
23398 {
23399 int x = 0, i;
23400 struct glyph *glyphs = s->row->glyphs[s->area];
23401 int first = (s->first_glyph - glyphs
23402 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23403 int end = s->row->used[s->area];
23404
23405 for (i = first; i < end && s->right_overhang > x; ++i)
23406 x += glyphs[i].pixel_width;
23407
23408 k = i;
23409 }
23410
23411 return k;
23412 }
23413
23414
23415 /* Return the index of the last glyph following glyph string S that
23416 overwrites S because of its left overhang. Value is negative
23417 if no such glyph is found. */
23418
23419 static int
23420 right_overwriting (struct glyph_string *s)
23421 {
23422 int i, k, x;
23423 int end = s->row->used[s->area];
23424 struct glyph *glyphs = s->row->glyphs[s->area];
23425 int first = (s->first_glyph - glyphs
23426 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23427
23428 k = -1;
23429 x = 0;
23430 for (i = first; i < end; ++i)
23431 {
23432 int left, right;
23433 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23434 if (x - left < 0)
23435 k = i;
23436 x += glyphs[i].pixel_width;
23437 }
23438
23439 return k;
23440 }
23441
23442
23443 /* Set background width of glyph string S. START is the index of the
23444 first glyph following S. LAST_X is the right-most x-position + 1
23445 in the drawing area. */
23446
23447 static void
23448 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23449 {
23450 /* If the face of this glyph string has to be drawn to the end of
23451 the drawing area, set S->extends_to_end_of_line_p. */
23452
23453 if (start == s->row->used[s->area]
23454 && s->area == TEXT_AREA
23455 && ((s->row->fill_line_p
23456 && (s->hl == DRAW_NORMAL_TEXT
23457 || s->hl == DRAW_IMAGE_RAISED
23458 || s->hl == DRAW_IMAGE_SUNKEN))
23459 || s->hl == DRAW_MOUSE_FACE))
23460 s->extends_to_end_of_line_p = 1;
23461
23462 /* If S extends its face to the end of the line, set its
23463 background_width to the distance to the right edge of the drawing
23464 area. */
23465 if (s->extends_to_end_of_line_p)
23466 s->background_width = last_x - s->x + 1;
23467 else
23468 s->background_width = s->width;
23469 }
23470
23471
23472 /* Compute overhangs and x-positions for glyph string S and its
23473 predecessors, or successors. X is the starting x-position for S.
23474 BACKWARD_P non-zero means process predecessors. */
23475
23476 static void
23477 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23478 {
23479 if (backward_p)
23480 {
23481 while (s)
23482 {
23483 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23484 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23485 x -= s->width;
23486 s->x = x;
23487 s = s->prev;
23488 }
23489 }
23490 else
23491 {
23492 while (s)
23493 {
23494 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23495 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23496 s->x = x;
23497 x += s->width;
23498 s = s->next;
23499 }
23500 }
23501 }
23502
23503
23504
23505 /* The following macros are only called from draw_glyphs below.
23506 They reference the following parameters of that function directly:
23507 `w', `row', `area', and `overlap_p'
23508 as well as the following local variables:
23509 `s', `f', and `hdc' (in W32) */
23510
23511 #ifdef HAVE_NTGUI
23512 /* On W32, silently add local `hdc' variable to argument list of
23513 init_glyph_string. */
23514 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23515 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23516 #else
23517 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23518 init_glyph_string (s, char2b, w, row, area, start, hl)
23519 #endif
23520
23521 /* Add a glyph string for a stretch glyph to the list of strings
23522 between HEAD and TAIL. START is the index of the stretch glyph in
23523 row area AREA of glyph row ROW. END is the index of the last glyph
23524 in that glyph row area. X is the current output position assigned
23525 to the new glyph string constructed. HL overrides that face of the
23526 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23527 is the right-most x-position of the drawing area. */
23528
23529 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23530 and below -- keep them on one line. */
23531 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23532 do \
23533 { \
23534 s = alloca (sizeof *s); \
23535 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23536 START = fill_stretch_glyph_string (s, START, END); \
23537 append_glyph_string (&HEAD, &TAIL, s); \
23538 s->x = (X); \
23539 } \
23540 while (0)
23541
23542
23543 /* Add a glyph string for an image glyph to the list of strings
23544 between HEAD and TAIL. START is the index of the image glyph in
23545 row area AREA of glyph row ROW. END is the index of the last glyph
23546 in that glyph row area. X is the current output position assigned
23547 to the new glyph string constructed. HL overrides that face of the
23548 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23549 is the right-most x-position of the drawing area. */
23550
23551 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23552 do \
23553 { \
23554 s = alloca (sizeof *s); \
23555 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23556 fill_image_glyph_string (s); \
23557 append_glyph_string (&HEAD, &TAIL, s); \
23558 ++START; \
23559 s->x = (X); \
23560 } \
23561 while (0)
23562
23563
23564 /* Add a glyph string for a sequence of character glyphs to the list
23565 of strings between HEAD and TAIL. START is the index of the first
23566 glyph in row area AREA of glyph row ROW that is part of the new
23567 glyph string. END is the index of the last glyph in that glyph row
23568 area. X is the current output position assigned to the new glyph
23569 string constructed. HL overrides that face of the glyph; e.g. it
23570 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23571 right-most x-position of the drawing area. */
23572
23573 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23574 do \
23575 { \
23576 int face_id; \
23577 XChar2b *char2b; \
23578 \
23579 face_id = (row)->glyphs[area][START].face_id; \
23580 \
23581 s = alloca (sizeof *s); \
23582 char2b = alloca ((END - START) * sizeof *char2b); \
23583 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23584 append_glyph_string (&HEAD, &TAIL, s); \
23585 s->x = (X); \
23586 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23587 } \
23588 while (0)
23589
23590
23591 /* Add a glyph string for a composite sequence to the list of strings
23592 between HEAD and TAIL. START is the index of the first glyph in
23593 row area AREA of glyph row ROW that is part of the new glyph
23594 string. END is the index of the last glyph in that glyph row area.
23595 X is the current output position assigned to the new glyph string
23596 constructed. HL overrides that face of the glyph; e.g. it is
23597 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23598 x-position of the drawing area. */
23599
23600 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23601 do { \
23602 int face_id = (row)->glyphs[area][START].face_id; \
23603 struct face *base_face = FACE_FROM_ID (f, face_id); \
23604 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23605 struct composition *cmp = composition_table[cmp_id]; \
23606 XChar2b *char2b; \
23607 struct glyph_string *first_s = NULL; \
23608 int n; \
23609 \
23610 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23611 \
23612 /* Make glyph_strings for each glyph sequence that is drawable by \
23613 the same face, and append them to HEAD/TAIL. */ \
23614 for (n = 0; n < cmp->glyph_len;) \
23615 { \
23616 s = alloca (sizeof *s); \
23617 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23618 append_glyph_string (&(HEAD), &(TAIL), s); \
23619 s->cmp = cmp; \
23620 s->cmp_from = n; \
23621 s->x = (X); \
23622 if (n == 0) \
23623 first_s = s; \
23624 n = fill_composite_glyph_string (s, base_face, overlaps); \
23625 } \
23626 \
23627 ++START; \
23628 s = first_s; \
23629 } while (0)
23630
23631
23632 /* Add a glyph string for a glyph-string sequence to the list of strings
23633 between HEAD and TAIL. */
23634
23635 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23636 do { \
23637 int face_id; \
23638 XChar2b *char2b; \
23639 Lisp_Object gstring; \
23640 \
23641 face_id = (row)->glyphs[area][START].face_id; \
23642 gstring = (composition_gstring_from_id \
23643 ((row)->glyphs[area][START].u.cmp.id)); \
23644 s = alloca (sizeof *s); \
23645 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23646 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23647 append_glyph_string (&(HEAD), &(TAIL), s); \
23648 s->x = (X); \
23649 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23650 } while (0)
23651
23652
23653 /* Add a glyph string for a sequence of glyphless character's glyphs
23654 to the list of strings between HEAD and TAIL. The meanings of
23655 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23656
23657 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23658 do \
23659 { \
23660 int face_id; \
23661 \
23662 face_id = (row)->glyphs[area][START].face_id; \
23663 \
23664 s = alloca (sizeof *s); \
23665 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23666 append_glyph_string (&HEAD, &TAIL, s); \
23667 s->x = (X); \
23668 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23669 overlaps); \
23670 } \
23671 while (0)
23672
23673
23674 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23675 of AREA of glyph row ROW on window W between indices START and END.
23676 HL overrides the face for drawing glyph strings, e.g. it is
23677 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23678 x-positions of the drawing area.
23679
23680 This is an ugly monster macro construct because we must use alloca
23681 to allocate glyph strings (because draw_glyphs can be called
23682 asynchronously). */
23683
23684 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23685 do \
23686 { \
23687 HEAD = TAIL = NULL; \
23688 while (START < END) \
23689 { \
23690 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23691 switch (first_glyph->type) \
23692 { \
23693 case CHAR_GLYPH: \
23694 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23695 HL, X, LAST_X); \
23696 break; \
23697 \
23698 case COMPOSITE_GLYPH: \
23699 if (first_glyph->u.cmp.automatic) \
23700 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23701 HL, X, LAST_X); \
23702 else \
23703 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23704 HL, X, LAST_X); \
23705 break; \
23706 \
23707 case STRETCH_GLYPH: \
23708 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23709 HL, X, LAST_X); \
23710 break; \
23711 \
23712 case IMAGE_GLYPH: \
23713 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23714 HL, X, LAST_X); \
23715 break; \
23716 \
23717 case GLYPHLESS_GLYPH: \
23718 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23719 HL, X, LAST_X); \
23720 break; \
23721 \
23722 default: \
23723 emacs_abort (); \
23724 } \
23725 \
23726 if (s) \
23727 { \
23728 set_glyph_string_background_width (s, START, LAST_X); \
23729 (X) += s->width; \
23730 } \
23731 } \
23732 } while (0)
23733
23734
23735 /* Draw glyphs between START and END in AREA of ROW on window W,
23736 starting at x-position X. X is relative to AREA in W. HL is a
23737 face-override with the following meaning:
23738
23739 DRAW_NORMAL_TEXT draw normally
23740 DRAW_CURSOR draw in cursor face
23741 DRAW_MOUSE_FACE draw in mouse face.
23742 DRAW_INVERSE_VIDEO draw in mode line face
23743 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23744 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23745
23746 If OVERLAPS is non-zero, draw only the foreground of characters and
23747 clip to the physical height of ROW. Non-zero value also defines
23748 the overlapping part to be drawn:
23749
23750 OVERLAPS_PRED overlap with preceding rows
23751 OVERLAPS_SUCC overlap with succeeding rows
23752 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23753 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23754
23755 Value is the x-position reached, relative to AREA of W. */
23756
23757 static int
23758 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23759 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23760 enum draw_glyphs_face hl, int overlaps)
23761 {
23762 struct glyph_string *head, *tail;
23763 struct glyph_string *s;
23764 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23765 int i, j, x_reached, last_x, area_left = 0;
23766 struct frame *f = XFRAME (WINDOW_FRAME (w));
23767 DECLARE_HDC (hdc);
23768
23769 ALLOCATE_HDC (hdc, f);
23770
23771 /* Let's rather be paranoid than getting a SEGV. */
23772 end = min (end, row->used[area]);
23773 start = clip_to_bounds (0, start, end);
23774
23775 /* Translate X to frame coordinates. Set last_x to the right
23776 end of the drawing area. */
23777 if (row->full_width_p)
23778 {
23779 /* X is relative to the left edge of W, without scroll bars
23780 or fringes. */
23781 area_left = WINDOW_LEFT_EDGE_X (w);
23782 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23783 }
23784 else
23785 {
23786 area_left = window_box_left (w, area);
23787 last_x = area_left + window_box_width (w, area);
23788 }
23789 x += area_left;
23790
23791 /* Build a doubly-linked list of glyph_string structures between
23792 head and tail from what we have to draw. Note that the macro
23793 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23794 the reason we use a separate variable `i'. */
23795 i = start;
23796 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23797 if (tail)
23798 x_reached = tail->x + tail->background_width;
23799 else
23800 x_reached = x;
23801
23802 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23803 the row, redraw some glyphs in front or following the glyph
23804 strings built above. */
23805 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23806 {
23807 struct glyph_string *h, *t;
23808 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23809 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23810 int check_mouse_face = 0;
23811 int dummy_x = 0;
23812
23813 /* If mouse highlighting is on, we may need to draw adjacent
23814 glyphs using mouse-face highlighting. */
23815 if (area == TEXT_AREA && row->mouse_face_p
23816 && hlinfo->mouse_face_beg_row >= 0
23817 && hlinfo->mouse_face_end_row >= 0)
23818 {
23819 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
23820
23821 if (row_vpos >= hlinfo->mouse_face_beg_row
23822 && row_vpos <= hlinfo->mouse_face_end_row)
23823 {
23824 check_mouse_face = 1;
23825 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
23826 ? hlinfo->mouse_face_beg_col : 0;
23827 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
23828 ? hlinfo->mouse_face_end_col
23829 : row->used[TEXT_AREA];
23830 }
23831 }
23832
23833 /* Compute overhangs for all glyph strings. */
23834 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23835 for (s = head; s; s = s->next)
23836 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23837
23838 /* Prepend glyph strings for glyphs in front of the first glyph
23839 string that are overwritten because of the first glyph
23840 string's left overhang. The background of all strings
23841 prepended must be drawn because the first glyph string
23842 draws over it. */
23843 i = left_overwritten (head);
23844 if (i >= 0)
23845 {
23846 enum draw_glyphs_face overlap_hl;
23847
23848 /* If this row contains mouse highlighting, attempt to draw
23849 the overlapped glyphs with the correct highlight. This
23850 code fails if the overlap encompasses more than one glyph
23851 and mouse-highlight spans only some of these glyphs.
23852 However, making it work perfectly involves a lot more
23853 code, and I don't know if the pathological case occurs in
23854 practice, so we'll stick to this for now. --- cyd */
23855 if (check_mouse_face
23856 && mouse_beg_col < start && mouse_end_col > i)
23857 overlap_hl = DRAW_MOUSE_FACE;
23858 else
23859 overlap_hl = DRAW_NORMAL_TEXT;
23860
23861 j = i;
23862 BUILD_GLYPH_STRINGS (j, start, h, t,
23863 overlap_hl, dummy_x, last_x);
23864 start = i;
23865 compute_overhangs_and_x (t, head->x, 1);
23866 prepend_glyph_string_lists (&head, &tail, h, t);
23867 clip_head = head;
23868 }
23869
23870 /* Prepend glyph strings for glyphs in front of the first glyph
23871 string that overwrite that glyph string because of their
23872 right overhang. For these strings, only the foreground must
23873 be drawn, because it draws over the glyph string at `head'.
23874 The background must not be drawn because this would overwrite
23875 right overhangs of preceding glyphs for which no glyph
23876 strings exist. */
23877 i = left_overwriting (head);
23878 if (i >= 0)
23879 {
23880 enum draw_glyphs_face overlap_hl;
23881
23882 if (check_mouse_face
23883 && mouse_beg_col < start && mouse_end_col > i)
23884 overlap_hl = DRAW_MOUSE_FACE;
23885 else
23886 overlap_hl = DRAW_NORMAL_TEXT;
23887
23888 clip_head = head;
23889 BUILD_GLYPH_STRINGS (i, start, h, t,
23890 overlap_hl, dummy_x, last_x);
23891 for (s = h; s; s = s->next)
23892 s->background_filled_p = 1;
23893 compute_overhangs_and_x (t, head->x, 1);
23894 prepend_glyph_string_lists (&head, &tail, h, t);
23895 }
23896
23897 /* Append glyphs strings for glyphs following the last glyph
23898 string tail that are overwritten by tail. The background of
23899 these strings has to be drawn because tail's foreground draws
23900 over it. */
23901 i = right_overwritten (tail);
23902 if (i >= 0)
23903 {
23904 enum draw_glyphs_face overlap_hl;
23905
23906 if (check_mouse_face
23907 && mouse_beg_col < i && mouse_end_col > end)
23908 overlap_hl = DRAW_MOUSE_FACE;
23909 else
23910 overlap_hl = DRAW_NORMAL_TEXT;
23911
23912 BUILD_GLYPH_STRINGS (end, i, h, t,
23913 overlap_hl, x, last_x);
23914 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23915 we don't have `end = i;' here. */
23916 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23917 append_glyph_string_lists (&head, &tail, h, t);
23918 clip_tail = tail;
23919 }
23920
23921 /* Append glyph strings for glyphs following the last glyph
23922 string tail that overwrite tail. The foreground of such
23923 glyphs has to be drawn because it writes into the background
23924 of tail. The background must not be drawn because it could
23925 paint over the foreground of following glyphs. */
23926 i = right_overwriting (tail);
23927 if (i >= 0)
23928 {
23929 enum draw_glyphs_face overlap_hl;
23930 if (check_mouse_face
23931 && mouse_beg_col < i && mouse_end_col > end)
23932 overlap_hl = DRAW_MOUSE_FACE;
23933 else
23934 overlap_hl = DRAW_NORMAL_TEXT;
23935
23936 clip_tail = tail;
23937 i++; /* We must include the Ith glyph. */
23938 BUILD_GLYPH_STRINGS (end, i, h, t,
23939 overlap_hl, x, last_x);
23940 for (s = h; s; s = s->next)
23941 s->background_filled_p = 1;
23942 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23943 append_glyph_string_lists (&head, &tail, h, t);
23944 }
23945 if (clip_head || clip_tail)
23946 for (s = head; s; s = s->next)
23947 {
23948 s->clip_head = clip_head;
23949 s->clip_tail = clip_tail;
23950 }
23951 }
23952
23953 /* Draw all strings. */
23954 for (s = head; s; s = s->next)
23955 FRAME_RIF (f)->draw_glyph_string (s);
23956
23957 #ifndef HAVE_NS
23958 /* When focus a sole frame and move horizontally, this sets on_p to 0
23959 causing a failure to erase prev cursor position. */
23960 if (area == TEXT_AREA
23961 && !row->full_width_p
23962 /* When drawing overlapping rows, only the glyph strings'
23963 foreground is drawn, which doesn't erase a cursor
23964 completely. */
23965 && !overlaps)
23966 {
23967 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23968 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23969 : (tail ? tail->x + tail->background_width : x));
23970 x0 -= area_left;
23971 x1 -= area_left;
23972
23973 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23974 row->y, MATRIX_ROW_BOTTOM_Y (row));
23975 }
23976 #endif
23977
23978 /* Value is the x-position up to which drawn, relative to AREA of W.
23979 This doesn't include parts drawn because of overhangs. */
23980 if (row->full_width_p)
23981 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23982 else
23983 x_reached -= area_left;
23984
23985 RELEASE_HDC (hdc, f);
23986
23987 return x_reached;
23988 }
23989
23990 /* Expand row matrix if too narrow. Don't expand if area
23991 is not present. */
23992
23993 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23994 { \
23995 if (!it->f->fonts_changed \
23996 && (it->glyph_row->glyphs[area] \
23997 < it->glyph_row->glyphs[area + 1])) \
23998 { \
23999 it->w->ncols_scale_factor++; \
24000 it->f->fonts_changed = 1; \
24001 } \
24002 }
24003
24004 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24005 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24006
24007 static void
24008 append_glyph (struct it *it)
24009 {
24010 struct glyph *glyph;
24011 enum glyph_row_area area = it->area;
24012
24013 eassert (it->glyph_row);
24014 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
24015
24016 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24017 if (glyph < it->glyph_row->glyphs[area + 1])
24018 {
24019 /* If the glyph row is reversed, we need to prepend the glyph
24020 rather than append it. */
24021 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24022 {
24023 struct glyph *g;
24024
24025 /* Make room for the additional glyph. */
24026 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24027 g[1] = *g;
24028 glyph = it->glyph_row->glyphs[area];
24029 }
24030 glyph->charpos = CHARPOS (it->position);
24031 glyph->object = it->object;
24032 if (it->pixel_width > 0)
24033 {
24034 glyph->pixel_width = it->pixel_width;
24035 glyph->padding_p = 0;
24036 }
24037 else
24038 {
24039 /* Assure at least 1-pixel width. Otherwise, cursor can't
24040 be displayed correctly. */
24041 glyph->pixel_width = 1;
24042 glyph->padding_p = 1;
24043 }
24044 glyph->ascent = it->ascent;
24045 glyph->descent = it->descent;
24046 glyph->voffset = it->voffset;
24047 glyph->type = CHAR_GLYPH;
24048 glyph->avoid_cursor_p = it->avoid_cursor_p;
24049 glyph->multibyte_p = it->multibyte_p;
24050 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24051 {
24052 /* In R2L rows, the left and the right box edges need to be
24053 drawn in reverse direction. */
24054 glyph->right_box_line_p = it->start_of_box_run_p;
24055 glyph->left_box_line_p = it->end_of_box_run_p;
24056 }
24057 else
24058 {
24059 glyph->left_box_line_p = it->start_of_box_run_p;
24060 glyph->right_box_line_p = it->end_of_box_run_p;
24061 }
24062 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24063 || it->phys_descent > it->descent);
24064 glyph->glyph_not_available_p = it->glyph_not_available_p;
24065 glyph->face_id = it->face_id;
24066 glyph->u.ch = it->char_to_display;
24067 glyph->slice.img = null_glyph_slice;
24068 glyph->font_type = FONT_TYPE_UNKNOWN;
24069 if (it->bidi_p)
24070 {
24071 glyph->resolved_level = it->bidi_it.resolved_level;
24072 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24073 emacs_abort ();
24074 glyph->bidi_type = it->bidi_it.type;
24075 }
24076 else
24077 {
24078 glyph->resolved_level = 0;
24079 glyph->bidi_type = UNKNOWN_BT;
24080 }
24081 ++it->glyph_row->used[area];
24082 }
24083 else
24084 IT_EXPAND_MATRIX_WIDTH (it, area);
24085 }
24086
24087 /* Store one glyph for the composition IT->cmp_it.id in
24088 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24089 non-null. */
24090
24091 static void
24092 append_composite_glyph (struct it *it)
24093 {
24094 struct glyph *glyph;
24095 enum glyph_row_area area = it->area;
24096
24097 eassert (it->glyph_row);
24098
24099 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24100 if (glyph < it->glyph_row->glyphs[area + 1])
24101 {
24102 /* If the glyph row is reversed, we need to prepend the glyph
24103 rather than append it. */
24104 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
24105 {
24106 struct glyph *g;
24107
24108 /* Make room for the new glyph. */
24109 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
24110 g[1] = *g;
24111 glyph = it->glyph_row->glyphs[it->area];
24112 }
24113 glyph->charpos = it->cmp_it.charpos;
24114 glyph->object = it->object;
24115 glyph->pixel_width = it->pixel_width;
24116 glyph->ascent = it->ascent;
24117 glyph->descent = it->descent;
24118 glyph->voffset = it->voffset;
24119 glyph->type = COMPOSITE_GLYPH;
24120 if (it->cmp_it.ch < 0)
24121 {
24122 glyph->u.cmp.automatic = 0;
24123 glyph->u.cmp.id = it->cmp_it.id;
24124 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
24125 }
24126 else
24127 {
24128 glyph->u.cmp.automatic = 1;
24129 glyph->u.cmp.id = it->cmp_it.id;
24130 glyph->slice.cmp.from = it->cmp_it.from;
24131 glyph->slice.cmp.to = it->cmp_it.to - 1;
24132 }
24133 glyph->avoid_cursor_p = it->avoid_cursor_p;
24134 glyph->multibyte_p = it->multibyte_p;
24135 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24136 {
24137 /* In R2L rows, the left and the right box edges need to be
24138 drawn in reverse direction. */
24139 glyph->right_box_line_p = it->start_of_box_run_p;
24140 glyph->left_box_line_p = it->end_of_box_run_p;
24141 }
24142 else
24143 {
24144 glyph->left_box_line_p = it->start_of_box_run_p;
24145 glyph->right_box_line_p = it->end_of_box_run_p;
24146 }
24147 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24148 || it->phys_descent > it->descent);
24149 glyph->padding_p = 0;
24150 glyph->glyph_not_available_p = 0;
24151 glyph->face_id = it->face_id;
24152 glyph->font_type = FONT_TYPE_UNKNOWN;
24153 if (it->bidi_p)
24154 {
24155 glyph->resolved_level = it->bidi_it.resolved_level;
24156 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24157 emacs_abort ();
24158 glyph->bidi_type = it->bidi_it.type;
24159 }
24160 ++it->glyph_row->used[area];
24161 }
24162 else
24163 IT_EXPAND_MATRIX_WIDTH (it, area);
24164 }
24165
24166
24167 /* Change IT->ascent and IT->height according to the setting of
24168 IT->voffset. */
24169
24170 static void
24171 take_vertical_position_into_account (struct it *it)
24172 {
24173 if (it->voffset)
24174 {
24175 if (it->voffset < 0)
24176 /* Increase the ascent so that we can display the text higher
24177 in the line. */
24178 it->ascent -= it->voffset;
24179 else
24180 /* Increase the descent so that we can display the text lower
24181 in the line. */
24182 it->descent += it->voffset;
24183 }
24184 }
24185
24186
24187 /* Produce glyphs/get display metrics for the image IT is loaded with.
24188 See the description of struct display_iterator in dispextern.h for
24189 an overview of struct display_iterator. */
24190
24191 static void
24192 produce_image_glyph (struct it *it)
24193 {
24194 struct image *img;
24195 struct face *face;
24196 int glyph_ascent, crop;
24197 struct glyph_slice slice;
24198
24199 eassert (it->what == IT_IMAGE);
24200
24201 face = FACE_FROM_ID (it->f, it->face_id);
24202 eassert (face);
24203 /* Make sure X resources of the face is loaded. */
24204 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24205
24206 if (it->image_id < 0)
24207 {
24208 /* Fringe bitmap. */
24209 it->ascent = it->phys_ascent = 0;
24210 it->descent = it->phys_descent = 0;
24211 it->pixel_width = 0;
24212 it->nglyphs = 0;
24213 return;
24214 }
24215
24216 img = IMAGE_FROM_ID (it->f, it->image_id);
24217 eassert (img);
24218 /* Make sure X resources of the image is loaded. */
24219 prepare_image_for_display (it->f, img);
24220
24221 slice.x = slice.y = 0;
24222 slice.width = img->width;
24223 slice.height = img->height;
24224
24225 if (INTEGERP (it->slice.x))
24226 slice.x = XINT (it->slice.x);
24227 else if (FLOATP (it->slice.x))
24228 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24229
24230 if (INTEGERP (it->slice.y))
24231 slice.y = XINT (it->slice.y);
24232 else if (FLOATP (it->slice.y))
24233 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24234
24235 if (INTEGERP (it->slice.width))
24236 slice.width = XINT (it->slice.width);
24237 else if (FLOATP (it->slice.width))
24238 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24239
24240 if (INTEGERP (it->slice.height))
24241 slice.height = XINT (it->slice.height);
24242 else if (FLOATP (it->slice.height))
24243 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24244
24245 if (slice.x >= img->width)
24246 slice.x = img->width;
24247 if (slice.y >= img->height)
24248 slice.y = img->height;
24249 if (slice.x + slice.width >= img->width)
24250 slice.width = img->width - slice.x;
24251 if (slice.y + slice.height > img->height)
24252 slice.height = img->height - slice.y;
24253
24254 if (slice.width == 0 || slice.height == 0)
24255 return;
24256
24257 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24258
24259 it->descent = slice.height - glyph_ascent;
24260 if (slice.y == 0)
24261 it->descent += img->vmargin;
24262 if (slice.y + slice.height == img->height)
24263 it->descent += img->vmargin;
24264 it->phys_descent = it->descent;
24265
24266 it->pixel_width = slice.width;
24267 if (slice.x == 0)
24268 it->pixel_width += img->hmargin;
24269 if (slice.x + slice.width == img->width)
24270 it->pixel_width += img->hmargin;
24271
24272 /* It's quite possible for images to have an ascent greater than
24273 their height, so don't get confused in that case. */
24274 if (it->descent < 0)
24275 it->descent = 0;
24276
24277 it->nglyphs = 1;
24278
24279 if (face->box != FACE_NO_BOX)
24280 {
24281 if (face->box_line_width > 0)
24282 {
24283 if (slice.y == 0)
24284 it->ascent += face->box_line_width;
24285 if (slice.y + slice.height == img->height)
24286 it->descent += face->box_line_width;
24287 }
24288
24289 if (it->start_of_box_run_p && slice.x == 0)
24290 it->pixel_width += eabs (face->box_line_width);
24291 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24292 it->pixel_width += eabs (face->box_line_width);
24293 }
24294
24295 take_vertical_position_into_account (it);
24296
24297 /* Automatically crop wide image glyphs at right edge so we can
24298 draw the cursor on same display row. */
24299 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24300 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24301 {
24302 it->pixel_width -= crop;
24303 slice.width -= crop;
24304 }
24305
24306 if (it->glyph_row)
24307 {
24308 struct glyph *glyph;
24309 enum glyph_row_area area = it->area;
24310
24311 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24312 if (glyph < it->glyph_row->glyphs[area + 1])
24313 {
24314 glyph->charpos = CHARPOS (it->position);
24315 glyph->object = it->object;
24316 glyph->pixel_width = it->pixel_width;
24317 glyph->ascent = glyph_ascent;
24318 glyph->descent = it->descent;
24319 glyph->voffset = it->voffset;
24320 glyph->type = IMAGE_GLYPH;
24321 glyph->avoid_cursor_p = it->avoid_cursor_p;
24322 glyph->multibyte_p = it->multibyte_p;
24323 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24324 {
24325 /* In R2L rows, the left and the right box edges need to be
24326 drawn in reverse direction. */
24327 glyph->right_box_line_p = it->start_of_box_run_p;
24328 glyph->left_box_line_p = it->end_of_box_run_p;
24329 }
24330 else
24331 {
24332 glyph->left_box_line_p = it->start_of_box_run_p;
24333 glyph->right_box_line_p = it->end_of_box_run_p;
24334 }
24335 glyph->overlaps_vertically_p = 0;
24336 glyph->padding_p = 0;
24337 glyph->glyph_not_available_p = 0;
24338 glyph->face_id = it->face_id;
24339 glyph->u.img_id = img->id;
24340 glyph->slice.img = slice;
24341 glyph->font_type = FONT_TYPE_UNKNOWN;
24342 if (it->bidi_p)
24343 {
24344 glyph->resolved_level = it->bidi_it.resolved_level;
24345 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24346 emacs_abort ();
24347 glyph->bidi_type = it->bidi_it.type;
24348 }
24349 ++it->glyph_row->used[area];
24350 }
24351 else
24352 IT_EXPAND_MATRIX_WIDTH (it, area);
24353 }
24354 }
24355
24356
24357 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24358 of the glyph, WIDTH and HEIGHT are the width and height of the
24359 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24360
24361 static void
24362 append_stretch_glyph (struct it *it, Lisp_Object object,
24363 int width, int height, int ascent)
24364 {
24365 struct glyph *glyph;
24366 enum glyph_row_area area = it->area;
24367
24368 eassert (ascent >= 0 && ascent <= height);
24369
24370 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24371 if (glyph < it->glyph_row->glyphs[area + 1])
24372 {
24373 /* If the glyph row is reversed, we need to prepend the glyph
24374 rather than append it. */
24375 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24376 {
24377 struct glyph *g;
24378
24379 /* Make room for the additional glyph. */
24380 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24381 g[1] = *g;
24382 glyph = it->glyph_row->glyphs[area];
24383 }
24384 glyph->charpos = CHARPOS (it->position);
24385 glyph->object = object;
24386 glyph->pixel_width = width;
24387 glyph->ascent = ascent;
24388 glyph->descent = height - ascent;
24389 glyph->voffset = it->voffset;
24390 glyph->type = STRETCH_GLYPH;
24391 glyph->avoid_cursor_p = it->avoid_cursor_p;
24392 glyph->multibyte_p = it->multibyte_p;
24393 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24394 {
24395 /* In R2L rows, the left and the right box edges need to be
24396 drawn in reverse direction. */
24397 glyph->right_box_line_p = it->start_of_box_run_p;
24398 glyph->left_box_line_p = it->end_of_box_run_p;
24399 }
24400 else
24401 {
24402 glyph->left_box_line_p = it->start_of_box_run_p;
24403 glyph->right_box_line_p = it->end_of_box_run_p;
24404 }
24405 glyph->overlaps_vertically_p = 0;
24406 glyph->padding_p = 0;
24407 glyph->glyph_not_available_p = 0;
24408 glyph->face_id = it->face_id;
24409 glyph->u.stretch.ascent = ascent;
24410 glyph->u.stretch.height = height;
24411 glyph->slice.img = null_glyph_slice;
24412 glyph->font_type = FONT_TYPE_UNKNOWN;
24413 if (it->bidi_p)
24414 {
24415 glyph->resolved_level = it->bidi_it.resolved_level;
24416 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24417 emacs_abort ();
24418 glyph->bidi_type = it->bidi_it.type;
24419 }
24420 else
24421 {
24422 glyph->resolved_level = 0;
24423 glyph->bidi_type = UNKNOWN_BT;
24424 }
24425 ++it->glyph_row->used[area];
24426 }
24427 else
24428 IT_EXPAND_MATRIX_WIDTH (it, area);
24429 }
24430
24431 #endif /* HAVE_WINDOW_SYSTEM */
24432
24433 /* Produce a stretch glyph for iterator IT. IT->object is the value
24434 of the glyph property displayed. The value must be a list
24435 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24436 being recognized:
24437
24438 1. `:width WIDTH' specifies that the space should be WIDTH *
24439 canonical char width wide. WIDTH may be an integer or floating
24440 point number.
24441
24442 2. `:relative-width FACTOR' specifies that the width of the stretch
24443 should be computed from the width of the first character having the
24444 `glyph' property, and should be FACTOR times that width.
24445
24446 3. `:align-to HPOS' specifies that the space should be wide enough
24447 to reach HPOS, a value in canonical character units.
24448
24449 Exactly one of the above pairs must be present.
24450
24451 4. `:height HEIGHT' specifies that the height of the stretch produced
24452 should be HEIGHT, measured in canonical character units.
24453
24454 5. `:relative-height FACTOR' specifies that the height of the
24455 stretch should be FACTOR times the height of the characters having
24456 the glyph property.
24457
24458 Either none or exactly one of 4 or 5 must be present.
24459
24460 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24461 of the stretch should be used for the ascent of the stretch.
24462 ASCENT must be in the range 0 <= ASCENT <= 100. */
24463
24464 void
24465 produce_stretch_glyph (struct it *it)
24466 {
24467 /* (space :width WIDTH :height HEIGHT ...) */
24468 Lisp_Object prop, plist;
24469 int width = 0, height = 0, align_to = -1;
24470 int zero_width_ok_p = 0;
24471 double tem;
24472 struct font *font = NULL;
24473
24474 #ifdef HAVE_WINDOW_SYSTEM
24475 int ascent = 0;
24476 int zero_height_ok_p = 0;
24477
24478 if (FRAME_WINDOW_P (it->f))
24479 {
24480 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24481 font = face->font ? face->font : FRAME_FONT (it->f);
24482 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24483 }
24484 #endif
24485
24486 /* List should start with `space'. */
24487 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24488 plist = XCDR (it->object);
24489
24490 /* Compute the width of the stretch. */
24491 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24492 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24493 {
24494 /* Absolute width `:width WIDTH' specified and valid. */
24495 zero_width_ok_p = 1;
24496 width = (int)tem;
24497 }
24498 #ifdef HAVE_WINDOW_SYSTEM
24499 else if (FRAME_WINDOW_P (it->f)
24500 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24501 {
24502 /* Relative width `:relative-width FACTOR' specified and valid.
24503 Compute the width of the characters having the `glyph'
24504 property. */
24505 struct it it2;
24506 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24507
24508 it2 = *it;
24509 if (it->multibyte_p)
24510 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24511 else
24512 {
24513 it2.c = it2.char_to_display = *p, it2.len = 1;
24514 if (! ASCII_CHAR_P (it2.c))
24515 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24516 }
24517
24518 it2.glyph_row = NULL;
24519 it2.what = IT_CHARACTER;
24520 x_produce_glyphs (&it2);
24521 width = NUMVAL (prop) * it2.pixel_width;
24522 }
24523 #endif /* HAVE_WINDOW_SYSTEM */
24524 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24525 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24526 {
24527 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24528 align_to = (align_to < 0
24529 ? 0
24530 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24531 else if (align_to < 0)
24532 align_to = window_box_left_offset (it->w, TEXT_AREA);
24533 width = max (0, (int)tem + align_to - it->current_x);
24534 zero_width_ok_p = 1;
24535 }
24536 else
24537 /* Nothing specified -> width defaults to canonical char width. */
24538 width = FRAME_COLUMN_WIDTH (it->f);
24539
24540 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24541 width = 1;
24542
24543 #ifdef HAVE_WINDOW_SYSTEM
24544 /* Compute height. */
24545 if (FRAME_WINDOW_P (it->f))
24546 {
24547 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24548 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24549 {
24550 height = (int)tem;
24551 zero_height_ok_p = 1;
24552 }
24553 else if (prop = Fplist_get (plist, QCrelative_height),
24554 NUMVAL (prop) > 0)
24555 height = FONT_HEIGHT (font) * NUMVAL (prop);
24556 else
24557 height = FONT_HEIGHT (font);
24558
24559 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24560 height = 1;
24561
24562 /* Compute percentage of height used for ascent. If
24563 `:ascent ASCENT' is present and valid, use that. Otherwise,
24564 derive the ascent from the font in use. */
24565 if (prop = Fplist_get (plist, QCascent),
24566 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24567 ascent = height * NUMVAL (prop) / 100.0;
24568 else if (!NILP (prop)
24569 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24570 ascent = min (max (0, (int)tem), height);
24571 else
24572 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24573 }
24574 else
24575 #endif /* HAVE_WINDOW_SYSTEM */
24576 height = 1;
24577
24578 if (width > 0 && it->line_wrap != TRUNCATE
24579 && it->current_x + width > it->last_visible_x)
24580 {
24581 width = it->last_visible_x - it->current_x;
24582 #ifdef HAVE_WINDOW_SYSTEM
24583 /* Subtract one more pixel from the stretch width, but only on
24584 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24585 width -= FRAME_WINDOW_P (it->f);
24586 #endif
24587 }
24588
24589 if (width > 0 && height > 0 && it->glyph_row)
24590 {
24591 Lisp_Object o_object = it->object;
24592 Lisp_Object object = it->stack[it->sp - 1].string;
24593 int n = width;
24594
24595 if (!STRINGP (object))
24596 object = it->w->contents;
24597 #ifdef HAVE_WINDOW_SYSTEM
24598 if (FRAME_WINDOW_P (it->f))
24599 append_stretch_glyph (it, object, width, height, ascent);
24600 else
24601 #endif
24602 {
24603 it->object = object;
24604 it->char_to_display = ' ';
24605 it->pixel_width = it->len = 1;
24606 while (n--)
24607 tty_append_glyph (it);
24608 it->object = o_object;
24609 }
24610 }
24611
24612 it->pixel_width = width;
24613 #ifdef HAVE_WINDOW_SYSTEM
24614 if (FRAME_WINDOW_P (it->f))
24615 {
24616 it->ascent = it->phys_ascent = ascent;
24617 it->descent = it->phys_descent = height - it->ascent;
24618 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24619 take_vertical_position_into_account (it);
24620 }
24621 else
24622 #endif
24623 it->nglyphs = width;
24624 }
24625
24626 /* Get information about special display element WHAT in an
24627 environment described by IT. WHAT is one of IT_TRUNCATION or
24628 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24629 non-null glyph_row member. This function ensures that fields like
24630 face_id, c, len of IT are left untouched. */
24631
24632 static void
24633 produce_special_glyphs (struct it *it, enum display_element_type what)
24634 {
24635 struct it temp_it;
24636 Lisp_Object gc;
24637 GLYPH glyph;
24638
24639 temp_it = *it;
24640 temp_it.object = make_number (0);
24641 memset (&temp_it.current, 0, sizeof temp_it.current);
24642
24643 if (what == IT_CONTINUATION)
24644 {
24645 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24646 if (it->bidi_it.paragraph_dir == R2L)
24647 SET_GLYPH_FROM_CHAR (glyph, '/');
24648 else
24649 SET_GLYPH_FROM_CHAR (glyph, '\\');
24650 if (it->dp
24651 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24652 {
24653 /* FIXME: Should we mirror GC for R2L lines? */
24654 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24655 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24656 }
24657 }
24658 else if (what == IT_TRUNCATION)
24659 {
24660 /* Truncation glyph. */
24661 SET_GLYPH_FROM_CHAR (glyph, '$');
24662 if (it->dp
24663 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24664 {
24665 /* FIXME: Should we mirror GC for R2L lines? */
24666 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24667 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24668 }
24669 }
24670 else
24671 emacs_abort ();
24672
24673 #ifdef HAVE_WINDOW_SYSTEM
24674 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24675 is turned off, we precede the truncation/continuation glyphs by a
24676 stretch glyph whose width is computed such that these special
24677 glyphs are aligned at the window margin, even when very different
24678 fonts are used in different glyph rows. */
24679 if (FRAME_WINDOW_P (temp_it.f)
24680 /* init_iterator calls this with it->glyph_row == NULL, and it
24681 wants only the pixel width of the truncation/continuation
24682 glyphs. */
24683 && temp_it.glyph_row
24684 /* insert_left_trunc_glyphs calls us at the beginning of the
24685 row, and it has its own calculation of the stretch glyph
24686 width. */
24687 && temp_it.glyph_row->used[TEXT_AREA] > 0
24688 && (temp_it.glyph_row->reversed_p
24689 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24690 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24691 {
24692 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24693
24694 if (stretch_width > 0)
24695 {
24696 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24697 struct font *font =
24698 face->font ? face->font : FRAME_FONT (temp_it.f);
24699 int stretch_ascent =
24700 (((temp_it.ascent + temp_it.descent)
24701 * FONT_BASE (font)) / FONT_HEIGHT (font));
24702
24703 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24704 temp_it.ascent + temp_it.descent,
24705 stretch_ascent);
24706 }
24707 }
24708 #endif
24709
24710 temp_it.dp = NULL;
24711 temp_it.what = IT_CHARACTER;
24712 temp_it.len = 1;
24713 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24714 temp_it.face_id = GLYPH_FACE (glyph);
24715 temp_it.len = CHAR_BYTES (temp_it.c);
24716
24717 PRODUCE_GLYPHS (&temp_it);
24718 it->pixel_width = temp_it.pixel_width;
24719 it->nglyphs = temp_it.pixel_width;
24720 }
24721
24722 #ifdef HAVE_WINDOW_SYSTEM
24723
24724 /* Calculate line-height and line-spacing properties.
24725 An integer value specifies explicit pixel value.
24726 A float value specifies relative value to current face height.
24727 A cons (float . face-name) specifies relative value to
24728 height of specified face font.
24729
24730 Returns height in pixels, or nil. */
24731
24732
24733 static Lisp_Object
24734 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24735 int boff, int override)
24736 {
24737 Lisp_Object face_name = Qnil;
24738 int ascent, descent, height;
24739
24740 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24741 return val;
24742
24743 if (CONSP (val))
24744 {
24745 face_name = XCAR (val);
24746 val = XCDR (val);
24747 if (!NUMBERP (val))
24748 val = make_number (1);
24749 if (NILP (face_name))
24750 {
24751 height = it->ascent + it->descent;
24752 goto scale;
24753 }
24754 }
24755
24756 if (NILP (face_name))
24757 {
24758 font = FRAME_FONT (it->f);
24759 boff = FRAME_BASELINE_OFFSET (it->f);
24760 }
24761 else if (EQ (face_name, Qt))
24762 {
24763 override = 0;
24764 }
24765 else
24766 {
24767 int face_id;
24768 struct face *face;
24769
24770 face_id = lookup_named_face (it->f, face_name, 0);
24771 if (face_id < 0)
24772 return make_number (-1);
24773
24774 face = FACE_FROM_ID (it->f, face_id);
24775 font = face->font;
24776 if (font == NULL)
24777 return make_number (-1);
24778 boff = font->baseline_offset;
24779 if (font->vertical_centering)
24780 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24781 }
24782
24783 ascent = FONT_BASE (font) + boff;
24784 descent = FONT_DESCENT (font) - boff;
24785
24786 if (override)
24787 {
24788 it->override_ascent = ascent;
24789 it->override_descent = descent;
24790 it->override_boff = boff;
24791 }
24792
24793 height = ascent + descent;
24794
24795 scale:
24796 if (FLOATP (val))
24797 height = (int)(XFLOAT_DATA (val) * height);
24798 else if (INTEGERP (val))
24799 height *= XINT (val);
24800
24801 return make_number (height);
24802 }
24803
24804
24805 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24806 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24807 and only if this is for a character for which no font was found.
24808
24809 If the display method (it->glyphless_method) is
24810 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24811 length of the acronym or the hexadecimal string, UPPER_XOFF and
24812 UPPER_YOFF are pixel offsets for the upper part of the string,
24813 LOWER_XOFF and LOWER_YOFF are for the lower part.
24814
24815 For the other display methods, LEN through LOWER_YOFF are zero. */
24816
24817 static void
24818 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24819 short upper_xoff, short upper_yoff,
24820 short lower_xoff, short lower_yoff)
24821 {
24822 struct glyph *glyph;
24823 enum glyph_row_area area = it->area;
24824
24825 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24826 if (glyph < it->glyph_row->glyphs[area + 1])
24827 {
24828 /* If the glyph row is reversed, we need to prepend the glyph
24829 rather than append it. */
24830 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24831 {
24832 struct glyph *g;
24833
24834 /* Make room for the additional glyph. */
24835 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24836 g[1] = *g;
24837 glyph = it->glyph_row->glyphs[area];
24838 }
24839 glyph->charpos = CHARPOS (it->position);
24840 glyph->object = it->object;
24841 glyph->pixel_width = it->pixel_width;
24842 glyph->ascent = it->ascent;
24843 glyph->descent = it->descent;
24844 glyph->voffset = it->voffset;
24845 glyph->type = GLYPHLESS_GLYPH;
24846 glyph->u.glyphless.method = it->glyphless_method;
24847 glyph->u.glyphless.for_no_font = for_no_font;
24848 glyph->u.glyphless.len = len;
24849 glyph->u.glyphless.ch = it->c;
24850 glyph->slice.glyphless.upper_xoff = upper_xoff;
24851 glyph->slice.glyphless.upper_yoff = upper_yoff;
24852 glyph->slice.glyphless.lower_xoff = lower_xoff;
24853 glyph->slice.glyphless.lower_yoff = lower_yoff;
24854 glyph->avoid_cursor_p = it->avoid_cursor_p;
24855 glyph->multibyte_p = it->multibyte_p;
24856 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24857 {
24858 /* In R2L rows, the left and the right box edges need to be
24859 drawn in reverse direction. */
24860 glyph->right_box_line_p = it->start_of_box_run_p;
24861 glyph->left_box_line_p = it->end_of_box_run_p;
24862 }
24863 else
24864 {
24865 glyph->left_box_line_p = it->start_of_box_run_p;
24866 glyph->right_box_line_p = it->end_of_box_run_p;
24867 }
24868 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24869 || it->phys_descent > it->descent);
24870 glyph->padding_p = 0;
24871 glyph->glyph_not_available_p = 0;
24872 glyph->face_id = face_id;
24873 glyph->font_type = FONT_TYPE_UNKNOWN;
24874 if (it->bidi_p)
24875 {
24876 glyph->resolved_level = it->bidi_it.resolved_level;
24877 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24878 emacs_abort ();
24879 glyph->bidi_type = it->bidi_it.type;
24880 }
24881 ++it->glyph_row->used[area];
24882 }
24883 else
24884 IT_EXPAND_MATRIX_WIDTH (it, area);
24885 }
24886
24887
24888 /* Produce a glyph for a glyphless character for iterator IT.
24889 IT->glyphless_method specifies which method to use for displaying
24890 the character. See the description of enum
24891 glyphless_display_method in dispextern.h for the detail.
24892
24893 FOR_NO_FONT is nonzero if and only if this is for a character for
24894 which no font was found. ACRONYM, if non-nil, is an acronym string
24895 for the character. */
24896
24897 static void
24898 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24899 {
24900 int face_id;
24901 struct face *face;
24902 struct font *font;
24903 int base_width, base_height, width, height;
24904 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24905 int len;
24906
24907 /* Get the metrics of the base font. We always refer to the current
24908 ASCII face. */
24909 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24910 font = face->font ? face->font : FRAME_FONT (it->f);
24911 it->ascent = FONT_BASE (font) + font->baseline_offset;
24912 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24913 base_height = it->ascent + it->descent;
24914 base_width = font->average_width;
24915
24916 face_id = merge_glyphless_glyph_face (it);
24917
24918 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24919 {
24920 it->pixel_width = THIN_SPACE_WIDTH;
24921 len = 0;
24922 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24923 }
24924 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24925 {
24926 width = CHAR_WIDTH (it->c);
24927 if (width == 0)
24928 width = 1;
24929 else if (width > 4)
24930 width = 4;
24931 it->pixel_width = base_width * width;
24932 len = 0;
24933 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24934 }
24935 else
24936 {
24937 char buf[7];
24938 const char *str;
24939 unsigned int code[6];
24940 int upper_len;
24941 int ascent, descent;
24942 struct font_metrics metrics_upper, metrics_lower;
24943
24944 face = FACE_FROM_ID (it->f, face_id);
24945 font = face->font ? face->font : FRAME_FONT (it->f);
24946 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24947
24948 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24949 {
24950 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24951 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24952 if (CONSP (acronym))
24953 acronym = XCAR (acronym);
24954 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24955 }
24956 else
24957 {
24958 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24959 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24960 str = buf;
24961 }
24962 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24963 code[len] = font->driver->encode_char (font, str[len]);
24964 upper_len = (len + 1) / 2;
24965 font->driver->text_extents (font, code, upper_len,
24966 &metrics_upper);
24967 font->driver->text_extents (font, code + upper_len, len - upper_len,
24968 &metrics_lower);
24969
24970
24971
24972 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24973 width = max (metrics_upper.width, metrics_lower.width) + 4;
24974 upper_xoff = upper_yoff = 2; /* the typical case */
24975 if (base_width >= width)
24976 {
24977 /* Align the upper to the left, the lower to the right. */
24978 it->pixel_width = base_width;
24979 lower_xoff = base_width - 2 - metrics_lower.width;
24980 }
24981 else
24982 {
24983 /* Center the shorter one. */
24984 it->pixel_width = width;
24985 if (metrics_upper.width >= metrics_lower.width)
24986 lower_xoff = (width - metrics_lower.width) / 2;
24987 else
24988 {
24989 /* FIXME: This code doesn't look right. It formerly was
24990 missing the "lower_xoff = 0;", which couldn't have
24991 been right since it left lower_xoff uninitialized. */
24992 lower_xoff = 0;
24993 upper_xoff = (width - metrics_upper.width) / 2;
24994 }
24995 }
24996
24997 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24998 top, bottom, and between upper and lower strings. */
24999 height = (metrics_upper.ascent + metrics_upper.descent
25000 + metrics_lower.ascent + metrics_lower.descent) + 5;
25001 /* Center vertically.
25002 H:base_height, D:base_descent
25003 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25004
25005 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25006 descent = D - H/2 + h/2;
25007 lower_yoff = descent - 2 - ld;
25008 upper_yoff = lower_yoff - la - 1 - ud; */
25009 ascent = - (it->descent - (base_height + height + 1) / 2);
25010 descent = it->descent - (base_height - height) / 2;
25011 lower_yoff = descent - 2 - metrics_lower.descent;
25012 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
25013 - metrics_upper.descent);
25014 /* Don't make the height shorter than the base height. */
25015 if (height > base_height)
25016 {
25017 it->ascent = ascent;
25018 it->descent = descent;
25019 }
25020 }
25021
25022 it->phys_ascent = it->ascent;
25023 it->phys_descent = it->descent;
25024 if (it->glyph_row)
25025 append_glyphless_glyph (it, face_id, for_no_font, len,
25026 upper_xoff, upper_yoff,
25027 lower_xoff, lower_yoff);
25028 it->nglyphs = 1;
25029 take_vertical_position_into_account (it);
25030 }
25031
25032
25033 /* RIF:
25034 Produce glyphs/get display metrics for the display element IT is
25035 loaded with. See the description of struct it in dispextern.h
25036 for an overview of struct it. */
25037
25038 void
25039 x_produce_glyphs (struct it *it)
25040 {
25041 int extra_line_spacing = it->extra_line_spacing;
25042
25043 it->glyph_not_available_p = 0;
25044
25045 if (it->what == IT_CHARACTER)
25046 {
25047 XChar2b char2b;
25048 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25049 struct font *font = face->font;
25050 struct font_metrics *pcm = NULL;
25051 int boff; /* baseline offset */
25052
25053 if (font == NULL)
25054 {
25055 /* When no suitable font is found, display this character by
25056 the method specified in the first extra slot of
25057 Vglyphless_char_display. */
25058 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
25059
25060 eassert (it->what == IT_GLYPHLESS);
25061 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
25062 goto done;
25063 }
25064
25065 boff = font->baseline_offset;
25066 if (font->vertical_centering)
25067 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25068
25069 if (it->char_to_display != '\n' && it->char_to_display != '\t')
25070 {
25071 int stretched_p;
25072
25073 it->nglyphs = 1;
25074
25075 if (it->override_ascent >= 0)
25076 {
25077 it->ascent = it->override_ascent;
25078 it->descent = it->override_descent;
25079 boff = it->override_boff;
25080 }
25081 else
25082 {
25083 it->ascent = FONT_BASE (font) + boff;
25084 it->descent = FONT_DESCENT (font) - boff;
25085 }
25086
25087 if (get_char_glyph_code (it->char_to_display, font, &char2b))
25088 {
25089 pcm = get_per_char_metric (font, &char2b);
25090 if (pcm->width == 0
25091 && pcm->rbearing == 0 && pcm->lbearing == 0)
25092 pcm = NULL;
25093 }
25094
25095 if (pcm)
25096 {
25097 it->phys_ascent = pcm->ascent + boff;
25098 it->phys_descent = pcm->descent - boff;
25099 it->pixel_width = pcm->width;
25100 }
25101 else
25102 {
25103 it->glyph_not_available_p = 1;
25104 it->phys_ascent = it->ascent;
25105 it->phys_descent = it->descent;
25106 it->pixel_width = font->space_width;
25107 }
25108
25109 if (it->constrain_row_ascent_descent_p)
25110 {
25111 if (it->descent > it->max_descent)
25112 {
25113 it->ascent += it->descent - it->max_descent;
25114 it->descent = it->max_descent;
25115 }
25116 if (it->ascent > it->max_ascent)
25117 {
25118 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25119 it->ascent = it->max_ascent;
25120 }
25121 it->phys_ascent = min (it->phys_ascent, it->ascent);
25122 it->phys_descent = min (it->phys_descent, it->descent);
25123 extra_line_spacing = 0;
25124 }
25125
25126 /* If this is a space inside a region of text with
25127 `space-width' property, change its width. */
25128 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
25129 if (stretched_p)
25130 it->pixel_width *= XFLOATINT (it->space_width);
25131
25132 /* If face has a box, add the box thickness to the character
25133 height. If character has a box line to the left and/or
25134 right, add the box line width to the character's width. */
25135 if (face->box != FACE_NO_BOX)
25136 {
25137 int thick = face->box_line_width;
25138
25139 if (thick > 0)
25140 {
25141 it->ascent += thick;
25142 it->descent += thick;
25143 }
25144 else
25145 thick = -thick;
25146
25147 if (it->start_of_box_run_p)
25148 it->pixel_width += thick;
25149 if (it->end_of_box_run_p)
25150 it->pixel_width += thick;
25151 }
25152
25153 /* If face has an overline, add the height of the overline
25154 (1 pixel) and a 1 pixel margin to the character height. */
25155 if (face->overline_p)
25156 it->ascent += overline_margin;
25157
25158 if (it->constrain_row_ascent_descent_p)
25159 {
25160 if (it->ascent > it->max_ascent)
25161 it->ascent = it->max_ascent;
25162 if (it->descent > it->max_descent)
25163 it->descent = it->max_descent;
25164 }
25165
25166 take_vertical_position_into_account (it);
25167
25168 /* If we have to actually produce glyphs, do it. */
25169 if (it->glyph_row)
25170 {
25171 if (stretched_p)
25172 {
25173 /* Translate a space with a `space-width' property
25174 into a stretch glyph. */
25175 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25176 / FONT_HEIGHT (font));
25177 append_stretch_glyph (it, it->object, it->pixel_width,
25178 it->ascent + it->descent, ascent);
25179 }
25180 else
25181 append_glyph (it);
25182
25183 /* If characters with lbearing or rbearing are displayed
25184 in this line, record that fact in a flag of the
25185 glyph row. This is used to optimize X output code. */
25186 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25187 it->glyph_row->contains_overlapping_glyphs_p = 1;
25188 }
25189 if (! stretched_p && it->pixel_width == 0)
25190 /* We assure that all visible glyphs have at least 1-pixel
25191 width. */
25192 it->pixel_width = 1;
25193 }
25194 else if (it->char_to_display == '\n')
25195 {
25196 /* A newline has no width, but we need the height of the
25197 line. But if previous part of the line sets a height,
25198 don't increase that height */
25199
25200 Lisp_Object height;
25201 Lisp_Object total_height = Qnil;
25202
25203 it->override_ascent = -1;
25204 it->pixel_width = 0;
25205 it->nglyphs = 0;
25206
25207 height = get_it_property (it, Qline_height);
25208 /* Split (line-height total-height) list */
25209 if (CONSP (height)
25210 && CONSP (XCDR (height))
25211 && NILP (XCDR (XCDR (height))))
25212 {
25213 total_height = XCAR (XCDR (height));
25214 height = XCAR (height);
25215 }
25216 height = calc_line_height_property (it, height, font, boff, 1);
25217
25218 if (it->override_ascent >= 0)
25219 {
25220 it->ascent = it->override_ascent;
25221 it->descent = it->override_descent;
25222 boff = it->override_boff;
25223 }
25224 else
25225 {
25226 it->ascent = FONT_BASE (font) + boff;
25227 it->descent = FONT_DESCENT (font) - boff;
25228 }
25229
25230 if (EQ (height, Qt))
25231 {
25232 if (it->descent > it->max_descent)
25233 {
25234 it->ascent += it->descent - it->max_descent;
25235 it->descent = it->max_descent;
25236 }
25237 if (it->ascent > it->max_ascent)
25238 {
25239 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25240 it->ascent = it->max_ascent;
25241 }
25242 it->phys_ascent = min (it->phys_ascent, it->ascent);
25243 it->phys_descent = min (it->phys_descent, it->descent);
25244 it->constrain_row_ascent_descent_p = 1;
25245 extra_line_spacing = 0;
25246 }
25247 else
25248 {
25249 Lisp_Object spacing;
25250
25251 it->phys_ascent = it->ascent;
25252 it->phys_descent = it->descent;
25253
25254 if ((it->max_ascent > 0 || it->max_descent > 0)
25255 && face->box != FACE_NO_BOX
25256 && face->box_line_width > 0)
25257 {
25258 it->ascent += face->box_line_width;
25259 it->descent += face->box_line_width;
25260 }
25261 if (!NILP (height)
25262 && XINT (height) > it->ascent + it->descent)
25263 it->ascent = XINT (height) - it->descent;
25264
25265 if (!NILP (total_height))
25266 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25267 else
25268 {
25269 spacing = get_it_property (it, Qline_spacing);
25270 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25271 }
25272 if (INTEGERP (spacing))
25273 {
25274 extra_line_spacing = XINT (spacing);
25275 if (!NILP (total_height))
25276 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25277 }
25278 }
25279 }
25280 else /* i.e. (it->char_to_display == '\t') */
25281 {
25282 if (font->space_width > 0)
25283 {
25284 int tab_width = it->tab_width * font->space_width;
25285 int x = it->current_x + it->continuation_lines_width;
25286 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25287
25288 /* If the distance from the current position to the next tab
25289 stop is less than a space character width, use the
25290 tab stop after that. */
25291 if (next_tab_x - x < font->space_width)
25292 next_tab_x += tab_width;
25293
25294 it->pixel_width = next_tab_x - x;
25295 it->nglyphs = 1;
25296 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25297 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25298
25299 if (it->glyph_row)
25300 {
25301 append_stretch_glyph (it, it->object, it->pixel_width,
25302 it->ascent + it->descent, it->ascent);
25303 }
25304 }
25305 else
25306 {
25307 it->pixel_width = 0;
25308 it->nglyphs = 1;
25309 }
25310 }
25311 }
25312 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25313 {
25314 /* A static composition.
25315
25316 Note: A composition is represented as one glyph in the
25317 glyph matrix. There are no padding glyphs.
25318
25319 Important note: pixel_width, ascent, and descent are the
25320 values of what is drawn by draw_glyphs (i.e. the values of
25321 the overall glyphs composed). */
25322 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25323 int boff; /* baseline offset */
25324 struct composition *cmp = composition_table[it->cmp_it.id];
25325 int glyph_len = cmp->glyph_len;
25326 struct font *font = face->font;
25327
25328 it->nglyphs = 1;
25329
25330 /* If we have not yet calculated pixel size data of glyphs of
25331 the composition for the current face font, calculate them
25332 now. Theoretically, we have to check all fonts for the
25333 glyphs, but that requires much time and memory space. So,
25334 here we check only the font of the first glyph. This may
25335 lead to incorrect display, but it's very rare, and C-l
25336 (recenter-top-bottom) can correct the display anyway. */
25337 if (! cmp->font || cmp->font != font)
25338 {
25339 /* Ascent and descent of the font of the first character
25340 of this composition (adjusted by baseline offset).
25341 Ascent and descent of overall glyphs should not be less
25342 than these, respectively. */
25343 int font_ascent, font_descent, font_height;
25344 /* Bounding box of the overall glyphs. */
25345 int leftmost, rightmost, lowest, highest;
25346 int lbearing, rbearing;
25347 int i, width, ascent, descent;
25348 int left_padded = 0, right_padded = 0;
25349 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25350 XChar2b char2b;
25351 struct font_metrics *pcm;
25352 int font_not_found_p;
25353 ptrdiff_t pos;
25354
25355 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25356 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25357 break;
25358 if (glyph_len < cmp->glyph_len)
25359 right_padded = 1;
25360 for (i = 0; i < glyph_len; i++)
25361 {
25362 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25363 break;
25364 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25365 }
25366 if (i > 0)
25367 left_padded = 1;
25368
25369 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25370 : IT_CHARPOS (*it));
25371 /* If no suitable font is found, use the default font. */
25372 font_not_found_p = font == NULL;
25373 if (font_not_found_p)
25374 {
25375 face = face->ascii_face;
25376 font = face->font;
25377 }
25378 boff = font->baseline_offset;
25379 if (font->vertical_centering)
25380 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25381 font_ascent = FONT_BASE (font) + boff;
25382 font_descent = FONT_DESCENT (font) - boff;
25383 font_height = FONT_HEIGHT (font);
25384
25385 cmp->font = font;
25386
25387 pcm = NULL;
25388 if (! font_not_found_p)
25389 {
25390 get_char_face_and_encoding (it->f, c, it->face_id,
25391 &char2b, 0);
25392 pcm = get_per_char_metric (font, &char2b);
25393 }
25394
25395 /* Initialize the bounding box. */
25396 if (pcm)
25397 {
25398 width = cmp->glyph_len > 0 ? pcm->width : 0;
25399 ascent = pcm->ascent;
25400 descent = pcm->descent;
25401 lbearing = pcm->lbearing;
25402 rbearing = pcm->rbearing;
25403 }
25404 else
25405 {
25406 width = cmp->glyph_len > 0 ? font->space_width : 0;
25407 ascent = FONT_BASE (font);
25408 descent = FONT_DESCENT (font);
25409 lbearing = 0;
25410 rbearing = width;
25411 }
25412
25413 rightmost = width;
25414 leftmost = 0;
25415 lowest = - descent + boff;
25416 highest = ascent + boff;
25417
25418 if (! font_not_found_p
25419 && font->default_ascent
25420 && CHAR_TABLE_P (Vuse_default_ascent)
25421 && !NILP (Faref (Vuse_default_ascent,
25422 make_number (it->char_to_display))))
25423 highest = font->default_ascent + boff;
25424
25425 /* Draw the first glyph at the normal position. It may be
25426 shifted to right later if some other glyphs are drawn
25427 at the left. */
25428 cmp->offsets[i * 2] = 0;
25429 cmp->offsets[i * 2 + 1] = boff;
25430 cmp->lbearing = lbearing;
25431 cmp->rbearing = rbearing;
25432
25433 /* Set cmp->offsets for the remaining glyphs. */
25434 for (i++; i < glyph_len; i++)
25435 {
25436 int left, right, btm, top;
25437 int ch = COMPOSITION_GLYPH (cmp, i);
25438 int face_id;
25439 struct face *this_face;
25440
25441 if (ch == '\t')
25442 ch = ' ';
25443 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25444 this_face = FACE_FROM_ID (it->f, face_id);
25445 font = this_face->font;
25446
25447 if (font == NULL)
25448 pcm = NULL;
25449 else
25450 {
25451 get_char_face_and_encoding (it->f, ch, face_id,
25452 &char2b, 0);
25453 pcm = get_per_char_metric (font, &char2b);
25454 }
25455 if (! pcm)
25456 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25457 else
25458 {
25459 width = pcm->width;
25460 ascent = pcm->ascent;
25461 descent = pcm->descent;
25462 lbearing = pcm->lbearing;
25463 rbearing = pcm->rbearing;
25464 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25465 {
25466 /* Relative composition with or without
25467 alternate chars. */
25468 left = (leftmost + rightmost - width) / 2;
25469 btm = - descent + boff;
25470 if (font->relative_compose
25471 && (! CHAR_TABLE_P (Vignore_relative_composition)
25472 || NILP (Faref (Vignore_relative_composition,
25473 make_number (ch)))))
25474 {
25475
25476 if (- descent >= font->relative_compose)
25477 /* One extra pixel between two glyphs. */
25478 btm = highest + 1;
25479 else if (ascent <= 0)
25480 /* One extra pixel between two glyphs. */
25481 btm = lowest - 1 - ascent - descent;
25482 }
25483 }
25484 else
25485 {
25486 /* A composition rule is specified by an integer
25487 value that encodes global and new reference
25488 points (GREF and NREF). GREF and NREF are
25489 specified by numbers as below:
25490
25491 0---1---2 -- ascent
25492 | |
25493 | |
25494 | |
25495 9--10--11 -- center
25496 | |
25497 ---3---4---5--- baseline
25498 | |
25499 6---7---8 -- descent
25500 */
25501 int rule = COMPOSITION_RULE (cmp, i);
25502 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25503
25504 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25505 grefx = gref % 3, nrefx = nref % 3;
25506 grefy = gref / 3, nrefy = nref / 3;
25507 if (xoff)
25508 xoff = font_height * (xoff - 128) / 256;
25509 if (yoff)
25510 yoff = font_height * (yoff - 128) / 256;
25511
25512 left = (leftmost
25513 + grefx * (rightmost - leftmost) / 2
25514 - nrefx * width / 2
25515 + xoff);
25516
25517 btm = ((grefy == 0 ? highest
25518 : grefy == 1 ? 0
25519 : grefy == 2 ? lowest
25520 : (highest + lowest) / 2)
25521 - (nrefy == 0 ? ascent + descent
25522 : nrefy == 1 ? descent - boff
25523 : nrefy == 2 ? 0
25524 : (ascent + descent) / 2)
25525 + yoff);
25526 }
25527
25528 cmp->offsets[i * 2] = left;
25529 cmp->offsets[i * 2 + 1] = btm + descent;
25530
25531 /* Update the bounding box of the overall glyphs. */
25532 if (width > 0)
25533 {
25534 right = left + width;
25535 if (left < leftmost)
25536 leftmost = left;
25537 if (right > rightmost)
25538 rightmost = right;
25539 }
25540 top = btm + descent + ascent;
25541 if (top > highest)
25542 highest = top;
25543 if (btm < lowest)
25544 lowest = btm;
25545
25546 if (cmp->lbearing > left + lbearing)
25547 cmp->lbearing = left + lbearing;
25548 if (cmp->rbearing < left + rbearing)
25549 cmp->rbearing = left + rbearing;
25550 }
25551 }
25552
25553 /* If there are glyphs whose x-offsets are negative,
25554 shift all glyphs to the right and make all x-offsets
25555 non-negative. */
25556 if (leftmost < 0)
25557 {
25558 for (i = 0; i < cmp->glyph_len; i++)
25559 cmp->offsets[i * 2] -= leftmost;
25560 rightmost -= leftmost;
25561 cmp->lbearing -= leftmost;
25562 cmp->rbearing -= leftmost;
25563 }
25564
25565 if (left_padded && cmp->lbearing < 0)
25566 {
25567 for (i = 0; i < cmp->glyph_len; i++)
25568 cmp->offsets[i * 2] -= cmp->lbearing;
25569 rightmost -= cmp->lbearing;
25570 cmp->rbearing -= cmp->lbearing;
25571 cmp->lbearing = 0;
25572 }
25573 if (right_padded && rightmost < cmp->rbearing)
25574 {
25575 rightmost = cmp->rbearing;
25576 }
25577
25578 cmp->pixel_width = rightmost;
25579 cmp->ascent = highest;
25580 cmp->descent = - lowest;
25581 if (cmp->ascent < font_ascent)
25582 cmp->ascent = font_ascent;
25583 if (cmp->descent < font_descent)
25584 cmp->descent = font_descent;
25585 }
25586
25587 if (it->glyph_row
25588 && (cmp->lbearing < 0
25589 || cmp->rbearing > cmp->pixel_width))
25590 it->glyph_row->contains_overlapping_glyphs_p = 1;
25591
25592 it->pixel_width = cmp->pixel_width;
25593 it->ascent = it->phys_ascent = cmp->ascent;
25594 it->descent = it->phys_descent = cmp->descent;
25595 if (face->box != FACE_NO_BOX)
25596 {
25597 int thick = face->box_line_width;
25598
25599 if (thick > 0)
25600 {
25601 it->ascent += thick;
25602 it->descent += thick;
25603 }
25604 else
25605 thick = - thick;
25606
25607 if (it->start_of_box_run_p)
25608 it->pixel_width += thick;
25609 if (it->end_of_box_run_p)
25610 it->pixel_width += thick;
25611 }
25612
25613 /* If face has an overline, add the height of the overline
25614 (1 pixel) and a 1 pixel margin to the character height. */
25615 if (face->overline_p)
25616 it->ascent += overline_margin;
25617
25618 take_vertical_position_into_account (it);
25619 if (it->ascent < 0)
25620 it->ascent = 0;
25621 if (it->descent < 0)
25622 it->descent = 0;
25623
25624 if (it->glyph_row && cmp->glyph_len > 0)
25625 append_composite_glyph (it);
25626 }
25627 else if (it->what == IT_COMPOSITION)
25628 {
25629 /* A dynamic (automatic) composition. */
25630 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25631 Lisp_Object gstring;
25632 struct font_metrics metrics;
25633
25634 it->nglyphs = 1;
25635
25636 gstring = composition_gstring_from_id (it->cmp_it.id);
25637 it->pixel_width
25638 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25639 &metrics);
25640 if (it->glyph_row
25641 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25642 it->glyph_row->contains_overlapping_glyphs_p = 1;
25643 it->ascent = it->phys_ascent = metrics.ascent;
25644 it->descent = it->phys_descent = metrics.descent;
25645 if (face->box != FACE_NO_BOX)
25646 {
25647 int thick = face->box_line_width;
25648
25649 if (thick > 0)
25650 {
25651 it->ascent += thick;
25652 it->descent += thick;
25653 }
25654 else
25655 thick = - thick;
25656
25657 if (it->start_of_box_run_p)
25658 it->pixel_width += thick;
25659 if (it->end_of_box_run_p)
25660 it->pixel_width += thick;
25661 }
25662 /* If face has an overline, add the height of the overline
25663 (1 pixel) and a 1 pixel margin to the character height. */
25664 if (face->overline_p)
25665 it->ascent += overline_margin;
25666 take_vertical_position_into_account (it);
25667 if (it->ascent < 0)
25668 it->ascent = 0;
25669 if (it->descent < 0)
25670 it->descent = 0;
25671
25672 if (it->glyph_row)
25673 append_composite_glyph (it);
25674 }
25675 else if (it->what == IT_GLYPHLESS)
25676 produce_glyphless_glyph (it, 0, Qnil);
25677 else if (it->what == IT_IMAGE)
25678 produce_image_glyph (it);
25679 else if (it->what == IT_STRETCH)
25680 produce_stretch_glyph (it);
25681
25682 done:
25683 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25684 because this isn't true for images with `:ascent 100'. */
25685 eassert (it->ascent >= 0 && it->descent >= 0);
25686 if (it->area == TEXT_AREA)
25687 it->current_x += it->pixel_width;
25688
25689 if (extra_line_spacing > 0)
25690 {
25691 it->descent += extra_line_spacing;
25692 if (extra_line_spacing > it->max_extra_line_spacing)
25693 it->max_extra_line_spacing = extra_line_spacing;
25694 }
25695
25696 it->max_ascent = max (it->max_ascent, it->ascent);
25697 it->max_descent = max (it->max_descent, it->descent);
25698 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25699 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25700 }
25701
25702 /* EXPORT for RIF:
25703 Output LEN glyphs starting at START at the nominal cursor position.
25704 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
25705 being updated, and UPDATED_AREA is the area of that row being updated. */
25706
25707 void
25708 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
25709 struct glyph *start, enum glyph_row_area updated_area, int len)
25710 {
25711 int x, hpos, chpos = w->phys_cursor.hpos;
25712
25713 eassert (updated_row);
25714 /* When the window is hscrolled, cursor hpos can legitimately be out
25715 of bounds, but we draw the cursor at the corresponding window
25716 margin in that case. */
25717 if (!updated_row->reversed_p && chpos < 0)
25718 chpos = 0;
25719 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25720 chpos = updated_row->used[TEXT_AREA] - 1;
25721
25722 block_input ();
25723
25724 /* Write glyphs. */
25725
25726 hpos = start - updated_row->glyphs[updated_area];
25727 x = draw_glyphs (w, w->output_cursor.x,
25728 updated_row, updated_area,
25729 hpos, hpos + len,
25730 DRAW_NORMAL_TEXT, 0);
25731
25732 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25733 if (updated_area == TEXT_AREA
25734 && w->phys_cursor_on_p
25735 && w->phys_cursor.vpos == w->output_cursor.vpos
25736 && chpos >= hpos
25737 && chpos < hpos + len)
25738 w->phys_cursor_on_p = 0;
25739
25740 unblock_input ();
25741
25742 /* Advance the output cursor. */
25743 w->output_cursor.hpos += len;
25744 w->output_cursor.x = x;
25745 }
25746
25747
25748 /* EXPORT for RIF:
25749 Insert LEN glyphs from START at the nominal cursor position. */
25750
25751 void
25752 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
25753 struct glyph *start, enum glyph_row_area updated_area, int len)
25754 {
25755 struct frame *f;
25756 int line_height, shift_by_width, shifted_region_width;
25757 struct glyph_row *row;
25758 struct glyph *glyph;
25759 int frame_x, frame_y;
25760 ptrdiff_t hpos;
25761
25762 eassert (updated_row);
25763 block_input ();
25764 f = XFRAME (WINDOW_FRAME (w));
25765
25766 /* Get the height of the line we are in. */
25767 row = updated_row;
25768 line_height = row->height;
25769
25770 /* Get the width of the glyphs to insert. */
25771 shift_by_width = 0;
25772 for (glyph = start; glyph < start + len; ++glyph)
25773 shift_by_width += glyph->pixel_width;
25774
25775 /* Get the width of the region to shift right. */
25776 shifted_region_width = (window_box_width (w, updated_area)
25777 - w->output_cursor.x
25778 - shift_by_width);
25779
25780 /* Shift right. */
25781 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
25782 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
25783
25784 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25785 line_height, shift_by_width);
25786
25787 /* Write the glyphs. */
25788 hpos = start - row->glyphs[updated_area];
25789 draw_glyphs (w, w->output_cursor.x, row, updated_area,
25790 hpos, hpos + len,
25791 DRAW_NORMAL_TEXT, 0);
25792
25793 /* Advance the output cursor. */
25794 w->output_cursor.hpos += len;
25795 w->output_cursor.x += shift_by_width;
25796 unblock_input ();
25797 }
25798
25799
25800 /* EXPORT for RIF:
25801 Erase the current text line from the nominal cursor position
25802 (inclusive) to pixel column TO_X (exclusive). The idea is that
25803 everything from TO_X onward is already erased.
25804
25805 TO_X is a pixel position relative to UPDATED_AREA of currently
25806 updated window W. TO_X == -1 means clear to the end of this area. */
25807
25808 void
25809 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
25810 enum glyph_row_area updated_area, int to_x)
25811 {
25812 struct frame *f;
25813 int max_x, min_y, max_y;
25814 int from_x, from_y, to_y;
25815
25816 eassert (updated_row);
25817 f = XFRAME (w->frame);
25818
25819 if (updated_row->full_width_p)
25820 max_x = WINDOW_TOTAL_WIDTH (w);
25821 else
25822 max_x = window_box_width (w, updated_area);
25823 max_y = window_text_bottom_y (w);
25824
25825 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25826 of window. For TO_X > 0, truncate to end of drawing area. */
25827 if (to_x == 0)
25828 return;
25829 else if (to_x < 0)
25830 to_x = max_x;
25831 else
25832 to_x = min (to_x, max_x);
25833
25834 to_y = min (max_y, w->output_cursor.y + updated_row->height);
25835
25836 /* Notice if the cursor will be cleared by this operation. */
25837 if (!updated_row->full_width_p)
25838 notice_overwritten_cursor (w, updated_area,
25839 w->output_cursor.x, -1,
25840 updated_row->y,
25841 MATRIX_ROW_BOTTOM_Y (updated_row));
25842
25843 from_x = w->output_cursor.x;
25844
25845 /* Translate to frame coordinates. */
25846 if (updated_row->full_width_p)
25847 {
25848 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25849 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25850 }
25851 else
25852 {
25853 int area_left = window_box_left (w, updated_area);
25854 from_x += area_left;
25855 to_x += area_left;
25856 }
25857
25858 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25859 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
25860 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25861
25862 /* Prevent inadvertently clearing to end of the X window. */
25863 if (to_x > from_x && to_y > from_y)
25864 {
25865 block_input ();
25866 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25867 to_x - from_x, to_y - from_y);
25868 unblock_input ();
25869 }
25870 }
25871
25872 #endif /* HAVE_WINDOW_SYSTEM */
25873
25874
25875 \f
25876 /***********************************************************************
25877 Cursor types
25878 ***********************************************************************/
25879
25880 /* Value is the internal representation of the specified cursor type
25881 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25882 of the bar cursor. */
25883
25884 static enum text_cursor_kinds
25885 get_specified_cursor_type (Lisp_Object arg, int *width)
25886 {
25887 enum text_cursor_kinds type;
25888
25889 if (NILP (arg))
25890 return NO_CURSOR;
25891
25892 if (EQ (arg, Qbox))
25893 return FILLED_BOX_CURSOR;
25894
25895 if (EQ (arg, Qhollow))
25896 return HOLLOW_BOX_CURSOR;
25897
25898 if (EQ (arg, Qbar))
25899 {
25900 *width = 2;
25901 return BAR_CURSOR;
25902 }
25903
25904 if (CONSP (arg)
25905 && EQ (XCAR (arg), Qbar)
25906 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25907 {
25908 *width = XINT (XCDR (arg));
25909 return BAR_CURSOR;
25910 }
25911
25912 if (EQ (arg, Qhbar))
25913 {
25914 *width = 2;
25915 return HBAR_CURSOR;
25916 }
25917
25918 if (CONSP (arg)
25919 && EQ (XCAR (arg), Qhbar)
25920 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25921 {
25922 *width = XINT (XCDR (arg));
25923 return HBAR_CURSOR;
25924 }
25925
25926 /* Treat anything unknown as "hollow box cursor".
25927 It was bad to signal an error; people have trouble fixing
25928 .Xdefaults with Emacs, when it has something bad in it. */
25929 type = HOLLOW_BOX_CURSOR;
25930
25931 return type;
25932 }
25933
25934 /* Set the default cursor types for specified frame. */
25935 void
25936 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25937 {
25938 int width = 1;
25939 Lisp_Object tem;
25940
25941 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25942 FRAME_CURSOR_WIDTH (f) = width;
25943
25944 /* By default, set up the blink-off state depending on the on-state. */
25945
25946 tem = Fassoc (arg, Vblink_cursor_alist);
25947 if (!NILP (tem))
25948 {
25949 FRAME_BLINK_OFF_CURSOR (f)
25950 = get_specified_cursor_type (XCDR (tem), &width);
25951 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25952 }
25953 else
25954 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25955
25956 /* Make sure the cursor gets redrawn. */
25957 f->cursor_type_changed = 1;
25958 }
25959
25960
25961 #ifdef HAVE_WINDOW_SYSTEM
25962
25963 /* Return the cursor we want to be displayed in window W. Return
25964 width of bar/hbar cursor through WIDTH arg. Return with
25965 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25966 (i.e. if the `system caret' should track this cursor).
25967
25968 In a mini-buffer window, we want the cursor only to appear if we
25969 are reading input from this window. For the selected window, we
25970 want the cursor type given by the frame parameter or buffer local
25971 setting of cursor-type. If explicitly marked off, draw no cursor.
25972 In all other cases, we want a hollow box cursor. */
25973
25974 static enum text_cursor_kinds
25975 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25976 int *active_cursor)
25977 {
25978 struct frame *f = XFRAME (w->frame);
25979 struct buffer *b = XBUFFER (w->contents);
25980 int cursor_type = DEFAULT_CURSOR;
25981 Lisp_Object alt_cursor;
25982 int non_selected = 0;
25983
25984 *active_cursor = 1;
25985
25986 /* Echo area */
25987 if (cursor_in_echo_area
25988 && FRAME_HAS_MINIBUF_P (f)
25989 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25990 {
25991 if (w == XWINDOW (echo_area_window))
25992 {
25993 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25994 {
25995 *width = FRAME_CURSOR_WIDTH (f);
25996 return FRAME_DESIRED_CURSOR (f);
25997 }
25998 else
25999 return get_specified_cursor_type (BVAR (b, cursor_type), width);
26000 }
26001
26002 *active_cursor = 0;
26003 non_selected = 1;
26004 }
26005
26006 /* Detect a nonselected window or nonselected frame. */
26007 else if (w != XWINDOW (f->selected_window)
26008 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
26009 {
26010 *active_cursor = 0;
26011
26012 if (MINI_WINDOW_P (w) && minibuf_level == 0)
26013 return NO_CURSOR;
26014
26015 non_selected = 1;
26016 }
26017
26018 /* Never display a cursor in a window in which cursor-type is nil. */
26019 if (NILP (BVAR (b, cursor_type)))
26020 return NO_CURSOR;
26021
26022 /* Get the normal cursor type for this window. */
26023 if (EQ (BVAR (b, cursor_type), Qt))
26024 {
26025 cursor_type = FRAME_DESIRED_CURSOR (f);
26026 *width = FRAME_CURSOR_WIDTH (f);
26027 }
26028 else
26029 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
26030
26031 /* Use cursor-in-non-selected-windows instead
26032 for non-selected window or frame. */
26033 if (non_selected)
26034 {
26035 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
26036 if (!EQ (Qt, alt_cursor))
26037 return get_specified_cursor_type (alt_cursor, width);
26038 /* t means modify the normal cursor type. */
26039 if (cursor_type == FILLED_BOX_CURSOR)
26040 cursor_type = HOLLOW_BOX_CURSOR;
26041 else if (cursor_type == BAR_CURSOR && *width > 1)
26042 --*width;
26043 return cursor_type;
26044 }
26045
26046 /* Use normal cursor if not blinked off. */
26047 if (!w->cursor_off_p)
26048 {
26049 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26050 {
26051 if (cursor_type == FILLED_BOX_CURSOR)
26052 {
26053 /* Using a block cursor on large images can be very annoying.
26054 So use a hollow cursor for "large" images.
26055 If image is not transparent (no mask), also use hollow cursor. */
26056 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26057 if (img != NULL && IMAGEP (img->spec))
26058 {
26059 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26060 where N = size of default frame font size.
26061 This should cover most of the "tiny" icons people may use. */
26062 if (!img->mask
26063 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
26064 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
26065 cursor_type = HOLLOW_BOX_CURSOR;
26066 }
26067 }
26068 else if (cursor_type != NO_CURSOR)
26069 {
26070 /* Display current only supports BOX and HOLLOW cursors for images.
26071 So for now, unconditionally use a HOLLOW cursor when cursor is
26072 not a solid box cursor. */
26073 cursor_type = HOLLOW_BOX_CURSOR;
26074 }
26075 }
26076 return cursor_type;
26077 }
26078
26079 /* Cursor is blinked off, so determine how to "toggle" it. */
26080
26081 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26082 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
26083 return get_specified_cursor_type (XCDR (alt_cursor), width);
26084
26085 /* Then see if frame has specified a specific blink off cursor type. */
26086 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
26087 {
26088 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
26089 return FRAME_BLINK_OFF_CURSOR (f);
26090 }
26091
26092 #if 0
26093 /* Some people liked having a permanently visible blinking cursor,
26094 while others had very strong opinions against it. So it was
26095 decided to remove it. KFS 2003-09-03 */
26096
26097 /* Finally perform built-in cursor blinking:
26098 filled box <-> hollow box
26099 wide [h]bar <-> narrow [h]bar
26100 narrow [h]bar <-> no cursor
26101 other type <-> no cursor */
26102
26103 if (cursor_type == FILLED_BOX_CURSOR)
26104 return HOLLOW_BOX_CURSOR;
26105
26106 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
26107 {
26108 *width = 1;
26109 return cursor_type;
26110 }
26111 #endif
26112
26113 return NO_CURSOR;
26114 }
26115
26116
26117 /* Notice when the text cursor of window W has been completely
26118 overwritten by a drawing operation that outputs glyphs in AREA
26119 starting at X0 and ending at X1 in the line starting at Y0 and
26120 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26121 the rest of the line after X0 has been written. Y coordinates
26122 are window-relative. */
26123
26124 static void
26125 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
26126 int x0, int x1, int y0, int y1)
26127 {
26128 int cx0, cx1, cy0, cy1;
26129 struct glyph_row *row;
26130
26131 if (!w->phys_cursor_on_p)
26132 return;
26133 if (area != TEXT_AREA)
26134 return;
26135
26136 if (w->phys_cursor.vpos < 0
26137 || w->phys_cursor.vpos >= w->current_matrix->nrows
26138 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
26139 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
26140 return;
26141
26142 if (row->cursor_in_fringe_p)
26143 {
26144 row->cursor_in_fringe_p = 0;
26145 draw_fringe_bitmap (w, row, row->reversed_p);
26146 w->phys_cursor_on_p = 0;
26147 return;
26148 }
26149
26150 cx0 = w->phys_cursor.x;
26151 cx1 = cx0 + w->phys_cursor_width;
26152 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26153 return;
26154
26155 /* The cursor image will be completely removed from the
26156 screen if the output area intersects the cursor area in
26157 y-direction. When we draw in [y0 y1[, and some part of
26158 the cursor is at y < y0, that part must have been drawn
26159 before. When scrolling, the cursor is erased before
26160 actually scrolling, so we don't come here. When not
26161 scrolling, the rows above the old cursor row must have
26162 changed, and in this case these rows must have written
26163 over the cursor image.
26164
26165 Likewise if part of the cursor is below y1, with the
26166 exception of the cursor being in the first blank row at
26167 the buffer and window end because update_text_area
26168 doesn't draw that row. (Except when it does, but
26169 that's handled in update_text_area.) */
26170
26171 cy0 = w->phys_cursor.y;
26172 cy1 = cy0 + w->phys_cursor_height;
26173 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26174 return;
26175
26176 w->phys_cursor_on_p = 0;
26177 }
26178
26179 #endif /* HAVE_WINDOW_SYSTEM */
26180
26181 \f
26182 /************************************************************************
26183 Mouse Face
26184 ************************************************************************/
26185
26186 #ifdef HAVE_WINDOW_SYSTEM
26187
26188 /* EXPORT for RIF:
26189 Fix the display of area AREA of overlapping row ROW in window W
26190 with respect to the overlapping part OVERLAPS. */
26191
26192 void
26193 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26194 enum glyph_row_area area, int overlaps)
26195 {
26196 int i, x;
26197
26198 block_input ();
26199
26200 x = 0;
26201 for (i = 0; i < row->used[area];)
26202 {
26203 if (row->glyphs[area][i].overlaps_vertically_p)
26204 {
26205 int start = i, start_x = x;
26206
26207 do
26208 {
26209 x += row->glyphs[area][i].pixel_width;
26210 ++i;
26211 }
26212 while (i < row->used[area]
26213 && row->glyphs[area][i].overlaps_vertically_p);
26214
26215 draw_glyphs (w, start_x, row, area,
26216 start, i,
26217 DRAW_NORMAL_TEXT, overlaps);
26218 }
26219 else
26220 {
26221 x += row->glyphs[area][i].pixel_width;
26222 ++i;
26223 }
26224 }
26225
26226 unblock_input ();
26227 }
26228
26229
26230 /* EXPORT:
26231 Draw the cursor glyph of window W in glyph row ROW. See the
26232 comment of draw_glyphs for the meaning of HL. */
26233
26234 void
26235 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26236 enum draw_glyphs_face hl)
26237 {
26238 /* If cursor hpos is out of bounds, don't draw garbage. This can
26239 happen in mini-buffer windows when switching between echo area
26240 glyphs and mini-buffer. */
26241 if ((row->reversed_p
26242 ? (w->phys_cursor.hpos >= 0)
26243 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26244 {
26245 int on_p = w->phys_cursor_on_p;
26246 int x1;
26247 int hpos = w->phys_cursor.hpos;
26248
26249 /* When the window is hscrolled, cursor hpos can legitimately be
26250 out of bounds, but we draw the cursor at the corresponding
26251 window margin in that case. */
26252 if (!row->reversed_p && hpos < 0)
26253 hpos = 0;
26254 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26255 hpos = row->used[TEXT_AREA] - 1;
26256
26257 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26258 hl, 0);
26259 w->phys_cursor_on_p = on_p;
26260
26261 if (hl == DRAW_CURSOR)
26262 w->phys_cursor_width = x1 - w->phys_cursor.x;
26263 /* When we erase the cursor, and ROW is overlapped by other
26264 rows, make sure that these overlapping parts of other rows
26265 are redrawn. */
26266 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26267 {
26268 w->phys_cursor_width = x1 - w->phys_cursor.x;
26269
26270 if (row > w->current_matrix->rows
26271 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26272 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26273 OVERLAPS_ERASED_CURSOR);
26274
26275 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26276 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26277 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26278 OVERLAPS_ERASED_CURSOR);
26279 }
26280 }
26281 }
26282
26283
26284 /* EXPORT:
26285 Erase the image of a cursor of window W from the screen. */
26286
26287 void
26288 erase_phys_cursor (struct window *w)
26289 {
26290 struct frame *f = XFRAME (w->frame);
26291 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26292 int hpos = w->phys_cursor.hpos;
26293 int vpos = w->phys_cursor.vpos;
26294 int mouse_face_here_p = 0;
26295 struct glyph_matrix *active_glyphs = w->current_matrix;
26296 struct glyph_row *cursor_row;
26297 struct glyph *cursor_glyph;
26298 enum draw_glyphs_face hl;
26299
26300 /* No cursor displayed or row invalidated => nothing to do on the
26301 screen. */
26302 if (w->phys_cursor_type == NO_CURSOR)
26303 goto mark_cursor_off;
26304
26305 /* VPOS >= active_glyphs->nrows means that window has been resized.
26306 Don't bother to erase the cursor. */
26307 if (vpos >= active_glyphs->nrows)
26308 goto mark_cursor_off;
26309
26310 /* If row containing cursor is marked invalid, there is nothing we
26311 can do. */
26312 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26313 if (!cursor_row->enabled_p)
26314 goto mark_cursor_off;
26315
26316 /* If line spacing is > 0, old cursor may only be partially visible in
26317 window after split-window. So adjust visible height. */
26318 cursor_row->visible_height = min (cursor_row->visible_height,
26319 window_text_bottom_y (w) - cursor_row->y);
26320
26321 /* If row is completely invisible, don't attempt to delete a cursor which
26322 isn't there. This can happen if cursor is at top of a window, and
26323 we switch to a buffer with a header line in that window. */
26324 if (cursor_row->visible_height <= 0)
26325 goto mark_cursor_off;
26326
26327 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26328 if (cursor_row->cursor_in_fringe_p)
26329 {
26330 cursor_row->cursor_in_fringe_p = 0;
26331 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26332 goto mark_cursor_off;
26333 }
26334
26335 /* This can happen when the new row is shorter than the old one.
26336 In this case, either draw_glyphs or clear_end_of_line
26337 should have cleared the cursor. Note that we wouldn't be
26338 able to erase the cursor in this case because we don't have a
26339 cursor glyph at hand. */
26340 if ((cursor_row->reversed_p
26341 ? (w->phys_cursor.hpos < 0)
26342 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26343 goto mark_cursor_off;
26344
26345 /* When the window is hscrolled, cursor hpos can legitimately be out
26346 of bounds, but we draw the cursor at the corresponding window
26347 margin in that case. */
26348 if (!cursor_row->reversed_p && hpos < 0)
26349 hpos = 0;
26350 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26351 hpos = cursor_row->used[TEXT_AREA] - 1;
26352
26353 /* If the cursor is in the mouse face area, redisplay that when
26354 we clear the cursor. */
26355 if (! NILP (hlinfo->mouse_face_window)
26356 && coords_in_mouse_face_p (w, hpos, vpos)
26357 /* Don't redraw the cursor's spot in mouse face if it is at the
26358 end of a line (on a newline). The cursor appears there, but
26359 mouse highlighting does not. */
26360 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26361 mouse_face_here_p = 1;
26362
26363 /* Maybe clear the display under the cursor. */
26364 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26365 {
26366 int x, y, left_x;
26367 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26368 int width;
26369
26370 cursor_glyph = get_phys_cursor_glyph (w);
26371 if (cursor_glyph == NULL)
26372 goto mark_cursor_off;
26373
26374 width = cursor_glyph->pixel_width;
26375 left_x = window_box_left_offset (w, TEXT_AREA);
26376 x = w->phys_cursor.x;
26377 if (x < left_x)
26378 width -= left_x - x;
26379 width = min (width, window_box_width (w, TEXT_AREA) - x);
26380 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26381 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26382
26383 if (width > 0)
26384 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26385 }
26386
26387 /* Erase the cursor by redrawing the character underneath it. */
26388 if (mouse_face_here_p)
26389 hl = DRAW_MOUSE_FACE;
26390 else
26391 hl = DRAW_NORMAL_TEXT;
26392 draw_phys_cursor_glyph (w, cursor_row, hl);
26393
26394 mark_cursor_off:
26395 w->phys_cursor_on_p = 0;
26396 w->phys_cursor_type = NO_CURSOR;
26397 }
26398
26399
26400 /* EXPORT:
26401 Display or clear cursor of window W. If ON is zero, clear the
26402 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26403 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26404
26405 void
26406 display_and_set_cursor (struct window *w, bool on,
26407 int hpos, int vpos, int x, int y)
26408 {
26409 struct frame *f = XFRAME (w->frame);
26410 int new_cursor_type;
26411 int new_cursor_width;
26412 int active_cursor;
26413 struct glyph_row *glyph_row;
26414 struct glyph *glyph;
26415
26416 /* This is pointless on invisible frames, and dangerous on garbaged
26417 windows and frames; in the latter case, the frame or window may
26418 be in the midst of changing its size, and x and y may be off the
26419 window. */
26420 if (! FRAME_VISIBLE_P (f)
26421 || FRAME_GARBAGED_P (f)
26422 || vpos >= w->current_matrix->nrows
26423 || hpos >= w->current_matrix->matrix_w)
26424 return;
26425
26426 /* If cursor is off and we want it off, return quickly. */
26427 if (!on && !w->phys_cursor_on_p)
26428 return;
26429
26430 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26431 /* If cursor row is not enabled, we don't really know where to
26432 display the cursor. */
26433 if (!glyph_row->enabled_p)
26434 {
26435 w->phys_cursor_on_p = 0;
26436 return;
26437 }
26438
26439 glyph = NULL;
26440 if (!glyph_row->exact_window_width_line_p
26441 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26442 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26443
26444 eassert (input_blocked_p ());
26445
26446 /* Set new_cursor_type to the cursor we want to be displayed. */
26447 new_cursor_type = get_window_cursor_type (w, glyph,
26448 &new_cursor_width, &active_cursor);
26449
26450 /* If cursor is currently being shown and we don't want it to be or
26451 it is in the wrong place, or the cursor type is not what we want,
26452 erase it. */
26453 if (w->phys_cursor_on_p
26454 && (!on
26455 || w->phys_cursor.x != x
26456 || w->phys_cursor.y != y
26457 || new_cursor_type != w->phys_cursor_type
26458 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26459 && new_cursor_width != w->phys_cursor_width)))
26460 erase_phys_cursor (w);
26461
26462 /* Don't check phys_cursor_on_p here because that flag is only set
26463 to zero in some cases where we know that the cursor has been
26464 completely erased, to avoid the extra work of erasing the cursor
26465 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26466 still not be visible, or it has only been partly erased. */
26467 if (on)
26468 {
26469 w->phys_cursor_ascent = glyph_row->ascent;
26470 w->phys_cursor_height = glyph_row->height;
26471
26472 /* Set phys_cursor_.* before x_draw_.* is called because some
26473 of them may need the information. */
26474 w->phys_cursor.x = x;
26475 w->phys_cursor.y = glyph_row->y;
26476 w->phys_cursor.hpos = hpos;
26477 w->phys_cursor.vpos = vpos;
26478 }
26479
26480 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26481 new_cursor_type, new_cursor_width,
26482 on, active_cursor);
26483 }
26484
26485
26486 /* Switch the display of W's cursor on or off, according to the value
26487 of ON. */
26488
26489 static void
26490 update_window_cursor (struct window *w, bool on)
26491 {
26492 /* Don't update cursor in windows whose frame is in the process
26493 of being deleted. */
26494 if (w->current_matrix)
26495 {
26496 int hpos = w->phys_cursor.hpos;
26497 int vpos = w->phys_cursor.vpos;
26498 struct glyph_row *row;
26499
26500 if (vpos >= w->current_matrix->nrows
26501 || hpos >= w->current_matrix->matrix_w)
26502 return;
26503
26504 row = MATRIX_ROW (w->current_matrix, vpos);
26505
26506 /* When the window is hscrolled, cursor hpos can legitimately be
26507 out of bounds, but we draw the cursor at the corresponding
26508 window margin in that case. */
26509 if (!row->reversed_p && hpos < 0)
26510 hpos = 0;
26511 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26512 hpos = row->used[TEXT_AREA] - 1;
26513
26514 block_input ();
26515 display_and_set_cursor (w, on, hpos, vpos,
26516 w->phys_cursor.x, w->phys_cursor.y);
26517 unblock_input ();
26518 }
26519 }
26520
26521
26522 /* Call update_window_cursor with parameter ON_P on all leaf windows
26523 in the window tree rooted at W. */
26524
26525 static void
26526 update_cursor_in_window_tree (struct window *w, bool on_p)
26527 {
26528 while (w)
26529 {
26530 if (WINDOWP (w->contents))
26531 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26532 else
26533 update_window_cursor (w, on_p);
26534
26535 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26536 }
26537 }
26538
26539
26540 /* EXPORT:
26541 Display the cursor on window W, or clear it, according to ON_P.
26542 Don't change the cursor's position. */
26543
26544 void
26545 x_update_cursor (struct frame *f, bool on_p)
26546 {
26547 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26548 }
26549
26550
26551 /* EXPORT:
26552 Clear the cursor of window W to background color, and mark the
26553 cursor as not shown. This is used when the text where the cursor
26554 is about to be rewritten. */
26555
26556 void
26557 x_clear_cursor (struct window *w)
26558 {
26559 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26560 update_window_cursor (w, 0);
26561 }
26562
26563 #endif /* HAVE_WINDOW_SYSTEM */
26564
26565 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26566 and MSDOS. */
26567 static void
26568 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26569 int start_hpos, int end_hpos,
26570 enum draw_glyphs_face draw)
26571 {
26572 #ifdef HAVE_WINDOW_SYSTEM
26573 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26574 {
26575 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26576 return;
26577 }
26578 #endif
26579 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26580 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26581 #endif
26582 }
26583
26584 /* Display the active region described by mouse_face_* according to DRAW. */
26585
26586 static void
26587 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26588 {
26589 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26590 struct frame *f = XFRAME (WINDOW_FRAME (w));
26591
26592 if (/* If window is in the process of being destroyed, don't bother
26593 to do anything. */
26594 w->current_matrix != NULL
26595 /* Don't update mouse highlight if hidden */
26596 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26597 /* Recognize when we are called to operate on rows that don't exist
26598 anymore. This can happen when a window is split. */
26599 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26600 {
26601 int phys_cursor_on_p = w->phys_cursor_on_p;
26602 struct glyph_row *row, *first, *last;
26603
26604 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26605 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26606
26607 for (row = first; row <= last && row->enabled_p; ++row)
26608 {
26609 int start_hpos, end_hpos, start_x;
26610
26611 /* For all but the first row, the highlight starts at column 0. */
26612 if (row == first)
26613 {
26614 /* R2L rows have BEG and END in reversed order, but the
26615 screen drawing geometry is always left to right. So
26616 we need to mirror the beginning and end of the
26617 highlighted area in R2L rows. */
26618 if (!row->reversed_p)
26619 {
26620 start_hpos = hlinfo->mouse_face_beg_col;
26621 start_x = hlinfo->mouse_face_beg_x;
26622 }
26623 else if (row == last)
26624 {
26625 start_hpos = hlinfo->mouse_face_end_col;
26626 start_x = hlinfo->mouse_face_end_x;
26627 }
26628 else
26629 {
26630 start_hpos = 0;
26631 start_x = 0;
26632 }
26633 }
26634 else if (row->reversed_p && row == last)
26635 {
26636 start_hpos = hlinfo->mouse_face_end_col;
26637 start_x = hlinfo->mouse_face_end_x;
26638 }
26639 else
26640 {
26641 start_hpos = 0;
26642 start_x = 0;
26643 }
26644
26645 if (row == last)
26646 {
26647 if (!row->reversed_p)
26648 end_hpos = hlinfo->mouse_face_end_col;
26649 else if (row == first)
26650 end_hpos = hlinfo->mouse_face_beg_col;
26651 else
26652 {
26653 end_hpos = row->used[TEXT_AREA];
26654 if (draw == DRAW_NORMAL_TEXT)
26655 row->fill_line_p = 1; /* Clear to end of line */
26656 }
26657 }
26658 else if (row->reversed_p && row == first)
26659 end_hpos = hlinfo->mouse_face_beg_col;
26660 else
26661 {
26662 end_hpos = row->used[TEXT_AREA];
26663 if (draw == DRAW_NORMAL_TEXT)
26664 row->fill_line_p = 1; /* Clear to end of line */
26665 }
26666
26667 if (end_hpos > start_hpos)
26668 {
26669 draw_row_with_mouse_face (w, start_x, row,
26670 start_hpos, end_hpos, draw);
26671
26672 row->mouse_face_p
26673 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26674 }
26675 }
26676
26677 #ifdef HAVE_WINDOW_SYSTEM
26678 /* When we've written over the cursor, arrange for it to
26679 be displayed again. */
26680 if (FRAME_WINDOW_P (f)
26681 && phys_cursor_on_p && !w->phys_cursor_on_p)
26682 {
26683 int hpos = w->phys_cursor.hpos;
26684
26685 /* When the window is hscrolled, cursor hpos can legitimately be
26686 out of bounds, but we draw the cursor at the corresponding
26687 window margin in that case. */
26688 if (!row->reversed_p && hpos < 0)
26689 hpos = 0;
26690 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26691 hpos = row->used[TEXT_AREA] - 1;
26692
26693 block_input ();
26694 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26695 w->phys_cursor.x, w->phys_cursor.y);
26696 unblock_input ();
26697 }
26698 #endif /* HAVE_WINDOW_SYSTEM */
26699 }
26700
26701 #ifdef HAVE_WINDOW_SYSTEM
26702 /* Change the mouse cursor. */
26703 if (FRAME_WINDOW_P (f))
26704 {
26705 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
26706 if (draw == DRAW_NORMAL_TEXT
26707 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26708 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26709 else
26710 #endif
26711 if (draw == DRAW_MOUSE_FACE)
26712 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26713 else
26714 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26715 }
26716 #endif /* HAVE_WINDOW_SYSTEM */
26717 }
26718
26719 /* EXPORT:
26720 Clear out the mouse-highlighted active region.
26721 Redraw it un-highlighted first. Value is non-zero if mouse
26722 face was actually drawn unhighlighted. */
26723
26724 int
26725 clear_mouse_face (Mouse_HLInfo *hlinfo)
26726 {
26727 int cleared = 0;
26728
26729 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26730 {
26731 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26732 cleared = 1;
26733 }
26734
26735 reset_mouse_highlight (hlinfo);
26736 return cleared;
26737 }
26738
26739 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26740 within the mouse face on that window. */
26741 static int
26742 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26743 {
26744 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26745
26746 /* Quickly resolve the easy cases. */
26747 if (!(WINDOWP (hlinfo->mouse_face_window)
26748 && XWINDOW (hlinfo->mouse_face_window) == w))
26749 return 0;
26750 if (vpos < hlinfo->mouse_face_beg_row
26751 || vpos > hlinfo->mouse_face_end_row)
26752 return 0;
26753 if (vpos > hlinfo->mouse_face_beg_row
26754 && vpos < hlinfo->mouse_face_end_row)
26755 return 1;
26756
26757 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26758 {
26759 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26760 {
26761 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26762 return 1;
26763 }
26764 else if ((vpos == hlinfo->mouse_face_beg_row
26765 && hpos >= hlinfo->mouse_face_beg_col)
26766 || (vpos == hlinfo->mouse_face_end_row
26767 && hpos < hlinfo->mouse_face_end_col))
26768 return 1;
26769 }
26770 else
26771 {
26772 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26773 {
26774 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26775 return 1;
26776 }
26777 else if ((vpos == hlinfo->mouse_face_beg_row
26778 && hpos <= hlinfo->mouse_face_beg_col)
26779 || (vpos == hlinfo->mouse_face_end_row
26780 && hpos > hlinfo->mouse_face_end_col))
26781 return 1;
26782 }
26783 return 0;
26784 }
26785
26786
26787 /* EXPORT:
26788 Non-zero if physical cursor of window W is within mouse face. */
26789
26790 int
26791 cursor_in_mouse_face_p (struct window *w)
26792 {
26793 int hpos = w->phys_cursor.hpos;
26794 int vpos = w->phys_cursor.vpos;
26795 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26796
26797 /* When the window is hscrolled, cursor hpos can legitimately be out
26798 of bounds, but we draw the cursor at the corresponding window
26799 margin in that case. */
26800 if (!row->reversed_p && hpos < 0)
26801 hpos = 0;
26802 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26803 hpos = row->used[TEXT_AREA] - 1;
26804
26805 return coords_in_mouse_face_p (w, hpos, vpos);
26806 }
26807
26808
26809 \f
26810 /* Find the glyph rows START_ROW and END_ROW of window W that display
26811 characters between buffer positions START_CHARPOS and END_CHARPOS
26812 (excluding END_CHARPOS). DISP_STRING is a display string that
26813 covers these buffer positions. This is similar to
26814 row_containing_pos, but is more accurate when bidi reordering makes
26815 buffer positions change non-linearly with glyph rows. */
26816 static void
26817 rows_from_pos_range (struct window *w,
26818 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26819 Lisp_Object disp_string,
26820 struct glyph_row **start, struct glyph_row **end)
26821 {
26822 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26823 int last_y = window_text_bottom_y (w);
26824 struct glyph_row *row;
26825
26826 *start = NULL;
26827 *end = NULL;
26828
26829 while (!first->enabled_p
26830 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26831 first++;
26832
26833 /* Find the START row. */
26834 for (row = first;
26835 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26836 row++)
26837 {
26838 /* A row can potentially be the START row if the range of the
26839 characters it displays intersects the range
26840 [START_CHARPOS..END_CHARPOS). */
26841 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26842 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26843 /* See the commentary in row_containing_pos, for the
26844 explanation of the complicated way to check whether
26845 some position is beyond the end of the characters
26846 displayed by a row. */
26847 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26848 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26849 && !row->ends_at_zv_p
26850 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26851 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26852 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26853 && !row->ends_at_zv_p
26854 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26855 {
26856 /* Found a candidate row. Now make sure at least one of the
26857 glyphs it displays has a charpos from the range
26858 [START_CHARPOS..END_CHARPOS).
26859
26860 This is not obvious because bidi reordering could make
26861 buffer positions of a row be 1,2,3,102,101,100, and if we
26862 want to highlight characters in [50..60), we don't want
26863 this row, even though [50..60) does intersect [1..103),
26864 the range of character positions given by the row's start
26865 and end positions. */
26866 struct glyph *g = row->glyphs[TEXT_AREA];
26867 struct glyph *e = g + row->used[TEXT_AREA];
26868
26869 while (g < e)
26870 {
26871 if (((BUFFERP (g->object) || INTEGERP (g->object))
26872 && start_charpos <= g->charpos && g->charpos < end_charpos)
26873 /* A glyph that comes from DISP_STRING is by
26874 definition to be highlighted. */
26875 || EQ (g->object, disp_string))
26876 *start = row;
26877 g++;
26878 }
26879 if (*start)
26880 break;
26881 }
26882 }
26883
26884 /* Find the END row. */
26885 if (!*start
26886 /* If the last row is partially visible, start looking for END
26887 from that row, instead of starting from FIRST. */
26888 && !(row->enabled_p
26889 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26890 row = first;
26891 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26892 {
26893 struct glyph_row *next = row + 1;
26894 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26895
26896 if (!next->enabled_p
26897 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26898 /* The first row >= START whose range of displayed characters
26899 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26900 is the row END + 1. */
26901 || (start_charpos < next_start
26902 && end_charpos < next_start)
26903 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26904 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26905 && !next->ends_at_zv_p
26906 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26907 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26908 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26909 && !next->ends_at_zv_p
26910 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26911 {
26912 *end = row;
26913 break;
26914 }
26915 else
26916 {
26917 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26918 but none of the characters it displays are in the range, it is
26919 also END + 1. */
26920 struct glyph *g = next->glyphs[TEXT_AREA];
26921 struct glyph *s = g;
26922 struct glyph *e = g + next->used[TEXT_AREA];
26923
26924 while (g < e)
26925 {
26926 if (((BUFFERP (g->object) || INTEGERP (g->object))
26927 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26928 /* If the buffer position of the first glyph in
26929 the row is equal to END_CHARPOS, it means
26930 the last character to be highlighted is the
26931 newline of ROW, and we must consider NEXT as
26932 END, not END+1. */
26933 || (((!next->reversed_p && g == s)
26934 || (next->reversed_p && g == e - 1))
26935 && (g->charpos == end_charpos
26936 /* Special case for when NEXT is an
26937 empty line at ZV. */
26938 || (g->charpos == -1
26939 && !row->ends_at_zv_p
26940 && next_start == end_charpos)))))
26941 /* A glyph that comes from DISP_STRING is by
26942 definition to be highlighted. */
26943 || EQ (g->object, disp_string))
26944 break;
26945 g++;
26946 }
26947 if (g == e)
26948 {
26949 *end = row;
26950 break;
26951 }
26952 /* The first row that ends at ZV must be the last to be
26953 highlighted. */
26954 else if (next->ends_at_zv_p)
26955 {
26956 *end = next;
26957 break;
26958 }
26959 }
26960 }
26961 }
26962
26963 /* This function sets the mouse_face_* elements of HLINFO, assuming
26964 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26965 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26966 for the overlay or run of text properties specifying the mouse
26967 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26968 before-string and after-string that must also be highlighted.
26969 DISP_STRING, if non-nil, is a display string that may cover some
26970 or all of the highlighted text. */
26971
26972 static void
26973 mouse_face_from_buffer_pos (Lisp_Object window,
26974 Mouse_HLInfo *hlinfo,
26975 ptrdiff_t mouse_charpos,
26976 ptrdiff_t start_charpos,
26977 ptrdiff_t end_charpos,
26978 Lisp_Object before_string,
26979 Lisp_Object after_string,
26980 Lisp_Object disp_string)
26981 {
26982 struct window *w = XWINDOW (window);
26983 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26984 struct glyph_row *r1, *r2;
26985 struct glyph *glyph, *end;
26986 ptrdiff_t ignore, pos;
26987 int x;
26988
26989 eassert (NILP (disp_string) || STRINGP (disp_string));
26990 eassert (NILP (before_string) || STRINGP (before_string));
26991 eassert (NILP (after_string) || STRINGP (after_string));
26992
26993 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26994 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26995 if (r1 == NULL)
26996 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
26997 /* If the before-string or display-string contains newlines,
26998 rows_from_pos_range skips to its last row. Move back. */
26999 if (!NILP (before_string) || !NILP (disp_string))
27000 {
27001 struct glyph_row *prev;
27002 while ((prev = r1 - 1, prev >= first)
27003 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
27004 && prev->used[TEXT_AREA] > 0)
27005 {
27006 struct glyph *beg = prev->glyphs[TEXT_AREA];
27007 glyph = beg + prev->used[TEXT_AREA];
27008 while (--glyph >= beg && INTEGERP (glyph->object));
27009 if (glyph < beg
27010 || !(EQ (glyph->object, before_string)
27011 || EQ (glyph->object, disp_string)))
27012 break;
27013 r1 = prev;
27014 }
27015 }
27016 if (r2 == NULL)
27017 {
27018 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27019 hlinfo->mouse_face_past_end = 1;
27020 }
27021 else if (!NILP (after_string))
27022 {
27023 /* If the after-string has newlines, advance to its last row. */
27024 struct glyph_row *next;
27025 struct glyph_row *last
27026 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27027
27028 for (next = r2 + 1;
27029 next <= last
27030 && next->used[TEXT_AREA] > 0
27031 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
27032 ++next)
27033 r2 = next;
27034 }
27035 /* The rest of the display engine assumes that mouse_face_beg_row is
27036 either above mouse_face_end_row or identical to it. But with
27037 bidi-reordered continued lines, the row for START_CHARPOS could
27038 be below the row for END_CHARPOS. If so, swap the rows and store
27039 them in correct order. */
27040 if (r1->y > r2->y)
27041 {
27042 struct glyph_row *tem = r2;
27043
27044 r2 = r1;
27045 r1 = tem;
27046 }
27047
27048 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27049 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27050
27051 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27052 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27053 could be anywhere in the row and in any order. The strategy
27054 below is to find the leftmost and the rightmost glyph that
27055 belongs to either of these 3 strings, or whose position is
27056 between START_CHARPOS and END_CHARPOS, and highlight all the
27057 glyphs between those two. This may cover more than just the text
27058 between START_CHARPOS and END_CHARPOS if the range of characters
27059 strides the bidi level boundary, e.g. if the beginning is in R2L
27060 text while the end is in L2R text or vice versa. */
27061 if (!r1->reversed_p)
27062 {
27063 /* This row is in a left to right paragraph. Scan it left to
27064 right. */
27065 glyph = r1->glyphs[TEXT_AREA];
27066 end = glyph + r1->used[TEXT_AREA];
27067 x = r1->x;
27068
27069 /* Skip truncation glyphs at the start of the glyph row. */
27070 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27071 for (; glyph < end
27072 && INTEGERP (glyph->object)
27073 && glyph->charpos < 0;
27074 ++glyph)
27075 x += glyph->pixel_width;
27076
27077 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27078 or DISP_STRING, and the first glyph from buffer whose
27079 position is between START_CHARPOS and END_CHARPOS. */
27080 for (; glyph < end
27081 && !INTEGERP (glyph->object)
27082 && !EQ (glyph->object, disp_string)
27083 && !(BUFFERP (glyph->object)
27084 && (glyph->charpos >= start_charpos
27085 && glyph->charpos < end_charpos));
27086 ++glyph)
27087 {
27088 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27089 are present at buffer positions between START_CHARPOS and
27090 END_CHARPOS, or if they come from an overlay. */
27091 if (EQ (glyph->object, before_string))
27092 {
27093 pos = string_buffer_position (before_string,
27094 start_charpos);
27095 /* If pos == 0, it means before_string came from an
27096 overlay, not from a buffer position. */
27097 if (!pos || (pos >= start_charpos && pos < end_charpos))
27098 break;
27099 }
27100 else if (EQ (glyph->object, after_string))
27101 {
27102 pos = string_buffer_position (after_string, end_charpos);
27103 if (!pos || (pos >= start_charpos && pos < end_charpos))
27104 break;
27105 }
27106 x += glyph->pixel_width;
27107 }
27108 hlinfo->mouse_face_beg_x = x;
27109 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27110 }
27111 else
27112 {
27113 /* This row is in a right to left paragraph. Scan it right to
27114 left. */
27115 struct glyph *g;
27116
27117 end = r1->glyphs[TEXT_AREA] - 1;
27118 glyph = end + r1->used[TEXT_AREA];
27119
27120 /* Skip truncation glyphs at the start of the glyph row. */
27121 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27122 for (; glyph > end
27123 && INTEGERP (glyph->object)
27124 && glyph->charpos < 0;
27125 --glyph)
27126 ;
27127
27128 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27129 or DISP_STRING, and the first glyph from buffer whose
27130 position is between START_CHARPOS and END_CHARPOS. */
27131 for (; glyph > end
27132 && !INTEGERP (glyph->object)
27133 && !EQ (glyph->object, disp_string)
27134 && !(BUFFERP (glyph->object)
27135 && (glyph->charpos >= start_charpos
27136 && glyph->charpos < end_charpos));
27137 --glyph)
27138 {
27139 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27140 are present at buffer positions between START_CHARPOS and
27141 END_CHARPOS, or if they come from an overlay. */
27142 if (EQ (glyph->object, before_string))
27143 {
27144 pos = string_buffer_position (before_string, start_charpos);
27145 /* If pos == 0, it means before_string came from an
27146 overlay, not from a buffer position. */
27147 if (!pos || (pos >= start_charpos && pos < end_charpos))
27148 break;
27149 }
27150 else if (EQ (glyph->object, after_string))
27151 {
27152 pos = string_buffer_position (after_string, end_charpos);
27153 if (!pos || (pos >= start_charpos && pos < end_charpos))
27154 break;
27155 }
27156 }
27157
27158 glyph++; /* first glyph to the right of the highlighted area */
27159 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27160 x += g->pixel_width;
27161 hlinfo->mouse_face_beg_x = x;
27162 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27163 }
27164
27165 /* If the highlight ends in a different row, compute GLYPH and END
27166 for the end row. Otherwise, reuse the values computed above for
27167 the row where the highlight begins. */
27168 if (r2 != r1)
27169 {
27170 if (!r2->reversed_p)
27171 {
27172 glyph = r2->glyphs[TEXT_AREA];
27173 end = glyph + r2->used[TEXT_AREA];
27174 x = r2->x;
27175 }
27176 else
27177 {
27178 end = r2->glyphs[TEXT_AREA] - 1;
27179 glyph = end + r2->used[TEXT_AREA];
27180 }
27181 }
27182
27183 if (!r2->reversed_p)
27184 {
27185 /* Skip truncation and continuation glyphs near the end of the
27186 row, and also blanks and stretch glyphs inserted by
27187 extend_face_to_end_of_line. */
27188 while (end > glyph
27189 && INTEGERP ((end - 1)->object))
27190 --end;
27191 /* Scan the rest of the glyph row from the end, looking for the
27192 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27193 DISP_STRING, or whose position is between START_CHARPOS
27194 and END_CHARPOS */
27195 for (--end;
27196 end > glyph
27197 && !INTEGERP (end->object)
27198 && !EQ (end->object, disp_string)
27199 && !(BUFFERP (end->object)
27200 && (end->charpos >= start_charpos
27201 && end->charpos < end_charpos));
27202 --end)
27203 {
27204 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27205 are present at buffer positions between START_CHARPOS and
27206 END_CHARPOS, or if they come from an overlay. */
27207 if (EQ (end->object, before_string))
27208 {
27209 pos = string_buffer_position (before_string, start_charpos);
27210 if (!pos || (pos >= start_charpos && pos < end_charpos))
27211 break;
27212 }
27213 else if (EQ (end->object, after_string))
27214 {
27215 pos = string_buffer_position (after_string, end_charpos);
27216 if (!pos || (pos >= start_charpos && pos < end_charpos))
27217 break;
27218 }
27219 }
27220 /* Find the X coordinate of the last glyph to be highlighted. */
27221 for (; glyph <= end; ++glyph)
27222 x += glyph->pixel_width;
27223
27224 hlinfo->mouse_face_end_x = x;
27225 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27226 }
27227 else
27228 {
27229 /* Skip truncation and continuation glyphs near the end of the
27230 row, and also blanks and stretch glyphs inserted by
27231 extend_face_to_end_of_line. */
27232 x = r2->x;
27233 end++;
27234 while (end < glyph
27235 && INTEGERP (end->object))
27236 {
27237 x += end->pixel_width;
27238 ++end;
27239 }
27240 /* Scan the rest of the glyph row from the end, looking for the
27241 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27242 DISP_STRING, or whose position is between START_CHARPOS
27243 and END_CHARPOS */
27244 for ( ;
27245 end < glyph
27246 && !INTEGERP (end->object)
27247 && !EQ (end->object, disp_string)
27248 && !(BUFFERP (end->object)
27249 && (end->charpos >= start_charpos
27250 && end->charpos < end_charpos));
27251 ++end)
27252 {
27253 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27254 are present at buffer positions between START_CHARPOS and
27255 END_CHARPOS, or if they come from an overlay. */
27256 if (EQ (end->object, before_string))
27257 {
27258 pos = string_buffer_position (before_string, start_charpos);
27259 if (!pos || (pos >= start_charpos && pos < end_charpos))
27260 break;
27261 }
27262 else if (EQ (end->object, after_string))
27263 {
27264 pos = string_buffer_position (after_string, end_charpos);
27265 if (!pos || (pos >= start_charpos && pos < end_charpos))
27266 break;
27267 }
27268 x += end->pixel_width;
27269 }
27270 /* If we exited the above loop because we arrived at the last
27271 glyph of the row, and its buffer position is still not in
27272 range, it means the last character in range is the preceding
27273 newline. Bump the end column and x values to get past the
27274 last glyph. */
27275 if (end == glyph
27276 && BUFFERP (end->object)
27277 && (end->charpos < start_charpos
27278 || end->charpos >= end_charpos))
27279 {
27280 x += end->pixel_width;
27281 ++end;
27282 }
27283 hlinfo->mouse_face_end_x = x;
27284 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27285 }
27286
27287 hlinfo->mouse_face_window = window;
27288 hlinfo->mouse_face_face_id
27289 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
27290 mouse_charpos + 1,
27291 !hlinfo->mouse_face_hidden, -1);
27292 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27293 }
27294
27295 /* The following function is not used anymore (replaced with
27296 mouse_face_from_string_pos), but I leave it here for the time
27297 being, in case someone would. */
27298
27299 #if 0 /* not used */
27300
27301 /* Find the position of the glyph for position POS in OBJECT in
27302 window W's current matrix, and return in *X, *Y the pixel
27303 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27304
27305 RIGHT_P non-zero means return the position of the right edge of the
27306 glyph, RIGHT_P zero means return the left edge position.
27307
27308 If no glyph for POS exists in the matrix, return the position of
27309 the glyph with the next smaller position that is in the matrix, if
27310 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27311 exists in the matrix, return the position of the glyph with the
27312 next larger position in OBJECT.
27313
27314 Value is non-zero if a glyph was found. */
27315
27316 static int
27317 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27318 int *hpos, int *vpos, int *x, int *y, int right_p)
27319 {
27320 int yb = window_text_bottom_y (w);
27321 struct glyph_row *r;
27322 struct glyph *best_glyph = NULL;
27323 struct glyph_row *best_row = NULL;
27324 int best_x = 0;
27325
27326 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27327 r->enabled_p && r->y < yb;
27328 ++r)
27329 {
27330 struct glyph *g = r->glyphs[TEXT_AREA];
27331 struct glyph *e = g + r->used[TEXT_AREA];
27332 int gx;
27333
27334 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27335 if (EQ (g->object, object))
27336 {
27337 if (g->charpos == pos)
27338 {
27339 best_glyph = g;
27340 best_x = gx;
27341 best_row = r;
27342 goto found;
27343 }
27344 else if (best_glyph == NULL
27345 || ((eabs (g->charpos - pos)
27346 < eabs (best_glyph->charpos - pos))
27347 && (right_p
27348 ? g->charpos < pos
27349 : g->charpos > pos)))
27350 {
27351 best_glyph = g;
27352 best_x = gx;
27353 best_row = r;
27354 }
27355 }
27356 }
27357
27358 found:
27359
27360 if (best_glyph)
27361 {
27362 *x = best_x;
27363 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27364
27365 if (right_p)
27366 {
27367 *x += best_glyph->pixel_width;
27368 ++*hpos;
27369 }
27370
27371 *y = best_row->y;
27372 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
27373 }
27374
27375 return best_glyph != NULL;
27376 }
27377 #endif /* not used */
27378
27379 /* Find the positions of the first and the last glyphs in window W's
27380 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27381 (assumed to be a string), and return in HLINFO's mouse_face_*
27382 members the pixel and column/row coordinates of those glyphs. */
27383
27384 static void
27385 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27386 Lisp_Object object,
27387 ptrdiff_t startpos, ptrdiff_t endpos)
27388 {
27389 int yb = window_text_bottom_y (w);
27390 struct glyph_row *r;
27391 struct glyph *g, *e;
27392 int gx;
27393 int found = 0;
27394
27395 /* Find the glyph row with at least one position in the range
27396 [STARTPOS..ENDPOS], and the first glyph in that row whose
27397 position belongs to that range. */
27398 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27399 r->enabled_p && r->y < yb;
27400 ++r)
27401 {
27402 if (!r->reversed_p)
27403 {
27404 g = r->glyphs[TEXT_AREA];
27405 e = g + r->used[TEXT_AREA];
27406 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27407 if (EQ (g->object, object)
27408 && startpos <= g->charpos && g->charpos <= endpos)
27409 {
27410 hlinfo->mouse_face_beg_row
27411 = MATRIX_ROW_VPOS (r, w->current_matrix);
27412 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27413 hlinfo->mouse_face_beg_x = gx;
27414 found = 1;
27415 break;
27416 }
27417 }
27418 else
27419 {
27420 struct glyph *g1;
27421
27422 e = r->glyphs[TEXT_AREA];
27423 g = e + r->used[TEXT_AREA];
27424 for ( ; g > e; --g)
27425 if (EQ ((g-1)->object, object)
27426 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27427 {
27428 hlinfo->mouse_face_beg_row
27429 = MATRIX_ROW_VPOS (r, w->current_matrix);
27430 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27431 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27432 gx += g1->pixel_width;
27433 hlinfo->mouse_face_beg_x = gx;
27434 found = 1;
27435 break;
27436 }
27437 }
27438 if (found)
27439 break;
27440 }
27441
27442 if (!found)
27443 return;
27444
27445 /* Starting with the next row, look for the first row which does NOT
27446 include any glyphs whose positions are in the range. */
27447 for (++r; r->enabled_p && r->y < yb; ++r)
27448 {
27449 g = r->glyphs[TEXT_AREA];
27450 e = g + r->used[TEXT_AREA];
27451 found = 0;
27452 for ( ; g < e; ++g)
27453 if (EQ (g->object, object)
27454 && startpos <= g->charpos && g->charpos <= endpos)
27455 {
27456 found = 1;
27457 break;
27458 }
27459 if (!found)
27460 break;
27461 }
27462
27463 /* The highlighted region ends on the previous row. */
27464 r--;
27465
27466 /* Set the end row. */
27467 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27468
27469 /* Compute and set the end column and the end column's horizontal
27470 pixel coordinate. */
27471 if (!r->reversed_p)
27472 {
27473 g = r->glyphs[TEXT_AREA];
27474 e = g + r->used[TEXT_AREA];
27475 for ( ; e > g; --e)
27476 if (EQ ((e-1)->object, object)
27477 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27478 break;
27479 hlinfo->mouse_face_end_col = e - g;
27480
27481 for (gx = r->x; g < e; ++g)
27482 gx += g->pixel_width;
27483 hlinfo->mouse_face_end_x = gx;
27484 }
27485 else
27486 {
27487 e = r->glyphs[TEXT_AREA];
27488 g = e + r->used[TEXT_AREA];
27489 for (gx = r->x ; e < g; ++e)
27490 {
27491 if (EQ (e->object, object)
27492 && startpos <= e->charpos && e->charpos <= endpos)
27493 break;
27494 gx += e->pixel_width;
27495 }
27496 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27497 hlinfo->mouse_face_end_x = gx;
27498 }
27499 }
27500
27501 #ifdef HAVE_WINDOW_SYSTEM
27502
27503 /* See if position X, Y is within a hot-spot of an image. */
27504
27505 static int
27506 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27507 {
27508 if (!CONSP (hot_spot))
27509 return 0;
27510
27511 if (EQ (XCAR (hot_spot), Qrect))
27512 {
27513 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27514 Lisp_Object rect = XCDR (hot_spot);
27515 Lisp_Object tem;
27516 if (!CONSP (rect))
27517 return 0;
27518 if (!CONSP (XCAR (rect)))
27519 return 0;
27520 if (!CONSP (XCDR (rect)))
27521 return 0;
27522 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27523 return 0;
27524 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27525 return 0;
27526 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27527 return 0;
27528 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27529 return 0;
27530 return 1;
27531 }
27532 else if (EQ (XCAR (hot_spot), Qcircle))
27533 {
27534 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27535 Lisp_Object circ = XCDR (hot_spot);
27536 Lisp_Object lr, lx0, ly0;
27537 if (CONSP (circ)
27538 && CONSP (XCAR (circ))
27539 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27540 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27541 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27542 {
27543 double r = XFLOATINT (lr);
27544 double dx = XINT (lx0) - x;
27545 double dy = XINT (ly0) - y;
27546 return (dx * dx + dy * dy <= r * r);
27547 }
27548 }
27549 else if (EQ (XCAR (hot_spot), Qpoly))
27550 {
27551 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27552 if (VECTORP (XCDR (hot_spot)))
27553 {
27554 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27555 Lisp_Object *poly = v->contents;
27556 ptrdiff_t n = v->header.size;
27557 ptrdiff_t i;
27558 int inside = 0;
27559 Lisp_Object lx, ly;
27560 int x0, y0;
27561
27562 /* Need an even number of coordinates, and at least 3 edges. */
27563 if (n < 6 || n & 1)
27564 return 0;
27565
27566 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27567 If count is odd, we are inside polygon. Pixels on edges
27568 may or may not be included depending on actual geometry of the
27569 polygon. */
27570 if ((lx = poly[n-2], !INTEGERP (lx))
27571 || (ly = poly[n-1], !INTEGERP (lx)))
27572 return 0;
27573 x0 = XINT (lx), y0 = XINT (ly);
27574 for (i = 0; i < n; i += 2)
27575 {
27576 int x1 = x0, y1 = y0;
27577 if ((lx = poly[i], !INTEGERP (lx))
27578 || (ly = poly[i+1], !INTEGERP (ly)))
27579 return 0;
27580 x0 = XINT (lx), y0 = XINT (ly);
27581
27582 /* Does this segment cross the X line? */
27583 if (x0 >= x)
27584 {
27585 if (x1 >= x)
27586 continue;
27587 }
27588 else if (x1 < x)
27589 continue;
27590 if (y > y0 && y > y1)
27591 continue;
27592 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27593 inside = !inside;
27594 }
27595 return inside;
27596 }
27597 }
27598 return 0;
27599 }
27600
27601 Lisp_Object
27602 find_hot_spot (Lisp_Object map, int x, int y)
27603 {
27604 while (CONSP (map))
27605 {
27606 if (CONSP (XCAR (map))
27607 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27608 return XCAR (map);
27609 map = XCDR (map);
27610 }
27611
27612 return Qnil;
27613 }
27614
27615 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27616 3, 3, 0,
27617 doc: /* Lookup in image map MAP coordinates X and Y.
27618 An image map is an alist where each element has the format (AREA ID PLIST).
27619 An AREA is specified as either a rectangle, a circle, or a polygon:
27620 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27621 pixel coordinates of the upper left and bottom right corners.
27622 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27623 and the radius of the circle; r may be a float or integer.
27624 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27625 vector describes one corner in the polygon.
27626 Returns the alist element for the first matching AREA in MAP. */)
27627 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27628 {
27629 if (NILP (map))
27630 return Qnil;
27631
27632 CHECK_NUMBER (x);
27633 CHECK_NUMBER (y);
27634
27635 return find_hot_spot (map,
27636 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27637 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27638 }
27639
27640
27641 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27642 static void
27643 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27644 {
27645 /* Do not change cursor shape while dragging mouse. */
27646 if (!NILP (do_mouse_tracking))
27647 return;
27648
27649 if (!NILP (pointer))
27650 {
27651 if (EQ (pointer, Qarrow))
27652 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27653 else if (EQ (pointer, Qhand))
27654 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27655 else if (EQ (pointer, Qtext))
27656 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27657 else if (EQ (pointer, intern ("hdrag")))
27658 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27659 #ifdef HAVE_X_WINDOWS
27660 else if (EQ (pointer, intern ("vdrag")))
27661 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27662 #endif
27663 else if (EQ (pointer, intern ("hourglass")))
27664 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27665 else if (EQ (pointer, Qmodeline))
27666 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27667 else
27668 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27669 }
27670
27671 if (cursor != No_Cursor)
27672 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27673 }
27674
27675 #endif /* HAVE_WINDOW_SYSTEM */
27676
27677 /* Take proper action when mouse has moved to the mode or header line
27678 or marginal area AREA of window W, x-position X and y-position Y.
27679 X is relative to the start of the text display area of W, so the
27680 width of bitmap areas and scroll bars must be subtracted to get a
27681 position relative to the start of the mode line. */
27682
27683 static void
27684 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27685 enum window_part area)
27686 {
27687 struct window *w = XWINDOW (window);
27688 struct frame *f = XFRAME (w->frame);
27689 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27690 #ifdef HAVE_WINDOW_SYSTEM
27691 Display_Info *dpyinfo;
27692 #endif
27693 Cursor cursor = No_Cursor;
27694 Lisp_Object pointer = Qnil;
27695 int dx, dy, width, height;
27696 ptrdiff_t charpos;
27697 Lisp_Object string, object = Qnil;
27698 Lisp_Object pos IF_LINT (= Qnil), help;
27699
27700 Lisp_Object mouse_face;
27701 int original_x_pixel = x;
27702 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27703 struct glyph_row *row IF_LINT (= 0);
27704
27705 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27706 {
27707 int x0;
27708 struct glyph *end;
27709
27710 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27711 returns them in row/column units! */
27712 string = mode_line_string (w, area, &x, &y, &charpos,
27713 &object, &dx, &dy, &width, &height);
27714
27715 row = (area == ON_MODE_LINE
27716 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27717 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27718
27719 /* Find the glyph under the mouse pointer. */
27720 if (row->mode_line_p && row->enabled_p)
27721 {
27722 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27723 end = glyph + row->used[TEXT_AREA];
27724
27725 for (x0 = original_x_pixel;
27726 glyph < end && x0 >= glyph->pixel_width;
27727 ++glyph)
27728 x0 -= glyph->pixel_width;
27729
27730 if (glyph >= end)
27731 glyph = NULL;
27732 }
27733 }
27734 else
27735 {
27736 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27737 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27738 returns them in row/column units! */
27739 string = marginal_area_string (w, area, &x, &y, &charpos,
27740 &object, &dx, &dy, &width, &height);
27741 }
27742
27743 help = Qnil;
27744
27745 #ifdef HAVE_WINDOW_SYSTEM
27746 if (IMAGEP (object))
27747 {
27748 Lisp_Object image_map, hotspot;
27749 if ((image_map = Fplist_get (XCDR (object), QCmap),
27750 !NILP (image_map))
27751 && (hotspot = find_hot_spot (image_map, dx, dy),
27752 CONSP (hotspot))
27753 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27754 {
27755 Lisp_Object plist;
27756
27757 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27758 If so, we could look for mouse-enter, mouse-leave
27759 properties in PLIST (and do something...). */
27760 hotspot = XCDR (hotspot);
27761 if (CONSP (hotspot)
27762 && (plist = XCAR (hotspot), CONSP (plist)))
27763 {
27764 pointer = Fplist_get (plist, Qpointer);
27765 if (NILP (pointer))
27766 pointer = Qhand;
27767 help = Fplist_get (plist, Qhelp_echo);
27768 if (!NILP (help))
27769 {
27770 help_echo_string = help;
27771 XSETWINDOW (help_echo_window, w);
27772 help_echo_object = w->contents;
27773 help_echo_pos = charpos;
27774 }
27775 }
27776 }
27777 if (NILP (pointer))
27778 pointer = Fplist_get (XCDR (object), QCpointer);
27779 }
27780 #endif /* HAVE_WINDOW_SYSTEM */
27781
27782 if (STRINGP (string))
27783 pos = make_number (charpos);
27784
27785 /* Set the help text and mouse pointer. If the mouse is on a part
27786 of the mode line without any text (e.g. past the right edge of
27787 the mode line text), use the default help text and pointer. */
27788 if (STRINGP (string) || area == ON_MODE_LINE)
27789 {
27790 /* Arrange to display the help by setting the global variables
27791 help_echo_string, help_echo_object, and help_echo_pos. */
27792 if (NILP (help))
27793 {
27794 if (STRINGP (string))
27795 help = Fget_text_property (pos, Qhelp_echo, string);
27796
27797 if (!NILP (help))
27798 {
27799 help_echo_string = help;
27800 XSETWINDOW (help_echo_window, w);
27801 help_echo_object = string;
27802 help_echo_pos = charpos;
27803 }
27804 else if (area == ON_MODE_LINE)
27805 {
27806 Lisp_Object default_help
27807 = buffer_local_value_1 (Qmode_line_default_help_echo,
27808 w->contents);
27809
27810 if (STRINGP (default_help))
27811 {
27812 help_echo_string = default_help;
27813 XSETWINDOW (help_echo_window, w);
27814 help_echo_object = Qnil;
27815 help_echo_pos = -1;
27816 }
27817 }
27818 }
27819
27820 #ifdef HAVE_WINDOW_SYSTEM
27821 /* Change the mouse pointer according to what is under it. */
27822 if (FRAME_WINDOW_P (f))
27823 {
27824 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27825 if (STRINGP (string))
27826 {
27827 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27828
27829 if (NILP (pointer))
27830 pointer = Fget_text_property (pos, Qpointer, string);
27831
27832 /* Change the mouse pointer according to what is under X/Y. */
27833 if (NILP (pointer)
27834 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27835 {
27836 Lisp_Object map;
27837 map = Fget_text_property (pos, Qlocal_map, string);
27838 if (!KEYMAPP (map))
27839 map = Fget_text_property (pos, Qkeymap, string);
27840 if (!KEYMAPP (map))
27841 cursor = dpyinfo->vertical_scroll_bar_cursor;
27842 }
27843 }
27844 else
27845 /* Default mode-line pointer. */
27846 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27847 }
27848 #endif
27849 }
27850
27851 /* Change the mouse face according to what is under X/Y. */
27852 if (STRINGP (string))
27853 {
27854 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27855 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27856 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27857 && glyph)
27858 {
27859 Lisp_Object b, e;
27860
27861 struct glyph * tmp_glyph;
27862
27863 int gpos;
27864 int gseq_length;
27865 int total_pixel_width;
27866 ptrdiff_t begpos, endpos, ignore;
27867
27868 int vpos, hpos;
27869
27870 b = Fprevious_single_property_change (make_number (charpos + 1),
27871 Qmouse_face, string, Qnil);
27872 if (NILP (b))
27873 begpos = 0;
27874 else
27875 begpos = XINT (b);
27876
27877 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27878 if (NILP (e))
27879 endpos = SCHARS (string);
27880 else
27881 endpos = XINT (e);
27882
27883 /* Calculate the glyph position GPOS of GLYPH in the
27884 displayed string, relative to the beginning of the
27885 highlighted part of the string.
27886
27887 Note: GPOS is different from CHARPOS. CHARPOS is the
27888 position of GLYPH in the internal string object. A mode
27889 line string format has structures which are converted to
27890 a flattened string by the Emacs Lisp interpreter. The
27891 internal string is an element of those structures. The
27892 displayed string is the flattened string. */
27893 tmp_glyph = row_start_glyph;
27894 while (tmp_glyph < glyph
27895 && (!(EQ (tmp_glyph->object, glyph->object)
27896 && begpos <= tmp_glyph->charpos
27897 && tmp_glyph->charpos < endpos)))
27898 tmp_glyph++;
27899 gpos = glyph - tmp_glyph;
27900
27901 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27902 the highlighted part of the displayed string to which
27903 GLYPH belongs. Note: GSEQ_LENGTH is different from
27904 SCHARS (STRING), because the latter returns the length of
27905 the internal string. */
27906 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27907 tmp_glyph > glyph
27908 && (!(EQ (tmp_glyph->object, glyph->object)
27909 && begpos <= tmp_glyph->charpos
27910 && tmp_glyph->charpos < endpos));
27911 tmp_glyph--)
27912 ;
27913 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27914
27915 /* Calculate the total pixel width of all the glyphs between
27916 the beginning of the highlighted area and GLYPH. */
27917 total_pixel_width = 0;
27918 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27919 total_pixel_width += tmp_glyph->pixel_width;
27920
27921 /* Pre calculation of re-rendering position. Note: X is in
27922 column units here, after the call to mode_line_string or
27923 marginal_area_string. */
27924 hpos = x - gpos;
27925 vpos = (area == ON_MODE_LINE
27926 ? (w->current_matrix)->nrows - 1
27927 : 0);
27928
27929 /* If GLYPH's position is included in the region that is
27930 already drawn in mouse face, we have nothing to do. */
27931 if ( EQ (window, hlinfo->mouse_face_window)
27932 && (!row->reversed_p
27933 ? (hlinfo->mouse_face_beg_col <= hpos
27934 && hpos < hlinfo->mouse_face_end_col)
27935 /* In R2L rows we swap BEG and END, see below. */
27936 : (hlinfo->mouse_face_end_col <= hpos
27937 && hpos < hlinfo->mouse_face_beg_col))
27938 && hlinfo->mouse_face_beg_row == vpos )
27939 return;
27940
27941 if (clear_mouse_face (hlinfo))
27942 cursor = No_Cursor;
27943
27944 if (!row->reversed_p)
27945 {
27946 hlinfo->mouse_face_beg_col = hpos;
27947 hlinfo->mouse_face_beg_x = original_x_pixel
27948 - (total_pixel_width + dx);
27949 hlinfo->mouse_face_end_col = hpos + gseq_length;
27950 hlinfo->mouse_face_end_x = 0;
27951 }
27952 else
27953 {
27954 /* In R2L rows, show_mouse_face expects BEG and END
27955 coordinates to be swapped. */
27956 hlinfo->mouse_face_end_col = hpos;
27957 hlinfo->mouse_face_end_x = original_x_pixel
27958 - (total_pixel_width + dx);
27959 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27960 hlinfo->mouse_face_beg_x = 0;
27961 }
27962
27963 hlinfo->mouse_face_beg_row = vpos;
27964 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27965 hlinfo->mouse_face_past_end = 0;
27966 hlinfo->mouse_face_window = window;
27967
27968 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27969 charpos,
27970 0, 0, 0,
27971 &ignore,
27972 glyph->face_id,
27973 1);
27974 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27975
27976 if (NILP (pointer))
27977 pointer = Qhand;
27978 }
27979 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27980 clear_mouse_face (hlinfo);
27981 }
27982 #ifdef HAVE_WINDOW_SYSTEM
27983 if (FRAME_WINDOW_P (f))
27984 define_frame_cursor1 (f, cursor, pointer);
27985 #endif
27986 }
27987
27988
27989 /* EXPORT:
27990 Take proper action when the mouse has moved to position X, Y on
27991 frame F with regards to highlighting portions of display that have
27992 mouse-face properties. Also de-highlight portions of display where
27993 the mouse was before, set the mouse pointer shape as appropriate
27994 for the mouse coordinates, and activate help echo (tooltips).
27995 X and Y can be negative or out of range. */
27996
27997 void
27998 note_mouse_highlight (struct frame *f, int x, int y)
27999 {
28000 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28001 enum window_part part = ON_NOTHING;
28002 Lisp_Object window;
28003 struct window *w;
28004 Cursor cursor = No_Cursor;
28005 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
28006 struct buffer *b;
28007
28008 /* When a menu is active, don't highlight because this looks odd. */
28009 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28010 if (popup_activated ())
28011 return;
28012 #endif
28013
28014 if (!f->glyphs_initialized_p
28015 || f->pointer_invisible)
28016 return;
28017
28018 hlinfo->mouse_face_mouse_x = x;
28019 hlinfo->mouse_face_mouse_y = y;
28020 hlinfo->mouse_face_mouse_frame = f;
28021
28022 if (hlinfo->mouse_face_defer)
28023 return;
28024
28025 /* Which window is that in? */
28026 window = window_from_coordinates (f, x, y, &part, 1);
28027
28028 /* If displaying active text in another window, clear that. */
28029 if (! EQ (window, hlinfo->mouse_face_window)
28030 /* Also clear if we move out of text area in same window. */
28031 || (!NILP (hlinfo->mouse_face_window)
28032 && !NILP (window)
28033 && part != ON_TEXT
28034 && part != ON_MODE_LINE
28035 && part != ON_HEADER_LINE))
28036 clear_mouse_face (hlinfo);
28037
28038 /* Not on a window -> return. */
28039 if (!WINDOWP (window))
28040 return;
28041
28042 /* Reset help_echo_string. It will get recomputed below. */
28043 help_echo_string = Qnil;
28044
28045 /* Convert to window-relative pixel coordinates. */
28046 w = XWINDOW (window);
28047 frame_to_window_pixel_xy (w, &x, &y);
28048
28049 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
28050 /* Handle tool-bar window differently since it doesn't display a
28051 buffer. */
28052 if (EQ (window, f->tool_bar_window))
28053 {
28054 note_tool_bar_highlight (f, x, y);
28055 return;
28056 }
28057 #endif
28058
28059 /* Mouse is on the mode, header line or margin? */
28060 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
28061 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
28062 {
28063 note_mode_line_or_margin_highlight (window, x, y, part);
28064 return;
28065 }
28066
28067 #ifdef HAVE_WINDOW_SYSTEM
28068 if (part == ON_VERTICAL_BORDER)
28069 {
28070 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28071 help_echo_string = build_string ("drag-mouse-1: resize");
28072 }
28073 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28074 || part == ON_SCROLL_BAR)
28075 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28076 else
28077 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28078 #endif
28079
28080 /* Are we in a window whose display is up to date?
28081 And verify the buffer's text has not changed. */
28082 b = XBUFFER (w->contents);
28083 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28084 {
28085 int hpos, vpos, dx, dy, area = LAST_AREA;
28086 ptrdiff_t pos;
28087 struct glyph *glyph;
28088 Lisp_Object object;
28089 Lisp_Object mouse_face = Qnil, position;
28090 Lisp_Object *overlay_vec = NULL;
28091 ptrdiff_t i, noverlays;
28092 struct buffer *obuf;
28093 ptrdiff_t obegv, ozv;
28094 int same_region;
28095
28096 /* Find the glyph under X/Y. */
28097 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
28098
28099 #ifdef HAVE_WINDOW_SYSTEM
28100 /* Look for :pointer property on image. */
28101 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28102 {
28103 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
28104 if (img != NULL && IMAGEP (img->spec))
28105 {
28106 Lisp_Object image_map, hotspot;
28107 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
28108 !NILP (image_map))
28109 && (hotspot = find_hot_spot (image_map,
28110 glyph->slice.img.x + dx,
28111 glyph->slice.img.y + dy),
28112 CONSP (hotspot))
28113 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28114 {
28115 Lisp_Object plist;
28116
28117 /* Could check XCAR (hotspot) to see if we enter/leave
28118 this hot-spot.
28119 If so, we could look for mouse-enter, mouse-leave
28120 properties in PLIST (and do something...). */
28121 hotspot = XCDR (hotspot);
28122 if (CONSP (hotspot)
28123 && (plist = XCAR (hotspot), CONSP (plist)))
28124 {
28125 pointer = Fplist_get (plist, Qpointer);
28126 if (NILP (pointer))
28127 pointer = Qhand;
28128 help_echo_string = Fplist_get (plist, Qhelp_echo);
28129 if (!NILP (help_echo_string))
28130 {
28131 help_echo_window = window;
28132 help_echo_object = glyph->object;
28133 help_echo_pos = glyph->charpos;
28134 }
28135 }
28136 }
28137 if (NILP (pointer))
28138 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28139 }
28140 }
28141 #endif /* HAVE_WINDOW_SYSTEM */
28142
28143 /* Clear mouse face if X/Y not over text. */
28144 if (glyph == NULL
28145 || area != TEXT_AREA
28146 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
28147 /* Glyph's OBJECT is an integer for glyphs inserted by the
28148 display engine for its internal purposes, like truncation
28149 and continuation glyphs and blanks beyond the end of
28150 line's text on text terminals. If we are over such a
28151 glyph, we are not over any text. */
28152 || INTEGERP (glyph->object)
28153 /* R2L rows have a stretch glyph at their front, which
28154 stands for no text, whereas L2R rows have no glyphs at
28155 all beyond the end of text. Treat such stretch glyphs
28156 like we do with NULL glyphs in L2R rows. */
28157 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28158 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
28159 && glyph->type == STRETCH_GLYPH
28160 && glyph->avoid_cursor_p))
28161 {
28162 if (clear_mouse_face (hlinfo))
28163 cursor = No_Cursor;
28164 #ifdef HAVE_WINDOW_SYSTEM
28165 if (FRAME_WINDOW_P (f) && NILP (pointer))
28166 {
28167 if (area != TEXT_AREA)
28168 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28169 else
28170 pointer = Vvoid_text_area_pointer;
28171 }
28172 #endif
28173 goto set_cursor;
28174 }
28175
28176 pos = glyph->charpos;
28177 object = glyph->object;
28178 if (!STRINGP (object) && !BUFFERP (object))
28179 goto set_cursor;
28180
28181 /* If we get an out-of-range value, return now; avoid an error. */
28182 if (BUFFERP (object) && pos > BUF_Z (b))
28183 goto set_cursor;
28184
28185 /* Make the window's buffer temporarily current for
28186 overlays_at and compute_char_face. */
28187 obuf = current_buffer;
28188 current_buffer = b;
28189 obegv = BEGV;
28190 ozv = ZV;
28191 BEGV = BEG;
28192 ZV = Z;
28193
28194 /* Is this char mouse-active or does it have help-echo? */
28195 position = make_number (pos);
28196
28197 if (BUFFERP (object))
28198 {
28199 /* Put all the overlays we want in a vector in overlay_vec. */
28200 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28201 /* Sort overlays into increasing priority order. */
28202 noverlays = sort_overlays (overlay_vec, noverlays, w);
28203 }
28204 else
28205 noverlays = 0;
28206
28207 if (NILP (Vmouse_highlight))
28208 {
28209 clear_mouse_face (hlinfo);
28210 goto check_help_echo;
28211 }
28212
28213 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28214
28215 if (same_region)
28216 cursor = No_Cursor;
28217
28218 /* Check mouse-face highlighting. */
28219 if (! same_region
28220 /* If there exists an overlay with mouse-face overlapping
28221 the one we are currently highlighting, we have to
28222 check if we enter the overlapping overlay, and then
28223 highlight only that. */
28224 || (OVERLAYP (hlinfo->mouse_face_overlay)
28225 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28226 {
28227 /* Find the highest priority overlay with a mouse-face. */
28228 Lisp_Object overlay = Qnil;
28229 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28230 {
28231 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28232 if (!NILP (mouse_face))
28233 overlay = overlay_vec[i];
28234 }
28235
28236 /* If we're highlighting the same overlay as before, there's
28237 no need to do that again. */
28238 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28239 goto check_help_echo;
28240 hlinfo->mouse_face_overlay = overlay;
28241
28242 /* Clear the display of the old active region, if any. */
28243 if (clear_mouse_face (hlinfo))
28244 cursor = No_Cursor;
28245
28246 /* If no overlay applies, get a text property. */
28247 if (NILP (overlay))
28248 mouse_face = Fget_text_property (position, Qmouse_face, object);
28249
28250 /* Next, compute the bounds of the mouse highlighting and
28251 display it. */
28252 if (!NILP (mouse_face) && STRINGP (object))
28253 {
28254 /* The mouse-highlighting comes from a display string
28255 with a mouse-face. */
28256 Lisp_Object s, e;
28257 ptrdiff_t ignore;
28258
28259 s = Fprevious_single_property_change
28260 (make_number (pos + 1), Qmouse_face, object, Qnil);
28261 e = Fnext_single_property_change
28262 (position, Qmouse_face, object, Qnil);
28263 if (NILP (s))
28264 s = make_number (0);
28265 if (NILP (e))
28266 e = make_number (SCHARS (object) - 1);
28267 mouse_face_from_string_pos (w, hlinfo, object,
28268 XINT (s), XINT (e));
28269 hlinfo->mouse_face_past_end = 0;
28270 hlinfo->mouse_face_window = window;
28271 hlinfo->mouse_face_face_id
28272 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
28273 glyph->face_id, 1);
28274 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28275 cursor = No_Cursor;
28276 }
28277 else
28278 {
28279 /* The mouse-highlighting, if any, comes from an overlay
28280 or text property in the buffer. */
28281 Lisp_Object buffer IF_LINT (= Qnil);
28282 Lisp_Object disp_string IF_LINT (= Qnil);
28283
28284 if (STRINGP (object))
28285 {
28286 /* If we are on a display string with no mouse-face,
28287 check if the text under it has one. */
28288 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28289 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28290 pos = string_buffer_position (object, start);
28291 if (pos > 0)
28292 {
28293 mouse_face = get_char_property_and_overlay
28294 (make_number (pos), Qmouse_face, w->contents, &overlay);
28295 buffer = w->contents;
28296 disp_string = object;
28297 }
28298 }
28299 else
28300 {
28301 buffer = object;
28302 disp_string = Qnil;
28303 }
28304
28305 if (!NILP (mouse_face))
28306 {
28307 Lisp_Object before, after;
28308 Lisp_Object before_string, after_string;
28309 /* To correctly find the limits of mouse highlight
28310 in a bidi-reordered buffer, we must not use the
28311 optimization of limiting the search in
28312 previous-single-property-change and
28313 next-single-property-change, because
28314 rows_from_pos_range needs the real start and end
28315 positions to DTRT in this case. That's because
28316 the first row visible in a window does not
28317 necessarily display the character whose position
28318 is the smallest. */
28319 Lisp_Object lim1 =
28320 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28321 ? Fmarker_position (w->start)
28322 : Qnil;
28323 Lisp_Object lim2 =
28324 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28325 ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos)
28326 : Qnil;
28327
28328 if (NILP (overlay))
28329 {
28330 /* Handle the text property case. */
28331 before = Fprevious_single_property_change
28332 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28333 after = Fnext_single_property_change
28334 (make_number (pos), Qmouse_face, buffer, lim2);
28335 before_string = after_string = Qnil;
28336 }
28337 else
28338 {
28339 /* Handle the overlay case. */
28340 before = Foverlay_start (overlay);
28341 after = Foverlay_end (overlay);
28342 before_string = Foverlay_get (overlay, Qbefore_string);
28343 after_string = Foverlay_get (overlay, Qafter_string);
28344
28345 if (!STRINGP (before_string)) before_string = Qnil;
28346 if (!STRINGP (after_string)) after_string = Qnil;
28347 }
28348
28349 mouse_face_from_buffer_pos (window, hlinfo, pos,
28350 NILP (before)
28351 ? 1
28352 : XFASTINT (before),
28353 NILP (after)
28354 ? BUF_Z (XBUFFER (buffer))
28355 : XFASTINT (after),
28356 before_string, after_string,
28357 disp_string);
28358 cursor = No_Cursor;
28359 }
28360 }
28361 }
28362
28363 check_help_echo:
28364
28365 /* Look for a `help-echo' property. */
28366 if (NILP (help_echo_string)) {
28367 Lisp_Object help, overlay;
28368
28369 /* Check overlays first. */
28370 help = overlay = Qnil;
28371 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28372 {
28373 overlay = overlay_vec[i];
28374 help = Foverlay_get (overlay, Qhelp_echo);
28375 }
28376
28377 if (!NILP (help))
28378 {
28379 help_echo_string = help;
28380 help_echo_window = window;
28381 help_echo_object = overlay;
28382 help_echo_pos = pos;
28383 }
28384 else
28385 {
28386 Lisp_Object obj = glyph->object;
28387 ptrdiff_t charpos = glyph->charpos;
28388
28389 /* Try text properties. */
28390 if (STRINGP (obj)
28391 && charpos >= 0
28392 && charpos < SCHARS (obj))
28393 {
28394 help = Fget_text_property (make_number (charpos),
28395 Qhelp_echo, obj);
28396 if (NILP (help))
28397 {
28398 /* If the string itself doesn't specify a help-echo,
28399 see if the buffer text ``under'' it does. */
28400 struct glyph_row *r
28401 = MATRIX_ROW (w->current_matrix, vpos);
28402 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28403 ptrdiff_t p = string_buffer_position (obj, start);
28404 if (p > 0)
28405 {
28406 help = Fget_char_property (make_number (p),
28407 Qhelp_echo, w->contents);
28408 if (!NILP (help))
28409 {
28410 charpos = p;
28411 obj = w->contents;
28412 }
28413 }
28414 }
28415 }
28416 else if (BUFFERP (obj)
28417 && charpos >= BEGV
28418 && charpos < ZV)
28419 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28420 obj);
28421
28422 if (!NILP (help))
28423 {
28424 help_echo_string = help;
28425 help_echo_window = window;
28426 help_echo_object = obj;
28427 help_echo_pos = charpos;
28428 }
28429 }
28430 }
28431
28432 #ifdef HAVE_WINDOW_SYSTEM
28433 /* Look for a `pointer' property. */
28434 if (FRAME_WINDOW_P (f) && NILP (pointer))
28435 {
28436 /* Check overlays first. */
28437 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28438 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28439
28440 if (NILP (pointer))
28441 {
28442 Lisp_Object obj = glyph->object;
28443 ptrdiff_t charpos = glyph->charpos;
28444
28445 /* Try text properties. */
28446 if (STRINGP (obj)
28447 && charpos >= 0
28448 && charpos < SCHARS (obj))
28449 {
28450 pointer = Fget_text_property (make_number (charpos),
28451 Qpointer, obj);
28452 if (NILP (pointer))
28453 {
28454 /* If the string itself doesn't specify a pointer,
28455 see if the buffer text ``under'' it does. */
28456 struct glyph_row *r
28457 = MATRIX_ROW (w->current_matrix, vpos);
28458 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28459 ptrdiff_t p = string_buffer_position (obj, start);
28460 if (p > 0)
28461 pointer = Fget_char_property (make_number (p),
28462 Qpointer, w->contents);
28463 }
28464 }
28465 else if (BUFFERP (obj)
28466 && charpos >= BEGV
28467 && charpos < ZV)
28468 pointer = Fget_text_property (make_number (charpos),
28469 Qpointer, obj);
28470 }
28471 }
28472 #endif /* HAVE_WINDOW_SYSTEM */
28473
28474 BEGV = obegv;
28475 ZV = ozv;
28476 current_buffer = obuf;
28477 }
28478
28479 set_cursor:
28480
28481 #ifdef HAVE_WINDOW_SYSTEM
28482 if (FRAME_WINDOW_P (f))
28483 define_frame_cursor1 (f, cursor, pointer);
28484 #else
28485 /* This is here to prevent a compiler error, about "label at end of
28486 compound statement". */
28487 return;
28488 #endif
28489 }
28490
28491
28492 /* EXPORT for RIF:
28493 Clear any mouse-face on window W. This function is part of the
28494 redisplay interface, and is called from try_window_id and similar
28495 functions to ensure the mouse-highlight is off. */
28496
28497 void
28498 x_clear_window_mouse_face (struct window *w)
28499 {
28500 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28501 Lisp_Object window;
28502
28503 block_input ();
28504 XSETWINDOW (window, w);
28505 if (EQ (window, hlinfo->mouse_face_window))
28506 clear_mouse_face (hlinfo);
28507 unblock_input ();
28508 }
28509
28510
28511 /* EXPORT:
28512 Just discard the mouse face information for frame F, if any.
28513 This is used when the size of F is changed. */
28514
28515 void
28516 cancel_mouse_face (struct frame *f)
28517 {
28518 Lisp_Object window;
28519 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28520
28521 window = hlinfo->mouse_face_window;
28522 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28523 reset_mouse_highlight (hlinfo);
28524 }
28525
28526
28527 \f
28528 /***********************************************************************
28529 Exposure Events
28530 ***********************************************************************/
28531
28532 #ifdef HAVE_WINDOW_SYSTEM
28533
28534 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28535 which intersects rectangle R. R is in window-relative coordinates. */
28536
28537 static void
28538 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28539 enum glyph_row_area area)
28540 {
28541 struct glyph *first = row->glyphs[area];
28542 struct glyph *end = row->glyphs[area] + row->used[area];
28543 struct glyph *last;
28544 int first_x, start_x, x;
28545
28546 if (area == TEXT_AREA && row->fill_line_p)
28547 /* If row extends face to end of line write the whole line. */
28548 draw_glyphs (w, 0, row, area,
28549 0, row->used[area],
28550 DRAW_NORMAL_TEXT, 0);
28551 else
28552 {
28553 /* Set START_X to the window-relative start position for drawing glyphs of
28554 AREA. The first glyph of the text area can be partially visible.
28555 The first glyphs of other areas cannot. */
28556 start_x = window_box_left_offset (w, area);
28557 x = start_x;
28558 if (area == TEXT_AREA)
28559 x += row->x;
28560
28561 /* Find the first glyph that must be redrawn. */
28562 while (first < end
28563 && x + first->pixel_width < r->x)
28564 {
28565 x += first->pixel_width;
28566 ++first;
28567 }
28568
28569 /* Find the last one. */
28570 last = first;
28571 first_x = x;
28572 while (last < end
28573 && x < r->x + r->width)
28574 {
28575 x += last->pixel_width;
28576 ++last;
28577 }
28578
28579 /* Repaint. */
28580 if (last > first)
28581 draw_glyphs (w, first_x - start_x, row, area,
28582 first - row->glyphs[area], last - row->glyphs[area],
28583 DRAW_NORMAL_TEXT, 0);
28584 }
28585 }
28586
28587
28588 /* Redraw the parts of the glyph row ROW on window W intersecting
28589 rectangle R. R is in window-relative coordinates. Value is
28590 non-zero if mouse-face was overwritten. */
28591
28592 static int
28593 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28594 {
28595 eassert (row->enabled_p);
28596
28597 if (row->mode_line_p || w->pseudo_window_p)
28598 draw_glyphs (w, 0, row, TEXT_AREA,
28599 0, row->used[TEXT_AREA],
28600 DRAW_NORMAL_TEXT, 0);
28601 else
28602 {
28603 if (row->used[LEFT_MARGIN_AREA])
28604 expose_area (w, row, r, LEFT_MARGIN_AREA);
28605 if (row->used[TEXT_AREA])
28606 expose_area (w, row, r, TEXT_AREA);
28607 if (row->used[RIGHT_MARGIN_AREA])
28608 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28609 draw_row_fringe_bitmaps (w, row);
28610 }
28611
28612 return row->mouse_face_p;
28613 }
28614
28615
28616 /* Redraw those parts of glyphs rows during expose event handling that
28617 overlap other rows. Redrawing of an exposed line writes over parts
28618 of lines overlapping that exposed line; this function fixes that.
28619
28620 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28621 row in W's current matrix that is exposed and overlaps other rows.
28622 LAST_OVERLAPPING_ROW is the last such row. */
28623
28624 static void
28625 expose_overlaps (struct window *w,
28626 struct glyph_row *first_overlapping_row,
28627 struct glyph_row *last_overlapping_row,
28628 XRectangle *r)
28629 {
28630 struct glyph_row *row;
28631
28632 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28633 if (row->overlapping_p)
28634 {
28635 eassert (row->enabled_p && !row->mode_line_p);
28636
28637 row->clip = r;
28638 if (row->used[LEFT_MARGIN_AREA])
28639 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28640
28641 if (row->used[TEXT_AREA])
28642 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28643
28644 if (row->used[RIGHT_MARGIN_AREA])
28645 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28646 row->clip = NULL;
28647 }
28648 }
28649
28650
28651 /* Return non-zero if W's cursor intersects rectangle R. */
28652
28653 static int
28654 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28655 {
28656 XRectangle cr, result;
28657 struct glyph *cursor_glyph;
28658 struct glyph_row *row;
28659
28660 if (w->phys_cursor.vpos >= 0
28661 && w->phys_cursor.vpos < w->current_matrix->nrows
28662 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28663 row->enabled_p)
28664 && row->cursor_in_fringe_p)
28665 {
28666 /* Cursor is in the fringe. */
28667 cr.x = window_box_right_offset (w,
28668 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28669 ? RIGHT_MARGIN_AREA
28670 : TEXT_AREA));
28671 cr.y = row->y;
28672 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28673 cr.height = row->height;
28674 return x_intersect_rectangles (&cr, r, &result);
28675 }
28676
28677 cursor_glyph = get_phys_cursor_glyph (w);
28678 if (cursor_glyph)
28679 {
28680 /* r is relative to W's box, but w->phys_cursor.x is relative
28681 to left edge of W's TEXT area. Adjust it. */
28682 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28683 cr.y = w->phys_cursor.y;
28684 cr.width = cursor_glyph->pixel_width;
28685 cr.height = w->phys_cursor_height;
28686 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28687 I assume the effect is the same -- and this is portable. */
28688 return x_intersect_rectangles (&cr, r, &result);
28689 }
28690 /* If we don't understand the format, pretend we're not in the hot-spot. */
28691 return 0;
28692 }
28693
28694
28695 /* EXPORT:
28696 Draw a vertical window border to the right of window W if W doesn't
28697 have vertical scroll bars. */
28698
28699 void
28700 x_draw_vertical_border (struct window *w)
28701 {
28702 struct frame *f = XFRAME (WINDOW_FRAME (w));
28703
28704 /* We could do better, if we knew what type of scroll-bar the adjacent
28705 windows (on either side) have... But we don't :-(
28706 However, I think this works ok. ++KFS 2003-04-25 */
28707
28708 /* Redraw borders between horizontally adjacent windows. Don't
28709 do it for frames with vertical scroll bars because either the
28710 right scroll bar of a window, or the left scroll bar of its
28711 neighbor will suffice as a border. */
28712 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28713 return;
28714
28715 /* Note: It is necessary to redraw both the left and the right
28716 borders, for when only this single window W is being
28717 redisplayed. */
28718 if (!WINDOW_RIGHTMOST_P (w)
28719 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28720 {
28721 int x0, x1, y0, y1;
28722
28723 window_box_edges (w, &x0, &y0, &x1, &y1);
28724 y1 -= 1;
28725
28726 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28727 x1 -= 1;
28728
28729 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28730 }
28731 if (!WINDOW_LEFTMOST_P (w)
28732 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28733 {
28734 int x0, x1, y0, y1;
28735
28736 window_box_edges (w, &x0, &y0, &x1, &y1);
28737 y1 -= 1;
28738
28739 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28740 x0 -= 1;
28741
28742 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28743 }
28744 }
28745
28746
28747 /* Redraw the part of window W intersection rectangle FR. Pixel
28748 coordinates in FR are frame-relative. Call this function with
28749 input blocked. Value is non-zero if the exposure overwrites
28750 mouse-face. */
28751
28752 static int
28753 expose_window (struct window *w, XRectangle *fr)
28754 {
28755 struct frame *f = XFRAME (w->frame);
28756 XRectangle wr, r;
28757 int mouse_face_overwritten_p = 0;
28758
28759 /* If window is not yet fully initialized, do nothing. This can
28760 happen when toolkit scroll bars are used and a window is split.
28761 Reconfiguring the scroll bar will generate an expose for a newly
28762 created window. */
28763 if (w->current_matrix == NULL)
28764 return 0;
28765
28766 /* When we're currently updating the window, display and current
28767 matrix usually don't agree. Arrange for a thorough display
28768 later. */
28769 if (w->must_be_updated_p)
28770 {
28771 SET_FRAME_GARBAGED (f);
28772 return 0;
28773 }
28774
28775 /* Frame-relative pixel rectangle of W. */
28776 wr.x = WINDOW_LEFT_EDGE_X (w);
28777 wr.y = WINDOW_TOP_EDGE_Y (w);
28778 wr.width = WINDOW_TOTAL_WIDTH (w);
28779 wr.height = WINDOW_TOTAL_HEIGHT (w);
28780
28781 if (x_intersect_rectangles (fr, &wr, &r))
28782 {
28783 int yb = window_text_bottom_y (w);
28784 struct glyph_row *row;
28785 int cursor_cleared_p, phys_cursor_on_p;
28786 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28787
28788 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28789 r.x, r.y, r.width, r.height));
28790
28791 /* Convert to window coordinates. */
28792 r.x -= WINDOW_LEFT_EDGE_X (w);
28793 r.y -= WINDOW_TOP_EDGE_Y (w);
28794
28795 /* Turn off the cursor. */
28796 if (!w->pseudo_window_p
28797 && phys_cursor_in_rect_p (w, &r))
28798 {
28799 x_clear_cursor (w);
28800 cursor_cleared_p = 1;
28801 }
28802 else
28803 cursor_cleared_p = 0;
28804
28805 /* If the row containing the cursor extends face to end of line,
28806 then expose_area might overwrite the cursor outside the
28807 rectangle and thus notice_overwritten_cursor might clear
28808 w->phys_cursor_on_p. We remember the original value and
28809 check later if it is changed. */
28810 phys_cursor_on_p = w->phys_cursor_on_p;
28811
28812 /* Update lines intersecting rectangle R. */
28813 first_overlapping_row = last_overlapping_row = NULL;
28814 for (row = w->current_matrix->rows;
28815 row->enabled_p;
28816 ++row)
28817 {
28818 int y0 = row->y;
28819 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28820
28821 if ((y0 >= r.y && y0 < r.y + r.height)
28822 || (y1 > r.y && y1 < r.y + r.height)
28823 || (r.y >= y0 && r.y < y1)
28824 || (r.y + r.height > y0 && r.y + r.height < y1))
28825 {
28826 /* A header line may be overlapping, but there is no need
28827 to fix overlapping areas for them. KFS 2005-02-12 */
28828 if (row->overlapping_p && !row->mode_line_p)
28829 {
28830 if (first_overlapping_row == NULL)
28831 first_overlapping_row = row;
28832 last_overlapping_row = row;
28833 }
28834
28835 row->clip = fr;
28836 if (expose_line (w, row, &r))
28837 mouse_face_overwritten_p = 1;
28838 row->clip = NULL;
28839 }
28840 else if (row->overlapping_p)
28841 {
28842 /* We must redraw a row overlapping the exposed area. */
28843 if (y0 < r.y
28844 ? y0 + row->phys_height > r.y
28845 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28846 {
28847 if (first_overlapping_row == NULL)
28848 first_overlapping_row = row;
28849 last_overlapping_row = row;
28850 }
28851 }
28852
28853 if (y1 >= yb)
28854 break;
28855 }
28856
28857 /* Display the mode line if there is one. */
28858 if (WINDOW_WANTS_MODELINE_P (w)
28859 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28860 row->enabled_p)
28861 && row->y < r.y + r.height)
28862 {
28863 if (expose_line (w, row, &r))
28864 mouse_face_overwritten_p = 1;
28865 }
28866
28867 if (!w->pseudo_window_p)
28868 {
28869 /* Fix the display of overlapping rows. */
28870 if (first_overlapping_row)
28871 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28872 fr);
28873
28874 /* Draw border between windows. */
28875 x_draw_vertical_border (w);
28876
28877 /* Turn the cursor on again. */
28878 if (cursor_cleared_p
28879 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28880 update_window_cursor (w, 1);
28881 }
28882 }
28883
28884 return mouse_face_overwritten_p;
28885 }
28886
28887
28888
28889 /* Redraw (parts) of all windows in the window tree rooted at W that
28890 intersect R. R contains frame pixel coordinates. Value is
28891 non-zero if the exposure overwrites mouse-face. */
28892
28893 static int
28894 expose_window_tree (struct window *w, XRectangle *r)
28895 {
28896 struct frame *f = XFRAME (w->frame);
28897 int mouse_face_overwritten_p = 0;
28898
28899 while (w && !FRAME_GARBAGED_P (f))
28900 {
28901 if (WINDOWP (w->contents))
28902 mouse_face_overwritten_p
28903 |= expose_window_tree (XWINDOW (w->contents), r);
28904 else
28905 mouse_face_overwritten_p |= expose_window (w, r);
28906
28907 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28908 }
28909
28910 return mouse_face_overwritten_p;
28911 }
28912
28913
28914 /* EXPORT:
28915 Redisplay an exposed area of frame F. X and Y are the upper-left
28916 corner of the exposed rectangle. W and H are width and height of
28917 the exposed area. All are pixel values. W or H zero means redraw
28918 the entire frame. */
28919
28920 void
28921 expose_frame (struct frame *f, int x, int y, int w, int h)
28922 {
28923 XRectangle r;
28924 int mouse_face_overwritten_p = 0;
28925
28926 TRACE ((stderr, "expose_frame "));
28927
28928 /* No need to redraw if frame will be redrawn soon. */
28929 if (FRAME_GARBAGED_P (f))
28930 {
28931 TRACE ((stderr, " garbaged\n"));
28932 return;
28933 }
28934
28935 /* If basic faces haven't been realized yet, there is no point in
28936 trying to redraw anything. This can happen when we get an expose
28937 event while Emacs is starting, e.g. by moving another window. */
28938 if (FRAME_FACE_CACHE (f) == NULL
28939 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28940 {
28941 TRACE ((stderr, " no faces\n"));
28942 return;
28943 }
28944
28945 if (w == 0 || h == 0)
28946 {
28947 r.x = r.y = 0;
28948 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28949 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28950 }
28951 else
28952 {
28953 r.x = x;
28954 r.y = y;
28955 r.width = w;
28956 r.height = h;
28957 }
28958
28959 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28960 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28961
28962 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
28963 if (WINDOWP (f->tool_bar_window))
28964 mouse_face_overwritten_p
28965 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28966 #endif
28967
28968 #ifdef HAVE_X_WINDOWS
28969 #ifndef MSDOS
28970 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28971 if (WINDOWP (f->menu_bar_window))
28972 mouse_face_overwritten_p
28973 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28974 #endif /* not USE_X_TOOLKIT and not USE_GTK */
28975 #endif
28976 #endif
28977
28978 /* Some window managers support a focus-follows-mouse style with
28979 delayed raising of frames. Imagine a partially obscured frame,
28980 and moving the mouse into partially obscured mouse-face on that
28981 frame. The visible part of the mouse-face will be highlighted,
28982 then the WM raises the obscured frame. With at least one WM, KDE
28983 2.1, Emacs is not getting any event for the raising of the frame
28984 (even tried with SubstructureRedirectMask), only Expose events.
28985 These expose events will draw text normally, i.e. not
28986 highlighted. Which means we must redo the highlight here.
28987 Subsume it under ``we love X''. --gerd 2001-08-15 */
28988 /* Included in Windows version because Windows most likely does not
28989 do the right thing if any third party tool offers
28990 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28991 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
28992 {
28993 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28994 if (f == hlinfo->mouse_face_mouse_frame)
28995 {
28996 int mouse_x = hlinfo->mouse_face_mouse_x;
28997 int mouse_y = hlinfo->mouse_face_mouse_y;
28998 clear_mouse_face (hlinfo);
28999 note_mouse_highlight (f, mouse_x, mouse_y);
29000 }
29001 }
29002 }
29003
29004
29005 /* EXPORT:
29006 Determine the intersection of two rectangles R1 and R2. Return
29007 the intersection in *RESULT. Value is non-zero if RESULT is not
29008 empty. */
29009
29010 int
29011 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
29012 {
29013 XRectangle *left, *right;
29014 XRectangle *upper, *lower;
29015 int intersection_p = 0;
29016
29017 /* Rearrange so that R1 is the left-most rectangle. */
29018 if (r1->x < r2->x)
29019 left = r1, right = r2;
29020 else
29021 left = r2, right = r1;
29022
29023 /* X0 of the intersection is right.x0, if this is inside R1,
29024 otherwise there is no intersection. */
29025 if (right->x <= left->x + left->width)
29026 {
29027 result->x = right->x;
29028
29029 /* The right end of the intersection is the minimum of
29030 the right ends of left and right. */
29031 result->width = (min (left->x + left->width, right->x + right->width)
29032 - result->x);
29033
29034 /* Same game for Y. */
29035 if (r1->y < r2->y)
29036 upper = r1, lower = r2;
29037 else
29038 upper = r2, lower = r1;
29039
29040 /* The upper end of the intersection is lower.y0, if this is inside
29041 of upper. Otherwise, there is no intersection. */
29042 if (lower->y <= upper->y + upper->height)
29043 {
29044 result->y = lower->y;
29045
29046 /* The lower end of the intersection is the minimum of the lower
29047 ends of upper and lower. */
29048 result->height = (min (lower->y + lower->height,
29049 upper->y + upper->height)
29050 - result->y);
29051 intersection_p = 1;
29052 }
29053 }
29054
29055 return intersection_p;
29056 }
29057
29058 #endif /* HAVE_WINDOW_SYSTEM */
29059
29060 \f
29061 /***********************************************************************
29062 Initialization
29063 ***********************************************************************/
29064
29065 void
29066 syms_of_xdisp (void)
29067 {
29068 Vwith_echo_area_save_vector = Qnil;
29069 staticpro (&Vwith_echo_area_save_vector);
29070
29071 Vmessage_stack = Qnil;
29072 staticpro (&Vmessage_stack);
29073
29074 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
29075 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
29076
29077 message_dolog_marker1 = Fmake_marker ();
29078 staticpro (&message_dolog_marker1);
29079 message_dolog_marker2 = Fmake_marker ();
29080 staticpro (&message_dolog_marker2);
29081 message_dolog_marker3 = Fmake_marker ();
29082 staticpro (&message_dolog_marker3);
29083
29084 #ifdef GLYPH_DEBUG
29085 defsubr (&Sdump_frame_glyph_matrix);
29086 defsubr (&Sdump_glyph_matrix);
29087 defsubr (&Sdump_glyph_row);
29088 defsubr (&Sdump_tool_bar_row);
29089 defsubr (&Strace_redisplay);
29090 defsubr (&Strace_to_stderr);
29091 #endif
29092 #ifdef HAVE_WINDOW_SYSTEM
29093 defsubr (&Stool_bar_lines_needed);
29094 defsubr (&Slookup_image_map);
29095 #endif
29096 defsubr (&Sline_pixel_height);
29097 defsubr (&Sformat_mode_line);
29098 defsubr (&Sinvisible_p);
29099 defsubr (&Scurrent_bidi_paragraph_direction);
29100 defsubr (&Smove_point_visually);
29101
29102 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
29103 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
29104 DEFSYM (Qoverriding_local_map, "overriding-local-map");
29105 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
29106 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
29107 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
29108 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
29109 DEFSYM (Qeval, "eval");
29110 DEFSYM (QCdata, ":data");
29111 DEFSYM (Qdisplay, "display");
29112 DEFSYM (Qspace_width, "space-width");
29113 DEFSYM (Qraise, "raise");
29114 DEFSYM (Qslice, "slice");
29115 DEFSYM (Qspace, "space");
29116 DEFSYM (Qmargin, "margin");
29117 DEFSYM (Qpointer, "pointer");
29118 DEFSYM (Qleft_margin, "left-margin");
29119 DEFSYM (Qright_margin, "right-margin");
29120 DEFSYM (Qcenter, "center");
29121 DEFSYM (Qline_height, "line-height");
29122 DEFSYM (QCalign_to, ":align-to");
29123 DEFSYM (QCrelative_width, ":relative-width");
29124 DEFSYM (QCrelative_height, ":relative-height");
29125 DEFSYM (QCeval, ":eval");
29126 DEFSYM (QCpropertize, ":propertize");
29127 DEFSYM (QCfile, ":file");
29128 DEFSYM (Qfontified, "fontified");
29129 DEFSYM (Qfontification_functions, "fontification-functions");
29130 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
29131 DEFSYM (Qescape_glyph, "escape-glyph");
29132 DEFSYM (Qnobreak_space, "nobreak-space");
29133 DEFSYM (Qimage, "image");
29134 DEFSYM (Qtext, "text");
29135 DEFSYM (Qboth, "both");
29136 DEFSYM (Qboth_horiz, "both-horiz");
29137 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29138 DEFSYM (QCmap, ":map");
29139 DEFSYM (QCpointer, ":pointer");
29140 DEFSYM (Qrect, "rect");
29141 DEFSYM (Qcircle, "circle");
29142 DEFSYM (Qpoly, "poly");
29143 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29144 DEFSYM (Qgrow_only, "grow-only");
29145 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29146 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29147 DEFSYM (Qposition, "position");
29148 DEFSYM (Qbuffer_position, "buffer-position");
29149 DEFSYM (Qobject, "object");
29150 DEFSYM (Qbar, "bar");
29151 DEFSYM (Qhbar, "hbar");
29152 DEFSYM (Qbox, "box");
29153 DEFSYM (Qhollow, "hollow");
29154 DEFSYM (Qhand, "hand");
29155 DEFSYM (Qarrow, "arrow");
29156 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29157
29158 list_of_error = list1 (list2 (intern_c_string ("error"),
29159 intern_c_string ("void-variable")));
29160 staticpro (&list_of_error);
29161
29162 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29163 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29164 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29165 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29166
29167 echo_buffer[0] = echo_buffer[1] = Qnil;
29168 staticpro (&echo_buffer[0]);
29169 staticpro (&echo_buffer[1]);
29170
29171 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29172 staticpro (&echo_area_buffer[0]);
29173 staticpro (&echo_area_buffer[1]);
29174
29175 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29176 staticpro (&Vmessages_buffer_name);
29177
29178 mode_line_proptrans_alist = Qnil;
29179 staticpro (&mode_line_proptrans_alist);
29180 mode_line_string_list = Qnil;
29181 staticpro (&mode_line_string_list);
29182 mode_line_string_face = Qnil;
29183 staticpro (&mode_line_string_face);
29184 mode_line_string_face_prop = Qnil;
29185 staticpro (&mode_line_string_face_prop);
29186 Vmode_line_unwind_vector = Qnil;
29187 staticpro (&Vmode_line_unwind_vector);
29188
29189 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29190
29191 help_echo_string = Qnil;
29192 staticpro (&help_echo_string);
29193 help_echo_object = Qnil;
29194 staticpro (&help_echo_object);
29195 help_echo_window = Qnil;
29196 staticpro (&help_echo_window);
29197 previous_help_echo_string = Qnil;
29198 staticpro (&previous_help_echo_string);
29199 help_echo_pos = -1;
29200
29201 DEFSYM (Qright_to_left, "right-to-left");
29202 DEFSYM (Qleft_to_right, "left-to-right");
29203
29204 #ifdef HAVE_WINDOW_SYSTEM
29205 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29206 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29207 For example, if a block cursor is over a tab, it will be drawn as
29208 wide as that tab on the display. */);
29209 x_stretch_cursor_p = 0;
29210 #endif
29211
29212 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29213 doc: /* Non-nil means highlight trailing whitespace.
29214 The face used for trailing whitespace is `trailing-whitespace'. */);
29215 Vshow_trailing_whitespace = Qnil;
29216
29217 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29218 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29219 If the value is t, Emacs highlights non-ASCII chars which have the
29220 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29221 or `escape-glyph' face respectively.
29222
29223 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29224 U+2011 (non-breaking hyphen) are affected.
29225
29226 Any other non-nil value means to display these characters as a escape
29227 glyph followed by an ordinary space or hyphen.
29228
29229 A value of nil means no special handling of these characters. */);
29230 Vnobreak_char_display = Qt;
29231
29232 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29233 doc: /* The pointer shape to show in void text areas.
29234 A value of nil means to show the text pointer. Other options are `arrow',
29235 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29236 Vvoid_text_area_pointer = Qarrow;
29237
29238 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29239 doc: /* Non-nil means don't actually do any redisplay.
29240 This is used for internal purposes. */);
29241 Vinhibit_redisplay = Qnil;
29242
29243 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29244 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29245 Vglobal_mode_string = Qnil;
29246
29247 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29248 doc: /* Marker for where to display an arrow on top of the buffer text.
29249 This must be the beginning of a line in order to work.
29250 See also `overlay-arrow-string'. */);
29251 Voverlay_arrow_position = Qnil;
29252
29253 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29254 doc: /* String to display as an arrow in non-window frames.
29255 See also `overlay-arrow-position'. */);
29256 Voverlay_arrow_string = build_pure_c_string ("=>");
29257
29258 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29259 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29260 The symbols on this list are examined during redisplay to determine
29261 where to display overlay arrows. */);
29262 Voverlay_arrow_variable_list
29263 = list1 (intern_c_string ("overlay-arrow-position"));
29264
29265 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29266 doc: /* The number of lines to try scrolling a window by when point moves out.
29267 If that fails to bring point back on frame, point is centered instead.
29268 If this is zero, point is always centered after it moves off frame.
29269 If you want scrolling to always be a line at a time, you should set
29270 `scroll-conservatively' to a large value rather than set this to 1. */);
29271
29272 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29273 doc: /* Scroll up to this many lines, to bring point back on screen.
29274 If point moves off-screen, redisplay will scroll by up to
29275 `scroll-conservatively' lines in order to bring point just barely
29276 onto the screen again. If that cannot be done, then redisplay
29277 recenters point as usual.
29278
29279 If the value is greater than 100, redisplay will never recenter point,
29280 but will always scroll just enough text to bring point into view, even
29281 if you move far away.
29282
29283 A value of zero means always recenter point if it moves off screen. */);
29284 scroll_conservatively = 0;
29285
29286 DEFVAR_INT ("scroll-margin", scroll_margin,
29287 doc: /* Number of lines of margin at the top and bottom of a window.
29288 Recenter the window whenever point gets within this many lines
29289 of the top or bottom of the window. */);
29290 scroll_margin = 0;
29291
29292 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29293 doc: /* Pixels per inch value for non-window system displays.
29294 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29295 Vdisplay_pixels_per_inch = make_float (72.0);
29296
29297 #ifdef GLYPH_DEBUG
29298 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29299 #endif
29300
29301 DEFVAR_LISP ("truncate-partial-width-windows",
29302 Vtruncate_partial_width_windows,
29303 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29304 For an integer value, truncate lines in each window narrower than the
29305 full frame width, provided the window width is less than that integer;
29306 otherwise, respect the value of `truncate-lines'.
29307
29308 For any other non-nil value, truncate lines in all windows that do
29309 not span the full frame width.
29310
29311 A value of nil means to respect the value of `truncate-lines'.
29312
29313 If `word-wrap' is enabled, you might want to reduce this. */);
29314 Vtruncate_partial_width_windows = make_number (50);
29315
29316 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29317 doc: /* Maximum buffer size for which line number should be displayed.
29318 If the buffer is bigger than this, the line number does not appear
29319 in the mode line. A value of nil means no limit. */);
29320 Vline_number_display_limit = Qnil;
29321
29322 DEFVAR_INT ("line-number-display-limit-width",
29323 line_number_display_limit_width,
29324 doc: /* Maximum line width (in characters) for line number display.
29325 If the average length of the lines near point is bigger than this, then the
29326 line number may be omitted from the mode line. */);
29327 line_number_display_limit_width = 200;
29328
29329 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29330 doc: /* Non-nil means highlight region even in nonselected windows. */);
29331 highlight_nonselected_windows = 0;
29332
29333 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29334 doc: /* Non-nil if more than one frame is visible on this display.
29335 Minibuffer-only frames don't count, but iconified frames do.
29336 This variable is not guaranteed to be accurate except while processing
29337 `frame-title-format' and `icon-title-format'. */);
29338
29339 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29340 doc: /* Template for displaying the title bar of visible frames.
29341 \(Assuming the window manager supports this feature.)
29342
29343 This variable has the same structure as `mode-line-format', except that
29344 the %c and %l constructs are ignored. It is used only on frames for
29345 which no explicit name has been set \(see `modify-frame-parameters'). */);
29346
29347 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29348 doc: /* Template for displaying the title bar of an iconified frame.
29349 \(Assuming the window manager supports this feature.)
29350 This variable has the same structure as `mode-line-format' (which see),
29351 and is used only on frames for which no explicit name has been set
29352 \(see `modify-frame-parameters'). */);
29353 Vicon_title_format
29354 = Vframe_title_format
29355 = listn (CONSTYPE_PURE, 3,
29356 intern_c_string ("multiple-frames"),
29357 build_pure_c_string ("%b"),
29358 listn (CONSTYPE_PURE, 4,
29359 empty_unibyte_string,
29360 intern_c_string ("invocation-name"),
29361 build_pure_c_string ("@"),
29362 intern_c_string ("system-name")));
29363
29364 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29365 doc: /* Maximum number of lines to keep in the message log buffer.
29366 If nil, disable message logging. If t, log messages but don't truncate
29367 the buffer when it becomes large. */);
29368 Vmessage_log_max = make_number (1000);
29369
29370 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29371 doc: /* Functions called before redisplay, if window sizes have changed.
29372 The value should be a list of functions that take one argument.
29373 Just before redisplay, for each frame, if any of its windows have changed
29374 size since the last redisplay, or have been split or deleted,
29375 all the functions in the list are called, with the frame as argument. */);
29376 Vwindow_size_change_functions = Qnil;
29377
29378 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29379 doc: /* List of functions to call before redisplaying a window with scrolling.
29380 Each function is called with two arguments, the window and its new
29381 display-start position. Note that these functions are also called by
29382 `set-window-buffer'. Also note that the value of `window-end' is not
29383 valid when these functions are called.
29384
29385 Warning: Do not use this feature to alter the way the window
29386 is scrolled. It is not designed for that, and such use probably won't
29387 work. */);
29388 Vwindow_scroll_functions = Qnil;
29389
29390 DEFVAR_LISP ("window-text-change-functions",
29391 Vwindow_text_change_functions,
29392 doc: /* Functions to call in redisplay when text in the window might change. */);
29393 Vwindow_text_change_functions = Qnil;
29394
29395 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29396 doc: /* Functions called when redisplay of a window reaches the end trigger.
29397 Each function is called with two arguments, the window and the end trigger value.
29398 See `set-window-redisplay-end-trigger'. */);
29399 Vredisplay_end_trigger_functions = Qnil;
29400
29401 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29402 doc: /* Non-nil means autoselect window with mouse pointer.
29403 If nil, do not autoselect windows.
29404 A positive number means delay autoselection by that many seconds: a
29405 window is autoselected only after the mouse has remained in that
29406 window for the duration of the delay.
29407 A negative number has a similar effect, but causes windows to be
29408 autoselected only after the mouse has stopped moving. \(Because of
29409 the way Emacs compares mouse events, you will occasionally wait twice
29410 that time before the window gets selected.\)
29411 Any other value means to autoselect window instantaneously when the
29412 mouse pointer enters it.
29413
29414 Autoselection selects the minibuffer only if it is active, and never
29415 unselects the minibuffer if it is active.
29416
29417 When customizing this variable make sure that the actual value of
29418 `focus-follows-mouse' matches the behavior of your window manager. */);
29419 Vmouse_autoselect_window = Qnil;
29420
29421 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29422 doc: /* Non-nil means automatically resize tool-bars.
29423 This dynamically changes the tool-bar's height to the minimum height
29424 that is needed to make all tool-bar items visible.
29425 If value is `grow-only', the tool-bar's height is only increased
29426 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29427 Vauto_resize_tool_bars = Qt;
29428
29429 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29430 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29431 auto_raise_tool_bar_buttons_p = 1;
29432
29433 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29434 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29435 make_cursor_line_fully_visible_p = 1;
29436
29437 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29438 doc: /* Border below tool-bar in pixels.
29439 If an integer, use it as the height of the border.
29440 If it is one of `internal-border-width' or `border-width', use the
29441 value of the corresponding frame parameter.
29442 Otherwise, no border is added below the tool-bar. */);
29443 Vtool_bar_border = Qinternal_border_width;
29444
29445 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29446 doc: /* Margin around tool-bar buttons in pixels.
29447 If an integer, use that for both horizontal and vertical margins.
29448 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29449 HORZ specifying the horizontal margin, and VERT specifying the
29450 vertical margin. */);
29451 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29452
29453 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29454 doc: /* Relief thickness of tool-bar buttons. */);
29455 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29456
29457 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29458 doc: /* Tool bar style to use.
29459 It can be one of
29460 image - show images only
29461 text - show text only
29462 both - show both, text below image
29463 both-horiz - show text to the right of the image
29464 text-image-horiz - show text to the left of the image
29465 any other - use system default or image if no system default.
29466
29467 This variable only affects the GTK+ toolkit version of Emacs. */);
29468 Vtool_bar_style = Qnil;
29469
29470 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29471 doc: /* Maximum number of characters a label can have to be shown.
29472 The tool bar style must also show labels for this to have any effect, see
29473 `tool-bar-style'. */);
29474 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29475
29476 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29477 doc: /* List of functions to call to fontify regions of text.
29478 Each function is called with one argument POS. Functions must
29479 fontify a region starting at POS in the current buffer, and give
29480 fontified regions the property `fontified'. */);
29481 Vfontification_functions = Qnil;
29482 Fmake_variable_buffer_local (Qfontification_functions);
29483
29484 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29485 unibyte_display_via_language_environment,
29486 doc: /* Non-nil means display unibyte text according to language environment.
29487 Specifically, this means that raw bytes in the range 160-255 decimal
29488 are displayed by converting them to the equivalent multibyte characters
29489 according to the current language environment. As a result, they are
29490 displayed according to the current fontset.
29491
29492 Note that this variable affects only how these bytes are displayed,
29493 but does not change the fact they are interpreted as raw bytes. */);
29494 unibyte_display_via_language_environment = 0;
29495
29496 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29497 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29498 If a float, it specifies a fraction of the mini-window frame's height.
29499 If an integer, it specifies a number of lines. */);
29500 Vmax_mini_window_height = make_float (0.25);
29501
29502 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29503 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29504 A value of nil means don't automatically resize mini-windows.
29505 A value of t means resize them to fit the text displayed in them.
29506 A value of `grow-only', the default, means let mini-windows grow only;
29507 they return to their normal size when the minibuffer is closed, or the
29508 echo area becomes empty. */);
29509 Vresize_mini_windows = Qgrow_only;
29510
29511 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29512 doc: /* Alist specifying how to blink the cursor off.
29513 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29514 `cursor-type' frame-parameter or variable equals ON-STATE,
29515 comparing using `equal', Emacs uses OFF-STATE to specify
29516 how to blink it off. ON-STATE and OFF-STATE are values for
29517 the `cursor-type' frame parameter.
29518
29519 If a frame's ON-STATE has no entry in this list,
29520 the frame's other specifications determine how to blink the cursor off. */);
29521 Vblink_cursor_alist = Qnil;
29522
29523 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29524 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29525 If non-nil, windows are automatically scrolled horizontally to make
29526 point visible. */);
29527 automatic_hscrolling_p = 1;
29528 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29529
29530 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29531 doc: /* How many columns away from the window edge point is allowed to get
29532 before automatic hscrolling will horizontally scroll the window. */);
29533 hscroll_margin = 5;
29534
29535 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29536 doc: /* How many columns to scroll the window when point gets too close to the edge.
29537 When point is less than `hscroll-margin' columns from the window
29538 edge, automatic hscrolling will scroll the window by the amount of columns
29539 determined by this variable. If its value is a positive integer, scroll that
29540 many columns. If it's a positive floating-point number, it specifies the
29541 fraction of the window's width to scroll. If it's nil or zero, point will be
29542 centered horizontally after the scroll. Any other value, including negative
29543 numbers, are treated as if the value were zero.
29544
29545 Automatic hscrolling always moves point outside the scroll margin, so if
29546 point was more than scroll step columns inside the margin, the window will
29547 scroll more than the value given by the scroll step.
29548
29549 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29550 and `scroll-right' overrides this variable's effect. */);
29551 Vhscroll_step = make_number (0);
29552
29553 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29554 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29555 Bind this around calls to `message' to let it take effect. */);
29556 message_truncate_lines = 0;
29557
29558 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29559 doc: /* Normal hook run to update the menu bar definitions.
29560 Redisplay runs this hook before it redisplays the menu bar.
29561 This is used to update submenus such as Buffers,
29562 whose contents depend on various data. */);
29563 Vmenu_bar_update_hook = Qnil;
29564
29565 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29566 doc: /* Frame for which we are updating a menu.
29567 The enable predicate for a menu binding should check this variable. */);
29568 Vmenu_updating_frame = Qnil;
29569
29570 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29571 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29572 inhibit_menubar_update = 0;
29573
29574 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29575 doc: /* Prefix prepended to all continuation lines at display time.
29576 The value may be a string, an image, or a stretch-glyph; it is
29577 interpreted in the same way as the value of a `display' text property.
29578
29579 This variable is overridden by any `wrap-prefix' text or overlay
29580 property.
29581
29582 To add a prefix to non-continuation lines, use `line-prefix'. */);
29583 Vwrap_prefix = Qnil;
29584 DEFSYM (Qwrap_prefix, "wrap-prefix");
29585 Fmake_variable_buffer_local (Qwrap_prefix);
29586
29587 DEFVAR_LISP ("line-prefix", Vline_prefix,
29588 doc: /* Prefix prepended to all non-continuation lines at display time.
29589 The value may be a string, an image, or a stretch-glyph; it is
29590 interpreted in the same way as the value of a `display' text property.
29591
29592 This variable is overridden by any `line-prefix' text or overlay
29593 property.
29594
29595 To add a prefix to continuation lines, use `wrap-prefix'. */);
29596 Vline_prefix = Qnil;
29597 DEFSYM (Qline_prefix, "line-prefix");
29598 Fmake_variable_buffer_local (Qline_prefix);
29599
29600 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29601 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29602 inhibit_eval_during_redisplay = 0;
29603
29604 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29605 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29606 inhibit_free_realized_faces = 0;
29607
29608 #ifdef GLYPH_DEBUG
29609 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29610 doc: /* Inhibit try_window_id display optimization. */);
29611 inhibit_try_window_id = 0;
29612
29613 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29614 doc: /* Inhibit try_window_reusing display optimization. */);
29615 inhibit_try_window_reusing = 0;
29616
29617 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29618 doc: /* Inhibit try_cursor_movement display optimization. */);
29619 inhibit_try_cursor_movement = 0;
29620 #endif /* GLYPH_DEBUG */
29621
29622 DEFVAR_INT ("overline-margin", overline_margin,
29623 doc: /* Space between overline and text, in pixels.
29624 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29625 margin to the character height. */);
29626 overline_margin = 2;
29627
29628 DEFVAR_INT ("underline-minimum-offset",
29629 underline_minimum_offset,
29630 doc: /* Minimum distance between baseline and underline.
29631 This can improve legibility of underlined text at small font sizes,
29632 particularly when using variable `x-use-underline-position-properties'
29633 with fonts that specify an UNDERLINE_POSITION relatively close to the
29634 baseline. The default value is 1. */);
29635 underline_minimum_offset = 1;
29636
29637 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29638 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29639 This feature only works when on a window system that can change
29640 cursor shapes. */);
29641 display_hourglass_p = 1;
29642
29643 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29644 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29645 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29646
29647 #ifdef HAVE_WINDOW_SYSTEM
29648 hourglass_atimer = NULL;
29649 hourglass_shown_p = 0;
29650 #endif /* HAVE_WINDOW_SYSTEM */
29651
29652 DEFSYM (Qglyphless_char, "glyphless-char");
29653 DEFSYM (Qhex_code, "hex-code");
29654 DEFSYM (Qempty_box, "empty-box");
29655 DEFSYM (Qthin_space, "thin-space");
29656 DEFSYM (Qzero_width, "zero-width");
29657
29658 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29659 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29660
29661 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29662 doc: /* Char-table defining glyphless characters.
29663 Each element, if non-nil, should be one of the following:
29664 an ASCII acronym string: display this string in a box
29665 `hex-code': display the hexadecimal code of a character in a box
29666 `empty-box': display as an empty box
29667 `thin-space': display as 1-pixel width space
29668 `zero-width': don't display
29669 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29670 display method for graphical terminals and text terminals respectively.
29671 GRAPHICAL and TEXT should each have one of the values listed above.
29672
29673 The char-table has one extra slot to control the display of a character for
29674 which no font is found. This slot only takes effect on graphical terminals.
29675 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29676 `thin-space'. The default is `empty-box'. */);
29677 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29678 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29679 Qempty_box);
29680
29681 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29682 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29683 Vdebug_on_message = Qnil;
29684 }
29685
29686
29687 /* Initialize this module when Emacs starts. */
29688
29689 void
29690 init_xdisp (void)
29691 {
29692 CHARPOS (this_line_start_pos) = 0;
29693
29694 if (!noninteractive)
29695 {
29696 struct window *m = XWINDOW (minibuf_window);
29697 Lisp_Object frame = m->frame;
29698 struct frame *f = XFRAME (frame);
29699 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29700 struct window *r = XWINDOW (root);
29701 int i;
29702
29703 echo_area_window = minibuf_window;
29704
29705 r->top_line = FRAME_TOP_MARGIN (f);
29706 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29707 r->total_cols = FRAME_COLS (f);
29708
29709 m->top_line = FRAME_LINES (f) - 1;
29710 m->total_lines = 1;
29711 m->total_cols = FRAME_COLS (f);
29712
29713 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29714 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29715 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29716
29717 /* The default ellipsis glyphs `...'. */
29718 for (i = 0; i < 3; ++i)
29719 default_invis_vector[i] = make_number ('.');
29720 }
29721
29722 {
29723 /* Allocate the buffer for frame titles.
29724 Also used for `format-mode-line'. */
29725 int size = 100;
29726 mode_line_noprop_buf = xmalloc (size);
29727 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29728 mode_line_noprop_ptr = mode_line_noprop_buf;
29729 mode_line_target = MODE_LINE_DISPLAY;
29730 }
29731
29732 help_echo_showing_p = 0;
29733 }
29734
29735 #ifdef HAVE_WINDOW_SYSTEM
29736
29737 /* Platform-independent portion of hourglass implementation. */
29738
29739 /* Cancel a currently active hourglass timer, and start a new one. */
29740 void
29741 start_hourglass (void)
29742 {
29743 struct timespec delay;
29744
29745 cancel_hourglass ();
29746
29747 if (INTEGERP (Vhourglass_delay)
29748 && XINT (Vhourglass_delay) > 0)
29749 delay = make_timespec (min (XINT (Vhourglass_delay),
29750 TYPE_MAXIMUM (time_t)),
29751 0);
29752 else if (FLOATP (Vhourglass_delay)
29753 && XFLOAT_DATA (Vhourglass_delay) > 0)
29754 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
29755 else
29756 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
29757
29758 #ifdef HAVE_NTGUI
29759 {
29760 extern void w32_note_current_window (void);
29761 w32_note_current_window ();
29762 }
29763 #endif /* HAVE_NTGUI */
29764
29765 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29766 show_hourglass, NULL);
29767 }
29768
29769
29770 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29771 shown. */
29772 void
29773 cancel_hourglass (void)
29774 {
29775 if (hourglass_atimer)
29776 {
29777 cancel_atimer (hourglass_atimer);
29778 hourglass_atimer = NULL;
29779 }
29780
29781 if (hourglass_shown_p)
29782 hide_hourglass ();
29783 }
29784
29785 #endif /* HAVE_WINDOW_SYSTEM */