Refine redisplay optimizations to only redisplay *some* frames/windows
[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, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
21
22 Redisplay.
23
24 Emacs separates the task of updating the display from code
25 modifying global state, e.g. buffer text. This way functions
26 operating on buffers don't also have to be concerned with updating
27 the display.
28
29 Updating the display is triggered by the Lisp interpreter when it
30 decides it's time to do it. This is done either automatically for
31 you as part of the interpreter's command loop or as the result of
32 calling Lisp functions like `sit-for'. The C function `redisplay'
33 in xdisp.c is the only entry into the inner redisplay code.
34
35 The following diagram shows how redisplay code is invoked. As you
36 can see, Lisp calls redisplay and vice versa. Under window systems
37 like X, some portions of the redisplay code are also called
38 asynchronously during mouse movement or expose events. It is very
39 important that these code parts do NOT use the C library (malloc,
40 free) because many C libraries under Unix are not reentrant. They
41 may also NOT call functions of the Lisp interpreter which could
42 change the interpreter's state. If you don't follow these rules,
43 you will encounter bugs which are very hard to explain.
44
45 +--------------+ redisplay +----------------+
46 | Lisp machine |---------------->| Redisplay code |<--+
47 +--------------+ (xdisp.c) +----------------+ |
48 ^ | |
49 +----------------------------------+ |
50 Don't use this path when called |
51 asynchronously! |
52 |
53 expose_window (asynchronous) |
54 |
55 X expose events -----+
56
57 What does redisplay do? Obviously, it has to figure out somehow what
58 has been changed since the last time the display has been updated,
59 and to make these changes visible. Preferably it would do that in
60 a moderately intelligent way, i.e. fast.
61
62 Changes in buffer text can be deduced from window and buffer
63 structures, and from some global variables like `beg_unchanged' and
64 `end_unchanged'. The contents of the display are additionally
65 recorded in a `glyph matrix', a two-dimensional matrix of glyph
66 structures. Each row in such a matrix corresponds to a line on the
67 display, and each glyph in a row corresponds to a column displaying
68 a character, an image, or what else. This matrix is called the
69 `current glyph matrix' or `current matrix' in redisplay
70 terminology.
71
72 For buffer parts that have been changed since the last update, a
73 second glyph matrix is constructed, the so called `desired glyph
74 matrix' or short `desired matrix'. Current and desired matrix are
75 then compared to find a cheap way to update the display, e.g. by
76 reusing part of the display by scrolling lines.
77
78 You will find a lot of redisplay optimizations when you start
79 looking at the innards of redisplay. The overall goal of all these
80 optimizations is to make redisplay fast because it is done
81 frequently. Some of these optimizations are implemented by the
82 following functions:
83
84 . try_cursor_movement
85
86 This function tries to update the display if the text in the
87 window did not change and did not scroll, only point moved, and
88 it did not move off the displayed portion of the text.
89
90 . try_window_reusing_current_matrix
91
92 This function reuses the current matrix of a window when text
93 has not changed, but the window start changed (e.g., due to
94 scrolling).
95
96 . try_window_id
97
98 This function attempts to redisplay a window by reusing parts of
99 its existing display. It finds and reuses the part that was not
100 changed, and redraws the rest.
101
102 . try_window
103
104 This function performs the full redisplay of a single window
105 assuming that its fonts were not changed and that the cursor
106 will not end up in the scroll margins. (Loading fonts requires
107 re-adjustment of dimensions of glyph matrices, which makes this
108 method impossible to use.)
109
110 These optimizations are tried in sequence (some can be skipped if
111 it is known that they are not applicable). If none of the
112 optimizations were successful, redisplay calls redisplay_windows,
113 which performs a full redisplay of all windows.
114
115 Desired matrices.
116
117 Desired matrices are always built per Emacs window. The function
118 `display_line' is the central function to look at if you are
119 interested. It constructs one row in a desired matrix given an
120 iterator structure containing both a buffer position and a
121 description of the environment in which the text is to be
122 displayed. But this is too early, read on.
123
124 Characters and pixmaps displayed for a range of buffer text depend
125 on various settings of buffers and windows, on overlays and text
126 properties, on display tables, on selective display. The good news
127 is that all this hairy stuff is hidden behind a small set of
128 interface functions taking an iterator structure (struct it)
129 argument.
130
131 Iteration over things to be displayed is then simple. It is
132 started by initializing an iterator with a call to init_iterator,
133 passing it the buffer position where to start iteration. For
134 iteration over strings, pass -1 as the position to init_iterator,
135 and call reseat_to_string when the string is ready, to initialize
136 the iterator for that string. Thereafter, calls to
137 get_next_display_element fill the iterator structure with relevant
138 information about the next thing to display. Calls to
139 set_iterator_to_next move the iterator to the next thing.
140
141 Besides this, an iterator also contains information about the
142 display environment in which glyphs for display elements are to be
143 produced. It has fields for the width and height of the display,
144 the information whether long lines are truncated or continued, a
145 current X and Y position, and lots of other stuff you can better
146 see in dispextern.h.
147
148 Glyphs in a desired matrix are normally constructed in a loop
149 calling get_next_display_element and then PRODUCE_GLYPHS. The call
150 to PRODUCE_GLYPHS will fill the iterator structure with pixel
151 information about the element being displayed and at the same time
152 produce glyphs for it. If the display element fits on the line
153 being displayed, set_iterator_to_next is called next, otherwise the
154 glyphs produced are discarded. The function display_line is the
155 workhorse of filling glyph rows in the desired matrix with glyphs.
156 In addition to producing glyphs, it also handles line truncation
157 and continuation, word wrap, and cursor positioning (for the
158 latter, see also set_cursor_from_row).
159
160 Frame matrices.
161
162 That just couldn't be all, could it? What about terminal types not
163 supporting operations on sub-windows of the screen? To update the
164 display on such a terminal, window-based glyph matrices are not
165 well suited. To be able to reuse part of the display (scrolling
166 lines up and down), we must instead have a view of the whole
167 screen. This is what `frame matrices' are for. They are a trick.
168
169 Frames on terminals like above have a glyph pool. Windows on such
170 a frame sub-allocate their glyph memory from their frame's glyph
171 pool. The frame itself is given its own glyph matrices. By
172 coincidence---or maybe something else---rows in window glyph
173 matrices are slices of corresponding rows in frame matrices. Thus
174 writing to window matrices implicitly updates a frame matrix which
175 provides us with the view of the whole screen that we originally
176 wanted to have without having to move many bytes around. To be
177 honest, there is a little bit more done, but not much more. If you
178 plan to extend that code, take a look at dispnew.c. The function
179 build_frame_matrix is a good starting point.
180
181 Bidirectional display.
182
183 Bidirectional display adds quite some hair to this already complex
184 design. The good news are that a large portion of that hairy stuff
185 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
186 reordering engine which is called by set_iterator_to_next and
187 returns the next character to display in the visual order. See
188 commentary on bidi.c for more details. As far as redisplay is
189 concerned, the effect of calling bidi_move_to_visually_next, the
190 main interface of the reordering engine, is that the iterator gets
191 magically placed on the buffer or string position that is to be
192 displayed next. In other words, a linear iteration through the
193 buffer/string is replaced with a non-linear one. All the rest of
194 the redisplay is oblivious to the bidi reordering.
195
196 Well, almost oblivious---there are still complications, most of
197 them due to the fact that buffer and string positions no longer
198 change monotonously with glyph indices in a glyph row. Moreover,
199 for continued lines, the buffer positions may not even be
200 monotonously changing with vertical positions. Also, accounting
201 for face changes, overlays, etc. becomes more complex because
202 non-linear iteration could potentially skip many positions with
203 changes, and then cross them again on the way back...
204
205 One other prominent effect of bidirectional display is that some
206 paragraphs of text need to be displayed starting at the right
207 margin of the window---the so-called right-to-left, or R2L
208 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
209 which have their reversed_p flag set. The bidi reordering engine
210 produces characters in such rows starting from the character which
211 should be the rightmost on display. PRODUCE_GLYPHS then reverses
212 the order, when it fills up the glyph row whose reversed_p flag is
213 set, by prepending each new glyph to what is already there, instead
214 of appending it. When the glyph row is complete, the function
215 extend_face_to_end_of_line fills the empty space to the left of the
216 leftmost character with special glyphs, which will display as,
217 well, empty. On text terminals, these special glyphs are simply
218 blank characters. On graphics terminals, there's a single stretch
219 glyph of a suitably computed width. Both the blanks and the
220 stretch glyph are given the face of the background of the line.
221 This way, the terminal-specific back-end can still draw the glyphs
222 left to right, even for R2L lines.
223
224 Bidirectional display and character compositions
225
226 Some scripts cannot be displayed by drawing each character
227 individually, because adjacent characters change each other's shape
228 on display. For example, Arabic and Indic scripts belong to this
229 category.
230
231 Emacs display supports this by providing "character compositions",
232 most of which is implemented in composite.c. During the buffer
233 scan that delivers characters to PRODUCE_GLYPHS, if the next
234 character to be delivered is a composed character, the iteration
235 calls composition_reseat_it and next_element_from_composition. If
236 they succeed to compose the character with one or more of the
237 following characters, the whole sequence of characters that where
238 composed is recorded in the `struct composition_it' object that is
239 part of the buffer iterator. The composed sequence could produce
240 one or more font glyphs (called "grapheme clusters") on the screen.
241 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
242 in the direction corresponding to the current bidi scan direction
243 (recorded in the scan_dir member of the `struct bidi_it' object
244 that is part of the buffer iterator). In particular, if the bidi
245 iterator currently scans the buffer backwards, the grapheme
246 clusters are delivered back to front. This reorders the grapheme
247 clusters as appropriate for the current bidi context. Note that
248 this means that the grapheme clusters are always stored in the
249 LGSTRING object (see composite.c) in the logical order.
250
251 Moving an iterator in bidirectional text
252 without producing glyphs
253
254 Note one important detail mentioned above: that the bidi reordering
255 engine, driven by the iterator, produces characters in R2L rows
256 starting at the character that will be the rightmost on display.
257 As far as the iterator is concerned, the geometry of such rows is
258 still left to right, i.e. the iterator "thinks" the first character
259 is at the leftmost pixel position. The iterator does not know that
260 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
261 delivers. This is important when functions from the move_it_*
262 family are used to get to certain screen position or to match
263 screen coordinates with buffer coordinates: these functions use the
264 iterator geometry, which is left to right even in R2L paragraphs.
265 This works well with most callers of move_it_*, because they need
266 to get to a specific column, and columns are still numbered in the
267 reading order, i.e. the rightmost character in a R2L paragraph is
268 still column zero. But some callers do not get well with this; a
269 notable example is mouse clicks that need to find the character
270 that corresponds to certain pixel coordinates. See
271 buffer_posn_from_coords in dispnew.c for how this is handled. */
272
273 #include <config.h>
274 #include <stdio.h>
275 #include <limits.h>
276
277 #include "lisp.h"
278 #include "atimer.h"
279 #include "keyboard.h"
280 #include "frame.h"
281 #include "window.h"
282 #include "termchar.h"
283 #include "dispextern.h"
284 #include "character.h"
285 #include "buffer.h"
286 #include "charset.h"
287 #include "indent.h"
288 #include "commands.h"
289 #include "keymap.h"
290 #include "macros.h"
291 #include "disptab.h"
292 #include "termhooks.h"
293 #include "termopts.h"
294 #include "intervals.h"
295 #include "coding.h"
296 #include "process.h"
297 #include "region-cache.h"
298 #include "font.h"
299 #include "fontset.h"
300 #include "blockinput.h"
301 #ifdef HAVE_WINDOW_SYSTEM
302 #include TERM_HEADER
303 #endif /* HAVE_WINDOW_SYSTEM */
304
305 #ifndef FRAME_X_OUTPUT
306 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
307 #endif
308
309 #define INFINITY 10000000
310
311 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
312 Lisp_Object Qwindow_scroll_functions;
313 static Lisp_Object Qwindow_text_change_functions;
314 static Lisp_Object Qredisplay_end_trigger_functions;
315 Lisp_Object Qinhibit_point_motion_hooks;
316 static Lisp_Object QCeval, QCpropertize;
317 Lisp_Object QCfile, QCdata;
318 static Lisp_Object Qfontified;
319 static Lisp_Object Qgrow_only;
320 static Lisp_Object Qinhibit_eval_during_redisplay;
321 static Lisp_Object Qbuffer_position, Qposition, Qobject;
322 static Lisp_Object Qright_to_left, Qleft_to_right;
323
324 /* Cursor shapes. */
325 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
326
327 /* Pointer shapes. */
328 static Lisp_Object Qarrow, Qhand;
329 Lisp_Object Qtext;
330
331 /* Holds the list (error). */
332 static Lisp_Object list_of_error;
333
334 static Lisp_Object Qfontification_functions;
335
336 static Lisp_Object Qwrap_prefix;
337 static Lisp_Object Qline_prefix;
338 static Lisp_Object Qredisplay_internal;
339
340 /* Non-nil means don't actually do any redisplay. */
341
342 Lisp_Object Qinhibit_redisplay;
343
344 /* Names of text properties relevant for redisplay. */
345
346 Lisp_Object Qdisplay;
347
348 Lisp_Object Qspace, QCalign_to;
349 static Lisp_Object QCrelative_width, QCrelative_height;
350 Lisp_Object Qleft_margin, Qright_margin;
351 static Lisp_Object Qspace_width, Qraise;
352 static Lisp_Object Qslice;
353 Lisp_Object Qcenter;
354 static Lisp_Object Qmargin, Qpointer;
355 static Lisp_Object Qline_height;
356
357 #ifdef HAVE_WINDOW_SYSTEM
358
359 /* Test if overflow newline into fringe. Called with iterator IT
360 at or past right window margin, and with IT->current_x set. */
361
362 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
363 (!NILP (Voverflow_newline_into_fringe) \
364 && FRAME_WINDOW_P ((IT)->f) \
365 && ((IT)->bidi_it.paragraph_dir == R2L \
366 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
367 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
368 && (IT)->current_x == (IT)->last_visible_x)
369
370 #else /* !HAVE_WINDOW_SYSTEM */
371 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
372 #endif /* HAVE_WINDOW_SYSTEM */
373
374 /* Test if the display element loaded in IT, or the underlying buffer
375 or string character, is a space or a TAB character. This is used
376 to determine where word wrapping can occur. */
377
378 #define IT_DISPLAYING_WHITESPACE(it) \
379 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
380 || ((STRINGP (it->string) \
381 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
382 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
383 || (it->s \
384 && (it->s[IT_BYTEPOS (*it)] == ' ' \
385 || it->s[IT_BYTEPOS (*it)] == '\t')) \
386 || (IT_BYTEPOS (*it) < ZV_BYTE \
387 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
388 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
389
390 /* Name of the face used to highlight trailing whitespace. */
391
392 static Lisp_Object Qtrailing_whitespace;
393
394 /* Name and number of the face used to highlight escape glyphs. */
395
396 static Lisp_Object Qescape_glyph;
397
398 /* Name and number of the face used to highlight non-breaking spaces. */
399
400 static Lisp_Object Qnobreak_space;
401
402 /* The symbol `image' which is the car of the lists used to represent
403 images in Lisp. Also a tool bar style. */
404
405 Lisp_Object Qimage;
406
407 /* The image map types. */
408 Lisp_Object QCmap;
409 static Lisp_Object QCpointer;
410 static Lisp_Object Qrect, Qcircle, Qpoly;
411
412 /* Tool bar styles */
413 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
414
415 /* Non-zero means print newline to stdout before next mini-buffer
416 message. */
417
418 bool noninteractive_need_newline;
419
420 /* Non-zero means print newline to message log before next message. */
421
422 static bool message_log_need_newline;
423
424 /* Three markers that message_dolog uses.
425 It could allocate them itself, but that causes trouble
426 in handling memory-full errors. */
427 static Lisp_Object message_dolog_marker1;
428 static Lisp_Object message_dolog_marker2;
429 static Lisp_Object message_dolog_marker3;
430 \f
431 /* The buffer position of the first character appearing entirely or
432 partially on the line of the selected window which contains the
433 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
434 redisplay optimization in redisplay_internal. */
435
436 static struct text_pos this_line_start_pos;
437
438 /* Number of characters past the end of the line above, including the
439 terminating newline. */
440
441 static struct text_pos this_line_end_pos;
442
443 /* The vertical positions and the height of this line. */
444
445 static int this_line_vpos;
446 static int this_line_y;
447 static int this_line_pixel_height;
448
449 /* X position at which this display line starts. Usually zero;
450 negative if first character is partially visible. */
451
452 static int this_line_start_x;
453
454 /* The smallest character position seen by move_it_* functions as they
455 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
456 hscrolled lines, see display_line. */
457
458 static struct text_pos this_line_min_pos;
459
460 /* Buffer that this_line_.* variables are referring to. */
461
462 static struct buffer *this_line_buffer;
463
464
465 /* Values of those variables at last redisplay are stored as
466 properties on `overlay-arrow-position' symbol. However, if
467 Voverlay_arrow_position is a marker, last-arrow-position is its
468 numerical position. */
469
470 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
471
472 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
473 properties on a symbol in overlay-arrow-variable-list. */
474
475 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
476
477 Lisp_Object Qmenu_bar_update_hook;
478
479 /* Nonzero if an overlay arrow has been displayed in this window. */
480
481 static bool overlay_arrow_seen;
482
483 /* Vector containing glyphs for an ellipsis `...'. */
484
485 static Lisp_Object default_invis_vector[3];
486
487 /* This is the window where the echo area message was displayed. It
488 is always a mini-buffer window, but it may not be the same window
489 currently active as a mini-buffer. */
490
491 Lisp_Object echo_area_window;
492
493 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
494 pushes the current message and the value of
495 message_enable_multibyte on the stack, the function restore_message
496 pops the stack and displays MESSAGE again. */
497
498 static Lisp_Object Vmessage_stack;
499
500 /* Nonzero means multibyte characters were enabled when the echo area
501 message was specified. */
502
503 static bool message_enable_multibyte;
504
505 /* Nonzero if we should redraw the mode lines on the next redisplay.
506 If it has value REDISPLAY_SOME, then only redisplay the mode lines where
507 the `redisplay' bit has been set. Otherwise, redisplay all mode lines
508 (the number used is then only used to track down the cause for this
509 full-redisplay). */
510
511 int update_mode_lines;
512
513 /* Nonzero if window sizes or contents other than selected-window have changed
514 since last redisplay that finished.
515 If it has value REDISPLAY_SOME, then only redisplay the windows where
516 the `redisplay' bit has been set. Otherwise, redisplay all windows
517 (the number used is then only used to track down the cause for this
518 full-redisplay). */
519
520 int windows_or_buffers_changed;
521
522 /* Nonzero after display_mode_line if %l was used and it displayed a
523 line number. */
524
525 static bool line_number_displayed;
526
527 /* The name of the *Messages* buffer, a string. */
528
529 static Lisp_Object Vmessages_buffer_name;
530
531 /* Current, index 0, and last displayed echo area message. Either
532 buffers from echo_buffers, or nil to indicate no message. */
533
534 Lisp_Object echo_area_buffer[2];
535
536 /* The buffers referenced from echo_area_buffer. */
537
538 static Lisp_Object echo_buffer[2];
539
540 /* A vector saved used in with_area_buffer to reduce consing. */
541
542 static Lisp_Object Vwith_echo_area_save_vector;
543
544 /* Non-zero means display_echo_area should display the last echo area
545 message again. Set by redisplay_preserve_echo_area. */
546
547 static bool display_last_displayed_message_p;
548
549 /* Nonzero if echo area is being used by print; zero if being used by
550 message. */
551
552 static bool message_buf_print;
553
554 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
555
556 static Lisp_Object Qinhibit_menubar_update;
557 static Lisp_Object Qmessage_truncate_lines;
558
559 /* Set to 1 in clear_message to make redisplay_internal aware
560 of an emptied echo area. */
561
562 static bool message_cleared_p;
563
564 /* A scratch glyph row with contents used for generating truncation
565 glyphs. Also used in direct_output_for_insert. */
566
567 #define MAX_SCRATCH_GLYPHS 100
568 static struct glyph_row scratch_glyph_row;
569 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
570
571 /* Ascent and height of the last line processed by move_it_to. */
572
573 static int last_height;
574
575 /* Non-zero if there's a help-echo in the echo area. */
576
577 bool help_echo_showing_p;
578
579 /* The maximum distance to look ahead for text properties. Values
580 that are too small let us call compute_char_face and similar
581 functions too often which is expensive. Values that are too large
582 let us call compute_char_face and alike too often because we
583 might not be interested in text properties that far away. */
584
585 #define TEXT_PROP_DISTANCE_LIMIT 100
586
587 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
588 iterator state and later restore it. This is needed because the
589 bidi iterator on bidi.c keeps a stacked cache of its states, which
590 is really a singleton. When we use scratch iterator objects to
591 move around the buffer, we can cause the bidi cache to be pushed or
592 popped, and therefore we need to restore the cache state when we
593 return to the original iterator. */
594 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
595 do { \
596 if (CACHE) \
597 bidi_unshelve_cache (CACHE, 1); \
598 ITCOPY = ITORIG; \
599 CACHE = bidi_shelve_cache (); \
600 } while (0)
601
602 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
603 do { \
604 if (pITORIG != pITCOPY) \
605 *(pITORIG) = *(pITCOPY); \
606 bidi_unshelve_cache (CACHE, 0); \
607 CACHE = NULL; \
608 } while (0)
609
610 /* Functions to mark elements as needing redisplay. */
611 enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
612
613 void redisplay_other_windows (void)
614 {
615 if (!windows_or_buffers_changed)
616 windows_or_buffers_changed = REDISPLAY_SOME;
617 }
618
619 void wset_redisplay (struct window *w)
620 {
621 redisplay_other_windows ();
622 w->redisplay = true;
623 }
624
625 void fset_redisplay (struct frame *f)
626 {
627 redisplay_other_windows ();
628 f->redisplay = true;
629 }
630
631 void bset_redisplay (struct buffer *b)
632 {
633 int count = buffer_window_count (b);
634 if (count > 0)
635 {
636 /* ... it's visible in other window than selected, */
637 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
638 redisplay_other_windows ();
639 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
640 so that if we later set windows_or_buffers_changed, this buffer will
641 not be omitted. */
642 b->text->redisplay = true;
643 }
644 }
645
646 extern void bset_update_mode_line (struct buffer *b)
647 {
648 if (!update_mode_lines)
649 update_mode_lines = REDISPLAY_SOME;
650 b->text->redisplay = true;
651 }
652
653 #ifdef GLYPH_DEBUG
654
655 /* Non-zero means print traces of redisplay if compiled with
656 GLYPH_DEBUG defined. */
657
658 int trace_redisplay_p;
659
660 #endif /* GLYPH_DEBUG */
661
662 #ifdef DEBUG_TRACE_MOVE
663 /* Non-zero means trace with TRACE_MOVE to stderr. */
664 int trace_move;
665
666 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
667 #else
668 #define TRACE_MOVE(x) (void) 0
669 #endif
670
671 static Lisp_Object Qauto_hscroll_mode;
672
673 /* Buffer being redisplayed -- for redisplay_window_error. */
674
675 static struct buffer *displayed_buffer;
676
677 /* Value returned from text property handlers (see below). */
678
679 enum prop_handled
680 {
681 HANDLED_NORMALLY,
682 HANDLED_RECOMPUTE_PROPS,
683 HANDLED_OVERLAY_STRING_CONSUMED,
684 HANDLED_RETURN
685 };
686
687 /* A description of text properties that redisplay is interested
688 in. */
689
690 struct props
691 {
692 /* The name of the property. */
693 Lisp_Object *name;
694
695 /* A unique index for the property. */
696 enum prop_idx idx;
697
698 /* A handler function called to set up iterator IT from the property
699 at IT's current position. Value is used to steer handle_stop. */
700 enum prop_handled (*handler) (struct it *it);
701 };
702
703 static enum prop_handled handle_face_prop (struct it *);
704 static enum prop_handled handle_invisible_prop (struct it *);
705 static enum prop_handled handle_display_prop (struct it *);
706 static enum prop_handled handle_composition_prop (struct it *);
707 static enum prop_handled handle_overlay_change (struct it *);
708 static enum prop_handled handle_fontified_prop (struct it *);
709
710 /* Properties handled by iterators. */
711
712 static struct props it_props[] =
713 {
714 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
715 /* Handle `face' before `display' because some sub-properties of
716 `display' need to know the face. */
717 {&Qface, FACE_PROP_IDX, handle_face_prop},
718 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
719 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
720 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
721 {NULL, 0, NULL}
722 };
723
724 /* Value is the position described by X. If X is a marker, value is
725 the marker_position of X. Otherwise, value is X. */
726
727 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
728
729 /* Enumeration returned by some move_it_.* functions internally. */
730
731 enum move_it_result
732 {
733 /* Not used. Undefined value. */
734 MOVE_UNDEFINED,
735
736 /* Move ended at the requested buffer position or ZV. */
737 MOVE_POS_MATCH_OR_ZV,
738
739 /* Move ended at the requested X pixel position. */
740 MOVE_X_REACHED,
741
742 /* Move within a line ended at the end of a line that must be
743 continued. */
744 MOVE_LINE_CONTINUED,
745
746 /* Move within a line ended at the end of a line that would
747 be displayed truncated. */
748 MOVE_LINE_TRUNCATED,
749
750 /* Move within a line ended at a line end. */
751 MOVE_NEWLINE_OR_CR
752 };
753
754 /* This counter is used to clear the face cache every once in a while
755 in redisplay_internal. It is incremented for each redisplay.
756 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
757 cleared. */
758
759 #define CLEAR_FACE_CACHE_COUNT 500
760 static int clear_face_cache_count;
761
762 /* Similarly for the image cache. */
763
764 #ifdef HAVE_WINDOW_SYSTEM
765 #define CLEAR_IMAGE_CACHE_COUNT 101
766 static int clear_image_cache_count;
767
768 /* Null glyph slice */
769 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
770 #endif
771
772 /* True while redisplay_internal is in progress. */
773
774 bool redisplaying_p;
775
776 static Lisp_Object Qinhibit_free_realized_faces;
777 static Lisp_Object Qmode_line_default_help_echo;
778
779 /* If a string, XTread_socket generates an event to display that string.
780 (The display is done in read_char.) */
781
782 Lisp_Object help_echo_string;
783 Lisp_Object help_echo_window;
784 Lisp_Object help_echo_object;
785 ptrdiff_t help_echo_pos;
786
787 /* Temporary variable for XTread_socket. */
788
789 Lisp_Object previous_help_echo_string;
790
791 /* Platform-independent portion of hourglass implementation. */
792
793 #ifdef HAVE_WINDOW_SYSTEM
794
795 /* Non-zero means an hourglass cursor is currently shown. */
796 bool hourglass_shown_p;
797
798 /* If non-null, an asynchronous timer that, when it expires, displays
799 an hourglass cursor on all frames. */
800 struct atimer *hourglass_atimer;
801
802 #endif /* HAVE_WINDOW_SYSTEM */
803
804 /* Name of the face used to display glyphless characters. */
805 static Lisp_Object Qglyphless_char;
806
807 /* Symbol for the purpose of Vglyphless_char_display. */
808 static Lisp_Object Qglyphless_char_display;
809
810 /* Method symbols for Vglyphless_char_display. */
811 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
812
813 /* Default number of seconds to wait before displaying an hourglass
814 cursor. */
815 #define DEFAULT_HOURGLASS_DELAY 1
816
817 #ifdef HAVE_WINDOW_SYSTEM
818
819 /* Default pixel width of `thin-space' display method. */
820 #define THIN_SPACE_WIDTH 1
821
822 #endif /* HAVE_WINDOW_SYSTEM */
823
824 /* Function prototypes. */
825
826 static void setup_for_ellipsis (struct it *, int);
827 static void set_iterator_to_next (struct it *, int);
828 static void mark_window_display_accurate_1 (struct window *, int);
829 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
830 static int display_prop_string_p (Lisp_Object, Lisp_Object);
831 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
832 static int cursor_row_p (struct glyph_row *);
833 static int redisplay_mode_lines (Lisp_Object, int);
834 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
835
836 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
837
838 static void handle_line_prefix (struct it *);
839
840 static void pint2str (char *, int, ptrdiff_t);
841 static void pint2hrstr (char *, int, ptrdiff_t);
842 static struct text_pos run_window_scroll_functions (Lisp_Object,
843 struct text_pos);
844 static int text_outside_line_unchanged_p (struct window *,
845 ptrdiff_t, ptrdiff_t);
846 static void store_mode_line_noprop_char (char);
847 static int store_mode_line_noprop (const char *, int, int);
848 static void handle_stop (struct it *);
849 static void handle_stop_backwards (struct it *, ptrdiff_t);
850 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
851 static void ensure_echo_area_buffers (void);
852 static void unwind_with_echo_area_buffer (Lisp_Object);
853 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
854 static int with_echo_area_buffer (struct window *, int,
855 int (*) (ptrdiff_t, Lisp_Object),
856 ptrdiff_t, Lisp_Object);
857 static void clear_garbaged_frames (void);
858 static int current_message_1 (ptrdiff_t, Lisp_Object);
859 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
860 static void set_message (Lisp_Object);
861 static int set_message_1 (ptrdiff_t, Lisp_Object);
862 static int display_echo_area (struct window *);
863 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
864 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
865 static void unwind_redisplay (void);
866 static int string_char_and_length (const unsigned char *, int *);
867 static struct text_pos display_prop_end (struct it *, Lisp_Object,
868 struct text_pos);
869 static int compute_window_start_on_continuation_line (struct window *);
870 static void insert_left_trunc_glyphs (struct it *);
871 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
872 Lisp_Object);
873 static void extend_face_to_end_of_line (struct it *);
874 static int append_space_for_newline (struct it *, int);
875 static int cursor_row_fully_visible_p (struct window *, int, int);
876 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
877 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
878 static int trailing_whitespace_p (ptrdiff_t);
879 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
880 static void push_it (struct it *, struct text_pos *);
881 static void iterate_out_of_display_property (struct it *);
882 static void pop_it (struct it *);
883 static void sync_frame_with_window_matrix_rows (struct window *);
884 static void redisplay_internal (void);
885 static int echo_area_display (int);
886 static void redisplay_windows (Lisp_Object);
887 static void redisplay_window (Lisp_Object, int);
888 static Lisp_Object redisplay_window_error (Lisp_Object);
889 static Lisp_Object redisplay_window_0 (Lisp_Object);
890 static Lisp_Object redisplay_window_1 (Lisp_Object);
891 static int set_cursor_from_row (struct window *, struct glyph_row *,
892 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
893 int, int);
894 static int update_menu_bar (struct frame *, int, int);
895 static int try_window_reusing_current_matrix (struct window *);
896 static int try_window_id (struct window *);
897 static int display_line (struct it *);
898 static int display_mode_lines (struct window *);
899 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
900 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
901 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
902 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
903 static void display_menu_bar (struct window *);
904 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
905 ptrdiff_t *);
906 static int display_string (const char *, Lisp_Object, Lisp_Object,
907 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
908 static void compute_line_metrics (struct it *);
909 static void run_redisplay_end_trigger_hook (struct it *);
910 static int get_overlay_strings (struct it *, ptrdiff_t);
911 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
912 static void next_overlay_string (struct it *);
913 static void reseat (struct it *, struct text_pos, int);
914 static void reseat_1 (struct it *, struct text_pos, int);
915 static void back_to_previous_visible_line_start (struct it *);
916 static void reseat_at_next_visible_line_start (struct it *, int);
917 static int next_element_from_ellipsis (struct it *);
918 static int next_element_from_display_vector (struct it *);
919 static int next_element_from_string (struct it *);
920 static int next_element_from_c_string (struct it *);
921 static int next_element_from_buffer (struct it *);
922 static int next_element_from_composition (struct it *);
923 static int next_element_from_image (struct it *);
924 static int next_element_from_stretch (struct it *);
925 static void load_overlay_strings (struct it *, ptrdiff_t);
926 static int init_from_display_pos (struct it *, struct window *,
927 struct display_pos *);
928 static void reseat_to_string (struct it *, const char *,
929 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
930 static int get_next_display_element (struct it *);
931 static enum move_it_result
932 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
933 enum move_operation_enum);
934 static void get_visually_first_element (struct it *);
935 static void init_to_row_start (struct it *, struct window *,
936 struct glyph_row *);
937 static int init_to_row_end (struct it *, struct window *,
938 struct glyph_row *);
939 static void back_to_previous_line_start (struct it *);
940 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
941 static struct text_pos string_pos_nchars_ahead (struct text_pos,
942 Lisp_Object, ptrdiff_t);
943 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
944 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
945 static ptrdiff_t number_of_chars (const char *, bool);
946 static void compute_stop_pos (struct it *);
947 static void compute_string_pos (struct text_pos *, struct text_pos,
948 Lisp_Object);
949 static int face_before_or_after_it_pos (struct it *, int);
950 static ptrdiff_t next_overlay_change (ptrdiff_t);
951 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
952 Lisp_Object, struct text_pos *, ptrdiff_t, int);
953 static int handle_single_display_spec (struct it *, Lisp_Object,
954 Lisp_Object, Lisp_Object,
955 struct text_pos *, ptrdiff_t, int, int);
956 static int underlying_face_id (struct it *);
957 static int in_ellipses_for_invisible_text_p (struct display_pos *,
958 struct window *);
959
960 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
961 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
962
963 #ifdef HAVE_WINDOW_SYSTEM
964
965 static void x_consider_frame_title (Lisp_Object);
966 static void update_tool_bar (struct frame *, int);
967 static int redisplay_tool_bar (struct frame *);
968 static void notice_overwritten_cursor (struct window *,
969 enum glyph_row_area,
970 int, int, int, int);
971 static void append_stretch_glyph (struct it *, Lisp_Object,
972 int, int, int);
973
974
975 #endif /* HAVE_WINDOW_SYSTEM */
976
977 static void produce_special_glyphs (struct it *, enum display_element_type);
978 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
979 static int coords_in_mouse_face_p (struct window *, int, int);
980
981
982 \f
983 /***********************************************************************
984 Window display dimensions
985 ***********************************************************************/
986
987 /* Return the bottom boundary y-position for text lines in window W.
988 This is the first y position at which a line cannot start.
989 It is relative to the top of the window.
990
991 This is the height of W minus the height of a mode line, if any. */
992
993 int
994 window_text_bottom_y (struct window *w)
995 {
996 int height = WINDOW_TOTAL_HEIGHT (w);
997
998 if (WINDOW_WANTS_MODELINE_P (w))
999 height -= CURRENT_MODE_LINE_HEIGHT (w);
1000 return height;
1001 }
1002
1003 /* Return the pixel width of display area AREA of window W.
1004 ANY_AREA means return the total width of W, not including
1005 fringes to the left and right of the window. */
1006
1007 int
1008 window_box_width (struct window *w, enum glyph_row_area area)
1009 {
1010 int cols = w->total_cols;
1011 int pixels = 0;
1012
1013 if (!w->pseudo_window_p)
1014 {
1015 cols -= WINDOW_SCROLL_BAR_COLS (w);
1016
1017 if (area == TEXT_AREA)
1018 {
1019 cols -= max (0, w->left_margin_cols);
1020 cols -= max (0, w->right_margin_cols);
1021 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1022 }
1023 else if (area == LEFT_MARGIN_AREA)
1024 {
1025 cols = max (0, w->left_margin_cols);
1026 pixels = 0;
1027 }
1028 else if (area == RIGHT_MARGIN_AREA)
1029 {
1030 cols = max (0, w->right_margin_cols);
1031 pixels = 0;
1032 }
1033 }
1034
1035 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1036 }
1037
1038
1039 /* Return the pixel height of the display area of window W, not
1040 including mode lines of W, if any. */
1041
1042 int
1043 window_box_height (struct window *w)
1044 {
1045 struct frame *f = XFRAME (w->frame);
1046 int height = WINDOW_TOTAL_HEIGHT (w);
1047
1048 eassert (height >= 0);
1049
1050 /* Note: the code below that determines the mode-line/header-line
1051 height is essentially the same as that contained in the macro
1052 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1053 the appropriate glyph row has its `mode_line_p' flag set,
1054 and if it doesn't, uses estimate_mode_line_height instead. */
1055
1056 if (WINDOW_WANTS_MODELINE_P (w))
1057 {
1058 struct glyph_row *ml_row
1059 = (w->current_matrix && w->current_matrix->rows
1060 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1061 : 0);
1062 if (ml_row && ml_row->mode_line_p)
1063 height -= ml_row->height;
1064 else
1065 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1066 }
1067
1068 if (WINDOW_WANTS_HEADER_LINE_P (w))
1069 {
1070 struct glyph_row *hl_row
1071 = (w->current_matrix && w->current_matrix->rows
1072 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1073 : 0);
1074 if (hl_row && hl_row->mode_line_p)
1075 height -= hl_row->height;
1076 else
1077 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1078 }
1079
1080 /* With a very small font and a mode-line that's taller than
1081 default, we might end up with a negative height. */
1082 return max (0, height);
1083 }
1084
1085 /* Return the window-relative coordinate of the left edge of display
1086 area AREA of window W. ANY_AREA means return the left edge of the
1087 whole window, to the right of the left fringe of W. */
1088
1089 int
1090 window_box_left_offset (struct window *w, enum glyph_row_area area)
1091 {
1092 int x;
1093
1094 if (w->pseudo_window_p)
1095 return 0;
1096
1097 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1098
1099 if (area == TEXT_AREA)
1100 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1101 + window_box_width (w, LEFT_MARGIN_AREA));
1102 else if (area == RIGHT_MARGIN_AREA)
1103 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1104 + window_box_width (w, LEFT_MARGIN_AREA)
1105 + window_box_width (w, TEXT_AREA)
1106 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1107 ? 0
1108 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1109 else if (area == LEFT_MARGIN_AREA
1110 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1111 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1112
1113 return x;
1114 }
1115
1116
1117 /* Return the window-relative coordinate of the right edge of display
1118 area AREA of window W. ANY_AREA means return the right edge of the
1119 whole window, to the left of the right fringe of W. */
1120
1121 int
1122 window_box_right_offset (struct window *w, enum glyph_row_area area)
1123 {
1124 return window_box_left_offset (w, area) + window_box_width (w, area);
1125 }
1126
1127 /* Return the frame-relative coordinate of the left edge of display
1128 area AREA of window W. ANY_AREA means return the left edge of the
1129 whole window, to the right of the left fringe of W. */
1130
1131 int
1132 window_box_left (struct window *w, enum glyph_row_area area)
1133 {
1134 struct frame *f = XFRAME (w->frame);
1135 int x;
1136
1137 if (w->pseudo_window_p)
1138 return FRAME_INTERNAL_BORDER_WIDTH (f);
1139
1140 x = (WINDOW_LEFT_EDGE_X (w)
1141 + window_box_left_offset (w, area));
1142
1143 return x;
1144 }
1145
1146
1147 /* Return the frame-relative coordinate of the right edge of display
1148 area AREA of window W. ANY_AREA means return the right edge of the
1149 whole window, to the left of the right fringe of W. */
1150
1151 int
1152 window_box_right (struct window *w, enum glyph_row_area area)
1153 {
1154 return window_box_left (w, area) + window_box_width (w, area);
1155 }
1156
1157 /* Get the bounding box of the display area AREA of window W, without
1158 mode lines, in frame-relative coordinates. ANY_AREA means the
1159 whole window, not including the left and right fringes of
1160 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1161 coordinates of the upper-left corner of the box. Return in
1162 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1163
1164 void
1165 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1166 int *box_y, int *box_width, int *box_height)
1167 {
1168 if (box_width)
1169 *box_width = window_box_width (w, area);
1170 if (box_height)
1171 *box_height = window_box_height (w);
1172 if (box_x)
1173 *box_x = window_box_left (w, area);
1174 if (box_y)
1175 {
1176 *box_y = WINDOW_TOP_EDGE_Y (w);
1177 if (WINDOW_WANTS_HEADER_LINE_P (w))
1178 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1179 }
1180 }
1181
1182 #ifdef HAVE_WINDOW_SYSTEM
1183
1184 /* Get the bounding box of the display area AREA of window W, without
1185 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1186 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1187 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1188 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1189 box. */
1190
1191 static void
1192 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1193 int *bottom_right_x, int *bottom_right_y)
1194 {
1195 window_box (w, ANY_AREA, top_left_x, top_left_y,
1196 bottom_right_x, bottom_right_y);
1197 *bottom_right_x += *top_left_x;
1198 *bottom_right_y += *top_left_y;
1199 }
1200
1201 #endif /* HAVE_WINDOW_SYSTEM */
1202
1203 /***********************************************************************
1204 Utilities
1205 ***********************************************************************/
1206
1207 /* Return the bottom y-position of the line the iterator IT is in.
1208 This can modify IT's settings. */
1209
1210 int
1211 line_bottom_y (struct it *it)
1212 {
1213 int line_height = it->max_ascent + it->max_descent;
1214 int line_top_y = it->current_y;
1215
1216 if (line_height == 0)
1217 {
1218 if (last_height)
1219 line_height = last_height;
1220 else if (IT_CHARPOS (*it) < ZV)
1221 {
1222 move_it_by_lines (it, 1);
1223 line_height = (it->max_ascent || it->max_descent
1224 ? it->max_ascent + it->max_descent
1225 : last_height);
1226 }
1227 else
1228 {
1229 struct glyph_row *row = it->glyph_row;
1230
1231 /* Use the default character height. */
1232 it->glyph_row = NULL;
1233 it->what = IT_CHARACTER;
1234 it->c = ' ';
1235 it->len = 1;
1236 PRODUCE_GLYPHS (it);
1237 line_height = it->ascent + it->descent;
1238 it->glyph_row = row;
1239 }
1240 }
1241
1242 return line_top_y + line_height;
1243 }
1244
1245 DEFUN ("line-pixel-height", Fline_pixel_height,
1246 Sline_pixel_height, 0, 0, 0,
1247 doc: /* Return height in pixels of text line in the selected window.
1248
1249 Value is the height in pixels of the line at point. */)
1250 (void)
1251 {
1252 struct it it;
1253 struct text_pos pt;
1254 struct window *w = XWINDOW (selected_window);
1255
1256 SET_TEXT_POS (pt, PT, PT_BYTE);
1257 start_display (&it, w, pt);
1258 it.vpos = it.current_y = 0;
1259 last_height = 0;
1260 return make_number (line_bottom_y (&it));
1261 }
1262
1263 /* Return the default pixel height of text lines in window W. The
1264 value is the canonical height of the W frame's default font, plus
1265 any extra space required by the line-spacing variable or frame
1266 parameter.
1267
1268 Implementation note: this ignores any line-spacing text properties
1269 put on the newline characters. This is because those properties
1270 only affect the _screen_ line ending in the newline (i.e., in a
1271 continued line, only the last screen line will be affected), which
1272 means only a small number of lines in a buffer can ever use this
1273 feature. Since this function is used to compute the default pixel
1274 equivalent of text lines in a window, we can safely ignore those
1275 few lines. For the same reasons, we ignore the line-height
1276 properties. */
1277 int
1278 default_line_pixel_height (struct window *w)
1279 {
1280 struct frame *f = WINDOW_XFRAME (w);
1281 int height = FRAME_LINE_HEIGHT (f);
1282
1283 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1284 {
1285 struct buffer *b = XBUFFER (w->contents);
1286 Lisp_Object val = BVAR (b, extra_line_spacing);
1287
1288 if (NILP (val))
1289 val = BVAR (&buffer_defaults, extra_line_spacing);
1290 if (!NILP (val))
1291 {
1292 if (RANGED_INTEGERP (0, val, INT_MAX))
1293 height += XFASTINT (val);
1294 else if (FLOATP (val))
1295 {
1296 int addon = XFLOAT_DATA (val) * height + 0.5;
1297
1298 if (addon >= 0)
1299 height += addon;
1300 }
1301 }
1302 else
1303 height += f->extra_line_spacing;
1304 }
1305
1306 return height;
1307 }
1308
1309 /* Subroutine of pos_visible_p below. Extracts a display string, if
1310 any, from the display spec given as its argument. */
1311 static Lisp_Object
1312 string_from_display_spec (Lisp_Object spec)
1313 {
1314 if (CONSP (spec))
1315 {
1316 while (CONSP (spec))
1317 {
1318 if (STRINGP (XCAR (spec)))
1319 return XCAR (spec);
1320 spec = XCDR (spec);
1321 }
1322 }
1323 else if (VECTORP (spec))
1324 {
1325 ptrdiff_t i;
1326
1327 for (i = 0; i < ASIZE (spec); i++)
1328 {
1329 if (STRINGP (AREF (spec, i)))
1330 return AREF (spec, i);
1331 }
1332 return Qnil;
1333 }
1334
1335 return spec;
1336 }
1337
1338
1339 /* Limit insanely large values of W->hscroll on frame F to the largest
1340 value that will still prevent first_visible_x and last_visible_x of
1341 'struct it' from overflowing an int. */
1342 static int
1343 window_hscroll_limited (struct window *w, struct frame *f)
1344 {
1345 ptrdiff_t window_hscroll = w->hscroll;
1346 int window_text_width = window_box_width (w, TEXT_AREA);
1347 int colwidth = FRAME_COLUMN_WIDTH (f);
1348
1349 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1350 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1351
1352 return window_hscroll;
1353 }
1354
1355 /* Return 1 if position CHARPOS is visible in window W.
1356 CHARPOS < 0 means return info about WINDOW_END position.
1357 If visible, set *X and *Y to pixel coordinates of top left corner.
1358 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1359 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1360
1361 int
1362 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1363 int *rtop, int *rbot, int *rowh, int *vpos)
1364 {
1365 struct it it;
1366 void *itdata = bidi_shelve_cache ();
1367 struct text_pos top;
1368 int visible_p = 0;
1369 struct buffer *old_buffer = NULL;
1370
1371 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1372 return visible_p;
1373
1374 if (XBUFFER (w->contents) != current_buffer)
1375 {
1376 old_buffer = current_buffer;
1377 set_buffer_internal_1 (XBUFFER (w->contents));
1378 }
1379
1380 SET_TEXT_POS_FROM_MARKER (top, w->start);
1381 /* Scrolling a minibuffer window via scroll bar when the echo area
1382 shows long text sometimes resets the minibuffer contents behind
1383 our backs. */
1384 if (CHARPOS (top) > ZV)
1385 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1386
1387 /* Compute exact mode line heights. */
1388 if (WINDOW_WANTS_MODELINE_P (w))
1389 w->mode_line_height
1390 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1391 BVAR (current_buffer, mode_line_format));
1392
1393 if (WINDOW_WANTS_HEADER_LINE_P (w))
1394 w->header_line_height
1395 = display_mode_line (w, HEADER_LINE_FACE_ID,
1396 BVAR (current_buffer, header_line_format));
1397
1398 start_display (&it, w, top);
1399 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1400 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1401
1402 if (charpos >= 0
1403 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1404 && IT_CHARPOS (it) >= charpos)
1405 /* When scanning backwards under bidi iteration, move_it_to
1406 stops at or _before_ CHARPOS, because it stops at or to
1407 the _right_ of the character at CHARPOS. */
1408 || (it.bidi_p && it.bidi_it.scan_dir == -1
1409 && IT_CHARPOS (it) <= charpos)))
1410 {
1411 /* We have reached CHARPOS, or passed it. How the call to
1412 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1413 or covered by a display property, move_it_to stops at the end
1414 of the invisible text, to the right of CHARPOS. (ii) If
1415 CHARPOS is in a display vector, move_it_to stops on its last
1416 glyph. */
1417 int top_x = it.current_x;
1418 int top_y = it.current_y;
1419 /* Calling line_bottom_y may change it.method, it.position, etc. */
1420 enum it_method it_method = it.method;
1421 int bottom_y = (last_height = 0, line_bottom_y (&it));
1422 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1423
1424 if (top_y < window_top_y)
1425 visible_p = bottom_y > window_top_y;
1426 else if (top_y < it.last_visible_y)
1427 visible_p = 1;
1428 if (bottom_y >= it.last_visible_y
1429 && it.bidi_p && it.bidi_it.scan_dir == -1
1430 && IT_CHARPOS (it) < charpos)
1431 {
1432 /* When the last line of the window is scanned backwards
1433 under bidi iteration, we could be duped into thinking
1434 that we have passed CHARPOS, when in fact move_it_to
1435 simply stopped short of CHARPOS because it reached
1436 last_visible_y. To see if that's what happened, we call
1437 move_it_to again with a slightly larger vertical limit,
1438 and see if it actually moved vertically; if it did, we
1439 didn't really reach CHARPOS, which is beyond window end. */
1440 struct it save_it = it;
1441 /* Why 10? because we don't know how many canonical lines
1442 will the height of the next line(s) be. So we guess. */
1443 int ten_more_lines = 10 * default_line_pixel_height (w);
1444
1445 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1446 MOVE_TO_POS | MOVE_TO_Y);
1447 if (it.current_y > top_y)
1448 visible_p = 0;
1449
1450 it = save_it;
1451 }
1452 if (visible_p)
1453 {
1454 if (it_method == GET_FROM_DISPLAY_VECTOR)
1455 {
1456 /* We stopped on the last glyph of a display vector.
1457 Try and recompute. Hack alert! */
1458 if (charpos < 2 || top.charpos >= charpos)
1459 top_x = it.glyph_row->x;
1460 else
1461 {
1462 struct it it2, it2_prev;
1463 /* The idea is to get to the previous buffer
1464 position, consume the character there, and use
1465 the pixel coordinates we get after that. But if
1466 the previous buffer position is also displayed
1467 from a display vector, we need to consume all of
1468 the glyphs from that display vector. */
1469 start_display (&it2, w, top);
1470 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1471 /* If we didn't get to CHARPOS - 1, there's some
1472 replacing display property at that position, and
1473 we stopped after it. That is exactly the place
1474 whose coordinates we want. */
1475 if (IT_CHARPOS (it2) != charpos - 1)
1476 it2_prev = it2;
1477 else
1478 {
1479 /* Iterate until we get out of the display
1480 vector that displays the character at
1481 CHARPOS - 1. */
1482 do {
1483 get_next_display_element (&it2);
1484 PRODUCE_GLYPHS (&it2);
1485 it2_prev = it2;
1486 set_iterator_to_next (&it2, 1);
1487 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1488 && IT_CHARPOS (it2) < charpos);
1489 }
1490 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1491 || it2_prev.current_x > it2_prev.last_visible_x)
1492 top_x = it.glyph_row->x;
1493 else
1494 {
1495 top_x = it2_prev.current_x;
1496 top_y = it2_prev.current_y;
1497 }
1498 }
1499 }
1500 else if (IT_CHARPOS (it) != charpos)
1501 {
1502 Lisp_Object cpos = make_number (charpos);
1503 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1504 Lisp_Object string = string_from_display_spec (spec);
1505 struct text_pos tpos;
1506 int replacing_spec_p;
1507 bool newline_in_string
1508 = (STRINGP (string)
1509 && memchr (SDATA (string), '\n', SBYTES (string)));
1510
1511 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1512 replacing_spec_p
1513 = (!NILP (spec)
1514 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1515 charpos, FRAME_WINDOW_P (it.f)));
1516 /* The tricky code below is needed because there's a
1517 discrepancy between move_it_to and how we set cursor
1518 when PT is at the beginning of a portion of text
1519 covered by a display property or an overlay with a
1520 display property, or the display line ends in a
1521 newline from a display string. move_it_to will stop
1522 _after_ such display strings, whereas
1523 set_cursor_from_row conspires with cursor_row_p to
1524 place the cursor on the first glyph produced from the
1525 display string. */
1526
1527 /* We have overshoot PT because it is covered by a
1528 display property that replaces the text it covers.
1529 If the string includes embedded newlines, we are also
1530 in the wrong display line. Backtrack to the correct
1531 line, where the display property begins. */
1532 if (replacing_spec_p)
1533 {
1534 Lisp_Object startpos, endpos;
1535 EMACS_INT start, end;
1536 struct it it3;
1537 int it3_moved;
1538
1539 /* Find the first and the last buffer positions
1540 covered by the display string. */
1541 endpos =
1542 Fnext_single_char_property_change (cpos, Qdisplay,
1543 Qnil, Qnil);
1544 startpos =
1545 Fprevious_single_char_property_change (endpos, Qdisplay,
1546 Qnil, Qnil);
1547 start = XFASTINT (startpos);
1548 end = XFASTINT (endpos);
1549 /* Move to the last buffer position before the
1550 display property. */
1551 start_display (&it3, w, top);
1552 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1553 /* Move forward one more line if the position before
1554 the display string is a newline or if it is the
1555 rightmost character on a line that is
1556 continued or word-wrapped. */
1557 if (it3.method == GET_FROM_BUFFER
1558 && (it3.c == '\n'
1559 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1560 move_it_by_lines (&it3, 1);
1561 else if (move_it_in_display_line_to (&it3, -1,
1562 it3.current_x
1563 + it3.pixel_width,
1564 MOVE_TO_X)
1565 == MOVE_LINE_CONTINUED)
1566 {
1567 move_it_by_lines (&it3, 1);
1568 /* When we are under word-wrap, the #$@%!
1569 move_it_by_lines moves 2 lines, so we need to
1570 fix that up. */
1571 if (it3.line_wrap == WORD_WRAP)
1572 move_it_by_lines (&it3, -1);
1573 }
1574
1575 /* Record the vertical coordinate of the display
1576 line where we wound up. */
1577 top_y = it3.current_y;
1578 if (it3.bidi_p)
1579 {
1580 /* When characters are reordered for display,
1581 the character displayed to the left of the
1582 display string could be _after_ the display
1583 property in the logical order. Use the
1584 smallest vertical position of these two. */
1585 start_display (&it3, w, top);
1586 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1587 if (it3.current_y < top_y)
1588 top_y = it3.current_y;
1589 }
1590 /* Move from the top of the window to the beginning
1591 of the display line where the display string
1592 begins. */
1593 start_display (&it3, w, top);
1594 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1595 /* If it3_moved stays zero after the 'while' loop
1596 below, that means we already were at a newline
1597 before the loop (e.g., the display string begins
1598 with a newline), so we don't need to (and cannot)
1599 inspect the glyphs of it3.glyph_row, because
1600 PRODUCE_GLYPHS will not produce anything for a
1601 newline, and thus it3.glyph_row stays at its
1602 stale content it got at top of the window. */
1603 it3_moved = 0;
1604 /* Finally, advance the iterator until we hit the
1605 first display element whose character position is
1606 CHARPOS, or until the first newline from the
1607 display string, which signals the end of the
1608 display line. */
1609 while (get_next_display_element (&it3))
1610 {
1611 PRODUCE_GLYPHS (&it3);
1612 if (IT_CHARPOS (it3) == charpos
1613 || ITERATOR_AT_END_OF_LINE_P (&it3))
1614 break;
1615 it3_moved = 1;
1616 set_iterator_to_next (&it3, 0);
1617 }
1618 top_x = it3.current_x - it3.pixel_width;
1619 /* Normally, we would exit the above loop because we
1620 found the display element whose character
1621 position is CHARPOS. For the contingency that we
1622 didn't, and stopped at the first newline from the
1623 display string, move back over the glyphs
1624 produced from the string, until we find the
1625 rightmost glyph not from the string. */
1626 if (it3_moved
1627 && newline_in_string
1628 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1629 {
1630 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1631 + it3.glyph_row->used[TEXT_AREA];
1632
1633 while (EQ ((g - 1)->object, string))
1634 {
1635 --g;
1636 top_x -= g->pixel_width;
1637 }
1638 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1639 + it3.glyph_row->used[TEXT_AREA]);
1640 }
1641 }
1642 }
1643
1644 *x = top_x;
1645 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1646 *rtop = max (0, window_top_y - top_y);
1647 *rbot = max (0, bottom_y - it.last_visible_y);
1648 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1649 - max (top_y, window_top_y)));
1650 *vpos = it.vpos;
1651 }
1652 }
1653 else
1654 {
1655 /* We were asked to provide info about WINDOW_END. */
1656 struct it it2;
1657 void *it2data = NULL;
1658
1659 SAVE_IT (it2, it, it2data);
1660 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1661 move_it_by_lines (&it, 1);
1662 if (charpos < IT_CHARPOS (it)
1663 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1664 {
1665 visible_p = 1;
1666 RESTORE_IT (&it2, &it2, it2data);
1667 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1668 *x = it2.current_x;
1669 *y = it2.current_y + it2.max_ascent - it2.ascent;
1670 *rtop = max (0, -it2.current_y);
1671 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1672 - it.last_visible_y));
1673 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1674 it.last_visible_y)
1675 - max (it2.current_y,
1676 WINDOW_HEADER_LINE_HEIGHT (w))));
1677 *vpos = it2.vpos;
1678 }
1679 else
1680 bidi_unshelve_cache (it2data, 1);
1681 }
1682 bidi_unshelve_cache (itdata, 0);
1683
1684 if (old_buffer)
1685 set_buffer_internal_1 (old_buffer);
1686
1687 if (visible_p && w->hscroll > 0)
1688 *x -=
1689 window_hscroll_limited (w, WINDOW_XFRAME (w))
1690 * WINDOW_FRAME_COLUMN_WIDTH (w);
1691
1692 #if 0
1693 /* Debugging code. */
1694 if (visible_p)
1695 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1696 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1697 else
1698 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1699 #endif
1700
1701 return visible_p;
1702 }
1703
1704
1705 /* Return the next character from STR. Return in *LEN the length of
1706 the character. This is like STRING_CHAR_AND_LENGTH but never
1707 returns an invalid character. If we find one, we return a `?', but
1708 with the length of the invalid character. */
1709
1710 static int
1711 string_char_and_length (const unsigned char *str, int *len)
1712 {
1713 int c;
1714
1715 c = STRING_CHAR_AND_LENGTH (str, *len);
1716 if (!CHAR_VALID_P (c))
1717 /* We may not change the length here because other places in Emacs
1718 don't use this function, i.e. they silently accept invalid
1719 characters. */
1720 c = '?';
1721
1722 return c;
1723 }
1724
1725
1726
1727 /* Given a position POS containing a valid character and byte position
1728 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1729
1730 static struct text_pos
1731 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1732 {
1733 eassert (STRINGP (string) && nchars >= 0);
1734
1735 if (STRING_MULTIBYTE (string))
1736 {
1737 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1738 int len;
1739
1740 while (nchars--)
1741 {
1742 string_char_and_length (p, &len);
1743 p += len;
1744 CHARPOS (pos) += 1;
1745 BYTEPOS (pos) += len;
1746 }
1747 }
1748 else
1749 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1750
1751 return pos;
1752 }
1753
1754
1755 /* Value is the text position, i.e. character and byte position,
1756 for character position CHARPOS in STRING. */
1757
1758 static struct text_pos
1759 string_pos (ptrdiff_t charpos, Lisp_Object string)
1760 {
1761 struct text_pos pos;
1762 eassert (STRINGP (string));
1763 eassert (charpos >= 0);
1764 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1765 return pos;
1766 }
1767
1768
1769 /* Value is a text position, i.e. character and byte position, for
1770 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1771 means recognize multibyte characters. */
1772
1773 static struct text_pos
1774 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1775 {
1776 struct text_pos pos;
1777
1778 eassert (s != NULL);
1779 eassert (charpos >= 0);
1780
1781 if (multibyte_p)
1782 {
1783 int len;
1784
1785 SET_TEXT_POS (pos, 0, 0);
1786 while (charpos--)
1787 {
1788 string_char_and_length ((const unsigned char *) s, &len);
1789 s += len;
1790 CHARPOS (pos) += 1;
1791 BYTEPOS (pos) += len;
1792 }
1793 }
1794 else
1795 SET_TEXT_POS (pos, charpos, charpos);
1796
1797 return pos;
1798 }
1799
1800
1801 /* Value is the number of characters in C string S. MULTIBYTE_P
1802 non-zero means recognize multibyte characters. */
1803
1804 static ptrdiff_t
1805 number_of_chars (const char *s, bool multibyte_p)
1806 {
1807 ptrdiff_t nchars;
1808
1809 if (multibyte_p)
1810 {
1811 ptrdiff_t rest = strlen (s);
1812 int len;
1813 const unsigned char *p = (const unsigned char *) s;
1814
1815 for (nchars = 0; rest > 0; ++nchars)
1816 {
1817 string_char_and_length (p, &len);
1818 rest -= len, p += len;
1819 }
1820 }
1821 else
1822 nchars = strlen (s);
1823
1824 return nchars;
1825 }
1826
1827
1828 /* Compute byte position NEWPOS->bytepos corresponding to
1829 NEWPOS->charpos. POS is a known position in string STRING.
1830 NEWPOS->charpos must be >= POS.charpos. */
1831
1832 static void
1833 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1834 {
1835 eassert (STRINGP (string));
1836 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1837
1838 if (STRING_MULTIBYTE (string))
1839 *newpos = string_pos_nchars_ahead (pos, string,
1840 CHARPOS (*newpos) - CHARPOS (pos));
1841 else
1842 BYTEPOS (*newpos) = CHARPOS (*newpos);
1843 }
1844
1845 /* EXPORT:
1846 Return an estimation of the pixel height of mode or header lines on
1847 frame F. FACE_ID specifies what line's height to estimate. */
1848
1849 int
1850 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1851 {
1852 #ifdef HAVE_WINDOW_SYSTEM
1853 if (FRAME_WINDOW_P (f))
1854 {
1855 int height = FONT_HEIGHT (FRAME_FONT (f));
1856
1857 /* This function is called so early when Emacs starts that the face
1858 cache and mode line face are not yet initialized. */
1859 if (FRAME_FACE_CACHE (f))
1860 {
1861 struct face *face = FACE_FROM_ID (f, face_id);
1862 if (face)
1863 {
1864 if (face->font)
1865 height = FONT_HEIGHT (face->font);
1866 if (face->box_line_width > 0)
1867 height += 2 * face->box_line_width;
1868 }
1869 }
1870
1871 return height;
1872 }
1873 #endif
1874
1875 return 1;
1876 }
1877
1878 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1879 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1880 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1881 not force the value into range. */
1882
1883 void
1884 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1885 int *x, int *y, NativeRectangle *bounds, int noclip)
1886 {
1887
1888 #ifdef HAVE_WINDOW_SYSTEM
1889 if (FRAME_WINDOW_P (f))
1890 {
1891 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1892 even for negative values. */
1893 if (pix_x < 0)
1894 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1895 if (pix_y < 0)
1896 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1897
1898 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1899 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1900
1901 if (bounds)
1902 STORE_NATIVE_RECT (*bounds,
1903 FRAME_COL_TO_PIXEL_X (f, pix_x),
1904 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1905 FRAME_COLUMN_WIDTH (f) - 1,
1906 FRAME_LINE_HEIGHT (f) - 1);
1907
1908 if (!noclip)
1909 {
1910 if (pix_x < 0)
1911 pix_x = 0;
1912 else if (pix_x > FRAME_TOTAL_COLS (f))
1913 pix_x = FRAME_TOTAL_COLS (f);
1914
1915 if (pix_y < 0)
1916 pix_y = 0;
1917 else if (pix_y > FRAME_LINES (f))
1918 pix_y = FRAME_LINES (f);
1919 }
1920 }
1921 #endif
1922
1923 *x = pix_x;
1924 *y = pix_y;
1925 }
1926
1927
1928 /* Find the glyph under window-relative coordinates X/Y in window W.
1929 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1930 strings. Return in *HPOS and *VPOS the row and column number of
1931 the glyph found. Return in *AREA the glyph area containing X.
1932 Value is a pointer to the glyph found or null if X/Y is not on
1933 text, or we can't tell because W's current matrix is not up to
1934 date. */
1935
1936 static struct glyph *
1937 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1938 int *dx, int *dy, int *area)
1939 {
1940 struct glyph *glyph, *end;
1941 struct glyph_row *row = NULL;
1942 int x0, i;
1943
1944 /* Find row containing Y. Give up if some row is not enabled. */
1945 for (i = 0; i < w->current_matrix->nrows; ++i)
1946 {
1947 row = MATRIX_ROW (w->current_matrix, i);
1948 if (!row->enabled_p)
1949 return NULL;
1950 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1951 break;
1952 }
1953
1954 *vpos = i;
1955 *hpos = 0;
1956
1957 /* Give up if Y is not in the window. */
1958 if (i == w->current_matrix->nrows)
1959 return NULL;
1960
1961 /* Get the glyph area containing X. */
1962 if (w->pseudo_window_p)
1963 {
1964 *area = TEXT_AREA;
1965 x0 = 0;
1966 }
1967 else
1968 {
1969 if (x < window_box_left_offset (w, TEXT_AREA))
1970 {
1971 *area = LEFT_MARGIN_AREA;
1972 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1973 }
1974 else if (x < window_box_right_offset (w, TEXT_AREA))
1975 {
1976 *area = TEXT_AREA;
1977 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1978 }
1979 else
1980 {
1981 *area = RIGHT_MARGIN_AREA;
1982 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1983 }
1984 }
1985
1986 /* Find glyph containing X. */
1987 glyph = row->glyphs[*area];
1988 end = glyph + row->used[*area];
1989 x -= x0;
1990 while (glyph < end && x >= glyph->pixel_width)
1991 {
1992 x -= glyph->pixel_width;
1993 ++glyph;
1994 }
1995
1996 if (glyph == end)
1997 return NULL;
1998
1999 if (dx)
2000 {
2001 *dx = x;
2002 *dy = y - (row->y + row->ascent - glyph->ascent);
2003 }
2004
2005 *hpos = glyph - row->glyphs[*area];
2006 return glyph;
2007 }
2008
2009 /* Convert frame-relative x/y to coordinates relative to window W.
2010 Takes pseudo-windows into account. */
2011
2012 static void
2013 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2014 {
2015 if (w->pseudo_window_p)
2016 {
2017 /* A pseudo-window is always full-width, and starts at the
2018 left edge of the frame, plus a frame border. */
2019 struct frame *f = XFRAME (w->frame);
2020 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2021 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2022 }
2023 else
2024 {
2025 *x -= WINDOW_LEFT_EDGE_X (w);
2026 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2027 }
2028 }
2029
2030 #ifdef HAVE_WINDOW_SYSTEM
2031
2032 /* EXPORT:
2033 Return in RECTS[] at most N clipping rectangles for glyph string S.
2034 Return the number of stored rectangles. */
2035
2036 int
2037 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2038 {
2039 XRectangle r;
2040
2041 if (n <= 0)
2042 return 0;
2043
2044 if (s->row->full_width_p)
2045 {
2046 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2047 r.x = WINDOW_LEFT_EDGE_X (s->w);
2048 r.width = WINDOW_TOTAL_WIDTH (s->w);
2049
2050 /* Unless displaying a mode or menu bar line, which are always
2051 fully visible, clip to the visible part of the row. */
2052 if (s->w->pseudo_window_p)
2053 r.height = s->row->visible_height;
2054 else
2055 r.height = s->height;
2056 }
2057 else
2058 {
2059 /* This is a text line that may be partially visible. */
2060 r.x = window_box_left (s->w, s->area);
2061 r.width = window_box_width (s->w, s->area);
2062 r.height = s->row->visible_height;
2063 }
2064
2065 if (s->clip_head)
2066 if (r.x < s->clip_head->x)
2067 {
2068 if (r.width >= s->clip_head->x - r.x)
2069 r.width -= s->clip_head->x - r.x;
2070 else
2071 r.width = 0;
2072 r.x = s->clip_head->x;
2073 }
2074 if (s->clip_tail)
2075 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2076 {
2077 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2078 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2079 else
2080 r.width = 0;
2081 }
2082
2083 /* If S draws overlapping rows, it's sufficient to use the top and
2084 bottom of the window for clipping because this glyph string
2085 intentionally draws over other lines. */
2086 if (s->for_overlaps)
2087 {
2088 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2089 r.height = window_text_bottom_y (s->w) - r.y;
2090
2091 /* Alas, the above simple strategy does not work for the
2092 environments with anti-aliased text: if the same text is
2093 drawn onto the same place multiple times, it gets thicker.
2094 If the overlap we are processing is for the erased cursor, we
2095 take the intersection with the rectangle of the cursor. */
2096 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2097 {
2098 XRectangle rc, r_save = r;
2099
2100 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2101 rc.y = s->w->phys_cursor.y;
2102 rc.width = s->w->phys_cursor_width;
2103 rc.height = s->w->phys_cursor_height;
2104
2105 x_intersect_rectangles (&r_save, &rc, &r);
2106 }
2107 }
2108 else
2109 {
2110 /* Don't use S->y for clipping because it doesn't take partially
2111 visible lines into account. For example, it can be negative for
2112 partially visible lines at the top of a window. */
2113 if (!s->row->full_width_p
2114 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2115 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2116 else
2117 r.y = max (0, s->row->y);
2118 }
2119
2120 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2121
2122 /* If drawing the cursor, don't let glyph draw outside its
2123 advertised boundaries. Cleartype does this under some circumstances. */
2124 if (s->hl == DRAW_CURSOR)
2125 {
2126 struct glyph *glyph = s->first_glyph;
2127 int height, max_y;
2128
2129 if (s->x > r.x)
2130 {
2131 r.width -= s->x - r.x;
2132 r.x = s->x;
2133 }
2134 r.width = min (r.width, glyph->pixel_width);
2135
2136 /* If r.y is below window bottom, ensure that we still see a cursor. */
2137 height = min (glyph->ascent + glyph->descent,
2138 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2139 max_y = window_text_bottom_y (s->w) - height;
2140 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2141 if (s->ybase - glyph->ascent > max_y)
2142 {
2143 r.y = max_y;
2144 r.height = height;
2145 }
2146 else
2147 {
2148 /* Don't draw cursor glyph taller than our actual glyph. */
2149 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2150 if (height < r.height)
2151 {
2152 max_y = r.y + r.height;
2153 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2154 r.height = min (max_y - r.y, height);
2155 }
2156 }
2157 }
2158
2159 if (s->row->clip)
2160 {
2161 XRectangle r_save = r;
2162
2163 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2164 r.width = 0;
2165 }
2166
2167 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2168 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2169 {
2170 #ifdef CONVERT_FROM_XRECT
2171 CONVERT_FROM_XRECT (r, *rects);
2172 #else
2173 *rects = r;
2174 #endif
2175 return 1;
2176 }
2177 else
2178 {
2179 /* If we are processing overlapping and allowed to return
2180 multiple clipping rectangles, we exclude the row of the glyph
2181 string from the clipping rectangle. This is to avoid drawing
2182 the same text on the environment with anti-aliasing. */
2183 #ifdef CONVERT_FROM_XRECT
2184 XRectangle rs[2];
2185 #else
2186 XRectangle *rs = rects;
2187 #endif
2188 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2189
2190 if (s->for_overlaps & OVERLAPS_PRED)
2191 {
2192 rs[i] = r;
2193 if (r.y + r.height > row_y)
2194 {
2195 if (r.y < row_y)
2196 rs[i].height = row_y - r.y;
2197 else
2198 rs[i].height = 0;
2199 }
2200 i++;
2201 }
2202 if (s->for_overlaps & OVERLAPS_SUCC)
2203 {
2204 rs[i] = r;
2205 if (r.y < row_y + s->row->visible_height)
2206 {
2207 if (r.y + r.height > row_y + s->row->visible_height)
2208 {
2209 rs[i].y = row_y + s->row->visible_height;
2210 rs[i].height = r.y + r.height - rs[i].y;
2211 }
2212 else
2213 rs[i].height = 0;
2214 }
2215 i++;
2216 }
2217
2218 n = i;
2219 #ifdef CONVERT_FROM_XRECT
2220 for (i = 0; i < n; i++)
2221 CONVERT_FROM_XRECT (rs[i], rects[i]);
2222 #endif
2223 return n;
2224 }
2225 }
2226
2227 /* EXPORT:
2228 Return in *NR the clipping rectangle for glyph string S. */
2229
2230 void
2231 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2232 {
2233 get_glyph_string_clip_rects (s, nr, 1);
2234 }
2235
2236
2237 /* EXPORT:
2238 Return the position and height of the phys cursor in window W.
2239 Set w->phys_cursor_width to width of phys cursor.
2240 */
2241
2242 void
2243 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2244 struct glyph *glyph, int *xp, int *yp, int *heightp)
2245 {
2246 struct frame *f = XFRAME (WINDOW_FRAME (w));
2247 int x, y, wd, h, h0, y0;
2248
2249 /* Compute the width of the rectangle to draw. If on a stretch
2250 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2251 rectangle as wide as the glyph, but use a canonical character
2252 width instead. */
2253 wd = glyph->pixel_width - 1;
2254 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2255 wd++; /* Why? */
2256 #endif
2257
2258 x = w->phys_cursor.x;
2259 if (x < 0)
2260 {
2261 wd += x;
2262 x = 0;
2263 }
2264
2265 if (glyph->type == STRETCH_GLYPH
2266 && !x_stretch_cursor_p)
2267 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2268 w->phys_cursor_width = wd;
2269
2270 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2271
2272 /* If y is below window bottom, ensure that we still see a cursor. */
2273 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2274
2275 h = max (h0, glyph->ascent + glyph->descent);
2276 h0 = min (h0, glyph->ascent + glyph->descent);
2277
2278 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2279 if (y < y0)
2280 {
2281 h = max (h - (y0 - y) + 1, h0);
2282 y = y0 - 1;
2283 }
2284 else
2285 {
2286 y0 = window_text_bottom_y (w) - h0;
2287 if (y > y0)
2288 {
2289 h += y - y0;
2290 y = y0;
2291 }
2292 }
2293
2294 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2295 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2296 *heightp = h;
2297 }
2298
2299 /*
2300 * Remember which glyph the mouse is over.
2301 */
2302
2303 void
2304 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2305 {
2306 Lisp_Object window;
2307 struct window *w;
2308 struct glyph_row *r, *gr, *end_row;
2309 enum window_part part;
2310 enum glyph_row_area area;
2311 int x, y, width, height;
2312
2313 /* Try to determine frame pixel position and size of the glyph under
2314 frame pixel coordinates X/Y on frame F. */
2315
2316 if (!f->glyphs_initialized_p
2317 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2318 NILP (window)))
2319 {
2320 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2321 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2322 goto virtual_glyph;
2323 }
2324
2325 w = XWINDOW (window);
2326 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2327 height = WINDOW_FRAME_LINE_HEIGHT (w);
2328
2329 x = window_relative_x_coord (w, part, gx);
2330 y = gy - WINDOW_TOP_EDGE_Y (w);
2331
2332 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2333 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2334
2335 if (w->pseudo_window_p)
2336 {
2337 area = TEXT_AREA;
2338 part = ON_MODE_LINE; /* Don't adjust margin. */
2339 goto text_glyph;
2340 }
2341
2342 switch (part)
2343 {
2344 case ON_LEFT_MARGIN:
2345 area = LEFT_MARGIN_AREA;
2346 goto text_glyph;
2347
2348 case ON_RIGHT_MARGIN:
2349 area = RIGHT_MARGIN_AREA;
2350 goto text_glyph;
2351
2352 case ON_HEADER_LINE:
2353 case ON_MODE_LINE:
2354 gr = (part == ON_HEADER_LINE
2355 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2356 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2357 gy = gr->y;
2358 area = TEXT_AREA;
2359 goto text_glyph_row_found;
2360
2361 case ON_TEXT:
2362 area = TEXT_AREA;
2363
2364 text_glyph:
2365 gr = 0; gy = 0;
2366 for (; r <= end_row && r->enabled_p; ++r)
2367 if (r->y + r->height > y)
2368 {
2369 gr = r; gy = r->y;
2370 break;
2371 }
2372
2373 text_glyph_row_found:
2374 if (gr && gy <= y)
2375 {
2376 struct glyph *g = gr->glyphs[area];
2377 struct glyph *end = g + gr->used[area];
2378
2379 height = gr->height;
2380 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2381 if (gx + g->pixel_width > x)
2382 break;
2383
2384 if (g < end)
2385 {
2386 if (g->type == IMAGE_GLYPH)
2387 {
2388 /* Don't remember when mouse is over image, as
2389 image may have hot-spots. */
2390 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2391 return;
2392 }
2393 width = g->pixel_width;
2394 }
2395 else
2396 {
2397 /* Use nominal char spacing at end of line. */
2398 x -= gx;
2399 gx += (x / width) * width;
2400 }
2401
2402 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2403 gx += window_box_left_offset (w, area);
2404 }
2405 else
2406 {
2407 /* Use nominal line height at end of window. */
2408 gx = (x / width) * width;
2409 y -= gy;
2410 gy += (y / height) * height;
2411 }
2412 break;
2413
2414 case ON_LEFT_FRINGE:
2415 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2416 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2417 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2418 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2419 goto row_glyph;
2420
2421 case ON_RIGHT_FRINGE:
2422 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2423 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2424 : window_box_right_offset (w, TEXT_AREA));
2425 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2426 goto row_glyph;
2427
2428 case ON_SCROLL_BAR:
2429 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2430 ? 0
2431 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2432 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2433 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2434 : 0)));
2435 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2436
2437 row_glyph:
2438 gr = 0, gy = 0;
2439 for (; r <= end_row && r->enabled_p; ++r)
2440 if (r->y + r->height > y)
2441 {
2442 gr = r; gy = r->y;
2443 break;
2444 }
2445
2446 if (gr && gy <= y)
2447 height = gr->height;
2448 else
2449 {
2450 /* Use nominal line height at end of window. */
2451 y -= gy;
2452 gy += (y / height) * height;
2453 }
2454 break;
2455
2456 default:
2457 ;
2458 virtual_glyph:
2459 /* If there is no glyph under the mouse, then we divide the screen
2460 into a grid of the smallest glyph in the frame, and use that
2461 as our "glyph". */
2462
2463 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2464 round down even for negative values. */
2465 if (gx < 0)
2466 gx -= width - 1;
2467 if (gy < 0)
2468 gy -= height - 1;
2469
2470 gx = (gx / width) * width;
2471 gy = (gy / height) * height;
2472
2473 goto store_rect;
2474 }
2475
2476 gx += WINDOW_LEFT_EDGE_X (w);
2477 gy += WINDOW_TOP_EDGE_Y (w);
2478
2479 store_rect:
2480 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2481
2482 /* Visible feedback for debugging. */
2483 #if 0
2484 #if HAVE_X_WINDOWS
2485 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2486 f->output_data.x->normal_gc,
2487 gx, gy, width, height);
2488 #endif
2489 #endif
2490 }
2491
2492
2493 #endif /* HAVE_WINDOW_SYSTEM */
2494
2495 static void
2496 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2497 {
2498 eassert (w);
2499 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2500 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2501 w->window_end_vpos
2502 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2503 }
2504
2505 /***********************************************************************
2506 Lisp form evaluation
2507 ***********************************************************************/
2508
2509 /* Error handler for safe_eval and safe_call. */
2510
2511 static Lisp_Object
2512 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2513 {
2514 add_to_log ("Error during redisplay: %S signaled %S",
2515 Flist (nargs, args), arg);
2516 return Qnil;
2517 }
2518
2519 /* Call function FUNC with the rest of NARGS - 1 arguments
2520 following. Return the result, or nil if something went
2521 wrong. Prevent redisplay during the evaluation. */
2522
2523 Lisp_Object
2524 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2525 {
2526 Lisp_Object val;
2527
2528 if (inhibit_eval_during_redisplay)
2529 val = Qnil;
2530 else
2531 {
2532 va_list ap;
2533 ptrdiff_t i;
2534 ptrdiff_t count = SPECPDL_INDEX ();
2535 struct gcpro gcpro1;
2536 Lisp_Object *args = alloca (nargs * word_size);
2537
2538 args[0] = func;
2539 va_start (ap, func);
2540 for (i = 1; i < nargs; i++)
2541 args[i] = va_arg (ap, Lisp_Object);
2542 va_end (ap);
2543
2544 GCPRO1 (args[0]);
2545 gcpro1.nvars = nargs;
2546 specbind (Qinhibit_redisplay, Qt);
2547 /* Use Qt to ensure debugger does not run,
2548 so there is no possibility of wanting to redisplay. */
2549 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2550 safe_eval_handler);
2551 UNGCPRO;
2552 val = unbind_to (count, val);
2553 }
2554
2555 return val;
2556 }
2557
2558
2559 /* Call function FN with one argument ARG.
2560 Return the result, or nil if something went wrong. */
2561
2562 Lisp_Object
2563 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2564 {
2565 return safe_call (2, fn, arg);
2566 }
2567
2568 static Lisp_Object Qeval;
2569
2570 Lisp_Object
2571 safe_eval (Lisp_Object sexpr)
2572 {
2573 return safe_call1 (Qeval, sexpr);
2574 }
2575
2576 /* Call function FN with two arguments ARG1 and ARG2.
2577 Return the result, or nil if something went wrong. */
2578
2579 Lisp_Object
2580 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2581 {
2582 return safe_call (3, fn, arg1, arg2);
2583 }
2584
2585
2586 \f
2587 /***********************************************************************
2588 Debugging
2589 ***********************************************************************/
2590
2591 #if 0
2592
2593 /* Define CHECK_IT to perform sanity checks on iterators.
2594 This is for debugging. It is too slow to do unconditionally. */
2595
2596 static void
2597 check_it (struct it *it)
2598 {
2599 if (it->method == GET_FROM_STRING)
2600 {
2601 eassert (STRINGP (it->string));
2602 eassert (IT_STRING_CHARPOS (*it) >= 0);
2603 }
2604 else
2605 {
2606 eassert (IT_STRING_CHARPOS (*it) < 0);
2607 if (it->method == GET_FROM_BUFFER)
2608 {
2609 /* Check that character and byte positions agree. */
2610 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2611 }
2612 }
2613
2614 if (it->dpvec)
2615 eassert (it->current.dpvec_index >= 0);
2616 else
2617 eassert (it->current.dpvec_index < 0);
2618 }
2619
2620 #define CHECK_IT(IT) check_it ((IT))
2621
2622 #else /* not 0 */
2623
2624 #define CHECK_IT(IT) (void) 0
2625
2626 #endif /* not 0 */
2627
2628
2629 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2630
2631 /* Check that the window end of window W is what we expect it
2632 to be---the last row in the current matrix displaying text. */
2633
2634 static void
2635 check_window_end (struct window *w)
2636 {
2637 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2638 {
2639 struct glyph_row *row;
2640 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2641 !row->enabled_p
2642 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2643 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2644 }
2645 }
2646
2647 #define CHECK_WINDOW_END(W) check_window_end ((W))
2648
2649 #else
2650
2651 #define CHECK_WINDOW_END(W) (void) 0
2652
2653 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2654
2655 /***********************************************************************
2656 Iterator initialization
2657 ***********************************************************************/
2658
2659 /* Initialize IT for displaying current_buffer in window W, starting
2660 at character position CHARPOS. CHARPOS < 0 means that no buffer
2661 position is specified which is useful when the iterator is assigned
2662 a position later. BYTEPOS is the byte position corresponding to
2663 CHARPOS.
2664
2665 If ROW is not null, calls to produce_glyphs with IT as parameter
2666 will produce glyphs in that row.
2667
2668 BASE_FACE_ID is the id of a base face to use. It must be one of
2669 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2670 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2671 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2672
2673 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2674 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2675 will be initialized to use the corresponding mode line glyph row of
2676 the desired matrix of W. */
2677
2678 void
2679 init_iterator (struct it *it, struct window *w,
2680 ptrdiff_t charpos, ptrdiff_t bytepos,
2681 struct glyph_row *row, enum face_id base_face_id)
2682 {
2683 enum face_id remapped_base_face_id = base_face_id;
2684
2685 /* Some precondition checks. */
2686 eassert (w != NULL && it != NULL);
2687 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2688 && charpos <= ZV));
2689
2690 /* If face attributes have been changed since the last redisplay,
2691 free realized faces now because they depend on face definitions
2692 that might have changed. Don't free faces while there might be
2693 desired matrices pending which reference these faces. */
2694 if (face_change_count && !inhibit_free_realized_faces)
2695 {
2696 face_change_count = 0;
2697 free_all_realized_faces (Qnil);
2698 }
2699
2700 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2701 if (! NILP (Vface_remapping_alist))
2702 remapped_base_face_id
2703 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2704
2705 /* Use one of the mode line rows of W's desired matrix if
2706 appropriate. */
2707 if (row == NULL)
2708 {
2709 if (base_face_id == MODE_LINE_FACE_ID
2710 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2711 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2712 else if (base_face_id == HEADER_LINE_FACE_ID)
2713 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2714 }
2715
2716 /* Clear IT. */
2717 memset (it, 0, sizeof *it);
2718 it->current.overlay_string_index = -1;
2719 it->current.dpvec_index = -1;
2720 it->base_face_id = remapped_base_face_id;
2721 it->string = Qnil;
2722 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2723 it->paragraph_embedding = L2R;
2724 it->bidi_it.string.lstring = Qnil;
2725 it->bidi_it.string.s = NULL;
2726 it->bidi_it.string.bufpos = 0;
2727 it->bidi_it.w = w;
2728
2729 /* The window in which we iterate over current_buffer: */
2730 XSETWINDOW (it->window, w);
2731 it->w = w;
2732 it->f = XFRAME (w->frame);
2733
2734 it->cmp_it.id = -1;
2735
2736 /* Extra space between lines (on window systems only). */
2737 if (base_face_id == DEFAULT_FACE_ID
2738 && FRAME_WINDOW_P (it->f))
2739 {
2740 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2741 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2742 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2743 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2744 * FRAME_LINE_HEIGHT (it->f));
2745 else if (it->f->extra_line_spacing > 0)
2746 it->extra_line_spacing = it->f->extra_line_spacing;
2747 it->max_extra_line_spacing = 0;
2748 }
2749
2750 /* If realized faces have been removed, e.g. because of face
2751 attribute changes of named faces, recompute them. When running
2752 in batch mode, the face cache of the initial frame is null. If
2753 we happen to get called, make a dummy face cache. */
2754 if (FRAME_FACE_CACHE (it->f) == NULL)
2755 init_frame_faces (it->f);
2756 if (FRAME_FACE_CACHE (it->f)->used == 0)
2757 recompute_basic_faces (it->f);
2758
2759 /* Current value of the `slice', `space-width', and 'height' properties. */
2760 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2761 it->space_width = Qnil;
2762 it->font_height = Qnil;
2763 it->override_ascent = -1;
2764
2765 /* Are control characters displayed as `^C'? */
2766 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2767
2768 /* -1 means everything between a CR and the following line end
2769 is invisible. >0 means lines indented more than this value are
2770 invisible. */
2771 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2772 ? (clip_to_bounds
2773 (-1, XINT (BVAR (current_buffer, selective_display)),
2774 PTRDIFF_MAX))
2775 : (!NILP (BVAR (current_buffer, selective_display))
2776 ? -1 : 0));
2777 it->selective_display_ellipsis_p
2778 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2779
2780 /* Display table to use. */
2781 it->dp = window_display_table (w);
2782
2783 /* Are multibyte characters enabled in current_buffer? */
2784 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2785
2786 /* Get the position at which the redisplay_end_trigger hook should
2787 be run, if it is to be run at all. */
2788 if (MARKERP (w->redisplay_end_trigger)
2789 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2790 it->redisplay_end_trigger_charpos
2791 = marker_position (w->redisplay_end_trigger);
2792 else if (INTEGERP (w->redisplay_end_trigger))
2793 it->redisplay_end_trigger_charpos =
2794 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2795
2796 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2797
2798 /* Are lines in the display truncated? */
2799 if (base_face_id != DEFAULT_FACE_ID
2800 || it->w->hscroll
2801 || (! WINDOW_FULL_WIDTH_P (it->w)
2802 && ((!NILP (Vtruncate_partial_width_windows)
2803 && !INTEGERP (Vtruncate_partial_width_windows))
2804 || (INTEGERP (Vtruncate_partial_width_windows)
2805 && (WINDOW_TOTAL_COLS (it->w)
2806 < XINT (Vtruncate_partial_width_windows))))))
2807 it->line_wrap = TRUNCATE;
2808 else if (NILP (BVAR (current_buffer, truncate_lines)))
2809 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2810 ? WINDOW_WRAP : WORD_WRAP;
2811 else
2812 it->line_wrap = TRUNCATE;
2813
2814 /* Get dimensions of truncation and continuation glyphs. These are
2815 displayed as fringe bitmaps under X, but we need them for such
2816 frames when the fringes are turned off. But leave the dimensions
2817 zero for tooltip frames, as these glyphs look ugly there and also
2818 sabotage calculations of tooltip dimensions in x-show-tip. */
2819 #ifdef HAVE_WINDOW_SYSTEM
2820 if (!(FRAME_WINDOW_P (it->f)
2821 && FRAMEP (tip_frame)
2822 && it->f == XFRAME (tip_frame)))
2823 #endif
2824 {
2825 if (it->line_wrap == TRUNCATE)
2826 {
2827 /* We will need the truncation glyph. */
2828 eassert (it->glyph_row == NULL);
2829 produce_special_glyphs (it, IT_TRUNCATION);
2830 it->truncation_pixel_width = it->pixel_width;
2831 }
2832 else
2833 {
2834 /* We will need the continuation glyph. */
2835 eassert (it->glyph_row == NULL);
2836 produce_special_glyphs (it, IT_CONTINUATION);
2837 it->continuation_pixel_width = it->pixel_width;
2838 }
2839 }
2840
2841 /* Reset these values to zero because the produce_special_glyphs
2842 above has changed them. */
2843 it->pixel_width = it->ascent = it->descent = 0;
2844 it->phys_ascent = it->phys_descent = 0;
2845
2846 /* Set this after getting the dimensions of truncation and
2847 continuation glyphs, so that we don't produce glyphs when calling
2848 produce_special_glyphs, above. */
2849 it->glyph_row = row;
2850 it->area = TEXT_AREA;
2851
2852 /* Forget any previous info about this row being reversed. */
2853 if (it->glyph_row)
2854 it->glyph_row->reversed_p = 0;
2855
2856 /* Get the dimensions of the display area. The display area
2857 consists of the visible window area plus a horizontally scrolled
2858 part to the left of the window. All x-values are relative to the
2859 start of this total display area. */
2860 if (base_face_id != DEFAULT_FACE_ID)
2861 {
2862 /* Mode lines, menu bar in terminal frames. */
2863 it->first_visible_x = 0;
2864 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2865 }
2866 else
2867 {
2868 it->first_visible_x =
2869 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2870 it->last_visible_x = (it->first_visible_x
2871 + window_box_width (w, TEXT_AREA));
2872
2873 /* If we truncate lines, leave room for the truncation glyph(s) at
2874 the right margin. Otherwise, leave room for the continuation
2875 glyph(s). Done only if the window has no fringes. Since we
2876 don't know at this point whether there will be any R2L lines in
2877 the window, we reserve space for truncation/continuation glyphs
2878 even if only one of the fringes is absent. */
2879 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2880 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2881 {
2882 if (it->line_wrap == TRUNCATE)
2883 it->last_visible_x -= it->truncation_pixel_width;
2884 else
2885 it->last_visible_x -= it->continuation_pixel_width;
2886 }
2887
2888 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2889 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2890 }
2891
2892 /* Leave room for a border glyph. */
2893 if (!FRAME_WINDOW_P (it->f)
2894 && !WINDOW_RIGHTMOST_P (it->w))
2895 it->last_visible_x -= 1;
2896
2897 it->last_visible_y = window_text_bottom_y (w);
2898
2899 /* For mode lines and alike, arrange for the first glyph having a
2900 left box line if the face specifies a box. */
2901 if (base_face_id != DEFAULT_FACE_ID)
2902 {
2903 struct face *face;
2904
2905 it->face_id = remapped_base_face_id;
2906
2907 /* If we have a boxed mode line, make the first character appear
2908 with a left box line. */
2909 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2910 if (face->box != FACE_NO_BOX)
2911 it->start_of_box_run_p = 1;
2912 }
2913
2914 /* If a buffer position was specified, set the iterator there,
2915 getting overlays and face properties from that position. */
2916 if (charpos >= BUF_BEG (current_buffer))
2917 {
2918 it->end_charpos = ZV;
2919 eassert (charpos == BYTE_TO_CHAR (bytepos));
2920 IT_CHARPOS (*it) = charpos;
2921 IT_BYTEPOS (*it) = bytepos;
2922
2923 /* We will rely on `reseat' to set this up properly, via
2924 handle_face_prop. */
2925 it->face_id = it->base_face_id;
2926
2927 it->start = it->current;
2928 /* Do we need to reorder bidirectional text? Not if this is a
2929 unibyte buffer: by definition, none of the single-byte
2930 characters are strong R2L, so no reordering is needed. And
2931 bidi.c doesn't support unibyte buffers anyway. Also, don't
2932 reorder while we are loading loadup.el, since the tables of
2933 character properties needed for reordering are not yet
2934 available. */
2935 it->bidi_p =
2936 NILP (Vpurify_flag)
2937 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2938 && it->multibyte_p;
2939
2940 /* If we are to reorder bidirectional text, init the bidi
2941 iterator. */
2942 if (it->bidi_p)
2943 {
2944 /* Note the paragraph direction that this buffer wants to
2945 use. */
2946 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2947 Qleft_to_right))
2948 it->paragraph_embedding = L2R;
2949 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2950 Qright_to_left))
2951 it->paragraph_embedding = R2L;
2952 else
2953 it->paragraph_embedding = NEUTRAL_DIR;
2954 bidi_unshelve_cache (NULL, 0);
2955 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2956 &it->bidi_it);
2957 }
2958
2959 /* Compute faces etc. */
2960 reseat (it, it->current.pos, 1);
2961 }
2962
2963 CHECK_IT (it);
2964 }
2965
2966
2967 /* Initialize IT for the display of window W with window start POS. */
2968
2969 void
2970 start_display (struct it *it, struct window *w, struct text_pos pos)
2971 {
2972 struct glyph_row *row;
2973 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2974
2975 row = w->desired_matrix->rows + first_vpos;
2976 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2977 it->first_vpos = first_vpos;
2978
2979 /* Don't reseat to previous visible line start if current start
2980 position is in a string or image. */
2981 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2982 {
2983 int start_at_line_beg_p;
2984 int first_y = it->current_y;
2985
2986 /* If window start is not at a line start, skip forward to POS to
2987 get the correct continuation lines width. */
2988 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2989 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2990 if (!start_at_line_beg_p)
2991 {
2992 int new_x;
2993
2994 reseat_at_previous_visible_line_start (it);
2995 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2996
2997 new_x = it->current_x + it->pixel_width;
2998
2999 /* If lines are continued, this line may end in the middle
3000 of a multi-glyph character (e.g. a control character
3001 displayed as \003, or in the middle of an overlay
3002 string). In this case move_it_to above will not have
3003 taken us to the start of the continuation line but to the
3004 end of the continued line. */
3005 if (it->current_x > 0
3006 && it->line_wrap != TRUNCATE /* Lines are continued. */
3007 && (/* And glyph doesn't fit on the line. */
3008 new_x > it->last_visible_x
3009 /* Or it fits exactly and we're on a window
3010 system frame. */
3011 || (new_x == it->last_visible_x
3012 && FRAME_WINDOW_P (it->f)
3013 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3014 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3015 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3016 {
3017 if ((it->current.dpvec_index >= 0
3018 || it->current.overlay_string_index >= 0)
3019 /* If we are on a newline from a display vector or
3020 overlay string, then we are already at the end of
3021 a screen line; no need to go to the next line in
3022 that case, as this line is not really continued.
3023 (If we do go to the next line, C-e will not DTRT.) */
3024 && it->c != '\n')
3025 {
3026 set_iterator_to_next (it, 1);
3027 move_it_in_display_line_to (it, -1, -1, 0);
3028 }
3029
3030 it->continuation_lines_width += it->current_x;
3031 }
3032 /* If the character at POS is displayed via a display
3033 vector, move_it_to above stops at the final glyph of
3034 IT->dpvec. To make the caller redisplay that character
3035 again (a.k.a. start at POS), we need to reset the
3036 dpvec_index to the beginning of IT->dpvec. */
3037 else if (it->current.dpvec_index >= 0)
3038 it->current.dpvec_index = 0;
3039
3040 /* We're starting a new display line, not affected by the
3041 height of the continued line, so clear the appropriate
3042 fields in the iterator structure. */
3043 it->max_ascent = it->max_descent = 0;
3044 it->max_phys_ascent = it->max_phys_descent = 0;
3045
3046 it->current_y = first_y;
3047 it->vpos = 0;
3048 it->current_x = it->hpos = 0;
3049 }
3050 }
3051 }
3052
3053
3054 /* Return 1 if POS is a position in ellipses displayed for invisible
3055 text. W is the window we display, for text property lookup. */
3056
3057 static int
3058 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3059 {
3060 Lisp_Object prop, window;
3061 int ellipses_p = 0;
3062 ptrdiff_t charpos = CHARPOS (pos->pos);
3063
3064 /* If POS specifies a position in a display vector, this might
3065 be for an ellipsis displayed for invisible text. We won't
3066 get the iterator set up for delivering that ellipsis unless
3067 we make sure that it gets aware of the invisible text. */
3068 if (pos->dpvec_index >= 0
3069 && pos->overlay_string_index < 0
3070 && CHARPOS (pos->string_pos) < 0
3071 && charpos > BEGV
3072 && (XSETWINDOW (window, w),
3073 prop = Fget_char_property (make_number (charpos),
3074 Qinvisible, window),
3075 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3076 {
3077 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3078 window);
3079 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3080 }
3081
3082 return ellipses_p;
3083 }
3084
3085
3086 /* Initialize IT for stepping through current_buffer in window W,
3087 starting at position POS that includes overlay string and display
3088 vector/ control character translation position information. Value
3089 is zero if there are overlay strings with newlines at POS. */
3090
3091 static int
3092 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3093 {
3094 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3095 int i, overlay_strings_with_newlines = 0;
3096
3097 /* If POS specifies a position in a display vector, this might
3098 be for an ellipsis displayed for invisible text. We won't
3099 get the iterator set up for delivering that ellipsis unless
3100 we make sure that it gets aware of the invisible text. */
3101 if (in_ellipses_for_invisible_text_p (pos, w))
3102 {
3103 --charpos;
3104 bytepos = 0;
3105 }
3106
3107 /* Keep in mind: the call to reseat in init_iterator skips invisible
3108 text, so we might end up at a position different from POS. This
3109 is only a problem when POS is a row start after a newline and an
3110 overlay starts there with an after-string, and the overlay has an
3111 invisible property. Since we don't skip invisible text in
3112 display_line and elsewhere immediately after consuming the
3113 newline before the row start, such a POS will not be in a string,
3114 but the call to init_iterator below will move us to the
3115 after-string. */
3116 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3117
3118 /* This only scans the current chunk -- it should scan all chunks.
3119 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3120 to 16 in 22.1 to make this a lesser problem. */
3121 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3122 {
3123 const char *s = SSDATA (it->overlay_strings[i]);
3124 const char *e = s + SBYTES (it->overlay_strings[i]);
3125
3126 while (s < e && *s != '\n')
3127 ++s;
3128
3129 if (s < e)
3130 {
3131 overlay_strings_with_newlines = 1;
3132 break;
3133 }
3134 }
3135
3136 /* If position is within an overlay string, set up IT to the right
3137 overlay string. */
3138 if (pos->overlay_string_index >= 0)
3139 {
3140 int relative_index;
3141
3142 /* If the first overlay string happens to have a `display'
3143 property for an image, the iterator will be set up for that
3144 image, and we have to undo that setup first before we can
3145 correct the overlay string index. */
3146 if (it->method == GET_FROM_IMAGE)
3147 pop_it (it);
3148
3149 /* We already have the first chunk of overlay strings in
3150 IT->overlay_strings. Load more until the one for
3151 pos->overlay_string_index is in IT->overlay_strings. */
3152 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3153 {
3154 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3155 it->current.overlay_string_index = 0;
3156 while (n--)
3157 {
3158 load_overlay_strings (it, 0);
3159 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3160 }
3161 }
3162
3163 it->current.overlay_string_index = pos->overlay_string_index;
3164 relative_index = (it->current.overlay_string_index
3165 % OVERLAY_STRING_CHUNK_SIZE);
3166 it->string = it->overlay_strings[relative_index];
3167 eassert (STRINGP (it->string));
3168 it->current.string_pos = pos->string_pos;
3169 it->method = GET_FROM_STRING;
3170 it->end_charpos = SCHARS (it->string);
3171 /* Set up the bidi iterator for this overlay string. */
3172 if (it->bidi_p)
3173 {
3174 it->bidi_it.string.lstring = it->string;
3175 it->bidi_it.string.s = NULL;
3176 it->bidi_it.string.schars = SCHARS (it->string);
3177 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3178 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3179 it->bidi_it.string.unibyte = !it->multibyte_p;
3180 it->bidi_it.w = it->w;
3181 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3182 FRAME_WINDOW_P (it->f), &it->bidi_it);
3183
3184 /* Synchronize the state of the bidi iterator with
3185 pos->string_pos. For any string position other than
3186 zero, this will be done automagically when we resume
3187 iteration over the string and get_visually_first_element
3188 is called. But if string_pos is zero, and the string is
3189 to be reordered for display, we need to resync manually,
3190 since it could be that the iteration state recorded in
3191 pos ended at string_pos of 0 moving backwards in string. */
3192 if (CHARPOS (pos->string_pos) == 0)
3193 {
3194 get_visually_first_element (it);
3195 if (IT_STRING_CHARPOS (*it) != 0)
3196 do {
3197 /* Paranoia. */
3198 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3199 bidi_move_to_visually_next (&it->bidi_it);
3200 } while (it->bidi_it.charpos != 0);
3201 }
3202 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3203 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3204 }
3205 }
3206
3207 if (CHARPOS (pos->string_pos) >= 0)
3208 {
3209 /* Recorded position is not in an overlay string, but in another
3210 string. This can only be a string from a `display' property.
3211 IT should already be filled with that string. */
3212 it->current.string_pos = pos->string_pos;
3213 eassert (STRINGP (it->string));
3214 if (it->bidi_p)
3215 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3216 FRAME_WINDOW_P (it->f), &it->bidi_it);
3217 }
3218
3219 /* Restore position in display vector translations, control
3220 character translations or ellipses. */
3221 if (pos->dpvec_index >= 0)
3222 {
3223 if (it->dpvec == NULL)
3224 get_next_display_element (it);
3225 eassert (it->dpvec && it->current.dpvec_index == 0);
3226 it->current.dpvec_index = pos->dpvec_index;
3227 }
3228
3229 CHECK_IT (it);
3230 return !overlay_strings_with_newlines;
3231 }
3232
3233
3234 /* Initialize IT for stepping through current_buffer in window W
3235 starting at ROW->start. */
3236
3237 static void
3238 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3239 {
3240 init_from_display_pos (it, w, &row->start);
3241 it->start = row->start;
3242 it->continuation_lines_width = row->continuation_lines_width;
3243 CHECK_IT (it);
3244 }
3245
3246
3247 /* Initialize IT for stepping through current_buffer in window W
3248 starting in the line following ROW, i.e. starting at ROW->end.
3249 Value is zero if there are overlay strings with newlines at ROW's
3250 end position. */
3251
3252 static int
3253 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3254 {
3255 int success = 0;
3256
3257 if (init_from_display_pos (it, w, &row->end))
3258 {
3259 if (row->continued_p)
3260 it->continuation_lines_width
3261 = row->continuation_lines_width + row->pixel_width;
3262 CHECK_IT (it);
3263 success = 1;
3264 }
3265
3266 return success;
3267 }
3268
3269
3270
3271 \f
3272 /***********************************************************************
3273 Text properties
3274 ***********************************************************************/
3275
3276 /* Called when IT reaches IT->stop_charpos. Handle text property and
3277 overlay changes. Set IT->stop_charpos to the next position where
3278 to stop. */
3279
3280 static void
3281 handle_stop (struct it *it)
3282 {
3283 enum prop_handled handled;
3284 int handle_overlay_change_p;
3285 struct props *p;
3286
3287 it->dpvec = NULL;
3288 it->current.dpvec_index = -1;
3289 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3290 it->ignore_overlay_strings_at_pos_p = 0;
3291 it->ellipsis_p = 0;
3292
3293 /* Use face of preceding text for ellipsis (if invisible) */
3294 if (it->selective_display_ellipsis_p)
3295 it->saved_face_id = it->face_id;
3296
3297 do
3298 {
3299 handled = HANDLED_NORMALLY;
3300
3301 /* Call text property handlers. */
3302 for (p = it_props; p->handler; ++p)
3303 {
3304 handled = p->handler (it);
3305
3306 if (handled == HANDLED_RECOMPUTE_PROPS)
3307 break;
3308 else if (handled == HANDLED_RETURN)
3309 {
3310 /* We still want to show before and after strings from
3311 overlays even if the actual buffer text is replaced. */
3312 if (!handle_overlay_change_p
3313 || it->sp > 1
3314 /* Don't call get_overlay_strings_1 if we already
3315 have overlay strings loaded, because doing so
3316 will load them again and push the iterator state
3317 onto the stack one more time, which is not
3318 expected by the rest of the code that processes
3319 overlay strings. */
3320 || (it->current.overlay_string_index < 0
3321 ? !get_overlay_strings_1 (it, 0, 0)
3322 : 0))
3323 {
3324 if (it->ellipsis_p)
3325 setup_for_ellipsis (it, 0);
3326 /* When handling a display spec, we might load an
3327 empty string. In that case, discard it here. We
3328 used to discard it in handle_single_display_spec,
3329 but that causes get_overlay_strings_1, above, to
3330 ignore overlay strings that we must check. */
3331 if (STRINGP (it->string) && !SCHARS (it->string))
3332 pop_it (it);
3333 return;
3334 }
3335 else if (STRINGP (it->string) && !SCHARS (it->string))
3336 pop_it (it);
3337 else
3338 {
3339 it->ignore_overlay_strings_at_pos_p = 1;
3340 it->string_from_display_prop_p = 0;
3341 it->from_disp_prop_p = 0;
3342 handle_overlay_change_p = 0;
3343 }
3344 handled = HANDLED_RECOMPUTE_PROPS;
3345 break;
3346 }
3347 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3348 handle_overlay_change_p = 0;
3349 }
3350
3351 if (handled != HANDLED_RECOMPUTE_PROPS)
3352 {
3353 /* Don't check for overlay strings below when set to deliver
3354 characters from a display vector. */
3355 if (it->method == GET_FROM_DISPLAY_VECTOR)
3356 handle_overlay_change_p = 0;
3357
3358 /* Handle overlay changes.
3359 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3360 if it finds overlays. */
3361 if (handle_overlay_change_p)
3362 handled = handle_overlay_change (it);
3363 }
3364
3365 if (it->ellipsis_p)
3366 {
3367 setup_for_ellipsis (it, 0);
3368 break;
3369 }
3370 }
3371 while (handled == HANDLED_RECOMPUTE_PROPS);
3372
3373 /* Determine where to stop next. */
3374 if (handled == HANDLED_NORMALLY)
3375 compute_stop_pos (it);
3376 }
3377
3378
3379 /* Compute IT->stop_charpos from text property and overlay change
3380 information for IT's current position. */
3381
3382 static void
3383 compute_stop_pos (struct it *it)
3384 {
3385 register INTERVAL iv, next_iv;
3386 Lisp_Object object, limit, position;
3387 ptrdiff_t charpos, bytepos;
3388
3389 if (STRINGP (it->string))
3390 {
3391 /* Strings are usually short, so don't limit the search for
3392 properties. */
3393 it->stop_charpos = it->end_charpos;
3394 object = it->string;
3395 limit = Qnil;
3396 charpos = IT_STRING_CHARPOS (*it);
3397 bytepos = IT_STRING_BYTEPOS (*it);
3398 }
3399 else
3400 {
3401 ptrdiff_t pos;
3402
3403 /* If end_charpos is out of range for some reason, such as a
3404 misbehaving display function, rationalize it (Bug#5984). */
3405 if (it->end_charpos > ZV)
3406 it->end_charpos = ZV;
3407 it->stop_charpos = it->end_charpos;
3408
3409 /* If next overlay change is in front of the current stop pos
3410 (which is IT->end_charpos), stop there. Note: value of
3411 next_overlay_change is point-max if no overlay change
3412 follows. */
3413 charpos = IT_CHARPOS (*it);
3414 bytepos = IT_BYTEPOS (*it);
3415 pos = next_overlay_change (charpos);
3416 if (pos < it->stop_charpos)
3417 it->stop_charpos = pos;
3418
3419 /* Set up variables for computing the stop position from text
3420 property changes. */
3421 XSETBUFFER (object, current_buffer);
3422 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3423 }
3424
3425 /* Get the interval containing IT's position. Value is a null
3426 interval if there isn't such an interval. */
3427 position = make_number (charpos);
3428 iv = validate_interval_range (object, &position, &position, 0);
3429 if (iv)
3430 {
3431 Lisp_Object values_here[LAST_PROP_IDX];
3432 struct props *p;
3433
3434 /* Get properties here. */
3435 for (p = it_props; p->handler; ++p)
3436 values_here[p->idx] = textget (iv->plist, *p->name);
3437
3438 /* Look for an interval following iv that has different
3439 properties. */
3440 for (next_iv = next_interval (iv);
3441 (next_iv
3442 && (NILP (limit)
3443 || XFASTINT (limit) > next_iv->position));
3444 next_iv = next_interval (next_iv))
3445 {
3446 for (p = it_props; p->handler; ++p)
3447 {
3448 Lisp_Object new_value;
3449
3450 new_value = textget (next_iv->plist, *p->name);
3451 if (!EQ (values_here[p->idx], new_value))
3452 break;
3453 }
3454
3455 if (p->handler)
3456 break;
3457 }
3458
3459 if (next_iv)
3460 {
3461 if (INTEGERP (limit)
3462 && next_iv->position >= XFASTINT (limit))
3463 /* No text property change up to limit. */
3464 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3465 else
3466 /* Text properties change in next_iv. */
3467 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3468 }
3469 }
3470
3471 if (it->cmp_it.id < 0)
3472 {
3473 ptrdiff_t stoppos = it->end_charpos;
3474
3475 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3476 stoppos = -1;
3477 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3478 stoppos, it->string);
3479 }
3480
3481 eassert (STRINGP (it->string)
3482 || (it->stop_charpos >= BEGV
3483 && it->stop_charpos >= IT_CHARPOS (*it)));
3484 }
3485
3486
3487 /* Return the position of the next overlay change after POS in
3488 current_buffer. Value is point-max if no overlay change
3489 follows. This is like `next-overlay-change' but doesn't use
3490 xmalloc. */
3491
3492 static ptrdiff_t
3493 next_overlay_change (ptrdiff_t pos)
3494 {
3495 ptrdiff_t i, noverlays;
3496 ptrdiff_t endpos;
3497 Lisp_Object *overlays;
3498
3499 /* Get all overlays at the given position. */
3500 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3501
3502 /* If any of these overlays ends before endpos,
3503 use its ending point instead. */
3504 for (i = 0; i < noverlays; ++i)
3505 {
3506 Lisp_Object oend;
3507 ptrdiff_t oendpos;
3508
3509 oend = OVERLAY_END (overlays[i]);
3510 oendpos = OVERLAY_POSITION (oend);
3511 endpos = min (endpos, oendpos);
3512 }
3513
3514 return endpos;
3515 }
3516
3517 /* How many characters forward to search for a display property or
3518 display string. Searching too far forward makes the bidi display
3519 sluggish, especially in small windows. */
3520 #define MAX_DISP_SCAN 250
3521
3522 /* Return the character position of a display string at or after
3523 position specified by POSITION. If no display string exists at or
3524 after POSITION, return ZV. A display string is either an overlay
3525 with `display' property whose value is a string, or a `display'
3526 text property whose value is a string. STRING is data about the
3527 string to iterate; if STRING->lstring is nil, we are iterating a
3528 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3529 on a GUI frame. DISP_PROP is set to zero if we searched
3530 MAX_DISP_SCAN characters forward without finding any display
3531 strings, non-zero otherwise. It is set to 2 if the display string
3532 uses any kind of `(space ...)' spec that will produce a stretch of
3533 white space in the text area. */
3534 ptrdiff_t
3535 compute_display_string_pos (struct text_pos *position,
3536 struct bidi_string_data *string,
3537 struct window *w,
3538 int frame_window_p, int *disp_prop)
3539 {
3540 /* OBJECT = nil means current buffer. */
3541 Lisp_Object object, object1;
3542 Lisp_Object pos, spec, limpos;
3543 int string_p = (string && (STRINGP (string->lstring) || string->s));
3544 ptrdiff_t eob = string_p ? string->schars : ZV;
3545 ptrdiff_t begb = string_p ? 0 : BEGV;
3546 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3547 ptrdiff_t lim =
3548 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3549 struct text_pos tpos;
3550 int rv = 0;
3551
3552 if (string && STRINGP (string->lstring))
3553 object1 = object = string->lstring;
3554 else if (w && !string_p)
3555 {
3556 XSETWINDOW (object, w);
3557 object1 = Qnil;
3558 }
3559 else
3560 object1 = object = Qnil;
3561
3562 *disp_prop = 1;
3563
3564 if (charpos >= eob
3565 /* We don't support display properties whose values are strings
3566 that have display string properties. */
3567 || string->from_disp_str
3568 /* C strings cannot have display properties. */
3569 || (string->s && !STRINGP (object)))
3570 {
3571 *disp_prop = 0;
3572 return eob;
3573 }
3574
3575 /* If the character at CHARPOS is where the display string begins,
3576 return CHARPOS. */
3577 pos = make_number (charpos);
3578 if (STRINGP (object))
3579 bufpos = string->bufpos;
3580 else
3581 bufpos = charpos;
3582 tpos = *position;
3583 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3584 && (charpos <= begb
3585 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3586 object),
3587 spec))
3588 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3589 frame_window_p)))
3590 {
3591 if (rv == 2)
3592 *disp_prop = 2;
3593 return charpos;
3594 }
3595
3596 /* Look forward for the first character with a `display' property
3597 that will replace the underlying text when displayed. */
3598 limpos = make_number (lim);
3599 do {
3600 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3601 CHARPOS (tpos) = XFASTINT (pos);
3602 if (CHARPOS (tpos) >= lim)
3603 {
3604 *disp_prop = 0;
3605 break;
3606 }
3607 if (STRINGP (object))
3608 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3609 else
3610 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3611 spec = Fget_char_property (pos, Qdisplay, object);
3612 if (!STRINGP (object))
3613 bufpos = CHARPOS (tpos);
3614 } while (NILP (spec)
3615 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3616 bufpos, frame_window_p)));
3617 if (rv == 2)
3618 *disp_prop = 2;
3619
3620 return CHARPOS (tpos);
3621 }
3622
3623 /* Return the character position of the end of the display string that
3624 started at CHARPOS. If there's no display string at CHARPOS,
3625 return -1. A display string is either an overlay with `display'
3626 property whose value is a string or a `display' text property whose
3627 value is a string. */
3628 ptrdiff_t
3629 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3630 {
3631 /* OBJECT = nil means current buffer. */
3632 Lisp_Object object =
3633 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3634 Lisp_Object pos = make_number (charpos);
3635 ptrdiff_t eob =
3636 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3637
3638 if (charpos >= eob || (string->s && !STRINGP (object)))
3639 return eob;
3640
3641 /* It could happen that the display property or overlay was removed
3642 since we found it in compute_display_string_pos above. One way
3643 this can happen is if JIT font-lock was called (through
3644 handle_fontified_prop), and jit-lock-functions remove text
3645 properties or overlays from the portion of buffer that includes
3646 CHARPOS. Muse mode is known to do that, for example. In this
3647 case, we return -1 to the caller, to signal that no display
3648 string is actually present at CHARPOS. See bidi_fetch_char for
3649 how this is handled.
3650
3651 An alternative would be to never look for display properties past
3652 it->stop_charpos. But neither compute_display_string_pos nor
3653 bidi_fetch_char that calls it know or care where the next
3654 stop_charpos is. */
3655 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3656 return -1;
3657
3658 /* Look forward for the first character where the `display' property
3659 changes. */
3660 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3661
3662 return XFASTINT (pos);
3663 }
3664
3665
3666 \f
3667 /***********************************************************************
3668 Fontification
3669 ***********************************************************************/
3670
3671 /* Handle changes in the `fontified' property of the current buffer by
3672 calling hook functions from Qfontification_functions to fontify
3673 regions of text. */
3674
3675 static enum prop_handled
3676 handle_fontified_prop (struct it *it)
3677 {
3678 Lisp_Object prop, pos;
3679 enum prop_handled handled = HANDLED_NORMALLY;
3680
3681 if (!NILP (Vmemory_full))
3682 return handled;
3683
3684 /* Get the value of the `fontified' property at IT's current buffer
3685 position. (The `fontified' property doesn't have a special
3686 meaning in strings.) If the value is nil, call functions from
3687 Qfontification_functions. */
3688 if (!STRINGP (it->string)
3689 && it->s == NULL
3690 && !NILP (Vfontification_functions)
3691 && !NILP (Vrun_hooks)
3692 && (pos = make_number (IT_CHARPOS (*it)),
3693 prop = Fget_char_property (pos, Qfontified, Qnil),
3694 /* Ignore the special cased nil value always present at EOB since
3695 no amount of fontifying will be able to change it. */
3696 NILP (prop) && IT_CHARPOS (*it) < Z))
3697 {
3698 ptrdiff_t count = SPECPDL_INDEX ();
3699 Lisp_Object val;
3700 struct buffer *obuf = current_buffer;
3701 ptrdiff_t begv = BEGV, zv = ZV;
3702 bool old_clip_changed = current_buffer->clip_changed;
3703
3704 val = Vfontification_functions;
3705 specbind (Qfontification_functions, Qnil);
3706
3707 eassert (it->end_charpos == ZV);
3708
3709 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3710 safe_call1 (val, pos);
3711 else
3712 {
3713 Lisp_Object fns, fn;
3714 struct gcpro gcpro1, gcpro2;
3715
3716 fns = Qnil;
3717 GCPRO2 (val, fns);
3718
3719 for (; CONSP (val); val = XCDR (val))
3720 {
3721 fn = XCAR (val);
3722
3723 if (EQ (fn, Qt))
3724 {
3725 /* A value of t indicates this hook has a local
3726 binding; it means to run the global binding too.
3727 In a global value, t should not occur. If it
3728 does, we must ignore it to avoid an endless
3729 loop. */
3730 for (fns = Fdefault_value (Qfontification_functions);
3731 CONSP (fns);
3732 fns = XCDR (fns))
3733 {
3734 fn = XCAR (fns);
3735 if (!EQ (fn, Qt))
3736 safe_call1 (fn, pos);
3737 }
3738 }
3739 else
3740 safe_call1 (fn, pos);
3741 }
3742
3743 UNGCPRO;
3744 }
3745
3746 unbind_to (count, Qnil);
3747
3748 /* Fontification functions routinely call `save-restriction'.
3749 Normally, this tags clip_changed, which can confuse redisplay
3750 (see discussion in Bug#6671). Since we don't perform any
3751 special handling of fontification changes in the case where
3752 `save-restriction' isn't called, there's no point doing so in
3753 this case either. So, if the buffer's restrictions are
3754 actually left unchanged, reset clip_changed. */
3755 if (obuf == current_buffer)
3756 {
3757 if (begv == BEGV && zv == ZV)
3758 current_buffer->clip_changed = old_clip_changed;
3759 }
3760 /* There isn't much we can reasonably do to protect against
3761 misbehaving fontification, but here's a fig leaf. */
3762 else if (BUFFER_LIVE_P (obuf))
3763 set_buffer_internal_1 (obuf);
3764
3765 /* The fontification code may have added/removed text.
3766 It could do even a lot worse, but let's at least protect against
3767 the most obvious case where only the text past `pos' gets changed',
3768 as is/was done in grep.el where some escapes sequences are turned
3769 into face properties (bug#7876). */
3770 it->end_charpos = ZV;
3771
3772 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3773 something. This avoids an endless loop if they failed to
3774 fontify the text for which reason ever. */
3775 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3776 handled = HANDLED_RECOMPUTE_PROPS;
3777 }
3778
3779 return handled;
3780 }
3781
3782
3783 \f
3784 /***********************************************************************
3785 Faces
3786 ***********************************************************************/
3787
3788 /* Set up iterator IT from face properties at its current position.
3789 Called from handle_stop. */
3790
3791 static enum prop_handled
3792 handle_face_prop (struct it *it)
3793 {
3794 int new_face_id;
3795 ptrdiff_t next_stop;
3796
3797 if (!STRINGP (it->string))
3798 {
3799 new_face_id
3800 = face_at_buffer_position (it->w,
3801 IT_CHARPOS (*it),
3802 &next_stop,
3803 (IT_CHARPOS (*it)
3804 + TEXT_PROP_DISTANCE_LIMIT),
3805 0, it->base_face_id);
3806
3807 /* Is this a start of a run of characters with box face?
3808 Caveat: this can be called for a freshly initialized
3809 iterator; face_id is -1 in this case. We know that the new
3810 face will not change until limit, i.e. if the new face has a
3811 box, all characters up to limit will have one. But, as
3812 usual, we don't know whether limit is really the end. */
3813 if (new_face_id != it->face_id)
3814 {
3815 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3816 /* If it->face_id is -1, old_face below will be NULL, see
3817 the definition of FACE_FROM_ID. This will happen if this
3818 is the initial call that gets the face. */
3819 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3820
3821 /* If the value of face_id of the iterator is -1, we have to
3822 look in front of IT's position and see whether there is a
3823 face there that's different from new_face_id. */
3824 if (!old_face && IT_CHARPOS (*it) > BEG)
3825 {
3826 int prev_face_id = face_before_it_pos (it);
3827
3828 old_face = FACE_FROM_ID (it->f, prev_face_id);
3829 }
3830
3831 /* If the new face has a box, but the old face does not,
3832 this is the start of a run of characters with box face,
3833 i.e. this character has a shadow on the left side. */
3834 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3835 && (old_face == NULL || !old_face->box));
3836 it->face_box_p = new_face->box != FACE_NO_BOX;
3837 }
3838 }
3839 else
3840 {
3841 int base_face_id;
3842 ptrdiff_t bufpos;
3843 int i;
3844 Lisp_Object from_overlay
3845 = (it->current.overlay_string_index >= 0
3846 ? it->string_overlays[it->current.overlay_string_index
3847 % OVERLAY_STRING_CHUNK_SIZE]
3848 : Qnil);
3849
3850 /* See if we got to this string directly or indirectly from
3851 an overlay property. That includes the before-string or
3852 after-string of an overlay, strings in display properties
3853 provided by an overlay, their text properties, etc.
3854
3855 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3856 if (! NILP (from_overlay))
3857 for (i = it->sp - 1; i >= 0; i--)
3858 {
3859 if (it->stack[i].current.overlay_string_index >= 0)
3860 from_overlay
3861 = it->string_overlays[it->stack[i].current.overlay_string_index
3862 % OVERLAY_STRING_CHUNK_SIZE];
3863 else if (! NILP (it->stack[i].from_overlay))
3864 from_overlay = it->stack[i].from_overlay;
3865
3866 if (!NILP (from_overlay))
3867 break;
3868 }
3869
3870 if (! NILP (from_overlay))
3871 {
3872 bufpos = IT_CHARPOS (*it);
3873 /* For a string from an overlay, the base face depends
3874 only on text properties and ignores overlays. */
3875 base_face_id
3876 = face_for_overlay_string (it->w,
3877 IT_CHARPOS (*it),
3878 &next_stop,
3879 (IT_CHARPOS (*it)
3880 + TEXT_PROP_DISTANCE_LIMIT),
3881 0,
3882 from_overlay);
3883 }
3884 else
3885 {
3886 bufpos = 0;
3887
3888 /* For strings from a `display' property, use the face at
3889 IT's current buffer position as the base face to merge
3890 with, so that overlay strings appear in the same face as
3891 surrounding text, unless they specify their own faces.
3892 For strings from wrap-prefix and line-prefix properties,
3893 use the default face, possibly remapped via
3894 Vface_remapping_alist. */
3895 base_face_id = it->string_from_prefix_prop_p
3896 ? (!NILP (Vface_remapping_alist)
3897 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
3898 : DEFAULT_FACE_ID)
3899 : underlying_face_id (it);
3900 }
3901
3902 new_face_id = face_at_string_position (it->w,
3903 it->string,
3904 IT_STRING_CHARPOS (*it),
3905 bufpos,
3906 &next_stop,
3907 base_face_id, 0);
3908
3909 /* Is this a start of a run of characters with box? Caveat:
3910 this can be called for a freshly allocated iterator; face_id
3911 is -1 is this case. We know that the new face will not
3912 change until the next check pos, i.e. if the new face has a
3913 box, all characters up to that position will have a
3914 box. But, as usual, we don't know whether that position
3915 is really the end. */
3916 if (new_face_id != it->face_id)
3917 {
3918 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3919 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3920
3921 /* If new face has a box but old face hasn't, this is the
3922 start of a run of characters with box, i.e. it has a
3923 shadow on the left side. */
3924 it->start_of_box_run_p
3925 = new_face->box && (old_face == NULL || !old_face->box);
3926 it->face_box_p = new_face->box != FACE_NO_BOX;
3927 }
3928 }
3929
3930 it->face_id = new_face_id;
3931 return HANDLED_NORMALLY;
3932 }
3933
3934
3935 /* Return the ID of the face ``underlying'' IT's current position,
3936 which is in a string. If the iterator is associated with a
3937 buffer, return the face at IT's current buffer position.
3938 Otherwise, use the iterator's base_face_id. */
3939
3940 static int
3941 underlying_face_id (struct it *it)
3942 {
3943 int face_id = it->base_face_id, i;
3944
3945 eassert (STRINGP (it->string));
3946
3947 for (i = it->sp - 1; i >= 0; --i)
3948 if (NILP (it->stack[i].string))
3949 face_id = it->stack[i].face_id;
3950
3951 return face_id;
3952 }
3953
3954
3955 /* Compute the face one character before or after the current position
3956 of IT, in the visual order. BEFORE_P non-zero means get the face
3957 in front (to the left in L2R paragraphs, to the right in R2L
3958 paragraphs) of IT's screen position. Value is the ID of the face. */
3959
3960 static int
3961 face_before_or_after_it_pos (struct it *it, int before_p)
3962 {
3963 int face_id, limit;
3964 ptrdiff_t next_check_charpos;
3965 struct it it_copy;
3966 void *it_copy_data = NULL;
3967
3968 eassert (it->s == NULL);
3969
3970 if (STRINGP (it->string))
3971 {
3972 ptrdiff_t bufpos, charpos;
3973 int base_face_id;
3974
3975 /* No face change past the end of the string (for the case
3976 we are padding with spaces). No face change before the
3977 string start. */
3978 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3979 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3980 return it->face_id;
3981
3982 if (!it->bidi_p)
3983 {
3984 /* Set charpos to the position before or after IT's current
3985 position, in the logical order, which in the non-bidi
3986 case is the same as the visual order. */
3987 if (before_p)
3988 charpos = IT_STRING_CHARPOS (*it) - 1;
3989 else if (it->what == IT_COMPOSITION)
3990 /* For composition, we must check the character after the
3991 composition. */
3992 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3993 else
3994 charpos = IT_STRING_CHARPOS (*it) + 1;
3995 }
3996 else
3997 {
3998 if (before_p)
3999 {
4000 /* With bidi iteration, the character before the current
4001 in the visual order cannot be found by simple
4002 iteration, because "reverse" reordering is not
4003 supported. Instead, we need to use the move_it_*
4004 family of functions. */
4005 /* Ignore face changes before the first visible
4006 character on this display line. */
4007 if (it->current_x <= it->first_visible_x)
4008 return it->face_id;
4009 SAVE_IT (it_copy, *it, it_copy_data);
4010 /* Implementation note: Since move_it_in_display_line
4011 works in the iterator geometry, and thinks the first
4012 character is always the leftmost, even in R2L lines,
4013 we don't need to distinguish between the R2L and L2R
4014 cases here. */
4015 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4016 it_copy.current_x - 1, MOVE_TO_X);
4017 charpos = IT_STRING_CHARPOS (it_copy);
4018 RESTORE_IT (it, it, it_copy_data);
4019 }
4020 else
4021 {
4022 /* Set charpos to the string position of the character
4023 that comes after IT's current position in the visual
4024 order. */
4025 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4026
4027 it_copy = *it;
4028 while (n--)
4029 bidi_move_to_visually_next (&it_copy.bidi_it);
4030
4031 charpos = it_copy.bidi_it.charpos;
4032 }
4033 }
4034 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4035
4036 if (it->current.overlay_string_index >= 0)
4037 bufpos = IT_CHARPOS (*it);
4038 else
4039 bufpos = 0;
4040
4041 base_face_id = underlying_face_id (it);
4042
4043 /* Get the face for ASCII, or unibyte. */
4044 face_id = face_at_string_position (it->w,
4045 it->string,
4046 charpos,
4047 bufpos,
4048 &next_check_charpos,
4049 base_face_id, 0);
4050
4051 /* Correct the face for charsets different from ASCII. Do it
4052 for the multibyte case only. The face returned above is
4053 suitable for unibyte text if IT->string is unibyte. */
4054 if (STRING_MULTIBYTE (it->string))
4055 {
4056 struct text_pos pos1 = string_pos (charpos, it->string);
4057 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4058 int c, len;
4059 struct face *face = FACE_FROM_ID (it->f, face_id);
4060
4061 c = string_char_and_length (p, &len);
4062 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4063 }
4064 }
4065 else
4066 {
4067 struct text_pos pos;
4068
4069 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4070 || (IT_CHARPOS (*it) <= BEGV && before_p))
4071 return it->face_id;
4072
4073 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4074 pos = it->current.pos;
4075
4076 if (!it->bidi_p)
4077 {
4078 if (before_p)
4079 DEC_TEXT_POS (pos, it->multibyte_p);
4080 else
4081 {
4082 if (it->what == IT_COMPOSITION)
4083 {
4084 /* For composition, we must check the position after
4085 the composition. */
4086 pos.charpos += it->cmp_it.nchars;
4087 pos.bytepos += it->len;
4088 }
4089 else
4090 INC_TEXT_POS (pos, it->multibyte_p);
4091 }
4092 }
4093 else
4094 {
4095 if (before_p)
4096 {
4097 /* With bidi iteration, the character before the current
4098 in the visual order cannot be found by simple
4099 iteration, because "reverse" reordering is not
4100 supported. Instead, we need to use the move_it_*
4101 family of functions. */
4102 /* Ignore face changes before the first visible
4103 character on this display line. */
4104 if (it->current_x <= it->first_visible_x)
4105 return it->face_id;
4106 SAVE_IT (it_copy, *it, it_copy_data);
4107 /* Implementation note: Since move_it_in_display_line
4108 works in the iterator geometry, and thinks the first
4109 character is always the leftmost, even in R2L lines,
4110 we don't need to distinguish between the R2L and L2R
4111 cases here. */
4112 move_it_in_display_line (&it_copy, ZV,
4113 it_copy.current_x - 1, MOVE_TO_X);
4114 pos = it_copy.current.pos;
4115 RESTORE_IT (it, it, it_copy_data);
4116 }
4117 else
4118 {
4119 /* Set charpos to the buffer position of the character
4120 that comes after IT's current position in the visual
4121 order. */
4122 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4123
4124 it_copy = *it;
4125 while (n--)
4126 bidi_move_to_visually_next (&it_copy.bidi_it);
4127
4128 SET_TEXT_POS (pos,
4129 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4130 }
4131 }
4132 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4133
4134 /* Determine face for CHARSET_ASCII, or unibyte. */
4135 face_id = face_at_buffer_position (it->w,
4136 CHARPOS (pos),
4137 &next_check_charpos,
4138 limit, 0, -1);
4139
4140 /* Correct the face for charsets different from ASCII. Do it
4141 for the multibyte case only. The face returned above is
4142 suitable for unibyte text if current_buffer is unibyte. */
4143 if (it->multibyte_p)
4144 {
4145 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4146 struct face *face = FACE_FROM_ID (it->f, face_id);
4147 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4148 }
4149 }
4150
4151 return face_id;
4152 }
4153
4154
4155 \f
4156 /***********************************************************************
4157 Invisible text
4158 ***********************************************************************/
4159
4160 /* Set up iterator IT from invisible properties at its current
4161 position. Called from handle_stop. */
4162
4163 static enum prop_handled
4164 handle_invisible_prop (struct it *it)
4165 {
4166 enum prop_handled handled = HANDLED_NORMALLY;
4167 int invis_p;
4168 Lisp_Object prop;
4169
4170 if (STRINGP (it->string))
4171 {
4172 Lisp_Object end_charpos, limit, charpos;
4173
4174 /* Get the value of the invisible text property at the
4175 current position. Value will be nil if there is no such
4176 property. */
4177 charpos = make_number (IT_STRING_CHARPOS (*it));
4178 prop = Fget_text_property (charpos, Qinvisible, it->string);
4179 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4180
4181 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4182 {
4183 /* Record whether we have to display an ellipsis for the
4184 invisible text. */
4185 int display_ellipsis_p = (invis_p == 2);
4186 ptrdiff_t len, endpos;
4187
4188 handled = HANDLED_RECOMPUTE_PROPS;
4189
4190 /* Get the position at which the next visible text can be
4191 found in IT->string, if any. */
4192 endpos = len = SCHARS (it->string);
4193 XSETINT (limit, len);
4194 do
4195 {
4196 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4197 it->string, limit);
4198 if (INTEGERP (end_charpos))
4199 {
4200 endpos = XFASTINT (end_charpos);
4201 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4202 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4203 if (invis_p == 2)
4204 display_ellipsis_p = 1;
4205 }
4206 }
4207 while (invis_p && endpos < len);
4208
4209 if (display_ellipsis_p)
4210 it->ellipsis_p = 1;
4211
4212 if (endpos < len)
4213 {
4214 /* Text at END_CHARPOS is visible. Move IT there. */
4215 struct text_pos old;
4216 ptrdiff_t oldpos;
4217
4218 old = it->current.string_pos;
4219 oldpos = CHARPOS (old);
4220 if (it->bidi_p)
4221 {
4222 if (it->bidi_it.first_elt
4223 && it->bidi_it.charpos < SCHARS (it->string))
4224 bidi_paragraph_init (it->paragraph_embedding,
4225 &it->bidi_it, 1);
4226 /* Bidi-iterate out of the invisible text. */
4227 do
4228 {
4229 bidi_move_to_visually_next (&it->bidi_it);
4230 }
4231 while (oldpos <= it->bidi_it.charpos
4232 && it->bidi_it.charpos < endpos);
4233
4234 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4235 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4236 if (IT_CHARPOS (*it) >= endpos)
4237 it->prev_stop = endpos;
4238 }
4239 else
4240 {
4241 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4242 compute_string_pos (&it->current.string_pos, old, it->string);
4243 }
4244 }
4245 else
4246 {
4247 /* The rest of the string is invisible. If this is an
4248 overlay string, proceed with the next overlay string
4249 or whatever comes and return a character from there. */
4250 if (it->current.overlay_string_index >= 0
4251 && !display_ellipsis_p)
4252 {
4253 next_overlay_string (it);
4254 /* Don't check for overlay strings when we just
4255 finished processing them. */
4256 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4257 }
4258 else
4259 {
4260 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4261 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4262 }
4263 }
4264 }
4265 }
4266 else
4267 {
4268 ptrdiff_t newpos, next_stop, start_charpos, tem;
4269 Lisp_Object pos, overlay;
4270
4271 /* First of all, is there invisible text at this position? */
4272 tem = start_charpos = IT_CHARPOS (*it);
4273 pos = make_number (tem);
4274 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4275 &overlay);
4276 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4277
4278 /* If we are on invisible text, skip over it. */
4279 if (invis_p && start_charpos < it->end_charpos)
4280 {
4281 /* Record whether we have to display an ellipsis for the
4282 invisible text. */
4283 int display_ellipsis_p = invis_p == 2;
4284
4285 handled = HANDLED_RECOMPUTE_PROPS;
4286
4287 /* Loop skipping over invisible text. The loop is left at
4288 ZV or with IT on the first char being visible again. */
4289 do
4290 {
4291 /* Try to skip some invisible text. Return value is the
4292 position reached which can be equal to where we start
4293 if there is nothing invisible there. This skips both
4294 over invisible text properties and overlays with
4295 invisible property. */
4296 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4297
4298 /* If we skipped nothing at all we weren't at invisible
4299 text in the first place. If everything to the end of
4300 the buffer was skipped, end the loop. */
4301 if (newpos == tem || newpos >= ZV)
4302 invis_p = 0;
4303 else
4304 {
4305 /* We skipped some characters but not necessarily
4306 all there are. Check if we ended up on visible
4307 text. Fget_char_property returns the property of
4308 the char before the given position, i.e. if we
4309 get invis_p = 0, this means that the char at
4310 newpos is visible. */
4311 pos = make_number (newpos);
4312 prop = Fget_char_property (pos, Qinvisible, it->window);
4313 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4314 }
4315
4316 /* If we ended up on invisible text, proceed to
4317 skip starting with next_stop. */
4318 if (invis_p)
4319 tem = next_stop;
4320
4321 /* If there are adjacent invisible texts, don't lose the
4322 second one's ellipsis. */
4323 if (invis_p == 2)
4324 display_ellipsis_p = 1;
4325 }
4326 while (invis_p);
4327
4328 /* The position newpos is now either ZV or on visible text. */
4329 if (it->bidi_p)
4330 {
4331 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4332 int on_newline =
4333 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4334 int after_newline =
4335 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4336
4337 /* If the invisible text ends on a newline or on a
4338 character after a newline, we can avoid the costly,
4339 character by character, bidi iteration to NEWPOS, and
4340 instead simply reseat the iterator there. That's
4341 because all bidi reordering information is tossed at
4342 the newline. This is a big win for modes that hide
4343 complete lines, like Outline, Org, etc. */
4344 if (on_newline || after_newline)
4345 {
4346 struct text_pos tpos;
4347 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4348
4349 SET_TEXT_POS (tpos, newpos, bpos);
4350 reseat_1 (it, tpos, 0);
4351 /* If we reseat on a newline/ZV, we need to prep the
4352 bidi iterator for advancing to the next character
4353 after the newline/EOB, keeping the current paragraph
4354 direction (so that PRODUCE_GLYPHS does TRT wrt
4355 prepending/appending glyphs to a glyph row). */
4356 if (on_newline)
4357 {
4358 it->bidi_it.first_elt = 0;
4359 it->bidi_it.paragraph_dir = pdir;
4360 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4361 it->bidi_it.nchars = 1;
4362 it->bidi_it.ch_len = 1;
4363 }
4364 }
4365 else /* Must use the slow method. */
4366 {
4367 /* With bidi iteration, the region of invisible text
4368 could start and/or end in the middle of a
4369 non-base embedding level. Therefore, we need to
4370 skip invisible text using the bidi iterator,
4371 starting at IT's current position, until we find
4372 ourselves outside of the invisible text.
4373 Skipping invisible text _after_ bidi iteration
4374 avoids affecting the visual order of the
4375 displayed text when invisible properties are
4376 added or removed. */
4377 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4378 {
4379 /* If we were `reseat'ed to a new paragraph,
4380 determine the paragraph base direction. We
4381 need to do it now because
4382 next_element_from_buffer may not have a
4383 chance to do it, if we are going to skip any
4384 text at the beginning, which resets the
4385 FIRST_ELT flag. */
4386 bidi_paragraph_init (it->paragraph_embedding,
4387 &it->bidi_it, 1);
4388 }
4389 do
4390 {
4391 bidi_move_to_visually_next (&it->bidi_it);
4392 }
4393 while (it->stop_charpos <= it->bidi_it.charpos
4394 && it->bidi_it.charpos < newpos);
4395 IT_CHARPOS (*it) = it->bidi_it.charpos;
4396 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4397 /* If we overstepped NEWPOS, record its position in
4398 the iterator, so that we skip invisible text if
4399 later the bidi iteration lands us in the
4400 invisible region again. */
4401 if (IT_CHARPOS (*it) >= newpos)
4402 it->prev_stop = newpos;
4403 }
4404 }
4405 else
4406 {
4407 IT_CHARPOS (*it) = newpos;
4408 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4409 }
4410
4411 /* If there are before-strings at the start of invisible
4412 text, and the text is invisible because of a text
4413 property, arrange to show before-strings because 20.x did
4414 it that way. (If the text is invisible because of an
4415 overlay property instead of a text property, this is
4416 already handled in the overlay code.) */
4417 if (NILP (overlay)
4418 && get_overlay_strings (it, it->stop_charpos))
4419 {
4420 handled = HANDLED_RECOMPUTE_PROPS;
4421 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4422 }
4423 else if (display_ellipsis_p)
4424 {
4425 /* Make sure that the glyphs of the ellipsis will get
4426 correct `charpos' values. If we would not update
4427 it->position here, the glyphs would belong to the
4428 last visible character _before_ the invisible
4429 text, which confuses `set_cursor_from_row'.
4430
4431 We use the last invisible position instead of the
4432 first because this way the cursor is always drawn on
4433 the first "." of the ellipsis, whenever PT is inside
4434 the invisible text. Otherwise the cursor would be
4435 placed _after_ the ellipsis when the point is after the
4436 first invisible character. */
4437 if (!STRINGP (it->object))
4438 {
4439 it->position.charpos = newpos - 1;
4440 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4441 }
4442 it->ellipsis_p = 1;
4443 /* Let the ellipsis display before
4444 considering any properties of the following char.
4445 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4446 handled = HANDLED_RETURN;
4447 }
4448 }
4449 }
4450
4451 return handled;
4452 }
4453
4454
4455 /* Make iterator IT return `...' next.
4456 Replaces LEN characters from buffer. */
4457
4458 static void
4459 setup_for_ellipsis (struct it *it, int len)
4460 {
4461 /* Use the display table definition for `...'. Invalid glyphs
4462 will be handled by the method returning elements from dpvec. */
4463 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4464 {
4465 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4466 it->dpvec = v->contents;
4467 it->dpend = v->contents + v->header.size;
4468 }
4469 else
4470 {
4471 /* Default `...'. */
4472 it->dpvec = default_invis_vector;
4473 it->dpend = default_invis_vector + 3;
4474 }
4475
4476 it->dpvec_char_len = len;
4477 it->current.dpvec_index = 0;
4478 it->dpvec_face_id = -1;
4479
4480 /* Remember the current face id in case glyphs specify faces.
4481 IT's face is restored in set_iterator_to_next.
4482 saved_face_id was set to preceding char's face in handle_stop. */
4483 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4484 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4485
4486 it->method = GET_FROM_DISPLAY_VECTOR;
4487 it->ellipsis_p = 1;
4488 }
4489
4490
4491 \f
4492 /***********************************************************************
4493 'display' property
4494 ***********************************************************************/
4495
4496 /* Set up iterator IT from `display' property at its current position.
4497 Called from handle_stop.
4498 We return HANDLED_RETURN if some part of the display property
4499 overrides the display of the buffer text itself.
4500 Otherwise we return HANDLED_NORMALLY. */
4501
4502 static enum prop_handled
4503 handle_display_prop (struct it *it)
4504 {
4505 Lisp_Object propval, object, overlay;
4506 struct text_pos *position;
4507 ptrdiff_t bufpos;
4508 /* Nonzero if some property replaces the display of the text itself. */
4509 int display_replaced_p = 0;
4510
4511 if (STRINGP (it->string))
4512 {
4513 object = it->string;
4514 position = &it->current.string_pos;
4515 bufpos = CHARPOS (it->current.pos);
4516 }
4517 else
4518 {
4519 XSETWINDOW (object, it->w);
4520 position = &it->current.pos;
4521 bufpos = CHARPOS (*position);
4522 }
4523
4524 /* Reset those iterator values set from display property values. */
4525 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4526 it->space_width = Qnil;
4527 it->font_height = Qnil;
4528 it->voffset = 0;
4529
4530 /* We don't support recursive `display' properties, i.e. string
4531 values that have a string `display' property, that have a string
4532 `display' property etc. */
4533 if (!it->string_from_display_prop_p)
4534 it->area = TEXT_AREA;
4535
4536 propval = get_char_property_and_overlay (make_number (position->charpos),
4537 Qdisplay, object, &overlay);
4538 if (NILP (propval))
4539 return HANDLED_NORMALLY;
4540 /* Now OVERLAY is the overlay that gave us this property, or nil
4541 if it was a text property. */
4542
4543 if (!STRINGP (it->string))
4544 object = it->w->contents;
4545
4546 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4547 position, bufpos,
4548 FRAME_WINDOW_P (it->f));
4549
4550 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4551 }
4552
4553 /* Subroutine of handle_display_prop. Returns non-zero if the display
4554 specification in SPEC is a replacing specification, i.e. it would
4555 replace the text covered by `display' property with something else,
4556 such as an image or a display string. If SPEC includes any kind or
4557 `(space ...) specification, the value is 2; this is used by
4558 compute_display_string_pos, which see.
4559
4560 See handle_single_display_spec for documentation of arguments.
4561 frame_window_p is non-zero if the window being redisplayed is on a
4562 GUI frame; this argument is used only if IT is NULL, see below.
4563
4564 IT can be NULL, if this is called by the bidi reordering code
4565 through compute_display_string_pos, which see. In that case, this
4566 function only examines SPEC, but does not otherwise "handle" it, in
4567 the sense that it doesn't set up members of IT from the display
4568 spec. */
4569 static int
4570 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4571 Lisp_Object overlay, struct text_pos *position,
4572 ptrdiff_t bufpos, int frame_window_p)
4573 {
4574 int replacing_p = 0;
4575 int rv;
4576
4577 if (CONSP (spec)
4578 /* Simple specifications. */
4579 && !EQ (XCAR (spec), Qimage)
4580 && !EQ (XCAR (spec), Qspace)
4581 && !EQ (XCAR (spec), Qwhen)
4582 && !EQ (XCAR (spec), Qslice)
4583 && !EQ (XCAR (spec), Qspace_width)
4584 && !EQ (XCAR (spec), Qheight)
4585 && !EQ (XCAR (spec), Qraise)
4586 /* Marginal area specifications. */
4587 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4588 && !EQ (XCAR (spec), Qleft_fringe)
4589 && !EQ (XCAR (spec), Qright_fringe)
4590 && !NILP (XCAR (spec)))
4591 {
4592 for (; CONSP (spec); spec = XCDR (spec))
4593 {
4594 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4595 overlay, position, bufpos,
4596 replacing_p, frame_window_p)))
4597 {
4598 replacing_p = rv;
4599 /* If some text in a string is replaced, `position' no
4600 longer points to the position of `object'. */
4601 if (!it || STRINGP (object))
4602 break;
4603 }
4604 }
4605 }
4606 else if (VECTORP (spec))
4607 {
4608 ptrdiff_t i;
4609 for (i = 0; i < ASIZE (spec); ++i)
4610 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4611 overlay, position, bufpos,
4612 replacing_p, frame_window_p)))
4613 {
4614 replacing_p = rv;
4615 /* If some text in a string is replaced, `position' no
4616 longer points to the position of `object'. */
4617 if (!it || STRINGP (object))
4618 break;
4619 }
4620 }
4621 else
4622 {
4623 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4624 position, bufpos, 0,
4625 frame_window_p)))
4626 replacing_p = rv;
4627 }
4628
4629 return replacing_p;
4630 }
4631
4632 /* Value is the position of the end of the `display' property starting
4633 at START_POS in OBJECT. */
4634
4635 static struct text_pos
4636 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4637 {
4638 Lisp_Object end;
4639 struct text_pos end_pos;
4640
4641 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4642 Qdisplay, object, Qnil);
4643 CHARPOS (end_pos) = XFASTINT (end);
4644 if (STRINGP (object))
4645 compute_string_pos (&end_pos, start_pos, it->string);
4646 else
4647 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4648
4649 return end_pos;
4650 }
4651
4652
4653 /* Set up IT from a single `display' property specification SPEC. OBJECT
4654 is the object in which the `display' property was found. *POSITION
4655 is the position in OBJECT at which the `display' property was found.
4656 BUFPOS is the buffer position of OBJECT (different from POSITION if
4657 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4658 previously saw a display specification which already replaced text
4659 display with something else, for example an image; we ignore such
4660 properties after the first one has been processed.
4661
4662 OVERLAY is the overlay this `display' property came from,
4663 or nil if it was a text property.
4664
4665 If SPEC is a `space' or `image' specification, and in some other
4666 cases too, set *POSITION to the position where the `display'
4667 property ends.
4668
4669 If IT is NULL, only examine the property specification in SPEC, but
4670 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4671 is intended to be displayed in a window on a GUI frame.
4672
4673 Value is non-zero if something was found which replaces the display
4674 of buffer or string text. */
4675
4676 static int
4677 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4678 Lisp_Object overlay, struct text_pos *position,
4679 ptrdiff_t bufpos, int display_replaced_p,
4680 int frame_window_p)
4681 {
4682 Lisp_Object form;
4683 Lisp_Object location, value;
4684 struct text_pos start_pos = *position;
4685 int valid_p;
4686
4687 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4688 If the result is non-nil, use VALUE instead of SPEC. */
4689 form = Qt;
4690 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4691 {
4692 spec = XCDR (spec);
4693 if (!CONSP (spec))
4694 return 0;
4695 form = XCAR (spec);
4696 spec = XCDR (spec);
4697 }
4698
4699 if (!NILP (form) && !EQ (form, Qt))
4700 {
4701 ptrdiff_t count = SPECPDL_INDEX ();
4702 struct gcpro gcpro1;
4703
4704 /* Bind `object' to the object having the `display' property, a
4705 buffer or string. Bind `position' to the position in the
4706 object where the property was found, and `buffer-position'
4707 to the current position in the buffer. */
4708
4709 if (NILP (object))
4710 XSETBUFFER (object, current_buffer);
4711 specbind (Qobject, object);
4712 specbind (Qposition, make_number (CHARPOS (*position)));
4713 specbind (Qbuffer_position, make_number (bufpos));
4714 GCPRO1 (form);
4715 form = safe_eval (form);
4716 UNGCPRO;
4717 unbind_to (count, Qnil);
4718 }
4719
4720 if (NILP (form))
4721 return 0;
4722
4723 /* Handle `(height HEIGHT)' specifications. */
4724 if (CONSP (spec)
4725 && EQ (XCAR (spec), Qheight)
4726 && CONSP (XCDR (spec)))
4727 {
4728 if (it)
4729 {
4730 if (!FRAME_WINDOW_P (it->f))
4731 return 0;
4732
4733 it->font_height = XCAR (XCDR (spec));
4734 if (!NILP (it->font_height))
4735 {
4736 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4737 int new_height = -1;
4738
4739 if (CONSP (it->font_height)
4740 && (EQ (XCAR (it->font_height), Qplus)
4741 || EQ (XCAR (it->font_height), Qminus))
4742 && CONSP (XCDR (it->font_height))
4743 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4744 {
4745 /* `(+ N)' or `(- N)' where N is an integer. */
4746 int steps = XINT (XCAR (XCDR (it->font_height)));
4747 if (EQ (XCAR (it->font_height), Qplus))
4748 steps = - steps;
4749 it->face_id = smaller_face (it->f, it->face_id, steps);
4750 }
4751 else if (FUNCTIONP (it->font_height))
4752 {
4753 /* Call function with current height as argument.
4754 Value is the new height. */
4755 Lisp_Object height;
4756 height = safe_call1 (it->font_height,
4757 face->lface[LFACE_HEIGHT_INDEX]);
4758 if (NUMBERP (height))
4759 new_height = XFLOATINT (height);
4760 }
4761 else if (NUMBERP (it->font_height))
4762 {
4763 /* Value is a multiple of the canonical char height. */
4764 struct face *f;
4765
4766 f = FACE_FROM_ID (it->f,
4767 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4768 new_height = (XFLOATINT (it->font_height)
4769 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4770 }
4771 else
4772 {
4773 /* Evaluate IT->font_height with `height' bound to the
4774 current specified height to get the new height. */
4775 ptrdiff_t count = SPECPDL_INDEX ();
4776
4777 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4778 value = safe_eval (it->font_height);
4779 unbind_to (count, Qnil);
4780
4781 if (NUMBERP (value))
4782 new_height = XFLOATINT (value);
4783 }
4784
4785 if (new_height > 0)
4786 it->face_id = face_with_height (it->f, it->face_id, new_height);
4787 }
4788 }
4789
4790 return 0;
4791 }
4792
4793 /* Handle `(space-width WIDTH)'. */
4794 if (CONSP (spec)
4795 && EQ (XCAR (spec), Qspace_width)
4796 && CONSP (XCDR (spec)))
4797 {
4798 if (it)
4799 {
4800 if (!FRAME_WINDOW_P (it->f))
4801 return 0;
4802
4803 value = XCAR (XCDR (spec));
4804 if (NUMBERP (value) && XFLOATINT (value) > 0)
4805 it->space_width = value;
4806 }
4807
4808 return 0;
4809 }
4810
4811 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4812 if (CONSP (spec)
4813 && EQ (XCAR (spec), Qslice))
4814 {
4815 Lisp_Object tem;
4816
4817 if (it)
4818 {
4819 if (!FRAME_WINDOW_P (it->f))
4820 return 0;
4821
4822 if (tem = XCDR (spec), CONSP (tem))
4823 {
4824 it->slice.x = XCAR (tem);
4825 if (tem = XCDR (tem), CONSP (tem))
4826 {
4827 it->slice.y = XCAR (tem);
4828 if (tem = XCDR (tem), CONSP (tem))
4829 {
4830 it->slice.width = XCAR (tem);
4831 if (tem = XCDR (tem), CONSP (tem))
4832 it->slice.height = XCAR (tem);
4833 }
4834 }
4835 }
4836 }
4837
4838 return 0;
4839 }
4840
4841 /* Handle `(raise FACTOR)'. */
4842 if (CONSP (spec)
4843 && EQ (XCAR (spec), Qraise)
4844 && CONSP (XCDR (spec)))
4845 {
4846 if (it)
4847 {
4848 if (!FRAME_WINDOW_P (it->f))
4849 return 0;
4850
4851 #ifdef HAVE_WINDOW_SYSTEM
4852 value = XCAR (XCDR (spec));
4853 if (NUMBERP (value))
4854 {
4855 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4856 it->voffset = - (XFLOATINT (value)
4857 * (FONT_HEIGHT (face->font)));
4858 }
4859 #endif /* HAVE_WINDOW_SYSTEM */
4860 }
4861
4862 return 0;
4863 }
4864
4865 /* Don't handle the other kinds of display specifications
4866 inside a string that we got from a `display' property. */
4867 if (it && it->string_from_display_prop_p)
4868 return 0;
4869
4870 /* Characters having this form of property are not displayed, so
4871 we have to find the end of the property. */
4872 if (it)
4873 {
4874 start_pos = *position;
4875 *position = display_prop_end (it, object, start_pos);
4876 }
4877 value = Qnil;
4878
4879 /* Stop the scan at that end position--we assume that all
4880 text properties change there. */
4881 if (it)
4882 it->stop_charpos = position->charpos;
4883
4884 /* Handle `(left-fringe BITMAP [FACE])'
4885 and `(right-fringe BITMAP [FACE])'. */
4886 if (CONSP (spec)
4887 && (EQ (XCAR (spec), Qleft_fringe)
4888 || EQ (XCAR (spec), Qright_fringe))
4889 && CONSP (XCDR (spec)))
4890 {
4891 int fringe_bitmap;
4892
4893 if (it)
4894 {
4895 if (!FRAME_WINDOW_P (it->f))
4896 /* If we return here, POSITION has been advanced
4897 across the text with this property. */
4898 {
4899 /* Synchronize the bidi iterator with POSITION. This is
4900 needed because we are not going to push the iterator
4901 on behalf of this display property, so there will be
4902 no pop_it call to do this synchronization for us. */
4903 if (it->bidi_p)
4904 {
4905 it->position = *position;
4906 iterate_out_of_display_property (it);
4907 *position = it->position;
4908 }
4909 return 1;
4910 }
4911 }
4912 else if (!frame_window_p)
4913 return 1;
4914
4915 #ifdef HAVE_WINDOW_SYSTEM
4916 value = XCAR (XCDR (spec));
4917 if (!SYMBOLP (value)
4918 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4919 /* If we return here, POSITION has been advanced
4920 across the text with this property. */
4921 {
4922 if (it && it->bidi_p)
4923 {
4924 it->position = *position;
4925 iterate_out_of_display_property (it);
4926 *position = it->position;
4927 }
4928 return 1;
4929 }
4930
4931 if (it)
4932 {
4933 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4934
4935 if (CONSP (XCDR (XCDR (spec))))
4936 {
4937 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4938 int face_id2 = lookup_derived_face (it->f, face_name,
4939 FRINGE_FACE_ID, 0);
4940 if (face_id2 >= 0)
4941 face_id = face_id2;
4942 }
4943
4944 /* Save current settings of IT so that we can restore them
4945 when we are finished with the glyph property value. */
4946 push_it (it, position);
4947
4948 it->area = TEXT_AREA;
4949 it->what = IT_IMAGE;
4950 it->image_id = -1; /* no image */
4951 it->position = start_pos;
4952 it->object = NILP (object) ? it->w->contents : object;
4953 it->method = GET_FROM_IMAGE;
4954 it->from_overlay = Qnil;
4955 it->face_id = face_id;
4956 it->from_disp_prop_p = 1;
4957
4958 /* Say that we haven't consumed the characters with
4959 `display' property yet. The call to pop_it in
4960 set_iterator_to_next will clean this up. */
4961 *position = start_pos;
4962
4963 if (EQ (XCAR (spec), Qleft_fringe))
4964 {
4965 it->left_user_fringe_bitmap = fringe_bitmap;
4966 it->left_user_fringe_face_id = face_id;
4967 }
4968 else
4969 {
4970 it->right_user_fringe_bitmap = fringe_bitmap;
4971 it->right_user_fringe_face_id = face_id;
4972 }
4973 }
4974 #endif /* HAVE_WINDOW_SYSTEM */
4975 return 1;
4976 }
4977
4978 /* Prepare to handle `((margin left-margin) ...)',
4979 `((margin right-margin) ...)' and `((margin nil) ...)'
4980 prefixes for display specifications. */
4981 location = Qunbound;
4982 if (CONSP (spec) && CONSP (XCAR (spec)))
4983 {
4984 Lisp_Object tem;
4985
4986 value = XCDR (spec);
4987 if (CONSP (value))
4988 value = XCAR (value);
4989
4990 tem = XCAR (spec);
4991 if (EQ (XCAR (tem), Qmargin)
4992 && (tem = XCDR (tem),
4993 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4994 (NILP (tem)
4995 || EQ (tem, Qleft_margin)
4996 || EQ (tem, Qright_margin))))
4997 location = tem;
4998 }
4999
5000 if (EQ (location, Qunbound))
5001 {
5002 location = Qnil;
5003 value = spec;
5004 }
5005
5006 /* After this point, VALUE is the property after any
5007 margin prefix has been stripped. It must be a string,
5008 an image specification, or `(space ...)'.
5009
5010 LOCATION specifies where to display: `left-margin',
5011 `right-margin' or nil. */
5012
5013 valid_p = (STRINGP (value)
5014 #ifdef HAVE_WINDOW_SYSTEM
5015 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5016 && valid_image_p (value))
5017 #endif /* not HAVE_WINDOW_SYSTEM */
5018 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5019
5020 if (valid_p && !display_replaced_p)
5021 {
5022 int retval = 1;
5023
5024 if (!it)
5025 {
5026 /* Callers need to know whether the display spec is any kind
5027 of `(space ...)' spec that is about to affect text-area
5028 display. */
5029 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5030 retval = 2;
5031 return retval;
5032 }
5033
5034 /* Save current settings of IT so that we can restore them
5035 when we are finished with the glyph property value. */
5036 push_it (it, position);
5037 it->from_overlay = overlay;
5038 it->from_disp_prop_p = 1;
5039
5040 if (NILP (location))
5041 it->area = TEXT_AREA;
5042 else if (EQ (location, Qleft_margin))
5043 it->area = LEFT_MARGIN_AREA;
5044 else
5045 it->area = RIGHT_MARGIN_AREA;
5046
5047 if (STRINGP (value))
5048 {
5049 it->string = value;
5050 it->multibyte_p = STRING_MULTIBYTE (it->string);
5051 it->current.overlay_string_index = -1;
5052 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5053 it->end_charpos = it->string_nchars = SCHARS (it->string);
5054 it->method = GET_FROM_STRING;
5055 it->stop_charpos = 0;
5056 it->prev_stop = 0;
5057 it->base_level_stop = 0;
5058 it->string_from_display_prop_p = 1;
5059 /* Say that we haven't consumed the characters with
5060 `display' property yet. The call to pop_it in
5061 set_iterator_to_next will clean this up. */
5062 if (BUFFERP (object))
5063 *position = start_pos;
5064
5065 /* Force paragraph direction to be that of the parent
5066 object. If the parent object's paragraph direction is
5067 not yet determined, default to L2R. */
5068 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5069 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5070 else
5071 it->paragraph_embedding = L2R;
5072
5073 /* Set up the bidi iterator for this display string. */
5074 if (it->bidi_p)
5075 {
5076 it->bidi_it.string.lstring = it->string;
5077 it->bidi_it.string.s = NULL;
5078 it->bidi_it.string.schars = it->end_charpos;
5079 it->bidi_it.string.bufpos = bufpos;
5080 it->bidi_it.string.from_disp_str = 1;
5081 it->bidi_it.string.unibyte = !it->multibyte_p;
5082 it->bidi_it.w = it->w;
5083 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5084 }
5085 }
5086 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5087 {
5088 it->method = GET_FROM_STRETCH;
5089 it->object = value;
5090 *position = it->position = start_pos;
5091 retval = 1 + (it->area == TEXT_AREA);
5092 }
5093 #ifdef HAVE_WINDOW_SYSTEM
5094 else
5095 {
5096 it->what = IT_IMAGE;
5097 it->image_id = lookup_image (it->f, value);
5098 it->position = start_pos;
5099 it->object = NILP (object) ? it->w->contents : object;
5100 it->method = GET_FROM_IMAGE;
5101
5102 /* Say that we haven't consumed the characters with
5103 `display' property yet. The call to pop_it in
5104 set_iterator_to_next will clean this up. */
5105 *position = start_pos;
5106 }
5107 #endif /* HAVE_WINDOW_SYSTEM */
5108
5109 return retval;
5110 }
5111
5112 /* Invalid property or property not supported. Restore
5113 POSITION to what it was before. */
5114 *position = start_pos;
5115 return 0;
5116 }
5117
5118 /* Check if PROP is a display property value whose text should be
5119 treated as intangible. OVERLAY is the overlay from which PROP
5120 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5121 specify the buffer position covered by PROP. */
5122
5123 int
5124 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5125 ptrdiff_t charpos, ptrdiff_t bytepos)
5126 {
5127 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5128 struct text_pos position;
5129
5130 SET_TEXT_POS (position, charpos, bytepos);
5131 return handle_display_spec (NULL, prop, Qnil, overlay,
5132 &position, charpos, frame_window_p);
5133 }
5134
5135
5136 /* Return 1 if PROP is a display sub-property value containing STRING.
5137
5138 Implementation note: this and the following function are really
5139 special cases of handle_display_spec and
5140 handle_single_display_spec, and should ideally use the same code.
5141 Until they do, these two pairs must be consistent and must be
5142 modified in sync. */
5143
5144 static int
5145 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5146 {
5147 if (EQ (string, prop))
5148 return 1;
5149
5150 /* Skip over `when FORM'. */
5151 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5152 {
5153 prop = XCDR (prop);
5154 if (!CONSP (prop))
5155 return 0;
5156 /* Actually, the condition following `when' should be eval'ed,
5157 like handle_single_display_spec does, and we should return
5158 zero if it evaluates to nil. However, this function is
5159 called only when the buffer was already displayed and some
5160 glyph in the glyph matrix was found to come from a display
5161 string. Therefore, the condition was already evaluated, and
5162 the result was non-nil, otherwise the display string wouldn't
5163 have been displayed and we would have never been called for
5164 this property. Thus, we can skip the evaluation and assume
5165 its result is non-nil. */
5166 prop = XCDR (prop);
5167 }
5168
5169 if (CONSP (prop))
5170 /* Skip over `margin LOCATION'. */
5171 if (EQ (XCAR (prop), Qmargin))
5172 {
5173 prop = XCDR (prop);
5174 if (!CONSP (prop))
5175 return 0;
5176
5177 prop = XCDR (prop);
5178 if (!CONSP (prop))
5179 return 0;
5180 }
5181
5182 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5183 }
5184
5185
5186 /* Return 1 if STRING appears in the `display' property PROP. */
5187
5188 static int
5189 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5190 {
5191 if (CONSP (prop)
5192 && !EQ (XCAR (prop), Qwhen)
5193 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5194 {
5195 /* A list of sub-properties. */
5196 while (CONSP (prop))
5197 {
5198 if (single_display_spec_string_p (XCAR (prop), string))
5199 return 1;
5200 prop = XCDR (prop);
5201 }
5202 }
5203 else if (VECTORP (prop))
5204 {
5205 /* A vector of sub-properties. */
5206 ptrdiff_t i;
5207 for (i = 0; i < ASIZE (prop); ++i)
5208 if (single_display_spec_string_p (AREF (prop, i), string))
5209 return 1;
5210 }
5211 else
5212 return single_display_spec_string_p (prop, string);
5213
5214 return 0;
5215 }
5216
5217 /* Look for STRING in overlays and text properties in the current
5218 buffer, between character positions FROM and TO (excluding TO).
5219 BACK_P non-zero means look back (in this case, TO is supposed to be
5220 less than FROM).
5221 Value is the first character position where STRING was found, or
5222 zero if it wasn't found before hitting TO.
5223
5224 This function may only use code that doesn't eval because it is
5225 called asynchronously from note_mouse_highlight. */
5226
5227 static ptrdiff_t
5228 string_buffer_position_lim (Lisp_Object string,
5229 ptrdiff_t from, ptrdiff_t to, int back_p)
5230 {
5231 Lisp_Object limit, prop, pos;
5232 int found = 0;
5233
5234 pos = make_number (max (from, BEGV));
5235
5236 if (!back_p) /* looking forward */
5237 {
5238 limit = make_number (min (to, ZV));
5239 while (!found && !EQ (pos, limit))
5240 {
5241 prop = Fget_char_property (pos, Qdisplay, Qnil);
5242 if (!NILP (prop) && display_prop_string_p (prop, string))
5243 found = 1;
5244 else
5245 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5246 limit);
5247 }
5248 }
5249 else /* looking back */
5250 {
5251 limit = make_number (max (to, BEGV));
5252 while (!found && !EQ (pos, limit))
5253 {
5254 prop = Fget_char_property (pos, Qdisplay, Qnil);
5255 if (!NILP (prop) && display_prop_string_p (prop, string))
5256 found = 1;
5257 else
5258 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5259 limit);
5260 }
5261 }
5262
5263 return found ? XINT (pos) : 0;
5264 }
5265
5266 /* Determine which buffer position in current buffer STRING comes from.
5267 AROUND_CHARPOS is an approximate position where it could come from.
5268 Value is the buffer position or 0 if it couldn't be determined.
5269
5270 This function is necessary because we don't record buffer positions
5271 in glyphs generated from strings (to keep struct glyph small).
5272 This function may only use code that doesn't eval because it is
5273 called asynchronously from note_mouse_highlight. */
5274
5275 static ptrdiff_t
5276 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5277 {
5278 const int MAX_DISTANCE = 1000;
5279 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5280 around_charpos + MAX_DISTANCE,
5281 0);
5282
5283 if (!found)
5284 found = string_buffer_position_lim (string, around_charpos,
5285 around_charpos - MAX_DISTANCE, 1);
5286 return found;
5287 }
5288
5289
5290 \f
5291 /***********************************************************************
5292 `composition' property
5293 ***********************************************************************/
5294
5295 /* Set up iterator IT from `composition' property at its current
5296 position. Called from handle_stop. */
5297
5298 static enum prop_handled
5299 handle_composition_prop (struct it *it)
5300 {
5301 Lisp_Object prop, string;
5302 ptrdiff_t pos, pos_byte, start, end;
5303
5304 if (STRINGP (it->string))
5305 {
5306 unsigned char *s;
5307
5308 pos = IT_STRING_CHARPOS (*it);
5309 pos_byte = IT_STRING_BYTEPOS (*it);
5310 string = it->string;
5311 s = SDATA (string) + pos_byte;
5312 it->c = STRING_CHAR (s);
5313 }
5314 else
5315 {
5316 pos = IT_CHARPOS (*it);
5317 pos_byte = IT_BYTEPOS (*it);
5318 string = Qnil;
5319 it->c = FETCH_CHAR (pos_byte);
5320 }
5321
5322 /* If there's a valid composition and point is not inside of the
5323 composition (in the case that the composition is from the current
5324 buffer), draw a glyph composed from the composition components. */
5325 if (find_composition (pos, -1, &start, &end, &prop, string)
5326 && composition_valid_p (start, end, prop)
5327 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5328 {
5329 if (start < pos)
5330 /* As we can't handle this situation (perhaps font-lock added
5331 a new composition), we just return here hoping that next
5332 redisplay will detect this composition much earlier. */
5333 return HANDLED_NORMALLY;
5334 if (start != pos)
5335 {
5336 if (STRINGP (it->string))
5337 pos_byte = string_char_to_byte (it->string, start);
5338 else
5339 pos_byte = CHAR_TO_BYTE (start);
5340 }
5341 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5342 prop, string);
5343
5344 if (it->cmp_it.id >= 0)
5345 {
5346 it->cmp_it.ch = -1;
5347 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5348 it->cmp_it.nglyphs = -1;
5349 }
5350 }
5351
5352 return HANDLED_NORMALLY;
5353 }
5354
5355
5356 \f
5357 /***********************************************************************
5358 Overlay strings
5359 ***********************************************************************/
5360
5361 /* The following structure is used to record overlay strings for
5362 later sorting in load_overlay_strings. */
5363
5364 struct overlay_entry
5365 {
5366 Lisp_Object overlay;
5367 Lisp_Object string;
5368 EMACS_INT priority;
5369 int after_string_p;
5370 };
5371
5372
5373 /* Set up iterator IT from overlay strings at its current position.
5374 Called from handle_stop. */
5375
5376 static enum prop_handled
5377 handle_overlay_change (struct it *it)
5378 {
5379 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5380 return HANDLED_RECOMPUTE_PROPS;
5381 else
5382 return HANDLED_NORMALLY;
5383 }
5384
5385
5386 /* Set up the next overlay string for delivery by IT, if there is an
5387 overlay string to deliver. Called by set_iterator_to_next when the
5388 end of the current overlay string is reached. If there are more
5389 overlay strings to display, IT->string and
5390 IT->current.overlay_string_index are set appropriately here.
5391 Otherwise IT->string is set to nil. */
5392
5393 static void
5394 next_overlay_string (struct it *it)
5395 {
5396 ++it->current.overlay_string_index;
5397 if (it->current.overlay_string_index == it->n_overlay_strings)
5398 {
5399 /* No more overlay strings. Restore IT's settings to what
5400 they were before overlay strings were processed, and
5401 continue to deliver from current_buffer. */
5402
5403 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5404 pop_it (it);
5405 eassert (it->sp > 0
5406 || (NILP (it->string)
5407 && it->method == GET_FROM_BUFFER
5408 && it->stop_charpos >= BEGV
5409 && it->stop_charpos <= it->end_charpos));
5410 it->current.overlay_string_index = -1;
5411 it->n_overlay_strings = 0;
5412 it->overlay_strings_charpos = -1;
5413 /* If there's an empty display string on the stack, pop the
5414 stack, to resync the bidi iterator with IT's position. Such
5415 empty strings are pushed onto the stack in
5416 get_overlay_strings_1. */
5417 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5418 pop_it (it);
5419
5420 /* If we're at the end of the buffer, record that we have
5421 processed the overlay strings there already, so that
5422 next_element_from_buffer doesn't try it again. */
5423 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5424 it->overlay_strings_at_end_processed_p = 1;
5425 }
5426 else
5427 {
5428 /* There are more overlay strings to process. If
5429 IT->current.overlay_string_index has advanced to a position
5430 where we must load IT->overlay_strings with more strings, do
5431 it. We must load at the IT->overlay_strings_charpos where
5432 IT->n_overlay_strings was originally computed; when invisible
5433 text is present, this might not be IT_CHARPOS (Bug#7016). */
5434 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5435
5436 if (it->current.overlay_string_index && i == 0)
5437 load_overlay_strings (it, it->overlay_strings_charpos);
5438
5439 /* Initialize IT to deliver display elements from the overlay
5440 string. */
5441 it->string = it->overlay_strings[i];
5442 it->multibyte_p = STRING_MULTIBYTE (it->string);
5443 SET_TEXT_POS (it->current.string_pos, 0, 0);
5444 it->method = GET_FROM_STRING;
5445 it->stop_charpos = 0;
5446 it->end_charpos = SCHARS (it->string);
5447 if (it->cmp_it.stop_pos >= 0)
5448 it->cmp_it.stop_pos = 0;
5449 it->prev_stop = 0;
5450 it->base_level_stop = 0;
5451
5452 /* Set up the bidi iterator for this overlay string. */
5453 if (it->bidi_p)
5454 {
5455 it->bidi_it.string.lstring = it->string;
5456 it->bidi_it.string.s = NULL;
5457 it->bidi_it.string.schars = SCHARS (it->string);
5458 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5459 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5460 it->bidi_it.string.unibyte = !it->multibyte_p;
5461 it->bidi_it.w = it->w;
5462 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5463 }
5464 }
5465
5466 CHECK_IT (it);
5467 }
5468
5469
5470 /* Compare two overlay_entry structures E1 and E2. Used as a
5471 comparison function for qsort in load_overlay_strings. Overlay
5472 strings for the same position are sorted so that
5473
5474 1. All after-strings come in front of before-strings, except
5475 when they come from the same overlay.
5476
5477 2. Within after-strings, strings are sorted so that overlay strings
5478 from overlays with higher priorities come first.
5479
5480 2. Within before-strings, strings are sorted so that overlay
5481 strings from overlays with higher priorities come last.
5482
5483 Value is analogous to strcmp. */
5484
5485
5486 static int
5487 compare_overlay_entries (const void *e1, const void *e2)
5488 {
5489 struct overlay_entry const *entry1 = e1;
5490 struct overlay_entry const *entry2 = e2;
5491 int result;
5492
5493 if (entry1->after_string_p != entry2->after_string_p)
5494 {
5495 /* Let after-strings appear in front of before-strings if
5496 they come from different overlays. */
5497 if (EQ (entry1->overlay, entry2->overlay))
5498 result = entry1->after_string_p ? 1 : -1;
5499 else
5500 result = entry1->after_string_p ? -1 : 1;
5501 }
5502 else if (entry1->priority != entry2->priority)
5503 {
5504 if (entry1->after_string_p)
5505 /* After-strings sorted in order of decreasing priority. */
5506 result = entry2->priority < entry1->priority ? -1 : 1;
5507 else
5508 /* Before-strings sorted in order of increasing priority. */
5509 result = entry1->priority < entry2->priority ? -1 : 1;
5510 }
5511 else
5512 result = 0;
5513
5514 return result;
5515 }
5516
5517
5518 /* Load the vector IT->overlay_strings with overlay strings from IT's
5519 current buffer position, or from CHARPOS if that is > 0. Set
5520 IT->n_overlays to the total number of overlay strings found.
5521
5522 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5523 a time. On entry into load_overlay_strings,
5524 IT->current.overlay_string_index gives the number of overlay
5525 strings that have already been loaded by previous calls to this
5526 function.
5527
5528 IT->add_overlay_start contains an additional overlay start
5529 position to consider for taking overlay strings from, if non-zero.
5530 This position comes into play when the overlay has an `invisible'
5531 property, and both before and after-strings. When we've skipped to
5532 the end of the overlay, because of its `invisible' property, we
5533 nevertheless want its before-string to appear.
5534 IT->add_overlay_start will contain the overlay start position
5535 in this case.
5536
5537 Overlay strings are sorted so that after-string strings come in
5538 front of before-string strings. Within before and after-strings,
5539 strings are sorted by overlay priority. See also function
5540 compare_overlay_entries. */
5541
5542 static void
5543 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5544 {
5545 Lisp_Object overlay, window, str, invisible;
5546 struct Lisp_Overlay *ov;
5547 ptrdiff_t start, end;
5548 ptrdiff_t size = 20;
5549 ptrdiff_t n = 0, i, j;
5550 int invis_p;
5551 struct overlay_entry *entries = alloca (size * sizeof *entries);
5552 USE_SAFE_ALLOCA;
5553
5554 if (charpos <= 0)
5555 charpos = IT_CHARPOS (*it);
5556
5557 /* Append the overlay string STRING of overlay OVERLAY to vector
5558 `entries' which has size `size' and currently contains `n'
5559 elements. AFTER_P non-zero means STRING is an after-string of
5560 OVERLAY. */
5561 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5562 do \
5563 { \
5564 Lisp_Object priority; \
5565 \
5566 if (n == size) \
5567 { \
5568 struct overlay_entry *old = entries; \
5569 SAFE_NALLOCA (entries, 2, size); \
5570 memcpy (entries, old, size * sizeof *entries); \
5571 size *= 2; \
5572 } \
5573 \
5574 entries[n].string = (STRING); \
5575 entries[n].overlay = (OVERLAY); \
5576 priority = Foverlay_get ((OVERLAY), Qpriority); \
5577 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5578 entries[n].after_string_p = (AFTER_P); \
5579 ++n; \
5580 } \
5581 while (0)
5582
5583 /* Process overlay before the overlay center. */
5584 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5585 {
5586 XSETMISC (overlay, ov);
5587 eassert (OVERLAYP (overlay));
5588 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5589 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5590
5591 if (end < charpos)
5592 break;
5593
5594 /* Skip this overlay if it doesn't start or end at IT's current
5595 position. */
5596 if (end != charpos && start != charpos)
5597 continue;
5598
5599 /* Skip this overlay if it doesn't apply to IT->w. */
5600 window = Foverlay_get (overlay, Qwindow);
5601 if (WINDOWP (window) && XWINDOW (window) != it->w)
5602 continue;
5603
5604 /* If the text ``under'' the overlay is invisible, both before-
5605 and after-strings from this overlay are visible; start and
5606 end position are indistinguishable. */
5607 invisible = Foverlay_get (overlay, Qinvisible);
5608 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5609
5610 /* If overlay has a non-empty before-string, record it. */
5611 if ((start == charpos || (end == charpos && invis_p))
5612 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5613 && SCHARS (str))
5614 RECORD_OVERLAY_STRING (overlay, str, 0);
5615
5616 /* If overlay has a non-empty after-string, record it. */
5617 if ((end == charpos || (start == charpos && invis_p))
5618 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5619 && SCHARS (str))
5620 RECORD_OVERLAY_STRING (overlay, str, 1);
5621 }
5622
5623 /* Process overlays after the overlay center. */
5624 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5625 {
5626 XSETMISC (overlay, ov);
5627 eassert (OVERLAYP (overlay));
5628 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5629 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5630
5631 if (start > charpos)
5632 break;
5633
5634 /* Skip this overlay if it doesn't start or end at IT's current
5635 position. */
5636 if (end != charpos && start != charpos)
5637 continue;
5638
5639 /* Skip this overlay if it doesn't apply to IT->w. */
5640 window = Foverlay_get (overlay, Qwindow);
5641 if (WINDOWP (window) && XWINDOW (window) != it->w)
5642 continue;
5643
5644 /* If the text ``under'' the overlay is invisible, it has a zero
5645 dimension, and both before- and after-strings apply. */
5646 invisible = Foverlay_get (overlay, Qinvisible);
5647 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5648
5649 /* If overlay has a non-empty before-string, record it. */
5650 if ((start == charpos || (end == charpos && invis_p))
5651 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5652 && SCHARS (str))
5653 RECORD_OVERLAY_STRING (overlay, str, 0);
5654
5655 /* If overlay has a non-empty after-string, record it. */
5656 if ((end == charpos || (start == charpos && invis_p))
5657 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5658 && SCHARS (str))
5659 RECORD_OVERLAY_STRING (overlay, str, 1);
5660 }
5661
5662 #undef RECORD_OVERLAY_STRING
5663
5664 /* Sort entries. */
5665 if (n > 1)
5666 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5667
5668 /* Record number of overlay strings, and where we computed it. */
5669 it->n_overlay_strings = n;
5670 it->overlay_strings_charpos = charpos;
5671
5672 /* IT->current.overlay_string_index is the number of overlay strings
5673 that have already been consumed by IT. Copy some of the
5674 remaining overlay strings to IT->overlay_strings. */
5675 i = 0;
5676 j = it->current.overlay_string_index;
5677 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5678 {
5679 it->overlay_strings[i] = entries[j].string;
5680 it->string_overlays[i++] = entries[j++].overlay;
5681 }
5682
5683 CHECK_IT (it);
5684 SAFE_FREE ();
5685 }
5686
5687
5688 /* Get the first chunk of overlay strings at IT's current buffer
5689 position, or at CHARPOS if that is > 0. Value is non-zero if at
5690 least one overlay string was found. */
5691
5692 static int
5693 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5694 {
5695 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5696 process. This fills IT->overlay_strings with strings, and sets
5697 IT->n_overlay_strings to the total number of strings to process.
5698 IT->pos.overlay_string_index has to be set temporarily to zero
5699 because load_overlay_strings needs this; it must be set to -1
5700 when no overlay strings are found because a zero value would
5701 indicate a position in the first overlay string. */
5702 it->current.overlay_string_index = 0;
5703 load_overlay_strings (it, charpos);
5704
5705 /* If we found overlay strings, set up IT to deliver display
5706 elements from the first one. Otherwise set up IT to deliver
5707 from current_buffer. */
5708 if (it->n_overlay_strings)
5709 {
5710 /* Make sure we know settings in current_buffer, so that we can
5711 restore meaningful values when we're done with the overlay
5712 strings. */
5713 if (compute_stop_p)
5714 compute_stop_pos (it);
5715 eassert (it->face_id >= 0);
5716
5717 /* Save IT's settings. They are restored after all overlay
5718 strings have been processed. */
5719 eassert (!compute_stop_p || it->sp == 0);
5720
5721 /* When called from handle_stop, there might be an empty display
5722 string loaded. In that case, don't bother saving it. But
5723 don't use this optimization with the bidi iterator, since we
5724 need the corresponding pop_it call to resync the bidi
5725 iterator's position with IT's position, after we are done
5726 with the overlay strings. (The corresponding call to pop_it
5727 in case of an empty display string is in
5728 next_overlay_string.) */
5729 if (!(!it->bidi_p
5730 && STRINGP (it->string) && !SCHARS (it->string)))
5731 push_it (it, NULL);
5732
5733 /* Set up IT to deliver display elements from the first overlay
5734 string. */
5735 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5736 it->string = it->overlay_strings[0];
5737 it->from_overlay = Qnil;
5738 it->stop_charpos = 0;
5739 eassert (STRINGP (it->string));
5740 it->end_charpos = SCHARS (it->string);
5741 it->prev_stop = 0;
5742 it->base_level_stop = 0;
5743 it->multibyte_p = STRING_MULTIBYTE (it->string);
5744 it->method = GET_FROM_STRING;
5745 it->from_disp_prop_p = 0;
5746
5747 /* Force paragraph direction to be that of the parent
5748 buffer. */
5749 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5750 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5751 else
5752 it->paragraph_embedding = L2R;
5753
5754 /* Set up the bidi iterator for this overlay string. */
5755 if (it->bidi_p)
5756 {
5757 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5758
5759 it->bidi_it.string.lstring = it->string;
5760 it->bidi_it.string.s = NULL;
5761 it->bidi_it.string.schars = SCHARS (it->string);
5762 it->bidi_it.string.bufpos = pos;
5763 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5764 it->bidi_it.string.unibyte = !it->multibyte_p;
5765 it->bidi_it.w = it->w;
5766 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5767 }
5768 return 1;
5769 }
5770
5771 it->current.overlay_string_index = -1;
5772 return 0;
5773 }
5774
5775 static int
5776 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5777 {
5778 it->string = Qnil;
5779 it->method = GET_FROM_BUFFER;
5780
5781 (void) get_overlay_strings_1 (it, charpos, 1);
5782
5783 CHECK_IT (it);
5784
5785 /* Value is non-zero if we found at least one overlay string. */
5786 return STRINGP (it->string);
5787 }
5788
5789
5790 \f
5791 /***********************************************************************
5792 Saving and restoring state
5793 ***********************************************************************/
5794
5795 /* Save current settings of IT on IT->stack. Called, for example,
5796 before setting up IT for an overlay string, to be able to restore
5797 IT's settings to what they were after the overlay string has been
5798 processed. If POSITION is non-NULL, it is the position to save on
5799 the stack instead of IT->position. */
5800
5801 static void
5802 push_it (struct it *it, struct text_pos *position)
5803 {
5804 struct iterator_stack_entry *p;
5805
5806 eassert (it->sp < IT_STACK_SIZE);
5807 p = it->stack + it->sp;
5808
5809 p->stop_charpos = it->stop_charpos;
5810 p->prev_stop = it->prev_stop;
5811 p->base_level_stop = it->base_level_stop;
5812 p->cmp_it = it->cmp_it;
5813 eassert (it->face_id >= 0);
5814 p->face_id = it->face_id;
5815 p->string = it->string;
5816 p->method = it->method;
5817 p->from_overlay = it->from_overlay;
5818 switch (p->method)
5819 {
5820 case GET_FROM_IMAGE:
5821 p->u.image.object = it->object;
5822 p->u.image.image_id = it->image_id;
5823 p->u.image.slice = it->slice;
5824 break;
5825 case GET_FROM_STRETCH:
5826 p->u.stretch.object = it->object;
5827 break;
5828 }
5829 p->position = position ? *position : it->position;
5830 p->current = it->current;
5831 p->end_charpos = it->end_charpos;
5832 p->string_nchars = it->string_nchars;
5833 p->area = it->area;
5834 p->multibyte_p = it->multibyte_p;
5835 p->avoid_cursor_p = it->avoid_cursor_p;
5836 p->space_width = it->space_width;
5837 p->font_height = it->font_height;
5838 p->voffset = it->voffset;
5839 p->string_from_display_prop_p = it->string_from_display_prop_p;
5840 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5841 p->display_ellipsis_p = 0;
5842 p->line_wrap = it->line_wrap;
5843 p->bidi_p = it->bidi_p;
5844 p->paragraph_embedding = it->paragraph_embedding;
5845 p->from_disp_prop_p = it->from_disp_prop_p;
5846 ++it->sp;
5847
5848 /* Save the state of the bidi iterator as well. */
5849 if (it->bidi_p)
5850 bidi_push_it (&it->bidi_it);
5851 }
5852
5853 static void
5854 iterate_out_of_display_property (struct it *it)
5855 {
5856 int buffer_p = !STRINGP (it->string);
5857 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5858 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5859
5860 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5861
5862 /* Maybe initialize paragraph direction. If we are at the beginning
5863 of a new paragraph, next_element_from_buffer may not have a
5864 chance to do that. */
5865 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5866 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5867 /* prev_stop can be zero, so check against BEGV as well. */
5868 while (it->bidi_it.charpos >= bob
5869 && it->prev_stop <= it->bidi_it.charpos
5870 && it->bidi_it.charpos < CHARPOS (it->position)
5871 && it->bidi_it.charpos < eob)
5872 bidi_move_to_visually_next (&it->bidi_it);
5873 /* Record the stop_pos we just crossed, for when we cross it
5874 back, maybe. */
5875 if (it->bidi_it.charpos > CHARPOS (it->position))
5876 it->prev_stop = CHARPOS (it->position);
5877 /* If we ended up not where pop_it put us, resync IT's
5878 positional members with the bidi iterator. */
5879 if (it->bidi_it.charpos != CHARPOS (it->position))
5880 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5881 if (buffer_p)
5882 it->current.pos = it->position;
5883 else
5884 it->current.string_pos = it->position;
5885 }
5886
5887 /* Restore IT's settings from IT->stack. Called, for example, when no
5888 more overlay strings must be processed, and we return to delivering
5889 display elements from a buffer, or when the end of a string from a
5890 `display' property is reached and we return to delivering display
5891 elements from an overlay string, or from a buffer. */
5892
5893 static void
5894 pop_it (struct it *it)
5895 {
5896 struct iterator_stack_entry *p;
5897 int from_display_prop = it->from_disp_prop_p;
5898
5899 eassert (it->sp > 0);
5900 --it->sp;
5901 p = it->stack + it->sp;
5902 it->stop_charpos = p->stop_charpos;
5903 it->prev_stop = p->prev_stop;
5904 it->base_level_stop = p->base_level_stop;
5905 it->cmp_it = p->cmp_it;
5906 it->face_id = p->face_id;
5907 it->current = p->current;
5908 it->position = p->position;
5909 it->string = p->string;
5910 it->from_overlay = p->from_overlay;
5911 if (NILP (it->string))
5912 SET_TEXT_POS (it->current.string_pos, -1, -1);
5913 it->method = p->method;
5914 switch (it->method)
5915 {
5916 case GET_FROM_IMAGE:
5917 it->image_id = p->u.image.image_id;
5918 it->object = p->u.image.object;
5919 it->slice = p->u.image.slice;
5920 break;
5921 case GET_FROM_STRETCH:
5922 it->object = p->u.stretch.object;
5923 break;
5924 case GET_FROM_BUFFER:
5925 it->object = it->w->contents;
5926 break;
5927 case GET_FROM_STRING:
5928 it->object = it->string;
5929 break;
5930 case GET_FROM_DISPLAY_VECTOR:
5931 if (it->s)
5932 it->method = GET_FROM_C_STRING;
5933 else if (STRINGP (it->string))
5934 it->method = GET_FROM_STRING;
5935 else
5936 {
5937 it->method = GET_FROM_BUFFER;
5938 it->object = it->w->contents;
5939 }
5940 }
5941 it->end_charpos = p->end_charpos;
5942 it->string_nchars = p->string_nchars;
5943 it->area = p->area;
5944 it->multibyte_p = p->multibyte_p;
5945 it->avoid_cursor_p = p->avoid_cursor_p;
5946 it->space_width = p->space_width;
5947 it->font_height = p->font_height;
5948 it->voffset = p->voffset;
5949 it->string_from_display_prop_p = p->string_from_display_prop_p;
5950 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5951 it->line_wrap = p->line_wrap;
5952 it->bidi_p = p->bidi_p;
5953 it->paragraph_embedding = p->paragraph_embedding;
5954 it->from_disp_prop_p = p->from_disp_prop_p;
5955 if (it->bidi_p)
5956 {
5957 bidi_pop_it (&it->bidi_it);
5958 /* Bidi-iterate until we get out of the portion of text, if any,
5959 covered by a `display' text property or by an overlay with
5960 `display' property. (We cannot just jump there, because the
5961 internal coherency of the bidi iterator state can not be
5962 preserved across such jumps.) We also must determine the
5963 paragraph base direction if the overlay we just processed is
5964 at the beginning of a new paragraph. */
5965 if (from_display_prop
5966 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5967 iterate_out_of_display_property (it);
5968
5969 eassert ((BUFFERP (it->object)
5970 && IT_CHARPOS (*it) == it->bidi_it.charpos
5971 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5972 || (STRINGP (it->object)
5973 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5974 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5975 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5976 }
5977 }
5978
5979
5980 \f
5981 /***********************************************************************
5982 Moving over lines
5983 ***********************************************************************/
5984
5985 /* Set IT's current position to the previous line start. */
5986
5987 static void
5988 back_to_previous_line_start (struct it *it)
5989 {
5990 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
5991
5992 DEC_BOTH (cp, bp);
5993 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
5994 }
5995
5996
5997 /* Move IT to the next line start.
5998
5999 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6000 we skipped over part of the text (as opposed to moving the iterator
6001 continuously over the text). Otherwise, don't change the value
6002 of *SKIPPED_P.
6003
6004 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6005 iterator on the newline, if it was found.
6006
6007 Newlines may come from buffer text, overlay strings, or strings
6008 displayed via the `display' property. That's the reason we can't
6009 simply use find_newline_no_quit.
6010
6011 Note that this function may not skip over invisible text that is so
6012 because of text properties and immediately follows a newline. If
6013 it would, function reseat_at_next_visible_line_start, when called
6014 from set_iterator_to_next, would effectively make invisible
6015 characters following a newline part of the wrong glyph row, which
6016 leads to wrong cursor motion. */
6017
6018 static int
6019 forward_to_next_line_start (struct it *it, int *skipped_p,
6020 struct bidi_it *bidi_it_prev)
6021 {
6022 ptrdiff_t old_selective;
6023 int newline_found_p, n;
6024 const int MAX_NEWLINE_DISTANCE = 500;
6025
6026 /* If already on a newline, just consume it to avoid unintended
6027 skipping over invisible text below. */
6028 if (it->what == IT_CHARACTER
6029 && it->c == '\n'
6030 && CHARPOS (it->position) == IT_CHARPOS (*it))
6031 {
6032 if (it->bidi_p && bidi_it_prev)
6033 *bidi_it_prev = it->bidi_it;
6034 set_iterator_to_next (it, 0);
6035 it->c = 0;
6036 return 1;
6037 }
6038
6039 /* Don't handle selective display in the following. It's (a)
6040 unnecessary because it's done by the caller, and (b) leads to an
6041 infinite recursion because next_element_from_ellipsis indirectly
6042 calls this function. */
6043 old_selective = it->selective;
6044 it->selective = 0;
6045
6046 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6047 from buffer text. */
6048 for (n = newline_found_p = 0;
6049 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6050 n += STRINGP (it->string) ? 0 : 1)
6051 {
6052 if (!get_next_display_element (it))
6053 return 0;
6054 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6055 if (newline_found_p && it->bidi_p && bidi_it_prev)
6056 *bidi_it_prev = it->bidi_it;
6057 set_iterator_to_next (it, 0);
6058 }
6059
6060 /* If we didn't find a newline near enough, see if we can use a
6061 short-cut. */
6062 if (!newline_found_p)
6063 {
6064 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6065 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6066 1, &bytepos);
6067 Lisp_Object pos;
6068
6069 eassert (!STRINGP (it->string));
6070
6071 /* If there isn't any `display' property in sight, and no
6072 overlays, we can just use the position of the newline in
6073 buffer text. */
6074 if (it->stop_charpos >= limit
6075 || ((pos = Fnext_single_property_change (make_number (start),
6076 Qdisplay, Qnil,
6077 make_number (limit)),
6078 NILP (pos))
6079 && next_overlay_change (start) == ZV))
6080 {
6081 if (!it->bidi_p)
6082 {
6083 IT_CHARPOS (*it) = limit;
6084 IT_BYTEPOS (*it) = bytepos;
6085 }
6086 else
6087 {
6088 struct bidi_it bprev;
6089
6090 /* Help bidi.c avoid expensive searches for display
6091 properties and overlays, by telling it that there are
6092 none up to `limit'. */
6093 if (it->bidi_it.disp_pos < limit)
6094 {
6095 it->bidi_it.disp_pos = limit;
6096 it->bidi_it.disp_prop = 0;
6097 }
6098 do {
6099 bprev = it->bidi_it;
6100 bidi_move_to_visually_next (&it->bidi_it);
6101 } while (it->bidi_it.charpos != limit);
6102 IT_CHARPOS (*it) = limit;
6103 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6104 if (bidi_it_prev)
6105 *bidi_it_prev = bprev;
6106 }
6107 *skipped_p = newline_found_p = 1;
6108 }
6109 else
6110 {
6111 while (get_next_display_element (it)
6112 && !newline_found_p)
6113 {
6114 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6115 if (newline_found_p && it->bidi_p && bidi_it_prev)
6116 *bidi_it_prev = it->bidi_it;
6117 set_iterator_to_next (it, 0);
6118 }
6119 }
6120 }
6121
6122 it->selective = old_selective;
6123 return newline_found_p;
6124 }
6125
6126
6127 /* Set IT's current position to the previous visible line start. Skip
6128 invisible text that is so either due to text properties or due to
6129 selective display. Caution: this does not change IT->current_x and
6130 IT->hpos. */
6131
6132 static void
6133 back_to_previous_visible_line_start (struct it *it)
6134 {
6135 while (IT_CHARPOS (*it) > BEGV)
6136 {
6137 back_to_previous_line_start (it);
6138
6139 if (IT_CHARPOS (*it) <= BEGV)
6140 break;
6141
6142 /* If selective > 0, then lines indented more than its value are
6143 invisible. */
6144 if (it->selective > 0
6145 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6146 it->selective))
6147 continue;
6148
6149 /* Check the newline before point for invisibility. */
6150 {
6151 Lisp_Object prop;
6152 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6153 Qinvisible, it->window);
6154 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6155 continue;
6156 }
6157
6158 if (IT_CHARPOS (*it) <= BEGV)
6159 break;
6160
6161 {
6162 struct it it2;
6163 void *it2data = NULL;
6164 ptrdiff_t pos;
6165 ptrdiff_t beg, end;
6166 Lisp_Object val, overlay;
6167
6168 SAVE_IT (it2, *it, it2data);
6169
6170 /* If newline is part of a composition, continue from start of composition */
6171 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6172 && beg < IT_CHARPOS (*it))
6173 goto replaced;
6174
6175 /* If newline is replaced by a display property, find start of overlay
6176 or interval and continue search from that point. */
6177 pos = --IT_CHARPOS (it2);
6178 --IT_BYTEPOS (it2);
6179 it2.sp = 0;
6180 bidi_unshelve_cache (NULL, 0);
6181 it2.string_from_display_prop_p = 0;
6182 it2.from_disp_prop_p = 0;
6183 if (handle_display_prop (&it2) == HANDLED_RETURN
6184 && !NILP (val = get_char_property_and_overlay
6185 (make_number (pos), Qdisplay, Qnil, &overlay))
6186 && (OVERLAYP (overlay)
6187 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6188 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6189 {
6190 RESTORE_IT (it, it, it2data);
6191 goto replaced;
6192 }
6193
6194 /* Newline is not replaced by anything -- so we are done. */
6195 RESTORE_IT (it, it, it2data);
6196 break;
6197
6198 replaced:
6199 if (beg < BEGV)
6200 beg = BEGV;
6201 IT_CHARPOS (*it) = beg;
6202 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6203 }
6204 }
6205
6206 it->continuation_lines_width = 0;
6207
6208 eassert (IT_CHARPOS (*it) >= BEGV);
6209 eassert (IT_CHARPOS (*it) == BEGV
6210 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6211 CHECK_IT (it);
6212 }
6213
6214
6215 /* Reseat iterator IT at the previous visible line start. Skip
6216 invisible text that is so either due to text properties or due to
6217 selective display. At the end, update IT's overlay information,
6218 face information etc. */
6219
6220 void
6221 reseat_at_previous_visible_line_start (struct it *it)
6222 {
6223 back_to_previous_visible_line_start (it);
6224 reseat (it, it->current.pos, 1);
6225 CHECK_IT (it);
6226 }
6227
6228
6229 /* Reseat iterator IT on the next visible line start in the current
6230 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6231 preceding the line start. Skip over invisible text that is so
6232 because of selective display. Compute faces, overlays etc at the
6233 new position. Note that this function does not skip over text that
6234 is invisible because of text properties. */
6235
6236 static void
6237 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6238 {
6239 int newline_found_p, skipped_p = 0;
6240 struct bidi_it bidi_it_prev;
6241
6242 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6243
6244 /* Skip over lines that are invisible because they are indented
6245 more than the value of IT->selective. */
6246 if (it->selective > 0)
6247 while (IT_CHARPOS (*it) < ZV
6248 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6249 it->selective))
6250 {
6251 eassert (IT_BYTEPOS (*it) == BEGV
6252 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6253 newline_found_p =
6254 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6255 }
6256
6257 /* Position on the newline if that's what's requested. */
6258 if (on_newline_p && newline_found_p)
6259 {
6260 if (STRINGP (it->string))
6261 {
6262 if (IT_STRING_CHARPOS (*it) > 0)
6263 {
6264 if (!it->bidi_p)
6265 {
6266 --IT_STRING_CHARPOS (*it);
6267 --IT_STRING_BYTEPOS (*it);
6268 }
6269 else
6270 {
6271 /* We need to restore the bidi iterator to the state
6272 it had on the newline, and resync the IT's
6273 position with that. */
6274 it->bidi_it = bidi_it_prev;
6275 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6276 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6277 }
6278 }
6279 }
6280 else if (IT_CHARPOS (*it) > BEGV)
6281 {
6282 if (!it->bidi_p)
6283 {
6284 --IT_CHARPOS (*it);
6285 --IT_BYTEPOS (*it);
6286 }
6287 else
6288 {
6289 /* We need to restore the bidi iterator to the state it
6290 had on the newline and resync IT with that. */
6291 it->bidi_it = bidi_it_prev;
6292 IT_CHARPOS (*it) = it->bidi_it.charpos;
6293 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6294 }
6295 reseat (it, it->current.pos, 0);
6296 }
6297 }
6298 else if (skipped_p)
6299 reseat (it, it->current.pos, 0);
6300
6301 CHECK_IT (it);
6302 }
6303
6304
6305 \f
6306 /***********************************************************************
6307 Changing an iterator's position
6308 ***********************************************************************/
6309
6310 /* Change IT's current position to POS in current_buffer. If FORCE_P
6311 is non-zero, always check for text properties at the new position.
6312 Otherwise, text properties are only looked up if POS >=
6313 IT->check_charpos of a property. */
6314
6315 static void
6316 reseat (struct it *it, struct text_pos pos, int force_p)
6317 {
6318 ptrdiff_t original_pos = IT_CHARPOS (*it);
6319
6320 reseat_1 (it, pos, 0);
6321
6322 /* Determine where to check text properties. Avoid doing it
6323 where possible because text property lookup is very expensive. */
6324 if (force_p
6325 || CHARPOS (pos) > it->stop_charpos
6326 || CHARPOS (pos) < original_pos)
6327 {
6328 if (it->bidi_p)
6329 {
6330 /* For bidi iteration, we need to prime prev_stop and
6331 base_level_stop with our best estimations. */
6332 /* Implementation note: Of course, POS is not necessarily a
6333 stop position, so assigning prev_pos to it is a lie; we
6334 should have called compute_stop_backwards. However, if
6335 the current buffer does not include any R2L characters,
6336 that call would be a waste of cycles, because the
6337 iterator will never move back, and thus never cross this
6338 "fake" stop position. So we delay that backward search
6339 until the time we really need it, in next_element_from_buffer. */
6340 if (CHARPOS (pos) != it->prev_stop)
6341 it->prev_stop = CHARPOS (pos);
6342 if (CHARPOS (pos) < it->base_level_stop)
6343 it->base_level_stop = 0; /* meaning it's unknown */
6344 handle_stop (it);
6345 }
6346 else
6347 {
6348 handle_stop (it);
6349 it->prev_stop = it->base_level_stop = 0;
6350 }
6351
6352 }
6353
6354 CHECK_IT (it);
6355 }
6356
6357
6358 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6359 IT->stop_pos to POS, also. */
6360
6361 static void
6362 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6363 {
6364 /* Don't call this function when scanning a C string. */
6365 eassert (it->s == NULL);
6366
6367 /* POS must be a reasonable value. */
6368 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6369
6370 it->current.pos = it->position = pos;
6371 it->end_charpos = ZV;
6372 it->dpvec = NULL;
6373 it->current.dpvec_index = -1;
6374 it->current.overlay_string_index = -1;
6375 IT_STRING_CHARPOS (*it) = -1;
6376 IT_STRING_BYTEPOS (*it) = -1;
6377 it->string = Qnil;
6378 it->method = GET_FROM_BUFFER;
6379 it->object = it->w->contents;
6380 it->area = TEXT_AREA;
6381 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6382 it->sp = 0;
6383 it->string_from_display_prop_p = 0;
6384 it->string_from_prefix_prop_p = 0;
6385
6386 it->from_disp_prop_p = 0;
6387 it->face_before_selective_p = 0;
6388 if (it->bidi_p)
6389 {
6390 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6391 &it->bidi_it);
6392 bidi_unshelve_cache (NULL, 0);
6393 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6394 it->bidi_it.string.s = NULL;
6395 it->bidi_it.string.lstring = Qnil;
6396 it->bidi_it.string.bufpos = 0;
6397 it->bidi_it.string.unibyte = 0;
6398 it->bidi_it.w = it->w;
6399 }
6400
6401 if (set_stop_p)
6402 {
6403 it->stop_charpos = CHARPOS (pos);
6404 it->base_level_stop = CHARPOS (pos);
6405 }
6406 /* This make the information stored in it->cmp_it invalidate. */
6407 it->cmp_it.id = -1;
6408 }
6409
6410
6411 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6412 If S is non-null, it is a C string to iterate over. Otherwise,
6413 STRING gives a Lisp string to iterate over.
6414
6415 If PRECISION > 0, don't return more then PRECISION number of
6416 characters from the string.
6417
6418 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6419 characters have been returned. FIELD_WIDTH < 0 means an infinite
6420 field width.
6421
6422 MULTIBYTE = 0 means disable processing of multibyte characters,
6423 MULTIBYTE > 0 means enable it,
6424 MULTIBYTE < 0 means use IT->multibyte_p.
6425
6426 IT must be initialized via a prior call to init_iterator before
6427 calling this function. */
6428
6429 static void
6430 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6431 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6432 int multibyte)
6433 {
6434 /* No text property checks performed by default, but see below. */
6435 it->stop_charpos = -1;
6436
6437 /* Set iterator position and end position. */
6438 memset (&it->current, 0, sizeof it->current);
6439 it->current.overlay_string_index = -1;
6440 it->current.dpvec_index = -1;
6441 eassert (charpos >= 0);
6442
6443 /* If STRING is specified, use its multibyteness, otherwise use the
6444 setting of MULTIBYTE, if specified. */
6445 if (multibyte >= 0)
6446 it->multibyte_p = multibyte > 0;
6447
6448 /* Bidirectional reordering of strings is controlled by the default
6449 value of bidi-display-reordering. Don't try to reorder while
6450 loading loadup.el, as the necessary character property tables are
6451 not yet available. */
6452 it->bidi_p =
6453 NILP (Vpurify_flag)
6454 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6455
6456 if (s == NULL)
6457 {
6458 eassert (STRINGP (string));
6459 it->string = string;
6460 it->s = NULL;
6461 it->end_charpos = it->string_nchars = SCHARS (string);
6462 it->method = GET_FROM_STRING;
6463 it->current.string_pos = string_pos (charpos, string);
6464
6465 if (it->bidi_p)
6466 {
6467 it->bidi_it.string.lstring = string;
6468 it->bidi_it.string.s = NULL;
6469 it->bidi_it.string.schars = it->end_charpos;
6470 it->bidi_it.string.bufpos = 0;
6471 it->bidi_it.string.from_disp_str = 0;
6472 it->bidi_it.string.unibyte = !it->multibyte_p;
6473 it->bidi_it.w = it->w;
6474 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6475 FRAME_WINDOW_P (it->f), &it->bidi_it);
6476 }
6477 }
6478 else
6479 {
6480 it->s = (const unsigned char *) s;
6481 it->string = Qnil;
6482
6483 /* Note that we use IT->current.pos, not it->current.string_pos,
6484 for displaying C strings. */
6485 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6486 if (it->multibyte_p)
6487 {
6488 it->current.pos = c_string_pos (charpos, s, 1);
6489 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6490 }
6491 else
6492 {
6493 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6494 it->end_charpos = it->string_nchars = strlen (s);
6495 }
6496
6497 if (it->bidi_p)
6498 {
6499 it->bidi_it.string.lstring = Qnil;
6500 it->bidi_it.string.s = (const unsigned char *) s;
6501 it->bidi_it.string.schars = it->end_charpos;
6502 it->bidi_it.string.bufpos = 0;
6503 it->bidi_it.string.from_disp_str = 0;
6504 it->bidi_it.string.unibyte = !it->multibyte_p;
6505 it->bidi_it.w = it->w;
6506 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6507 &it->bidi_it);
6508 }
6509 it->method = GET_FROM_C_STRING;
6510 }
6511
6512 /* PRECISION > 0 means don't return more than PRECISION characters
6513 from the string. */
6514 if (precision > 0 && it->end_charpos - charpos > precision)
6515 {
6516 it->end_charpos = it->string_nchars = charpos + precision;
6517 if (it->bidi_p)
6518 it->bidi_it.string.schars = it->end_charpos;
6519 }
6520
6521 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6522 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6523 FIELD_WIDTH < 0 means infinite field width. This is useful for
6524 padding with `-' at the end of a mode line. */
6525 if (field_width < 0)
6526 field_width = INFINITY;
6527 /* Implementation note: We deliberately don't enlarge
6528 it->bidi_it.string.schars here to fit it->end_charpos, because
6529 the bidi iterator cannot produce characters out of thin air. */
6530 if (field_width > it->end_charpos - charpos)
6531 it->end_charpos = charpos + field_width;
6532
6533 /* Use the standard display table for displaying strings. */
6534 if (DISP_TABLE_P (Vstandard_display_table))
6535 it->dp = XCHAR_TABLE (Vstandard_display_table);
6536
6537 it->stop_charpos = charpos;
6538 it->prev_stop = charpos;
6539 it->base_level_stop = 0;
6540 if (it->bidi_p)
6541 {
6542 it->bidi_it.first_elt = 1;
6543 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6544 it->bidi_it.disp_pos = -1;
6545 }
6546 if (s == NULL && it->multibyte_p)
6547 {
6548 ptrdiff_t endpos = SCHARS (it->string);
6549 if (endpos > it->end_charpos)
6550 endpos = it->end_charpos;
6551 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6552 it->string);
6553 }
6554 CHECK_IT (it);
6555 }
6556
6557
6558 \f
6559 /***********************************************************************
6560 Iteration
6561 ***********************************************************************/
6562
6563 /* Map enum it_method value to corresponding next_element_from_* function. */
6564
6565 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6566 {
6567 next_element_from_buffer,
6568 next_element_from_display_vector,
6569 next_element_from_string,
6570 next_element_from_c_string,
6571 next_element_from_image,
6572 next_element_from_stretch
6573 };
6574
6575 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6576
6577
6578 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6579 (possibly with the following characters). */
6580
6581 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6582 ((IT)->cmp_it.id >= 0 \
6583 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6584 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6585 END_CHARPOS, (IT)->w, \
6586 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6587 (IT)->string)))
6588
6589
6590 /* Lookup the char-table Vglyphless_char_display for character C (-1
6591 if we want information for no-font case), and return the display
6592 method symbol. By side-effect, update it->what and
6593 it->glyphless_method. This function is called from
6594 get_next_display_element for each character element, and from
6595 x_produce_glyphs when no suitable font was found. */
6596
6597 Lisp_Object
6598 lookup_glyphless_char_display (int c, struct it *it)
6599 {
6600 Lisp_Object glyphless_method = Qnil;
6601
6602 if (CHAR_TABLE_P (Vglyphless_char_display)
6603 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6604 {
6605 if (c >= 0)
6606 {
6607 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6608 if (CONSP (glyphless_method))
6609 glyphless_method = FRAME_WINDOW_P (it->f)
6610 ? XCAR (glyphless_method)
6611 : XCDR (glyphless_method);
6612 }
6613 else
6614 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6615 }
6616
6617 retry:
6618 if (NILP (glyphless_method))
6619 {
6620 if (c >= 0)
6621 /* The default is to display the character by a proper font. */
6622 return Qnil;
6623 /* The default for the no-font case is to display an empty box. */
6624 glyphless_method = Qempty_box;
6625 }
6626 if (EQ (glyphless_method, Qzero_width))
6627 {
6628 if (c >= 0)
6629 return glyphless_method;
6630 /* This method can't be used for the no-font case. */
6631 glyphless_method = Qempty_box;
6632 }
6633 if (EQ (glyphless_method, Qthin_space))
6634 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6635 else if (EQ (glyphless_method, Qempty_box))
6636 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6637 else if (EQ (glyphless_method, Qhex_code))
6638 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6639 else if (STRINGP (glyphless_method))
6640 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6641 else
6642 {
6643 /* Invalid value. We use the default method. */
6644 glyphless_method = Qnil;
6645 goto retry;
6646 }
6647 it->what = IT_GLYPHLESS;
6648 return glyphless_method;
6649 }
6650
6651 /* Merge escape glyph face and cache the result. */
6652
6653 static struct frame *last_escape_glyph_frame = NULL;
6654 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6655 static int last_escape_glyph_merged_face_id = 0;
6656
6657 static int
6658 merge_escape_glyph_face (struct it *it)
6659 {
6660 int face_id;
6661
6662 if (it->f == last_escape_glyph_frame
6663 && it->face_id == last_escape_glyph_face_id)
6664 face_id = last_escape_glyph_merged_face_id;
6665 else
6666 {
6667 /* Merge the `escape-glyph' face into the current face. */
6668 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6669 last_escape_glyph_frame = it->f;
6670 last_escape_glyph_face_id = it->face_id;
6671 last_escape_glyph_merged_face_id = face_id;
6672 }
6673 return face_id;
6674 }
6675
6676 /* Likewise for glyphless glyph face. */
6677
6678 static struct frame *last_glyphless_glyph_frame = NULL;
6679 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6680 static int last_glyphless_glyph_merged_face_id = 0;
6681
6682 int
6683 merge_glyphless_glyph_face (struct it *it)
6684 {
6685 int face_id;
6686
6687 if (it->f == last_glyphless_glyph_frame
6688 && it->face_id == last_glyphless_glyph_face_id)
6689 face_id = last_glyphless_glyph_merged_face_id;
6690 else
6691 {
6692 /* Merge the `glyphless-char' face into the current face. */
6693 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6694 last_glyphless_glyph_frame = it->f;
6695 last_glyphless_glyph_face_id = it->face_id;
6696 last_glyphless_glyph_merged_face_id = face_id;
6697 }
6698 return face_id;
6699 }
6700
6701 /* Load IT's display element fields with information about the next
6702 display element from the current position of IT. Value is zero if
6703 end of buffer (or C string) is reached. */
6704
6705 static int
6706 get_next_display_element (struct it *it)
6707 {
6708 /* Non-zero means that we found a display element. Zero means that
6709 we hit the end of what we iterate over. Performance note: the
6710 function pointer `method' used here turns out to be faster than
6711 using a sequence of if-statements. */
6712 int success_p;
6713
6714 get_next:
6715 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6716
6717 if (it->what == IT_CHARACTER)
6718 {
6719 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6720 and only if (a) the resolved directionality of that character
6721 is R..." */
6722 /* FIXME: Do we need an exception for characters from display
6723 tables? */
6724 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6725 it->c = bidi_mirror_char (it->c);
6726 /* Map via display table or translate control characters.
6727 IT->c, IT->len etc. have been set to the next character by
6728 the function call above. If we have a display table, and it
6729 contains an entry for IT->c, translate it. Don't do this if
6730 IT->c itself comes from a display table, otherwise we could
6731 end up in an infinite recursion. (An alternative could be to
6732 count the recursion depth of this function and signal an
6733 error when a certain maximum depth is reached.) Is it worth
6734 it? */
6735 if (success_p && it->dpvec == NULL)
6736 {
6737 Lisp_Object dv;
6738 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6739 int nonascii_space_p = 0;
6740 int nonascii_hyphen_p = 0;
6741 int c = it->c; /* This is the character to display. */
6742
6743 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6744 {
6745 eassert (SINGLE_BYTE_CHAR_P (c));
6746 if (unibyte_display_via_language_environment)
6747 {
6748 c = DECODE_CHAR (unibyte, c);
6749 if (c < 0)
6750 c = BYTE8_TO_CHAR (it->c);
6751 }
6752 else
6753 c = BYTE8_TO_CHAR (it->c);
6754 }
6755
6756 if (it->dp
6757 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6758 VECTORP (dv)))
6759 {
6760 struct Lisp_Vector *v = XVECTOR (dv);
6761
6762 /* Return the first character from the display table
6763 entry, if not empty. If empty, don't display the
6764 current character. */
6765 if (v->header.size)
6766 {
6767 it->dpvec_char_len = it->len;
6768 it->dpvec = v->contents;
6769 it->dpend = v->contents + v->header.size;
6770 it->current.dpvec_index = 0;
6771 it->dpvec_face_id = -1;
6772 it->saved_face_id = it->face_id;
6773 it->method = GET_FROM_DISPLAY_VECTOR;
6774 it->ellipsis_p = 0;
6775 }
6776 else
6777 {
6778 set_iterator_to_next (it, 0);
6779 }
6780 goto get_next;
6781 }
6782
6783 if (! NILP (lookup_glyphless_char_display (c, it)))
6784 {
6785 if (it->what == IT_GLYPHLESS)
6786 goto done;
6787 /* Don't display this character. */
6788 set_iterator_to_next (it, 0);
6789 goto get_next;
6790 }
6791
6792 /* If `nobreak-char-display' is non-nil, we display
6793 non-ASCII spaces and hyphens specially. */
6794 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6795 {
6796 if (c == 0xA0)
6797 nonascii_space_p = 1;
6798 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6799 nonascii_hyphen_p = 1;
6800 }
6801
6802 /* Translate control characters into `\003' or `^C' form.
6803 Control characters coming from a display table entry are
6804 currently not translated because we use IT->dpvec to hold
6805 the translation. This could easily be changed but I
6806 don't believe that it is worth doing.
6807
6808 The characters handled by `nobreak-char-display' must be
6809 translated too.
6810
6811 Non-printable characters and raw-byte characters are also
6812 translated to octal form. */
6813 if (((c < ' ' || c == 127) /* ASCII control chars. */
6814 ? (it->area != TEXT_AREA
6815 /* In mode line, treat \n, \t like other crl chars. */
6816 || (c != '\t'
6817 && it->glyph_row
6818 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6819 || (c != '\n' && c != '\t'))
6820 : (nonascii_space_p
6821 || nonascii_hyphen_p
6822 || CHAR_BYTE8_P (c)
6823 || ! CHAR_PRINTABLE_P (c))))
6824 {
6825 /* C is a control character, non-ASCII space/hyphen,
6826 raw-byte, or a non-printable character which must be
6827 displayed either as '\003' or as `^C' where the '\\'
6828 and '^' can be defined in the display table. Fill
6829 IT->ctl_chars with glyphs for what we have to
6830 display. Then, set IT->dpvec to these glyphs. */
6831 Lisp_Object gc;
6832 int ctl_len;
6833 int face_id;
6834 int lface_id = 0;
6835 int escape_glyph;
6836
6837 /* Handle control characters with ^. */
6838
6839 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6840 {
6841 int g;
6842
6843 g = '^'; /* default glyph for Control */
6844 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6845 if (it->dp
6846 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6847 {
6848 g = GLYPH_CODE_CHAR (gc);
6849 lface_id = GLYPH_CODE_FACE (gc);
6850 }
6851
6852 face_id = (lface_id
6853 ? merge_faces (it->f, Qt, lface_id, it->face_id)
6854 : merge_escape_glyph_face (it));
6855
6856 XSETINT (it->ctl_chars[0], g);
6857 XSETINT (it->ctl_chars[1], c ^ 0100);
6858 ctl_len = 2;
6859 goto display_control;
6860 }
6861
6862 /* Handle non-ascii space in the mode where it only gets
6863 highlighting. */
6864
6865 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6866 {
6867 /* Merge `nobreak-space' into the current face. */
6868 face_id = merge_faces (it->f, Qnobreak_space, 0,
6869 it->face_id);
6870 XSETINT (it->ctl_chars[0], ' ');
6871 ctl_len = 1;
6872 goto display_control;
6873 }
6874
6875 /* Handle sequences that start with the "escape glyph". */
6876
6877 /* the default escape glyph is \. */
6878 escape_glyph = '\\';
6879
6880 if (it->dp
6881 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6882 {
6883 escape_glyph = GLYPH_CODE_CHAR (gc);
6884 lface_id = GLYPH_CODE_FACE (gc);
6885 }
6886
6887 face_id = (lface_id
6888 ? merge_faces (it->f, Qt, lface_id, it->face_id)
6889 : merge_escape_glyph_face (it));
6890
6891 /* Draw non-ASCII hyphen with just highlighting: */
6892
6893 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6894 {
6895 XSETINT (it->ctl_chars[0], '-');
6896 ctl_len = 1;
6897 goto display_control;
6898 }
6899
6900 /* Draw non-ASCII space/hyphen with escape glyph: */
6901
6902 if (nonascii_space_p || nonascii_hyphen_p)
6903 {
6904 XSETINT (it->ctl_chars[0], escape_glyph);
6905 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6906 ctl_len = 2;
6907 goto display_control;
6908 }
6909
6910 {
6911 char str[10];
6912 int len, i;
6913
6914 if (CHAR_BYTE8_P (c))
6915 /* Display \200 instead of \17777600. */
6916 c = CHAR_TO_BYTE8 (c);
6917 len = sprintf (str, "%03o", c);
6918
6919 XSETINT (it->ctl_chars[0], escape_glyph);
6920 for (i = 0; i < len; i++)
6921 XSETINT (it->ctl_chars[i + 1], str[i]);
6922 ctl_len = len + 1;
6923 }
6924
6925 display_control:
6926 /* Set up IT->dpvec and return first character from it. */
6927 it->dpvec_char_len = it->len;
6928 it->dpvec = it->ctl_chars;
6929 it->dpend = it->dpvec + ctl_len;
6930 it->current.dpvec_index = 0;
6931 it->dpvec_face_id = face_id;
6932 it->saved_face_id = it->face_id;
6933 it->method = GET_FROM_DISPLAY_VECTOR;
6934 it->ellipsis_p = 0;
6935 goto get_next;
6936 }
6937 it->char_to_display = c;
6938 }
6939 else if (success_p)
6940 {
6941 it->char_to_display = it->c;
6942 }
6943 }
6944
6945 #ifdef HAVE_WINDOW_SYSTEM
6946 /* Adjust face id for a multibyte character. There are no multibyte
6947 character in unibyte text. */
6948 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6949 && it->multibyte_p
6950 && success_p
6951 && FRAME_WINDOW_P (it->f))
6952 {
6953 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6954
6955 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6956 {
6957 /* Automatic composition with glyph-string. */
6958 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6959
6960 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6961 }
6962 else
6963 {
6964 ptrdiff_t pos = (it->s ? -1
6965 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6966 : IT_CHARPOS (*it));
6967 int c;
6968
6969 if (it->what == IT_CHARACTER)
6970 c = it->char_to_display;
6971 else
6972 {
6973 struct composition *cmp = composition_table[it->cmp_it.id];
6974 int i;
6975
6976 c = ' ';
6977 for (i = 0; i < cmp->glyph_len; i++)
6978 /* TAB in a composition means display glyphs with
6979 padding space on the left or right. */
6980 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6981 break;
6982 }
6983 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6984 }
6985 }
6986 #endif /* HAVE_WINDOW_SYSTEM */
6987
6988 done:
6989 /* Is this character the last one of a run of characters with
6990 box? If yes, set IT->end_of_box_run_p to 1. */
6991 if (it->face_box_p
6992 && it->s == NULL)
6993 {
6994 if (it->method == GET_FROM_STRING && it->sp)
6995 {
6996 int face_id = underlying_face_id (it);
6997 struct face *face = FACE_FROM_ID (it->f, face_id);
6998
6999 if (face)
7000 {
7001 if (face->box == FACE_NO_BOX)
7002 {
7003 /* If the box comes from face properties in a
7004 display string, check faces in that string. */
7005 int string_face_id = face_after_it_pos (it);
7006 it->end_of_box_run_p
7007 = (FACE_FROM_ID (it->f, string_face_id)->box
7008 == FACE_NO_BOX);
7009 }
7010 /* Otherwise, the box comes from the underlying face.
7011 If this is the last string character displayed, check
7012 the next buffer location. */
7013 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7014 && (it->current.overlay_string_index
7015 == it->n_overlay_strings - 1))
7016 {
7017 ptrdiff_t ignore;
7018 int next_face_id;
7019 struct text_pos pos = it->current.pos;
7020 INC_TEXT_POS (pos, it->multibyte_p);
7021
7022 next_face_id = face_at_buffer_position
7023 (it->w, CHARPOS (pos), &ignore,
7024 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
7025 -1);
7026 it->end_of_box_run_p
7027 = (FACE_FROM_ID (it->f, next_face_id)->box
7028 == FACE_NO_BOX);
7029 }
7030 }
7031 }
7032 /* next_element_from_display_vector sets this flag according to
7033 faces of the display vector glyphs, see there. */
7034 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7035 {
7036 int face_id = face_after_it_pos (it);
7037 it->end_of_box_run_p
7038 = (face_id != it->face_id
7039 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7040 }
7041 }
7042 /* If we reached the end of the object we've been iterating (e.g., a
7043 display string or an overlay string), and there's something on
7044 IT->stack, proceed with what's on the stack. It doesn't make
7045 sense to return zero if there's unprocessed stuff on the stack,
7046 because otherwise that stuff will never be displayed. */
7047 if (!success_p && it->sp > 0)
7048 {
7049 set_iterator_to_next (it, 0);
7050 success_p = get_next_display_element (it);
7051 }
7052
7053 /* Value is 0 if end of buffer or string reached. */
7054 return success_p;
7055 }
7056
7057
7058 /* Move IT to the next display element.
7059
7060 RESEAT_P non-zero means if called on a newline in buffer text,
7061 skip to the next visible line start.
7062
7063 Functions get_next_display_element and set_iterator_to_next are
7064 separate because I find this arrangement easier to handle than a
7065 get_next_display_element function that also increments IT's
7066 position. The way it is we can first look at an iterator's current
7067 display element, decide whether it fits on a line, and if it does,
7068 increment the iterator position. The other way around we probably
7069 would either need a flag indicating whether the iterator has to be
7070 incremented the next time, or we would have to implement a
7071 decrement position function which would not be easy to write. */
7072
7073 void
7074 set_iterator_to_next (struct it *it, int reseat_p)
7075 {
7076 /* Reset flags indicating start and end of a sequence of characters
7077 with box. Reset them at the start of this function because
7078 moving the iterator to a new position might set them. */
7079 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7080
7081 switch (it->method)
7082 {
7083 case GET_FROM_BUFFER:
7084 /* The current display element of IT is a character from
7085 current_buffer. Advance in the buffer, and maybe skip over
7086 invisible lines that are so because of selective display. */
7087 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7088 reseat_at_next_visible_line_start (it, 0);
7089 else if (it->cmp_it.id >= 0)
7090 {
7091 /* We are currently getting glyphs from a composition. */
7092 int i;
7093
7094 if (! it->bidi_p)
7095 {
7096 IT_CHARPOS (*it) += it->cmp_it.nchars;
7097 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7098 if (it->cmp_it.to < it->cmp_it.nglyphs)
7099 {
7100 it->cmp_it.from = it->cmp_it.to;
7101 }
7102 else
7103 {
7104 it->cmp_it.id = -1;
7105 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7106 IT_BYTEPOS (*it),
7107 it->end_charpos, Qnil);
7108 }
7109 }
7110 else if (! it->cmp_it.reversed_p)
7111 {
7112 /* Composition created while scanning forward. */
7113 /* Update IT's char/byte positions to point to the first
7114 character of the next grapheme cluster, or to the
7115 character visually after the current composition. */
7116 for (i = 0; i < it->cmp_it.nchars; i++)
7117 bidi_move_to_visually_next (&it->bidi_it);
7118 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7119 IT_CHARPOS (*it) = it->bidi_it.charpos;
7120
7121 if (it->cmp_it.to < it->cmp_it.nglyphs)
7122 {
7123 /* Proceed to the next grapheme cluster. */
7124 it->cmp_it.from = it->cmp_it.to;
7125 }
7126 else
7127 {
7128 /* No more grapheme clusters in this composition.
7129 Find the next stop position. */
7130 ptrdiff_t stop = it->end_charpos;
7131 if (it->bidi_it.scan_dir < 0)
7132 /* Now we are scanning backward and don't know
7133 where to stop. */
7134 stop = -1;
7135 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7136 IT_BYTEPOS (*it), stop, Qnil);
7137 }
7138 }
7139 else
7140 {
7141 /* Composition created while scanning backward. */
7142 /* Update IT's char/byte positions to point to the last
7143 character of the previous grapheme cluster, or the
7144 character visually after the current composition. */
7145 for (i = 0; i < it->cmp_it.nchars; i++)
7146 bidi_move_to_visually_next (&it->bidi_it);
7147 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7148 IT_CHARPOS (*it) = it->bidi_it.charpos;
7149 if (it->cmp_it.from > 0)
7150 {
7151 /* Proceed to the previous grapheme cluster. */
7152 it->cmp_it.to = it->cmp_it.from;
7153 }
7154 else
7155 {
7156 /* No more grapheme clusters in this composition.
7157 Find the next stop position. */
7158 ptrdiff_t stop = it->end_charpos;
7159 if (it->bidi_it.scan_dir < 0)
7160 /* Now we are scanning backward and don't know
7161 where to stop. */
7162 stop = -1;
7163 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7164 IT_BYTEPOS (*it), stop, Qnil);
7165 }
7166 }
7167 }
7168 else
7169 {
7170 eassert (it->len != 0);
7171
7172 if (!it->bidi_p)
7173 {
7174 IT_BYTEPOS (*it) += it->len;
7175 IT_CHARPOS (*it) += 1;
7176 }
7177 else
7178 {
7179 int prev_scan_dir = it->bidi_it.scan_dir;
7180 /* If this is a new paragraph, determine its base
7181 direction (a.k.a. its base embedding level). */
7182 if (it->bidi_it.new_paragraph)
7183 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7184 bidi_move_to_visually_next (&it->bidi_it);
7185 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7186 IT_CHARPOS (*it) = it->bidi_it.charpos;
7187 if (prev_scan_dir != it->bidi_it.scan_dir)
7188 {
7189 /* As the scan direction was changed, we must
7190 re-compute the stop position for composition. */
7191 ptrdiff_t stop = it->end_charpos;
7192 if (it->bidi_it.scan_dir < 0)
7193 stop = -1;
7194 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7195 IT_BYTEPOS (*it), stop, Qnil);
7196 }
7197 }
7198 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7199 }
7200 break;
7201
7202 case GET_FROM_C_STRING:
7203 /* Current display element of IT is from a C string. */
7204 if (!it->bidi_p
7205 /* If the string position is beyond string's end, it means
7206 next_element_from_c_string is padding the string with
7207 blanks, in which case we bypass the bidi iterator,
7208 because it cannot deal with such virtual characters. */
7209 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7210 {
7211 IT_BYTEPOS (*it) += it->len;
7212 IT_CHARPOS (*it) += 1;
7213 }
7214 else
7215 {
7216 bidi_move_to_visually_next (&it->bidi_it);
7217 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7218 IT_CHARPOS (*it) = it->bidi_it.charpos;
7219 }
7220 break;
7221
7222 case GET_FROM_DISPLAY_VECTOR:
7223 /* Current display element of IT is from a display table entry.
7224 Advance in the display table definition. Reset it to null if
7225 end reached, and continue with characters from buffers/
7226 strings. */
7227 ++it->current.dpvec_index;
7228
7229 /* Restore face of the iterator to what they were before the
7230 display vector entry (these entries may contain faces). */
7231 it->face_id = it->saved_face_id;
7232
7233 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7234 {
7235 int recheck_faces = it->ellipsis_p;
7236
7237 if (it->s)
7238 it->method = GET_FROM_C_STRING;
7239 else if (STRINGP (it->string))
7240 it->method = GET_FROM_STRING;
7241 else
7242 {
7243 it->method = GET_FROM_BUFFER;
7244 it->object = it->w->contents;
7245 }
7246
7247 it->dpvec = NULL;
7248 it->current.dpvec_index = -1;
7249
7250 /* Skip over characters which were displayed via IT->dpvec. */
7251 if (it->dpvec_char_len < 0)
7252 reseat_at_next_visible_line_start (it, 1);
7253 else if (it->dpvec_char_len > 0)
7254 {
7255 if (it->method == GET_FROM_STRING
7256 && it->current.overlay_string_index >= 0
7257 && it->n_overlay_strings > 0)
7258 it->ignore_overlay_strings_at_pos_p = 1;
7259 it->len = it->dpvec_char_len;
7260 set_iterator_to_next (it, reseat_p);
7261 }
7262
7263 /* Maybe recheck faces after display vector */
7264 if (recheck_faces)
7265 it->stop_charpos = IT_CHARPOS (*it);
7266 }
7267 break;
7268
7269 case GET_FROM_STRING:
7270 /* Current display element is a character from a Lisp string. */
7271 eassert (it->s == NULL && STRINGP (it->string));
7272 /* Don't advance past string end. These conditions are true
7273 when set_iterator_to_next is called at the end of
7274 get_next_display_element, in which case the Lisp string is
7275 already exhausted, and all we want is pop the iterator
7276 stack. */
7277 if (it->current.overlay_string_index >= 0)
7278 {
7279 /* This is an overlay string, so there's no padding with
7280 spaces, and the number of characters in the string is
7281 where the string ends. */
7282 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7283 goto consider_string_end;
7284 }
7285 else
7286 {
7287 /* Not an overlay string. There could be padding, so test
7288 against it->end_charpos . */
7289 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7290 goto consider_string_end;
7291 }
7292 if (it->cmp_it.id >= 0)
7293 {
7294 int i;
7295
7296 if (! it->bidi_p)
7297 {
7298 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7299 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7300 if (it->cmp_it.to < it->cmp_it.nglyphs)
7301 it->cmp_it.from = it->cmp_it.to;
7302 else
7303 {
7304 it->cmp_it.id = -1;
7305 composition_compute_stop_pos (&it->cmp_it,
7306 IT_STRING_CHARPOS (*it),
7307 IT_STRING_BYTEPOS (*it),
7308 it->end_charpos, it->string);
7309 }
7310 }
7311 else if (! it->cmp_it.reversed_p)
7312 {
7313 for (i = 0; i < it->cmp_it.nchars; i++)
7314 bidi_move_to_visually_next (&it->bidi_it);
7315 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7316 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7317
7318 if (it->cmp_it.to < it->cmp_it.nglyphs)
7319 it->cmp_it.from = it->cmp_it.to;
7320 else
7321 {
7322 ptrdiff_t stop = it->end_charpos;
7323 if (it->bidi_it.scan_dir < 0)
7324 stop = -1;
7325 composition_compute_stop_pos (&it->cmp_it,
7326 IT_STRING_CHARPOS (*it),
7327 IT_STRING_BYTEPOS (*it), stop,
7328 it->string);
7329 }
7330 }
7331 else
7332 {
7333 for (i = 0; i < it->cmp_it.nchars; i++)
7334 bidi_move_to_visually_next (&it->bidi_it);
7335 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7336 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7337 if (it->cmp_it.from > 0)
7338 it->cmp_it.to = it->cmp_it.from;
7339 else
7340 {
7341 ptrdiff_t stop = it->end_charpos;
7342 if (it->bidi_it.scan_dir < 0)
7343 stop = -1;
7344 composition_compute_stop_pos (&it->cmp_it,
7345 IT_STRING_CHARPOS (*it),
7346 IT_STRING_BYTEPOS (*it), stop,
7347 it->string);
7348 }
7349 }
7350 }
7351 else
7352 {
7353 if (!it->bidi_p
7354 /* If the string position is beyond string's end, it
7355 means next_element_from_string is padding the string
7356 with blanks, in which case we bypass the bidi
7357 iterator, because it cannot deal with such virtual
7358 characters. */
7359 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7360 {
7361 IT_STRING_BYTEPOS (*it) += it->len;
7362 IT_STRING_CHARPOS (*it) += 1;
7363 }
7364 else
7365 {
7366 int prev_scan_dir = it->bidi_it.scan_dir;
7367
7368 bidi_move_to_visually_next (&it->bidi_it);
7369 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7370 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7371 if (prev_scan_dir != it->bidi_it.scan_dir)
7372 {
7373 ptrdiff_t stop = it->end_charpos;
7374
7375 if (it->bidi_it.scan_dir < 0)
7376 stop = -1;
7377 composition_compute_stop_pos (&it->cmp_it,
7378 IT_STRING_CHARPOS (*it),
7379 IT_STRING_BYTEPOS (*it), stop,
7380 it->string);
7381 }
7382 }
7383 }
7384
7385 consider_string_end:
7386
7387 if (it->current.overlay_string_index >= 0)
7388 {
7389 /* IT->string is an overlay string. Advance to the
7390 next, if there is one. */
7391 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7392 {
7393 it->ellipsis_p = 0;
7394 next_overlay_string (it);
7395 if (it->ellipsis_p)
7396 setup_for_ellipsis (it, 0);
7397 }
7398 }
7399 else
7400 {
7401 /* IT->string is not an overlay string. If we reached
7402 its end, and there is something on IT->stack, proceed
7403 with what is on the stack. This can be either another
7404 string, this time an overlay string, or a buffer. */
7405 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7406 && it->sp > 0)
7407 {
7408 pop_it (it);
7409 if (it->method == GET_FROM_STRING)
7410 goto consider_string_end;
7411 }
7412 }
7413 break;
7414
7415 case GET_FROM_IMAGE:
7416 case GET_FROM_STRETCH:
7417 /* The position etc with which we have to proceed are on
7418 the stack. The position may be at the end of a string,
7419 if the `display' property takes up the whole string. */
7420 eassert (it->sp > 0);
7421 pop_it (it);
7422 if (it->method == GET_FROM_STRING)
7423 goto consider_string_end;
7424 break;
7425
7426 default:
7427 /* There are no other methods defined, so this should be a bug. */
7428 emacs_abort ();
7429 }
7430
7431 eassert (it->method != GET_FROM_STRING
7432 || (STRINGP (it->string)
7433 && IT_STRING_CHARPOS (*it) >= 0));
7434 }
7435
7436 /* Load IT's display element fields with information about the next
7437 display element which comes from a display table entry or from the
7438 result of translating a control character to one of the forms `^C'
7439 or `\003'.
7440
7441 IT->dpvec holds the glyphs to return as characters.
7442 IT->saved_face_id holds the face id before the display vector--it
7443 is restored into IT->face_id in set_iterator_to_next. */
7444
7445 static int
7446 next_element_from_display_vector (struct it *it)
7447 {
7448 Lisp_Object gc;
7449 int prev_face_id = it->face_id;
7450 int next_face_id;
7451
7452 /* Precondition. */
7453 eassert (it->dpvec && it->current.dpvec_index >= 0);
7454
7455 it->face_id = it->saved_face_id;
7456
7457 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7458 That seemed totally bogus - so I changed it... */
7459 gc = it->dpvec[it->current.dpvec_index];
7460
7461 if (GLYPH_CODE_P (gc))
7462 {
7463 struct face *this_face, *prev_face, *next_face;
7464
7465 it->c = GLYPH_CODE_CHAR (gc);
7466 it->len = CHAR_BYTES (it->c);
7467
7468 /* The entry may contain a face id to use. Such a face id is
7469 the id of a Lisp face, not a realized face. A face id of
7470 zero means no face is specified. */
7471 if (it->dpvec_face_id >= 0)
7472 it->face_id = it->dpvec_face_id;
7473 else
7474 {
7475 int lface_id = GLYPH_CODE_FACE (gc);
7476 if (lface_id > 0)
7477 it->face_id = merge_faces (it->f, Qt, lface_id,
7478 it->saved_face_id);
7479 }
7480
7481 /* Glyphs in the display vector could have the box face, so we
7482 need to set the related flags in the iterator, as
7483 appropriate. */
7484 this_face = FACE_FROM_ID (it->f, it->face_id);
7485 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7486
7487 /* Is this character the first character of a box-face run? */
7488 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7489 && (!prev_face
7490 || prev_face->box == FACE_NO_BOX));
7491
7492 /* For the last character of the box-face run, we need to look
7493 either at the next glyph from the display vector, or at the
7494 face we saw before the display vector. */
7495 next_face_id = it->saved_face_id;
7496 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7497 {
7498 if (it->dpvec_face_id >= 0)
7499 next_face_id = it->dpvec_face_id;
7500 else
7501 {
7502 int lface_id =
7503 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7504
7505 if (lface_id > 0)
7506 next_face_id = merge_faces (it->f, Qt, lface_id,
7507 it->saved_face_id);
7508 }
7509 }
7510 next_face = FACE_FROM_ID (it->f, next_face_id);
7511 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7512 && (!next_face
7513 || next_face->box == FACE_NO_BOX));
7514 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7515 }
7516 else
7517 /* Display table entry is invalid. Return a space. */
7518 it->c = ' ', it->len = 1;
7519
7520 /* Don't change position and object of the iterator here. They are
7521 still the values of the character that had this display table
7522 entry or was translated, and that's what we want. */
7523 it->what = IT_CHARACTER;
7524 return 1;
7525 }
7526
7527 /* Get the first element of string/buffer in the visual order, after
7528 being reseated to a new position in a string or a buffer. */
7529 static void
7530 get_visually_first_element (struct it *it)
7531 {
7532 int string_p = STRINGP (it->string) || it->s;
7533 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7534 ptrdiff_t bob = (string_p ? 0 : BEGV);
7535
7536 if (STRINGP (it->string))
7537 {
7538 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7539 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7540 }
7541 else
7542 {
7543 it->bidi_it.charpos = IT_CHARPOS (*it);
7544 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7545 }
7546
7547 if (it->bidi_it.charpos == eob)
7548 {
7549 /* Nothing to do, but reset the FIRST_ELT flag, like
7550 bidi_paragraph_init does, because we are not going to
7551 call it. */
7552 it->bidi_it.first_elt = 0;
7553 }
7554 else if (it->bidi_it.charpos == bob
7555 || (!string_p
7556 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7557 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7558 {
7559 /* If we are at the beginning of a line/string, we can produce
7560 the next element right away. */
7561 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7562 bidi_move_to_visually_next (&it->bidi_it);
7563 }
7564 else
7565 {
7566 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7567
7568 /* We need to prime the bidi iterator starting at the line's or
7569 string's beginning, before we will be able to produce the
7570 next element. */
7571 if (string_p)
7572 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7573 else
7574 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7575 IT_BYTEPOS (*it), -1,
7576 &it->bidi_it.bytepos);
7577 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7578 do
7579 {
7580 /* Now return to buffer/string position where we were asked
7581 to get the next display element, and produce that. */
7582 bidi_move_to_visually_next (&it->bidi_it);
7583 }
7584 while (it->bidi_it.bytepos != orig_bytepos
7585 && it->bidi_it.charpos < eob);
7586 }
7587
7588 /* Adjust IT's position information to where we ended up. */
7589 if (STRINGP (it->string))
7590 {
7591 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7592 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7593 }
7594 else
7595 {
7596 IT_CHARPOS (*it) = it->bidi_it.charpos;
7597 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7598 }
7599
7600 if (STRINGP (it->string) || !it->s)
7601 {
7602 ptrdiff_t stop, charpos, bytepos;
7603
7604 if (STRINGP (it->string))
7605 {
7606 eassert (!it->s);
7607 stop = SCHARS (it->string);
7608 if (stop > it->end_charpos)
7609 stop = it->end_charpos;
7610 charpos = IT_STRING_CHARPOS (*it);
7611 bytepos = IT_STRING_BYTEPOS (*it);
7612 }
7613 else
7614 {
7615 stop = it->end_charpos;
7616 charpos = IT_CHARPOS (*it);
7617 bytepos = IT_BYTEPOS (*it);
7618 }
7619 if (it->bidi_it.scan_dir < 0)
7620 stop = -1;
7621 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7622 it->string);
7623 }
7624 }
7625
7626 /* Load IT with the next display element from Lisp string IT->string.
7627 IT->current.string_pos is the current position within the string.
7628 If IT->current.overlay_string_index >= 0, the Lisp string is an
7629 overlay string. */
7630
7631 static int
7632 next_element_from_string (struct it *it)
7633 {
7634 struct text_pos position;
7635
7636 eassert (STRINGP (it->string));
7637 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7638 eassert (IT_STRING_CHARPOS (*it) >= 0);
7639 position = it->current.string_pos;
7640
7641 /* With bidi reordering, the character to display might not be the
7642 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7643 that we were reseat()ed to a new string, whose paragraph
7644 direction is not known. */
7645 if (it->bidi_p && it->bidi_it.first_elt)
7646 {
7647 get_visually_first_element (it);
7648 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7649 }
7650
7651 /* Time to check for invisible text? */
7652 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7653 {
7654 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7655 {
7656 if (!(!it->bidi_p
7657 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7658 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7659 {
7660 /* With bidi non-linear iteration, we could find
7661 ourselves far beyond the last computed stop_charpos,
7662 with several other stop positions in between that we
7663 missed. Scan them all now, in buffer's logical
7664 order, until we find and handle the last stop_charpos
7665 that precedes our current position. */
7666 handle_stop_backwards (it, it->stop_charpos);
7667 return GET_NEXT_DISPLAY_ELEMENT (it);
7668 }
7669 else
7670 {
7671 if (it->bidi_p)
7672 {
7673 /* Take note of the stop position we just moved
7674 across, for when we will move back across it. */
7675 it->prev_stop = it->stop_charpos;
7676 /* If we are at base paragraph embedding level, take
7677 note of the last stop position seen at this
7678 level. */
7679 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7680 it->base_level_stop = it->stop_charpos;
7681 }
7682 handle_stop (it);
7683
7684 /* Since a handler may have changed IT->method, we must
7685 recurse here. */
7686 return GET_NEXT_DISPLAY_ELEMENT (it);
7687 }
7688 }
7689 else if (it->bidi_p
7690 /* If we are before prev_stop, we may have overstepped
7691 on our way backwards a stop_pos, and if so, we need
7692 to handle that stop_pos. */
7693 && IT_STRING_CHARPOS (*it) < it->prev_stop
7694 /* We can sometimes back up for reasons that have nothing
7695 to do with bidi reordering. E.g., compositions. The
7696 code below is only needed when we are above the base
7697 embedding level, so test for that explicitly. */
7698 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7699 {
7700 /* If we lost track of base_level_stop, we have no better
7701 place for handle_stop_backwards to start from than string
7702 beginning. This happens, e.g., when we were reseated to
7703 the previous screenful of text by vertical-motion. */
7704 if (it->base_level_stop <= 0
7705 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7706 it->base_level_stop = 0;
7707 handle_stop_backwards (it, it->base_level_stop);
7708 return GET_NEXT_DISPLAY_ELEMENT (it);
7709 }
7710 }
7711
7712 if (it->current.overlay_string_index >= 0)
7713 {
7714 /* Get the next character from an overlay string. In overlay
7715 strings, there is no field width or padding with spaces to
7716 do. */
7717 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7718 {
7719 it->what = IT_EOB;
7720 return 0;
7721 }
7722 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7723 IT_STRING_BYTEPOS (*it),
7724 it->bidi_it.scan_dir < 0
7725 ? -1
7726 : SCHARS (it->string))
7727 && next_element_from_composition (it))
7728 {
7729 return 1;
7730 }
7731 else if (STRING_MULTIBYTE (it->string))
7732 {
7733 const unsigned char *s = (SDATA (it->string)
7734 + IT_STRING_BYTEPOS (*it));
7735 it->c = string_char_and_length (s, &it->len);
7736 }
7737 else
7738 {
7739 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7740 it->len = 1;
7741 }
7742 }
7743 else
7744 {
7745 /* Get the next character from a Lisp string that is not an
7746 overlay string. Such strings come from the mode line, for
7747 example. We may have to pad with spaces, or truncate the
7748 string. See also next_element_from_c_string. */
7749 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7750 {
7751 it->what = IT_EOB;
7752 return 0;
7753 }
7754 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7755 {
7756 /* Pad with spaces. */
7757 it->c = ' ', it->len = 1;
7758 CHARPOS (position) = BYTEPOS (position) = -1;
7759 }
7760 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7761 IT_STRING_BYTEPOS (*it),
7762 it->bidi_it.scan_dir < 0
7763 ? -1
7764 : it->string_nchars)
7765 && next_element_from_composition (it))
7766 {
7767 return 1;
7768 }
7769 else if (STRING_MULTIBYTE (it->string))
7770 {
7771 const unsigned char *s = (SDATA (it->string)
7772 + IT_STRING_BYTEPOS (*it));
7773 it->c = string_char_and_length (s, &it->len);
7774 }
7775 else
7776 {
7777 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7778 it->len = 1;
7779 }
7780 }
7781
7782 /* Record what we have and where it came from. */
7783 it->what = IT_CHARACTER;
7784 it->object = it->string;
7785 it->position = position;
7786 return 1;
7787 }
7788
7789
7790 /* Load IT with next display element from C string IT->s.
7791 IT->string_nchars is the maximum number of characters to return
7792 from the string. IT->end_charpos may be greater than
7793 IT->string_nchars when this function is called, in which case we
7794 may have to return padding spaces. Value is zero if end of string
7795 reached, including padding spaces. */
7796
7797 static int
7798 next_element_from_c_string (struct it *it)
7799 {
7800 int success_p = 1;
7801
7802 eassert (it->s);
7803 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7804 it->what = IT_CHARACTER;
7805 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7806 it->object = Qnil;
7807
7808 /* With bidi reordering, the character to display might not be the
7809 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7810 we were reseated to a new string, whose paragraph direction is
7811 not known. */
7812 if (it->bidi_p && it->bidi_it.first_elt)
7813 get_visually_first_element (it);
7814
7815 /* IT's position can be greater than IT->string_nchars in case a
7816 field width or precision has been specified when the iterator was
7817 initialized. */
7818 if (IT_CHARPOS (*it) >= it->end_charpos)
7819 {
7820 /* End of the game. */
7821 it->what = IT_EOB;
7822 success_p = 0;
7823 }
7824 else if (IT_CHARPOS (*it) >= it->string_nchars)
7825 {
7826 /* Pad with spaces. */
7827 it->c = ' ', it->len = 1;
7828 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7829 }
7830 else if (it->multibyte_p)
7831 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7832 else
7833 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7834
7835 return success_p;
7836 }
7837
7838
7839 /* Set up IT to return characters from an ellipsis, if appropriate.
7840 The definition of the ellipsis glyphs may come from a display table
7841 entry. This function fills IT with the first glyph from the
7842 ellipsis if an ellipsis is to be displayed. */
7843
7844 static int
7845 next_element_from_ellipsis (struct it *it)
7846 {
7847 if (it->selective_display_ellipsis_p)
7848 setup_for_ellipsis (it, it->len);
7849 else
7850 {
7851 /* The face at the current position may be different from the
7852 face we find after the invisible text. Remember what it
7853 was in IT->saved_face_id, and signal that it's there by
7854 setting face_before_selective_p. */
7855 it->saved_face_id = it->face_id;
7856 it->method = GET_FROM_BUFFER;
7857 it->object = it->w->contents;
7858 reseat_at_next_visible_line_start (it, 1);
7859 it->face_before_selective_p = 1;
7860 }
7861
7862 return GET_NEXT_DISPLAY_ELEMENT (it);
7863 }
7864
7865
7866 /* Deliver an image display element. The iterator IT is already
7867 filled with image information (done in handle_display_prop). Value
7868 is always 1. */
7869
7870
7871 static int
7872 next_element_from_image (struct it *it)
7873 {
7874 it->what = IT_IMAGE;
7875 it->ignore_overlay_strings_at_pos_p = 0;
7876 return 1;
7877 }
7878
7879
7880 /* Fill iterator IT with next display element from a stretch glyph
7881 property. IT->object is the value of the text property. Value is
7882 always 1. */
7883
7884 static int
7885 next_element_from_stretch (struct it *it)
7886 {
7887 it->what = IT_STRETCH;
7888 return 1;
7889 }
7890
7891 /* Scan backwards from IT's current position until we find a stop
7892 position, or until BEGV. This is called when we find ourself
7893 before both the last known prev_stop and base_level_stop while
7894 reordering bidirectional text. */
7895
7896 static void
7897 compute_stop_pos_backwards (struct it *it)
7898 {
7899 const int SCAN_BACK_LIMIT = 1000;
7900 struct text_pos pos;
7901 struct display_pos save_current = it->current;
7902 struct text_pos save_position = it->position;
7903 ptrdiff_t charpos = IT_CHARPOS (*it);
7904 ptrdiff_t where_we_are = charpos;
7905 ptrdiff_t save_stop_pos = it->stop_charpos;
7906 ptrdiff_t save_end_pos = it->end_charpos;
7907
7908 eassert (NILP (it->string) && !it->s);
7909 eassert (it->bidi_p);
7910 it->bidi_p = 0;
7911 do
7912 {
7913 it->end_charpos = min (charpos + 1, ZV);
7914 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7915 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7916 reseat_1 (it, pos, 0);
7917 compute_stop_pos (it);
7918 /* We must advance forward, right? */
7919 if (it->stop_charpos <= charpos)
7920 emacs_abort ();
7921 }
7922 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7923
7924 if (it->stop_charpos <= where_we_are)
7925 it->prev_stop = it->stop_charpos;
7926 else
7927 it->prev_stop = BEGV;
7928 it->bidi_p = 1;
7929 it->current = save_current;
7930 it->position = save_position;
7931 it->stop_charpos = save_stop_pos;
7932 it->end_charpos = save_end_pos;
7933 }
7934
7935 /* Scan forward from CHARPOS in the current buffer/string, until we
7936 find a stop position > current IT's position. Then handle the stop
7937 position before that. This is called when we bump into a stop
7938 position while reordering bidirectional text. CHARPOS should be
7939 the last previously processed stop_pos (or BEGV/0, if none were
7940 processed yet) whose position is less that IT's current
7941 position. */
7942
7943 static void
7944 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7945 {
7946 int bufp = !STRINGP (it->string);
7947 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7948 struct display_pos save_current = it->current;
7949 struct text_pos save_position = it->position;
7950 struct text_pos pos1;
7951 ptrdiff_t next_stop;
7952
7953 /* Scan in strict logical order. */
7954 eassert (it->bidi_p);
7955 it->bidi_p = 0;
7956 do
7957 {
7958 it->prev_stop = charpos;
7959 if (bufp)
7960 {
7961 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7962 reseat_1 (it, pos1, 0);
7963 }
7964 else
7965 it->current.string_pos = string_pos (charpos, it->string);
7966 compute_stop_pos (it);
7967 /* We must advance forward, right? */
7968 if (it->stop_charpos <= it->prev_stop)
7969 emacs_abort ();
7970 charpos = it->stop_charpos;
7971 }
7972 while (charpos <= where_we_are);
7973
7974 it->bidi_p = 1;
7975 it->current = save_current;
7976 it->position = save_position;
7977 next_stop = it->stop_charpos;
7978 it->stop_charpos = it->prev_stop;
7979 handle_stop (it);
7980 it->stop_charpos = next_stop;
7981 }
7982
7983 /* Load IT with the next display element from current_buffer. Value
7984 is zero if end of buffer reached. IT->stop_charpos is the next
7985 position at which to stop and check for text properties or buffer
7986 end. */
7987
7988 static int
7989 next_element_from_buffer (struct it *it)
7990 {
7991 int success_p = 1;
7992
7993 eassert (IT_CHARPOS (*it) >= BEGV);
7994 eassert (NILP (it->string) && !it->s);
7995 eassert (!it->bidi_p
7996 || (EQ (it->bidi_it.string.lstring, Qnil)
7997 && it->bidi_it.string.s == NULL));
7998
7999 /* With bidi reordering, the character to display might not be the
8000 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8001 we were reseat()ed to a new buffer position, which is potentially
8002 a different paragraph. */
8003 if (it->bidi_p && it->bidi_it.first_elt)
8004 {
8005 get_visually_first_element (it);
8006 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8007 }
8008
8009 if (IT_CHARPOS (*it) >= it->stop_charpos)
8010 {
8011 if (IT_CHARPOS (*it) >= it->end_charpos)
8012 {
8013 int overlay_strings_follow_p;
8014
8015 /* End of the game, except when overlay strings follow that
8016 haven't been returned yet. */
8017 if (it->overlay_strings_at_end_processed_p)
8018 overlay_strings_follow_p = 0;
8019 else
8020 {
8021 it->overlay_strings_at_end_processed_p = 1;
8022 overlay_strings_follow_p = get_overlay_strings (it, 0);
8023 }
8024
8025 if (overlay_strings_follow_p)
8026 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8027 else
8028 {
8029 it->what = IT_EOB;
8030 it->position = it->current.pos;
8031 success_p = 0;
8032 }
8033 }
8034 else if (!(!it->bidi_p
8035 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8036 || IT_CHARPOS (*it) == it->stop_charpos))
8037 {
8038 /* With bidi non-linear iteration, we could find ourselves
8039 far beyond the last computed stop_charpos, with several
8040 other stop positions in between that we missed. Scan
8041 them all now, in buffer's logical order, until we find
8042 and handle the last stop_charpos that precedes our
8043 current position. */
8044 handle_stop_backwards (it, it->stop_charpos);
8045 return GET_NEXT_DISPLAY_ELEMENT (it);
8046 }
8047 else
8048 {
8049 if (it->bidi_p)
8050 {
8051 /* Take note of the stop position we just moved across,
8052 for when we will move back across it. */
8053 it->prev_stop = it->stop_charpos;
8054 /* If we are at base paragraph embedding level, take
8055 note of the last stop position seen at this
8056 level. */
8057 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8058 it->base_level_stop = it->stop_charpos;
8059 }
8060 handle_stop (it);
8061 return GET_NEXT_DISPLAY_ELEMENT (it);
8062 }
8063 }
8064 else if (it->bidi_p
8065 /* If we are before prev_stop, we may have overstepped on
8066 our way backwards a stop_pos, and if so, we need to
8067 handle that stop_pos. */
8068 && IT_CHARPOS (*it) < it->prev_stop
8069 /* We can sometimes back up for reasons that have nothing
8070 to do with bidi reordering. E.g., compositions. The
8071 code below is only needed when we are above the base
8072 embedding level, so test for that explicitly. */
8073 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8074 {
8075 if (it->base_level_stop <= 0
8076 || IT_CHARPOS (*it) < it->base_level_stop)
8077 {
8078 /* If we lost track of base_level_stop, we need to find
8079 prev_stop by looking backwards. This happens, e.g., when
8080 we were reseated to the previous screenful of text by
8081 vertical-motion. */
8082 it->base_level_stop = BEGV;
8083 compute_stop_pos_backwards (it);
8084 handle_stop_backwards (it, it->prev_stop);
8085 }
8086 else
8087 handle_stop_backwards (it, it->base_level_stop);
8088 return GET_NEXT_DISPLAY_ELEMENT (it);
8089 }
8090 else
8091 {
8092 /* No face changes, overlays etc. in sight, so just return a
8093 character from current_buffer. */
8094 unsigned char *p;
8095 ptrdiff_t stop;
8096
8097 /* Maybe run the redisplay end trigger hook. Performance note:
8098 This doesn't seem to cost measurable time. */
8099 if (it->redisplay_end_trigger_charpos
8100 && it->glyph_row
8101 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8102 run_redisplay_end_trigger_hook (it);
8103
8104 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8105 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8106 stop)
8107 && next_element_from_composition (it))
8108 {
8109 return 1;
8110 }
8111
8112 /* Get the next character, maybe multibyte. */
8113 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8114 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8115 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8116 else
8117 it->c = *p, it->len = 1;
8118
8119 /* Record what we have and where it came from. */
8120 it->what = IT_CHARACTER;
8121 it->object = it->w->contents;
8122 it->position = it->current.pos;
8123
8124 /* Normally we return the character found above, except when we
8125 really want to return an ellipsis for selective display. */
8126 if (it->selective)
8127 {
8128 if (it->c == '\n')
8129 {
8130 /* A value of selective > 0 means hide lines indented more
8131 than that number of columns. */
8132 if (it->selective > 0
8133 && IT_CHARPOS (*it) + 1 < ZV
8134 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8135 IT_BYTEPOS (*it) + 1,
8136 it->selective))
8137 {
8138 success_p = next_element_from_ellipsis (it);
8139 it->dpvec_char_len = -1;
8140 }
8141 }
8142 else if (it->c == '\r' && it->selective == -1)
8143 {
8144 /* A value of selective == -1 means that everything from the
8145 CR to the end of the line is invisible, with maybe an
8146 ellipsis displayed for it. */
8147 success_p = next_element_from_ellipsis (it);
8148 it->dpvec_char_len = -1;
8149 }
8150 }
8151 }
8152
8153 /* Value is zero if end of buffer reached. */
8154 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8155 return success_p;
8156 }
8157
8158
8159 /* Run the redisplay end trigger hook for IT. */
8160
8161 static void
8162 run_redisplay_end_trigger_hook (struct it *it)
8163 {
8164 Lisp_Object args[3];
8165
8166 /* IT->glyph_row should be non-null, i.e. we should be actually
8167 displaying something, or otherwise we should not run the hook. */
8168 eassert (it->glyph_row);
8169
8170 /* Set up hook arguments. */
8171 args[0] = Qredisplay_end_trigger_functions;
8172 args[1] = it->window;
8173 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8174 it->redisplay_end_trigger_charpos = 0;
8175
8176 /* Since we are *trying* to run these functions, don't try to run
8177 them again, even if they get an error. */
8178 wset_redisplay_end_trigger (it->w, Qnil);
8179 Frun_hook_with_args (3, args);
8180
8181 /* Notice if it changed the face of the character we are on. */
8182 handle_face_prop (it);
8183 }
8184
8185
8186 /* Deliver a composition display element. Unlike the other
8187 next_element_from_XXX, this function is not registered in the array
8188 get_next_element[]. It is called from next_element_from_buffer and
8189 next_element_from_string when necessary. */
8190
8191 static int
8192 next_element_from_composition (struct it *it)
8193 {
8194 it->what = IT_COMPOSITION;
8195 it->len = it->cmp_it.nbytes;
8196 if (STRINGP (it->string))
8197 {
8198 if (it->c < 0)
8199 {
8200 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8201 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8202 return 0;
8203 }
8204 it->position = it->current.string_pos;
8205 it->object = it->string;
8206 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8207 IT_STRING_BYTEPOS (*it), it->string);
8208 }
8209 else
8210 {
8211 if (it->c < 0)
8212 {
8213 IT_CHARPOS (*it) += it->cmp_it.nchars;
8214 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8215 if (it->bidi_p)
8216 {
8217 if (it->bidi_it.new_paragraph)
8218 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8219 /* Resync the bidi iterator with IT's new position.
8220 FIXME: this doesn't support bidirectional text. */
8221 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8222 bidi_move_to_visually_next (&it->bidi_it);
8223 }
8224 return 0;
8225 }
8226 it->position = it->current.pos;
8227 it->object = it->w->contents;
8228 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8229 IT_BYTEPOS (*it), Qnil);
8230 }
8231 return 1;
8232 }
8233
8234
8235 \f
8236 /***********************************************************************
8237 Moving an iterator without producing glyphs
8238 ***********************************************************************/
8239
8240 /* Check if iterator is at a position corresponding to a valid buffer
8241 position after some move_it_ call. */
8242
8243 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8244 ((it)->method == GET_FROM_STRING \
8245 ? IT_STRING_CHARPOS (*it) == 0 \
8246 : 1)
8247
8248
8249 /* Move iterator IT to a specified buffer or X position within one
8250 line on the display without producing glyphs.
8251
8252 OP should be a bit mask including some or all of these bits:
8253 MOVE_TO_X: Stop upon reaching x-position TO_X.
8254 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8255 Regardless of OP's value, stop upon reaching the end of the display line.
8256
8257 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8258 This means, in particular, that TO_X includes window's horizontal
8259 scroll amount.
8260
8261 The return value has several possible values that
8262 say what condition caused the scan to stop:
8263
8264 MOVE_POS_MATCH_OR_ZV
8265 - when TO_POS or ZV was reached.
8266
8267 MOVE_X_REACHED
8268 -when TO_X was reached before TO_POS or ZV were reached.
8269
8270 MOVE_LINE_CONTINUED
8271 - when we reached the end of the display area and the line must
8272 be continued.
8273
8274 MOVE_LINE_TRUNCATED
8275 - when we reached the end of the display area and the line is
8276 truncated.
8277
8278 MOVE_NEWLINE_OR_CR
8279 - when we stopped at a line end, i.e. a newline or a CR and selective
8280 display is on. */
8281
8282 static enum move_it_result
8283 move_it_in_display_line_to (struct it *it,
8284 ptrdiff_t to_charpos, int to_x,
8285 enum move_operation_enum op)
8286 {
8287 enum move_it_result result = MOVE_UNDEFINED;
8288 struct glyph_row *saved_glyph_row;
8289 struct it wrap_it, atpos_it, atx_it, ppos_it;
8290 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8291 void *ppos_data = NULL;
8292 int may_wrap = 0;
8293 enum it_method prev_method = it->method;
8294 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8295 int saw_smaller_pos = prev_pos < to_charpos;
8296
8297 /* Don't produce glyphs in produce_glyphs. */
8298 saved_glyph_row = it->glyph_row;
8299 it->glyph_row = NULL;
8300
8301 /* Use wrap_it to save a copy of IT wherever a word wrap could
8302 occur. Use atpos_it to save a copy of IT at the desired buffer
8303 position, if found, so that we can scan ahead and check if the
8304 word later overshoots the window edge. Use atx_it similarly, for
8305 pixel positions. */
8306 wrap_it.sp = -1;
8307 atpos_it.sp = -1;
8308 atx_it.sp = -1;
8309
8310 /* Use ppos_it under bidi reordering to save a copy of IT for the
8311 position > CHARPOS that is the closest to CHARPOS. We restore
8312 that position in IT when we have scanned the entire display line
8313 without finding a match for CHARPOS and all the character
8314 positions are greater than CHARPOS. */
8315 if (it->bidi_p)
8316 {
8317 SAVE_IT (ppos_it, *it, ppos_data);
8318 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8319 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8320 SAVE_IT (ppos_it, *it, ppos_data);
8321 }
8322
8323 #define BUFFER_POS_REACHED_P() \
8324 ((op & MOVE_TO_POS) != 0 \
8325 && BUFFERP (it->object) \
8326 && (IT_CHARPOS (*it) == to_charpos \
8327 || ((!it->bidi_p \
8328 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8329 && IT_CHARPOS (*it) > to_charpos) \
8330 || (it->what == IT_COMPOSITION \
8331 && ((IT_CHARPOS (*it) > to_charpos \
8332 && to_charpos >= it->cmp_it.charpos) \
8333 || (IT_CHARPOS (*it) < to_charpos \
8334 && to_charpos <= it->cmp_it.charpos)))) \
8335 && (it->method == GET_FROM_BUFFER \
8336 || (it->method == GET_FROM_DISPLAY_VECTOR \
8337 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8338
8339 /* If there's a line-/wrap-prefix, handle it. */
8340 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8341 && it->current_y < it->last_visible_y)
8342 handle_line_prefix (it);
8343
8344 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8345 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8346
8347 while (1)
8348 {
8349 int x, i, ascent = 0, descent = 0;
8350
8351 /* Utility macro to reset an iterator with x, ascent, and descent. */
8352 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8353 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8354 (IT)->max_descent = descent)
8355
8356 /* Stop if we move beyond TO_CHARPOS (after an image or a
8357 display string or stretch glyph). */
8358 if ((op & MOVE_TO_POS) != 0
8359 && BUFFERP (it->object)
8360 && it->method == GET_FROM_BUFFER
8361 && (((!it->bidi_p
8362 /* When the iterator is at base embedding level, we
8363 are guaranteed that characters are delivered for
8364 display in strictly increasing order of their
8365 buffer positions. */
8366 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8367 && IT_CHARPOS (*it) > to_charpos)
8368 || (it->bidi_p
8369 && (prev_method == GET_FROM_IMAGE
8370 || prev_method == GET_FROM_STRETCH
8371 || prev_method == GET_FROM_STRING)
8372 /* Passed TO_CHARPOS from left to right. */
8373 && ((prev_pos < to_charpos
8374 && IT_CHARPOS (*it) > to_charpos)
8375 /* Passed TO_CHARPOS from right to left. */
8376 || (prev_pos > to_charpos
8377 && IT_CHARPOS (*it) < to_charpos)))))
8378 {
8379 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8380 {
8381 result = MOVE_POS_MATCH_OR_ZV;
8382 break;
8383 }
8384 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8385 /* If wrap_it is valid, the current position might be in a
8386 word that is wrapped. So, save the iterator in
8387 atpos_it and continue to see if wrapping happens. */
8388 SAVE_IT (atpos_it, *it, atpos_data);
8389 }
8390
8391 /* Stop when ZV reached.
8392 We used to stop here when TO_CHARPOS reached as well, but that is
8393 too soon if this glyph does not fit on this line. So we handle it
8394 explicitly below. */
8395 if (!get_next_display_element (it))
8396 {
8397 result = MOVE_POS_MATCH_OR_ZV;
8398 break;
8399 }
8400
8401 if (it->line_wrap == TRUNCATE)
8402 {
8403 if (BUFFER_POS_REACHED_P ())
8404 {
8405 result = MOVE_POS_MATCH_OR_ZV;
8406 break;
8407 }
8408 }
8409 else
8410 {
8411 if (it->line_wrap == WORD_WRAP)
8412 {
8413 if (IT_DISPLAYING_WHITESPACE (it))
8414 may_wrap = 1;
8415 else if (may_wrap)
8416 {
8417 /* We have reached a glyph that follows one or more
8418 whitespace characters. If the position is
8419 already found, we are done. */
8420 if (atpos_it.sp >= 0)
8421 {
8422 RESTORE_IT (it, &atpos_it, atpos_data);
8423 result = MOVE_POS_MATCH_OR_ZV;
8424 goto done;
8425 }
8426 if (atx_it.sp >= 0)
8427 {
8428 RESTORE_IT (it, &atx_it, atx_data);
8429 result = MOVE_X_REACHED;
8430 goto done;
8431 }
8432 /* Otherwise, we can wrap here. */
8433 SAVE_IT (wrap_it, *it, wrap_data);
8434 may_wrap = 0;
8435 }
8436 }
8437 }
8438
8439 /* Remember the line height for the current line, in case
8440 the next element doesn't fit on the line. */
8441 ascent = it->max_ascent;
8442 descent = it->max_descent;
8443
8444 /* The call to produce_glyphs will get the metrics of the
8445 display element IT is loaded with. Record the x-position
8446 before this display element, in case it doesn't fit on the
8447 line. */
8448 x = it->current_x;
8449
8450 PRODUCE_GLYPHS (it);
8451
8452 if (it->area != TEXT_AREA)
8453 {
8454 prev_method = it->method;
8455 if (it->method == GET_FROM_BUFFER)
8456 prev_pos = IT_CHARPOS (*it);
8457 set_iterator_to_next (it, 1);
8458 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8459 SET_TEXT_POS (this_line_min_pos,
8460 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8461 if (it->bidi_p
8462 && (op & MOVE_TO_POS)
8463 && IT_CHARPOS (*it) > to_charpos
8464 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8465 SAVE_IT (ppos_it, *it, ppos_data);
8466 continue;
8467 }
8468
8469 /* The number of glyphs we get back in IT->nglyphs will normally
8470 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8471 character on a terminal frame, or (iii) a line end. For the
8472 second case, IT->nglyphs - 1 padding glyphs will be present.
8473 (On X frames, there is only one glyph produced for a
8474 composite character.)
8475
8476 The behavior implemented below means, for continuation lines,
8477 that as many spaces of a TAB as fit on the current line are
8478 displayed there. For terminal frames, as many glyphs of a
8479 multi-glyph character are displayed in the current line, too.
8480 This is what the old redisplay code did, and we keep it that
8481 way. Under X, the whole shape of a complex character must
8482 fit on the line or it will be completely displayed in the
8483 next line.
8484
8485 Note that both for tabs and padding glyphs, all glyphs have
8486 the same width. */
8487 if (it->nglyphs)
8488 {
8489 /* More than one glyph or glyph doesn't fit on line. All
8490 glyphs have the same width. */
8491 int single_glyph_width = it->pixel_width / it->nglyphs;
8492 int new_x;
8493 int x_before_this_char = x;
8494 int hpos_before_this_char = it->hpos;
8495
8496 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8497 {
8498 new_x = x + single_glyph_width;
8499
8500 /* We want to leave anything reaching TO_X to the caller. */
8501 if ((op & MOVE_TO_X) && new_x > to_x)
8502 {
8503 if (BUFFER_POS_REACHED_P ())
8504 {
8505 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8506 goto buffer_pos_reached;
8507 if (atpos_it.sp < 0)
8508 {
8509 SAVE_IT (atpos_it, *it, atpos_data);
8510 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8511 }
8512 }
8513 else
8514 {
8515 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8516 {
8517 it->current_x = x;
8518 result = MOVE_X_REACHED;
8519 break;
8520 }
8521 if (atx_it.sp < 0)
8522 {
8523 SAVE_IT (atx_it, *it, atx_data);
8524 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8525 }
8526 }
8527 }
8528
8529 if (/* Lines are continued. */
8530 it->line_wrap != TRUNCATE
8531 && (/* And glyph doesn't fit on the line. */
8532 new_x > it->last_visible_x
8533 /* Or it fits exactly and we're on a window
8534 system frame. */
8535 || (new_x == it->last_visible_x
8536 && FRAME_WINDOW_P (it->f)
8537 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8538 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8539 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8540 {
8541 if (/* IT->hpos == 0 means the very first glyph
8542 doesn't fit on the line, e.g. a wide image. */
8543 it->hpos == 0
8544 || (new_x == it->last_visible_x
8545 && FRAME_WINDOW_P (it->f)))
8546 {
8547 ++it->hpos;
8548 it->current_x = new_x;
8549
8550 /* The character's last glyph just barely fits
8551 in this row. */
8552 if (i == it->nglyphs - 1)
8553 {
8554 /* If this is the destination position,
8555 return a position *before* it in this row,
8556 now that we know it fits in this row. */
8557 if (BUFFER_POS_REACHED_P ())
8558 {
8559 if (it->line_wrap != WORD_WRAP
8560 || wrap_it.sp < 0)
8561 {
8562 it->hpos = hpos_before_this_char;
8563 it->current_x = x_before_this_char;
8564 result = MOVE_POS_MATCH_OR_ZV;
8565 break;
8566 }
8567 if (it->line_wrap == WORD_WRAP
8568 && atpos_it.sp < 0)
8569 {
8570 SAVE_IT (atpos_it, *it, atpos_data);
8571 atpos_it.current_x = x_before_this_char;
8572 atpos_it.hpos = hpos_before_this_char;
8573 }
8574 }
8575
8576 prev_method = it->method;
8577 if (it->method == GET_FROM_BUFFER)
8578 prev_pos = IT_CHARPOS (*it);
8579 set_iterator_to_next (it, 1);
8580 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8581 SET_TEXT_POS (this_line_min_pos,
8582 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8583 /* On graphical terminals, newlines may
8584 "overflow" into the fringe if
8585 overflow-newline-into-fringe is non-nil.
8586 On text terminals, and on graphical
8587 terminals with no right margin, newlines
8588 may overflow into the last glyph on the
8589 display line.*/
8590 if (!FRAME_WINDOW_P (it->f)
8591 || ((it->bidi_p
8592 && it->bidi_it.paragraph_dir == R2L)
8593 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8594 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8595 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8596 {
8597 if (!get_next_display_element (it))
8598 {
8599 result = MOVE_POS_MATCH_OR_ZV;
8600 break;
8601 }
8602 if (BUFFER_POS_REACHED_P ())
8603 {
8604 if (ITERATOR_AT_END_OF_LINE_P (it))
8605 result = MOVE_POS_MATCH_OR_ZV;
8606 else
8607 result = MOVE_LINE_CONTINUED;
8608 break;
8609 }
8610 if (ITERATOR_AT_END_OF_LINE_P (it)
8611 && (it->line_wrap != WORD_WRAP
8612 || wrap_it.sp < 0))
8613 {
8614 result = MOVE_NEWLINE_OR_CR;
8615 break;
8616 }
8617 }
8618 }
8619 }
8620 else
8621 IT_RESET_X_ASCENT_DESCENT (it);
8622
8623 if (wrap_it.sp >= 0)
8624 {
8625 RESTORE_IT (it, &wrap_it, wrap_data);
8626 atpos_it.sp = -1;
8627 atx_it.sp = -1;
8628 }
8629
8630 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8631 IT_CHARPOS (*it)));
8632 result = MOVE_LINE_CONTINUED;
8633 break;
8634 }
8635
8636 if (BUFFER_POS_REACHED_P ())
8637 {
8638 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8639 goto buffer_pos_reached;
8640 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8641 {
8642 SAVE_IT (atpos_it, *it, atpos_data);
8643 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8644 }
8645 }
8646
8647 if (new_x > it->first_visible_x)
8648 {
8649 /* Glyph is visible. Increment number of glyphs that
8650 would be displayed. */
8651 ++it->hpos;
8652 }
8653 }
8654
8655 if (result != MOVE_UNDEFINED)
8656 break;
8657 }
8658 else if (BUFFER_POS_REACHED_P ())
8659 {
8660 buffer_pos_reached:
8661 IT_RESET_X_ASCENT_DESCENT (it);
8662 result = MOVE_POS_MATCH_OR_ZV;
8663 break;
8664 }
8665 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8666 {
8667 /* Stop when TO_X specified and reached. This check is
8668 necessary here because of lines consisting of a line end,
8669 only. The line end will not produce any glyphs and we
8670 would never get MOVE_X_REACHED. */
8671 eassert (it->nglyphs == 0);
8672 result = MOVE_X_REACHED;
8673 break;
8674 }
8675
8676 /* Is this a line end? If yes, we're done. */
8677 if (ITERATOR_AT_END_OF_LINE_P (it))
8678 {
8679 /* If we are past TO_CHARPOS, but never saw any character
8680 positions smaller than TO_CHARPOS, return
8681 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8682 did. */
8683 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8684 {
8685 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8686 {
8687 if (IT_CHARPOS (ppos_it) < ZV)
8688 {
8689 RESTORE_IT (it, &ppos_it, ppos_data);
8690 result = MOVE_POS_MATCH_OR_ZV;
8691 }
8692 else
8693 goto buffer_pos_reached;
8694 }
8695 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8696 && IT_CHARPOS (*it) > to_charpos)
8697 goto buffer_pos_reached;
8698 else
8699 result = MOVE_NEWLINE_OR_CR;
8700 }
8701 else
8702 result = MOVE_NEWLINE_OR_CR;
8703 break;
8704 }
8705
8706 prev_method = it->method;
8707 if (it->method == GET_FROM_BUFFER)
8708 prev_pos = IT_CHARPOS (*it);
8709 /* The current display element has been consumed. Advance
8710 to the next. */
8711 set_iterator_to_next (it, 1);
8712 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8713 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8714 if (IT_CHARPOS (*it) < to_charpos)
8715 saw_smaller_pos = 1;
8716 if (it->bidi_p
8717 && (op & MOVE_TO_POS)
8718 && IT_CHARPOS (*it) >= to_charpos
8719 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8720 SAVE_IT (ppos_it, *it, ppos_data);
8721
8722 /* Stop if lines are truncated and IT's current x-position is
8723 past the right edge of the window now. */
8724 if (it->line_wrap == TRUNCATE
8725 && it->current_x >= it->last_visible_x)
8726 {
8727 if (!FRAME_WINDOW_P (it->f)
8728 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8729 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8730 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8731 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8732 {
8733 int at_eob_p = 0;
8734
8735 if ((at_eob_p = !get_next_display_element (it))
8736 || BUFFER_POS_REACHED_P ()
8737 /* If we are past TO_CHARPOS, but never saw any
8738 character positions smaller than TO_CHARPOS,
8739 return MOVE_POS_MATCH_OR_ZV, like the
8740 unidirectional display did. */
8741 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8742 && !saw_smaller_pos
8743 && IT_CHARPOS (*it) > to_charpos))
8744 {
8745 if (it->bidi_p
8746 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8747 RESTORE_IT (it, &ppos_it, ppos_data);
8748 result = MOVE_POS_MATCH_OR_ZV;
8749 break;
8750 }
8751 if (ITERATOR_AT_END_OF_LINE_P (it))
8752 {
8753 result = MOVE_NEWLINE_OR_CR;
8754 break;
8755 }
8756 }
8757 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8758 && !saw_smaller_pos
8759 && IT_CHARPOS (*it) > to_charpos)
8760 {
8761 if (IT_CHARPOS (ppos_it) < ZV)
8762 RESTORE_IT (it, &ppos_it, ppos_data);
8763 result = MOVE_POS_MATCH_OR_ZV;
8764 break;
8765 }
8766 result = MOVE_LINE_TRUNCATED;
8767 break;
8768 }
8769 #undef IT_RESET_X_ASCENT_DESCENT
8770 }
8771
8772 #undef BUFFER_POS_REACHED_P
8773
8774 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8775 restore the saved iterator. */
8776 if (atpos_it.sp >= 0)
8777 RESTORE_IT (it, &atpos_it, atpos_data);
8778 else if (atx_it.sp >= 0)
8779 RESTORE_IT (it, &atx_it, atx_data);
8780
8781 done:
8782
8783 if (atpos_data)
8784 bidi_unshelve_cache (atpos_data, 1);
8785 if (atx_data)
8786 bidi_unshelve_cache (atx_data, 1);
8787 if (wrap_data)
8788 bidi_unshelve_cache (wrap_data, 1);
8789 if (ppos_data)
8790 bidi_unshelve_cache (ppos_data, 1);
8791
8792 /* Restore the iterator settings altered at the beginning of this
8793 function. */
8794 it->glyph_row = saved_glyph_row;
8795 return result;
8796 }
8797
8798 /* For external use. */
8799 void
8800 move_it_in_display_line (struct it *it,
8801 ptrdiff_t to_charpos, int to_x,
8802 enum move_operation_enum op)
8803 {
8804 if (it->line_wrap == WORD_WRAP
8805 && (op & MOVE_TO_X))
8806 {
8807 struct it save_it;
8808 void *save_data = NULL;
8809 int skip;
8810
8811 SAVE_IT (save_it, *it, save_data);
8812 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8813 /* When word-wrap is on, TO_X may lie past the end
8814 of a wrapped line. Then it->current is the
8815 character on the next line, so backtrack to the
8816 space before the wrap point. */
8817 if (skip == MOVE_LINE_CONTINUED)
8818 {
8819 int prev_x = max (it->current_x - 1, 0);
8820 RESTORE_IT (it, &save_it, save_data);
8821 move_it_in_display_line_to
8822 (it, -1, prev_x, MOVE_TO_X);
8823 }
8824 else
8825 bidi_unshelve_cache (save_data, 1);
8826 }
8827 else
8828 move_it_in_display_line_to (it, to_charpos, to_x, op);
8829 }
8830
8831
8832 /* Move IT forward until it satisfies one or more of the criteria in
8833 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8834
8835 OP is a bit-mask that specifies where to stop, and in particular,
8836 which of those four position arguments makes a difference. See the
8837 description of enum move_operation_enum.
8838
8839 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8840 screen line, this function will set IT to the next position that is
8841 displayed to the right of TO_CHARPOS on the screen. */
8842
8843 void
8844 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8845 {
8846 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8847 int line_height, line_start_x = 0, reached = 0;
8848 void *backup_data = NULL;
8849
8850 for (;;)
8851 {
8852 if (op & MOVE_TO_VPOS)
8853 {
8854 /* If no TO_CHARPOS and no TO_X specified, stop at the
8855 start of the line TO_VPOS. */
8856 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8857 {
8858 if (it->vpos == to_vpos)
8859 {
8860 reached = 1;
8861 break;
8862 }
8863 else
8864 skip = move_it_in_display_line_to (it, -1, -1, 0);
8865 }
8866 else
8867 {
8868 /* TO_VPOS >= 0 means stop at TO_X in the line at
8869 TO_VPOS, or at TO_POS, whichever comes first. */
8870 if (it->vpos == to_vpos)
8871 {
8872 reached = 2;
8873 break;
8874 }
8875
8876 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8877
8878 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8879 {
8880 reached = 3;
8881 break;
8882 }
8883 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8884 {
8885 /* We have reached TO_X but not in the line we want. */
8886 skip = move_it_in_display_line_to (it, to_charpos,
8887 -1, MOVE_TO_POS);
8888 if (skip == MOVE_POS_MATCH_OR_ZV)
8889 {
8890 reached = 4;
8891 break;
8892 }
8893 }
8894 }
8895 }
8896 else if (op & MOVE_TO_Y)
8897 {
8898 struct it it_backup;
8899
8900 if (it->line_wrap == WORD_WRAP)
8901 SAVE_IT (it_backup, *it, backup_data);
8902
8903 /* TO_Y specified means stop at TO_X in the line containing
8904 TO_Y---or at TO_CHARPOS if this is reached first. The
8905 problem is that we can't really tell whether the line
8906 contains TO_Y before we have completely scanned it, and
8907 this may skip past TO_X. What we do is to first scan to
8908 TO_X.
8909
8910 If TO_X is not specified, use a TO_X of zero. The reason
8911 is to make the outcome of this function more predictable.
8912 If we didn't use TO_X == 0, we would stop at the end of
8913 the line which is probably not what a caller would expect
8914 to happen. */
8915 skip = move_it_in_display_line_to
8916 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8917 (MOVE_TO_X | (op & MOVE_TO_POS)));
8918
8919 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8920 if (skip == MOVE_POS_MATCH_OR_ZV)
8921 reached = 5;
8922 else if (skip == MOVE_X_REACHED)
8923 {
8924 /* If TO_X was reached, we want to know whether TO_Y is
8925 in the line. We know this is the case if the already
8926 scanned glyphs make the line tall enough. Otherwise,
8927 we must check by scanning the rest of the line. */
8928 line_height = it->max_ascent + it->max_descent;
8929 if (to_y >= it->current_y
8930 && to_y < it->current_y + line_height)
8931 {
8932 reached = 6;
8933 break;
8934 }
8935 SAVE_IT (it_backup, *it, backup_data);
8936 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8937 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8938 op & MOVE_TO_POS);
8939 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8940 line_height = it->max_ascent + it->max_descent;
8941 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8942
8943 if (to_y >= it->current_y
8944 && to_y < it->current_y + line_height)
8945 {
8946 /* If TO_Y is in this line and TO_X was reached
8947 above, we scanned too far. We have to restore
8948 IT's settings to the ones before skipping. But
8949 keep the more accurate values of max_ascent and
8950 max_descent we've found while skipping the rest
8951 of the line, for the sake of callers, such as
8952 pos_visible_p, that need to know the line
8953 height. */
8954 int max_ascent = it->max_ascent;
8955 int max_descent = it->max_descent;
8956
8957 RESTORE_IT (it, &it_backup, backup_data);
8958 it->max_ascent = max_ascent;
8959 it->max_descent = max_descent;
8960 reached = 6;
8961 }
8962 else
8963 {
8964 skip = skip2;
8965 if (skip == MOVE_POS_MATCH_OR_ZV)
8966 reached = 7;
8967 }
8968 }
8969 else
8970 {
8971 /* Check whether TO_Y is in this line. */
8972 line_height = it->max_ascent + it->max_descent;
8973 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8974
8975 if (to_y >= it->current_y
8976 && to_y < it->current_y + line_height)
8977 {
8978 /* When word-wrap is on, TO_X may lie past the end
8979 of a wrapped line. Then it->current is the
8980 character on the next line, so backtrack to the
8981 space before the wrap point. */
8982 if (skip == MOVE_LINE_CONTINUED
8983 && it->line_wrap == WORD_WRAP)
8984 {
8985 int prev_x = max (it->current_x - 1, 0);
8986 RESTORE_IT (it, &it_backup, backup_data);
8987 skip = move_it_in_display_line_to
8988 (it, -1, prev_x, MOVE_TO_X);
8989 }
8990 reached = 6;
8991 }
8992 }
8993
8994 if (reached)
8995 break;
8996 }
8997 else if (BUFFERP (it->object)
8998 && (it->method == GET_FROM_BUFFER
8999 || it->method == GET_FROM_STRETCH)
9000 && IT_CHARPOS (*it) >= to_charpos
9001 /* Under bidi iteration, a call to set_iterator_to_next
9002 can scan far beyond to_charpos if the initial
9003 portion of the next line needs to be reordered. In
9004 that case, give move_it_in_display_line_to another
9005 chance below. */
9006 && !(it->bidi_p
9007 && it->bidi_it.scan_dir == -1))
9008 skip = MOVE_POS_MATCH_OR_ZV;
9009 else
9010 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9011
9012 switch (skip)
9013 {
9014 case MOVE_POS_MATCH_OR_ZV:
9015 reached = 8;
9016 goto out;
9017
9018 case MOVE_NEWLINE_OR_CR:
9019 set_iterator_to_next (it, 1);
9020 it->continuation_lines_width = 0;
9021 break;
9022
9023 case MOVE_LINE_TRUNCATED:
9024 it->continuation_lines_width = 0;
9025 reseat_at_next_visible_line_start (it, 0);
9026 if ((op & MOVE_TO_POS) != 0
9027 && IT_CHARPOS (*it) > to_charpos)
9028 {
9029 reached = 9;
9030 goto out;
9031 }
9032 break;
9033
9034 case MOVE_LINE_CONTINUED:
9035 /* For continued lines ending in a tab, some of the glyphs
9036 associated with the tab are displayed on the current
9037 line. Since it->current_x does not include these glyphs,
9038 we use it->last_visible_x instead. */
9039 if (it->c == '\t')
9040 {
9041 it->continuation_lines_width += it->last_visible_x;
9042 /* When moving by vpos, ensure that the iterator really
9043 advances to the next line (bug#847, bug#969). Fixme:
9044 do we need to do this in other circumstances? */
9045 if (it->current_x != it->last_visible_x
9046 && (op & MOVE_TO_VPOS)
9047 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9048 {
9049 line_start_x = it->current_x + it->pixel_width
9050 - it->last_visible_x;
9051 set_iterator_to_next (it, 0);
9052 }
9053 }
9054 else
9055 it->continuation_lines_width += it->current_x;
9056 break;
9057
9058 default:
9059 emacs_abort ();
9060 }
9061
9062 /* Reset/increment for the next run. */
9063 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9064 it->current_x = line_start_x;
9065 line_start_x = 0;
9066 it->hpos = 0;
9067 it->current_y += it->max_ascent + it->max_descent;
9068 ++it->vpos;
9069 last_height = it->max_ascent + it->max_descent;
9070 it->max_ascent = it->max_descent = 0;
9071 }
9072
9073 out:
9074
9075 /* On text terminals, we may stop at the end of a line in the middle
9076 of a multi-character glyph. If the glyph itself is continued,
9077 i.e. it is actually displayed on the next line, don't treat this
9078 stopping point as valid; move to the next line instead (unless
9079 that brings us offscreen). */
9080 if (!FRAME_WINDOW_P (it->f)
9081 && op & MOVE_TO_POS
9082 && IT_CHARPOS (*it) == to_charpos
9083 && it->what == IT_CHARACTER
9084 && it->nglyphs > 1
9085 && it->line_wrap == WINDOW_WRAP
9086 && it->current_x == it->last_visible_x - 1
9087 && it->c != '\n'
9088 && it->c != '\t'
9089 && it->vpos < it->w->window_end_vpos)
9090 {
9091 it->continuation_lines_width += it->current_x;
9092 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9093 it->current_y += it->max_ascent + it->max_descent;
9094 ++it->vpos;
9095 last_height = it->max_ascent + it->max_descent;
9096 }
9097
9098 if (backup_data)
9099 bidi_unshelve_cache (backup_data, 1);
9100
9101 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9102 }
9103
9104
9105 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9106
9107 If DY > 0, move IT backward at least that many pixels. DY = 0
9108 means move IT backward to the preceding line start or BEGV. This
9109 function may move over more than DY pixels if IT->current_y - DY
9110 ends up in the middle of a line; in this case IT->current_y will be
9111 set to the top of the line moved to. */
9112
9113 void
9114 move_it_vertically_backward (struct it *it, int dy)
9115 {
9116 int nlines, h;
9117 struct it it2, it3;
9118 void *it2data = NULL, *it3data = NULL;
9119 ptrdiff_t start_pos;
9120 int nchars_per_row
9121 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9122 ptrdiff_t pos_limit;
9123
9124 move_further_back:
9125 eassert (dy >= 0);
9126
9127 start_pos = IT_CHARPOS (*it);
9128
9129 /* Estimate how many newlines we must move back. */
9130 nlines = max (1, dy / default_line_pixel_height (it->w));
9131 if (it->line_wrap == TRUNCATE)
9132 pos_limit = BEGV;
9133 else
9134 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9135
9136 /* Set the iterator's position that many lines back. But don't go
9137 back more than NLINES full screen lines -- this wins a day with
9138 buffers which have very long lines. */
9139 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9140 back_to_previous_visible_line_start (it);
9141
9142 /* Reseat the iterator here. When moving backward, we don't want
9143 reseat to skip forward over invisible text, set up the iterator
9144 to deliver from overlay strings at the new position etc. So,
9145 use reseat_1 here. */
9146 reseat_1 (it, it->current.pos, 1);
9147
9148 /* We are now surely at a line start. */
9149 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9150 reordering is in effect. */
9151 it->continuation_lines_width = 0;
9152
9153 /* Move forward and see what y-distance we moved. First move to the
9154 start of the next line so that we get its height. We need this
9155 height to be able to tell whether we reached the specified
9156 y-distance. */
9157 SAVE_IT (it2, *it, it2data);
9158 it2.max_ascent = it2.max_descent = 0;
9159 do
9160 {
9161 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9162 MOVE_TO_POS | MOVE_TO_VPOS);
9163 }
9164 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9165 /* If we are in a display string which starts at START_POS,
9166 and that display string includes a newline, and we are
9167 right after that newline (i.e. at the beginning of a
9168 display line), exit the loop, because otherwise we will
9169 infloop, since move_it_to will see that it is already at
9170 START_POS and will not move. */
9171 || (it2.method == GET_FROM_STRING
9172 && IT_CHARPOS (it2) == start_pos
9173 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9174 eassert (IT_CHARPOS (*it) >= BEGV);
9175 SAVE_IT (it3, it2, it3data);
9176
9177 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9178 eassert (IT_CHARPOS (*it) >= BEGV);
9179 /* H is the actual vertical distance from the position in *IT
9180 and the starting position. */
9181 h = it2.current_y - it->current_y;
9182 /* NLINES is the distance in number of lines. */
9183 nlines = it2.vpos - it->vpos;
9184
9185 /* Correct IT's y and vpos position
9186 so that they are relative to the starting point. */
9187 it->vpos -= nlines;
9188 it->current_y -= h;
9189
9190 if (dy == 0)
9191 {
9192 /* DY == 0 means move to the start of the screen line. The
9193 value of nlines is > 0 if continuation lines were involved,
9194 or if the original IT position was at start of a line. */
9195 RESTORE_IT (it, it, it2data);
9196 if (nlines > 0)
9197 move_it_by_lines (it, nlines);
9198 /* The above code moves us to some position NLINES down,
9199 usually to its first glyph (leftmost in an L2R line), but
9200 that's not necessarily the start of the line, under bidi
9201 reordering. We want to get to the character position
9202 that is immediately after the newline of the previous
9203 line. */
9204 if (it->bidi_p
9205 && !it->continuation_lines_width
9206 && !STRINGP (it->string)
9207 && IT_CHARPOS (*it) > BEGV
9208 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9209 {
9210 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9211
9212 DEC_BOTH (cp, bp);
9213 cp = find_newline_no_quit (cp, bp, -1, NULL);
9214 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9215 }
9216 bidi_unshelve_cache (it3data, 1);
9217 }
9218 else
9219 {
9220 /* The y-position we try to reach, relative to *IT.
9221 Note that H has been subtracted in front of the if-statement. */
9222 int target_y = it->current_y + h - dy;
9223 int y0 = it3.current_y;
9224 int y1;
9225 int line_height;
9226
9227 RESTORE_IT (&it3, &it3, it3data);
9228 y1 = line_bottom_y (&it3);
9229 line_height = y1 - y0;
9230 RESTORE_IT (it, it, it2data);
9231 /* If we did not reach target_y, try to move further backward if
9232 we can. If we moved too far backward, try to move forward. */
9233 if (target_y < it->current_y
9234 /* This is heuristic. In a window that's 3 lines high, with
9235 a line height of 13 pixels each, recentering with point
9236 on the bottom line will try to move -39/2 = 19 pixels
9237 backward. Try to avoid moving into the first line. */
9238 && (it->current_y - target_y
9239 > min (window_box_height (it->w), line_height * 2 / 3))
9240 && IT_CHARPOS (*it) > BEGV)
9241 {
9242 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9243 target_y - it->current_y));
9244 dy = it->current_y - target_y;
9245 goto move_further_back;
9246 }
9247 else if (target_y >= it->current_y + line_height
9248 && IT_CHARPOS (*it) < ZV)
9249 {
9250 /* Should move forward by at least one line, maybe more.
9251
9252 Note: Calling move_it_by_lines can be expensive on
9253 terminal frames, where compute_motion is used (via
9254 vmotion) to do the job, when there are very long lines
9255 and truncate-lines is nil. That's the reason for
9256 treating terminal frames specially here. */
9257
9258 if (!FRAME_WINDOW_P (it->f))
9259 move_it_vertically (it, target_y - (it->current_y + line_height));
9260 else
9261 {
9262 do
9263 {
9264 move_it_by_lines (it, 1);
9265 }
9266 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9267 }
9268 }
9269 }
9270 }
9271
9272
9273 /* Move IT by a specified amount of pixel lines DY. DY negative means
9274 move backwards. DY = 0 means move to start of screen line. At the
9275 end, IT will be on the start of a screen line. */
9276
9277 void
9278 move_it_vertically (struct it *it, int dy)
9279 {
9280 if (dy <= 0)
9281 move_it_vertically_backward (it, -dy);
9282 else
9283 {
9284 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9285 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9286 MOVE_TO_POS | MOVE_TO_Y);
9287 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9288
9289 /* If buffer ends in ZV without a newline, move to the start of
9290 the line to satisfy the post-condition. */
9291 if (IT_CHARPOS (*it) == ZV
9292 && ZV > BEGV
9293 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9294 move_it_by_lines (it, 0);
9295 }
9296 }
9297
9298
9299 /* Move iterator IT past the end of the text line it is in. */
9300
9301 void
9302 move_it_past_eol (struct it *it)
9303 {
9304 enum move_it_result rc;
9305
9306 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9307 if (rc == MOVE_NEWLINE_OR_CR)
9308 set_iterator_to_next (it, 0);
9309 }
9310
9311
9312 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9313 negative means move up. DVPOS == 0 means move to the start of the
9314 screen line.
9315
9316 Optimization idea: If we would know that IT->f doesn't use
9317 a face with proportional font, we could be faster for
9318 truncate-lines nil. */
9319
9320 void
9321 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9322 {
9323
9324 /* The commented-out optimization uses vmotion on terminals. This
9325 gives bad results, because elements like it->what, on which
9326 callers such as pos_visible_p rely, aren't updated. */
9327 /* struct position pos;
9328 if (!FRAME_WINDOW_P (it->f))
9329 {
9330 struct text_pos textpos;
9331
9332 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9333 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9334 reseat (it, textpos, 1);
9335 it->vpos += pos.vpos;
9336 it->current_y += pos.vpos;
9337 }
9338 else */
9339
9340 if (dvpos == 0)
9341 {
9342 /* DVPOS == 0 means move to the start of the screen line. */
9343 move_it_vertically_backward (it, 0);
9344 /* Let next call to line_bottom_y calculate real line height. */
9345 last_height = 0;
9346 }
9347 else if (dvpos > 0)
9348 {
9349 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9350 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9351 {
9352 /* Only move to the next buffer position if we ended up in a
9353 string from display property, not in an overlay string
9354 (before-string or after-string). That is because the
9355 latter don't conceal the underlying buffer position, so
9356 we can ask to move the iterator to the exact position we
9357 are interested in. Note that, even if we are already at
9358 IT_CHARPOS (*it), the call below is not a no-op, as it
9359 will detect that we are at the end of the string, pop the
9360 iterator, and compute it->current_x and it->hpos
9361 correctly. */
9362 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9363 -1, -1, -1, MOVE_TO_POS);
9364 }
9365 }
9366 else
9367 {
9368 struct it it2;
9369 void *it2data = NULL;
9370 ptrdiff_t start_charpos, i;
9371 int nchars_per_row
9372 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9373 ptrdiff_t pos_limit;
9374
9375 /* Start at the beginning of the screen line containing IT's
9376 position. This may actually move vertically backwards,
9377 in case of overlays, so adjust dvpos accordingly. */
9378 dvpos += it->vpos;
9379 move_it_vertically_backward (it, 0);
9380 dvpos -= it->vpos;
9381
9382 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9383 screen lines, and reseat the iterator there. */
9384 start_charpos = IT_CHARPOS (*it);
9385 if (it->line_wrap == TRUNCATE)
9386 pos_limit = BEGV;
9387 else
9388 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9389 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9390 back_to_previous_visible_line_start (it);
9391 reseat (it, it->current.pos, 1);
9392
9393 /* Move further back if we end up in a string or an image. */
9394 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9395 {
9396 /* First try to move to start of display line. */
9397 dvpos += it->vpos;
9398 move_it_vertically_backward (it, 0);
9399 dvpos -= it->vpos;
9400 if (IT_POS_VALID_AFTER_MOVE_P (it))
9401 break;
9402 /* If start of line is still in string or image,
9403 move further back. */
9404 back_to_previous_visible_line_start (it);
9405 reseat (it, it->current.pos, 1);
9406 dvpos--;
9407 }
9408
9409 it->current_x = it->hpos = 0;
9410
9411 /* Above call may have moved too far if continuation lines
9412 are involved. Scan forward and see if it did. */
9413 SAVE_IT (it2, *it, it2data);
9414 it2.vpos = it2.current_y = 0;
9415 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9416 it->vpos -= it2.vpos;
9417 it->current_y -= it2.current_y;
9418 it->current_x = it->hpos = 0;
9419
9420 /* If we moved too far back, move IT some lines forward. */
9421 if (it2.vpos > -dvpos)
9422 {
9423 int delta = it2.vpos + dvpos;
9424
9425 RESTORE_IT (&it2, &it2, it2data);
9426 SAVE_IT (it2, *it, it2data);
9427 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9428 /* Move back again if we got too far ahead. */
9429 if (IT_CHARPOS (*it) >= start_charpos)
9430 RESTORE_IT (it, &it2, it2data);
9431 else
9432 bidi_unshelve_cache (it2data, 1);
9433 }
9434 else
9435 RESTORE_IT (it, it, it2data);
9436 }
9437 }
9438
9439 /* Return 1 if IT points into the middle of a display vector. */
9440
9441 int
9442 in_display_vector_p (struct it *it)
9443 {
9444 return (it->method == GET_FROM_DISPLAY_VECTOR
9445 && it->current.dpvec_index > 0
9446 && it->dpvec + it->current.dpvec_index != it->dpend);
9447 }
9448
9449 \f
9450 /***********************************************************************
9451 Messages
9452 ***********************************************************************/
9453
9454
9455 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9456 to *Messages*. */
9457
9458 void
9459 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9460 {
9461 Lisp_Object args[3];
9462 Lisp_Object msg, fmt;
9463 char *buffer;
9464 ptrdiff_t len;
9465 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9466 USE_SAFE_ALLOCA;
9467
9468 fmt = msg = Qnil;
9469 GCPRO4 (fmt, msg, arg1, arg2);
9470
9471 args[0] = fmt = build_string (format);
9472 args[1] = arg1;
9473 args[2] = arg2;
9474 msg = Fformat (3, args);
9475
9476 len = SBYTES (msg) + 1;
9477 buffer = SAFE_ALLOCA (len);
9478 memcpy (buffer, SDATA (msg), len);
9479
9480 message_dolog (buffer, len - 1, 1, 0);
9481 SAFE_FREE ();
9482
9483 UNGCPRO;
9484 }
9485
9486
9487 /* Output a newline in the *Messages* buffer if "needs" one. */
9488
9489 void
9490 message_log_maybe_newline (void)
9491 {
9492 if (message_log_need_newline)
9493 message_dolog ("", 0, 1, 0);
9494 }
9495
9496
9497 /* Add a string M of length NBYTES to the message log, optionally
9498 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9499 true, means interpret the contents of M as multibyte. This
9500 function calls low-level routines in order to bypass text property
9501 hooks, etc. which might not be safe to run.
9502
9503 This may GC (insert may run before/after change hooks),
9504 so the buffer M must NOT point to a Lisp string. */
9505
9506 void
9507 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9508 {
9509 const unsigned char *msg = (const unsigned char *) m;
9510
9511 if (!NILP (Vmemory_full))
9512 return;
9513
9514 if (!NILP (Vmessage_log_max))
9515 {
9516 struct buffer *oldbuf;
9517 Lisp_Object oldpoint, oldbegv, oldzv;
9518 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9519 ptrdiff_t point_at_end = 0;
9520 ptrdiff_t zv_at_end = 0;
9521 Lisp_Object old_deactivate_mark;
9522 struct gcpro gcpro1;
9523
9524 old_deactivate_mark = Vdeactivate_mark;
9525 oldbuf = current_buffer;
9526
9527 /* Ensure the Messages buffer exists, and switch to it.
9528 If we created it, set the major-mode. */
9529 {
9530 int newbuffer = 0;
9531 if (NILP (Fget_buffer (Vmessages_buffer_name))) newbuffer = 1;
9532
9533 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9534
9535 if (newbuffer
9536 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
9537 call0 (intern ("messages-buffer-mode"));
9538 }
9539
9540 bset_undo_list (current_buffer, Qt);
9541 bset_cache_long_scans (current_buffer, Qnil);
9542
9543 oldpoint = message_dolog_marker1;
9544 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9545 oldbegv = message_dolog_marker2;
9546 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9547 oldzv = message_dolog_marker3;
9548 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9549 GCPRO1 (old_deactivate_mark);
9550
9551 if (PT == Z)
9552 point_at_end = 1;
9553 if (ZV == Z)
9554 zv_at_end = 1;
9555
9556 BEGV = BEG;
9557 BEGV_BYTE = BEG_BYTE;
9558 ZV = Z;
9559 ZV_BYTE = Z_BYTE;
9560 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9561
9562 /* Insert the string--maybe converting multibyte to single byte
9563 or vice versa, so that all the text fits the buffer. */
9564 if (multibyte
9565 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9566 {
9567 ptrdiff_t i;
9568 int c, char_bytes;
9569 char work[1];
9570
9571 /* Convert a multibyte string to single-byte
9572 for the *Message* buffer. */
9573 for (i = 0; i < nbytes; i += char_bytes)
9574 {
9575 c = string_char_and_length (msg + i, &char_bytes);
9576 work[0] = (ASCII_CHAR_P (c)
9577 ? c
9578 : multibyte_char_to_unibyte (c));
9579 insert_1_both (work, 1, 1, 1, 0, 0);
9580 }
9581 }
9582 else if (! multibyte
9583 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9584 {
9585 ptrdiff_t i;
9586 int c, char_bytes;
9587 unsigned char str[MAX_MULTIBYTE_LENGTH];
9588 /* Convert a single-byte string to multibyte
9589 for the *Message* buffer. */
9590 for (i = 0; i < nbytes; i++)
9591 {
9592 c = msg[i];
9593 MAKE_CHAR_MULTIBYTE (c);
9594 char_bytes = CHAR_STRING (c, str);
9595 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9596 }
9597 }
9598 else if (nbytes)
9599 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9600
9601 if (nlflag)
9602 {
9603 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9604 printmax_t dups;
9605
9606 insert_1_both ("\n", 1, 1, 1, 0, 0);
9607
9608 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9609 this_bol = PT;
9610 this_bol_byte = PT_BYTE;
9611
9612 /* See if this line duplicates the previous one.
9613 If so, combine duplicates. */
9614 if (this_bol > BEG)
9615 {
9616 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9617 prev_bol = PT;
9618 prev_bol_byte = PT_BYTE;
9619
9620 dups = message_log_check_duplicate (prev_bol_byte,
9621 this_bol_byte);
9622 if (dups)
9623 {
9624 del_range_both (prev_bol, prev_bol_byte,
9625 this_bol, this_bol_byte, 0);
9626 if (dups > 1)
9627 {
9628 char dupstr[sizeof " [ times]"
9629 + INT_STRLEN_BOUND (printmax_t)];
9630
9631 /* If you change this format, don't forget to also
9632 change message_log_check_duplicate. */
9633 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9634 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9635 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9636 }
9637 }
9638 }
9639
9640 /* If we have more than the desired maximum number of lines
9641 in the *Messages* buffer now, delete the oldest ones.
9642 This is safe because we don't have undo in this buffer. */
9643
9644 if (NATNUMP (Vmessage_log_max))
9645 {
9646 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9647 -XFASTINT (Vmessage_log_max) - 1, 0);
9648 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9649 }
9650 }
9651 BEGV = marker_position (oldbegv);
9652 BEGV_BYTE = marker_byte_position (oldbegv);
9653
9654 if (zv_at_end)
9655 {
9656 ZV = Z;
9657 ZV_BYTE = Z_BYTE;
9658 }
9659 else
9660 {
9661 ZV = marker_position (oldzv);
9662 ZV_BYTE = marker_byte_position (oldzv);
9663 }
9664
9665 if (point_at_end)
9666 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9667 else
9668 /* We can't do Fgoto_char (oldpoint) because it will run some
9669 Lisp code. */
9670 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9671 marker_byte_position (oldpoint));
9672
9673 UNGCPRO;
9674 unchain_marker (XMARKER (oldpoint));
9675 unchain_marker (XMARKER (oldbegv));
9676 unchain_marker (XMARKER (oldzv));
9677
9678 /* We called insert_1_both above with its 5th argument (PREPARE)
9679 zero, which prevents insert_1_both from calling
9680 prepare_to_modify_buffer, which in turns prevents us from
9681 incrementing windows_or_buffers_changed even if *Messages* is
9682 shown in some window. So we must manually set
9683 windows_or_buffers_changed here to make up for that. */
9684 windows_or_buffers_changed = old_windows_or_buffers_changed;
9685 bset_redisplay (current_buffer);
9686
9687 set_buffer_internal (oldbuf);
9688
9689 message_log_need_newline = !nlflag;
9690 Vdeactivate_mark = old_deactivate_mark;
9691 }
9692 }
9693
9694
9695 /* We are at the end of the buffer after just having inserted a newline.
9696 (Note: We depend on the fact we won't be crossing the gap.)
9697 Check to see if the most recent message looks a lot like the previous one.
9698 Return 0 if different, 1 if the new one should just replace it, or a
9699 value N > 1 if we should also append " [N times]". */
9700
9701 static intmax_t
9702 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9703 {
9704 ptrdiff_t i;
9705 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9706 int seen_dots = 0;
9707 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9708 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9709
9710 for (i = 0; i < len; i++)
9711 {
9712 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9713 seen_dots = 1;
9714 if (p1[i] != p2[i])
9715 return seen_dots;
9716 }
9717 p1 += len;
9718 if (*p1 == '\n')
9719 return 2;
9720 if (*p1++ == ' ' && *p1++ == '[')
9721 {
9722 char *pend;
9723 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9724 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9725 return n + 1;
9726 }
9727 return 0;
9728 }
9729 \f
9730
9731 /* Display an echo area message M with a specified length of NBYTES
9732 bytes. The string may include null characters. If M is not a
9733 string, clear out any existing message, and let the mini-buffer
9734 text show through.
9735
9736 This function cancels echoing. */
9737
9738 void
9739 message3 (Lisp_Object m)
9740 {
9741 struct gcpro gcpro1;
9742
9743 GCPRO1 (m);
9744 clear_message (1,1);
9745 cancel_echoing ();
9746
9747 /* First flush out any partial line written with print. */
9748 message_log_maybe_newline ();
9749 if (STRINGP (m))
9750 {
9751 ptrdiff_t nbytes = SBYTES (m);
9752 bool multibyte = STRING_MULTIBYTE (m);
9753 USE_SAFE_ALLOCA;
9754 char *buffer = SAFE_ALLOCA (nbytes);
9755 memcpy (buffer, SDATA (m), nbytes);
9756 message_dolog (buffer, nbytes, 1, multibyte);
9757 SAFE_FREE ();
9758 }
9759 message3_nolog (m);
9760
9761 UNGCPRO;
9762 }
9763
9764
9765 /* The non-logging version of message3.
9766 This does not cancel echoing, because it is used for echoing.
9767 Perhaps we need to make a separate function for echoing
9768 and make this cancel echoing. */
9769
9770 void
9771 message3_nolog (Lisp_Object m)
9772 {
9773 struct frame *sf = SELECTED_FRAME ();
9774
9775 if (FRAME_INITIAL_P (sf))
9776 {
9777 if (noninteractive_need_newline)
9778 putc ('\n', stderr);
9779 noninteractive_need_newline = 0;
9780 if (STRINGP (m))
9781 {
9782 Lisp_Object s = ENCODE_SYSTEM (m);
9783
9784 fwrite (SDATA (s), SBYTES (s), 1, stderr);
9785 }
9786 if (cursor_in_echo_area == 0)
9787 fprintf (stderr, "\n");
9788 fflush (stderr);
9789 }
9790 /* Error messages get reported properly by cmd_error, so this must be just an
9791 informative message; if the frame hasn't really been initialized yet, just
9792 toss it. */
9793 else if (INTERACTIVE && sf->glyphs_initialized_p)
9794 {
9795 /* Get the frame containing the mini-buffer
9796 that the selected frame is using. */
9797 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9798 Lisp_Object frame = XWINDOW (mini_window)->frame;
9799 struct frame *f = XFRAME (frame);
9800
9801 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9802 Fmake_frame_visible (frame);
9803
9804 if (STRINGP (m) && SCHARS (m) > 0)
9805 {
9806 set_message (m);
9807 if (minibuffer_auto_raise)
9808 Fraise_frame (frame);
9809 /* Assume we are not echoing.
9810 (If we are, echo_now will override this.) */
9811 echo_message_buffer = Qnil;
9812 }
9813 else
9814 clear_message (1, 1);
9815
9816 do_pending_window_change (0);
9817 echo_area_display (1);
9818 do_pending_window_change (0);
9819 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9820 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9821 }
9822 }
9823
9824
9825 /* Display a null-terminated echo area message M. If M is 0, clear
9826 out any existing message, and let the mini-buffer text show through.
9827
9828 The buffer M must continue to exist until after the echo area gets
9829 cleared or some other message gets displayed there. Do not pass
9830 text that is stored in a Lisp string. Do not pass text in a buffer
9831 that was alloca'd. */
9832
9833 void
9834 message1 (const char *m)
9835 {
9836 message3 (m ? build_unibyte_string (m) : Qnil);
9837 }
9838
9839
9840 /* The non-logging counterpart of message1. */
9841
9842 void
9843 message1_nolog (const char *m)
9844 {
9845 message3_nolog (m ? build_unibyte_string (m) : Qnil);
9846 }
9847
9848 /* Display a message M which contains a single %s
9849 which gets replaced with STRING. */
9850
9851 void
9852 message_with_string (const char *m, Lisp_Object string, int log)
9853 {
9854 CHECK_STRING (string);
9855
9856 if (noninteractive)
9857 {
9858 if (m)
9859 {
9860 /* ENCODE_SYSTEM below can GC and/or relocate the Lisp
9861 String whose data pointer might be passed to us in M. So
9862 we use a local copy. */
9863 char *fmt = xstrdup (m);
9864
9865 if (noninteractive_need_newline)
9866 putc ('\n', stderr);
9867 noninteractive_need_newline = 0;
9868 fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string)));
9869 if (!cursor_in_echo_area)
9870 fprintf (stderr, "\n");
9871 fflush (stderr);
9872 xfree (fmt);
9873 }
9874 }
9875 else if (INTERACTIVE)
9876 {
9877 /* The frame whose minibuffer we're going to display the message on.
9878 It may be larger than the selected frame, so we need
9879 to use its buffer, not the selected frame's buffer. */
9880 Lisp_Object mini_window;
9881 struct frame *f, *sf = SELECTED_FRAME ();
9882
9883 /* Get the frame containing the minibuffer
9884 that the selected frame is using. */
9885 mini_window = FRAME_MINIBUF_WINDOW (sf);
9886 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9887
9888 /* Error messages get reported properly by cmd_error, so this must be
9889 just an informative message; if the frame hasn't really been
9890 initialized yet, just toss it. */
9891 if (f->glyphs_initialized_p)
9892 {
9893 Lisp_Object args[2], msg;
9894 struct gcpro gcpro1, gcpro2;
9895
9896 args[0] = build_string (m);
9897 args[1] = msg = string;
9898 GCPRO2 (args[0], msg);
9899 gcpro1.nvars = 2;
9900
9901 msg = Fformat (2, args);
9902
9903 if (log)
9904 message3 (msg);
9905 else
9906 message3_nolog (msg);
9907
9908 UNGCPRO;
9909
9910 /* Print should start at the beginning of the message
9911 buffer next time. */
9912 message_buf_print = 0;
9913 }
9914 }
9915 }
9916
9917
9918 /* Dump an informative message to the minibuf. If M is 0, clear out
9919 any existing message, and let the mini-buffer text show through. */
9920
9921 static void
9922 vmessage (const char *m, va_list ap)
9923 {
9924 if (noninteractive)
9925 {
9926 if (m)
9927 {
9928 if (noninteractive_need_newline)
9929 putc ('\n', stderr);
9930 noninteractive_need_newline = 0;
9931 vfprintf (stderr, m, ap);
9932 if (cursor_in_echo_area == 0)
9933 fprintf (stderr, "\n");
9934 fflush (stderr);
9935 }
9936 }
9937 else if (INTERACTIVE)
9938 {
9939 /* The frame whose mini-buffer we're going to display the message
9940 on. It may be larger than the selected frame, so we need to
9941 use its buffer, not the selected frame's buffer. */
9942 Lisp_Object mini_window;
9943 struct frame *f, *sf = SELECTED_FRAME ();
9944
9945 /* Get the frame containing the mini-buffer
9946 that the selected frame is using. */
9947 mini_window = FRAME_MINIBUF_WINDOW (sf);
9948 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9949
9950 /* Error messages get reported properly by cmd_error, so this must be
9951 just an informative message; if the frame hasn't really been
9952 initialized yet, just toss it. */
9953 if (f->glyphs_initialized_p)
9954 {
9955 if (m)
9956 {
9957 ptrdiff_t len;
9958 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9959 char *message_buf = alloca (maxsize + 1);
9960
9961 len = doprnt (message_buf, maxsize, m, 0, ap);
9962
9963 message3 (make_string (message_buf, len));
9964 }
9965 else
9966 message1 (0);
9967
9968 /* Print should start at the beginning of the message
9969 buffer next time. */
9970 message_buf_print = 0;
9971 }
9972 }
9973 }
9974
9975 void
9976 message (const char *m, ...)
9977 {
9978 va_list ap;
9979 va_start (ap, m);
9980 vmessage (m, ap);
9981 va_end (ap);
9982 }
9983
9984
9985 #if 0
9986 /* The non-logging version of message. */
9987
9988 void
9989 message_nolog (const char *m, ...)
9990 {
9991 Lisp_Object old_log_max;
9992 va_list ap;
9993 va_start (ap, m);
9994 old_log_max = Vmessage_log_max;
9995 Vmessage_log_max = Qnil;
9996 vmessage (m, ap);
9997 Vmessage_log_max = old_log_max;
9998 va_end (ap);
9999 }
10000 #endif
10001
10002
10003 /* Display the current message in the current mini-buffer. This is
10004 only called from error handlers in process.c, and is not time
10005 critical. */
10006
10007 void
10008 update_echo_area (void)
10009 {
10010 if (!NILP (echo_area_buffer[0]))
10011 {
10012 Lisp_Object string;
10013 string = Fcurrent_message ();
10014 message3 (string);
10015 }
10016 }
10017
10018
10019 /* Make sure echo area buffers in `echo_buffers' are live.
10020 If they aren't, make new ones. */
10021
10022 static void
10023 ensure_echo_area_buffers (void)
10024 {
10025 int i;
10026
10027 for (i = 0; i < 2; ++i)
10028 if (!BUFFERP (echo_buffer[i])
10029 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10030 {
10031 char name[30];
10032 Lisp_Object old_buffer;
10033 int j;
10034
10035 old_buffer = echo_buffer[i];
10036 echo_buffer[i] = Fget_buffer_create
10037 (make_formatted_string (name, " *Echo Area %d*", i));
10038 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10039 /* to force word wrap in echo area -
10040 it was decided to postpone this*/
10041 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10042
10043 for (j = 0; j < 2; ++j)
10044 if (EQ (old_buffer, echo_area_buffer[j]))
10045 echo_area_buffer[j] = echo_buffer[i];
10046 }
10047 }
10048
10049
10050 /* Call FN with args A1..A2 with either the current or last displayed
10051 echo_area_buffer as current buffer.
10052
10053 WHICH zero means use the current message buffer
10054 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10055 from echo_buffer[] and clear it.
10056
10057 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10058 suitable buffer from echo_buffer[] and clear it.
10059
10060 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10061 that the current message becomes the last displayed one, make
10062 choose a suitable buffer for echo_area_buffer[0], and clear it.
10063
10064 Value is what FN returns. */
10065
10066 static int
10067 with_echo_area_buffer (struct window *w, int which,
10068 int (*fn) (ptrdiff_t, Lisp_Object),
10069 ptrdiff_t a1, Lisp_Object a2)
10070 {
10071 Lisp_Object buffer;
10072 int this_one, the_other, clear_buffer_p, rc;
10073 ptrdiff_t count = SPECPDL_INDEX ();
10074
10075 /* If buffers aren't live, make new ones. */
10076 ensure_echo_area_buffers ();
10077
10078 clear_buffer_p = 0;
10079
10080 if (which == 0)
10081 this_one = 0, the_other = 1;
10082 else if (which > 0)
10083 this_one = 1, the_other = 0;
10084 else
10085 {
10086 this_one = 0, the_other = 1;
10087 clear_buffer_p = 1;
10088
10089 /* We need a fresh one in case the current echo buffer equals
10090 the one containing the last displayed echo area message. */
10091 if (!NILP (echo_area_buffer[this_one])
10092 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10093 echo_area_buffer[this_one] = Qnil;
10094 }
10095
10096 /* Choose a suitable buffer from echo_buffer[] is we don't
10097 have one. */
10098 if (NILP (echo_area_buffer[this_one]))
10099 {
10100 echo_area_buffer[this_one]
10101 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10102 ? echo_buffer[the_other]
10103 : echo_buffer[this_one]);
10104 clear_buffer_p = 1;
10105 }
10106
10107 buffer = echo_area_buffer[this_one];
10108
10109 /* Don't get confused by reusing the buffer used for echoing
10110 for a different purpose. */
10111 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10112 cancel_echoing ();
10113
10114 record_unwind_protect (unwind_with_echo_area_buffer,
10115 with_echo_area_buffer_unwind_data (w));
10116
10117 /* Make the echo area buffer current. Note that for display
10118 purposes, it is not necessary that the displayed window's buffer
10119 == current_buffer, except for text property lookup. So, let's
10120 only set that buffer temporarily here without doing a full
10121 Fset_window_buffer. We must also change w->pointm, though,
10122 because otherwise an assertions in unshow_buffer fails, and Emacs
10123 aborts. */
10124 set_buffer_internal_1 (XBUFFER (buffer));
10125 if (w)
10126 {
10127 wset_buffer (w, buffer);
10128 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10129 }
10130
10131 bset_undo_list (current_buffer, Qt);
10132 bset_read_only (current_buffer, Qnil);
10133 specbind (Qinhibit_read_only, Qt);
10134 specbind (Qinhibit_modification_hooks, Qt);
10135
10136 if (clear_buffer_p && Z > BEG)
10137 del_range (BEG, Z);
10138
10139 eassert (BEGV >= BEG);
10140 eassert (ZV <= Z && ZV >= BEGV);
10141
10142 rc = fn (a1, a2);
10143
10144 eassert (BEGV >= BEG);
10145 eassert (ZV <= Z && ZV >= BEGV);
10146
10147 unbind_to (count, Qnil);
10148 return rc;
10149 }
10150
10151
10152 /* Save state that should be preserved around the call to the function
10153 FN called in with_echo_area_buffer. */
10154
10155 static Lisp_Object
10156 with_echo_area_buffer_unwind_data (struct window *w)
10157 {
10158 int i = 0;
10159 Lisp_Object vector, tmp;
10160
10161 /* Reduce consing by keeping one vector in
10162 Vwith_echo_area_save_vector. */
10163 vector = Vwith_echo_area_save_vector;
10164 Vwith_echo_area_save_vector = Qnil;
10165
10166 if (NILP (vector))
10167 vector = Fmake_vector (make_number (9), Qnil);
10168
10169 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10170 ASET (vector, i, Vdeactivate_mark); ++i;
10171 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10172
10173 if (w)
10174 {
10175 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10176 ASET (vector, i, w->contents); ++i;
10177 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10178 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10179 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10180 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10181 }
10182 else
10183 {
10184 int end = i + 6;
10185 for (; i < end; ++i)
10186 ASET (vector, i, Qnil);
10187 }
10188
10189 eassert (i == ASIZE (vector));
10190 return vector;
10191 }
10192
10193
10194 /* Restore global state from VECTOR which was created by
10195 with_echo_area_buffer_unwind_data. */
10196
10197 static void
10198 unwind_with_echo_area_buffer (Lisp_Object vector)
10199 {
10200 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10201 Vdeactivate_mark = AREF (vector, 1);
10202 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10203
10204 if (WINDOWP (AREF (vector, 3)))
10205 {
10206 struct window *w;
10207 Lisp_Object buffer;
10208
10209 w = XWINDOW (AREF (vector, 3));
10210 buffer = AREF (vector, 4);
10211
10212 wset_buffer (w, buffer);
10213 set_marker_both (w->pointm, buffer,
10214 XFASTINT (AREF (vector, 5)),
10215 XFASTINT (AREF (vector, 6)));
10216 set_marker_both (w->start, buffer,
10217 XFASTINT (AREF (vector, 7)),
10218 XFASTINT (AREF (vector, 8)));
10219 }
10220
10221 Vwith_echo_area_save_vector = vector;
10222 }
10223
10224
10225 /* Set up the echo area for use by print functions. MULTIBYTE_P
10226 non-zero means we will print multibyte. */
10227
10228 void
10229 setup_echo_area_for_printing (int multibyte_p)
10230 {
10231 /* If we can't find an echo area any more, exit. */
10232 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10233 Fkill_emacs (Qnil);
10234
10235 ensure_echo_area_buffers ();
10236
10237 if (!message_buf_print)
10238 {
10239 /* A message has been output since the last time we printed.
10240 Choose a fresh echo area buffer. */
10241 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10242 echo_area_buffer[0] = echo_buffer[1];
10243 else
10244 echo_area_buffer[0] = echo_buffer[0];
10245
10246 /* Switch to that buffer and clear it. */
10247 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10248 bset_truncate_lines (current_buffer, Qnil);
10249
10250 if (Z > BEG)
10251 {
10252 ptrdiff_t count = SPECPDL_INDEX ();
10253 specbind (Qinhibit_read_only, Qt);
10254 /* Note that undo recording is always disabled. */
10255 del_range (BEG, Z);
10256 unbind_to (count, Qnil);
10257 }
10258 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10259
10260 /* Set up the buffer for the multibyteness we need. */
10261 if (multibyte_p
10262 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10263 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10264
10265 /* Raise the frame containing the echo area. */
10266 if (minibuffer_auto_raise)
10267 {
10268 struct frame *sf = SELECTED_FRAME ();
10269 Lisp_Object mini_window;
10270 mini_window = FRAME_MINIBUF_WINDOW (sf);
10271 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10272 }
10273
10274 message_log_maybe_newline ();
10275 message_buf_print = 1;
10276 }
10277 else
10278 {
10279 if (NILP (echo_area_buffer[0]))
10280 {
10281 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10282 echo_area_buffer[0] = echo_buffer[1];
10283 else
10284 echo_area_buffer[0] = echo_buffer[0];
10285 }
10286
10287 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10288 {
10289 /* Someone switched buffers between print requests. */
10290 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10291 bset_truncate_lines (current_buffer, Qnil);
10292 }
10293 }
10294 }
10295
10296
10297 /* Display an echo area message in window W. Value is non-zero if W's
10298 height is changed. If display_last_displayed_message_p is
10299 non-zero, display the message that was last displayed, otherwise
10300 display the current message. */
10301
10302 static int
10303 display_echo_area (struct window *w)
10304 {
10305 int i, no_message_p, window_height_changed_p;
10306
10307 /* Temporarily disable garbage collections while displaying the echo
10308 area. This is done because a GC can print a message itself.
10309 That message would modify the echo area buffer's contents while a
10310 redisplay of the buffer is going on, and seriously confuse
10311 redisplay. */
10312 ptrdiff_t count = inhibit_garbage_collection ();
10313
10314 /* If there is no message, we must call display_echo_area_1
10315 nevertheless because it resizes the window. But we will have to
10316 reset the echo_area_buffer in question to nil at the end because
10317 with_echo_area_buffer will sets it to an empty buffer. */
10318 i = display_last_displayed_message_p ? 1 : 0;
10319 no_message_p = NILP (echo_area_buffer[i]);
10320
10321 window_height_changed_p
10322 = with_echo_area_buffer (w, display_last_displayed_message_p,
10323 display_echo_area_1,
10324 (intptr_t) w, Qnil);
10325
10326 if (no_message_p)
10327 echo_area_buffer[i] = Qnil;
10328
10329 unbind_to (count, Qnil);
10330 return window_height_changed_p;
10331 }
10332
10333
10334 /* Helper for display_echo_area. Display the current buffer which
10335 contains the current echo area message in window W, a mini-window,
10336 a pointer to which is passed in A1. A2..A4 are currently not used.
10337 Change the height of W so that all of the message is displayed.
10338 Value is non-zero if height of W was changed. */
10339
10340 static int
10341 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10342 {
10343 intptr_t i1 = a1;
10344 struct window *w = (struct window *) i1;
10345 Lisp_Object window;
10346 struct text_pos start;
10347 int window_height_changed_p = 0;
10348
10349 /* Do this before displaying, so that we have a large enough glyph
10350 matrix for the display. If we can't get enough space for the
10351 whole text, display the last N lines. That works by setting w->start. */
10352 window_height_changed_p = resize_mini_window (w, 0);
10353
10354 /* Use the starting position chosen by resize_mini_window. */
10355 SET_TEXT_POS_FROM_MARKER (start, w->start);
10356
10357 /* Display. */
10358 clear_glyph_matrix (w->desired_matrix);
10359 XSETWINDOW (window, w);
10360 try_window (window, start, 0);
10361
10362 return window_height_changed_p;
10363 }
10364
10365
10366 /* Resize the echo area window to exactly the size needed for the
10367 currently displayed message, if there is one. If a mini-buffer
10368 is active, don't shrink it. */
10369
10370 void
10371 resize_echo_area_exactly (void)
10372 {
10373 if (BUFFERP (echo_area_buffer[0])
10374 && WINDOWP (echo_area_window))
10375 {
10376 struct window *w = XWINDOW (echo_area_window);
10377 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
10378 int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10379 (intptr_t) w, resize_exactly);
10380 if (resized_p)
10381 {
10382 windows_or_buffers_changed = 42;
10383 update_mode_lines = 30;
10384 redisplay_internal ();
10385 }
10386 }
10387 }
10388
10389
10390 /* Callback function for with_echo_area_buffer, when used from
10391 resize_echo_area_exactly. A1 contains a pointer to the window to
10392 resize, EXACTLY non-nil means resize the mini-window exactly to the
10393 size of the text displayed. A3 and A4 are not used. Value is what
10394 resize_mini_window returns. */
10395
10396 static int
10397 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10398 {
10399 intptr_t i1 = a1;
10400 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10401 }
10402
10403
10404 /* Resize mini-window W to fit the size of its contents. EXACT_P
10405 means size the window exactly to the size needed. Otherwise, it's
10406 only enlarged until W's buffer is empty.
10407
10408 Set W->start to the right place to begin display. If the whole
10409 contents fit, start at the beginning. Otherwise, start so as
10410 to make the end of the contents appear. This is particularly
10411 important for y-or-n-p, but seems desirable generally.
10412
10413 Value is non-zero if the window height has been changed. */
10414
10415 int
10416 resize_mini_window (struct window *w, int exact_p)
10417 {
10418 struct frame *f = XFRAME (w->frame);
10419 int window_height_changed_p = 0;
10420
10421 eassert (MINI_WINDOW_P (w));
10422
10423 /* By default, start display at the beginning. */
10424 set_marker_both (w->start, w->contents,
10425 BUF_BEGV (XBUFFER (w->contents)),
10426 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10427
10428 /* Don't resize windows while redisplaying a window; it would
10429 confuse redisplay functions when the size of the window they are
10430 displaying changes from under them. Such a resizing can happen,
10431 for instance, when which-func prints a long message while
10432 we are running fontification-functions. We're running these
10433 functions with safe_call which binds inhibit-redisplay to t. */
10434 if (!NILP (Vinhibit_redisplay))
10435 return 0;
10436
10437 /* Nil means don't try to resize. */
10438 if (NILP (Vresize_mini_windows)
10439 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10440 return 0;
10441
10442 if (!FRAME_MINIBUF_ONLY_P (f))
10443 {
10444 struct it it;
10445 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10446 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10447 int height;
10448 EMACS_INT max_height;
10449 int unit = FRAME_LINE_HEIGHT (f);
10450 struct text_pos start;
10451 struct buffer *old_current_buffer = NULL;
10452
10453 if (current_buffer != XBUFFER (w->contents))
10454 {
10455 old_current_buffer = current_buffer;
10456 set_buffer_internal (XBUFFER (w->contents));
10457 }
10458
10459 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10460
10461 /* Compute the max. number of lines specified by the user. */
10462 if (FLOATP (Vmax_mini_window_height))
10463 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10464 else if (INTEGERP (Vmax_mini_window_height))
10465 max_height = XINT (Vmax_mini_window_height);
10466 else
10467 max_height = total_height / 4;
10468
10469 /* Correct that max. height if it's bogus. */
10470 max_height = clip_to_bounds (1, max_height, total_height);
10471
10472 /* Find out the height of the text in the window. */
10473 if (it.line_wrap == TRUNCATE)
10474 height = 1;
10475 else
10476 {
10477 last_height = 0;
10478 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10479 if (it.max_ascent == 0 && it.max_descent == 0)
10480 height = it.current_y + last_height;
10481 else
10482 height = it.current_y + it.max_ascent + it.max_descent;
10483 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10484 height = (height + unit - 1) / unit;
10485 }
10486
10487 /* Compute a suitable window start. */
10488 if (height > max_height)
10489 {
10490 height = max_height;
10491 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10492 move_it_vertically_backward (&it, (height - 1) * unit);
10493 start = it.current.pos;
10494 }
10495 else
10496 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10497 SET_MARKER_FROM_TEXT_POS (w->start, start);
10498
10499 if (EQ (Vresize_mini_windows, Qgrow_only))
10500 {
10501 /* Let it grow only, until we display an empty message, in which
10502 case the window shrinks again. */
10503 if (height > WINDOW_TOTAL_LINES (w))
10504 {
10505 int old_height = WINDOW_TOTAL_LINES (w);
10506
10507 FRAME_WINDOWS_FROZEN (f) = 1;
10508 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10509 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10510 }
10511 else if (height < WINDOW_TOTAL_LINES (w)
10512 && (exact_p || BEGV == ZV))
10513 {
10514 int old_height = WINDOW_TOTAL_LINES (w);
10515
10516 FRAME_WINDOWS_FROZEN (f) = 0;
10517 shrink_mini_window (w);
10518 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10519 }
10520 }
10521 else
10522 {
10523 /* Always resize to exact size needed. */
10524 if (height > WINDOW_TOTAL_LINES (w))
10525 {
10526 int old_height = WINDOW_TOTAL_LINES (w);
10527
10528 FRAME_WINDOWS_FROZEN (f) = 1;
10529 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10530 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10531 }
10532 else if (height < WINDOW_TOTAL_LINES (w))
10533 {
10534 int old_height = WINDOW_TOTAL_LINES (w);
10535
10536 FRAME_WINDOWS_FROZEN (f) = 0;
10537 shrink_mini_window (w);
10538
10539 if (height)
10540 {
10541 FRAME_WINDOWS_FROZEN (f) = 1;
10542 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10543 }
10544
10545 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10546 }
10547 }
10548
10549 if (old_current_buffer)
10550 set_buffer_internal (old_current_buffer);
10551 }
10552
10553 return window_height_changed_p;
10554 }
10555
10556
10557 /* Value is the current message, a string, or nil if there is no
10558 current message. */
10559
10560 Lisp_Object
10561 current_message (void)
10562 {
10563 Lisp_Object msg;
10564
10565 if (!BUFFERP (echo_area_buffer[0]))
10566 msg = Qnil;
10567 else
10568 {
10569 with_echo_area_buffer (0, 0, current_message_1,
10570 (intptr_t) &msg, Qnil);
10571 if (NILP (msg))
10572 echo_area_buffer[0] = Qnil;
10573 }
10574
10575 return msg;
10576 }
10577
10578
10579 static int
10580 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10581 {
10582 intptr_t i1 = a1;
10583 Lisp_Object *msg = (Lisp_Object *) i1;
10584
10585 if (Z > BEG)
10586 *msg = make_buffer_string (BEG, Z, 1);
10587 else
10588 *msg = Qnil;
10589 return 0;
10590 }
10591
10592
10593 /* Push the current message on Vmessage_stack for later restoration
10594 by restore_message. Value is non-zero if the current message isn't
10595 empty. This is a relatively infrequent operation, so it's not
10596 worth optimizing. */
10597
10598 bool
10599 push_message (void)
10600 {
10601 Lisp_Object msg = current_message ();
10602 Vmessage_stack = Fcons (msg, Vmessage_stack);
10603 return STRINGP (msg);
10604 }
10605
10606
10607 /* Restore message display from the top of Vmessage_stack. */
10608
10609 void
10610 restore_message (void)
10611 {
10612 eassert (CONSP (Vmessage_stack));
10613 message3_nolog (XCAR (Vmessage_stack));
10614 }
10615
10616
10617 /* Handler for unwind-protect calling pop_message. */
10618
10619 void
10620 pop_message_unwind (void)
10621 {
10622 /* Pop the top-most entry off Vmessage_stack. */
10623 eassert (CONSP (Vmessage_stack));
10624 Vmessage_stack = XCDR (Vmessage_stack);
10625 }
10626
10627
10628 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10629 exits. If the stack is not empty, we have a missing pop_message
10630 somewhere. */
10631
10632 void
10633 check_message_stack (void)
10634 {
10635 if (!NILP (Vmessage_stack))
10636 emacs_abort ();
10637 }
10638
10639
10640 /* Truncate to NCHARS what will be displayed in the echo area the next
10641 time we display it---but don't redisplay it now. */
10642
10643 void
10644 truncate_echo_area (ptrdiff_t nchars)
10645 {
10646 if (nchars == 0)
10647 echo_area_buffer[0] = Qnil;
10648 else if (!noninteractive
10649 && INTERACTIVE
10650 && !NILP (echo_area_buffer[0]))
10651 {
10652 struct frame *sf = SELECTED_FRAME ();
10653 /* Error messages get reported properly by cmd_error, so this must be
10654 just an informative message; if the frame hasn't really been
10655 initialized yet, just toss it. */
10656 if (sf->glyphs_initialized_p)
10657 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10658 }
10659 }
10660
10661
10662 /* Helper function for truncate_echo_area. Truncate the current
10663 message to at most NCHARS characters. */
10664
10665 static int
10666 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10667 {
10668 if (BEG + nchars < Z)
10669 del_range (BEG + nchars, Z);
10670 if (Z == BEG)
10671 echo_area_buffer[0] = Qnil;
10672 return 0;
10673 }
10674
10675 /* Set the current message to STRING. */
10676
10677 static void
10678 set_message (Lisp_Object string)
10679 {
10680 eassert (STRINGP (string));
10681
10682 message_enable_multibyte = STRING_MULTIBYTE (string);
10683
10684 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10685 message_buf_print = 0;
10686 help_echo_showing_p = 0;
10687
10688 if (STRINGP (Vdebug_on_message)
10689 && STRINGP (string)
10690 && fast_string_match (Vdebug_on_message, string) >= 0)
10691 call_debugger (list2 (Qerror, string));
10692 }
10693
10694
10695 /* Helper function for set_message. First argument is ignored and second
10696 argument has the same meaning as for set_message.
10697 This function is called with the echo area buffer being current. */
10698
10699 static int
10700 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10701 {
10702 eassert (STRINGP (string));
10703
10704 /* Change multibyteness of the echo buffer appropriately. */
10705 if (message_enable_multibyte
10706 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10707 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10708
10709 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10710 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10711 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10712
10713 /* Insert new message at BEG. */
10714 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10715
10716 /* This function takes care of single/multibyte conversion.
10717 We just have to ensure that the echo area buffer has the right
10718 setting of enable_multibyte_characters. */
10719 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10720
10721 return 0;
10722 }
10723
10724
10725 /* Clear messages. CURRENT_P non-zero means clear the current
10726 message. LAST_DISPLAYED_P non-zero means clear the message
10727 last displayed. */
10728
10729 void
10730 clear_message (int current_p, int last_displayed_p)
10731 {
10732 if (current_p)
10733 {
10734 echo_area_buffer[0] = Qnil;
10735 message_cleared_p = 1;
10736 }
10737
10738 if (last_displayed_p)
10739 echo_area_buffer[1] = Qnil;
10740
10741 message_buf_print = 0;
10742 }
10743
10744 /* Clear garbaged frames.
10745
10746 This function is used where the old redisplay called
10747 redraw_garbaged_frames which in turn called redraw_frame which in
10748 turn called clear_frame. The call to clear_frame was a source of
10749 flickering. I believe a clear_frame is not necessary. It should
10750 suffice in the new redisplay to invalidate all current matrices,
10751 and ensure a complete redisplay of all windows. */
10752
10753 static void
10754 clear_garbaged_frames (void)
10755 {
10756 if (frame_garbaged)
10757 {
10758 Lisp_Object tail, frame;
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 fset_redisplay (f);
10771 f->garbaged = false;
10772 f->resized_p = false;
10773 }
10774 }
10775
10776 frame_garbaged = false;
10777 }
10778 }
10779
10780
10781 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10782 is non-zero update selected_frame. Value is non-zero if the
10783 mini-windows height has been changed. */
10784
10785 static int
10786 echo_area_display (int update_frame_p)
10787 {
10788 Lisp_Object mini_window;
10789 struct window *w;
10790 struct frame *f;
10791 int window_height_changed_p = 0;
10792 struct frame *sf = SELECTED_FRAME ();
10793
10794 mini_window = FRAME_MINIBUF_WINDOW (sf);
10795 w = XWINDOW (mini_window);
10796 f = XFRAME (WINDOW_FRAME (w));
10797
10798 /* Don't display if frame is invisible or not yet initialized. */
10799 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10800 return 0;
10801
10802 #ifdef HAVE_WINDOW_SYSTEM
10803 /* When Emacs starts, selected_frame may be the initial terminal
10804 frame. If we let this through, a message would be displayed on
10805 the terminal. */
10806 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10807 return 0;
10808 #endif /* HAVE_WINDOW_SYSTEM */
10809
10810 /* Redraw garbaged frames. */
10811 clear_garbaged_frames ();
10812
10813 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10814 {
10815 echo_area_window = mini_window;
10816 window_height_changed_p = display_echo_area (w);
10817 w->must_be_updated_p = 1;
10818
10819 /* Update the display, unless called from redisplay_internal.
10820 Also don't update the screen during redisplay itself. The
10821 update will happen at the end of redisplay, and an update
10822 here could cause confusion. */
10823 if (update_frame_p && !redisplaying_p)
10824 {
10825 int n = 0;
10826
10827 /* If the display update has been interrupted by pending
10828 input, update mode lines in the frame. Due to the
10829 pending input, it might have been that redisplay hasn't
10830 been called, so that mode lines above the echo area are
10831 garbaged. This looks odd, so we prevent it here. */
10832 if (!display_completed)
10833 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10834
10835 if (window_height_changed_p
10836 /* Don't do this if Emacs is shutting down. Redisplay
10837 needs to run hooks. */
10838 && !NILP (Vrun_hooks))
10839 {
10840 /* Must update other windows. Likewise as in other
10841 cases, don't let this update be interrupted by
10842 pending input. */
10843 ptrdiff_t count = SPECPDL_INDEX ();
10844 specbind (Qredisplay_dont_pause, Qt);
10845 windows_or_buffers_changed = 44;
10846 redisplay_internal ();
10847 unbind_to (count, Qnil);
10848 }
10849 else if (FRAME_WINDOW_P (f) && n == 0)
10850 {
10851 /* Window configuration is the same as before.
10852 Can do with a display update of the echo area,
10853 unless we displayed some mode lines. */
10854 update_single_window (w, 1);
10855 flush_frame (f);
10856 }
10857 else
10858 update_frame (f, 1, 1);
10859
10860 /* If cursor is in the echo area, make sure that the next
10861 redisplay displays the minibuffer, so that the cursor will
10862 be replaced with what the minibuffer wants. */
10863 if (cursor_in_echo_area)
10864 wset_redisplay (XWINDOW (mini_window));
10865 }
10866 }
10867 else if (!EQ (mini_window, selected_window))
10868 wset_redisplay (XWINDOW (mini_window));
10869
10870 /* Last displayed message is now the current message. */
10871 echo_area_buffer[1] = echo_area_buffer[0];
10872 /* Inform read_char that we're not echoing. */
10873 echo_message_buffer = Qnil;
10874
10875 /* Prevent redisplay optimization in redisplay_internal by resetting
10876 this_line_start_pos. This is done because the mini-buffer now
10877 displays the message instead of its buffer text. */
10878 if (EQ (mini_window, selected_window))
10879 CHARPOS (this_line_start_pos) = 0;
10880
10881 return window_height_changed_p;
10882 }
10883
10884 /* Nonzero if W's buffer was changed but not saved. */
10885
10886 static int
10887 window_buffer_changed (struct window *w)
10888 {
10889 struct buffer *b = XBUFFER (w->contents);
10890
10891 eassert (BUFFER_LIVE_P (b));
10892
10893 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
10894 }
10895
10896 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10897
10898 static int
10899 mode_line_update_needed (struct window *w)
10900 {
10901 return (w->column_number_displayed != -1
10902 && !(PT == w->last_point && !window_outdated (w))
10903 && (w->column_number_displayed != current_column ()));
10904 }
10905
10906 /* Nonzero if window start of W is frozen and may not be changed during
10907 redisplay. */
10908
10909 static bool
10910 window_frozen_p (struct window *w)
10911 {
10912 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
10913 {
10914 Lisp_Object window;
10915
10916 XSETWINDOW (window, w);
10917 if (MINI_WINDOW_P (w))
10918 return 0;
10919 else if (EQ (window, selected_window))
10920 return 0;
10921 else if (MINI_WINDOW_P (XWINDOW (selected_window))
10922 && EQ (window, Vminibuf_scroll_window))
10923 /* This special window can't be frozen too. */
10924 return 0;
10925 else
10926 return 1;
10927 }
10928 return 0;
10929 }
10930
10931 /***********************************************************************
10932 Mode Lines and Frame Titles
10933 ***********************************************************************/
10934
10935 /* A buffer for constructing non-propertized mode-line strings and
10936 frame titles in it; allocated from the heap in init_xdisp and
10937 resized as needed in store_mode_line_noprop_char. */
10938
10939 static char *mode_line_noprop_buf;
10940
10941 /* The buffer's end, and a current output position in it. */
10942
10943 static char *mode_line_noprop_buf_end;
10944 static char *mode_line_noprop_ptr;
10945
10946 #define MODE_LINE_NOPROP_LEN(start) \
10947 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10948
10949 static enum {
10950 MODE_LINE_DISPLAY = 0,
10951 MODE_LINE_TITLE,
10952 MODE_LINE_NOPROP,
10953 MODE_LINE_STRING
10954 } mode_line_target;
10955
10956 /* Alist that caches the results of :propertize.
10957 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10958 static Lisp_Object mode_line_proptrans_alist;
10959
10960 /* List of strings making up the mode-line. */
10961 static Lisp_Object mode_line_string_list;
10962
10963 /* Base face property when building propertized mode line string. */
10964 static Lisp_Object mode_line_string_face;
10965 static Lisp_Object mode_line_string_face_prop;
10966
10967
10968 /* Unwind data for mode line strings */
10969
10970 static Lisp_Object Vmode_line_unwind_vector;
10971
10972 static Lisp_Object
10973 format_mode_line_unwind_data (struct frame *target_frame,
10974 struct buffer *obuf,
10975 Lisp_Object owin,
10976 int save_proptrans)
10977 {
10978 Lisp_Object vector, tmp;
10979
10980 /* Reduce consing by keeping one vector in
10981 Vwith_echo_area_save_vector. */
10982 vector = Vmode_line_unwind_vector;
10983 Vmode_line_unwind_vector = Qnil;
10984
10985 if (NILP (vector))
10986 vector = Fmake_vector (make_number (10), Qnil);
10987
10988 ASET (vector, 0, make_number (mode_line_target));
10989 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10990 ASET (vector, 2, mode_line_string_list);
10991 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10992 ASET (vector, 4, mode_line_string_face);
10993 ASET (vector, 5, mode_line_string_face_prop);
10994
10995 if (obuf)
10996 XSETBUFFER (tmp, obuf);
10997 else
10998 tmp = Qnil;
10999 ASET (vector, 6, tmp);
11000 ASET (vector, 7, owin);
11001 if (target_frame)
11002 {
11003 /* Similarly to `with-selected-window', if the operation selects
11004 a window on another frame, we must restore that frame's
11005 selected window, and (for a tty) the top-frame. */
11006 ASET (vector, 8, target_frame->selected_window);
11007 if (FRAME_TERMCAP_P (target_frame))
11008 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11009 }
11010
11011 return vector;
11012 }
11013
11014 static void
11015 unwind_format_mode_line (Lisp_Object vector)
11016 {
11017 Lisp_Object old_window = AREF (vector, 7);
11018 Lisp_Object target_frame_window = AREF (vector, 8);
11019 Lisp_Object old_top_frame = AREF (vector, 9);
11020
11021 mode_line_target = XINT (AREF (vector, 0));
11022 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11023 mode_line_string_list = AREF (vector, 2);
11024 if (! EQ (AREF (vector, 3), Qt))
11025 mode_line_proptrans_alist = AREF (vector, 3);
11026 mode_line_string_face = AREF (vector, 4);
11027 mode_line_string_face_prop = AREF (vector, 5);
11028
11029 /* Select window before buffer, since it may change the buffer. */
11030 if (!NILP (old_window))
11031 {
11032 /* If the operation that we are unwinding had selected a window
11033 on a different frame, reset its frame-selected-window. For a
11034 text terminal, reset its top-frame if necessary. */
11035 if (!NILP (target_frame_window))
11036 {
11037 Lisp_Object frame
11038 = WINDOW_FRAME (XWINDOW (target_frame_window));
11039
11040 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11041 Fselect_window (target_frame_window, Qt);
11042
11043 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11044 Fselect_frame (old_top_frame, Qt);
11045 }
11046
11047 Fselect_window (old_window, Qt);
11048 }
11049
11050 if (!NILP (AREF (vector, 6)))
11051 {
11052 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11053 ASET (vector, 6, Qnil);
11054 }
11055
11056 Vmode_line_unwind_vector = vector;
11057 }
11058
11059
11060 /* Store a single character C for the frame title in mode_line_noprop_buf.
11061 Re-allocate mode_line_noprop_buf if necessary. */
11062
11063 static void
11064 store_mode_line_noprop_char (char c)
11065 {
11066 /* If output position has reached the end of the allocated buffer,
11067 increase the buffer's size. */
11068 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11069 {
11070 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11071 ptrdiff_t size = len;
11072 mode_line_noprop_buf =
11073 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11074 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11075 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11076 }
11077
11078 *mode_line_noprop_ptr++ = c;
11079 }
11080
11081
11082 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11083 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11084 characters that yield more columns than PRECISION; PRECISION <= 0
11085 means copy the whole string. Pad with spaces until FIELD_WIDTH
11086 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11087 pad. Called from display_mode_element when it is used to build a
11088 frame title. */
11089
11090 static int
11091 store_mode_line_noprop (const char *string, int field_width, int precision)
11092 {
11093 const unsigned char *str = (const unsigned char *) string;
11094 int n = 0;
11095 ptrdiff_t dummy, nbytes;
11096
11097 /* Copy at most PRECISION chars from STR. */
11098 nbytes = strlen (string);
11099 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11100 while (nbytes--)
11101 store_mode_line_noprop_char (*str++);
11102
11103 /* Fill up with spaces until FIELD_WIDTH reached. */
11104 while (field_width > 0
11105 && n < field_width)
11106 {
11107 store_mode_line_noprop_char (' ');
11108 ++n;
11109 }
11110
11111 return n;
11112 }
11113
11114 /***********************************************************************
11115 Frame Titles
11116 ***********************************************************************/
11117
11118 #ifdef HAVE_WINDOW_SYSTEM
11119
11120 /* Set the title of FRAME, if it has changed. The title format is
11121 Vicon_title_format if FRAME is iconified, otherwise it is
11122 frame_title_format. */
11123
11124 static void
11125 x_consider_frame_title (Lisp_Object frame)
11126 {
11127 struct frame *f = XFRAME (frame);
11128
11129 if (FRAME_WINDOW_P (f)
11130 || FRAME_MINIBUF_ONLY_P (f)
11131 || f->explicit_name)
11132 {
11133 /* Do we have more than one visible frame on this X display? */
11134 Lisp_Object tail, other_frame, fmt;
11135 ptrdiff_t title_start;
11136 char *title;
11137 ptrdiff_t len;
11138 struct it it;
11139 ptrdiff_t count = SPECPDL_INDEX ();
11140
11141 FOR_EACH_FRAME (tail, other_frame)
11142 {
11143 struct frame *tf = XFRAME (other_frame);
11144
11145 if (tf != f
11146 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11147 && !FRAME_MINIBUF_ONLY_P (tf)
11148 && !EQ (other_frame, tip_frame)
11149 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11150 break;
11151 }
11152
11153 /* Set global variable indicating that multiple frames exist. */
11154 multiple_frames = CONSP (tail);
11155
11156 /* Switch to the buffer of selected window of the frame. Set up
11157 mode_line_target so that display_mode_element will output into
11158 mode_line_noprop_buf; then display the title. */
11159 record_unwind_protect (unwind_format_mode_line,
11160 format_mode_line_unwind_data
11161 (f, current_buffer, selected_window, 0));
11162
11163 Fselect_window (f->selected_window, Qt);
11164 set_buffer_internal_1
11165 (XBUFFER (XWINDOW (f->selected_window)->contents));
11166 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11167
11168 mode_line_target = MODE_LINE_TITLE;
11169 title_start = MODE_LINE_NOPROP_LEN (0);
11170 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11171 NULL, DEFAULT_FACE_ID);
11172 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11173 len = MODE_LINE_NOPROP_LEN (title_start);
11174 title = mode_line_noprop_buf + title_start;
11175 unbind_to (count, Qnil);
11176
11177 /* Set the title only if it's changed. This avoids consing in
11178 the common case where it hasn't. (If it turns out that we've
11179 already wasted too much time by walking through the list with
11180 display_mode_element, then we might need to optimize at a
11181 higher level than this.) */
11182 if (! STRINGP (f->name)
11183 || SBYTES (f->name) != len
11184 || memcmp (title, SDATA (f->name), len) != 0)
11185 x_implicitly_set_name (f, make_string (title, len), Qnil);
11186 }
11187 }
11188
11189 #endif /* not HAVE_WINDOW_SYSTEM */
11190
11191 \f
11192 /***********************************************************************
11193 Menu Bars
11194 ***********************************************************************/
11195
11196
11197 /* Prepare for redisplay by updating menu-bar item lists when
11198 appropriate. This can call eval. */
11199
11200 static void
11201 prepare_menu_bars (void)
11202 {
11203 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11204 bool some_windows
11205 = (windows_or_buffers_changed == 0
11206 || windows_or_buffers_changed == REDISPLAY_SOME)
11207 && (update_mode_lines == 0
11208 || update_mode_lines == REDISPLAY_SOME);
11209 struct gcpro gcpro1, gcpro2;
11210 Lisp_Object tooltip_frame;
11211
11212 #ifdef HAVE_WINDOW_SYSTEM
11213 tooltip_frame = tip_frame;
11214 #else
11215 tooltip_frame = Qnil;
11216 #endif
11217
11218 if (FUNCTIONP (Vpre_redisplay_function))
11219 {
11220 Lisp_Object windows = all_windows ? Qt : Qnil;
11221 if (all_windows && some_windows)
11222 {
11223 Lisp_Object ws = window_list ();
11224 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
11225 {
11226 Lisp_Object this = XCAR (ws);
11227 struct window *w = XWINDOW (this);
11228 if (w->redisplay
11229 || XFRAME (w->frame)->redisplay
11230 || XBUFFER (w->contents)->text->redisplay)
11231 {
11232 windows = Fcons (this, windows);
11233 }
11234 }
11235 }
11236 safe_call1 (Vpre_redisplay_function, windows);
11237 }
11238
11239 /* Update all frame titles based on their buffer names, etc. We do
11240 this before the menu bars so that the buffer-menu will show the
11241 up-to-date frame titles. */
11242 #ifdef HAVE_WINDOW_SYSTEM
11243 if (all_windows)
11244 {
11245 Lisp_Object tail, frame;
11246
11247 FOR_EACH_FRAME (tail, frame)
11248 {
11249 struct frame *f = XFRAME (frame);
11250 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11251 if (some_windows
11252 && !f->redisplay
11253 && !w->redisplay
11254 && !XBUFFER (w->contents)->text->redisplay)
11255 continue;
11256
11257 if (!EQ (frame, tooltip_frame)
11258 && (FRAME_ICONIFIED_P (f)
11259 || FRAME_VISIBLE_P (f) == 1
11260 /* Exclude TTY frames that are obscured because they
11261 are not the top frame on their console. This is
11262 because x_consider_frame_title actually switches
11263 to the frame, which for TTY frames means it is
11264 marked as garbaged, and will be completely
11265 redrawn on the next redisplay cycle. This causes
11266 TTY frames to be completely redrawn, when there
11267 are more than one of them, even though nothing
11268 should be changed on display. */
11269 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11270 x_consider_frame_title (frame);
11271 }
11272 }
11273 #endif /* HAVE_WINDOW_SYSTEM */
11274
11275 /* Update the menu bar item lists, if appropriate. This has to be
11276 done before any actual redisplay or generation of display lines. */
11277
11278 if (all_windows)
11279 {
11280 Lisp_Object tail, frame;
11281 ptrdiff_t count = SPECPDL_INDEX ();
11282 /* 1 means that update_menu_bar has run its hooks
11283 so any further calls to update_menu_bar shouldn't do so again. */
11284 int menu_bar_hooks_run = 0;
11285
11286 record_unwind_save_match_data ();
11287
11288 FOR_EACH_FRAME (tail, frame)
11289 {
11290 struct frame *f = XFRAME (frame);
11291 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11292
11293 /* Ignore tooltip frame. */
11294 if (EQ (frame, tooltip_frame))
11295 continue;
11296
11297 if (some_windows
11298 && !f->redisplay
11299 && !w->redisplay
11300 && !XBUFFER (w->contents)->text->redisplay)
11301 continue;
11302
11303 /* If a window on this frame changed size, report that to
11304 the user and clear the size-change flag. */
11305 if (FRAME_WINDOW_SIZES_CHANGED (f))
11306 {
11307 Lisp_Object functions;
11308
11309 /* Clear flag first in case we get an error below. */
11310 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11311 functions = Vwindow_size_change_functions;
11312 GCPRO2 (tail, functions);
11313
11314 while (CONSP (functions))
11315 {
11316 if (!EQ (XCAR (functions), Qt))
11317 call1 (XCAR (functions), frame);
11318 functions = XCDR (functions);
11319 }
11320 UNGCPRO;
11321 }
11322
11323 GCPRO1 (tail);
11324 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11325 #ifdef HAVE_WINDOW_SYSTEM
11326 update_tool_bar (f, 0);
11327 #endif
11328 #ifdef HAVE_NS
11329 if (windows_or_buffers_changed
11330 && FRAME_NS_P (f))
11331 ns_set_doc_edited
11332 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11333 #endif
11334 UNGCPRO;
11335 }
11336
11337 unbind_to (count, Qnil);
11338 }
11339 else
11340 {
11341 struct frame *sf = SELECTED_FRAME ();
11342 update_menu_bar (sf, 1, 0);
11343 #ifdef HAVE_WINDOW_SYSTEM
11344 update_tool_bar (sf, 1);
11345 #endif
11346 }
11347 }
11348
11349
11350 /* Update the menu bar item list for frame F. This has to be done
11351 before we start to fill in any display lines, because it can call
11352 eval.
11353
11354 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11355
11356 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11357 already ran the menu bar hooks for this redisplay, so there
11358 is no need to run them again. The return value is the
11359 updated value of this flag, to pass to the next call. */
11360
11361 static int
11362 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11363 {
11364 Lisp_Object window;
11365 register struct window *w;
11366
11367 /* If called recursively during a menu update, do nothing. This can
11368 happen when, for instance, an activate-menubar-hook causes a
11369 redisplay. */
11370 if (inhibit_menubar_update)
11371 return hooks_run;
11372
11373 window = FRAME_SELECTED_WINDOW (f);
11374 w = XWINDOW (window);
11375
11376 if (FRAME_WINDOW_P (f)
11377 ?
11378 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11379 || defined (HAVE_NS) || defined (USE_GTK)
11380 FRAME_EXTERNAL_MENU_BAR (f)
11381 #else
11382 FRAME_MENU_BAR_LINES (f) > 0
11383 #endif
11384 : FRAME_MENU_BAR_LINES (f) > 0)
11385 {
11386 /* If the user has switched buffers or windows, we need to
11387 recompute to reflect the new bindings. But we'll
11388 recompute when update_mode_lines is set too; that means
11389 that people can use force-mode-line-update to request
11390 that the menu bar be recomputed. The adverse effect on
11391 the rest of the redisplay algorithm is about the same as
11392 windows_or_buffers_changed anyway. */
11393 if (windows_or_buffers_changed
11394 /* This used to test w->update_mode_line, but we believe
11395 there is no need to recompute the menu in that case. */
11396 || update_mode_lines
11397 || window_buffer_changed (w))
11398 {
11399 struct buffer *prev = current_buffer;
11400 ptrdiff_t count = SPECPDL_INDEX ();
11401
11402 specbind (Qinhibit_menubar_update, Qt);
11403
11404 set_buffer_internal_1 (XBUFFER (w->contents));
11405 if (save_match_data)
11406 record_unwind_save_match_data ();
11407 if (NILP (Voverriding_local_map_menu_flag))
11408 {
11409 specbind (Qoverriding_terminal_local_map, Qnil);
11410 specbind (Qoverriding_local_map, Qnil);
11411 }
11412
11413 if (!hooks_run)
11414 {
11415 /* Run the Lucid hook. */
11416 safe_run_hooks (Qactivate_menubar_hook);
11417
11418 /* If it has changed current-menubar from previous value,
11419 really recompute the menu-bar from the value. */
11420 if (! NILP (Vlucid_menu_bar_dirty_flag))
11421 call0 (Qrecompute_lucid_menubar);
11422
11423 safe_run_hooks (Qmenu_bar_update_hook);
11424
11425 hooks_run = 1;
11426 }
11427
11428 XSETFRAME (Vmenu_updating_frame, f);
11429 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11430
11431 /* Redisplay the menu bar in case we changed it. */
11432 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11433 || defined (HAVE_NS) || defined (USE_GTK)
11434 if (FRAME_WINDOW_P (f))
11435 {
11436 #if defined (HAVE_NS)
11437 /* All frames on Mac OS share the same menubar. So only
11438 the selected frame should be allowed to set it. */
11439 if (f == SELECTED_FRAME ())
11440 #endif
11441 set_frame_menubar (f, 0, 0);
11442 }
11443 else
11444 /* On a terminal screen, the menu bar is an ordinary screen
11445 line, and this makes it get updated. */
11446 w->update_mode_line = 1;
11447 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11448 /* In the non-toolkit version, the menu bar is an ordinary screen
11449 line, and this makes it get updated. */
11450 w->update_mode_line = 1;
11451 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11452
11453 unbind_to (count, Qnil);
11454 set_buffer_internal_1 (prev);
11455 }
11456 }
11457
11458 return hooks_run;
11459 }
11460
11461 /***********************************************************************
11462 Tool-bars
11463 ***********************************************************************/
11464
11465 #ifdef HAVE_WINDOW_SYSTEM
11466
11467 /* Tool-bar item index of the item on which a mouse button was pressed
11468 or -1. */
11469
11470 int last_tool_bar_item;
11471
11472 /* Select `frame' temporarily without running all the code in
11473 do_switch_frame.
11474 FIXME: Maybe do_switch_frame should be trimmed down similarly
11475 when `norecord' is set. */
11476 static void
11477 fast_set_selected_frame (Lisp_Object frame)
11478 {
11479 if (!EQ (selected_frame, frame))
11480 {
11481 selected_frame = frame;
11482 selected_window = XFRAME (frame)->selected_window;
11483 }
11484 }
11485
11486 /* Update the tool-bar item list for frame F. This has to be done
11487 before we start to fill in any display lines. Called from
11488 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11489 and restore it here. */
11490
11491 static void
11492 update_tool_bar (struct frame *f, int save_match_data)
11493 {
11494 #if defined (USE_GTK) || defined (HAVE_NS)
11495 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11496 #else
11497 int do_update = WINDOWP (f->tool_bar_window)
11498 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11499 #endif
11500
11501 if (do_update)
11502 {
11503 Lisp_Object window;
11504 struct window *w;
11505
11506 window = FRAME_SELECTED_WINDOW (f);
11507 w = XWINDOW (window);
11508
11509 /* If the user has switched buffers or windows, we need to
11510 recompute to reflect the new bindings. But we'll
11511 recompute when update_mode_lines is set too; that means
11512 that people can use force-mode-line-update to request
11513 that the menu bar be recomputed. The adverse effect on
11514 the rest of the redisplay algorithm is about the same as
11515 windows_or_buffers_changed anyway. */
11516 if (windows_or_buffers_changed
11517 || w->update_mode_line
11518 || update_mode_lines
11519 || window_buffer_changed (w))
11520 {
11521 struct buffer *prev = current_buffer;
11522 ptrdiff_t count = SPECPDL_INDEX ();
11523 Lisp_Object frame, new_tool_bar;
11524 int new_n_tool_bar;
11525 struct gcpro gcpro1;
11526
11527 /* Set current_buffer to the buffer of the selected
11528 window of the frame, so that we get the right local
11529 keymaps. */
11530 set_buffer_internal_1 (XBUFFER (w->contents));
11531
11532 /* Save match data, if we must. */
11533 if (save_match_data)
11534 record_unwind_save_match_data ();
11535
11536 /* Make sure that we don't accidentally use bogus keymaps. */
11537 if (NILP (Voverriding_local_map_menu_flag))
11538 {
11539 specbind (Qoverriding_terminal_local_map, Qnil);
11540 specbind (Qoverriding_local_map, Qnil);
11541 }
11542
11543 GCPRO1 (new_tool_bar);
11544
11545 /* We must temporarily set the selected frame to this frame
11546 before calling tool_bar_items, because the calculation of
11547 the tool-bar keymap uses the selected frame (see
11548 `tool-bar-make-keymap' in tool-bar.el). */
11549 eassert (EQ (selected_window,
11550 /* Since we only explicitly preserve selected_frame,
11551 check that selected_window would be redundant. */
11552 XFRAME (selected_frame)->selected_window));
11553 record_unwind_protect (fast_set_selected_frame, selected_frame);
11554 XSETFRAME (frame, f);
11555 fast_set_selected_frame (frame);
11556
11557 /* Build desired tool-bar items from keymaps. */
11558 new_tool_bar
11559 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11560 &new_n_tool_bar);
11561
11562 /* Redisplay the tool-bar if we changed it. */
11563 if (new_n_tool_bar != f->n_tool_bar_items
11564 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11565 {
11566 /* Redisplay that happens asynchronously due to an expose event
11567 may access f->tool_bar_items. Make sure we update both
11568 variables within BLOCK_INPUT so no such event interrupts. */
11569 block_input ();
11570 fset_tool_bar_items (f, new_tool_bar);
11571 f->n_tool_bar_items = new_n_tool_bar;
11572 w->update_mode_line = 1;
11573 unblock_input ();
11574 }
11575
11576 UNGCPRO;
11577
11578 unbind_to (count, Qnil);
11579 set_buffer_internal_1 (prev);
11580 }
11581 }
11582 }
11583
11584 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11585
11586 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11587 F's desired tool-bar contents. F->tool_bar_items must have
11588 been set up previously by calling prepare_menu_bars. */
11589
11590 static void
11591 build_desired_tool_bar_string (struct frame *f)
11592 {
11593 int i, size, size_needed;
11594 struct gcpro gcpro1, gcpro2, gcpro3;
11595 Lisp_Object image, plist, props;
11596
11597 image = plist = props = Qnil;
11598 GCPRO3 (image, plist, props);
11599
11600 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11601 Otherwise, make a new string. */
11602
11603 /* The size of the string we might be able to reuse. */
11604 size = (STRINGP (f->desired_tool_bar_string)
11605 ? SCHARS (f->desired_tool_bar_string)
11606 : 0);
11607
11608 /* We need one space in the string for each image. */
11609 size_needed = f->n_tool_bar_items;
11610
11611 /* Reuse f->desired_tool_bar_string, if possible. */
11612 if (size < size_needed || NILP (f->desired_tool_bar_string))
11613 fset_desired_tool_bar_string
11614 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11615 else
11616 {
11617 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11618 Fremove_text_properties (make_number (0), make_number (size),
11619 props, f->desired_tool_bar_string);
11620 }
11621
11622 /* Put a `display' property on the string for the images to display,
11623 put a `menu_item' property on tool-bar items with a value that
11624 is the index of the item in F's tool-bar item vector. */
11625 for (i = 0; i < f->n_tool_bar_items; ++i)
11626 {
11627 #define PROP(IDX) \
11628 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11629
11630 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11631 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11632 int hmargin, vmargin, relief, idx, end;
11633
11634 /* If image is a vector, choose the image according to the
11635 button state. */
11636 image = PROP (TOOL_BAR_ITEM_IMAGES);
11637 if (VECTORP (image))
11638 {
11639 if (enabled_p)
11640 idx = (selected_p
11641 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11642 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11643 else
11644 idx = (selected_p
11645 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11646 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11647
11648 eassert (ASIZE (image) >= idx);
11649 image = AREF (image, idx);
11650 }
11651 else
11652 idx = -1;
11653
11654 /* Ignore invalid image specifications. */
11655 if (!valid_image_p (image))
11656 continue;
11657
11658 /* Display the tool-bar button pressed, or depressed. */
11659 plist = Fcopy_sequence (XCDR (image));
11660
11661 /* Compute margin and relief to draw. */
11662 relief = (tool_bar_button_relief >= 0
11663 ? tool_bar_button_relief
11664 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11665 hmargin = vmargin = relief;
11666
11667 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11668 INT_MAX - max (hmargin, vmargin)))
11669 {
11670 hmargin += XFASTINT (Vtool_bar_button_margin);
11671 vmargin += XFASTINT (Vtool_bar_button_margin);
11672 }
11673 else if (CONSP (Vtool_bar_button_margin))
11674 {
11675 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11676 INT_MAX - hmargin))
11677 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11678
11679 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11680 INT_MAX - vmargin))
11681 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11682 }
11683
11684 if (auto_raise_tool_bar_buttons_p)
11685 {
11686 /* Add a `:relief' property to the image spec if the item is
11687 selected. */
11688 if (selected_p)
11689 {
11690 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11691 hmargin -= relief;
11692 vmargin -= relief;
11693 }
11694 }
11695 else
11696 {
11697 /* If image is selected, display it pressed, i.e. with a
11698 negative relief. If it's not selected, display it with a
11699 raised relief. */
11700 plist = Fplist_put (plist, QCrelief,
11701 (selected_p
11702 ? make_number (-relief)
11703 : make_number (relief)));
11704 hmargin -= relief;
11705 vmargin -= relief;
11706 }
11707
11708 /* Put a margin around the image. */
11709 if (hmargin || vmargin)
11710 {
11711 if (hmargin == vmargin)
11712 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11713 else
11714 plist = Fplist_put (plist, QCmargin,
11715 Fcons (make_number (hmargin),
11716 make_number (vmargin)));
11717 }
11718
11719 /* If button is not enabled, and we don't have special images
11720 for the disabled state, make the image appear disabled by
11721 applying an appropriate algorithm to it. */
11722 if (!enabled_p && idx < 0)
11723 plist = Fplist_put (plist, QCconversion, Qdisabled);
11724
11725 /* Put a `display' text property on the string for the image to
11726 display. Put a `menu-item' property on the string that gives
11727 the start of this item's properties in the tool-bar items
11728 vector. */
11729 image = Fcons (Qimage, plist);
11730 props = list4 (Qdisplay, image,
11731 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11732
11733 /* Let the last image hide all remaining spaces in the tool bar
11734 string. The string can be longer than needed when we reuse a
11735 previous string. */
11736 if (i + 1 == f->n_tool_bar_items)
11737 end = SCHARS (f->desired_tool_bar_string);
11738 else
11739 end = i + 1;
11740 Fadd_text_properties (make_number (i), make_number (end),
11741 props, f->desired_tool_bar_string);
11742 #undef PROP
11743 }
11744
11745 UNGCPRO;
11746 }
11747
11748
11749 /* Display one line of the tool-bar of frame IT->f.
11750
11751 HEIGHT specifies the desired height of the tool-bar line.
11752 If the actual height of the glyph row is less than HEIGHT, the
11753 row's height is increased to HEIGHT, and the icons are centered
11754 vertically in the new height.
11755
11756 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11757 count a final empty row in case the tool-bar width exactly matches
11758 the window width.
11759 */
11760
11761 static void
11762 display_tool_bar_line (struct it *it, int height)
11763 {
11764 struct glyph_row *row = it->glyph_row;
11765 int max_x = it->last_visible_x;
11766 struct glyph *last;
11767
11768 prepare_desired_row (row);
11769 row->y = it->current_y;
11770
11771 /* Note that this isn't made use of if the face hasn't a box,
11772 so there's no need to check the face here. */
11773 it->start_of_box_run_p = 1;
11774
11775 while (it->current_x < max_x)
11776 {
11777 int x, n_glyphs_before, i, nglyphs;
11778 struct it it_before;
11779
11780 /* Get the next display element. */
11781 if (!get_next_display_element (it))
11782 {
11783 /* Don't count empty row if we are counting needed tool-bar lines. */
11784 if (height < 0 && !it->hpos)
11785 return;
11786 break;
11787 }
11788
11789 /* Produce glyphs. */
11790 n_glyphs_before = row->used[TEXT_AREA];
11791 it_before = *it;
11792
11793 PRODUCE_GLYPHS (it);
11794
11795 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11796 i = 0;
11797 x = it_before.current_x;
11798 while (i < nglyphs)
11799 {
11800 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11801
11802 if (x + glyph->pixel_width > max_x)
11803 {
11804 /* Glyph doesn't fit on line. Backtrack. */
11805 row->used[TEXT_AREA] = n_glyphs_before;
11806 *it = it_before;
11807 /* If this is the only glyph on this line, it will never fit on the
11808 tool-bar, so skip it. But ensure there is at least one glyph,
11809 so we don't accidentally disable the tool-bar. */
11810 if (n_glyphs_before == 0
11811 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11812 break;
11813 goto out;
11814 }
11815
11816 ++it->hpos;
11817 x += glyph->pixel_width;
11818 ++i;
11819 }
11820
11821 /* Stop at line end. */
11822 if (ITERATOR_AT_END_OF_LINE_P (it))
11823 break;
11824
11825 set_iterator_to_next (it, 1);
11826 }
11827
11828 out:;
11829
11830 row->displays_text_p = row->used[TEXT_AREA] != 0;
11831
11832 /* Use default face for the border below the tool bar.
11833
11834 FIXME: When auto-resize-tool-bars is grow-only, there is
11835 no additional border below the possibly empty tool-bar lines.
11836 So to make the extra empty lines look "normal", we have to
11837 use the tool-bar face for the border too. */
11838 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11839 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11840 it->face_id = DEFAULT_FACE_ID;
11841
11842 extend_face_to_end_of_line (it);
11843 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11844 last->right_box_line_p = 1;
11845 if (last == row->glyphs[TEXT_AREA])
11846 last->left_box_line_p = 1;
11847
11848 /* Make line the desired height and center it vertically. */
11849 if ((height -= it->max_ascent + it->max_descent) > 0)
11850 {
11851 /* Don't add more than one line height. */
11852 height %= FRAME_LINE_HEIGHT (it->f);
11853 it->max_ascent += height / 2;
11854 it->max_descent += (height + 1) / 2;
11855 }
11856
11857 compute_line_metrics (it);
11858
11859 /* If line is empty, make it occupy the rest of the tool-bar. */
11860 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11861 {
11862 row->height = row->phys_height = it->last_visible_y - row->y;
11863 row->visible_height = row->height;
11864 row->ascent = row->phys_ascent = 0;
11865 row->extra_line_spacing = 0;
11866 }
11867
11868 row->full_width_p = 1;
11869 row->continued_p = 0;
11870 row->truncated_on_left_p = 0;
11871 row->truncated_on_right_p = 0;
11872
11873 it->current_x = it->hpos = 0;
11874 it->current_y += row->height;
11875 ++it->vpos;
11876 ++it->glyph_row;
11877 }
11878
11879
11880 /* Max tool-bar height. */
11881
11882 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11883 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11884
11885 /* Value is the number of screen lines needed to make all tool-bar
11886 items of frame F visible. The number of actual rows needed is
11887 returned in *N_ROWS if non-NULL. */
11888
11889 static int
11890 tool_bar_lines_needed (struct frame *f, int *n_rows)
11891 {
11892 struct window *w = XWINDOW (f->tool_bar_window);
11893 struct it it;
11894 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11895 the desired matrix, so use (unused) mode-line row as temporary row to
11896 avoid destroying the first tool-bar row. */
11897 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11898
11899 /* Initialize an iterator for iteration over
11900 F->desired_tool_bar_string in the tool-bar window of frame F. */
11901 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11902 it.first_visible_x = 0;
11903 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11904 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11905 it.paragraph_embedding = L2R;
11906
11907 while (!ITERATOR_AT_END_P (&it))
11908 {
11909 clear_glyph_row (temp_row);
11910 it.glyph_row = temp_row;
11911 display_tool_bar_line (&it, -1);
11912 }
11913 clear_glyph_row (temp_row);
11914
11915 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11916 if (n_rows)
11917 *n_rows = it.vpos > 0 ? it.vpos : -1;
11918
11919 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11920 }
11921
11922 #endif /* !USE_GTK && !HAVE_NS */
11923
11924 #if defined USE_GTK || defined HAVE_NS
11925 EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
11926 #endif
11927
11928 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11929 0, 1, 0,
11930 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11931 If FRAME is nil or omitted, use the selected frame. */)
11932 (Lisp_Object frame)
11933 {
11934 int nlines = 0;
11935 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11936 struct frame *f = decode_any_frame (frame);
11937 struct window *w;
11938
11939 if (WINDOWP (f->tool_bar_window)
11940 && (w = XWINDOW (f->tool_bar_window),
11941 WINDOW_TOTAL_LINES (w) > 0))
11942 {
11943 update_tool_bar (f, 1);
11944 if (f->n_tool_bar_items)
11945 {
11946 build_desired_tool_bar_string (f);
11947 nlines = tool_bar_lines_needed (f, NULL);
11948 }
11949 }
11950 #endif
11951 return make_number (nlines);
11952 }
11953
11954
11955 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11956 height should be changed. */
11957
11958 static int
11959 redisplay_tool_bar (struct frame *f)
11960 {
11961 #if defined (USE_GTK) || defined (HAVE_NS)
11962
11963 if (FRAME_EXTERNAL_TOOL_BAR (f))
11964 update_frame_tool_bar (f);
11965 return 0;
11966
11967 #else /* !USE_GTK && !HAVE_NS */
11968
11969 struct window *w;
11970 struct it it;
11971 struct glyph_row *row;
11972
11973 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11974 do anything. This means you must start with tool-bar-lines
11975 non-zero to get the auto-sizing effect. Or in other words, you
11976 can turn off tool-bars by specifying tool-bar-lines zero. */
11977 if (!WINDOWP (f->tool_bar_window)
11978 || (w = XWINDOW (f->tool_bar_window),
11979 WINDOW_TOTAL_LINES (w) == 0))
11980 return 0;
11981
11982 /* Set up an iterator for the tool-bar window. */
11983 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11984 it.first_visible_x = 0;
11985 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11986 row = it.glyph_row;
11987
11988 /* Build a string that represents the contents of the tool-bar. */
11989 build_desired_tool_bar_string (f);
11990 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11991 /* FIXME: This should be controlled by a user option. But it
11992 doesn't make sense to have an R2L tool bar if the menu bar cannot
11993 be drawn also R2L, and making the menu bar R2L is tricky due
11994 toolkit-specific code that implements it. If an R2L tool bar is
11995 ever supported, display_tool_bar_line should also be augmented to
11996 call unproduce_glyphs like display_line and display_string
11997 do. */
11998 it.paragraph_embedding = L2R;
11999
12000 if (f->n_tool_bar_rows == 0)
12001 {
12002 int nlines;
12003
12004 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
12005 nlines != WINDOW_TOTAL_LINES (w)))
12006 {
12007 Lisp_Object frame;
12008 int old_height = WINDOW_TOTAL_LINES (w);
12009
12010 XSETFRAME (frame, f);
12011 Fmodify_frame_parameters (frame,
12012 list1 (Fcons (Qtool_bar_lines,
12013 make_number (nlines))));
12014 if (WINDOW_TOTAL_LINES (w) != old_height)
12015 {
12016 clear_glyph_matrix (w->desired_matrix);
12017 f->fonts_changed = 1;
12018 return 1;
12019 }
12020 }
12021 }
12022
12023 /* Display as many lines as needed to display all tool-bar items. */
12024
12025 if (f->n_tool_bar_rows > 0)
12026 {
12027 int border, rows, height, extra;
12028
12029 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12030 border = XINT (Vtool_bar_border);
12031 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12032 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12033 else if (EQ (Vtool_bar_border, Qborder_width))
12034 border = f->border_width;
12035 else
12036 border = 0;
12037 if (border < 0)
12038 border = 0;
12039
12040 rows = f->n_tool_bar_rows;
12041 height = max (1, (it.last_visible_y - border) / rows);
12042 extra = it.last_visible_y - border - height * rows;
12043
12044 while (it.current_y < it.last_visible_y)
12045 {
12046 int h = 0;
12047 if (extra > 0 && rows-- > 0)
12048 {
12049 h = (extra + rows - 1) / rows;
12050 extra -= h;
12051 }
12052 display_tool_bar_line (&it, height + h);
12053 }
12054 }
12055 else
12056 {
12057 while (it.current_y < it.last_visible_y)
12058 display_tool_bar_line (&it, 0);
12059 }
12060
12061 /* It doesn't make much sense to try scrolling in the tool-bar
12062 window, so don't do it. */
12063 w->desired_matrix->no_scrolling_p = 1;
12064 w->must_be_updated_p = 1;
12065
12066 if (!NILP (Vauto_resize_tool_bars))
12067 {
12068 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12069 int change_height_p = 0;
12070
12071 /* If we couldn't display everything, change the tool-bar's
12072 height if there is room for more. */
12073 if (IT_STRING_CHARPOS (it) < it.end_charpos
12074 && it.current_y < max_tool_bar_height)
12075 change_height_p = 1;
12076
12077 row = it.glyph_row - 1;
12078
12079 /* If there are blank lines at the end, except for a partially
12080 visible blank line at the end that is smaller than
12081 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12082 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12083 && row->height >= FRAME_LINE_HEIGHT (f))
12084 change_height_p = 1;
12085
12086 /* If row displays tool-bar items, but is partially visible,
12087 change the tool-bar's height. */
12088 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12089 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12090 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12091 change_height_p = 1;
12092
12093 /* Resize windows as needed by changing the `tool-bar-lines'
12094 frame parameter. */
12095 if (change_height_p)
12096 {
12097 Lisp_Object frame;
12098 int old_height = WINDOW_TOTAL_LINES (w);
12099 int nrows;
12100 int nlines = tool_bar_lines_needed (f, &nrows);
12101
12102 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12103 && !f->minimize_tool_bar_window_p)
12104 ? (nlines > old_height)
12105 : (nlines != old_height));
12106 f->minimize_tool_bar_window_p = 0;
12107
12108 if (change_height_p)
12109 {
12110 XSETFRAME (frame, f);
12111 Fmodify_frame_parameters (frame,
12112 list1 (Fcons (Qtool_bar_lines,
12113 make_number (nlines))));
12114 if (WINDOW_TOTAL_LINES (w) != old_height)
12115 {
12116 clear_glyph_matrix (w->desired_matrix);
12117 f->n_tool_bar_rows = nrows;
12118 f->fonts_changed = 1;
12119 return 1;
12120 }
12121 }
12122 }
12123 }
12124
12125 f->minimize_tool_bar_window_p = 0;
12126 return 0;
12127
12128 #endif /* USE_GTK || HAVE_NS */
12129 }
12130
12131 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12132
12133 /* Get information about the tool-bar item which is displayed in GLYPH
12134 on frame F. Return in *PROP_IDX the index where tool-bar item
12135 properties start in F->tool_bar_items. Value is zero if
12136 GLYPH doesn't display a tool-bar item. */
12137
12138 static int
12139 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12140 {
12141 Lisp_Object prop;
12142 int success_p;
12143 int charpos;
12144
12145 /* This function can be called asynchronously, which means we must
12146 exclude any possibility that Fget_text_property signals an
12147 error. */
12148 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12149 charpos = max (0, charpos);
12150
12151 /* Get the text property `menu-item' at pos. The value of that
12152 property is the start index of this item's properties in
12153 F->tool_bar_items. */
12154 prop = Fget_text_property (make_number (charpos),
12155 Qmenu_item, f->current_tool_bar_string);
12156 if (INTEGERP (prop))
12157 {
12158 *prop_idx = XINT (prop);
12159 success_p = 1;
12160 }
12161 else
12162 success_p = 0;
12163
12164 return success_p;
12165 }
12166
12167 \f
12168 /* Get information about the tool-bar item at position X/Y on frame F.
12169 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12170 the current matrix of the tool-bar window of F, or NULL if not
12171 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12172 item in F->tool_bar_items. Value is
12173
12174 -1 if X/Y is not on a tool-bar item
12175 0 if X/Y is on the same item that was highlighted before.
12176 1 otherwise. */
12177
12178 static int
12179 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12180 int *hpos, int *vpos, int *prop_idx)
12181 {
12182 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12183 struct window *w = XWINDOW (f->tool_bar_window);
12184 int area;
12185
12186 /* Find the glyph under X/Y. */
12187 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12188 if (*glyph == NULL)
12189 return -1;
12190
12191 /* Get the start of this tool-bar item's properties in
12192 f->tool_bar_items. */
12193 if (!tool_bar_item_info (f, *glyph, prop_idx))
12194 return -1;
12195
12196 /* Is mouse on the highlighted item? */
12197 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12198 && *vpos >= hlinfo->mouse_face_beg_row
12199 && *vpos <= hlinfo->mouse_face_end_row
12200 && (*vpos > hlinfo->mouse_face_beg_row
12201 || *hpos >= hlinfo->mouse_face_beg_col)
12202 && (*vpos < hlinfo->mouse_face_end_row
12203 || *hpos < hlinfo->mouse_face_end_col
12204 || hlinfo->mouse_face_past_end))
12205 return 0;
12206
12207 return 1;
12208 }
12209
12210
12211 /* EXPORT:
12212 Handle mouse button event on the tool-bar of frame F, at
12213 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12214 0 for button release. MODIFIERS is event modifiers for button
12215 release. */
12216
12217 void
12218 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12219 int modifiers)
12220 {
12221 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12222 struct window *w = XWINDOW (f->tool_bar_window);
12223 int hpos, vpos, prop_idx;
12224 struct glyph *glyph;
12225 Lisp_Object enabled_p;
12226 int ts;
12227
12228 /* If not on the highlighted tool-bar item, and mouse-highlight is
12229 non-nil, return. This is so we generate the tool-bar button
12230 click only when the mouse button is released on the same item as
12231 where it was pressed. However, when mouse-highlight is disabled,
12232 generate the click when the button is released regardless of the
12233 highlight, since tool-bar items are not highlighted in that
12234 case. */
12235 frame_to_window_pixel_xy (w, &x, &y);
12236 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12237 if (ts == -1
12238 || (ts != 0 && !NILP (Vmouse_highlight)))
12239 return;
12240
12241 /* When mouse-highlight is off, generate the click for the item
12242 where the button was pressed, disregarding where it was
12243 released. */
12244 if (NILP (Vmouse_highlight) && !down_p)
12245 prop_idx = last_tool_bar_item;
12246
12247 /* If item is disabled, do nothing. */
12248 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12249 if (NILP (enabled_p))
12250 return;
12251
12252 if (down_p)
12253 {
12254 /* Show item in pressed state. */
12255 if (!NILP (Vmouse_highlight))
12256 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12257 last_tool_bar_item = prop_idx;
12258 }
12259 else
12260 {
12261 Lisp_Object key, frame;
12262 struct input_event event;
12263 EVENT_INIT (event);
12264
12265 /* Show item in released state. */
12266 if (!NILP (Vmouse_highlight))
12267 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12268
12269 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12270
12271 XSETFRAME (frame, f);
12272 event.kind = TOOL_BAR_EVENT;
12273 event.frame_or_window = frame;
12274 event.arg = frame;
12275 kbd_buffer_store_event (&event);
12276
12277 event.kind = TOOL_BAR_EVENT;
12278 event.frame_or_window = frame;
12279 event.arg = key;
12280 event.modifiers = modifiers;
12281 kbd_buffer_store_event (&event);
12282 last_tool_bar_item = -1;
12283 }
12284 }
12285
12286
12287 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12288 tool-bar window-relative coordinates X/Y. Called from
12289 note_mouse_highlight. */
12290
12291 static void
12292 note_tool_bar_highlight (struct frame *f, int x, int y)
12293 {
12294 Lisp_Object window = f->tool_bar_window;
12295 struct window *w = XWINDOW (window);
12296 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
12297 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12298 int hpos, vpos;
12299 struct glyph *glyph;
12300 struct glyph_row *row;
12301 int i;
12302 Lisp_Object enabled_p;
12303 int prop_idx;
12304 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12305 int mouse_down_p, rc;
12306
12307 /* Function note_mouse_highlight is called with negative X/Y
12308 values when mouse moves outside of the frame. */
12309 if (x <= 0 || y <= 0)
12310 {
12311 clear_mouse_face (hlinfo);
12312 return;
12313 }
12314
12315 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12316 if (rc < 0)
12317 {
12318 /* Not on tool-bar item. */
12319 clear_mouse_face (hlinfo);
12320 return;
12321 }
12322 else if (rc == 0)
12323 /* On same tool-bar item as before. */
12324 goto set_help_echo;
12325
12326 clear_mouse_face (hlinfo);
12327
12328 /* Mouse is down, but on different tool-bar item? */
12329 mouse_down_p = (x_mouse_grabbed (dpyinfo)
12330 && f == dpyinfo->last_mouse_frame);
12331
12332 if (mouse_down_p
12333 && last_tool_bar_item != prop_idx)
12334 return;
12335
12336 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12337
12338 /* If tool-bar item is not enabled, don't highlight it. */
12339 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12340 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12341 {
12342 /* Compute the x-position of the glyph. In front and past the
12343 image is a space. We include this in the highlighted area. */
12344 row = MATRIX_ROW (w->current_matrix, vpos);
12345 for (i = x = 0; i < hpos; ++i)
12346 x += row->glyphs[TEXT_AREA][i].pixel_width;
12347
12348 /* Record this as the current active region. */
12349 hlinfo->mouse_face_beg_col = hpos;
12350 hlinfo->mouse_face_beg_row = vpos;
12351 hlinfo->mouse_face_beg_x = x;
12352 hlinfo->mouse_face_past_end = 0;
12353
12354 hlinfo->mouse_face_end_col = hpos + 1;
12355 hlinfo->mouse_face_end_row = vpos;
12356 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12357 hlinfo->mouse_face_window = window;
12358 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12359
12360 /* Display it as active. */
12361 show_mouse_face (hlinfo, draw);
12362 }
12363
12364 set_help_echo:
12365
12366 /* Set help_echo_string to a help string to display for this tool-bar item.
12367 XTread_socket does the rest. */
12368 help_echo_object = help_echo_window = Qnil;
12369 help_echo_pos = -1;
12370 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12371 if (NILP (help_echo_string))
12372 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12373 }
12374
12375 #endif /* !USE_GTK && !HAVE_NS */
12376
12377 #endif /* HAVE_WINDOW_SYSTEM */
12378
12379
12380 \f
12381 /************************************************************************
12382 Horizontal scrolling
12383 ************************************************************************/
12384
12385 static int hscroll_window_tree (Lisp_Object);
12386 static int hscroll_windows (Lisp_Object);
12387
12388 /* For all leaf windows in the window tree rooted at WINDOW, set their
12389 hscroll value so that PT is (i) visible in the window, and (ii) so
12390 that it is not within a certain margin at the window's left and
12391 right border. Value is non-zero if any window's hscroll has been
12392 changed. */
12393
12394 static int
12395 hscroll_window_tree (Lisp_Object window)
12396 {
12397 int hscrolled_p = 0;
12398 int hscroll_relative_p = FLOATP (Vhscroll_step);
12399 int hscroll_step_abs = 0;
12400 double hscroll_step_rel = 0;
12401
12402 if (hscroll_relative_p)
12403 {
12404 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12405 if (hscroll_step_rel < 0)
12406 {
12407 hscroll_relative_p = 0;
12408 hscroll_step_abs = 0;
12409 }
12410 }
12411 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12412 {
12413 hscroll_step_abs = XINT (Vhscroll_step);
12414 if (hscroll_step_abs < 0)
12415 hscroll_step_abs = 0;
12416 }
12417 else
12418 hscroll_step_abs = 0;
12419
12420 while (WINDOWP (window))
12421 {
12422 struct window *w = XWINDOW (window);
12423
12424 if (WINDOWP (w->contents))
12425 hscrolled_p |= hscroll_window_tree (w->contents);
12426 else if (w->cursor.vpos >= 0)
12427 {
12428 int h_margin;
12429 int text_area_width;
12430 struct glyph_row *current_cursor_row
12431 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12432 struct glyph_row *desired_cursor_row
12433 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12434 struct glyph_row *cursor_row
12435 = (desired_cursor_row->enabled_p
12436 ? desired_cursor_row
12437 : current_cursor_row);
12438 int row_r2l_p = cursor_row->reversed_p;
12439
12440 text_area_width = window_box_width (w, TEXT_AREA);
12441
12442 /* Scroll when cursor is inside this scroll margin. */
12443 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12444
12445 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12446 /* For left-to-right rows, hscroll when cursor is either
12447 (i) inside the right hscroll margin, or (ii) if it is
12448 inside the left margin and the window is already
12449 hscrolled. */
12450 && ((!row_r2l_p
12451 && ((w->hscroll
12452 && w->cursor.x <= h_margin)
12453 || (cursor_row->enabled_p
12454 && cursor_row->truncated_on_right_p
12455 && (w->cursor.x >= text_area_width - h_margin))))
12456 /* For right-to-left rows, the logic is similar,
12457 except that rules for scrolling to left and right
12458 are reversed. E.g., if cursor.x <= h_margin, we
12459 need to hscroll "to the right" unconditionally,
12460 and that will scroll the screen to the left so as
12461 to reveal the next portion of the row. */
12462 || (row_r2l_p
12463 && ((cursor_row->enabled_p
12464 /* FIXME: It is confusing to set the
12465 truncated_on_right_p flag when R2L rows
12466 are actually truncated on the left. */
12467 && cursor_row->truncated_on_right_p
12468 && w->cursor.x <= h_margin)
12469 || (w->hscroll
12470 && (w->cursor.x >= text_area_width - h_margin))))))
12471 {
12472 struct it it;
12473 ptrdiff_t hscroll;
12474 struct buffer *saved_current_buffer;
12475 ptrdiff_t pt;
12476 int wanted_x;
12477
12478 /* Find point in a display of infinite width. */
12479 saved_current_buffer = current_buffer;
12480 current_buffer = XBUFFER (w->contents);
12481
12482 if (w == XWINDOW (selected_window))
12483 pt = PT;
12484 else
12485 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12486
12487 /* Move iterator to pt starting at cursor_row->start in
12488 a line with infinite width. */
12489 init_to_row_start (&it, w, cursor_row);
12490 it.last_visible_x = INFINITY;
12491 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12492 current_buffer = saved_current_buffer;
12493
12494 /* Position cursor in window. */
12495 if (!hscroll_relative_p && hscroll_step_abs == 0)
12496 hscroll = max (0, (it.current_x
12497 - (ITERATOR_AT_END_OF_LINE_P (&it)
12498 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12499 : (text_area_width / 2))))
12500 / FRAME_COLUMN_WIDTH (it.f);
12501 else if ((!row_r2l_p
12502 && w->cursor.x >= text_area_width - h_margin)
12503 || (row_r2l_p && w->cursor.x <= h_margin))
12504 {
12505 if (hscroll_relative_p)
12506 wanted_x = text_area_width * (1 - hscroll_step_rel)
12507 - h_margin;
12508 else
12509 wanted_x = text_area_width
12510 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12511 - h_margin;
12512 hscroll
12513 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12514 }
12515 else
12516 {
12517 if (hscroll_relative_p)
12518 wanted_x = text_area_width * hscroll_step_rel
12519 + h_margin;
12520 else
12521 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12522 + h_margin;
12523 hscroll
12524 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12525 }
12526 hscroll = max (hscroll, w->min_hscroll);
12527
12528 /* Don't prevent redisplay optimizations if hscroll
12529 hasn't changed, as it will unnecessarily slow down
12530 redisplay. */
12531 if (w->hscroll != hscroll)
12532 {
12533 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12534 w->hscroll = hscroll;
12535 hscrolled_p = 1;
12536 }
12537 }
12538 }
12539
12540 window = w->next;
12541 }
12542
12543 /* Value is non-zero if hscroll of any leaf window has been changed. */
12544 return hscrolled_p;
12545 }
12546
12547
12548 /* Set hscroll so that cursor is visible and not inside horizontal
12549 scroll margins for all windows in the tree rooted at WINDOW. See
12550 also hscroll_window_tree above. Value is non-zero if any window's
12551 hscroll has been changed. If it has, desired matrices on the frame
12552 of WINDOW are cleared. */
12553
12554 static int
12555 hscroll_windows (Lisp_Object window)
12556 {
12557 int hscrolled_p = hscroll_window_tree (window);
12558 if (hscrolled_p)
12559 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12560 return hscrolled_p;
12561 }
12562
12563
12564 \f
12565 /************************************************************************
12566 Redisplay
12567 ************************************************************************/
12568
12569 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12570 to a non-zero value. This is sometimes handy to have in a debugger
12571 session. */
12572
12573 #ifdef GLYPH_DEBUG
12574
12575 /* First and last unchanged row for try_window_id. */
12576
12577 static int debug_first_unchanged_at_end_vpos;
12578 static int debug_last_unchanged_at_beg_vpos;
12579
12580 /* Delta vpos and y. */
12581
12582 static int debug_dvpos, debug_dy;
12583
12584 /* Delta in characters and bytes for try_window_id. */
12585
12586 static ptrdiff_t debug_delta, debug_delta_bytes;
12587
12588 /* Values of window_end_pos and window_end_vpos at the end of
12589 try_window_id. */
12590
12591 static ptrdiff_t debug_end_vpos;
12592
12593 /* Append a string to W->desired_matrix->method. FMT is a printf
12594 format string. If trace_redisplay_p is non-zero also printf the
12595 resulting string to stderr. */
12596
12597 static void debug_method_add (struct window *, char const *, ...)
12598 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12599
12600 static void
12601 debug_method_add (struct window *w, char const *fmt, ...)
12602 {
12603 void *ptr = w;
12604 char *method = w->desired_matrix->method;
12605 int len = strlen (method);
12606 int size = sizeof w->desired_matrix->method;
12607 int remaining = size - len - 1;
12608 va_list ap;
12609
12610 if (len && remaining)
12611 {
12612 method[len] = '|';
12613 --remaining, ++len;
12614 }
12615
12616 va_start (ap, fmt);
12617 vsnprintf (method + len, remaining + 1, fmt, ap);
12618 va_end (ap);
12619
12620 if (trace_redisplay_p)
12621 fprintf (stderr, "%p (%s): %s\n",
12622 ptr,
12623 ((BUFFERP (w->contents)
12624 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12625 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12626 : "no buffer"),
12627 method + len);
12628 }
12629
12630 #endif /* GLYPH_DEBUG */
12631
12632
12633 /* Value is non-zero if all changes in window W, which displays
12634 current_buffer, are in the text between START and END. START is a
12635 buffer position, END is given as a distance from Z. Used in
12636 redisplay_internal for display optimization. */
12637
12638 static int
12639 text_outside_line_unchanged_p (struct window *w,
12640 ptrdiff_t start, ptrdiff_t end)
12641 {
12642 int unchanged_p = 1;
12643
12644 /* If text or overlays have changed, see where. */
12645 if (window_outdated (w))
12646 {
12647 /* Gap in the line? */
12648 if (GPT < start || Z - GPT < end)
12649 unchanged_p = 0;
12650
12651 /* Changes start in front of the line, or end after it? */
12652 if (unchanged_p
12653 && (BEG_UNCHANGED < start - 1
12654 || END_UNCHANGED < end))
12655 unchanged_p = 0;
12656
12657 /* If selective display, can't optimize if changes start at the
12658 beginning of the line. */
12659 if (unchanged_p
12660 && INTEGERP (BVAR (current_buffer, selective_display))
12661 && XINT (BVAR (current_buffer, selective_display)) > 0
12662 && (BEG_UNCHANGED < start || GPT <= start))
12663 unchanged_p = 0;
12664
12665 /* If there are overlays at the start or end of the line, these
12666 may have overlay strings with newlines in them. A change at
12667 START, for instance, may actually concern the display of such
12668 overlay strings as well, and they are displayed on different
12669 lines. So, quickly rule out this case. (For the future, it
12670 might be desirable to implement something more telling than
12671 just BEG/END_UNCHANGED.) */
12672 if (unchanged_p)
12673 {
12674 if (BEG + BEG_UNCHANGED == start
12675 && overlay_touches_p (start))
12676 unchanged_p = 0;
12677 if (END_UNCHANGED == end
12678 && overlay_touches_p (Z - end))
12679 unchanged_p = 0;
12680 }
12681
12682 /* Under bidi reordering, adding or deleting a character in the
12683 beginning of a paragraph, before the first strong directional
12684 character, can change the base direction of the paragraph (unless
12685 the buffer specifies a fixed paragraph direction), which will
12686 require to redisplay the whole paragraph. It might be worthwhile
12687 to find the paragraph limits and widen the range of redisplayed
12688 lines to that, but for now just give up this optimization. */
12689 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12690 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12691 unchanged_p = 0;
12692 }
12693
12694 return unchanged_p;
12695 }
12696
12697
12698 /* Do a frame update, taking possible shortcuts into account. This is
12699 the main external entry point for redisplay.
12700
12701 If the last redisplay displayed an echo area message and that message
12702 is no longer requested, we clear the echo area or bring back the
12703 mini-buffer if that is in use. */
12704
12705 void
12706 redisplay (void)
12707 {
12708 redisplay_internal ();
12709 }
12710
12711
12712 static Lisp_Object
12713 overlay_arrow_string_or_property (Lisp_Object var)
12714 {
12715 Lisp_Object val;
12716
12717 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12718 return val;
12719
12720 return Voverlay_arrow_string;
12721 }
12722
12723 /* Return 1 if there are any overlay-arrows in current_buffer. */
12724 static int
12725 overlay_arrow_in_current_buffer_p (void)
12726 {
12727 Lisp_Object vlist;
12728
12729 for (vlist = Voverlay_arrow_variable_list;
12730 CONSP (vlist);
12731 vlist = XCDR (vlist))
12732 {
12733 Lisp_Object var = XCAR (vlist);
12734 Lisp_Object val;
12735
12736 if (!SYMBOLP (var))
12737 continue;
12738 val = find_symbol_value (var);
12739 if (MARKERP (val)
12740 && current_buffer == XMARKER (val)->buffer)
12741 return 1;
12742 }
12743 return 0;
12744 }
12745
12746
12747 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12748 has changed. */
12749
12750 static int
12751 overlay_arrows_changed_p (void)
12752 {
12753 Lisp_Object vlist;
12754
12755 for (vlist = Voverlay_arrow_variable_list;
12756 CONSP (vlist);
12757 vlist = XCDR (vlist))
12758 {
12759 Lisp_Object var = XCAR (vlist);
12760 Lisp_Object val, pstr;
12761
12762 if (!SYMBOLP (var))
12763 continue;
12764 val = find_symbol_value (var);
12765 if (!MARKERP (val))
12766 continue;
12767 if (! EQ (COERCE_MARKER (val),
12768 Fget (var, Qlast_arrow_position))
12769 || ! (pstr = overlay_arrow_string_or_property (var),
12770 EQ (pstr, Fget (var, Qlast_arrow_string))))
12771 return 1;
12772 }
12773 return 0;
12774 }
12775
12776 /* Mark overlay arrows to be updated on next redisplay. */
12777
12778 static void
12779 update_overlay_arrows (int up_to_date)
12780 {
12781 Lisp_Object vlist;
12782
12783 for (vlist = Voverlay_arrow_variable_list;
12784 CONSP (vlist);
12785 vlist = XCDR (vlist))
12786 {
12787 Lisp_Object var = XCAR (vlist);
12788
12789 if (!SYMBOLP (var))
12790 continue;
12791
12792 if (up_to_date > 0)
12793 {
12794 Lisp_Object val = find_symbol_value (var);
12795 Fput (var, Qlast_arrow_position,
12796 COERCE_MARKER (val));
12797 Fput (var, Qlast_arrow_string,
12798 overlay_arrow_string_or_property (var));
12799 }
12800 else if (up_to_date < 0
12801 || !NILP (Fget (var, Qlast_arrow_position)))
12802 {
12803 Fput (var, Qlast_arrow_position, Qt);
12804 Fput (var, Qlast_arrow_string, Qt);
12805 }
12806 }
12807 }
12808
12809
12810 /* Return overlay arrow string to display at row.
12811 Return integer (bitmap number) for arrow bitmap in left fringe.
12812 Return nil if no overlay arrow. */
12813
12814 static Lisp_Object
12815 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12816 {
12817 Lisp_Object vlist;
12818
12819 for (vlist = Voverlay_arrow_variable_list;
12820 CONSP (vlist);
12821 vlist = XCDR (vlist))
12822 {
12823 Lisp_Object var = XCAR (vlist);
12824 Lisp_Object val;
12825
12826 if (!SYMBOLP (var))
12827 continue;
12828
12829 val = find_symbol_value (var);
12830
12831 if (MARKERP (val)
12832 && current_buffer == XMARKER (val)->buffer
12833 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12834 {
12835 if (FRAME_WINDOW_P (it->f)
12836 /* FIXME: if ROW->reversed_p is set, this should test
12837 the right fringe, not the left one. */
12838 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12839 {
12840 #ifdef HAVE_WINDOW_SYSTEM
12841 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12842 {
12843 int fringe_bitmap;
12844 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12845 return make_number (fringe_bitmap);
12846 }
12847 #endif
12848 return make_number (-1); /* Use default arrow bitmap. */
12849 }
12850 return overlay_arrow_string_or_property (var);
12851 }
12852 }
12853
12854 return Qnil;
12855 }
12856
12857 /* Return 1 if point moved out of or into a composition. Otherwise
12858 return 0. PREV_BUF and PREV_PT are the last point buffer and
12859 position. BUF and PT are the current point buffer and position. */
12860
12861 static int
12862 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12863 struct buffer *buf, ptrdiff_t pt)
12864 {
12865 ptrdiff_t start, end;
12866 Lisp_Object prop;
12867 Lisp_Object buffer;
12868
12869 XSETBUFFER (buffer, buf);
12870 /* Check a composition at the last point if point moved within the
12871 same buffer. */
12872 if (prev_buf == buf)
12873 {
12874 if (prev_pt == pt)
12875 /* Point didn't move. */
12876 return 0;
12877
12878 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12879 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12880 && composition_valid_p (start, end, prop)
12881 && start < prev_pt && end > prev_pt)
12882 /* The last point was within the composition. Return 1 iff
12883 point moved out of the composition. */
12884 return (pt <= start || pt >= end);
12885 }
12886
12887 /* Check a composition at the current point. */
12888 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12889 && find_composition (pt, -1, &start, &end, &prop, buffer)
12890 && composition_valid_p (start, end, prop)
12891 && start < pt && end > pt);
12892 }
12893
12894 /* Reconsider the clip changes of buffer which is displayed in W. */
12895
12896 static void
12897 reconsider_clip_changes (struct window *w)
12898 {
12899 struct buffer *b = XBUFFER (w->contents);
12900
12901 if (b->clip_changed
12902 && w->window_end_valid
12903 && w->current_matrix->buffer == b
12904 && w->current_matrix->zv == BUF_ZV (b)
12905 && w->current_matrix->begv == BUF_BEGV (b))
12906 b->clip_changed = 0;
12907
12908 /* If display wasn't paused, and W is not a tool bar window, see if
12909 point has been moved into or out of a composition. In that case,
12910 we set b->clip_changed to 1 to force updating the screen. If
12911 b->clip_changed has already been set to 1, we can skip this
12912 check. */
12913 if (!b->clip_changed && w->window_end_valid)
12914 {
12915 ptrdiff_t pt = (w == XWINDOW (selected_window)
12916 ? PT : marker_position (w->pointm));
12917
12918 if ((w->current_matrix->buffer != b || pt != w->last_point)
12919 && check_point_in_composition (w->current_matrix->buffer,
12920 w->last_point, b, pt))
12921 b->clip_changed = 1;
12922 }
12923 }
12924
12925 void propagate_buffer_redisplay (void)
12926 { /* Resetting b->text->redisplay is problematic!
12927 We can't just reset it in the case that some window that displays
12928 it has not been redisplayed; and such a window can stay
12929 unredisplayed for a long time if it's currently invisible.
12930 But we do want to reset it at the end of redisplay otherwise
12931 its displayed windows will keep being redisplayed over and over
12932 again.
12933 So we copy all b->text->redisplay flags up to their windows here,
12934 such that mark_window_display_accurate can safely reset
12935 b->text->redisplay. */
12936 Lisp_Object ws = window_list ();
12937 for (; CONSP (ws); ws = XCDR (ws))
12938 {
12939 struct window *thisw = XWINDOW (XCAR (ws));
12940 struct buffer *thisb = XBUFFER (thisw->contents);
12941 if (thisb->text->redisplay)
12942 thisw->redisplay = true;
12943 }
12944 }
12945
12946 #define STOP_POLLING \
12947 do { if (! polling_stopped_here) stop_polling (); \
12948 polling_stopped_here = 1; } while (0)
12949
12950 #define RESUME_POLLING \
12951 do { if (polling_stopped_here) start_polling (); \
12952 polling_stopped_here = 0; } while (0)
12953
12954
12955 /* Perhaps in the future avoid recentering windows if it
12956 is not necessary; currently that causes some problems. */
12957
12958 static void
12959 redisplay_internal (void)
12960 {
12961 struct window *w = XWINDOW (selected_window);
12962 struct window *sw;
12963 struct frame *fr;
12964 int pending;
12965 bool must_finish = 0, match_p;
12966 struct text_pos tlbufpos, tlendpos;
12967 int number_of_visible_frames;
12968 ptrdiff_t count;
12969 struct frame *sf;
12970 int polling_stopped_here = 0;
12971 Lisp_Object tail, frame;
12972
12973 /* True means redisplay has to consider all windows on all
12974 frames. False, only selected_window is considered. */
12975 bool consider_all_windows_p;
12976
12977 /* True means redisplay has to redisplay the miniwindow. */
12978 bool update_miniwindow_p = false;
12979
12980 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12981
12982 /* No redisplay if running in batch mode or frame is not yet fully
12983 initialized, or redisplay is explicitly turned off by setting
12984 Vinhibit_redisplay. */
12985 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12986 || !NILP (Vinhibit_redisplay))
12987 return;
12988
12989 /* Don't examine these until after testing Vinhibit_redisplay.
12990 When Emacs is shutting down, perhaps because its connection to
12991 X has dropped, we should not look at them at all. */
12992 fr = XFRAME (w->frame);
12993 sf = SELECTED_FRAME ();
12994
12995 if (!fr->glyphs_initialized_p)
12996 return;
12997
12998 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12999 if (popup_activated ())
13000 return;
13001 #endif
13002
13003 /* I don't think this happens but let's be paranoid. */
13004 if (redisplaying_p)
13005 return;
13006
13007 /* Record a function that clears redisplaying_p
13008 when we leave this function. */
13009 count = SPECPDL_INDEX ();
13010 record_unwind_protect_void (unwind_redisplay);
13011 redisplaying_p = 1;
13012 specbind (Qinhibit_free_realized_faces, Qnil);
13013
13014 /* Record this function, so it appears on the profiler's backtraces. */
13015 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
13016
13017 FOR_EACH_FRAME (tail, frame)
13018 XFRAME (frame)->already_hscrolled_p = 0;
13019
13020 retry:
13021 /* Remember the currently selected window. */
13022 sw = w;
13023
13024 pending = 0;
13025 last_escape_glyph_frame = NULL;
13026 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13027 last_glyphless_glyph_frame = NULL;
13028 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13029
13030 /* If face_change_count is non-zero, init_iterator will free all
13031 realized faces, which includes the faces referenced from current
13032 matrices. So, we can't reuse current matrices in this case. */
13033 if (face_change_count)
13034 windows_or_buffers_changed = 47;
13035
13036 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13037 && FRAME_TTY (sf)->previous_frame != sf)
13038 {
13039 /* Since frames on a single ASCII terminal share the same
13040 display area, displaying a different frame means redisplay
13041 the whole thing. */
13042 SET_FRAME_GARBAGED (sf);
13043 #ifndef DOS_NT
13044 set_tty_color_mode (FRAME_TTY (sf), sf);
13045 #endif
13046 FRAME_TTY (sf)->previous_frame = sf;
13047 }
13048
13049 /* Set the visible flags for all frames. Do this before checking for
13050 resized or garbaged frames; they want to know if their frames are
13051 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13052 number_of_visible_frames = 0;
13053
13054 FOR_EACH_FRAME (tail, frame)
13055 {
13056 struct frame *f = XFRAME (frame);
13057
13058 if (FRAME_VISIBLE_P (f))
13059 {
13060 ++number_of_visible_frames;
13061 /* Adjust matrices for visible frames only. */
13062 if (f->fonts_changed)
13063 {
13064 adjust_frame_glyphs (f);
13065 f->fonts_changed = 0;
13066 }
13067 /* If cursor type has been changed on the frame
13068 other than selected, consider all frames. */
13069 if (f != sf && f->cursor_type_changed)
13070 update_mode_lines = 31;
13071 }
13072 clear_desired_matrices (f);
13073 }
13074
13075 /* Notice any pending interrupt request to change frame size. */
13076 do_pending_window_change (1);
13077
13078 /* do_pending_window_change could change the selected_window due to
13079 frame resizing which makes the selected window too small. */
13080 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13081 sw = w;
13082
13083 /* Clear frames marked as garbaged. */
13084 clear_garbaged_frames ();
13085
13086 /* Build menubar and tool-bar items. */
13087 if (NILP (Vmemory_full))
13088 prepare_menu_bars ();
13089
13090 reconsider_clip_changes (w);
13091
13092 /* In most cases selected window displays current buffer. */
13093 match_p = XBUFFER (w->contents) == current_buffer;
13094 if (match_p)
13095 {
13096 /* Detect case that we need to write or remove a star in the mode line. */
13097 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13098 w->update_mode_line = 1;
13099
13100 if (mode_line_update_needed (w))
13101 w->update_mode_line = 1;
13102 }
13103
13104 /* Normally the message* functions will have already displayed and
13105 updated the echo area, but the frame may have been trashed, or
13106 the update may have been preempted, so display the echo area
13107 again here. Checking message_cleared_p captures the case that
13108 the echo area should be cleared. */
13109 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13110 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13111 || (message_cleared_p
13112 && minibuf_level == 0
13113 /* If the mini-window is currently selected, this means the
13114 echo-area doesn't show through. */
13115 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13116 {
13117 int window_height_changed_p = echo_area_display (0);
13118
13119 if (message_cleared_p)
13120 update_miniwindow_p = true;
13121
13122 must_finish = 1;
13123
13124 /* If we don't display the current message, don't clear the
13125 message_cleared_p flag, because, if we did, we wouldn't clear
13126 the echo area in the next redisplay which doesn't preserve
13127 the echo area. */
13128 if (!display_last_displayed_message_p)
13129 message_cleared_p = 0;
13130
13131 if (window_height_changed_p)
13132 {
13133 windows_or_buffers_changed = 50;
13134
13135 /* If window configuration was changed, frames may have been
13136 marked garbaged. Clear them or we will experience
13137 surprises wrt scrolling. */
13138 clear_garbaged_frames ();
13139 }
13140 }
13141 else if (EQ (selected_window, minibuf_window)
13142 && (current_buffer->clip_changed || window_outdated (w))
13143 && resize_mini_window (w, 0))
13144 {
13145 /* Resized active mini-window to fit the size of what it is
13146 showing if its contents might have changed. */
13147 must_finish = 1;
13148
13149 /* If window configuration was changed, frames may have been
13150 marked garbaged. Clear them or we will experience
13151 surprises wrt scrolling. */
13152 clear_garbaged_frames ();
13153 }
13154
13155 if (windows_or_buffers_changed && !update_mode_lines)
13156 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13157 only the windows's contents needs to be refreshed, or whether the
13158 mode-lines also need a refresh. */
13159 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
13160 ? REDISPLAY_SOME : 32);
13161
13162 /* If specs for an arrow have changed, do thorough redisplay
13163 to ensure we remove any arrow that should no longer exist. */
13164 if (overlay_arrows_changed_p ())
13165 /* Apparently, this is the only case where we update other windows,
13166 without updating other mode-lines. */
13167 windows_or_buffers_changed = 49;
13168
13169 consider_all_windows_p = (update_mode_lines
13170 || windows_or_buffers_changed);
13171
13172 #define AINC(a,i) \
13173 if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
13174 ASET (a, i, make_number (1 + XINT (AREF (a, i))))
13175
13176 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
13177 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
13178
13179 /* Optimize the case that only the line containing the cursor in the
13180 selected window has changed. Variables starting with this_ are
13181 set in display_line and record information about the line
13182 containing the cursor. */
13183 tlbufpos = this_line_start_pos;
13184 tlendpos = this_line_end_pos;
13185 if (!consider_all_windows_p
13186 && CHARPOS (tlbufpos) > 0
13187 && !w->update_mode_line
13188 && !current_buffer->clip_changed
13189 && !current_buffer->prevent_redisplay_optimizations_p
13190 && FRAME_VISIBLE_P (XFRAME (w->frame))
13191 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13192 && !XFRAME (w->frame)->cursor_type_changed
13193 /* Make sure recorded data applies to current buffer, etc. */
13194 && this_line_buffer == current_buffer
13195 && match_p
13196 && !w->force_start
13197 && !w->optional_new_start
13198 /* Point must be on the line that we have info recorded about. */
13199 && PT >= CHARPOS (tlbufpos)
13200 && PT <= Z - CHARPOS (tlendpos)
13201 /* All text outside that line, including its final newline,
13202 must be unchanged. */
13203 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13204 CHARPOS (tlendpos)))
13205 {
13206 if (CHARPOS (tlbufpos) > BEGV
13207 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13208 && (CHARPOS (tlbufpos) == ZV
13209 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13210 /* Former continuation line has disappeared by becoming empty. */
13211 goto cancel;
13212 else if (window_outdated (w) || MINI_WINDOW_P (w))
13213 {
13214 /* We have to handle the case of continuation around a
13215 wide-column character (see the comment in indent.c around
13216 line 1340).
13217
13218 For instance, in the following case:
13219
13220 -------- Insert --------
13221 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13222 J_I_ ==> J_I_ `^^' are cursors.
13223 ^^ ^^
13224 -------- --------
13225
13226 As we have to redraw the line above, we cannot use this
13227 optimization. */
13228
13229 struct it it;
13230 int line_height_before = this_line_pixel_height;
13231
13232 /* Note that start_display will handle the case that the
13233 line starting at tlbufpos is a continuation line. */
13234 start_display (&it, w, tlbufpos);
13235
13236 /* Implementation note: It this still necessary? */
13237 if (it.current_x != this_line_start_x)
13238 goto cancel;
13239
13240 TRACE ((stderr, "trying display optimization 1\n"));
13241 w->cursor.vpos = -1;
13242 overlay_arrow_seen = 0;
13243 it.vpos = this_line_vpos;
13244 it.current_y = this_line_y;
13245 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13246 display_line (&it);
13247
13248 /* If line contains point, is not continued,
13249 and ends at same distance from eob as before, we win. */
13250 if (w->cursor.vpos >= 0
13251 /* Line is not continued, otherwise this_line_start_pos
13252 would have been set to 0 in display_line. */
13253 && CHARPOS (this_line_start_pos)
13254 /* Line ends as before. */
13255 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13256 /* Line has same height as before. Otherwise other lines
13257 would have to be shifted up or down. */
13258 && this_line_pixel_height == line_height_before)
13259 {
13260 /* If this is not the window's last line, we must adjust
13261 the charstarts of the lines below. */
13262 if (it.current_y < it.last_visible_y)
13263 {
13264 struct glyph_row *row
13265 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13266 ptrdiff_t delta, delta_bytes;
13267
13268 /* We used to distinguish between two cases here,
13269 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13270 when the line ends in a newline or the end of the
13271 buffer's accessible portion. But both cases did
13272 the same, so they were collapsed. */
13273 delta = (Z
13274 - CHARPOS (tlendpos)
13275 - MATRIX_ROW_START_CHARPOS (row));
13276 delta_bytes = (Z_BYTE
13277 - BYTEPOS (tlendpos)
13278 - MATRIX_ROW_START_BYTEPOS (row));
13279
13280 increment_matrix_positions (w->current_matrix,
13281 this_line_vpos + 1,
13282 w->current_matrix->nrows,
13283 delta, delta_bytes);
13284 }
13285
13286 /* If this row displays text now but previously didn't,
13287 or vice versa, w->window_end_vpos may have to be
13288 adjusted. */
13289 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13290 {
13291 if (w->window_end_vpos < this_line_vpos)
13292 w->window_end_vpos = this_line_vpos;
13293 }
13294 else if (w->window_end_vpos == this_line_vpos
13295 && this_line_vpos > 0)
13296 w->window_end_vpos = this_line_vpos - 1;
13297 w->window_end_valid = 0;
13298
13299 /* Update hint: No need to try to scroll in update_window. */
13300 w->desired_matrix->no_scrolling_p = 1;
13301
13302 #ifdef GLYPH_DEBUG
13303 *w->desired_matrix->method = 0;
13304 debug_method_add (w, "optimization 1");
13305 #endif
13306 #ifdef HAVE_WINDOW_SYSTEM
13307 update_window_fringes (w, 0);
13308 #endif
13309 goto update;
13310 }
13311 else
13312 goto cancel;
13313 }
13314 else if (/* Cursor position hasn't changed. */
13315 PT == w->last_point
13316 /* Make sure the cursor was last displayed
13317 in this window. Otherwise we have to reposition it. */
13318 && 0 <= w->cursor.vpos
13319 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13320 {
13321 if (!must_finish)
13322 {
13323 do_pending_window_change (1);
13324 /* If selected_window changed, redisplay again. */
13325 if (WINDOWP (selected_window)
13326 && (w = XWINDOW (selected_window)) != sw)
13327 goto retry;
13328
13329 /* We used to always goto end_of_redisplay here, but this
13330 isn't enough if we have a blinking cursor. */
13331 if (w->cursor_off_p == w->last_cursor_off_p)
13332 goto end_of_redisplay;
13333 }
13334 goto update;
13335 }
13336 /* If highlighting the region, or if the cursor is in the echo area,
13337 then we can't just move the cursor. */
13338 else if (NILP (Vshow_trailing_whitespace)
13339 && !cursor_in_echo_area)
13340 {
13341 struct it it;
13342 struct glyph_row *row;
13343
13344 /* Skip from tlbufpos to PT and see where it is. Note that
13345 PT may be in invisible text. If so, we will end at the
13346 next visible position. */
13347 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13348 NULL, DEFAULT_FACE_ID);
13349 it.current_x = this_line_start_x;
13350 it.current_y = this_line_y;
13351 it.vpos = this_line_vpos;
13352
13353 /* The call to move_it_to stops in front of PT, but
13354 moves over before-strings. */
13355 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13356
13357 if (it.vpos == this_line_vpos
13358 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13359 row->enabled_p))
13360 {
13361 eassert (this_line_vpos == it.vpos);
13362 eassert (this_line_y == it.current_y);
13363 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13364 #ifdef GLYPH_DEBUG
13365 *w->desired_matrix->method = 0;
13366 debug_method_add (w, "optimization 3");
13367 #endif
13368 goto update;
13369 }
13370 else
13371 goto cancel;
13372 }
13373
13374 cancel:
13375 /* Text changed drastically or point moved off of line. */
13376 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13377 }
13378
13379 CHARPOS (this_line_start_pos) = 0;
13380 ++clear_face_cache_count;
13381 #ifdef HAVE_WINDOW_SYSTEM
13382 ++clear_image_cache_count;
13383 #endif
13384
13385 /* Build desired matrices, and update the display. If
13386 consider_all_windows_p is non-zero, do it for all windows on all
13387 frames. Otherwise do it for selected_window, only. */
13388
13389 if (consider_all_windows_p)
13390 {
13391 FOR_EACH_FRAME (tail, frame)
13392 XFRAME (frame)->updated_p = 0;
13393
13394 propagate_buffer_redisplay ();
13395
13396 FOR_EACH_FRAME (tail, frame)
13397 {
13398 struct frame *f = XFRAME (frame);
13399
13400 /* We don't have to do anything for unselected terminal
13401 frames. */
13402 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13403 && !EQ (FRAME_TTY (f)->top_frame, frame))
13404 continue;
13405
13406 retry_frame:
13407
13408 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13409 {
13410 bool gcscrollbars
13411 /* Only GC scollbars when we redisplay the whole frame. */
13412 = f->redisplay || windows_or_buffers_changed != REDISPLAY_SOME;
13413 /* Mark all the scroll bars to be removed; we'll redeem
13414 the ones we want when we redisplay their windows. */
13415 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13416 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13417
13418 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13419 redisplay_windows (FRAME_ROOT_WINDOW (f));
13420
13421 /* The X error handler may have deleted that frame. */
13422 if (!FRAME_LIVE_P (f))
13423 continue;
13424
13425 /* Any scroll bars which redisplay_windows should have
13426 nuked should now go away. */
13427 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13428 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13429
13430 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13431 {
13432 /* If fonts changed on visible frame, display again. */
13433 if (f->fonts_changed)
13434 {
13435 adjust_frame_glyphs (f);
13436 f->fonts_changed = 0;
13437 goto retry_frame;
13438 }
13439
13440 /* See if we have to hscroll. */
13441 if (!f->already_hscrolled_p)
13442 {
13443 f->already_hscrolled_p = 1;
13444 if (hscroll_windows (f->root_window))
13445 goto retry_frame;
13446 }
13447
13448 /* Prevent various kinds of signals during display
13449 update. stdio is not robust about handling
13450 signals, which can cause an apparent I/O
13451 error. */
13452 if (interrupt_input)
13453 unrequest_sigio ();
13454 STOP_POLLING;
13455
13456 /* Mark windows on frame F to update. If we decide to
13457 update all frames but windows_or_buffers_changed is
13458 zero, we assume that only the windows that shows
13459 current buffer should be really updated. */
13460 set_window_update_flags
13461 (XWINDOW (f->root_window),
13462 (windows_or_buffers_changed ? NULL : current_buffer), 1);
13463 pending |= update_frame (f, 0, 0);
13464 f->cursor_type_changed = 0;
13465 f->updated_p = 1;
13466 }
13467 }
13468 }
13469
13470 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13471
13472 if (!pending)
13473 {
13474 /* Do the mark_window_display_accurate after all windows have
13475 been redisplayed because this call resets flags in buffers
13476 which are needed for proper redisplay. */
13477 FOR_EACH_FRAME (tail, frame)
13478 {
13479 struct frame *f = XFRAME (frame);
13480 if (f->updated_p)
13481 {
13482 f->redisplay = false;
13483 mark_window_display_accurate (f->root_window, 1);
13484 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13485 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13486 }
13487 }
13488 }
13489 }
13490 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13491 {
13492 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13493 struct frame *mini_frame;
13494
13495 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13496 /* Use list_of_error, not Qerror, so that
13497 we catch only errors and don't run the debugger. */
13498 internal_condition_case_1 (redisplay_window_1, selected_window,
13499 list_of_error,
13500 redisplay_window_error);
13501 if (update_miniwindow_p)
13502 internal_condition_case_1 (redisplay_window_1, mini_window,
13503 list_of_error,
13504 redisplay_window_error);
13505
13506 /* Compare desired and current matrices, perform output. */
13507
13508 update:
13509 /* If fonts changed, display again. */
13510 if (sf->fonts_changed)
13511 goto retry;
13512
13513 /* Prevent various kinds of signals during display update.
13514 stdio is not robust about handling signals,
13515 which can cause an apparent I/O error. */
13516 if (interrupt_input)
13517 unrequest_sigio ();
13518 STOP_POLLING;
13519
13520 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13521 {
13522 if (hscroll_windows (selected_window))
13523 goto retry;
13524
13525 XWINDOW (selected_window)->must_be_updated_p = 1;
13526 pending = update_frame (sf, 0, 0);
13527 sf->cursor_type_changed = 0;
13528 }
13529
13530 /* We may have called echo_area_display at the top of this
13531 function. If the echo area is on another frame, that may
13532 have put text on a frame other than the selected one, so the
13533 above call to update_frame would not have caught it. Catch
13534 it here. */
13535 mini_window = FRAME_MINIBUF_WINDOW (sf);
13536 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13537
13538 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13539 {
13540 XWINDOW (mini_window)->must_be_updated_p = 1;
13541 pending |= update_frame (mini_frame, 0, 0);
13542 mini_frame->cursor_type_changed = 0;
13543 if (!pending && hscroll_windows (mini_window))
13544 goto retry;
13545 }
13546 }
13547
13548 /* If display was paused because of pending input, make sure we do a
13549 thorough update the next time. */
13550 if (pending)
13551 {
13552 /* Prevent the optimization at the beginning of
13553 redisplay_internal that tries a single-line update of the
13554 line containing the cursor in the selected window. */
13555 CHARPOS (this_line_start_pos) = 0;
13556
13557 /* Let the overlay arrow be updated the next time. */
13558 update_overlay_arrows (0);
13559
13560 /* If we pause after scrolling, some rows in the current
13561 matrices of some windows are not valid. */
13562 if (!WINDOW_FULL_WIDTH_P (w)
13563 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13564 update_mode_lines = 36;
13565 }
13566 else
13567 {
13568 if (!consider_all_windows_p)
13569 {
13570 /* This has already been done above if
13571 consider_all_windows_p is set. */
13572 if (XBUFFER (w->contents)->text->redisplay
13573 && buffer_window_count (XBUFFER (w->contents)) > 1)
13574 /* This can happen if b->text->redisplay was set during
13575 jit-lock. */
13576 propagate_buffer_redisplay ();
13577 mark_window_display_accurate_1 (w, 1);
13578
13579 /* Say overlay arrows are up to date. */
13580 update_overlay_arrows (1);
13581
13582 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13583 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13584 }
13585
13586 update_mode_lines = 0;
13587 windows_or_buffers_changed = 0;
13588 }
13589
13590 /* Start SIGIO interrupts coming again. Having them off during the
13591 code above makes it less likely one will discard output, but not
13592 impossible, since there might be stuff in the system buffer here.
13593 But it is much hairier to try to do anything about that. */
13594 if (interrupt_input)
13595 request_sigio ();
13596 RESUME_POLLING;
13597
13598 /* If a frame has become visible which was not before, redisplay
13599 again, so that we display it. Expose events for such a frame
13600 (which it gets when becoming visible) don't call the parts of
13601 redisplay constructing glyphs, so simply exposing a frame won't
13602 display anything in this case. So, we have to display these
13603 frames here explicitly. */
13604 if (!pending)
13605 {
13606 int new_count = 0;
13607
13608 FOR_EACH_FRAME (tail, frame)
13609 {
13610 if (XFRAME (frame)->visible)
13611 new_count++;
13612 }
13613
13614 if (new_count != number_of_visible_frames)
13615 windows_or_buffers_changed = 52;
13616 }
13617
13618 /* Change frame size now if a change is pending. */
13619 do_pending_window_change (1);
13620
13621 /* If we just did a pending size change, or have additional
13622 visible frames, or selected_window changed, redisplay again. */
13623 if ((windows_or_buffers_changed && !pending)
13624 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13625 goto retry;
13626
13627 /* Clear the face and image caches.
13628
13629 We used to do this only if consider_all_windows_p. But the cache
13630 needs to be cleared if a timer creates images in the current
13631 buffer (e.g. the test case in Bug#6230). */
13632
13633 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13634 {
13635 clear_face_cache (0);
13636 clear_face_cache_count = 0;
13637 }
13638
13639 #ifdef HAVE_WINDOW_SYSTEM
13640 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13641 {
13642 clear_image_caches (Qnil);
13643 clear_image_cache_count = 0;
13644 }
13645 #endif /* HAVE_WINDOW_SYSTEM */
13646
13647 end_of_redisplay:
13648 unbind_to (count, Qnil);
13649 RESUME_POLLING;
13650 }
13651
13652
13653 /* Redisplay, but leave alone any recent echo area message unless
13654 another message has been requested in its place.
13655
13656 This is useful in situations where you need to redisplay but no
13657 user action has occurred, making it inappropriate for the message
13658 area to be cleared. See tracking_off and
13659 wait_reading_process_output for examples of these situations.
13660
13661 FROM_WHERE is an integer saying from where this function was
13662 called. This is useful for debugging. */
13663
13664 void
13665 redisplay_preserve_echo_area (int from_where)
13666 {
13667 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13668
13669 if (!NILP (echo_area_buffer[1]))
13670 {
13671 /* We have a previously displayed message, but no current
13672 message. Redisplay the previous message. */
13673 display_last_displayed_message_p = 1;
13674 redisplay_internal ();
13675 display_last_displayed_message_p = 0;
13676 }
13677 else
13678 redisplay_internal ();
13679
13680 flush_frame (SELECTED_FRAME ());
13681 }
13682
13683
13684 /* Function registered with record_unwind_protect in redisplay_internal. */
13685
13686 static void
13687 unwind_redisplay (void)
13688 {
13689 redisplaying_p = 0;
13690 }
13691
13692
13693 /* Mark the display of leaf window W as accurate or inaccurate.
13694 If ACCURATE_P is non-zero mark display of W as accurate. If
13695 ACCURATE_P is zero, arrange for W to be redisplayed the next
13696 time redisplay_internal is called. */
13697
13698 static void
13699 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13700 {
13701 struct buffer *b = XBUFFER (w->contents);
13702
13703 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13704 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13705 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13706
13707 if (accurate_p)
13708 {
13709 b->clip_changed = false;
13710 b->prevent_redisplay_optimizations_p = false;
13711 eassert (buffer_window_count (b) > 0);
13712 /* Resetting b->text->redisplay is problematic!
13713 In order to make it safer to do it here, redisplay_internal must
13714 have copied all b->text->redisplay to their respective windows. */
13715 b->text->redisplay = false;
13716
13717 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13718 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13719 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13720 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13721
13722 w->current_matrix->buffer = b;
13723 w->current_matrix->begv = BUF_BEGV (b);
13724 w->current_matrix->zv = BUF_ZV (b);
13725
13726 w->last_cursor_vpos = w->cursor.vpos;
13727 w->last_cursor_off_p = w->cursor_off_p;
13728
13729 if (w == XWINDOW (selected_window))
13730 w->last_point = BUF_PT (b);
13731 else
13732 w->last_point = marker_position (w->pointm);
13733
13734 w->window_end_valid = true;
13735 w->update_mode_line = false;
13736 }
13737
13738 w->redisplay = !accurate_p;
13739 }
13740
13741
13742 /* Mark the display of windows in the window tree rooted at WINDOW as
13743 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13744 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13745 be redisplayed the next time redisplay_internal is called. */
13746
13747 void
13748 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13749 {
13750 struct window *w;
13751
13752 for (; !NILP (window); window = w->next)
13753 {
13754 w = XWINDOW (window);
13755 if (WINDOWP (w->contents))
13756 mark_window_display_accurate (w->contents, accurate_p);
13757 else
13758 mark_window_display_accurate_1 (w, accurate_p);
13759 }
13760
13761 if (accurate_p)
13762 update_overlay_arrows (1);
13763 else
13764 /* Force a thorough redisplay the next time by setting
13765 last_arrow_position and last_arrow_string to t, which is
13766 unequal to any useful value of Voverlay_arrow_... */
13767 update_overlay_arrows (-1);
13768 }
13769
13770
13771 /* Return value in display table DP (Lisp_Char_Table *) for character
13772 C. Since a display table doesn't have any parent, we don't have to
13773 follow parent. Do not call this function directly but use the
13774 macro DISP_CHAR_VECTOR. */
13775
13776 Lisp_Object
13777 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13778 {
13779 Lisp_Object val;
13780
13781 if (ASCII_CHAR_P (c))
13782 {
13783 val = dp->ascii;
13784 if (SUB_CHAR_TABLE_P (val))
13785 val = XSUB_CHAR_TABLE (val)->contents[c];
13786 }
13787 else
13788 {
13789 Lisp_Object table;
13790
13791 XSETCHAR_TABLE (table, dp);
13792 val = char_table_ref (table, c);
13793 }
13794 if (NILP (val))
13795 val = dp->defalt;
13796 return val;
13797 }
13798
13799
13800 \f
13801 /***********************************************************************
13802 Window Redisplay
13803 ***********************************************************************/
13804
13805 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13806
13807 static void
13808 redisplay_windows (Lisp_Object window)
13809 {
13810 while (!NILP (window))
13811 {
13812 struct window *w = XWINDOW (window);
13813
13814 if (WINDOWP (w->contents))
13815 redisplay_windows (w->contents);
13816 else if (BUFFERP (w->contents))
13817 {
13818 displayed_buffer = XBUFFER (w->contents);
13819 /* Use list_of_error, not Qerror, so that
13820 we catch only errors and don't run the debugger. */
13821 internal_condition_case_1 (redisplay_window_0, window,
13822 list_of_error,
13823 redisplay_window_error);
13824 }
13825
13826 window = w->next;
13827 }
13828 }
13829
13830 static Lisp_Object
13831 redisplay_window_error (Lisp_Object ignore)
13832 {
13833 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13834 return Qnil;
13835 }
13836
13837 static Lisp_Object
13838 redisplay_window_0 (Lisp_Object window)
13839 {
13840 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13841 redisplay_window (window, 0);
13842 return Qnil;
13843 }
13844
13845 static Lisp_Object
13846 redisplay_window_1 (Lisp_Object window)
13847 {
13848 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13849 redisplay_window (window, 1);
13850 return Qnil;
13851 }
13852 \f
13853
13854 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13855 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13856 which positions recorded in ROW differ from current buffer
13857 positions.
13858
13859 Return 0 if cursor is not on this row, 1 otherwise. */
13860
13861 static int
13862 set_cursor_from_row (struct window *w, struct glyph_row *row,
13863 struct glyph_matrix *matrix,
13864 ptrdiff_t delta, ptrdiff_t delta_bytes,
13865 int dy, int dvpos)
13866 {
13867 struct glyph *glyph = row->glyphs[TEXT_AREA];
13868 struct glyph *end = glyph + row->used[TEXT_AREA];
13869 struct glyph *cursor = NULL;
13870 /* The last known character position in row. */
13871 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13872 int x = row->x;
13873 ptrdiff_t pt_old = PT - delta;
13874 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13875 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13876 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13877 /* A glyph beyond the edge of TEXT_AREA which we should never
13878 touch. */
13879 struct glyph *glyphs_end = end;
13880 /* Non-zero means we've found a match for cursor position, but that
13881 glyph has the avoid_cursor_p flag set. */
13882 int match_with_avoid_cursor = 0;
13883 /* Non-zero means we've seen at least one glyph that came from a
13884 display string. */
13885 int string_seen = 0;
13886 /* Largest and smallest buffer positions seen so far during scan of
13887 glyph row. */
13888 ptrdiff_t bpos_max = pos_before;
13889 ptrdiff_t bpos_min = pos_after;
13890 /* Last buffer position covered by an overlay string with an integer
13891 `cursor' property. */
13892 ptrdiff_t bpos_covered = 0;
13893 /* Non-zero means the display string on which to display the cursor
13894 comes from a text property, not from an overlay. */
13895 int string_from_text_prop = 0;
13896
13897 /* Don't even try doing anything if called for a mode-line or
13898 header-line row, since the rest of the code isn't prepared to
13899 deal with such calamities. */
13900 eassert (!row->mode_line_p);
13901 if (row->mode_line_p)
13902 return 0;
13903
13904 /* Skip over glyphs not having an object at the start and the end of
13905 the row. These are special glyphs like truncation marks on
13906 terminal frames. */
13907 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13908 {
13909 if (!row->reversed_p)
13910 {
13911 while (glyph < end
13912 && INTEGERP (glyph->object)
13913 && glyph->charpos < 0)
13914 {
13915 x += glyph->pixel_width;
13916 ++glyph;
13917 }
13918 while (end > glyph
13919 && INTEGERP ((end - 1)->object)
13920 /* CHARPOS is zero for blanks and stretch glyphs
13921 inserted by extend_face_to_end_of_line. */
13922 && (end - 1)->charpos <= 0)
13923 --end;
13924 glyph_before = glyph - 1;
13925 glyph_after = end;
13926 }
13927 else
13928 {
13929 struct glyph *g;
13930
13931 /* If the glyph row is reversed, we need to process it from back
13932 to front, so swap the edge pointers. */
13933 glyphs_end = end = glyph - 1;
13934 glyph += row->used[TEXT_AREA] - 1;
13935
13936 while (glyph > end + 1
13937 && INTEGERP (glyph->object)
13938 && glyph->charpos < 0)
13939 {
13940 --glyph;
13941 x -= glyph->pixel_width;
13942 }
13943 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13944 --glyph;
13945 /* By default, in reversed rows we put the cursor on the
13946 rightmost (first in the reading order) glyph. */
13947 for (g = end + 1; g < glyph; g++)
13948 x += g->pixel_width;
13949 while (end < glyph
13950 && INTEGERP ((end + 1)->object)
13951 && (end + 1)->charpos <= 0)
13952 ++end;
13953 glyph_before = glyph + 1;
13954 glyph_after = end;
13955 }
13956 }
13957 else if (row->reversed_p)
13958 {
13959 /* In R2L rows that don't display text, put the cursor on the
13960 rightmost glyph. Case in point: an empty last line that is
13961 part of an R2L paragraph. */
13962 cursor = end - 1;
13963 /* Avoid placing the cursor on the last glyph of the row, where
13964 on terminal frames we hold the vertical border between
13965 adjacent windows. */
13966 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13967 && !WINDOW_RIGHTMOST_P (w)
13968 && cursor == row->glyphs[LAST_AREA] - 1)
13969 cursor--;
13970 x = -1; /* will be computed below, at label compute_x */
13971 }
13972
13973 /* Step 1: Try to find the glyph whose character position
13974 corresponds to point. If that's not possible, find 2 glyphs
13975 whose character positions are the closest to point, one before
13976 point, the other after it. */
13977 if (!row->reversed_p)
13978 while (/* not marched to end of glyph row */
13979 glyph < end
13980 /* glyph was not inserted by redisplay for internal purposes */
13981 && !INTEGERP (glyph->object))
13982 {
13983 if (BUFFERP (glyph->object))
13984 {
13985 ptrdiff_t dpos = glyph->charpos - pt_old;
13986
13987 if (glyph->charpos > bpos_max)
13988 bpos_max = glyph->charpos;
13989 if (glyph->charpos < bpos_min)
13990 bpos_min = glyph->charpos;
13991 if (!glyph->avoid_cursor_p)
13992 {
13993 /* If we hit point, we've found the glyph on which to
13994 display the cursor. */
13995 if (dpos == 0)
13996 {
13997 match_with_avoid_cursor = 0;
13998 break;
13999 }
14000 /* See if we've found a better approximation to
14001 POS_BEFORE or to POS_AFTER. */
14002 if (0 > dpos && dpos > pos_before - pt_old)
14003 {
14004 pos_before = glyph->charpos;
14005 glyph_before = glyph;
14006 }
14007 else if (0 < dpos && dpos < pos_after - pt_old)
14008 {
14009 pos_after = glyph->charpos;
14010 glyph_after = glyph;
14011 }
14012 }
14013 else if (dpos == 0)
14014 match_with_avoid_cursor = 1;
14015 }
14016 else if (STRINGP (glyph->object))
14017 {
14018 Lisp_Object chprop;
14019 ptrdiff_t glyph_pos = glyph->charpos;
14020
14021 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14022 glyph->object);
14023 if (!NILP (chprop))
14024 {
14025 /* If the string came from a `display' text property,
14026 look up the buffer position of that property and
14027 use that position to update bpos_max, as if we
14028 actually saw such a position in one of the row's
14029 glyphs. This helps with supporting integer values
14030 of `cursor' property on the display string in
14031 situations where most or all of the row's buffer
14032 text is completely covered by display properties,
14033 so that no glyph with valid buffer positions is
14034 ever seen in the row. */
14035 ptrdiff_t prop_pos =
14036 string_buffer_position_lim (glyph->object, pos_before,
14037 pos_after, 0);
14038
14039 if (prop_pos >= pos_before)
14040 bpos_max = prop_pos - 1;
14041 }
14042 if (INTEGERP (chprop))
14043 {
14044 bpos_covered = bpos_max + XINT (chprop);
14045 /* If the `cursor' property covers buffer positions up
14046 to and including point, we should display cursor on
14047 this glyph. Note that, if a `cursor' property on one
14048 of the string's characters has an integer value, we
14049 will break out of the loop below _before_ we get to
14050 the position match above. IOW, integer values of
14051 the `cursor' property override the "exact match for
14052 point" strategy of positioning the cursor. */
14053 /* Implementation note: bpos_max == pt_old when, e.g.,
14054 we are in an empty line, where bpos_max is set to
14055 MATRIX_ROW_START_CHARPOS, see above. */
14056 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14057 {
14058 cursor = glyph;
14059 break;
14060 }
14061 }
14062
14063 string_seen = 1;
14064 }
14065 x += glyph->pixel_width;
14066 ++glyph;
14067 }
14068 else if (glyph > end) /* row is reversed */
14069 while (!INTEGERP (glyph->object))
14070 {
14071 if (BUFFERP (glyph->object))
14072 {
14073 ptrdiff_t dpos = glyph->charpos - pt_old;
14074
14075 if (glyph->charpos > bpos_max)
14076 bpos_max = glyph->charpos;
14077 if (glyph->charpos < bpos_min)
14078 bpos_min = glyph->charpos;
14079 if (!glyph->avoid_cursor_p)
14080 {
14081 if (dpos == 0)
14082 {
14083 match_with_avoid_cursor = 0;
14084 break;
14085 }
14086 if (0 > dpos && dpos > pos_before - pt_old)
14087 {
14088 pos_before = glyph->charpos;
14089 glyph_before = glyph;
14090 }
14091 else if (0 < dpos && dpos < pos_after - pt_old)
14092 {
14093 pos_after = glyph->charpos;
14094 glyph_after = glyph;
14095 }
14096 }
14097 else if (dpos == 0)
14098 match_with_avoid_cursor = 1;
14099 }
14100 else if (STRINGP (glyph->object))
14101 {
14102 Lisp_Object chprop;
14103 ptrdiff_t glyph_pos = glyph->charpos;
14104
14105 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14106 glyph->object);
14107 if (!NILP (chprop))
14108 {
14109 ptrdiff_t prop_pos =
14110 string_buffer_position_lim (glyph->object, pos_before,
14111 pos_after, 0);
14112
14113 if (prop_pos >= pos_before)
14114 bpos_max = prop_pos - 1;
14115 }
14116 if (INTEGERP (chprop))
14117 {
14118 bpos_covered = bpos_max + XINT (chprop);
14119 /* If the `cursor' property covers buffer positions up
14120 to and including point, we should display cursor on
14121 this glyph. */
14122 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14123 {
14124 cursor = glyph;
14125 break;
14126 }
14127 }
14128 string_seen = 1;
14129 }
14130 --glyph;
14131 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14132 {
14133 x--; /* can't use any pixel_width */
14134 break;
14135 }
14136 x -= glyph->pixel_width;
14137 }
14138
14139 /* Step 2: If we didn't find an exact match for point, we need to
14140 look for a proper place to put the cursor among glyphs between
14141 GLYPH_BEFORE and GLYPH_AFTER. */
14142 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14143 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14144 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14145 {
14146 /* An empty line has a single glyph whose OBJECT is zero and
14147 whose CHARPOS is the position of a newline on that line.
14148 Note that on a TTY, there are more glyphs after that, which
14149 were produced by extend_face_to_end_of_line, but their
14150 CHARPOS is zero or negative. */
14151 int empty_line_p =
14152 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14153 && INTEGERP (glyph->object) && glyph->charpos > 0
14154 /* On a TTY, continued and truncated rows also have a glyph at
14155 their end whose OBJECT is zero and whose CHARPOS is
14156 positive (the continuation and truncation glyphs), but such
14157 rows are obviously not "empty". */
14158 && !(row->continued_p || row->truncated_on_right_p);
14159
14160 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14161 {
14162 ptrdiff_t ellipsis_pos;
14163
14164 /* Scan back over the ellipsis glyphs. */
14165 if (!row->reversed_p)
14166 {
14167 ellipsis_pos = (glyph - 1)->charpos;
14168 while (glyph > row->glyphs[TEXT_AREA]
14169 && (glyph - 1)->charpos == ellipsis_pos)
14170 glyph--, x -= glyph->pixel_width;
14171 /* That loop always goes one position too far, including
14172 the glyph before the ellipsis. So scan forward over
14173 that one. */
14174 x += glyph->pixel_width;
14175 glyph++;
14176 }
14177 else /* row is reversed */
14178 {
14179 ellipsis_pos = (glyph + 1)->charpos;
14180 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14181 && (glyph + 1)->charpos == ellipsis_pos)
14182 glyph++, x += glyph->pixel_width;
14183 x -= glyph->pixel_width;
14184 glyph--;
14185 }
14186 }
14187 else if (match_with_avoid_cursor)
14188 {
14189 cursor = glyph_after;
14190 x = -1;
14191 }
14192 else if (string_seen)
14193 {
14194 int incr = row->reversed_p ? -1 : +1;
14195
14196 /* Need to find the glyph that came out of a string which is
14197 present at point. That glyph is somewhere between
14198 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14199 positioned between POS_BEFORE and POS_AFTER in the
14200 buffer. */
14201 struct glyph *start, *stop;
14202 ptrdiff_t pos = pos_before;
14203
14204 x = -1;
14205
14206 /* If the row ends in a newline from a display string,
14207 reordering could have moved the glyphs belonging to the
14208 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14209 in this case we extend the search to the last glyph in
14210 the row that was not inserted by redisplay. */
14211 if (row->ends_in_newline_from_string_p)
14212 {
14213 glyph_after = end;
14214 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14215 }
14216
14217 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14218 correspond to POS_BEFORE and POS_AFTER, respectively. We
14219 need START and STOP in the order that corresponds to the
14220 row's direction as given by its reversed_p flag. If the
14221 directionality of characters between POS_BEFORE and
14222 POS_AFTER is the opposite of the row's base direction,
14223 these characters will have been reordered for display,
14224 and we need to reverse START and STOP. */
14225 if (!row->reversed_p)
14226 {
14227 start = min (glyph_before, glyph_after);
14228 stop = max (glyph_before, glyph_after);
14229 }
14230 else
14231 {
14232 start = max (glyph_before, glyph_after);
14233 stop = min (glyph_before, glyph_after);
14234 }
14235 for (glyph = start + incr;
14236 row->reversed_p ? glyph > stop : glyph < stop; )
14237 {
14238
14239 /* Any glyphs that come from the buffer are here because
14240 of bidi reordering. Skip them, and only pay
14241 attention to glyphs that came from some string. */
14242 if (STRINGP (glyph->object))
14243 {
14244 Lisp_Object str;
14245 ptrdiff_t tem;
14246 /* If the display property covers the newline, we
14247 need to search for it one position farther. */
14248 ptrdiff_t lim = pos_after
14249 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14250
14251 string_from_text_prop = 0;
14252 str = glyph->object;
14253 tem = string_buffer_position_lim (str, pos, lim, 0);
14254 if (tem == 0 /* from overlay */
14255 || pos <= tem)
14256 {
14257 /* If the string from which this glyph came is
14258 found in the buffer at point, or at position
14259 that is closer to point than pos_after, then
14260 we've found the glyph we've been looking for.
14261 If it comes from an overlay (tem == 0), and
14262 it has the `cursor' property on one of its
14263 glyphs, record that glyph as a candidate for
14264 displaying the cursor. (As in the
14265 unidirectional version, we will display the
14266 cursor on the last candidate we find.) */
14267 if (tem == 0
14268 || tem == pt_old
14269 || (tem - pt_old > 0 && tem < pos_after))
14270 {
14271 /* The glyphs from this string could have
14272 been reordered. Find the one with the
14273 smallest string position. Or there could
14274 be a character in the string with the
14275 `cursor' property, which means display
14276 cursor on that character's glyph. */
14277 ptrdiff_t strpos = glyph->charpos;
14278
14279 if (tem)
14280 {
14281 cursor = glyph;
14282 string_from_text_prop = 1;
14283 }
14284 for ( ;
14285 (row->reversed_p ? glyph > stop : glyph < stop)
14286 && EQ (glyph->object, str);
14287 glyph += incr)
14288 {
14289 Lisp_Object cprop;
14290 ptrdiff_t gpos = glyph->charpos;
14291
14292 cprop = Fget_char_property (make_number (gpos),
14293 Qcursor,
14294 glyph->object);
14295 if (!NILP (cprop))
14296 {
14297 cursor = glyph;
14298 break;
14299 }
14300 if (tem && glyph->charpos < strpos)
14301 {
14302 strpos = glyph->charpos;
14303 cursor = glyph;
14304 }
14305 }
14306
14307 if (tem == pt_old
14308 || (tem - pt_old > 0 && tem < pos_after))
14309 goto compute_x;
14310 }
14311 if (tem)
14312 pos = tem + 1; /* don't find previous instances */
14313 }
14314 /* This string is not what we want; skip all of the
14315 glyphs that came from it. */
14316 while ((row->reversed_p ? glyph > stop : glyph < stop)
14317 && EQ (glyph->object, str))
14318 glyph += incr;
14319 }
14320 else
14321 glyph += incr;
14322 }
14323
14324 /* If we reached the end of the line, and END was from a string,
14325 the cursor is not on this line. */
14326 if (cursor == NULL
14327 && (row->reversed_p ? glyph <= end : glyph >= end)
14328 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14329 && STRINGP (end->object)
14330 && row->continued_p)
14331 return 0;
14332 }
14333 /* A truncated row may not include PT among its character positions.
14334 Setting the cursor inside the scroll margin will trigger
14335 recalculation of hscroll in hscroll_window_tree. But if a
14336 display string covers point, defer to the string-handling
14337 code below to figure this out. */
14338 else if (row->truncated_on_left_p && pt_old < bpos_min)
14339 {
14340 cursor = glyph_before;
14341 x = -1;
14342 }
14343 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14344 /* Zero-width characters produce no glyphs. */
14345 || (!empty_line_p
14346 && (row->reversed_p
14347 ? glyph_after > glyphs_end
14348 : glyph_after < glyphs_end)))
14349 {
14350 cursor = glyph_after;
14351 x = -1;
14352 }
14353 }
14354
14355 compute_x:
14356 if (cursor != NULL)
14357 glyph = cursor;
14358 else if (glyph == glyphs_end
14359 && pos_before == pos_after
14360 && STRINGP ((row->reversed_p
14361 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14362 : row->glyphs[TEXT_AREA])->object))
14363 {
14364 /* If all the glyphs of this row came from strings, put the
14365 cursor on the first glyph of the row. This avoids having the
14366 cursor outside of the text area in this very rare and hard
14367 use case. */
14368 glyph =
14369 row->reversed_p
14370 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14371 : row->glyphs[TEXT_AREA];
14372 }
14373 if (x < 0)
14374 {
14375 struct glyph *g;
14376
14377 /* Need to compute x that corresponds to GLYPH. */
14378 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14379 {
14380 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14381 emacs_abort ();
14382 x += g->pixel_width;
14383 }
14384 }
14385
14386 /* ROW could be part of a continued line, which, under bidi
14387 reordering, might have other rows whose start and end charpos
14388 occlude point. Only set w->cursor if we found a better
14389 approximation to the cursor position than we have from previously
14390 examined candidate rows belonging to the same continued line. */
14391 if (/* We already have a candidate row. */
14392 w->cursor.vpos >= 0
14393 /* That candidate is not the row we are processing. */
14394 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14395 /* Make sure cursor.vpos specifies a row whose start and end
14396 charpos occlude point, and it is valid candidate for being a
14397 cursor-row. This is because some callers of this function
14398 leave cursor.vpos at the row where the cursor was displayed
14399 during the last redisplay cycle. */
14400 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14401 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14402 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14403 {
14404 struct glyph *g1
14405 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14406
14407 /* Don't consider glyphs that are outside TEXT_AREA. */
14408 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14409 return 0;
14410 /* Keep the candidate whose buffer position is the closest to
14411 point or has the `cursor' property. */
14412 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
14413 w->cursor.hpos >= 0
14414 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14415 && ((BUFFERP (g1->object)
14416 && (g1->charpos == pt_old /* An exact match always wins. */
14417 || (BUFFERP (glyph->object)
14418 && eabs (g1->charpos - pt_old)
14419 < eabs (glyph->charpos - pt_old))))
14420 /* Previous candidate is a glyph from a string that has
14421 a non-nil `cursor' property. */
14422 || (STRINGP (g1->object)
14423 && (!NILP (Fget_char_property (make_number (g1->charpos),
14424 Qcursor, g1->object))
14425 /* Previous candidate is from the same display
14426 string as this one, and the display string
14427 came from a text property. */
14428 || (EQ (g1->object, glyph->object)
14429 && string_from_text_prop)
14430 /* this candidate is from newline and its
14431 position is not an exact match */
14432 || (INTEGERP (glyph->object)
14433 && glyph->charpos != pt_old)))))
14434 return 0;
14435 /* If this candidate gives an exact match, use that. */
14436 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14437 /* If this candidate is a glyph created for the
14438 terminating newline of a line, and point is on that
14439 newline, it wins because it's an exact match. */
14440 || (!row->continued_p
14441 && INTEGERP (glyph->object)
14442 && glyph->charpos == 0
14443 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14444 /* Otherwise, keep the candidate that comes from a row
14445 spanning less buffer positions. This may win when one or
14446 both candidate positions are on glyphs that came from
14447 display strings, for which we cannot compare buffer
14448 positions. */
14449 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14450 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14451 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14452 return 0;
14453 }
14454 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14455 w->cursor.x = x;
14456 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14457 w->cursor.y = row->y + dy;
14458
14459 if (w == XWINDOW (selected_window))
14460 {
14461 if (!row->continued_p
14462 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14463 && row->x == 0)
14464 {
14465 this_line_buffer = XBUFFER (w->contents);
14466
14467 CHARPOS (this_line_start_pos)
14468 = MATRIX_ROW_START_CHARPOS (row) + delta;
14469 BYTEPOS (this_line_start_pos)
14470 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14471
14472 CHARPOS (this_line_end_pos)
14473 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14474 BYTEPOS (this_line_end_pos)
14475 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14476
14477 this_line_y = w->cursor.y;
14478 this_line_pixel_height = row->height;
14479 this_line_vpos = w->cursor.vpos;
14480 this_line_start_x = row->x;
14481 }
14482 else
14483 CHARPOS (this_line_start_pos) = 0;
14484 }
14485
14486 return 1;
14487 }
14488
14489
14490 /* Run window scroll functions, if any, for WINDOW with new window
14491 start STARTP. Sets the window start of WINDOW to that position.
14492
14493 We assume that the window's buffer is really current. */
14494
14495 static struct text_pos
14496 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14497 {
14498 struct window *w = XWINDOW (window);
14499 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14500
14501 eassert (current_buffer == XBUFFER (w->contents));
14502
14503 if (!NILP (Vwindow_scroll_functions))
14504 {
14505 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14506 make_number (CHARPOS (startp)));
14507 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14508 /* In case the hook functions switch buffers. */
14509 set_buffer_internal (XBUFFER (w->contents));
14510 }
14511
14512 return startp;
14513 }
14514
14515
14516 /* Make sure the line containing the cursor is fully visible.
14517 A value of 1 means there is nothing to be done.
14518 (Either the line is fully visible, or it cannot be made so,
14519 or we cannot tell.)
14520
14521 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14522 is higher than window.
14523
14524 A value of 0 means the caller should do scrolling
14525 as if point had gone off the screen. */
14526
14527 static int
14528 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14529 {
14530 struct glyph_matrix *matrix;
14531 struct glyph_row *row;
14532 int window_height;
14533
14534 if (!make_cursor_line_fully_visible_p)
14535 return 1;
14536
14537 /* It's not always possible to find the cursor, e.g, when a window
14538 is full of overlay strings. Don't do anything in that case. */
14539 if (w->cursor.vpos < 0)
14540 return 1;
14541
14542 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14543 row = MATRIX_ROW (matrix, w->cursor.vpos);
14544
14545 /* If the cursor row is not partially visible, there's nothing to do. */
14546 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14547 return 1;
14548
14549 /* If the row the cursor is in is taller than the window's height,
14550 it's not clear what to do, so do nothing. */
14551 window_height = window_box_height (w);
14552 if (row->height >= window_height)
14553 {
14554 if (!force_p || MINI_WINDOW_P (w)
14555 || w->vscroll || w->cursor.vpos == 0)
14556 return 1;
14557 }
14558 return 0;
14559 }
14560
14561
14562 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14563 non-zero means only WINDOW is redisplayed in redisplay_internal.
14564 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14565 in redisplay_window to bring a partially visible line into view in
14566 the case that only the cursor has moved.
14567
14568 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14569 last screen line's vertical height extends past the end of the screen.
14570
14571 Value is
14572
14573 1 if scrolling succeeded
14574
14575 0 if scrolling didn't find point.
14576
14577 -1 if new fonts have been loaded so that we must interrupt
14578 redisplay, adjust glyph matrices, and try again. */
14579
14580 enum
14581 {
14582 SCROLLING_SUCCESS,
14583 SCROLLING_FAILED,
14584 SCROLLING_NEED_LARGER_MATRICES
14585 };
14586
14587 /* If scroll-conservatively is more than this, never recenter.
14588
14589 If you change this, don't forget to update the doc string of
14590 `scroll-conservatively' and the Emacs manual. */
14591 #define SCROLL_LIMIT 100
14592
14593 static int
14594 try_scrolling (Lisp_Object window, int just_this_one_p,
14595 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14596 int temp_scroll_step, int last_line_misfit)
14597 {
14598 struct window *w = XWINDOW (window);
14599 struct frame *f = XFRAME (w->frame);
14600 struct text_pos pos, startp;
14601 struct it it;
14602 int this_scroll_margin, scroll_max, rc, height;
14603 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14604 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14605 Lisp_Object aggressive;
14606 /* We will never try scrolling more than this number of lines. */
14607 int scroll_limit = SCROLL_LIMIT;
14608 int frame_line_height = default_line_pixel_height (w);
14609 int window_total_lines
14610 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
14611
14612 #ifdef GLYPH_DEBUG
14613 debug_method_add (w, "try_scrolling");
14614 #endif
14615
14616 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14617
14618 /* Compute scroll margin height in pixels. We scroll when point is
14619 within this distance from the top or bottom of the window. */
14620 if (scroll_margin > 0)
14621 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
14622 * frame_line_height;
14623 else
14624 this_scroll_margin = 0;
14625
14626 /* Force arg_scroll_conservatively to have a reasonable value, to
14627 avoid scrolling too far away with slow move_it_* functions. Note
14628 that the user can supply scroll-conservatively equal to
14629 `most-positive-fixnum', which can be larger than INT_MAX. */
14630 if (arg_scroll_conservatively > scroll_limit)
14631 {
14632 arg_scroll_conservatively = scroll_limit + 1;
14633 scroll_max = scroll_limit * frame_line_height;
14634 }
14635 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14636 /* Compute how much we should try to scroll maximally to bring
14637 point into view. */
14638 scroll_max = (max (scroll_step,
14639 max (arg_scroll_conservatively, temp_scroll_step))
14640 * frame_line_height);
14641 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14642 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14643 /* We're trying to scroll because of aggressive scrolling but no
14644 scroll_step is set. Choose an arbitrary one. */
14645 scroll_max = 10 * frame_line_height;
14646 else
14647 scroll_max = 0;
14648
14649 too_near_end:
14650
14651 /* Decide whether to scroll down. */
14652 if (PT > CHARPOS (startp))
14653 {
14654 int scroll_margin_y;
14655
14656 /* Compute the pixel ypos of the scroll margin, then move IT to
14657 either that ypos or PT, whichever comes first. */
14658 start_display (&it, w, startp);
14659 scroll_margin_y = it.last_visible_y - this_scroll_margin
14660 - frame_line_height * extra_scroll_margin_lines;
14661 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14662 (MOVE_TO_POS | MOVE_TO_Y));
14663
14664 if (PT > CHARPOS (it.current.pos))
14665 {
14666 int y0 = line_bottom_y (&it);
14667 /* Compute how many pixels below window bottom to stop searching
14668 for PT. This avoids costly search for PT that is far away if
14669 the user limited scrolling by a small number of lines, but
14670 always finds PT if scroll_conservatively is set to a large
14671 number, such as most-positive-fixnum. */
14672 int slack = max (scroll_max, 10 * frame_line_height);
14673 int y_to_move = it.last_visible_y + slack;
14674
14675 /* Compute the distance from the scroll margin to PT or to
14676 the scroll limit, whichever comes first. This should
14677 include the height of the cursor line, to make that line
14678 fully visible. */
14679 move_it_to (&it, PT, -1, y_to_move,
14680 -1, MOVE_TO_POS | MOVE_TO_Y);
14681 dy = line_bottom_y (&it) - y0;
14682
14683 if (dy > scroll_max)
14684 return SCROLLING_FAILED;
14685
14686 if (dy > 0)
14687 scroll_down_p = 1;
14688 }
14689 }
14690
14691 if (scroll_down_p)
14692 {
14693 /* Point is in or below the bottom scroll margin, so move the
14694 window start down. If scrolling conservatively, move it just
14695 enough down to make point visible. If scroll_step is set,
14696 move it down by scroll_step. */
14697 if (arg_scroll_conservatively)
14698 amount_to_scroll
14699 = min (max (dy, frame_line_height),
14700 frame_line_height * arg_scroll_conservatively);
14701 else if (scroll_step || temp_scroll_step)
14702 amount_to_scroll = scroll_max;
14703 else
14704 {
14705 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14706 height = WINDOW_BOX_TEXT_HEIGHT (w);
14707 if (NUMBERP (aggressive))
14708 {
14709 double float_amount = XFLOATINT (aggressive) * height;
14710 int aggressive_scroll = float_amount;
14711 if (aggressive_scroll == 0 && float_amount > 0)
14712 aggressive_scroll = 1;
14713 /* Don't let point enter the scroll margin near top of
14714 the window. This could happen if the value of
14715 scroll_up_aggressively is too large and there are
14716 non-zero margins, because scroll_up_aggressively
14717 means put point that fraction of window height
14718 _from_the_bottom_margin_. */
14719 if (aggressive_scroll + 2*this_scroll_margin > height)
14720 aggressive_scroll = height - 2*this_scroll_margin;
14721 amount_to_scroll = dy + aggressive_scroll;
14722 }
14723 }
14724
14725 if (amount_to_scroll <= 0)
14726 return SCROLLING_FAILED;
14727
14728 start_display (&it, w, startp);
14729 if (arg_scroll_conservatively <= scroll_limit)
14730 move_it_vertically (&it, amount_to_scroll);
14731 else
14732 {
14733 /* Extra precision for users who set scroll-conservatively
14734 to a large number: make sure the amount we scroll
14735 the window start is never less than amount_to_scroll,
14736 which was computed as distance from window bottom to
14737 point. This matters when lines at window top and lines
14738 below window bottom have different height. */
14739 struct it it1;
14740 void *it1data = NULL;
14741 /* We use a temporary it1 because line_bottom_y can modify
14742 its argument, if it moves one line down; see there. */
14743 int start_y;
14744
14745 SAVE_IT (it1, it, it1data);
14746 start_y = line_bottom_y (&it1);
14747 do {
14748 RESTORE_IT (&it, &it, it1data);
14749 move_it_by_lines (&it, 1);
14750 SAVE_IT (it1, it, it1data);
14751 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14752 }
14753
14754 /* If STARTP is unchanged, move it down another screen line. */
14755 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14756 move_it_by_lines (&it, 1);
14757 startp = it.current.pos;
14758 }
14759 else
14760 {
14761 struct text_pos scroll_margin_pos = startp;
14762 int y_offset = 0;
14763
14764 /* See if point is inside the scroll margin at the top of the
14765 window. */
14766 if (this_scroll_margin)
14767 {
14768 int y_start;
14769
14770 start_display (&it, w, startp);
14771 y_start = it.current_y;
14772 move_it_vertically (&it, this_scroll_margin);
14773 scroll_margin_pos = it.current.pos;
14774 /* If we didn't move enough before hitting ZV, request
14775 additional amount of scroll, to move point out of the
14776 scroll margin. */
14777 if (IT_CHARPOS (it) == ZV
14778 && it.current_y - y_start < this_scroll_margin)
14779 y_offset = this_scroll_margin - (it.current_y - y_start);
14780 }
14781
14782 if (PT < CHARPOS (scroll_margin_pos))
14783 {
14784 /* Point is in the scroll margin at the top of the window or
14785 above what is displayed in the window. */
14786 int y0, y_to_move;
14787
14788 /* Compute the vertical distance from PT to the scroll
14789 margin position. Move as far as scroll_max allows, or
14790 one screenful, or 10 screen lines, whichever is largest.
14791 Give up if distance is greater than scroll_max or if we
14792 didn't reach the scroll margin position. */
14793 SET_TEXT_POS (pos, PT, PT_BYTE);
14794 start_display (&it, w, pos);
14795 y0 = it.current_y;
14796 y_to_move = max (it.last_visible_y,
14797 max (scroll_max, 10 * frame_line_height));
14798 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14799 y_to_move, -1,
14800 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14801 dy = it.current_y - y0;
14802 if (dy > scroll_max
14803 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14804 return SCROLLING_FAILED;
14805
14806 /* Additional scroll for when ZV was too close to point. */
14807 dy += y_offset;
14808
14809 /* Compute new window start. */
14810 start_display (&it, w, startp);
14811
14812 if (arg_scroll_conservatively)
14813 amount_to_scroll = max (dy, frame_line_height *
14814 max (scroll_step, temp_scroll_step));
14815 else if (scroll_step || temp_scroll_step)
14816 amount_to_scroll = scroll_max;
14817 else
14818 {
14819 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14820 height = WINDOW_BOX_TEXT_HEIGHT (w);
14821 if (NUMBERP (aggressive))
14822 {
14823 double float_amount = XFLOATINT (aggressive) * height;
14824 int aggressive_scroll = float_amount;
14825 if (aggressive_scroll == 0 && float_amount > 0)
14826 aggressive_scroll = 1;
14827 /* Don't let point enter the scroll margin near
14828 bottom of the window, if the value of
14829 scroll_down_aggressively happens to be too
14830 large. */
14831 if (aggressive_scroll + 2*this_scroll_margin > height)
14832 aggressive_scroll = height - 2*this_scroll_margin;
14833 amount_to_scroll = dy + aggressive_scroll;
14834 }
14835 }
14836
14837 if (amount_to_scroll <= 0)
14838 return SCROLLING_FAILED;
14839
14840 move_it_vertically_backward (&it, amount_to_scroll);
14841 startp = it.current.pos;
14842 }
14843 }
14844
14845 /* Run window scroll functions. */
14846 startp = run_window_scroll_functions (window, startp);
14847
14848 /* Display the window. Give up if new fonts are loaded, or if point
14849 doesn't appear. */
14850 if (!try_window (window, startp, 0))
14851 rc = SCROLLING_NEED_LARGER_MATRICES;
14852 else if (w->cursor.vpos < 0)
14853 {
14854 clear_glyph_matrix (w->desired_matrix);
14855 rc = SCROLLING_FAILED;
14856 }
14857 else
14858 {
14859 /* Maybe forget recorded base line for line number display. */
14860 if (!just_this_one_p
14861 || current_buffer->clip_changed
14862 || BEG_UNCHANGED < CHARPOS (startp))
14863 w->base_line_number = 0;
14864
14865 /* If cursor ends up on a partially visible line,
14866 treat that as being off the bottom of the screen. */
14867 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14868 /* It's possible that the cursor is on the first line of the
14869 buffer, which is partially obscured due to a vscroll
14870 (Bug#7537). In that case, avoid looping forever . */
14871 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14872 {
14873 clear_glyph_matrix (w->desired_matrix);
14874 ++extra_scroll_margin_lines;
14875 goto too_near_end;
14876 }
14877 rc = SCROLLING_SUCCESS;
14878 }
14879
14880 return rc;
14881 }
14882
14883
14884 /* Compute a suitable window start for window W if display of W starts
14885 on a continuation line. Value is non-zero if a new window start
14886 was computed.
14887
14888 The new window start will be computed, based on W's width, starting
14889 from the start of the continued line. It is the start of the
14890 screen line with the minimum distance from the old start W->start. */
14891
14892 static int
14893 compute_window_start_on_continuation_line (struct window *w)
14894 {
14895 struct text_pos pos, start_pos;
14896 int window_start_changed_p = 0;
14897
14898 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14899
14900 /* If window start is on a continuation line... Window start may be
14901 < BEGV in case there's invisible text at the start of the
14902 buffer (M-x rmail, for example). */
14903 if (CHARPOS (start_pos) > BEGV
14904 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14905 {
14906 struct it it;
14907 struct glyph_row *row;
14908
14909 /* Handle the case that the window start is out of range. */
14910 if (CHARPOS (start_pos) < BEGV)
14911 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14912 else if (CHARPOS (start_pos) > ZV)
14913 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14914
14915 /* Find the start of the continued line. This should be fast
14916 because find_newline is fast (newline cache). */
14917 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14918 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14919 row, DEFAULT_FACE_ID);
14920 reseat_at_previous_visible_line_start (&it);
14921
14922 /* If the line start is "too far" away from the window start,
14923 say it takes too much time to compute a new window start. */
14924 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14925 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14926 {
14927 int min_distance, distance;
14928
14929 /* Move forward by display lines to find the new window
14930 start. If window width was enlarged, the new start can
14931 be expected to be > the old start. If window width was
14932 decreased, the new window start will be < the old start.
14933 So, we're looking for the display line start with the
14934 minimum distance from the old window start. */
14935 pos = it.current.pos;
14936 min_distance = INFINITY;
14937 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14938 distance < min_distance)
14939 {
14940 min_distance = distance;
14941 pos = it.current.pos;
14942 if (it.line_wrap == WORD_WRAP)
14943 {
14944 /* Under WORD_WRAP, move_it_by_lines is likely to
14945 overshoot and stop not at the first, but the
14946 second character from the left margin. So in
14947 that case, we need a more tight control on the X
14948 coordinate of the iterator than move_it_by_lines
14949 promises in its contract. The method is to first
14950 go to the last (rightmost) visible character of a
14951 line, then move to the leftmost character on the
14952 next line in a separate call. */
14953 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
14954 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14955 move_it_to (&it, ZV, 0,
14956 it.current_y + it.max_ascent + it.max_descent, -1,
14957 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14958 }
14959 else
14960 move_it_by_lines (&it, 1);
14961 }
14962
14963 /* Set the window start there. */
14964 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14965 window_start_changed_p = 1;
14966 }
14967 }
14968
14969 return window_start_changed_p;
14970 }
14971
14972
14973 /* Try cursor movement in case text has not changed in window WINDOW,
14974 with window start STARTP. Value is
14975
14976 CURSOR_MOVEMENT_SUCCESS if successful
14977
14978 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14979
14980 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14981 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14982 we want to scroll as if scroll-step were set to 1. See the code.
14983
14984 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14985 which case we have to abort this redisplay, and adjust matrices
14986 first. */
14987
14988 enum
14989 {
14990 CURSOR_MOVEMENT_SUCCESS,
14991 CURSOR_MOVEMENT_CANNOT_BE_USED,
14992 CURSOR_MOVEMENT_MUST_SCROLL,
14993 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14994 };
14995
14996 static int
14997 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14998 {
14999 struct window *w = XWINDOW (window);
15000 struct frame *f = XFRAME (w->frame);
15001 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15002
15003 #ifdef GLYPH_DEBUG
15004 if (inhibit_try_cursor_movement)
15005 return rc;
15006 #endif
15007
15008 /* Previously, there was a check for Lisp integer in the
15009 if-statement below. Now, this field is converted to
15010 ptrdiff_t, thus zero means invalid position in a buffer. */
15011 eassert (w->last_point > 0);
15012 /* Likewise there was a check whether window_end_vpos is nil or larger
15013 than the window. Now window_end_vpos is int and so never nil, but
15014 let's leave eassert to check whether it fits in the window. */
15015 eassert (w->window_end_vpos < w->current_matrix->nrows);
15016
15017 /* Handle case where text has not changed, only point, and it has
15018 not moved off the frame. */
15019 if (/* Point may be in this window. */
15020 PT >= CHARPOS (startp)
15021 /* Selective display hasn't changed. */
15022 && !current_buffer->clip_changed
15023 /* Function force-mode-line-update is used to force a thorough
15024 redisplay. It sets either windows_or_buffers_changed or
15025 update_mode_lines. So don't take a shortcut here for these
15026 cases. */
15027 && !update_mode_lines
15028 && !windows_or_buffers_changed
15029 && !f->cursor_type_changed
15030 && NILP (Vshow_trailing_whitespace)
15031 /* This code is not used for mini-buffer for the sake of the case
15032 of redisplaying to replace an echo area message; since in
15033 that case the mini-buffer contents per se are usually
15034 unchanged. This code is of no real use in the mini-buffer
15035 since the handling of this_line_start_pos, etc., in redisplay
15036 handles the same cases. */
15037 && !EQ (window, minibuf_window)
15038 && (FRAME_WINDOW_P (f)
15039 || !overlay_arrow_in_current_buffer_p ()))
15040 {
15041 int this_scroll_margin, top_scroll_margin;
15042 struct glyph_row *row = NULL;
15043 int frame_line_height = default_line_pixel_height (w);
15044 int window_total_lines
15045 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15046
15047 #ifdef GLYPH_DEBUG
15048 debug_method_add (w, "cursor movement");
15049 #endif
15050
15051 /* Scroll if point within this distance from the top or bottom
15052 of the window. This is a pixel value. */
15053 if (scroll_margin > 0)
15054 {
15055 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15056 this_scroll_margin *= frame_line_height;
15057 }
15058 else
15059 this_scroll_margin = 0;
15060
15061 top_scroll_margin = this_scroll_margin;
15062 if (WINDOW_WANTS_HEADER_LINE_P (w))
15063 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15064
15065 /* Start with the row the cursor was displayed during the last
15066 not paused redisplay. Give up if that row is not valid. */
15067 if (w->last_cursor_vpos < 0
15068 || w->last_cursor_vpos >= w->current_matrix->nrows)
15069 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15070 else
15071 {
15072 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15073 if (row->mode_line_p)
15074 ++row;
15075 if (!row->enabled_p)
15076 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15077 }
15078
15079 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15080 {
15081 int scroll_p = 0, must_scroll = 0;
15082 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15083
15084 if (PT > w->last_point)
15085 {
15086 /* Point has moved forward. */
15087 while (MATRIX_ROW_END_CHARPOS (row) < PT
15088 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15089 {
15090 eassert (row->enabled_p);
15091 ++row;
15092 }
15093
15094 /* If the end position of a row equals the start
15095 position of the next row, and PT is at that position,
15096 we would rather display cursor in the next line. */
15097 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15098 && MATRIX_ROW_END_CHARPOS (row) == PT
15099 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15100 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15101 && !cursor_row_p (row))
15102 ++row;
15103
15104 /* If within the scroll margin, scroll. Note that
15105 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15106 the next line would be drawn, and that
15107 this_scroll_margin can be zero. */
15108 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15109 || PT > MATRIX_ROW_END_CHARPOS (row)
15110 /* Line is completely visible last line in window
15111 and PT is to be set in the next line. */
15112 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15113 && PT == MATRIX_ROW_END_CHARPOS (row)
15114 && !row->ends_at_zv_p
15115 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15116 scroll_p = 1;
15117 }
15118 else if (PT < w->last_point)
15119 {
15120 /* Cursor has to be moved backward. Note that PT >=
15121 CHARPOS (startp) because of the outer if-statement. */
15122 while (!row->mode_line_p
15123 && (MATRIX_ROW_START_CHARPOS (row) > PT
15124 || (MATRIX_ROW_START_CHARPOS (row) == PT
15125 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15126 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15127 row > w->current_matrix->rows
15128 && (row-1)->ends_in_newline_from_string_p))))
15129 && (row->y > top_scroll_margin
15130 || CHARPOS (startp) == BEGV))
15131 {
15132 eassert (row->enabled_p);
15133 --row;
15134 }
15135
15136 /* Consider the following case: Window starts at BEGV,
15137 there is invisible, intangible text at BEGV, so that
15138 display starts at some point START > BEGV. It can
15139 happen that we are called with PT somewhere between
15140 BEGV and START. Try to handle that case. */
15141 if (row < w->current_matrix->rows
15142 || row->mode_line_p)
15143 {
15144 row = w->current_matrix->rows;
15145 if (row->mode_line_p)
15146 ++row;
15147 }
15148
15149 /* Due to newlines in overlay strings, we may have to
15150 skip forward over overlay strings. */
15151 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15152 && MATRIX_ROW_END_CHARPOS (row) == PT
15153 && !cursor_row_p (row))
15154 ++row;
15155
15156 /* If within the scroll margin, scroll. */
15157 if (row->y < top_scroll_margin
15158 && CHARPOS (startp) != BEGV)
15159 scroll_p = 1;
15160 }
15161 else
15162 {
15163 /* Cursor did not move. So don't scroll even if cursor line
15164 is partially visible, as it was so before. */
15165 rc = CURSOR_MOVEMENT_SUCCESS;
15166 }
15167
15168 if (PT < MATRIX_ROW_START_CHARPOS (row)
15169 || PT > MATRIX_ROW_END_CHARPOS (row))
15170 {
15171 /* if PT is not in the glyph row, give up. */
15172 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15173 must_scroll = 1;
15174 }
15175 else if (rc != CURSOR_MOVEMENT_SUCCESS
15176 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15177 {
15178 struct glyph_row *row1;
15179
15180 /* If rows are bidi-reordered and point moved, back up
15181 until we find a row that does not belong to a
15182 continuation line. This is because we must consider
15183 all rows of a continued line as candidates for the
15184 new cursor positioning, since row start and end
15185 positions change non-linearly with vertical position
15186 in such rows. */
15187 /* FIXME: Revisit this when glyph ``spilling'' in
15188 continuation lines' rows is implemented for
15189 bidi-reordered rows. */
15190 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15191 MATRIX_ROW_CONTINUATION_LINE_P (row);
15192 --row)
15193 {
15194 /* If we hit the beginning of the displayed portion
15195 without finding the first row of a continued
15196 line, give up. */
15197 if (row <= row1)
15198 {
15199 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15200 break;
15201 }
15202 eassert (row->enabled_p);
15203 }
15204 }
15205 if (must_scroll)
15206 ;
15207 else if (rc != CURSOR_MOVEMENT_SUCCESS
15208 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15209 /* Make sure this isn't a header line by any chance, since
15210 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15211 && !row->mode_line_p
15212 && make_cursor_line_fully_visible_p)
15213 {
15214 if (PT == MATRIX_ROW_END_CHARPOS (row)
15215 && !row->ends_at_zv_p
15216 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15217 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15218 else if (row->height > window_box_height (w))
15219 {
15220 /* If we end up in a partially visible line, let's
15221 make it fully visible, except when it's taller
15222 than the window, in which case we can't do much
15223 about it. */
15224 *scroll_step = 1;
15225 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15226 }
15227 else
15228 {
15229 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15230 if (!cursor_row_fully_visible_p (w, 0, 1))
15231 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15232 else
15233 rc = CURSOR_MOVEMENT_SUCCESS;
15234 }
15235 }
15236 else if (scroll_p)
15237 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15238 else if (rc != CURSOR_MOVEMENT_SUCCESS
15239 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15240 {
15241 /* With bidi-reordered rows, there could be more than
15242 one candidate row whose start and end positions
15243 occlude point. We need to let set_cursor_from_row
15244 find the best candidate. */
15245 /* FIXME: Revisit this when glyph ``spilling'' in
15246 continuation lines' rows is implemented for
15247 bidi-reordered rows. */
15248 int rv = 0;
15249
15250 do
15251 {
15252 int at_zv_p = 0, exact_match_p = 0;
15253
15254 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15255 && PT <= MATRIX_ROW_END_CHARPOS (row)
15256 && cursor_row_p (row))
15257 rv |= set_cursor_from_row (w, row, w->current_matrix,
15258 0, 0, 0, 0);
15259 /* As soon as we've found the exact match for point,
15260 or the first suitable row whose ends_at_zv_p flag
15261 is set, we are done. */
15262 at_zv_p =
15263 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15264 if (rv && !at_zv_p
15265 && w->cursor.hpos >= 0
15266 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15267 w->cursor.vpos))
15268 {
15269 struct glyph_row *candidate =
15270 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15271 struct glyph *g =
15272 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15273 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15274
15275 exact_match_p =
15276 (BUFFERP (g->object) && g->charpos == PT)
15277 || (INTEGERP (g->object)
15278 && (g->charpos == PT
15279 || (g->charpos == 0 && endpos - 1 == PT)));
15280 }
15281 if (rv && (at_zv_p || exact_match_p))
15282 {
15283 rc = CURSOR_MOVEMENT_SUCCESS;
15284 break;
15285 }
15286 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15287 break;
15288 ++row;
15289 }
15290 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15291 || row->continued_p)
15292 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15293 || (MATRIX_ROW_START_CHARPOS (row) == PT
15294 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15295 /* If we didn't find any candidate rows, or exited the
15296 loop before all the candidates were examined, signal
15297 to the caller that this method failed. */
15298 if (rc != CURSOR_MOVEMENT_SUCCESS
15299 && !(rv
15300 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15301 && !row->continued_p))
15302 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15303 else if (rv)
15304 rc = CURSOR_MOVEMENT_SUCCESS;
15305 }
15306 else
15307 {
15308 do
15309 {
15310 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15311 {
15312 rc = CURSOR_MOVEMENT_SUCCESS;
15313 break;
15314 }
15315 ++row;
15316 }
15317 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15318 && MATRIX_ROW_START_CHARPOS (row) == PT
15319 && cursor_row_p (row));
15320 }
15321 }
15322 }
15323
15324 return rc;
15325 }
15326
15327 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15328 static
15329 #endif
15330 void
15331 set_vertical_scroll_bar (struct window *w)
15332 {
15333 ptrdiff_t start, end, whole;
15334
15335 /* Calculate the start and end positions for the current window.
15336 At some point, it would be nice to choose between scrollbars
15337 which reflect the whole buffer size, with special markers
15338 indicating narrowing, and scrollbars which reflect only the
15339 visible region.
15340
15341 Note that mini-buffers sometimes aren't displaying any text. */
15342 if (!MINI_WINDOW_P (w)
15343 || (w == XWINDOW (minibuf_window)
15344 && NILP (echo_area_buffer[0])))
15345 {
15346 struct buffer *buf = XBUFFER (w->contents);
15347 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15348 start = marker_position (w->start) - BUF_BEGV (buf);
15349 /* I don't think this is guaranteed to be right. For the
15350 moment, we'll pretend it is. */
15351 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15352
15353 if (end < start)
15354 end = start;
15355 if (whole < (end - start))
15356 whole = end - start;
15357 }
15358 else
15359 start = end = whole = 0;
15360
15361 /* Indicate what this scroll bar ought to be displaying now. */
15362 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15363 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15364 (w, end - start, whole, start);
15365 }
15366
15367
15368 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15369 selected_window is redisplayed.
15370
15371 We can return without actually redisplaying the window if fonts has been
15372 changed on window's frame. In that case, redisplay_internal will retry. */
15373
15374 static void
15375 redisplay_window (Lisp_Object window, int just_this_one_p)
15376 {
15377 struct window *w = XWINDOW (window);
15378 struct frame *f = XFRAME (w->frame);
15379 struct buffer *buffer = XBUFFER (w->contents);
15380 struct buffer *old = current_buffer;
15381 struct text_pos lpoint, opoint, startp;
15382 int update_mode_line;
15383 int tem;
15384 struct it it;
15385 /* Record it now because it's overwritten. */
15386 int current_matrix_up_to_date_p = 0;
15387 int used_current_matrix_p = 0;
15388 /* This is less strict than current_matrix_up_to_date_p.
15389 It indicates that the buffer contents and narrowing are unchanged. */
15390 int buffer_unchanged_p = 0;
15391 int temp_scroll_step = 0;
15392 ptrdiff_t count = SPECPDL_INDEX ();
15393 int rc;
15394 int centering_position = -1;
15395 int last_line_misfit = 0;
15396 ptrdiff_t beg_unchanged, end_unchanged;
15397 int frame_line_height;
15398
15399 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15400 opoint = lpoint;
15401
15402 #ifdef GLYPH_DEBUG
15403 *w->desired_matrix->method = 0;
15404 #endif
15405
15406 if (!just_this_one_p
15407 && (update_mode_lines == REDISPLAY_SOME
15408 || update_mode_lines == 0)
15409 && (windows_or_buffers_changed == REDISPLAY_SOME
15410 || windows_or_buffers_changed == 0)
15411 && !w->redisplay
15412 && !f->redisplay
15413 && !buffer->text->redisplay)
15414 return;
15415
15416 /* Make sure that both W's markers are valid. */
15417 eassert (XMARKER (w->start)->buffer == buffer);
15418 eassert (XMARKER (w->pointm)->buffer == buffer);
15419
15420 restart:
15421 reconsider_clip_changes (w);
15422 frame_line_height = default_line_pixel_height (w);
15423
15424 /* Has the mode line to be updated? */
15425 update_mode_line = (w->update_mode_line
15426 || update_mode_lines
15427 || buffer->clip_changed
15428 || buffer->prevent_redisplay_optimizations_p);
15429
15430 if (MINI_WINDOW_P (w))
15431 {
15432 if (w == XWINDOW (echo_area_window)
15433 && !NILP (echo_area_buffer[0]))
15434 {
15435 if (update_mode_line)
15436 /* We may have to update a tty frame's menu bar or a
15437 tool-bar. Example `M-x C-h C-h C-g'. */
15438 goto finish_menu_bars;
15439 else
15440 /* We've already displayed the echo area glyphs in this window. */
15441 goto finish_scroll_bars;
15442 }
15443 else if ((w != XWINDOW (minibuf_window)
15444 || minibuf_level == 0)
15445 /* When buffer is nonempty, redisplay window normally. */
15446 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15447 /* Quail displays non-mini buffers in minibuffer window.
15448 In that case, redisplay the window normally. */
15449 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15450 {
15451 /* W is a mini-buffer window, but it's not active, so clear
15452 it. */
15453 int yb = window_text_bottom_y (w);
15454 struct glyph_row *row;
15455 int y;
15456
15457 for (y = 0, row = w->desired_matrix->rows;
15458 y < yb;
15459 y += row->height, ++row)
15460 blank_row (w, row, y);
15461 goto finish_scroll_bars;
15462 }
15463
15464 clear_glyph_matrix (w->desired_matrix);
15465 }
15466
15467 /* Otherwise set up data on this window; select its buffer and point
15468 value. */
15469 /* Really select the buffer, for the sake of buffer-local
15470 variables. */
15471 set_buffer_internal_1 (XBUFFER (w->contents));
15472
15473 current_matrix_up_to_date_p
15474 = (w->window_end_valid
15475 && !current_buffer->clip_changed
15476 && !current_buffer->prevent_redisplay_optimizations_p
15477 && !window_outdated (w));
15478
15479 /* Run the window-bottom-change-functions
15480 if it is possible that the text on the screen has changed
15481 (either due to modification of the text, or any other reason). */
15482 if (!current_matrix_up_to_date_p
15483 && !NILP (Vwindow_text_change_functions))
15484 {
15485 safe_run_hooks (Qwindow_text_change_functions);
15486 goto restart;
15487 }
15488
15489 beg_unchanged = BEG_UNCHANGED;
15490 end_unchanged = END_UNCHANGED;
15491
15492 SET_TEXT_POS (opoint, PT, PT_BYTE);
15493
15494 specbind (Qinhibit_point_motion_hooks, Qt);
15495
15496 buffer_unchanged_p
15497 = (w->window_end_valid
15498 && !current_buffer->clip_changed
15499 && !window_outdated (w));
15500
15501 /* When windows_or_buffers_changed is non-zero, we can't rely
15502 on the window end being valid, so set it to zero there. */
15503 if (windows_or_buffers_changed)
15504 {
15505 /* If window starts on a continuation line, maybe adjust the
15506 window start in case the window's width changed. */
15507 if (XMARKER (w->start)->buffer == current_buffer)
15508 compute_window_start_on_continuation_line (w);
15509
15510 w->window_end_valid = 0;
15511 /* If so, we also can't rely on current matrix
15512 and should not fool try_cursor_movement below. */
15513 current_matrix_up_to_date_p = 0;
15514 }
15515
15516 /* Some sanity checks. */
15517 CHECK_WINDOW_END (w);
15518 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15519 emacs_abort ();
15520 if (BYTEPOS (opoint) < CHARPOS (opoint))
15521 emacs_abort ();
15522
15523 if (mode_line_update_needed (w))
15524 update_mode_line = 1;
15525
15526 /* Point refers normally to the selected window. For any other
15527 window, set up appropriate value. */
15528 if (!EQ (window, selected_window))
15529 {
15530 ptrdiff_t new_pt = marker_position (w->pointm);
15531 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15532 if (new_pt < BEGV)
15533 {
15534 new_pt = BEGV;
15535 new_pt_byte = BEGV_BYTE;
15536 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15537 }
15538 else if (new_pt > (ZV - 1))
15539 {
15540 new_pt = ZV;
15541 new_pt_byte = ZV_BYTE;
15542 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15543 }
15544
15545 /* We don't use SET_PT so that the point-motion hooks don't run. */
15546 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15547 }
15548
15549 /* If any of the character widths specified in the display table
15550 have changed, invalidate the width run cache. It's true that
15551 this may be a bit late to catch such changes, but the rest of
15552 redisplay goes (non-fatally) haywire when the display table is
15553 changed, so why should we worry about doing any better? */
15554 if (current_buffer->width_run_cache)
15555 {
15556 struct Lisp_Char_Table *disptab = buffer_display_table ();
15557
15558 if (! disptab_matches_widthtab
15559 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15560 {
15561 invalidate_region_cache (current_buffer,
15562 current_buffer->width_run_cache,
15563 BEG, Z);
15564 recompute_width_table (current_buffer, disptab);
15565 }
15566 }
15567
15568 /* If window-start is screwed up, choose a new one. */
15569 if (XMARKER (w->start)->buffer != current_buffer)
15570 goto recenter;
15571
15572 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15573
15574 /* If someone specified a new starting point but did not insist,
15575 check whether it can be used. */
15576 if (w->optional_new_start
15577 && CHARPOS (startp) >= BEGV
15578 && CHARPOS (startp) <= ZV)
15579 {
15580 w->optional_new_start = 0;
15581 start_display (&it, w, startp);
15582 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15583 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15584 if (IT_CHARPOS (it) == PT)
15585 w->force_start = 1;
15586 /* IT may overshoot PT if text at PT is invisible. */
15587 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15588 w->force_start = 1;
15589 }
15590
15591 force_start:
15592
15593 /* Handle case where place to start displaying has been specified,
15594 unless the specified location is outside the accessible range. */
15595 if (w->force_start || window_frozen_p (w))
15596 {
15597 /* We set this later on if we have to adjust point. */
15598 int new_vpos = -1;
15599
15600 w->force_start = 0;
15601 w->vscroll = 0;
15602 w->window_end_valid = 0;
15603
15604 /* Forget any recorded base line for line number display. */
15605 if (!buffer_unchanged_p)
15606 w->base_line_number = 0;
15607
15608 /* Redisplay the mode line. Select the buffer properly for that.
15609 Also, run the hook window-scroll-functions
15610 because we have scrolled. */
15611 /* Note, we do this after clearing force_start because
15612 if there's an error, it is better to forget about force_start
15613 than to get into an infinite loop calling the hook functions
15614 and having them get more errors. */
15615 if (!update_mode_line
15616 || ! NILP (Vwindow_scroll_functions))
15617 {
15618 update_mode_line = 1;
15619 w->update_mode_line = 1;
15620 startp = run_window_scroll_functions (window, startp);
15621 }
15622
15623 if (CHARPOS (startp) < BEGV)
15624 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15625 else if (CHARPOS (startp) > ZV)
15626 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15627
15628 /* Redisplay, then check if cursor has been set during the
15629 redisplay. Give up if new fonts were loaded. */
15630 /* We used to issue a CHECK_MARGINS argument to try_window here,
15631 but this causes scrolling to fail when point begins inside
15632 the scroll margin (bug#148) -- cyd */
15633 if (!try_window (window, startp, 0))
15634 {
15635 w->force_start = 1;
15636 clear_glyph_matrix (w->desired_matrix);
15637 goto need_larger_matrices;
15638 }
15639
15640 if (w->cursor.vpos < 0 && !window_frozen_p (w))
15641 {
15642 /* If point does not appear, try to move point so it does
15643 appear. The desired matrix has been built above, so we
15644 can use it here. */
15645 new_vpos = window_box_height (w) / 2;
15646 }
15647
15648 if (!cursor_row_fully_visible_p (w, 0, 0))
15649 {
15650 /* Point does appear, but on a line partly visible at end of window.
15651 Move it back to a fully-visible line. */
15652 new_vpos = window_box_height (w);
15653 }
15654 else if (w->cursor.vpos >= 0)
15655 {
15656 /* Some people insist on not letting point enter the scroll
15657 margin, even though this part handles windows that didn't
15658 scroll at all. */
15659 int window_total_lines
15660 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15661 int margin = min (scroll_margin, window_total_lines / 4);
15662 int pixel_margin = margin * frame_line_height;
15663 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15664
15665 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15666 below, which finds the row to move point to, advances by
15667 the Y coordinate of the _next_ row, see the definition of
15668 MATRIX_ROW_BOTTOM_Y. */
15669 if (w->cursor.vpos < margin + header_line)
15670 {
15671 w->cursor.vpos = -1;
15672 clear_glyph_matrix (w->desired_matrix);
15673 goto try_to_scroll;
15674 }
15675 else
15676 {
15677 int window_height = window_box_height (w);
15678
15679 if (header_line)
15680 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15681 if (w->cursor.y >= window_height - pixel_margin)
15682 {
15683 w->cursor.vpos = -1;
15684 clear_glyph_matrix (w->desired_matrix);
15685 goto try_to_scroll;
15686 }
15687 }
15688 }
15689
15690 /* If we need to move point for either of the above reasons,
15691 now actually do it. */
15692 if (new_vpos >= 0)
15693 {
15694 struct glyph_row *row;
15695
15696 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15697 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15698 ++row;
15699
15700 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15701 MATRIX_ROW_START_BYTEPOS (row));
15702
15703 if (w != XWINDOW (selected_window))
15704 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15705 else if (current_buffer == old)
15706 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15707
15708 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15709
15710 /* If we are highlighting the region, then we just changed
15711 the region, so redisplay to show it. */
15712 /* FIXME: We need to (re)run pre-redisplay-function! */
15713 /* if (markpos_of_region () >= 0)
15714 {
15715 clear_glyph_matrix (w->desired_matrix);
15716 if (!try_window (window, startp, 0))
15717 goto need_larger_matrices;
15718 }
15719 */
15720 }
15721
15722 #ifdef GLYPH_DEBUG
15723 debug_method_add (w, "forced window start");
15724 #endif
15725 goto done;
15726 }
15727
15728 /* Handle case where text has not changed, only point, and it has
15729 not moved off the frame, and we are not retrying after hscroll.
15730 (current_matrix_up_to_date_p is nonzero when retrying.) */
15731 if (current_matrix_up_to_date_p
15732 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15733 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15734 {
15735 switch (rc)
15736 {
15737 case CURSOR_MOVEMENT_SUCCESS:
15738 used_current_matrix_p = 1;
15739 goto done;
15740
15741 case CURSOR_MOVEMENT_MUST_SCROLL:
15742 goto try_to_scroll;
15743
15744 default:
15745 emacs_abort ();
15746 }
15747 }
15748 /* If current starting point was originally the beginning of a line
15749 but no longer is, find a new starting point. */
15750 else if (w->start_at_line_beg
15751 && !(CHARPOS (startp) <= BEGV
15752 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15753 {
15754 #ifdef GLYPH_DEBUG
15755 debug_method_add (w, "recenter 1");
15756 #endif
15757 goto recenter;
15758 }
15759
15760 /* Try scrolling with try_window_id. Value is > 0 if update has
15761 been done, it is -1 if we know that the same window start will
15762 not work. It is 0 if unsuccessful for some other reason. */
15763 else if ((tem = try_window_id (w)) != 0)
15764 {
15765 #ifdef GLYPH_DEBUG
15766 debug_method_add (w, "try_window_id %d", tem);
15767 #endif
15768
15769 if (f->fonts_changed)
15770 goto need_larger_matrices;
15771 if (tem > 0)
15772 goto done;
15773
15774 /* Otherwise try_window_id has returned -1 which means that we
15775 don't want the alternative below this comment to execute. */
15776 }
15777 else if (CHARPOS (startp) >= BEGV
15778 && CHARPOS (startp) <= ZV
15779 && PT >= CHARPOS (startp)
15780 && (CHARPOS (startp) < ZV
15781 /* Avoid starting at end of buffer. */
15782 || CHARPOS (startp) == BEGV
15783 || !window_outdated (w)))
15784 {
15785 int d1, d2, d3, d4, d5, d6;
15786
15787 /* If first window line is a continuation line, and window start
15788 is inside the modified region, but the first change is before
15789 current window start, we must select a new window start.
15790
15791 However, if this is the result of a down-mouse event (e.g. by
15792 extending the mouse-drag-overlay), we don't want to select a
15793 new window start, since that would change the position under
15794 the mouse, resulting in an unwanted mouse-movement rather
15795 than a simple mouse-click. */
15796 if (!w->start_at_line_beg
15797 && NILP (do_mouse_tracking)
15798 && CHARPOS (startp) > BEGV
15799 && CHARPOS (startp) > BEG + beg_unchanged
15800 && CHARPOS (startp) <= Z - end_unchanged
15801 /* Even if w->start_at_line_beg is nil, a new window may
15802 start at a line_beg, since that's how set_buffer_window
15803 sets it. So, we need to check the return value of
15804 compute_window_start_on_continuation_line. (See also
15805 bug#197). */
15806 && XMARKER (w->start)->buffer == current_buffer
15807 && compute_window_start_on_continuation_line (w)
15808 /* It doesn't make sense to force the window start like we
15809 do at label force_start if it is already known that point
15810 will not be visible in the resulting window, because
15811 doing so will move point from its correct position
15812 instead of scrolling the window to bring point into view.
15813 See bug#9324. */
15814 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15815 {
15816 w->force_start = 1;
15817 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15818 goto force_start;
15819 }
15820
15821 #ifdef GLYPH_DEBUG
15822 debug_method_add (w, "same window start");
15823 #endif
15824
15825 /* Try to redisplay starting at same place as before.
15826 If point has not moved off frame, accept the results. */
15827 if (!current_matrix_up_to_date_p
15828 /* Don't use try_window_reusing_current_matrix in this case
15829 because a window scroll function can have changed the
15830 buffer. */
15831 || !NILP (Vwindow_scroll_functions)
15832 || MINI_WINDOW_P (w)
15833 || !(used_current_matrix_p
15834 = try_window_reusing_current_matrix (w)))
15835 {
15836 IF_DEBUG (debug_method_add (w, "1"));
15837 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15838 /* -1 means we need to scroll.
15839 0 means we need new matrices, but fonts_changed
15840 is set in that case, so we will detect it below. */
15841 goto try_to_scroll;
15842 }
15843
15844 if (f->fonts_changed)
15845 goto need_larger_matrices;
15846
15847 if (w->cursor.vpos >= 0)
15848 {
15849 if (!just_this_one_p
15850 || current_buffer->clip_changed
15851 || BEG_UNCHANGED < CHARPOS (startp))
15852 /* Forget any recorded base line for line number display. */
15853 w->base_line_number = 0;
15854
15855 if (!cursor_row_fully_visible_p (w, 1, 0))
15856 {
15857 clear_glyph_matrix (w->desired_matrix);
15858 last_line_misfit = 1;
15859 }
15860 /* Drop through and scroll. */
15861 else
15862 goto done;
15863 }
15864 else
15865 clear_glyph_matrix (w->desired_matrix);
15866 }
15867
15868 try_to_scroll:
15869
15870 /* Redisplay the mode line. Select the buffer properly for that. */
15871 if (!update_mode_line)
15872 {
15873 update_mode_line = 1;
15874 w->update_mode_line = 1;
15875 }
15876
15877 /* Try to scroll by specified few lines. */
15878 if ((scroll_conservatively
15879 || emacs_scroll_step
15880 || temp_scroll_step
15881 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15882 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15883 && CHARPOS (startp) >= BEGV
15884 && CHARPOS (startp) <= ZV)
15885 {
15886 /* The function returns -1 if new fonts were loaded, 1 if
15887 successful, 0 if not successful. */
15888 int ss = try_scrolling (window, just_this_one_p,
15889 scroll_conservatively,
15890 emacs_scroll_step,
15891 temp_scroll_step, last_line_misfit);
15892 switch (ss)
15893 {
15894 case SCROLLING_SUCCESS:
15895 goto done;
15896
15897 case SCROLLING_NEED_LARGER_MATRICES:
15898 goto need_larger_matrices;
15899
15900 case SCROLLING_FAILED:
15901 break;
15902
15903 default:
15904 emacs_abort ();
15905 }
15906 }
15907
15908 /* Finally, just choose a place to start which positions point
15909 according to user preferences. */
15910
15911 recenter:
15912
15913 #ifdef GLYPH_DEBUG
15914 debug_method_add (w, "recenter");
15915 #endif
15916
15917 /* Forget any previously recorded base line for line number display. */
15918 if (!buffer_unchanged_p)
15919 w->base_line_number = 0;
15920
15921 /* Determine the window start relative to point. */
15922 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15923 it.current_y = it.last_visible_y;
15924 if (centering_position < 0)
15925 {
15926 int window_total_lines
15927 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15928 int margin =
15929 scroll_margin > 0
15930 ? min (scroll_margin, window_total_lines / 4)
15931 : 0;
15932 ptrdiff_t margin_pos = CHARPOS (startp);
15933 Lisp_Object aggressive;
15934 int scrolling_up;
15935
15936 /* If there is a scroll margin at the top of the window, find
15937 its character position. */
15938 if (margin
15939 /* Cannot call start_display if startp is not in the
15940 accessible region of the buffer. This can happen when we
15941 have just switched to a different buffer and/or changed
15942 its restriction. In that case, startp is initialized to
15943 the character position 1 (BEGV) because we did not yet
15944 have chance to display the buffer even once. */
15945 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15946 {
15947 struct it it1;
15948 void *it1data = NULL;
15949
15950 SAVE_IT (it1, it, it1data);
15951 start_display (&it1, w, startp);
15952 move_it_vertically (&it1, margin * frame_line_height);
15953 margin_pos = IT_CHARPOS (it1);
15954 RESTORE_IT (&it, &it, it1data);
15955 }
15956 scrolling_up = PT > margin_pos;
15957 aggressive =
15958 scrolling_up
15959 ? BVAR (current_buffer, scroll_up_aggressively)
15960 : BVAR (current_buffer, scroll_down_aggressively);
15961
15962 if (!MINI_WINDOW_P (w)
15963 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15964 {
15965 int pt_offset = 0;
15966
15967 /* Setting scroll-conservatively overrides
15968 scroll-*-aggressively. */
15969 if (!scroll_conservatively && NUMBERP (aggressive))
15970 {
15971 double float_amount = XFLOATINT (aggressive);
15972
15973 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15974 if (pt_offset == 0 && float_amount > 0)
15975 pt_offset = 1;
15976 if (pt_offset && margin > 0)
15977 margin -= 1;
15978 }
15979 /* Compute how much to move the window start backward from
15980 point so that point will be displayed where the user
15981 wants it. */
15982 if (scrolling_up)
15983 {
15984 centering_position = it.last_visible_y;
15985 if (pt_offset)
15986 centering_position -= pt_offset;
15987 centering_position -=
15988 frame_line_height * (1 + margin + (last_line_misfit != 0))
15989 + WINDOW_HEADER_LINE_HEIGHT (w);
15990 /* Don't let point enter the scroll margin near top of
15991 the window. */
15992 if (centering_position < margin * frame_line_height)
15993 centering_position = margin * frame_line_height;
15994 }
15995 else
15996 centering_position = margin * frame_line_height + pt_offset;
15997 }
15998 else
15999 /* Set the window start half the height of the window backward
16000 from point. */
16001 centering_position = window_box_height (w) / 2;
16002 }
16003 move_it_vertically_backward (&it, centering_position);
16004
16005 eassert (IT_CHARPOS (it) >= BEGV);
16006
16007 /* The function move_it_vertically_backward may move over more
16008 than the specified y-distance. If it->w is small, e.g. a
16009 mini-buffer window, we may end up in front of the window's
16010 display area. Start displaying at the start of the line
16011 containing PT in this case. */
16012 if (it.current_y <= 0)
16013 {
16014 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16015 move_it_vertically_backward (&it, 0);
16016 it.current_y = 0;
16017 }
16018
16019 it.current_x = it.hpos = 0;
16020
16021 /* Set the window start position here explicitly, to avoid an
16022 infinite loop in case the functions in window-scroll-functions
16023 get errors. */
16024 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16025
16026 /* Run scroll hooks. */
16027 startp = run_window_scroll_functions (window, it.current.pos);
16028
16029 /* Redisplay the window. */
16030 if (!current_matrix_up_to_date_p
16031 || windows_or_buffers_changed
16032 || f->cursor_type_changed
16033 /* Don't use try_window_reusing_current_matrix in this case
16034 because it can have changed the buffer. */
16035 || !NILP (Vwindow_scroll_functions)
16036 || !just_this_one_p
16037 || MINI_WINDOW_P (w)
16038 || !(used_current_matrix_p
16039 = try_window_reusing_current_matrix (w)))
16040 try_window (window, startp, 0);
16041
16042 /* If new fonts have been loaded (due to fontsets), give up. We
16043 have to start a new redisplay since we need to re-adjust glyph
16044 matrices. */
16045 if (f->fonts_changed)
16046 goto need_larger_matrices;
16047
16048 /* If cursor did not appear assume that the middle of the window is
16049 in the first line of the window. Do it again with the next line.
16050 (Imagine a window of height 100, displaying two lines of height
16051 60. Moving back 50 from it->last_visible_y will end in the first
16052 line.) */
16053 if (w->cursor.vpos < 0)
16054 {
16055 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16056 {
16057 clear_glyph_matrix (w->desired_matrix);
16058 move_it_by_lines (&it, 1);
16059 try_window (window, it.current.pos, 0);
16060 }
16061 else if (PT < IT_CHARPOS (it))
16062 {
16063 clear_glyph_matrix (w->desired_matrix);
16064 move_it_by_lines (&it, -1);
16065 try_window (window, it.current.pos, 0);
16066 }
16067 else
16068 {
16069 /* Not much we can do about it. */
16070 }
16071 }
16072
16073 /* Consider the following case: Window starts at BEGV, there is
16074 invisible, intangible text at BEGV, so that display starts at
16075 some point START > BEGV. It can happen that we are called with
16076 PT somewhere between BEGV and START. Try to handle that case. */
16077 if (w->cursor.vpos < 0)
16078 {
16079 struct glyph_row *row = w->current_matrix->rows;
16080 if (row->mode_line_p)
16081 ++row;
16082 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16083 }
16084
16085 if (!cursor_row_fully_visible_p (w, 0, 0))
16086 {
16087 /* If vscroll is enabled, disable it and try again. */
16088 if (w->vscroll)
16089 {
16090 w->vscroll = 0;
16091 clear_glyph_matrix (w->desired_matrix);
16092 goto recenter;
16093 }
16094
16095 /* Users who set scroll-conservatively to a large number want
16096 point just above/below the scroll margin. If we ended up
16097 with point's row partially visible, move the window start to
16098 make that row fully visible and out of the margin. */
16099 if (scroll_conservatively > SCROLL_LIMIT)
16100 {
16101 int window_total_lines
16102 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16103 int margin =
16104 scroll_margin > 0
16105 ? min (scroll_margin, window_total_lines / 4)
16106 : 0;
16107 int move_down = w->cursor.vpos >= window_total_lines / 2;
16108
16109 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16110 clear_glyph_matrix (w->desired_matrix);
16111 if (1 == try_window (window, it.current.pos,
16112 TRY_WINDOW_CHECK_MARGINS))
16113 goto done;
16114 }
16115
16116 /* If centering point failed to make the whole line visible,
16117 put point at the top instead. That has to make the whole line
16118 visible, if it can be done. */
16119 if (centering_position == 0)
16120 goto done;
16121
16122 clear_glyph_matrix (w->desired_matrix);
16123 centering_position = 0;
16124 goto recenter;
16125 }
16126
16127 done:
16128
16129 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16130 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16131 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16132
16133 /* Display the mode line, if we must. */
16134 if ((update_mode_line
16135 /* If window not full width, must redo its mode line
16136 if (a) the window to its side is being redone and
16137 (b) we do a frame-based redisplay. This is a consequence
16138 of how inverted lines are drawn in frame-based redisplay. */
16139 || (!just_this_one_p
16140 && !FRAME_WINDOW_P (f)
16141 && !WINDOW_FULL_WIDTH_P (w))
16142 /* Line number to display. */
16143 || w->base_line_pos > 0
16144 /* Column number is displayed and different from the one displayed. */
16145 || (w->column_number_displayed != -1
16146 && (w->column_number_displayed != current_column ())))
16147 /* This means that the window has a mode line. */
16148 && (WINDOW_WANTS_MODELINE_P (w)
16149 || WINDOW_WANTS_HEADER_LINE_P (w)))
16150 {
16151 display_mode_lines (w);
16152
16153 /* If mode line height has changed, arrange for a thorough
16154 immediate redisplay using the correct mode line height. */
16155 if (WINDOW_WANTS_MODELINE_P (w)
16156 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16157 {
16158 f->fonts_changed = 1;
16159 w->mode_line_height = -1;
16160 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16161 = DESIRED_MODE_LINE_HEIGHT (w);
16162 }
16163
16164 /* If header line height has changed, arrange for a thorough
16165 immediate redisplay using the correct header line height. */
16166 if (WINDOW_WANTS_HEADER_LINE_P (w)
16167 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16168 {
16169 f->fonts_changed = 1;
16170 w->header_line_height = -1;
16171 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16172 = DESIRED_HEADER_LINE_HEIGHT (w);
16173 }
16174
16175 if (f->fonts_changed)
16176 goto need_larger_matrices;
16177 }
16178
16179 if (!line_number_displayed && w->base_line_pos != -1)
16180 {
16181 w->base_line_pos = 0;
16182 w->base_line_number = 0;
16183 }
16184
16185 finish_menu_bars:
16186
16187 /* When we reach a frame's selected window, redo the frame's menu bar. */
16188 if (update_mode_line
16189 && EQ (FRAME_SELECTED_WINDOW (f), window))
16190 {
16191 int redisplay_menu_p = 0;
16192
16193 if (FRAME_WINDOW_P (f))
16194 {
16195 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16196 || defined (HAVE_NS) || defined (USE_GTK)
16197 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16198 #else
16199 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16200 #endif
16201 }
16202 else
16203 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16204
16205 if (redisplay_menu_p)
16206 display_menu_bar (w);
16207
16208 #ifdef HAVE_WINDOW_SYSTEM
16209 if (FRAME_WINDOW_P (f))
16210 {
16211 #if defined (USE_GTK) || defined (HAVE_NS)
16212 if (FRAME_EXTERNAL_TOOL_BAR (f))
16213 redisplay_tool_bar (f);
16214 #else
16215 if (WINDOWP (f->tool_bar_window)
16216 && (FRAME_TOOL_BAR_LINES (f) > 0
16217 || !NILP (Vauto_resize_tool_bars))
16218 && redisplay_tool_bar (f))
16219 ignore_mouse_drag_p = 1;
16220 #endif
16221 }
16222 #endif
16223 }
16224
16225 #ifdef HAVE_WINDOW_SYSTEM
16226 if (FRAME_WINDOW_P (f)
16227 && update_window_fringes (w, (just_this_one_p
16228 || (!used_current_matrix_p && !overlay_arrow_seen)
16229 || w->pseudo_window_p)))
16230 {
16231 update_begin (f);
16232 block_input ();
16233 if (draw_window_fringes (w, 1))
16234 x_draw_vertical_border (w);
16235 unblock_input ();
16236 update_end (f);
16237 }
16238 #endif /* HAVE_WINDOW_SYSTEM */
16239
16240 /* We go to this label, with fonts_changed set, if it is
16241 necessary to try again using larger glyph matrices.
16242 We have to redeem the scroll bar even in this case,
16243 because the loop in redisplay_internal expects that. */
16244 need_larger_matrices:
16245 ;
16246 finish_scroll_bars:
16247
16248 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16249 {
16250 /* Set the thumb's position and size. */
16251 set_vertical_scroll_bar (w);
16252
16253 /* Note that we actually used the scroll bar attached to this
16254 window, so it shouldn't be deleted at the end of redisplay. */
16255 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16256 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16257 }
16258
16259 /* Restore current_buffer and value of point in it. The window
16260 update may have changed the buffer, so first make sure `opoint'
16261 is still valid (Bug#6177). */
16262 if (CHARPOS (opoint) < BEGV)
16263 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16264 else if (CHARPOS (opoint) > ZV)
16265 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16266 else
16267 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16268
16269 set_buffer_internal_1 (old);
16270 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16271 shorter. This can be caused by log truncation in *Messages*. */
16272 if (CHARPOS (lpoint) <= ZV)
16273 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16274
16275 unbind_to (count, Qnil);
16276 }
16277
16278
16279 /* Build the complete desired matrix of WINDOW with a window start
16280 buffer position POS.
16281
16282 Value is 1 if successful. It is zero if fonts were loaded during
16283 redisplay which makes re-adjusting glyph matrices necessary, and -1
16284 if point would appear in the scroll margins.
16285 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16286 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16287 set in FLAGS.) */
16288
16289 int
16290 try_window (Lisp_Object window, struct text_pos pos, int flags)
16291 {
16292 struct window *w = XWINDOW (window);
16293 struct it it;
16294 struct glyph_row *last_text_row = NULL;
16295 struct frame *f = XFRAME (w->frame);
16296 int frame_line_height = default_line_pixel_height (w);
16297
16298 /* Make POS the new window start. */
16299 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16300
16301 /* Mark cursor position as unknown. No overlay arrow seen. */
16302 w->cursor.vpos = -1;
16303 overlay_arrow_seen = 0;
16304
16305 /* Initialize iterator and info to start at POS. */
16306 start_display (&it, w, pos);
16307
16308 /* Display all lines of W. */
16309 while (it.current_y < it.last_visible_y)
16310 {
16311 if (display_line (&it))
16312 last_text_row = it.glyph_row - 1;
16313 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16314 return 0;
16315 }
16316
16317 /* Don't let the cursor end in the scroll margins. */
16318 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16319 && !MINI_WINDOW_P (w))
16320 {
16321 int this_scroll_margin;
16322 int window_total_lines
16323 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16324
16325 if (scroll_margin > 0)
16326 {
16327 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16328 this_scroll_margin *= frame_line_height;
16329 }
16330 else
16331 this_scroll_margin = 0;
16332
16333 if ((w->cursor.y >= 0 /* not vscrolled */
16334 && w->cursor.y < this_scroll_margin
16335 && CHARPOS (pos) > BEGV
16336 && IT_CHARPOS (it) < ZV)
16337 /* rms: considering make_cursor_line_fully_visible_p here
16338 seems to give wrong results. We don't want to recenter
16339 when the last line is partly visible, we want to allow
16340 that case to be handled in the usual way. */
16341 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16342 {
16343 w->cursor.vpos = -1;
16344 clear_glyph_matrix (w->desired_matrix);
16345 return -1;
16346 }
16347 }
16348
16349 /* If bottom moved off end of frame, change mode line percentage. */
16350 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
16351 w->update_mode_line = 1;
16352
16353 /* Set window_end_pos to the offset of the last character displayed
16354 on the window from the end of current_buffer. Set
16355 window_end_vpos to its row number. */
16356 if (last_text_row)
16357 {
16358 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16359 adjust_window_ends (w, last_text_row, 0);
16360 eassert
16361 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16362 w->window_end_vpos)));
16363 }
16364 else
16365 {
16366 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16367 w->window_end_pos = Z - ZV;
16368 w->window_end_vpos = 0;
16369 }
16370
16371 /* But that is not valid info until redisplay finishes. */
16372 w->window_end_valid = 0;
16373 return 1;
16374 }
16375
16376
16377 \f
16378 /************************************************************************
16379 Window redisplay reusing current matrix when buffer has not changed
16380 ************************************************************************/
16381
16382 /* Try redisplay of window W showing an unchanged buffer with a
16383 different window start than the last time it was displayed by
16384 reusing its current matrix. Value is non-zero if successful.
16385 W->start is the new window start. */
16386
16387 static int
16388 try_window_reusing_current_matrix (struct window *w)
16389 {
16390 struct frame *f = XFRAME (w->frame);
16391 struct glyph_row *bottom_row;
16392 struct it it;
16393 struct run run;
16394 struct text_pos start, new_start;
16395 int nrows_scrolled, i;
16396 struct glyph_row *last_text_row;
16397 struct glyph_row *last_reused_text_row;
16398 struct glyph_row *start_row;
16399 int start_vpos, min_y, max_y;
16400
16401 #ifdef GLYPH_DEBUG
16402 if (inhibit_try_window_reusing)
16403 return 0;
16404 #endif
16405
16406 if (/* This function doesn't handle terminal frames. */
16407 !FRAME_WINDOW_P (f)
16408 /* Don't try to reuse the display if windows have been split
16409 or such. */
16410 || windows_or_buffers_changed
16411 || f->cursor_type_changed)
16412 return 0;
16413
16414 /* Can't do this if showing trailing whitespace. */
16415 if (!NILP (Vshow_trailing_whitespace))
16416 return 0;
16417
16418 /* If top-line visibility has changed, give up. */
16419 if (WINDOW_WANTS_HEADER_LINE_P (w)
16420 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16421 return 0;
16422
16423 /* Give up if old or new display is scrolled vertically. We could
16424 make this function handle this, but right now it doesn't. */
16425 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16426 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16427 return 0;
16428
16429 /* The variable new_start now holds the new window start. The old
16430 start `start' can be determined from the current matrix. */
16431 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16432 start = start_row->minpos;
16433 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16434
16435 /* Clear the desired matrix for the display below. */
16436 clear_glyph_matrix (w->desired_matrix);
16437
16438 if (CHARPOS (new_start) <= CHARPOS (start))
16439 {
16440 /* Don't use this method if the display starts with an ellipsis
16441 displayed for invisible text. It's not easy to handle that case
16442 below, and it's certainly not worth the effort since this is
16443 not a frequent case. */
16444 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16445 return 0;
16446
16447 IF_DEBUG (debug_method_add (w, "twu1"));
16448
16449 /* Display up to a row that can be reused. The variable
16450 last_text_row is set to the last row displayed that displays
16451 text. Note that it.vpos == 0 if or if not there is a
16452 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16453 start_display (&it, w, new_start);
16454 w->cursor.vpos = -1;
16455 last_text_row = last_reused_text_row = NULL;
16456
16457 while (it.current_y < it.last_visible_y && !f->fonts_changed)
16458 {
16459 /* If we have reached into the characters in the START row,
16460 that means the line boundaries have changed. So we
16461 can't start copying with the row START. Maybe it will
16462 work to start copying with the following row. */
16463 while (IT_CHARPOS (it) > CHARPOS (start))
16464 {
16465 /* Advance to the next row as the "start". */
16466 start_row++;
16467 start = start_row->minpos;
16468 /* If there are no more rows to try, or just one, give up. */
16469 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16470 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16471 || CHARPOS (start) == ZV)
16472 {
16473 clear_glyph_matrix (w->desired_matrix);
16474 return 0;
16475 }
16476
16477 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16478 }
16479 /* If we have reached alignment, we can copy the rest of the
16480 rows. */
16481 if (IT_CHARPOS (it) == CHARPOS (start)
16482 /* Don't accept "alignment" inside a display vector,
16483 since start_row could have started in the middle of
16484 that same display vector (thus their character
16485 positions match), and we have no way of telling if
16486 that is the case. */
16487 && it.current.dpvec_index < 0)
16488 break;
16489
16490 if (display_line (&it))
16491 last_text_row = it.glyph_row - 1;
16492
16493 }
16494
16495 /* A value of current_y < last_visible_y means that we stopped
16496 at the previous window start, which in turn means that we
16497 have at least one reusable row. */
16498 if (it.current_y < it.last_visible_y)
16499 {
16500 struct glyph_row *row;
16501
16502 /* IT.vpos always starts from 0; it counts text lines. */
16503 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16504
16505 /* Find PT if not already found in the lines displayed. */
16506 if (w->cursor.vpos < 0)
16507 {
16508 int dy = it.current_y - start_row->y;
16509
16510 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16511 row = row_containing_pos (w, PT, row, NULL, dy);
16512 if (row)
16513 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16514 dy, nrows_scrolled);
16515 else
16516 {
16517 clear_glyph_matrix (w->desired_matrix);
16518 return 0;
16519 }
16520 }
16521
16522 /* Scroll the display. Do it before the current matrix is
16523 changed. The problem here is that update has not yet
16524 run, i.e. part of the current matrix is not up to date.
16525 scroll_run_hook will clear the cursor, and use the
16526 current matrix to get the height of the row the cursor is
16527 in. */
16528 run.current_y = start_row->y;
16529 run.desired_y = it.current_y;
16530 run.height = it.last_visible_y - it.current_y;
16531
16532 if (run.height > 0 && run.current_y != run.desired_y)
16533 {
16534 update_begin (f);
16535 FRAME_RIF (f)->update_window_begin_hook (w);
16536 FRAME_RIF (f)->clear_window_mouse_face (w);
16537 FRAME_RIF (f)->scroll_run_hook (w, &run);
16538 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16539 update_end (f);
16540 }
16541
16542 /* Shift current matrix down by nrows_scrolled lines. */
16543 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16544 rotate_matrix (w->current_matrix,
16545 start_vpos,
16546 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16547 nrows_scrolled);
16548
16549 /* Disable lines that must be updated. */
16550 for (i = 0; i < nrows_scrolled; ++i)
16551 (start_row + i)->enabled_p = 0;
16552
16553 /* Re-compute Y positions. */
16554 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16555 max_y = it.last_visible_y;
16556 for (row = start_row + nrows_scrolled;
16557 row < bottom_row;
16558 ++row)
16559 {
16560 row->y = it.current_y;
16561 row->visible_height = row->height;
16562
16563 if (row->y < min_y)
16564 row->visible_height -= min_y - row->y;
16565 if (row->y + row->height > max_y)
16566 row->visible_height -= row->y + row->height - max_y;
16567 if (row->fringe_bitmap_periodic_p)
16568 row->redraw_fringe_bitmaps_p = 1;
16569
16570 it.current_y += row->height;
16571
16572 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16573 last_reused_text_row = row;
16574 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16575 break;
16576 }
16577
16578 /* Disable lines in the current matrix which are now
16579 below the window. */
16580 for (++row; row < bottom_row; ++row)
16581 row->enabled_p = row->mode_line_p = 0;
16582 }
16583
16584 /* Update window_end_pos etc.; last_reused_text_row is the last
16585 reused row from the current matrix containing text, if any.
16586 The value of last_text_row is the last displayed line
16587 containing text. */
16588 if (last_reused_text_row)
16589 adjust_window_ends (w, last_reused_text_row, 1);
16590 else if (last_text_row)
16591 adjust_window_ends (w, last_text_row, 0);
16592 else
16593 {
16594 /* This window must be completely empty. */
16595 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16596 w->window_end_pos = Z - ZV;
16597 w->window_end_vpos = 0;
16598 }
16599 w->window_end_valid = 0;
16600
16601 /* Update hint: don't try scrolling again in update_window. */
16602 w->desired_matrix->no_scrolling_p = 1;
16603
16604 #ifdef GLYPH_DEBUG
16605 debug_method_add (w, "try_window_reusing_current_matrix 1");
16606 #endif
16607 return 1;
16608 }
16609 else if (CHARPOS (new_start) > CHARPOS (start))
16610 {
16611 struct glyph_row *pt_row, *row;
16612 struct glyph_row *first_reusable_row;
16613 struct glyph_row *first_row_to_display;
16614 int dy;
16615 int yb = window_text_bottom_y (w);
16616
16617 /* Find the row starting at new_start, if there is one. Don't
16618 reuse a partially visible line at the end. */
16619 first_reusable_row = start_row;
16620 while (first_reusable_row->enabled_p
16621 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16622 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16623 < CHARPOS (new_start)))
16624 ++first_reusable_row;
16625
16626 /* Give up if there is no row to reuse. */
16627 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16628 || !first_reusable_row->enabled_p
16629 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16630 != CHARPOS (new_start)))
16631 return 0;
16632
16633 /* We can reuse fully visible rows beginning with
16634 first_reusable_row to the end of the window. Set
16635 first_row_to_display to the first row that cannot be reused.
16636 Set pt_row to the row containing point, if there is any. */
16637 pt_row = NULL;
16638 for (first_row_to_display = first_reusable_row;
16639 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16640 ++first_row_to_display)
16641 {
16642 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16643 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16644 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16645 && first_row_to_display->ends_at_zv_p
16646 && pt_row == NULL)))
16647 pt_row = first_row_to_display;
16648 }
16649
16650 /* Start displaying at the start of first_row_to_display. */
16651 eassert (first_row_to_display->y < yb);
16652 init_to_row_start (&it, w, first_row_to_display);
16653
16654 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16655 - start_vpos);
16656 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16657 - nrows_scrolled);
16658 it.current_y = (first_row_to_display->y - first_reusable_row->y
16659 + WINDOW_HEADER_LINE_HEIGHT (w));
16660
16661 /* Display lines beginning with first_row_to_display in the
16662 desired matrix. Set last_text_row to the last row displayed
16663 that displays text. */
16664 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16665 if (pt_row == NULL)
16666 w->cursor.vpos = -1;
16667 last_text_row = NULL;
16668 while (it.current_y < it.last_visible_y && !f->fonts_changed)
16669 if (display_line (&it))
16670 last_text_row = it.glyph_row - 1;
16671
16672 /* If point is in a reused row, adjust y and vpos of the cursor
16673 position. */
16674 if (pt_row)
16675 {
16676 w->cursor.vpos -= nrows_scrolled;
16677 w->cursor.y -= first_reusable_row->y - start_row->y;
16678 }
16679
16680 /* Give up if point isn't in a row displayed or reused. (This
16681 also handles the case where w->cursor.vpos < nrows_scrolled
16682 after the calls to display_line, which can happen with scroll
16683 margins. See bug#1295.) */
16684 if (w->cursor.vpos < 0)
16685 {
16686 clear_glyph_matrix (w->desired_matrix);
16687 return 0;
16688 }
16689
16690 /* Scroll the display. */
16691 run.current_y = first_reusable_row->y;
16692 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16693 run.height = it.last_visible_y - run.current_y;
16694 dy = run.current_y - run.desired_y;
16695
16696 if (run.height)
16697 {
16698 update_begin (f);
16699 FRAME_RIF (f)->update_window_begin_hook (w);
16700 FRAME_RIF (f)->clear_window_mouse_face (w);
16701 FRAME_RIF (f)->scroll_run_hook (w, &run);
16702 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16703 update_end (f);
16704 }
16705
16706 /* Adjust Y positions of reused rows. */
16707 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16708 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16709 max_y = it.last_visible_y;
16710 for (row = first_reusable_row; row < first_row_to_display; ++row)
16711 {
16712 row->y -= dy;
16713 row->visible_height = row->height;
16714 if (row->y < min_y)
16715 row->visible_height -= min_y - row->y;
16716 if (row->y + row->height > max_y)
16717 row->visible_height -= row->y + row->height - max_y;
16718 if (row->fringe_bitmap_periodic_p)
16719 row->redraw_fringe_bitmaps_p = 1;
16720 }
16721
16722 /* Scroll the current matrix. */
16723 eassert (nrows_scrolled > 0);
16724 rotate_matrix (w->current_matrix,
16725 start_vpos,
16726 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16727 -nrows_scrolled);
16728
16729 /* Disable rows not reused. */
16730 for (row -= nrows_scrolled; row < bottom_row; ++row)
16731 row->enabled_p = 0;
16732
16733 /* Point may have moved to a different line, so we cannot assume that
16734 the previous cursor position is valid; locate the correct row. */
16735 if (pt_row)
16736 {
16737 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16738 row < bottom_row
16739 && PT >= MATRIX_ROW_END_CHARPOS (row)
16740 && !row->ends_at_zv_p;
16741 row++)
16742 {
16743 w->cursor.vpos++;
16744 w->cursor.y = row->y;
16745 }
16746 if (row < bottom_row)
16747 {
16748 /* Can't simply scan the row for point with
16749 bidi-reordered glyph rows. Let set_cursor_from_row
16750 figure out where to put the cursor, and if it fails,
16751 give up. */
16752 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16753 {
16754 if (!set_cursor_from_row (w, row, w->current_matrix,
16755 0, 0, 0, 0))
16756 {
16757 clear_glyph_matrix (w->desired_matrix);
16758 return 0;
16759 }
16760 }
16761 else
16762 {
16763 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16764 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16765
16766 for (; glyph < end
16767 && (!BUFFERP (glyph->object)
16768 || glyph->charpos < PT);
16769 glyph++)
16770 {
16771 w->cursor.hpos++;
16772 w->cursor.x += glyph->pixel_width;
16773 }
16774 }
16775 }
16776 }
16777
16778 /* Adjust window end. A null value of last_text_row means that
16779 the window end is in reused rows which in turn means that
16780 only its vpos can have changed. */
16781 if (last_text_row)
16782 adjust_window_ends (w, last_text_row, 0);
16783 else
16784 w->window_end_vpos -= nrows_scrolled;
16785
16786 w->window_end_valid = 0;
16787 w->desired_matrix->no_scrolling_p = 1;
16788
16789 #ifdef GLYPH_DEBUG
16790 debug_method_add (w, "try_window_reusing_current_matrix 2");
16791 #endif
16792 return 1;
16793 }
16794
16795 return 0;
16796 }
16797
16798
16799 \f
16800 /************************************************************************
16801 Window redisplay reusing current matrix when buffer has changed
16802 ************************************************************************/
16803
16804 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16805 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16806 ptrdiff_t *, ptrdiff_t *);
16807 static struct glyph_row *
16808 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16809 struct glyph_row *);
16810
16811
16812 /* Return the last row in MATRIX displaying text. If row START is
16813 non-null, start searching with that row. IT gives the dimensions
16814 of the display. Value is null if matrix is empty; otherwise it is
16815 a pointer to the row found. */
16816
16817 static struct glyph_row *
16818 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16819 struct glyph_row *start)
16820 {
16821 struct glyph_row *row, *row_found;
16822
16823 /* Set row_found to the last row in IT->w's current matrix
16824 displaying text. The loop looks funny but think of partially
16825 visible lines. */
16826 row_found = NULL;
16827 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16828 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16829 {
16830 eassert (row->enabled_p);
16831 row_found = row;
16832 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16833 break;
16834 ++row;
16835 }
16836
16837 return row_found;
16838 }
16839
16840
16841 /* Return the last row in the current matrix of W that is not affected
16842 by changes at the start of current_buffer that occurred since W's
16843 current matrix was built. Value is null if no such row exists.
16844
16845 BEG_UNCHANGED us the number of characters unchanged at the start of
16846 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16847 first changed character in current_buffer. Characters at positions <
16848 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16849 when the current matrix was built. */
16850
16851 static struct glyph_row *
16852 find_last_unchanged_at_beg_row (struct window *w)
16853 {
16854 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16855 struct glyph_row *row;
16856 struct glyph_row *row_found = NULL;
16857 int yb = window_text_bottom_y (w);
16858
16859 /* Find the last row displaying unchanged text. */
16860 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16861 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16862 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16863 ++row)
16864 {
16865 if (/* If row ends before first_changed_pos, it is unchanged,
16866 except in some case. */
16867 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16868 /* When row ends in ZV and we write at ZV it is not
16869 unchanged. */
16870 && !row->ends_at_zv_p
16871 /* When first_changed_pos is the end of a continued line,
16872 row is not unchanged because it may be no longer
16873 continued. */
16874 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16875 && (row->continued_p
16876 || row->exact_window_width_line_p))
16877 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16878 needs to be recomputed, so don't consider this row as
16879 unchanged. This happens when the last line was
16880 bidi-reordered and was killed immediately before this
16881 redisplay cycle. In that case, ROW->end stores the
16882 buffer position of the first visual-order character of
16883 the killed text, which is now beyond ZV. */
16884 && CHARPOS (row->end.pos) <= ZV)
16885 row_found = row;
16886
16887 /* Stop if last visible row. */
16888 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16889 break;
16890 }
16891
16892 return row_found;
16893 }
16894
16895
16896 /* Find the first glyph row in the current matrix of W that is not
16897 affected by changes at the end of current_buffer since the
16898 time W's current matrix was built.
16899
16900 Return in *DELTA the number of chars by which buffer positions in
16901 unchanged text at the end of current_buffer must be adjusted.
16902
16903 Return in *DELTA_BYTES the corresponding number of bytes.
16904
16905 Value is null if no such row exists, i.e. all rows are affected by
16906 changes. */
16907
16908 static struct glyph_row *
16909 find_first_unchanged_at_end_row (struct window *w,
16910 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16911 {
16912 struct glyph_row *row;
16913 struct glyph_row *row_found = NULL;
16914
16915 *delta = *delta_bytes = 0;
16916
16917 /* Display must not have been paused, otherwise the current matrix
16918 is not up to date. */
16919 eassert (w->window_end_valid);
16920
16921 /* A value of window_end_pos >= END_UNCHANGED means that the window
16922 end is in the range of changed text. If so, there is no
16923 unchanged row at the end of W's current matrix. */
16924 if (w->window_end_pos >= END_UNCHANGED)
16925 return NULL;
16926
16927 /* Set row to the last row in W's current matrix displaying text. */
16928 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
16929
16930 /* If matrix is entirely empty, no unchanged row exists. */
16931 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16932 {
16933 /* The value of row is the last glyph row in the matrix having a
16934 meaningful buffer position in it. The end position of row
16935 corresponds to window_end_pos. This allows us to translate
16936 buffer positions in the current matrix to current buffer
16937 positions for characters not in changed text. */
16938 ptrdiff_t Z_old =
16939 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
16940 ptrdiff_t Z_BYTE_old =
16941 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16942 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16943 struct glyph_row *first_text_row
16944 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16945
16946 *delta = Z - Z_old;
16947 *delta_bytes = Z_BYTE - Z_BYTE_old;
16948
16949 /* Set last_unchanged_pos to the buffer position of the last
16950 character in the buffer that has not been changed. Z is the
16951 index + 1 of the last character in current_buffer, i.e. by
16952 subtracting END_UNCHANGED we get the index of the last
16953 unchanged character, and we have to add BEG to get its buffer
16954 position. */
16955 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16956 last_unchanged_pos_old = last_unchanged_pos - *delta;
16957
16958 /* Search backward from ROW for a row displaying a line that
16959 starts at a minimum position >= last_unchanged_pos_old. */
16960 for (; row > first_text_row; --row)
16961 {
16962 /* This used to abort, but it can happen.
16963 It is ok to just stop the search instead here. KFS. */
16964 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16965 break;
16966
16967 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16968 row_found = row;
16969 }
16970 }
16971
16972 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16973
16974 return row_found;
16975 }
16976
16977
16978 /* Make sure that glyph rows in the current matrix of window W
16979 reference the same glyph memory as corresponding rows in the
16980 frame's frame matrix. This function is called after scrolling W's
16981 current matrix on a terminal frame in try_window_id and
16982 try_window_reusing_current_matrix. */
16983
16984 static void
16985 sync_frame_with_window_matrix_rows (struct window *w)
16986 {
16987 struct frame *f = XFRAME (w->frame);
16988 struct glyph_row *window_row, *window_row_end, *frame_row;
16989
16990 /* Preconditions: W must be a leaf window and full-width. Its frame
16991 must have a frame matrix. */
16992 eassert (BUFFERP (w->contents));
16993 eassert (WINDOW_FULL_WIDTH_P (w));
16994 eassert (!FRAME_WINDOW_P (f));
16995
16996 /* If W is a full-width window, glyph pointers in W's current matrix
16997 have, by definition, to be the same as glyph pointers in the
16998 corresponding frame matrix. Note that frame matrices have no
16999 marginal areas (see build_frame_matrix). */
17000 window_row = w->current_matrix->rows;
17001 window_row_end = window_row + w->current_matrix->nrows;
17002 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17003 while (window_row < window_row_end)
17004 {
17005 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17006 struct glyph *end = window_row->glyphs[LAST_AREA];
17007
17008 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17009 frame_row->glyphs[TEXT_AREA] = start;
17010 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17011 frame_row->glyphs[LAST_AREA] = end;
17012
17013 /* Disable frame rows whose corresponding window rows have
17014 been disabled in try_window_id. */
17015 if (!window_row->enabled_p)
17016 frame_row->enabled_p = 0;
17017
17018 ++window_row, ++frame_row;
17019 }
17020 }
17021
17022
17023 /* Find the glyph row in window W containing CHARPOS. Consider all
17024 rows between START and END (not inclusive). END null means search
17025 all rows to the end of the display area of W. Value is the row
17026 containing CHARPOS or null. */
17027
17028 struct glyph_row *
17029 row_containing_pos (struct window *w, ptrdiff_t charpos,
17030 struct glyph_row *start, struct glyph_row *end, int dy)
17031 {
17032 struct glyph_row *row = start;
17033 struct glyph_row *best_row = NULL;
17034 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17035 int last_y;
17036
17037 /* If we happen to start on a header-line, skip that. */
17038 if (row->mode_line_p)
17039 ++row;
17040
17041 if ((end && row >= end) || !row->enabled_p)
17042 return NULL;
17043
17044 last_y = window_text_bottom_y (w) - dy;
17045
17046 while (1)
17047 {
17048 /* Give up if we have gone too far. */
17049 if (end && row >= end)
17050 return NULL;
17051 /* This formerly returned if they were equal.
17052 I think that both quantities are of a "last plus one" type;
17053 if so, when they are equal, the row is within the screen. -- rms. */
17054 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17055 return NULL;
17056
17057 /* If it is in this row, return this row. */
17058 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17059 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17060 /* The end position of a row equals the start
17061 position of the next row. If CHARPOS is there, we
17062 would rather consider it displayed in the next
17063 line, except when this line ends in ZV. */
17064 && !row_for_charpos_p (row, charpos)))
17065 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17066 {
17067 struct glyph *g;
17068
17069 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17070 || (!best_row && !row->continued_p))
17071 return row;
17072 /* In bidi-reordered rows, there could be several rows whose
17073 edges surround CHARPOS, all of these rows belonging to
17074 the same continued line. We need to find the row which
17075 fits CHARPOS the best. */
17076 for (g = row->glyphs[TEXT_AREA];
17077 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17078 g++)
17079 {
17080 if (!STRINGP (g->object))
17081 {
17082 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17083 {
17084 mindif = eabs (g->charpos - charpos);
17085 best_row = row;
17086 /* Exact match always wins. */
17087 if (mindif == 0)
17088 return best_row;
17089 }
17090 }
17091 }
17092 }
17093 else if (best_row && !row->continued_p)
17094 return best_row;
17095 ++row;
17096 }
17097 }
17098
17099
17100 /* Try to redisplay window W by reusing its existing display. W's
17101 current matrix must be up to date when this function is called,
17102 i.e. window_end_valid must be nonzero.
17103
17104 Value is
17105
17106 1 if display has been updated
17107 0 if otherwise unsuccessful
17108 -1 if redisplay with same window start is known not to succeed
17109
17110 The following steps are performed:
17111
17112 1. Find the last row in the current matrix of W that is not
17113 affected by changes at the start of current_buffer. If no such row
17114 is found, give up.
17115
17116 2. Find the first row in W's current matrix that is not affected by
17117 changes at the end of current_buffer. Maybe there is no such row.
17118
17119 3. Display lines beginning with the row + 1 found in step 1 to the
17120 row found in step 2 or, if step 2 didn't find a row, to the end of
17121 the window.
17122
17123 4. If cursor is not known to appear on the window, give up.
17124
17125 5. If display stopped at the row found in step 2, scroll the
17126 display and current matrix as needed.
17127
17128 6. Maybe display some lines at the end of W, if we must. This can
17129 happen under various circumstances, like a partially visible line
17130 becoming fully visible, or because newly displayed lines are displayed
17131 in smaller font sizes.
17132
17133 7. Update W's window end information. */
17134
17135 static int
17136 try_window_id (struct window *w)
17137 {
17138 struct frame *f = XFRAME (w->frame);
17139 struct glyph_matrix *current_matrix = w->current_matrix;
17140 struct glyph_matrix *desired_matrix = w->desired_matrix;
17141 struct glyph_row *last_unchanged_at_beg_row;
17142 struct glyph_row *first_unchanged_at_end_row;
17143 struct glyph_row *row;
17144 struct glyph_row *bottom_row;
17145 int bottom_vpos;
17146 struct it it;
17147 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17148 int dvpos, dy;
17149 struct text_pos start_pos;
17150 struct run run;
17151 int first_unchanged_at_end_vpos = 0;
17152 struct glyph_row *last_text_row, *last_text_row_at_end;
17153 struct text_pos start;
17154 ptrdiff_t first_changed_charpos, last_changed_charpos;
17155
17156 #ifdef GLYPH_DEBUG
17157 if (inhibit_try_window_id)
17158 return 0;
17159 #endif
17160
17161 /* This is handy for debugging. */
17162 #if 0
17163 #define GIVE_UP(X) \
17164 do { \
17165 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17166 return 0; \
17167 } while (0)
17168 #else
17169 #define GIVE_UP(X) return 0
17170 #endif
17171
17172 SET_TEXT_POS_FROM_MARKER (start, w->start);
17173
17174 /* Don't use this for mini-windows because these can show
17175 messages and mini-buffers, and we don't handle that here. */
17176 if (MINI_WINDOW_P (w))
17177 GIVE_UP (1);
17178
17179 /* This flag is used to prevent redisplay optimizations. */
17180 if (windows_or_buffers_changed || f->cursor_type_changed)
17181 GIVE_UP (2);
17182
17183 /* Verify that narrowing has not changed.
17184 Also verify that we were not told to prevent redisplay optimizations.
17185 It would be nice to further
17186 reduce the number of cases where this prevents try_window_id. */
17187 if (current_buffer->clip_changed
17188 || current_buffer->prevent_redisplay_optimizations_p)
17189 GIVE_UP (3);
17190
17191 /* Window must either use window-based redisplay or be full width. */
17192 if (!FRAME_WINDOW_P (f)
17193 && (!FRAME_LINE_INS_DEL_OK (f)
17194 || !WINDOW_FULL_WIDTH_P (w)))
17195 GIVE_UP (4);
17196
17197 /* Give up if point is known NOT to appear in W. */
17198 if (PT < CHARPOS (start))
17199 GIVE_UP (5);
17200
17201 /* Another way to prevent redisplay optimizations. */
17202 if (w->last_modified == 0)
17203 GIVE_UP (6);
17204
17205 /* Verify that window is not hscrolled. */
17206 if (w->hscroll != 0)
17207 GIVE_UP (7);
17208
17209 /* Verify that display wasn't paused. */
17210 if (!w->window_end_valid)
17211 GIVE_UP (8);
17212
17213 /* Likewise if highlighting trailing whitespace. */
17214 if (!NILP (Vshow_trailing_whitespace))
17215 GIVE_UP (11);
17216
17217 /* Can't use this if overlay arrow position and/or string have
17218 changed. */
17219 if (overlay_arrows_changed_p ())
17220 GIVE_UP (12);
17221
17222 /* When word-wrap is on, adding a space to the first word of a
17223 wrapped line can change the wrap position, altering the line
17224 above it. It might be worthwhile to handle this more
17225 intelligently, but for now just redisplay from scratch. */
17226 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17227 GIVE_UP (21);
17228
17229 /* Under bidi reordering, adding or deleting a character in the
17230 beginning of a paragraph, before the first strong directional
17231 character, can change the base direction of the paragraph (unless
17232 the buffer specifies a fixed paragraph direction), which will
17233 require to redisplay the whole paragraph. It might be worthwhile
17234 to find the paragraph limits and widen the range of redisplayed
17235 lines to that, but for now just give up this optimization and
17236 redisplay from scratch. */
17237 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17238 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17239 GIVE_UP (22);
17240
17241 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17242 only if buffer has really changed. The reason is that the gap is
17243 initially at Z for freshly visited files. The code below would
17244 set end_unchanged to 0 in that case. */
17245 if (MODIFF > SAVE_MODIFF
17246 /* This seems to happen sometimes after saving a buffer. */
17247 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17248 {
17249 if (GPT - BEG < BEG_UNCHANGED)
17250 BEG_UNCHANGED = GPT - BEG;
17251 if (Z - GPT < END_UNCHANGED)
17252 END_UNCHANGED = Z - GPT;
17253 }
17254
17255 /* The position of the first and last character that has been changed. */
17256 first_changed_charpos = BEG + BEG_UNCHANGED;
17257 last_changed_charpos = Z - END_UNCHANGED;
17258
17259 /* If window starts after a line end, and the last change is in
17260 front of that newline, then changes don't affect the display.
17261 This case happens with stealth-fontification. Note that although
17262 the display is unchanged, glyph positions in the matrix have to
17263 be adjusted, of course. */
17264 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17265 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17266 && ((last_changed_charpos < CHARPOS (start)
17267 && CHARPOS (start) == BEGV)
17268 || (last_changed_charpos < CHARPOS (start) - 1
17269 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17270 {
17271 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17272 struct glyph_row *r0;
17273
17274 /* Compute how many chars/bytes have been added to or removed
17275 from the buffer. */
17276 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17277 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17278 Z_delta = Z - Z_old;
17279 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17280
17281 /* Give up if PT is not in the window. Note that it already has
17282 been checked at the start of try_window_id that PT is not in
17283 front of the window start. */
17284 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17285 GIVE_UP (13);
17286
17287 /* If window start is unchanged, we can reuse the whole matrix
17288 as is, after adjusting glyph positions. No need to compute
17289 the window end again, since its offset from Z hasn't changed. */
17290 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17291 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17292 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17293 /* PT must not be in a partially visible line. */
17294 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17295 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17296 {
17297 /* Adjust positions in the glyph matrix. */
17298 if (Z_delta || Z_delta_bytes)
17299 {
17300 struct glyph_row *r1
17301 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17302 increment_matrix_positions (w->current_matrix,
17303 MATRIX_ROW_VPOS (r0, current_matrix),
17304 MATRIX_ROW_VPOS (r1, current_matrix),
17305 Z_delta, Z_delta_bytes);
17306 }
17307
17308 /* Set the cursor. */
17309 row = row_containing_pos (w, PT, r0, NULL, 0);
17310 if (row)
17311 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17312 return 1;
17313 }
17314 }
17315
17316 /* Handle the case that changes are all below what is displayed in
17317 the window, and that PT is in the window. This shortcut cannot
17318 be taken if ZV is visible in the window, and text has been added
17319 there that is visible in the window. */
17320 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17321 /* ZV is not visible in the window, or there are no
17322 changes at ZV, actually. */
17323 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17324 || first_changed_charpos == last_changed_charpos))
17325 {
17326 struct glyph_row *r0;
17327
17328 /* Give up if PT is not in the window. Note that it already has
17329 been checked at the start of try_window_id that PT is not in
17330 front of the window start. */
17331 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17332 GIVE_UP (14);
17333
17334 /* If window start is unchanged, we can reuse the whole matrix
17335 as is, without changing glyph positions since no text has
17336 been added/removed in front of the window end. */
17337 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17338 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17339 /* PT must not be in a partially visible line. */
17340 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17341 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17342 {
17343 /* We have to compute the window end anew since text
17344 could have been added/removed after it. */
17345 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17346 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17347
17348 /* Set the cursor. */
17349 row = row_containing_pos (w, PT, r0, NULL, 0);
17350 if (row)
17351 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17352 return 2;
17353 }
17354 }
17355
17356 /* Give up if window start is in the changed area.
17357
17358 The condition used to read
17359
17360 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17361
17362 but why that was tested escapes me at the moment. */
17363 if (CHARPOS (start) >= first_changed_charpos
17364 && CHARPOS (start) <= last_changed_charpos)
17365 GIVE_UP (15);
17366
17367 /* Check that window start agrees with the start of the first glyph
17368 row in its current matrix. Check this after we know the window
17369 start is not in changed text, otherwise positions would not be
17370 comparable. */
17371 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17372 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17373 GIVE_UP (16);
17374
17375 /* Give up if the window ends in strings. Overlay strings
17376 at the end are difficult to handle, so don't try. */
17377 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
17378 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17379 GIVE_UP (20);
17380
17381 /* Compute the position at which we have to start displaying new
17382 lines. Some of the lines at the top of the window might be
17383 reusable because they are not displaying changed text. Find the
17384 last row in W's current matrix not affected by changes at the
17385 start of current_buffer. Value is null if changes start in the
17386 first line of window. */
17387 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17388 if (last_unchanged_at_beg_row)
17389 {
17390 /* Avoid starting to display in the middle of a character, a TAB
17391 for instance. This is easier than to set up the iterator
17392 exactly, and it's not a frequent case, so the additional
17393 effort wouldn't really pay off. */
17394 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17395 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17396 && last_unchanged_at_beg_row > w->current_matrix->rows)
17397 --last_unchanged_at_beg_row;
17398
17399 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17400 GIVE_UP (17);
17401
17402 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17403 GIVE_UP (18);
17404 start_pos = it.current.pos;
17405
17406 /* Start displaying new lines in the desired matrix at the same
17407 vpos we would use in the current matrix, i.e. below
17408 last_unchanged_at_beg_row. */
17409 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17410 current_matrix);
17411 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17412 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17413
17414 eassert (it.hpos == 0 && it.current_x == 0);
17415 }
17416 else
17417 {
17418 /* There are no reusable lines at the start of the window.
17419 Start displaying in the first text line. */
17420 start_display (&it, w, start);
17421 it.vpos = it.first_vpos;
17422 start_pos = it.current.pos;
17423 }
17424
17425 /* Find the first row that is not affected by changes at the end of
17426 the buffer. Value will be null if there is no unchanged row, in
17427 which case we must redisplay to the end of the window. delta
17428 will be set to the value by which buffer positions beginning with
17429 first_unchanged_at_end_row have to be adjusted due to text
17430 changes. */
17431 first_unchanged_at_end_row
17432 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17433 IF_DEBUG (debug_delta = delta);
17434 IF_DEBUG (debug_delta_bytes = delta_bytes);
17435
17436 /* Set stop_pos to the buffer position up to which we will have to
17437 display new lines. If first_unchanged_at_end_row != NULL, this
17438 is the buffer position of the start of the line displayed in that
17439 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17440 that we don't stop at a buffer position. */
17441 stop_pos = 0;
17442 if (first_unchanged_at_end_row)
17443 {
17444 eassert (last_unchanged_at_beg_row == NULL
17445 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17446
17447 /* If this is a continuation line, move forward to the next one
17448 that isn't. Changes in lines above affect this line.
17449 Caution: this may move first_unchanged_at_end_row to a row
17450 not displaying text. */
17451 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17452 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17453 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17454 < it.last_visible_y))
17455 ++first_unchanged_at_end_row;
17456
17457 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17458 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17459 >= it.last_visible_y))
17460 first_unchanged_at_end_row = NULL;
17461 else
17462 {
17463 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17464 + delta);
17465 first_unchanged_at_end_vpos
17466 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17467 eassert (stop_pos >= Z - END_UNCHANGED);
17468 }
17469 }
17470 else if (last_unchanged_at_beg_row == NULL)
17471 GIVE_UP (19);
17472
17473
17474 #ifdef GLYPH_DEBUG
17475
17476 /* Either there is no unchanged row at the end, or the one we have
17477 now displays text. This is a necessary condition for the window
17478 end pos calculation at the end of this function. */
17479 eassert (first_unchanged_at_end_row == NULL
17480 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17481
17482 debug_last_unchanged_at_beg_vpos
17483 = (last_unchanged_at_beg_row
17484 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17485 : -1);
17486 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17487
17488 #endif /* GLYPH_DEBUG */
17489
17490
17491 /* Display new lines. Set last_text_row to the last new line
17492 displayed which has text on it, i.e. might end up as being the
17493 line where the window_end_vpos is. */
17494 w->cursor.vpos = -1;
17495 last_text_row = NULL;
17496 overlay_arrow_seen = 0;
17497 while (it.current_y < it.last_visible_y
17498 && !f->fonts_changed
17499 && (first_unchanged_at_end_row == NULL
17500 || IT_CHARPOS (it) < stop_pos))
17501 {
17502 if (display_line (&it))
17503 last_text_row = it.glyph_row - 1;
17504 }
17505
17506 if (f->fonts_changed)
17507 return -1;
17508
17509
17510 /* Compute differences in buffer positions, y-positions etc. for
17511 lines reused at the bottom of the window. Compute what we can
17512 scroll. */
17513 if (first_unchanged_at_end_row
17514 /* No lines reused because we displayed everything up to the
17515 bottom of the window. */
17516 && it.current_y < it.last_visible_y)
17517 {
17518 dvpos = (it.vpos
17519 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17520 current_matrix));
17521 dy = it.current_y - first_unchanged_at_end_row->y;
17522 run.current_y = first_unchanged_at_end_row->y;
17523 run.desired_y = run.current_y + dy;
17524 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17525 }
17526 else
17527 {
17528 delta = delta_bytes = dvpos = dy
17529 = run.current_y = run.desired_y = run.height = 0;
17530 first_unchanged_at_end_row = NULL;
17531 }
17532 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17533
17534
17535 /* Find the cursor if not already found. We have to decide whether
17536 PT will appear on this window (it sometimes doesn't, but this is
17537 not a very frequent case.) This decision has to be made before
17538 the current matrix is altered. A value of cursor.vpos < 0 means
17539 that PT is either in one of the lines beginning at
17540 first_unchanged_at_end_row or below the window. Don't care for
17541 lines that might be displayed later at the window end; as
17542 mentioned, this is not a frequent case. */
17543 if (w->cursor.vpos < 0)
17544 {
17545 /* Cursor in unchanged rows at the top? */
17546 if (PT < CHARPOS (start_pos)
17547 && last_unchanged_at_beg_row)
17548 {
17549 row = row_containing_pos (w, PT,
17550 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17551 last_unchanged_at_beg_row + 1, 0);
17552 if (row)
17553 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17554 }
17555
17556 /* Start from first_unchanged_at_end_row looking for PT. */
17557 else if (first_unchanged_at_end_row)
17558 {
17559 row = row_containing_pos (w, PT - delta,
17560 first_unchanged_at_end_row, NULL, 0);
17561 if (row)
17562 set_cursor_from_row (w, row, w->current_matrix, delta,
17563 delta_bytes, dy, dvpos);
17564 }
17565
17566 /* Give up if cursor was not found. */
17567 if (w->cursor.vpos < 0)
17568 {
17569 clear_glyph_matrix (w->desired_matrix);
17570 return -1;
17571 }
17572 }
17573
17574 /* Don't let the cursor end in the scroll margins. */
17575 {
17576 int this_scroll_margin, cursor_height;
17577 int frame_line_height = default_line_pixel_height (w);
17578 int window_total_lines
17579 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
17580
17581 this_scroll_margin =
17582 max (0, min (scroll_margin, window_total_lines / 4));
17583 this_scroll_margin *= frame_line_height;
17584 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17585
17586 if ((w->cursor.y < this_scroll_margin
17587 && CHARPOS (start) > BEGV)
17588 /* Old redisplay didn't take scroll margin into account at the bottom,
17589 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17590 || (w->cursor.y + (make_cursor_line_fully_visible_p
17591 ? cursor_height + this_scroll_margin
17592 : 1)) > it.last_visible_y)
17593 {
17594 w->cursor.vpos = -1;
17595 clear_glyph_matrix (w->desired_matrix);
17596 return -1;
17597 }
17598 }
17599
17600 /* Scroll the display. Do it before changing the current matrix so
17601 that xterm.c doesn't get confused about where the cursor glyph is
17602 found. */
17603 if (dy && run.height)
17604 {
17605 update_begin (f);
17606
17607 if (FRAME_WINDOW_P (f))
17608 {
17609 FRAME_RIF (f)->update_window_begin_hook (w);
17610 FRAME_RIF (f)->clear_window_mouse_face (w);
17611 FRAME_RIF (f)->scroll_run_hook (w, &run);
17612 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17613 }
17614 else
17615 {
17616 /* Terminal frame. In this case, dvpos gives the number of
17617 lines to scroll by; dvpos < 0 means scroll up. */
17618 int from_vpos
17619 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17620 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17621 int end = (WINDOW_TOP_EDGE_LINE (w)
17622 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17623 + window_internal_height (w));
17624
17625 #if defined (HAVE_GPM) || defined (MSDOS)
17626 x_clear_window_mouse_face (w);
17627 #endif
17628 /* Perform the operation on the screen. */
17629 if (dvpos > 0)
17630 {
17631 /* Scroll last_unchanged_at_beg_row to the end of the
17632 window down dvpos lines. */
17633 set_terminal_window (f, end);
17634
17635 /* On dumb terminals delete dvpos lines at the end
17636 before inserting dvpos empty lines. */
17637 if (!FRAME_SCROLL_REGION_OK (f))
17638 ins_del_lines (f, end - dvpos, -dvpos);
17639
17640 /* Insert dvpos empty lines in front of
17641 last_unchanged_at_beg_row. */
17642 ins_del_lines (f, from, dvpos);
17643 }
17644 else if (dvpos < 0)
17645 {
17646 /* Scroll up last_unchanged_at_beg_vpos to the end of
17647 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17648 set_terminal_window (f, end);
17649
17650 /* Delete dvpos lines in front of
17651 last_unchanged_at_beg_vpos. ins_del_lines will set
17652 the cursor to the given vpos and emit |dvpos| delete
17653 line sequences. */
17654 ins_del_lines (f, from + dvpos, dvpos);
17655
17656 /* On a dumb terminal insert dvpos empty lines at the
17657 end. */
17658 if (!FRAME_SCROLL_REGION_OK (f))
17659 ins_del_lines (f, end + dvpos, -dvpos);
17660 }
17661
17662 set_terminal_window (f, 0);
17663 }
17664
17665 update_end (f);
17666 }
17667
17668 /* Shift reused rows of the current matrix to the right position.
17669 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17670 text. */
17671 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17672 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17673 if (dvpos < 0)
17674 {
17675 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17676 bottom_vpos, dvpos);
17677 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17678 bottom_vpos);
17679 }
17680 else if (dvpos > 0)
17681 {
17682 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17683 bottom_vpos, dvpos);
17684 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17685 first_unchanged_at_end_vpos + dvpos);
17686 }
17687
17688 /* For frame-based redisplay, make sure that current frame and window
17689 matrix are in sync with respect to glyph memory. */
17690 if (!FRAME_WINDOW_P (f))
17691 sync_frame_with_window_matrix_rows (w);
17692
17693 /* Adjust buffer positions in reused rows. */
17694 if (delta || delta_bytes)
17695 increment_matrix_positions (current_matrix,
17696 first_unchanged_at_end_vpos + dvpos,
17697 bottom_vpos, delta, delta_bytes);
17698
17699 /* Adjust Y positions. */
17700 if (dy)
17701 shift_glyph_matrix (w, current_matrix,
17702 first_unchanged_at_end_vpos + dvpos,
17703 bottom_vpos, dy);
17704
17705 if (first_unchanged_at_end_row)
17706 {
17707 first_unchanged_at_end_row += dvpos;
17708 if (first_unchanged_at_end_row->y >= it.last_visible_y
17709 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17710 first_unchanged_at_end_row = NULL;
17711 }
17712
17713 /* If scrolling up, there may be some lines to display at the end of
17714 the window. */
17715 last_text_row_at_end = NULL;
17716 if (dy < 0)
17717 {
17718 /* Scrolling up can leave for example a partially visible line
17719 at the end of the window to be redisplayed. */
17720 /* Set last_row to the glyph row in the current matrix where the
17721 window end line is found. It has been moved up or down in
17722 the matrix by dvpos. */
17723 int last_vpos = w->window_end_vpos + dvpos;
17724 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17725
17726 /* If last_row is the window end line, it should display text. */
17727 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17728
17729 /* If window end line was partially visible before, begin
17730 displaying at that line. Otherwise begin displaying with the
17731 line following it. */
17732 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17733 {
17734 init_to_row_start (&it, w, last_row);
17735 it.vpos = last_vpos;
17736 it.current_y = last_row->y;
17737 }
17738 else
17739 {
17740 init_to_row_end (&it, w, last_row);
17741 it.vpos = 1 + last_vpos;
17742 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17743 ++last_row;
17744 }
17745
17746 /* We may start in a continuation line. If so, we have to
17747 get the right continuation_lines_width and current_x. */
17748 it.continuation_lines_width = last_row->continuation_lines_width;
17749 it.hpos = it.current_x = 0;
17750
17751 /* Display the rest of the lines at the window end. */
17752 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17753 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17754 {
17755 /* Is it always sure that the display agrees with lines in
17756 the current matrix? I don't think so, so we mark rows
17757 displayed invalid in the current matrix by setting their
17758 enabled_p flag to zero. */
17759 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17760 if (display_line (&it))
17761 last_text_row_at_end = it.glyph_row - 1;
17762 }
17763 }
17764
17765 /* Update window_end_pos and window_end_vpos. */
17766 if (first_unchanged_at_end_row && !last_text_row_at_end)
17767 {
17768 /* Window end line if one of the preserved rows from the current
17769 matrix. Set row to the last row displaying text in current
17770 matrix starting at first_unchanged_at_end_row, after
17771 scrolling. */
17772 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17773 row = find_last_row_displaying_text (w->current_matrix, &it,
17774 first_unchanged_at_end_row);
17775 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17776 adjust_window_ends (w, row, 1);
17777 eassert (w->window_end_bytepos >= 0);
17778 IF_DEBUG (debug_method_add (w, "A"));
17779 }
17780 else if (last_text_row_at_end)
17781 {
17782 adjust_window_ends (w, last_text_row_at_end, 0);
17783 eassert (w->window_end_bytepos >= 0);
17784 IF_DEBUG (debug_method_add (w, "B"));
17785 }
17786 else if (last_text_row)
17787 {
17788 /* We have displayed either to the end of the window or at the
17789 end of the window, i.e. the last row with text is to be found
17790 in the desired matrix. */
17791 adjust_window_ends (w, last_text_row, 0);
17792 eassert (w->window_end_bytepos >= 0);
17793 }
17794 else if (first_unchanged_at_end_row == NULL
17795 && last_text_row == NULL
17796 && last_text_row_at_end == NULL)
17797 {
17798 /* Displayed to end of window, but no line containing text was
17799 displayed. Lines were deleted at the end of the window. */
17800 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17801 int vpos = w->window_end_vpos;
17802 struct glyph_row *current_row = current_matrix->rows + vpos;
17803 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17804
17805 for (row = NULL;
17806 row == NULL && vpos >= first_vpos;
17807 --vpos, --current_row, --desired_row)
17808 {
17809 if (desired_row->enabled_p)
17810 {
17811 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17812 row = desired_row;
17813 }
17814 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17815 row = current_row;
17816 }
17817
17818 eassert (row != NULL);
17819 w->window_end_vpos = vpos + 1;
17820 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17821 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17822 eassert (w->window_end_bytepos >= 0);
17823 IF_DEBUG (debug_method_add (w, "C"));
17824 }
17825 else
17826 emacs_abort ();
17827
17828 IF_DEBUG (debug_end_pos = w->window_end_pos;
17829 debug_end_vpos = w->window_end_vpos);
17830
17831 /* Record that display has not been completed. */
17832 w->window_end_valid = 0;
17833 w->desired_matrix->no_scrolling_p = 1;
17834 return 3;
17835
17836 #undef GIVE_UP
17837 }
17838
17839
17840 \f
17841 /***********************************************************************
17842 More debugging support
17843 ***********************************************************************/
17844
17845 #ifdef GLYPH_DEBUG
17846
17847 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17848 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17849 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17850
17851
17852 /* Dump the contents of glyph matrix MATRIX on stderr.
17853
17854 GLYPHS 0 means don't show glyph contents.
17855 GLYPHS 1 means show glyphs in short form
17856 GLYPHS > 1 means show glyphs in long form. */
17857
17858 void
17859 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17860 {
17861 int i;
17862 for (i = 0; i < matrix->nrows; ++i)
17863 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17864 }
17865
17866
17867 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17868 the glyph row and area where the glyph comes from. */
17869
17870 void
17871 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17872 {
17873 if (glyph->type == CHAR_GLYPH
17874 || glyph->type == GLYPHLESS_GLYPH)
17875 {
17876 fprintf (stderr,
17877 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17878 glyph - row->glyphs[TEXT_AREA],
17879 (glyph->type == CHAR_GLYPH
17880 ? 'C'
17881 : 'G'),
17882 glyph->charpos,
17883 (BUFFERP (glyph->object)
17884 ? 'B'
17885 : (STRINGP (glyph->object)
17886 ? 'S'
17887 : (INTEGERP (glyph->object)
17888 ? '0'
17889 : '-'))),
17890 glyph->pixel_width,
17891 glyph->u.ch,
17892 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17893 ? glyph->u.ch
17894 : '.'),
17895 glyph->face_id,
17896 glyph->left_box_line_p,
17897 glyph->right_box_line_p);
17898 }
17899 else if (glyph->type == STRETCH_GLYPH)
17900 {
17901 fprintf (stderr,
17902 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17903 glyph - row->glyphs[TEXT_AREA],
17904 'S',
17905 glyph->charpos,
17906 (BUFFERP (glyph->object)
17907 ? 'B'
17908 : (STRINGP (glyph->object)
17909 ? 'S'
17910 : (INTEGERP (glyph->object)
17911 ? '0'
17912 : '-'))),
17913 glyph->pixel_width,
17914 0,
17915 ' ',
17916 glyph->face_id,
17917 glyph->left_box_line_p,
17918 glyph->right_box_line_p);
17919 }
17920 else if (glyph->type == IMAGE_GLYPH)
17921 {
17922 fprintf (stderr,
17923 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17924 glyph - row->glyphs[TEXT_AREA],
17925 'I',
17926 glyph->charpos,
17927 (BUFFERP (glyph->object)
17928 ? 'B'
17929 : (STRINGP (glyph->object)
17930 ? 'S'
17931 : (INTEGERP (glyph->object)
17932 ? '0'
17933 : '-'))),
17934 glyph->pixel_width,
17935 glyph->u.img_id,
17936 '.',
17937 glyph->face_id,
17938 glyph->left_box_line_p,
17939 glyph->right_box_line_p);
17940 }
17941 else if (glyph->type == COMPOSITE_GLYPH)
17942 {
17943 fprintf (stderr,
17944 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17945 glyph - row->glyphs[TEXT_AREA],
17946 '+',
17947 glyph->charpos,
17948 (BUFFERP (glyph->object)
17949 ? 'B'
17950 : (STRINGP (glyph->object)
17951 ? 'S'
17952 : (INTEGERP (glyph->object)
17953 ? '0'
17954 : '-'))),
17955 glyph->pixel_width,
17956 glyph->u.cmp.id);
17957 if (glyph->u.cmp.automatic)
17958 fprintf (stderr,
17959 "[%d-%d]",
17960 glyph->slice.cmp.from, glyph->slice.cmp.to);
17961 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17962 glyph->face_id,
17963 glyph->left_box_line_p,
17964 glyph->right_box_line_p);
17965 }
17966 }
17967
17968
17969 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17970 GLYPHS 0 means don't show glyph contents.
17971 GLYPHS 1 means show glyphs in short form
17972 GLYPHS > 1 means show glyphs in long form. */
17973
17974 void
17975 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17976 {
17977 if (glyphs != 1)
17978 {
17979 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17980 fprintf (stderr, "==============================================================================\n");
17981
17982 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17983 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17984 vpos,
17985 MATRIX_ROW_START_CHARPOS (row),
17986 MATRIX_ROW_END_CHARPOS (row),
17987 row->used[TEXT_AREA],
17988 row->contains_overlapping_glyphs_p,
17989 row->enabled_p,
17990 row->truncated_on_left_p,
17991 row->truncated_on_right_p,
17992 row->continued_p,
17993 MATRIX_ROW_CONTINUATION_LINE_P (row),
17994 MATRIX_ROW_DISPLAYS_TEXT_P (row),
17995 row->ends_at_zv_p,
17996 row->fill_line_p,
17997 row->ends_in_middle_of_char_p,
17998 row->starts_in_middle_of_char_p,
17999 row->mouse_face_p,
18000 row->x,
18001 row->y,
18002 row->pixel_width,
18003 row->height,
18004 row->visible_height,
18005 row->ascent,
18006 row->phys_ascent);
18007 /* The next 3 lines should align to "Start" in the header. */
18008 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18009 row->end.overlay_string_index,
18010 row->continuation_lines_width);
18011 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18012 CHARPOS (row->start.string_pos),
18013 CHARPOS (row->end.string_pos));
18014 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18015 row->end.dpvec_index);
18016 }
18017
18018 if (glyphs > 1)
18019 {
18020 int area;
18021
18022 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18023 {
18024 struct glyph *glyph = row->glyphs[area];
18025 struct glyph *glyph_end = glyph + row->used[area];
18026
18027 /* Glyph for a line end in text. */
18028 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18029 ++glyph_end;
18030
18031 if (glyph < glyph_end)
18032 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18033
18034 for (; glyph < glyph_end; ++glyph)
18035 dump_glyph (row, glyph, area);
18036 }
18037 }
18038 else if (glyphs == 1)
18039 {
18040 int area;
18041
18042 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18043 {
18044 char *s = alloca (row->used[area] + 4);
18045 int i;
18046
18047 for (i = 0; i < row->used[area]; ++i)
18048 {
18049 struct glyph *glyph = row->glyphs[area] + i;
18050 if (i == row->used[area] - 1
18051 && area == TEXT_AREA
18052 && INTEGERP (glyph->object)
18053 && glyph->type == CHAR_GLYPH
18054 && glyph->u.ch == ' ')
18055 {
18056 strcpy (&s[i], "[\\n]");
18057 i += 4;
18058 }
18059 else if (glyph->type == CHAR_GLYPH
18060 && glyph->u.ch < 0x80
18061 && glyph->u.ch >= ' ')
18062 s[i] = glyph->u.ch;
18063 else
18064 s[i] = '.';
18065 }
18066
18067 s[i] = '\0';
18068 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18069 }
18070 }
18071 }
18072
18073
18074 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18075 Sdump_glyph_matrix, 0, 1, "p",
18076 doc: /* Dump the current matrix of the selected window to stderr.
18077 Shows contents of glyph row structures. With non-nil
18078 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18079 glyphs in short form, otherwise show glyphs in long form. */)
18080 (Lisp_Object glyphs)
18081 {
18082 struct window *w = XWINDOW (selected_window);
18083 struct buffer *buffer = XBUFFER (w->contents);
18084
18085 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18086 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18087 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18088 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18089 fprintf (stderr, "=============================================\n");
18090 dump_glyph_matrix (w->current_matrix,
18091 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18092 return Qnil;
18093 }
18094
18095
18096 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18097 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18098 (void)
18099 {
18100 struct frame *f = XFRAME (selected_frame);
18101 dump_glyph_matrix (f->current_matrix, 1);
18102 return Qnil;
18103 }
18104
18105
18106 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18107 doc: /* Dump glyph row ROW to stderr.
18108 GLYPH 0 means don't dump glyphs.
18109 GLYPH 1 means dump glyphs in short form.
18110 GLYPH > 1 or omitted means dump glyphs in long form. */)
18111 (Lisp_Object row, Lisp_Object glyphs)
18112 {
18113 struct glyph_matrix *matrix;
18114 EMACS_INT vpos;
18115
18116 CHECK_NUMBER (row);
18117 matrix = XWINDOW (selected_window)->current_matrix;
18118 vpos = XINT (row);
18119 if (vpos >= 0 && vpos < matrix->nrows)
18120 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18121 vpos,
18122 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18123 return Qnil;
18124 }
18125
18126
18127 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18128 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18129 GLYPH 0 means don't dump glyphs.
18130 GLYPH 1 means dump glyphs in short form.
18131 GLYPH > 1 or omitted means dump glyphs in long form.
18132
18133 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
18134 do nothing. */)
18135 (Lisp_Object row, Lisp_Object glyphs)
18136 {
18137 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
18138 struct frame *sf = SELECTED_FRAME ();
18139 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18140 EMACS_INT vpos;
18141
18142 CHECK_NUMBER (row);
18143 vpos = XINT (row);
18144 if (vpos >= 0 && vpos < m->nrows)
18145 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18146 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18147 #endif
18148 return Qnil;
18149 }
18150
18151
18152 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18153 doc: /* Toggle tracing of redisplay.
18154 With ARG, turn tracing on if and only if ARG is positive. */)
18155 (Lisp_Object arg)
18156 {
18157 if (NILP (arg))
18158 trace_redisplay_p = !trace_redisplay_p;
18159 else
18160 {
18161 arg = Fprefix_numeric_value (arg);
18162 trace_redisplay_p = XINT (arg) > 0;
18163 }
18164
18165 return Qnil;
18166 }
18167
18168
18169 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18170 doc: /* Like `format', but print result to stderr.
18171 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18172 (ptrdiff_t nargs, Lisp_Object *args)
18173 {
18174 Lisp_Object s = Fformat (nargs, args);
18175 fprintf (stderr, "%s", SDATA (s));
18176 return Qnil;
18177 }
18178
18179 #endif /* GLYPH_DEBUG */
18180
18181
18182 \f
18183 /***********************************************************************
18184 Building Desired Matrix Rows
18185 ***********************************************************************/
18186
18187 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18188 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18189
18190 static struct glyph_row *
18191 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18192 {
18193 struct frame *f = XFRAME (WINDOW_FRAME (w));
18194 struct buffer *buffer = XBUFFER (w->contents);
18195 struct buffer *old = current_buffer;
18196 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18197 int arrow_len = SCHARS (overlay_arrow_string);
18198 const unsigned char *arrow_end = arrow_string + arrow_len;
18199 const unsigned char *p;
18200 struct it it;
18201 bool multibyte_p;
18202 int n_glyphs_before;
18203
18204 set_buffer_temp (buffer);
18205 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18206 it.glyph_row->used[TEXT_AREA] = 0;
18207 SET_TEXT_POS (it.position, 0, 0);
18208
18209 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18210 p = arrow_string;
18211 while (p < arrow_end)
18212 {
18213 Lisp_Object face, ilisp;
18214
18215 /* Get the next character. */
18216 if (multibyte_p)
18217 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18218 else
18219 {
18220 it.c = it.char_to_display = *p, it.len = 1;
18221 if (! ASCII_CHAR_P (it.c))
18222 it.char_to_display = BYTE8_TO_CHAR (it.c);
18223 }
18224 p += it.len;
18225
18226 /* Get its face. */
18227 ilisp = make_number (p - arrow_string);
18228 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18229 it.face_id = compute_char_face (f, it.char_to_display, face);
18230
18231 /* Compute its width, get its glyphs. */
18232 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18233 SET_TEXT_POS (it.position, -1, -1);
18234 PRODUCE_GLYPHS (&it);
18235
18236 /* If this character doesn't fit any more in the line, we have
18237 to remove some glyphs. */
18238 if (it.current_x > it.last_visible_x)
18239 {
18240 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18241 break;
18242 }
18243 }
18244
18245 set_buffer_temp (old);
18246 return it.glyph_row;
18247 }
18248
18249
18250 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18251 glyphs to insert is determined by produce_special_glyphs. */
18252
18253 static void
18254 insert_left_trunc_glyphs (struct it *it)
18255 {
18256 struct it truncate_it;
18257 struct glyph *from, *end, *to, *toend;
18258
18259 eassert (!FRAME_WINDOW_P (it->f)
18260 || (!it->glyph_row->reversed_p
18261 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18262 || (it->glyph_row->reversed_p
18263 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18264
18265 /* Get the truncation glyphs. */
18266 truncate_it = *it;
18267 truncate_it.current_x = 0;
18268 truncate_it.face_id = DEFAULT_FACE_ID;
18269 truncate_it.glyph_row = &scratch_glyph_row;
18270 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18271 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18272 truncate_it.object = make_number (0);
18273 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18274
18275 /* Overwrite glyphs from IT with truncation glyphs. */
18276 if (!it->glyph_row->reversed_p)
18277 {
18278 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18279
18280 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18281 end = from + tused;
18282 to = it->glyph_row->glyphs[TEXT_AREA];
18283 toend = to + it->glyph_row->used[TEXT_AREA];
18284 if (FRAME_WINDOW_P (it->f))
18285 {
18286 /* On GUI frames, when variable-size fonts are displayed,
18287 the truncation glyphs may need more pixels than the row's
18288 glyphs they overwrite. We overwrite more glyphs to free
18289 enough screen real estate, and enlarge the stretch glyph
18290 on the right (see display_line), if there is one, to
18291 preserve the screen position of the truncation glyphs on
18292 the right. */
18293 int w = 0;
18294 struct glyph *g = to;
18295 short used;
18296
18297 /* The first glyph could be partially visible, in which case
18298 it->glyph_row->x will be negative. But we want the left
18299 truncation glyphs to be aligned at the left margin of the
18300 window, so we override the x coordinate at which the row
18301 will begin. */
18302 it->glyph_row->x = 0;
18303 while (g < toend && w < it->truncation_pixel_width)
18304 {
18305 w += g->pixel_width;
18306 ++g;
18307 }
18308 if (g - to - tused > 0)
18309 {
18310 memmove (to + tused, g, (toend - g) * sizeof(*g));
18311 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18312 }
18313 used = it->glyph_row->used[TEXT_AREA];
18314 if (it->glyph_row->truncated_on_right_p
18315 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18316 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18317 == STRETCH_GLYPH)
18318 {
18319 int extra = w - it->truncation_pixel_width;
18320
18321 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18322 }
18323 }
18324
18325 while (from < end)
18326 *to++ = *from++;
18327
18328 /* There may be padding glyphs left over. Overwrite them too. */
18329 if (!FRAME_WINDOW_P (it->f))
18330 {
18331 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18332 {
18333 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18334 while (from < end)
18335 *to++ = *from++;
18336 }
18337 }
18338
18339 if (to > toend)
18340 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18341 }
18342 else
18343 {
18344 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18345
18346 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18347 that back to front. */
18348 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18349 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18350 toend = it->glyph_row->glyphs[TEXT_AREA];
18351 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18352 if (FRAME_WINDOW_P (it->f))
18353 {
18354 int w = 0;
18355 struct glyph *g = to;
18356
18357 while (g >= toend && w < it->truncation_pixel_width)
18358 {
18359 w += g->pixel_width;
18360 --g;
18361 }
18362 if (to - g - tused > 0)
18363 to = g + tused;
18364 if (it->glyph_row->truncated_on_right_p
18365 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18366 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18367 {
18368 int extra = w - it->truncation_pixel_width;
18369
18370 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18371 }
18372 }
18373
18374 while (from >= end && to >= toend)
18375 *to-- = *from--;
18376 if (!FRAME_WINDOW_P (it->f))
18377 {
18378 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18379 {
18380 from =
18381 truncate_it.glyph_row->glyphs[TEXT_AREA]
18382 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18383 while (from >= end && to >= toend)
18384 *to-- = *from--;
18385 }
18386 }
18387 if (from >= end)
18388 {
18389 /* Need to free some room before prepending additional
18390 glyphs. */
18391 int move_by = from - end + 1;
18392 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18393 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18394
18395 for ( ; g >= g0; g--)
18396 g[move_by] = *g;
18397 while (from >= end)
18398 *to-- = *from--;
18399 it->glyph_row->used[TEXT_AREA] += move_by;
18400 }
18401 }
18402 }
18403
18404 /* Compute the hash code for ROW. */
18405 unsigned
18406 row_hash (struct glyph_row *row)
18407 {
18408 int area, k;
18409 unsigned hashval = 0;
18410
18411 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18412 for (k = 0; k < row->used[area]; ++k)
18413 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18414 + row->glyphs[area][k].u.val
18415 + row->glyphs[area][k].face_id
18416 + row->glyphs[area][k].padding_p
18417 + (row->glyphs[area][k].type << 2));
18418
18419 return hashval;
18420 }
18421
18422 /* Compute the pixel height and width of IT->glyph_row.
18423
18424 Most of the time, ascent and height of a display line will be equal
18425 to the max_ascent and max_height values of the display iterator
18426 structure. This is not the case if
18427
18428 1. We hit ZV without displaying anything. In this case, max_ascent
18429 and max_height will be zero.
18430
18431 2. We have some glyphs that don't contribute to the line height.
18432 (The glyph row flag contributes_to_line_height_p is for future
18433 pixmap extensions).
18434
18435 The first case is easily covered by using default values because in
18436 these cases, the line height does not really matter, except that it
18437 must not be zero. */
18438
18439 static void
18440 compute_line_metrics (struct it *it)
18441 {
18442 struct glyph_row *row = it->glyph_row;
18443
18444 if (FRAME_WINDOW_P (it->f))
18445 {
18446 int i, min_y, max_y;
18447
18448 /* The line may consist of one space only, that was added to
18449 place the cursor on it. If so, the row's height hasn't been
18450 computed yet. */
18451 if (row->height == 0)
18452 {
18453 if (it->max_ascent + it->max_descent == 0)
18454 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18455 row->ascent = it->max_ascent;
18456 row->height = it->max_ascent + it->max_descent;
18457 row->phys_ascent = it->max_phys_ascent;
18458 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18459 row->extra_line_spacing = it->max_extra_line_spacing;
18460 }
18461
18462 /* Compute the width of this line. */
18463 row->pixel_width = row->x;
18464 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18465 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18466
18467 eassert (row->pixel_width >= 0);
18468 eassert (row->ascent >= 0 && row->height > 0);
18469
18470 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18471 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18472
18473 /* If first line's physical ascent is larger than its logical
18474 ascent, use the physical ascent, and make the row taller.
18475 This makes accented characters fully visible. */
18476 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18477 && row->phys_ascent > row->ascent)
18478 {
18479 row->height += row->phys_ascent - row->ascent;
18480 row->ascent = row->phys_ascent;
18481 }
18482
18483 /* Compute how much of the line is visible. */
18484 row->visible_height = row->height;
18485
18486 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18487 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18488
18489 if (row->y < min_y)
18490 row->visible_height -= min_y - row->y;
18491 if (row->y + row->height > max_y)
18492 row->visible_height -= row->y + row->height - max_y;
18493 }
18494 else
18495 {
18496 row->pixel_width = row->used[TEXT_AREA];
18497 if (row->continued_p)
18498 row->pixel_width -= it->continuation_pixel_width;
18499 else if (row->truncated_on_right_p)
18500 row->pixel_width -= it->truncation_pixel_width;
18501 row->ascent = row->phys_ascent = 0;
18502 row->height = row->phys_height = row->visible_height = 1;
18503 row->extra_line_spacing = 0;
18504 }
18505
18506 /* Compute a hash code for this row. */
18507 row->hash = row_hash (row);
18508
18509 it->max_ascent = it->max_descent = 0;
18510 it->max_phys_ascent = it->max_phys_descent = 0;
18511 }
18512
18513
18514 /* Append one space to the glyph row of iterator IT if doing a
18515 window-based redisplay. The space has the same face as
18516 IT->face_id. Value is non-zero if a space was added.
18517
18518 This function is called to make sure that there is always one glyph
18519 at the end of a glyph row that the cursor can be set on under
18520 window-systems. (If there weren't such a glyph we would not know
18521 how wide and tall a box cursor should be displayed).
18522
18523 At the same time this space let's a nicely handle clearing to the
18524 end of the line if the row ends in italic text. */
18525
18526 static int
18527 append_space_for_newline (struct it *it, int default_face_p)
18528 {
18529 if (FRAME_WINDOW_P (it->f))
18530 {
18531 int n = it->glyph_row->used[TEXT_AREA];
18532
18533 if (it->glyph_row->glyphs[TEXT_AREA] + n
18534 < it->glyph_row->glyphs[1 + TEXT_AREA])
18535 {
18536 /* Save some values that must not be changed.
18537 Must save IT->c and IT->len because otherwise
18538 ITERATOR_AT_END_P wouldn't work anymore after
18539 append_space_for_newline has been called. */
18540 enum display_element_type saved_what = it->what;
18541 int saved_c = it->c, saved_len = it->len;
18542 int saved_char_to_display = it->char_to_display;
18543 int saved_x = it->current_x;
18544 int saved_face_id = it->face_id;
18545 int saved_box_end = it->end_of_box_run_p;
18546 struct text_pos saved_pos;
18547 Lisp_Object saved_object;
18548 struct face *face;
18549
18550 saved_object = it->object;
18551 saved_pos = it->position;
18552
18553 it->what = IT_CHARACTER;
18554 memset (&it->position, 0, sizeof it->position);
18555 it->object = make_number (0);
18556 it->c = it->char_to_display = ' ';
18557 it->len = 1;
18558
18559 /* If the default face was remapped, be sure to use the
18560 remapped face for the appended newline. */
18561 if (default_face_p)
18562 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18563 else if (it->face_before_selective_p)
18564 it->face_id = it->saved_face_id;
18565 face = FACE_FROM_ID (it->f, it->face_id);
18566 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18567 /* In R2L rows, we will prepend a stretch glyph that will
18568 have the end_of_box_run_p flag set for it, so there's no
18569 need for the appended newline glyph to have that flag
18570 set. */
18571 if (it->glyph_row->reversed_p
18572 /* But if the appended newline glyph goes all the way to
18573 the end of the row, there will be no stretch glyph,
18574 so leave the box flag set. */
18575 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18576 it->end_of_box_run_p = 0;
18577
18578 PRODUCE_GLYPHS (it);
18579
18580 it->override_ascent = -1;
18581 it->constrain_row_ascent_descent_p = 0;
18582 it->current_x = saved_x;
18583 it->object = saved_object;
18584 it->position = saved_pos;
18585 it->what = saved_what;
18586 it->face_id = saved_face_id;
18587 it->len = saved_len;
18588 it->c = saved_c;
18589 it->char_to_display = saved_char_to_display;
18590 it->end_of_box_run_p = saved_box_end;
18591 return 1;
18592 }
18593 }
18594
18595 return 0;
18596 }
18597
18598
18599 /* Extend the face of the last glyph in the text area of IT->glyph_row
18600 to the end of the display line. Called from display_line. If the
18601 glyph row is empty, add a space glyph to it so that we know the
18602 face to draw. Set the glyph row flag fill_line_p. If the glyph
18603 row is R2L, prepend a stretch glyph to cover the empty space to the
18604 left of the leftmost glyph. */
18605
18606 static void
18607 extend_face_to_end_of_line (struct it *it)
18608 {
18609 struct face *face, *default_face;
18610 struct frame *f = it->f;
18611
18612 /* If line is already filled, do nothing. Non window-system frames
18613 get a grace of one more ``pixel'' because their characters are
18614 1-``pixel'' wide, so they hit the equality too early. This grace
18615 is needed only for R2L rows that are not continued, to produce
18616 one extra blank where we could display the cursor. */
18617 if (it->current_x >= it->last_visible_x
18618 + (!FRAME_WINDOW_P (f)
18619 && it->glyph_row->reversed_p
18620 && !it->glyph_row->continued_p))
18621 return;
18622
18623 /* The default face, possibly remapped. */
18624 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18625
18626 /* Face extension extends the background and box of IT->face_id
18627 to the end of the line. If the background equals the background
18628 of the frame, we don't have to do anything. */
18629 if (it->face_before_selective_p)
18630 face = FACE_FROM_ID (f, it->saved_face_id);
18631 else
18632 face = FACE_FROM_ID (f, it->face_id);
18633
18634 if (FRAME_WINDOW_P (f)
18635 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18636 && face->box == FACE_NO_BOX
18637 && face->background == FRAME_BACKGROUND_PIXEL (f)
18638 #ifdef HAVE_WINDOW_SYSTEM
18639 && !face->stipple
18640 #endif
18641 && !it->glyph_row->reversed_p)
18642 return;
18643
18644 /* Set the glyph row flag indicating that the face of the last glyph
18645 in the text area has to be drawn to the end of the text area. */
18646 it->glyph_row->fill_line_p = 1;
18647
18648 /* If current character of IT is not ASCII, make sure we have the
18649 ASCII face. This will be automatically undone the next time
18650 get_next_display_element returns a multibyte character. Note
18651 that the character will always be single byte in unibyte
18652 text. */
18653 if (!ASCII_CHAR_P (it->c))
18654 {
18655 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18656 }
18657
18658 if (FRAME_WINDOW_P (f))
18659 {
18660 /* If the row is empty, add a space with the current face of IT,
18661 so that we know which face to draw. */
18662 if (it->glyph_row->used[TEXT_AREA] == 0)
18663 {
18664 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18665 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18666 it->glyph_row->used[TEXT_AREA] = 1;
18667 }
18668 #ifdef HAVE_WINDOW_SYSTEM
18669 if (it->glyph_row->reversed_p)
18670 {
18671 /* Prepend a stretch glyph to the row, such that the
18672 rightmost glyph will be drawn flushed all the way to the
18673 right margin of the window. The stretch glyph that will
18674 occupy the empty space, if any, to the left of the
18675 glyphs. */
18676 struct font *font = face->font ? face->font : FRAME_FONT (f);
18677 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18678 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18679 struct glyph *g;
18680 int row_width, stretch_ascent, stretch_width;
18681 struct text_pos saved_pos;
18682 int saved_face_id, saved_avoid_cursor, saved_box_start;
18683
18684 for (row_width = 0, g = row_start; g < row_end; g++)
18685 row_width += g->pixel_width;
18686 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18687 if (stretch_width > 0)
18688 {
18689 stretch_ascent =
18690 (((it->ascent + it->descent)
18691 * FONT_BASE (font)) / FONT_HEIGHT (font));
18692 saved_pos = it->position;
18693 memset (&it->position, 0, sizeof it->position);
18694 saved_avoid_cursor = it->avoid_cursor_p;
18695 it->avoid_cursor_p = 1;
18696 saved_face_id = it->face_id;
18697 saved_box_start = it->start_of_box_run_p;
18698 /* The last row's stretch glyph should get the default
18699 face, to avoid painting the rest of the window with
18700 the region face, if the region ends at ZV. */
18701 if (it->glyph_row->ends_at_zv_p)
18702 it->face_id = default_face->id;
18703 else
18704 it->face_id = face->id;
18705 it->start_of_box_run_p = 0;
18706 append_stretch_glyph (it, make_number (0), stretch_width,
18707 it->ascent + it->descent, stretch_ascent);
18708 it->position = saved_pos;
18709 it->avoid_cursor_p = saved_avoid_cursor;
18710 it->face_id = saved_face_id;
18711 it->start_of_box_run_p = saved_box_start;
18712 }
18713 }
18714 #endif /* HAVE_WINDOW_SYSTEM */
18715 }
18716 else
18717 {
18718 /* Save some values that must not be changed. */
18719 int saved_x = it->current_x;
18720 struct text_pos saved_pos;
18721 Lisp_Object saved_object;
18722 enum display_element_type saved_what = it->what;
18723 int saved_face_id = it->face_id;
18724
18725 saved_object = it->object;
18726 saved_pos = it->position;
18727
18728 it->what = IT_CHARACTER;
18729 memset (&it->position, 0, sizeof it->position);
18730 it->object = make_number (0);
18731 it->c = it->char_to_display = ' ';
18732 it->len = 1;
18733 /* The last row's blank glyphs should get the default face, to
18734 avoid painting the rest of the window with the region face,
18735 if the region ends at ZV. */
18736 if (it->glyph_row->ends_at_zv_p)
18737 it->face_id = default_face->id;
18738 else
18739 it->face_id = face->id;
18740
18741 PRODUCE_GLYPHS (it);
18742
18743 while (it->current_x <= it->last_visible_x)
18744 PRODUCE_GLYPHS (it);
18745
18746 /* Don't count these blanks really. It would let us insert a left
18747 truncation glyph below and make us set the cursor on them, maybe. */
18748 it->current_x = saved_x;
18749 it->object = saved_object;
18750 it->position = saved_pos;
18751 it->what = saved_what;
18752 it->face_id = saved_face_id;
18753 }
18754 }
18755
18756
18757 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18758 trailing whitespace. */
18759
18760 static int
18761 trailing_whitespace_p (ptrdiff_t charpos)
18762 {
18763 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18764 int c = 0;
18765
18766 while (bytepos < ZV_BYTE
18767 && (c = FETCH_CHAR (bytepos),
18768 c == ' ' || c == '\t'))
18769 ++bytepos;
18770
18771 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18772 {
18773 if (bytepos != PT_BYTE)
18774 return 1;
18775 }
18776 return 0;
18777 }
18778
18779
18780 /* Highlight trailing whitespace, if any, in ROW. */
18781
18782 static void
18783 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18784 {
18785 int used = row->used[TEXT_AREA];
18786
18787 if (used)
18788 {
18789 struct glyph *start = row->glyphs[TEXT_AREA];
18790 struct glyph *glyph = start + used - 1;
18791
18792 if (row->reversed_p)
18793 {
18794 /* Right-to-left rows need to be processed in the opposite
18795 direction, so swap the edge pointers. */
18796 glyph = start;
18797 start = row->glyphs[TEXT_AREA] + used - 1;
18798 }
18799
18800 /* Skip over glyphs inserted to display the cursor at the
18801 end of a line, for extending the face of the last glyph
18802 to the end of the line on terminals, and for truncation
18803 and continuation glyphs. */
18804 if (!row->reversed_p)
18805 {
18806 while (glyph >= start
18807 && glyph->type == CHAR_GLYPH
18808 && INTEGERP (glyph->object))
18809 --glyph;
18810 }
18811 else
18812 {
18813 while (glyph <= start
18814 && glyph->type == CHAR_GLYPH
18815 && INTEGERP (glyph->object))
18816 ++glyph;
18817 }
18818
18819 /* If last glyph is a space or stretch, and it's trailing
18820 whitespace, set the face of all trailing whitespace glyphs in
18821 IT->glyph_row to `trailing-whitespace'. */
18822 if ((row->reversed_p ? glyph <= start : glyph >= start)
18823 && BUFFERP (glyph->object)
18824 && (glyph->type == STRETCH_GLYPH
18825 || (glyph->type == CHAR_GLYPH
18826 && glyph->u.ch == ' '))
18827 && trailing_whitespace_p (glyph->charpos))
18828 {
18829 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18830 if (face_id < 0)
18831 return;
18832
18833 if (!row->reversed_p)
18834 {
18835 while (glyph >= start
18836 && BUFFERP (glyph->object)
18837 && (glyph->type == STRETCH_GLYPH
18838 || (glyph->type == CHAR_GLYPH
18839 && glyph->u.ch == ' ')))
18840 (glyph--)->face_id = face_id;
18841 }
18842 else
18843 {
18844 while (glyph <= start
18845 && BUFFERP (glyph->object)
18846 && (glyph->type == STRETCH_GLYPH
18847 || (glyph->type == CHAR_GLYPH
18848 && glyph->u.ch == ' ')))
18849 (glyph++)->face_id = face_id;
18850 }
18851 }
18852 }
18853 }
18854
18855
18856 /* Value is non-zero if glyph row ROW should be
18857 considered to hold the buffer position CHARPOS. */
18858
18859 static int
18860 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18861 {
18862 int result = 1;
18863
18864 if (charpos == CHARPOS (row->end.pos)
18865 || charpos == MATRIX_ROW_END_CHARPOS (row))
18866 {
18867 /* Suppose the row ends on a string.
18868 Unless the row is continued, that means it ends on a newline
18869 in the string. If it's anything other than a display string
18870 (e.g., a before-string from an overlay), we don't want the
18871 cursor there. (This heuristic seems to give the optimal
18872 behavior for the various types of multi-line strings.)
18873 One exception: if the string has `cursor' property on one of
18874 its characters, we _do_ want the cursor there. */
18875 if (CHARPOS (row->end.string_pos) >= 0)
18876 {
18877 if (row->continued_p)
18878 result = 1;
18879 else
18880 {
18881 /* Check for `display' property. */
18882 struct glyph *beg = row->glyphs[TEXT_AREA];
18883 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18884 struct glyph *glyph;
18885
18886 result = 0;
18887 for (glyph = end; glyph >= beg; --glyph)
18888 if (STRINGP (glyph->object))
18889 {
18890 Lisp_Object prop
18891 = Fget_char_property (make_number (charpos),
18892 Qdisplay, Qnil);
18893 result =
18894 (!NILP (prop)
18895 && display_prop_string_p (prop, glyph->object));
18896 /* If there's a `cursor' property on one of the
18897 string's characters, this row is a cursor row,
18898 even though this is not a display string. */
18899 if (!result)
18900 {
18901 Lisp_Object s = glyph->object;
18902
18903 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18904 {
18905 ptrdiff_t gpos = glyph->charpos;
18906
18907 if (!NILP (Fget_char_property (make_number (gpos),
18908 Qcursor, s)))
18909 {
18910 result = 1;
18911 break;
18912 }
18913 }
18914 }
18915 break;
18916 }
18917 }
18918 }
18919 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18920 {
18921 /* If the row ends in middle of a real character,
18922 and the line is continued, we want the cursor here.
18923 That's because CHARPOS (ROW->end.pos) would equal
18924 PT if PT is before the character. */
18925 if (!row->ends_in_ellipsis_p)
18926 result = row->continued_p;
18927 else
18928 /* If the row ends in an ellipsis, then
18929 CHARPOS (ROW->end.pos) will equal point after the
18930 invisible text. We want that position to be displayed
18931 after the ellipsis. */
18932 result = 0;
18933 }
18934 /* If the row ends at ZV, display the cursor at the end of that
18935 row instead of at the start of the row below. */
18936 else if (row->ends_at_zv_p)
18937 result = 1;
18938 else
18939 result = 0;
18940 }
18941
18942 return result;
18943 }
18944
18945 /* Value is non-zero if glyph row ROW should be
18946 used to hold the cursor. */
18947
18948 static int
18949 cursor_row_p (struct glyph_row *row)
18950 {
18951 return row_for_charpos_p (row, PT);
18952 }
18953
18954 \f
18955
18956 /* Push the property PROP so that it will be rendered at the current
18957 position in IT. Return 1 if PROP was successfully pushed, 0
18958 otherwise. Called from handle_line_prefix to handle the
18959 `line-prefix' and `wrap-prefix' properties. */
18960
18961 static int
18962 push_prefix_prop (struct it *it, Lisp_Object prop)
18963 {
18964 struct text_pos pos =
18965 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18966
18967 eassert (it->method == GET_FROM_BUFFER
18968 || it->method == GET_FROM_DISPLAY_VECTOR
18969 || it->method == GET_FROM_STRING);
18970
18971 /* We need to save the current buffer/string position, so it will be
18972 restored by pop_it, because iterate_out_of_display_property
18973 depends on that being set correctly, but some situations leave
18974 it->position not yet set when this function is called. */
18975 push_it (it, &pos);
18976
18977 if (STRINGP (prop))
18978 {
18979 if (SCHARS (prop) == 0)
18980 {
18981 pop_it (it);
18982 return 0;
18983 }
18984
18985 it->string = prop;
18986 it->string_from_prefix_prop_p = 1;
18987 it->multibyte_p = STRING_MULTIBYTE (it->string);
18988 it->current.overlay_string_index = -1;
18989 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18990 it->end_charpos = it->string_nchars = SCHARS (it->string);
18991 it->method = GET_FROM_STRING;
18992 it->stop_charpos = 0;
18993 it->prev_stop = 0;
18994 it->base_level_stop = 0;
18995
18996 /* Force paragraph direction to be that of the parent
18997 buffer/string. */
18998 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18999 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19000 else
19001 it->paragraph_embedding = L2R;
19002
19003 /* Set up the bidi iterator for this display string. */
19004 if (it->bidi_p)
19005 {
19006 it->bidi_it.string.lstring = it->string;
19007 it->bidi_it.string.s = NULL;
19008 it->bidi_it.string.schars = it->end_charpos;
19009 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19010 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19011 it->bidi_it.string.unibyte = !it->multibyte_p;
19012 it->bidi_it.w = it->w;
19013 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19014 }
19015 }
19016 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19017 {
19018 it->method = GET_FROM_STRETCH;
19019 it->object = prop;
19020 }
19021 #ifdef HAVE_WINDOW_SYSTEM
19022 else if (IMAGEP (prop))
19023 {
19024 it->what = IT_IMAGE;
19025 it->image_id = lookup_image (it->f, prop);
19026 it->method = GET_FROM_IMAGE;
19027 }
19028 #endif /* HAVE_WINDOW_SYSTEM */
19029 else
19030 {
19031 pop_it (it); /* bogus display property, give up */
19032 return 0;
19033 }
19034
19035 return 1;
19036 }
19037
19038 /* Return the character-property PROP at the current position in IT. */
19039
19040 static Lisp_Object
19041 get_it_property (struct it *it, Lisp_Object prop)
19042 {
19043 Lisp_Object position, object = it->object;
19044
19045 if (STRINGP (object))
19046 position = make_number (IT_STRING_CHARPOS (*it));
19047 else if (BUFFERP (object))
19048 {
19049 position = make_number (IT_CHARPOS (*it));
19050 object = it->window;
19051 }
19052 else
19053 return Qnil;
19054
19055 return Fget_char_property (position, prop, object);
19056 }
19057
19058 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19059
19060 static void
19061 handle_line_prefix (struct it *it)
19062 {
19063 Lisp_Object prefix;
19064
19065 if (it->continuation_lines_width > 0)
19066 {
19067 prefix = get_it_property (it, Qwrap_prefix);
19068 if (NILP (prefix))
19069 prefix = Vwrap_prefix;
19070 }
19071 else
19072 {
19073 prefix = get_it_property (it, Qline_prefix);
19074 if (NILP (prefix))
19075 prefix = Vline_prefix;
19076 }
19077 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19078 {
19079 /* If the prefix is wider than the window, and we try to wrap
19080 it, it would acquire its own wrap prefix, and so on till the
19081 iterator stack overflows. So, don't wrap the prefix. */
19082 it->line_wrap = TRUNCATE;
19083 it->avoid_cursor_p = 1;
19084 }
19085 }
19086
19087 \f
19088
19089 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19090 only for R2L lines from display_line and display_string, when they
19091 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19092 the line/string needs to be continued on the next glyph row. */
19093 static void
19094 unproduce_glyphs (struct it *it, int n)
19095 {
19096 struct glyph *glyph, *end;
19097
19098 eassert (it->glyph_row);
19099 eassert (it->glyph_row->reversed_p);
19100 eassert (it->area == TEXT_AREA);
19101 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19102
19103 if (n > it->glyph_row->used[TEXT_AREA])
19104 n = it->glyph_row->used[TEXT_AREA];
19105 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19106 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19107 for ( ; glyph < end; glyph++)
19108 glyph[-n] = *glyph;
19109 }
19110
19111 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19112 and ROW->maxpos. */
19113 static void
19114 find_row_edges (struct it *it, struct glyph_row *row,
19115 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19116 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19117 {
19118 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19119 lines' rows is implemented for bidi-reordered rows. */
19120
19121 /* ROW->minpos is the value of min_pos, the minimal buffer position
19122 we have in ROW, or ROW->start.pos if that is smaller. */
19123 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19124 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19125 else
19126 /* We didn't find buffer positions smaller than ROW->start, or
19127 didn't find _any_ valid buffer positions in any of the glyphs,
19128 so we must trust the iterator's computed positions. */
19129 row->minpos = row->start.pos;
19130 if (max_pos <= 0)
19131 {
19132 max_pos = CHARPOS (it->current.pos);
19133 max_bpos = BYTEPOS (it->current.pos);
19134 }
19135
19136 /* Here are the various use-cases for ending the row, and the
19137 corresponding values for ROW->maxpos:
19138
19139 Line ends in a newline from buffer eol_pos + 1
19140 Line is continued from buffer max_pos + 1
19141 Line is truncated on right it->current.pos
19142 Line ends in a newline from string max_pos + 1(*)
19143 (*) + 1 only when line ends in a forward scan
19144 Line is continued from string max_pos
19145 Line is continued from display vector max_pos
19146 Line is entirely from a string min_pos == max_pos
19147 Line is entirely from a display vector min_pos == max_pos
19148 Line that ends at ZV ZV
19149
19150 If you discover other use-cases, please add them here as
19151 appropriate. */
19152 if (row->ends_at_zv_p)
19153 row->maxpos = it->current.pos;
19154 else if (row->used[TEXT_AREA])
19155 {
19156 int seen_this_string = 0;
19157 struct glyph_row *r1 = row - 1;
19158
19159 /* Did we see the same display string on the previous row? */
19160 if (STRINGP (it->object)
19161 /* this is not the first row */
19162 && row > it->w->desired_matrix->rows
19163 /* previous row is not the header line */
19164 && !r1->mode_line_p
19165 /* previous row also ends in a newline from a string */
19166 && r1->ends_in_newline_from_string_p)
19167 {
19168 struct glyph *start, *end;
19169
19170 /* Search for the last glyph of the previous row that came
19171 from buffer or string. Depending on whether the row is
19172 L2R or R2L, we need to process it front to back or the
19173 other way round. */
19174 if (!r1->reversed_p)
19175 {
19176 start = r1->glyphs[TEXT_AREA];
19177 end = start + r1->used[TEXT_AREA];
19178 /* Glyphs inserted by redisplay have an integer (zero)
19179 as their object. */
19180 while (end > start
19181 && INTEGERP ((end - 1)->object)
19182 && (end - 1)->charpos <= 0)
19183 --end;
19184 if (end > start)
19185 {
19186 if (EQ ((end - 1)->object, it->object))
19187 seen_this_string = 1;
19188 }
19189 else
19190 /* If all the glyphs of the previous row were inserted
19191 by redisplay, it means the previous row was
19192 produced from a single newline, which is only
19193 possible if that newline came from the same string
19194 as the one which produced this ROW. */
19195 seen_this_string = 1;
19196 }
19197 else
19198 {
19199 end = r1->glyphs[TEXT_AREA] - 1;
19200 start = end + r1->used[TEXT_AREA];
19201 while (end < start
19202 && INTEGERP ((end + 1)->object)
19203 && (end + 1)->charpos <= 0)
19204 ++end;
19205 if (end < start)
19206 {
19207 if (EQ ((end + 1)->object, it->object))
19208 seen_this_string = 1;
19209 }
19210 else
19211 seen_this_string = 1;
19212 }
19213 }
19214 /* Take note of each display string that covers a newline only
19215 once, the first time we see it. This is for when a display
19216 string includes more than one newline in it. */
19217 if (row->ends_in_newline_from_string_p && !seen_this_string)
19218 {
19219 /* If we were scanning the buffer forward when we displayed
19220 the string, we want to account for at least one buffer
19221 position that belongs to this row (position covered by
19222 the display string), so that cursor positioning will
19223 consider this row as a candidate when point is at the end
19224 of the visual line represented by this row. This is not
19225 required when scanning back, because max_pos will already
19226 have a much larger value. */
19227 if (CHARPOS (row->end.pos) > max_pos)
19228 INC_BOTH (max_pos, max_bpos);
19229 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19230 }
19231 else if (CHARPOS (it->eol_pos) > 0)
19232 SET_TEXT_POS (row->maxpos,
19233 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19234 else if (row->continued_p)
19235 {
19236 /* If max_pos is different from IT's current position, it
19237 means IT->method does not belong to the display element
19238 at max_pos. However, it also means that the display
19239 element at max_pos was displayed in its entirety on this
19240 line, which is equivalent to saying that the next line
19241 starts at the next buffer position. */
19242 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19243 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19244 else
19245 {
19246 INC_BOTH (max_pos, max_bpos);
19247 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19248 }
19249 }
19250 else if (row->truncated_on_right_p)
19251 /* display_line already called reseat_at_next_visible_line_start,
19252 which puts the iterator at the beginning of the next line, in
19253 the logical order. */
19254 row->maxpos = it->current.pos;
19255 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19256 /* A line that is entirely from a string/image/stretch... */
19257 row->maxpos = row->minpos;
19258 else
19259 emacs_abort ();
19260 }
19261 else
19262 row->maxpos = it->current.pos;
19263 }
19264
19265 /* Construct the glyph row IT->glyph_row in the desired matrix of
19266 IT->w from text at the current position of IT. See dispextern.h
19267 for an overview of struct it. Value is non-zero if
19268 IT->glyph_row displays text, as opposed to a line displaying ZV
19269 only. */
19270
19271 static int
19272 display_line (struct it *it)
19273 {
19274 struct glyph_row *row = it->glyph_row;
19275 Lisp_Object overlay_arrow_string;
19276 struct it wrap_it;
19277 void *wrap_data = NULL;
19278 int may_wrap = 0, wrap_x IF_LINT (= 0);
19279 int wrap_row_used = -1;
19280 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19281 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19282 int wrap_row_extra_line_spacing IF_LINT (= 0);
19283 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19284 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19285 int cvpos;
19286 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19287 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19288
19289 /* We always start displaying at hpos zero even if hscrolled. */
19290 eassert (it->hpos == 0 && it->current_x == 0);
19291
19292 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19293 >= it->w->desired_matrix->nrows)
19294 {
19295 it->w->nrows_scale_factor++;
19296 it->f->fonts_changed = 1;
19297 return 0;
19298 }
19299
19300 /* Clear the result glyph row and enable it. */
19301 prepare_desired_row (row);
19302
19303 row->y = it->current_y;
19304 row->start = it->start;
19305 row->continuation_lines_width = it->continuation_lines_width;
19306 row->displays_text_p = 1;
19307 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19308 it->starts_in_middle_of_char_p = 0;
19309
19310 /* Arrange the overlays nicely for our purposes. Usually, we call
19311 display_line on only one line at a time, in which case this
19312 can't really hurt too much, or we call it on lines which appear
19313 one after another in the buffer, in which case all calls to
19314 recenter_overlay_lists but the first will be pretty cheap. */
19315 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19316
19317 /* Move over display elements that are not visible because we are
19318 hscrolled. This may stop at an x-position < IT->first_visible_x
19319 if the first glyph is partially visible or if we hit a line end. */
19320 if (it->current_x < it->first_visible_x)
19321 {
19322 enum move_it_result move_result;
19323
19324 this_line_min_pos = row->start.pos;
19325 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19326 MOVE_TO_POS | MOVE_TO_X);
19327 /* If we are under a large hscroll, move_it_in_display_line_to
19328 could hit the end of the line without reaching
19329 it->first_visible_x. Pretend that we did reach it. This is
19330 especially important on a TTY, where we will call
19331 extend_face_to_end_of_line, which needs to know how many
19332 blank glyphs to produce. */
19333 if (it->current_x < it->first_visible_x
19334 && (move_result == MOVE_NEWLINE_OR_CR
19335 || move_result == MOVE_POS_MATCH_OR_ZV))
19336 it->current_x = it->first_visible_x;
19337
19338 /* Record the smallest positions seen while we moved over
19339 display elements that are not visible. This is needed by
19340 redisplay_internal for optimizing the case where the cursor
19341 stays inside the same line. The rest of this function only
19342 considers positions that are actually displayed, so
19343 RECORD_MAX_MIN_POS will not otherwise record positions that
19344 are hscrolled to the left of the left edge of the window. */
19345 min_pos = CHARPOS (this_line_min_pos);
19346 min_bpos = BYTEPOS (this_line_min_pos);
19347 }
19348 else
19349 {
19350 /* We only do this when not calling `move_it_in_display_line_to'
19351 above, because move_it_in_display_line_to calls
19352 handle_line_prefix itself. */
19353 handle_line_prefix (it);
19354 }
19355
19356 /* Get the initial row height. This is either the height of the
19357 text hscrolled, if there is any, or zero. */
19358 row->ascent = it->max_ascent;
19359 row->height = it->max_ascent + it->max_descent;
19360 row->phys_ascent = it->max_phys_ascent;
19361 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19362 row->extra_line_spacing = it->max_extra_line_spacing;
19363
19364 /* Utility macro to record max and min buffer positions seen until now. */
19365 #define RECORD_MAX_MIN_POS(IT) \
19366 do \
19367 { \
19368 int composition_p = !STRINGP ((IT)->string) \
19369 && ((IT)->what == IT_COMPOSITION); \
19370 ptrdiff_t current_pos = \
19371 composition_p ? (IT)->cmp_it.charpos \
19372 : IT_CHARPOS (*(IT)); \
19373 ptrdiff_t current_bpos = \
19374 composition_p ? CHAR_TO_BYTE (current_pos) \
19375 : IT_BYTEPOS (*(IT)); \
19376 if (current_pos < min_pos) \
19377 { \
19378 min_pos = current_pos; \
19379 min_bpos = current_bpos; \
19380 } \
19381 if (IT_CHARPOS (*it) > max_pos) \
19382 { \
19383 max_pos = IT_CHARPOS (*it); \
19384 max_bpos = IT_BYTEPOS (*it); \
19385 } \
19386 } \
19387 while (0)
19388
19389 /* Loop generating characters. The loop is left with IT on the next
19390 character to display. */
19391 while (1)
19392 {
19393 int n_glyphs_before, hpos_before, x_before;
19394 int x, nglyphs;
19395 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19396
19397 /* Retrieve the next thing to display. Value is zero if end of
19398 buffer reached. */
19399 if (!get_next_display_element (it))
19400 {
19401 /* Maybe add a space at the end of this line that is used to
19402 display the cursor there under X. Set the charpos of the
19403 first glyph of blank lines not corresponding to any text
19404 to -1. */
19405 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19406 row->exact_window_width_line_p = 1;
19407 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19408 || row->used[TEXT_AREA] == 0)
19409 {
19410 row->glyphs[TEXT_AREA]->charpos = -1;
19411 row->displays_text_p = 0;
19412
19413 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19414 && (!MINI_WINDOW_P (it->w)
19415 || (minibuf_level && EQ (it->window, minibuf_window))))
19416 row->indicate_empty_line_p = 1;
19417 }
19418
19419 it->continuation_lines_width = 0;
19420 row->ends_at_zv_p = 1;
19421 /* A row that displays right-to-left text must always have
19422 its last face extended all the way to the end of line,
19423 even if this row ends in ZV, because we still write to
19424 the screen left to right. We also need to extend the
19425 last face if the default face is remapped to some
19426 different face, otherwise the functions that clear
19427 portions of the screen will clear with the default face's
19428 background color. */
19429 if (row->reversed_p
19430 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19431 extend_face_to_end_of_line (it);
19432 break;
19433 }
19434
19435 /* Now, get the metrics of what we want to display. This also
19436 generates glyphs in `row' (which is IT->glyph_row). */
19437 n_glyphs_before = row->used[TEXT_AREA];
19438 x = it->current_x;
19439
19440 /* Remember the line height so far in case the next element doesn't
19441 fit on the line. */
19442 if (it->line_wrap != TRUNCATE)
19443 {
19444 ascent = it->max_ascent;
19445 descent = it->max_descent;
19446 phys_ascent = it->max_phys_ascent;
19447 phys_descent = it->max_phys_descent;
19448
19449 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19450 {
19451 if (IT_DISPLAYING_WHITESPACE (it))
19452 may_wrap = 1;
19453 else if (may_wrap)
19454 {
19455 SAVE_IT (wrap_it, *it, wrap_data);
19456 wrap_x = x;
19457 wrap_row_used = row->used[TEXT_AREA];
19458 wrap_row_ascent = row->ascent;
19459 wrap_row_height = row->height;
19460 wrap_row_phys_ascent = row->phys_ascent;
19461 wrap_row_phys_height = row->phys_height;
19462 wrap_row_extra_line_spacing = row->extra_line_spacing;
19463 wrap_row_min_pos = min_pos;
19464 wrap_row_min_bpos = min_bpos;
19465 wrap_row_max_pos = max_pos;
19466 wrap_row_max_bpos = max_bpos;
19467 may_wrap = 0;
19468 }
19469 }
19470 }
19471
19472 PRODUCE_GLYPHS (it);
19473
19474 /* If this display element was in marginal areas, continue with
19475 the next one. */
19476 if (it->area != TEXT_AREA)
19477 {
19478 row->ascent = max (row->ascent, it->max_ascent);
19479 row->height = max (row->height, it->max_ascent + it->max_descent);
19480 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19481 row->phys_height = max (row->phys_height,
19482 it->max_phys_ascent + it->max_phys_descent);
19483 row->extra_line_spacing = max (row->extra_line_spacing,
19484 it->max_extra_line_spacing);
19485 set_iterator_to_next (it, 1);
19486 continue;
19487 }
19488
19489 /* Does the display element fit on the line? If we truncate
19490 lines, we should draw past the right edge of the window. If
19491 we don't truncate, we want to stop so that we can display the
19492 continuation glyph before the right margin. If lines are
19493 continued, there are two possible strategies for characters
19494 resulting in more than 1 glyph (e.g. tabs): Display as many
19495 glyphs as possible in this line and leave the rest for the
19496 continuation line, or display the whole element in the next
19497 line. Original redisplay did the former, so we do it also. */
19498 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19499 hpos_before = it->hpos;
19500 x_before = x;
19501
19502 if (/* Not a newline. */
19503 nglyphs > 0
19504 /* Glyphs produced fit entirely in the line. */
19505 && it->current_x < it->last_visible_x)
19506 {
19507 it->hpos += nglyphs;
19508 row->ascent = max (row->ascent, it->max_ascent);
19509 row->height = max (row->height, it->max_ascent + it->max_descent);
19510 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19511 row->phys_height = max (row->phys_height,
19512 it->max_phys_ascent + it->max_phys_descent);
19513 row->extra_line_spacing = max (row->extra_line_spacing,
19514 it->max_extra_line_spacing);
19515 if (it->current_x - it->pixel_width < it->first_visible_x)
19516 row->x = x - it->first_visible_x;
19517 /* Record the maximum and minimum buffer positions seen so
19518 far in glyphs that will be displayed by this row. */
19519 if (it->bidi_p)
19520 RECORD_MAX_MIN_POS (it);
19521 }
19522 else
19523 {
19524 int i, new_x;
19525 struct glyph *glyph;
19526
19527 for (i = 0; i < nglyphs; ++i, x = new_x)
19528 {
19529 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19530 new_x = x + glyph->pixel_width;
19531
19532 if (/* Lines are continued. */
19533 it->line_wrap != TRUNCATE
19534 && (/* Glyph doesn't fit on the line. */
19535 new_x > it->last_visible_x
19536 /* Or it fits exactly on a window system frame. */
19537 || (new_x == it->last_visible_x
19538 && FRAME_WINDOW_P (it->f)
19539 && (row->reversed_p
19540 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19541 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19542 {
19543 /* End of a continued line. */
19544
19545 if (it->hpos == 0
19546 || (new_x == it->last_visible_x
19547 && FRAME_WINDOW_P (it->f)
19548 && (row->reversed_p
19549 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19550 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19551 {
19552 /* Current glyph is the only one on the line or
19553 fits exactly on the line. We must continue
19554 the line because we can't draw the cursor
19555 after the glyph. */
19556 row->continued_p = 1;
19557 it->current_x = new_x;
19558 it->continuation_lines_width += new_x;
19559 ++it->hpos;
19560 if (i == nglyphs - 1)
19561 {
19562 /* If line-wrap is on, check if a previous
19563 wrap point was found. */
19564 if (wrap_row_used > 0
19565 /* Even if there is a previous wrap
19566 point, continue the line here as
19567 usual, if (i) the previous character
19568 was a space or tab AND (ii) the
19569 current character is not. */
19570 && (!may_wrap
19571 || IT_DISPLAYING_WHITESPACE (it)))
19572 goto back_to_wrap;
19573
19574 /* Record the maximum and minimum buffer
19575 positions seen so far in glyphs that will be
19576 displayed by this row. */
19577 if (it->bidi_p)
19578 RECORD_MAX_MIN_POS (it);
19579 set_iterator_to_next (it, 1);
19580 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19581 {
19582 if (!get_next_display_element (it))
19583 {
19584 row->exact_window_width_line_p = 1;
19585 it->continuation_lines_width = 0;
19586 row->continued_p = 0;
19587 row->ends_at_zv_p = 1;
19588 }
19589 else if (ITERATOR_AT_END_OF_LINE_P (it))
19590 {
19591 row->continued_p = 0;
19592 row->exact_window_width_line_p = 1;
19593 }
19594 }
19595 }
19596 else if (it->bidi_p)
19597 RECORD_MAX_MIN_POS (it);
19598 }
19599 else if (CHAR_GLYPH_PADDING_P (*glyph)
19600 && !FRAME_WINDOW_P (it->f))
19601 {
19602 /* A padding glyph that doesn't fit on this line.
19603 This means the whole character doesn't fit
19604 on the line. */
19605 if (row->reversed_p)
19606 unproduce_glyphs (it, row->used[TEXT_AREA]
19607 - n_glyphs_before);
19608 row->used[TEXT_AREA] = n_glyphs_before;
19609
19610 /* Fill the rest of the row with continuation
19611 glyphs like in 20.x. */
19612 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19613 < row->glyphs[1 + TEXT_AREA])
19614 produce_special_glyphs (it, IT_CONTINUATION);
19615
19616 row->continued_p = 1;
19617 it->current_x = x_before;
19618 it->continuation_lines_width += x_before;
19619
19620 /* Restore the height to what it was before the
19621 element not fitting on the line. */
19622 it->max_ascent = ascent;
19623 it->max_descent = descent;
19624 it->max_phys_ascent = phys_ascent;
19625 it->max_phys_descent = phys_descent;
19626 }
19627 else if (wrap_row_used > 0)
19628 {
19629 back_to_wrap:
19630 if (row->reversed_p)
19631 unproduce_glyphs (it,
19632 row->used[TEXT_AREA] - wrap_row_used);
19633 RESTORE_IT (it, &wrap_it, wrap_data);
19634 it->continuation_lines_width += wrap_x;
19635 row->used[TEXT_AREA] = wrap_row_used;
19636 row->ascent = wrap_row_ascent;
19637 row->height = wrap_row_height;
19638 row->phys_ascent = wrap_row_phys_ascent;
19639 row->phys_height = wrap_row_phys_height;
19640 row->extra_line_spacing = wrap_row_extra_line_spacing;
19641 min_pos = wrap_row_min_pos;
19642 min_bpos = wrap_row_min_bpos;
19643 max_pos = wrap_row_max_pos;
19644 max_bpos = wrap_row_max_bpos;
19645 row->continued_p = 1;
19646 row->ends_at_zv_p = 0;
19647 row->exact_window_width_line_p = 0;
19648 it->continuation_lines_width += x;
19649
19650 /* Make sure that a non-default face is extended
19651 up to the right margin of the window. */
19652 extend_face_to_end_of_line (it);
19653 }
19654 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19655 {
19656 /* A TAB that extends past the right edge of the
19657 window. This produces a single glyph on
19658 window system frames. We leave the glyph in
19659 this row and let it fill the row, but don't
19660 consume the TAB. */
19661 if ((row->reversed_p
19662 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19663 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19664 produce_special_glyphs (it, IT_CONTINUATION);
19665 it->continuation_lines_width += it->last_visible_x;
19666 row->ends_in_middle_of_char_p = 1;
19667 row->continued_p = 1;
19668 glyph->pixel_width = it->last_visible_x - x;
19669 it->starts_in_middle_of_char_p = 1;
19670 }
19671 else
19672 {
19673 /* Something other than a TAB that draws past
19674 the right edge of the window. Restore
19675 positions to values before the element. */
19676 if (row->reversed_p)
19677 unproduce_glyphs (it, row->used[TEXT_AREA]
19678 - (n_glyphs_before + i));
19679 row->used[TEXT_AREA] = n_glyphs_before + i;
19680
19681 /* Display continuation glyphs. */
19682 it->current_x = x_before;
19683 it->continuation_lines_width += x;
19684 if (!FRAME_WINDOW_P (it->f)
19685 || (row->reversed_p
19686 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19687 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19688 produce_special_glyphs (it, IT_CONTINUATION);
19689 row->continued_p = 1;
19690
19691 extend_face_to_end_of_line (it);
19692
19693 if (nglyphs > 1 && i > 0)
19694 {
19695 row->ends_in_middle_of_char_p = 1;
19696 it->starts_in_middle_of_char_p = 1;
19697 }
19698
19699 /* Restore the height to what it was before the
19700 element not fitting on the line. */
19701 it->max_ascent = ascent;
19702 it->max_descent = descent;
19703 it->max_phys_ascent = phys_ascent;
19704 it->max_phys_descent = phys_descent;
19705 }
19706
19707 break;
19708 }
19709 else if (new_x > it->first_visible_x)
19710 {
19711 /* Increment number of glyphs actually displayed. */
19712 ++it->hpos;
19713
19714 /* Record the maximum and minimum buffer positions
19715 seen so far in glyphs that will be displayed by
19716 this row. */
19717 if (it->bidi_p)
19718 RECORD_MAX_MIN_POS (it);
19719
19720 if (x < it->first_visible_x)
19721 /* Glyph is partially visible, i.e. row starts at
19722 negative X position. */
19723 row->x = x - it->first_visible_x;
19724 }
19725 else
19726 {
19727 /* Glyph is completely off the left margin of the
19728 window. This should not happen because of the
19729 move_it_in_display_line at the start of this
19730 function, unless the text display area of the
19731 window is empty. */
19732 eassert (it->first_visible_x <= it->last_visible_x);
19733 }
19734 }
19735 /* Even if this display element produced no glyphs at all,
19736 we want to record its position. */
19737 if (it->bidi_p && nglyphs == 0)
19738 RECORD_MAX_MIN_POS (it);
19739
19740 row->ascent = max (row->ascent, it->max_ascent);
19741 row->height = max (row->height, it->max_ascent + it->max_descent);
19742 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19743 row->phys_height = max (row->phys_height,
19744 it->max_phys_ascent + it->max_phys_descent);
19745 row->extra_line_spacing = max (row->extra_line_spacing,
19746 it->max_extra_line_spacing);
19747
19748 /* End of this display line if row is continued. */
19749 if (row->continued_p || row->ends_at_zv_p)
19750 break;
19751 }
19752
19753 at_end_of_line:
19754 /* Is this a line end? If yes, we're also done, after making
19755 sure that a non-default face is extended up to the right
19756 margin of the window. */
19757 if (ITERATOR_AT_END_OF_LINE_P (it))
19758 {
19759 int used_before = row->used[TEXT_AREA];
19760
19761 row->ends_in_newline_from_string_p = STRINGP (it->object);
19762
19763 /* Add a space at the end of the line that is used to
19764 display the cursor there. */
19765 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19766 append_space_for_newline (it, 0);
19767
19768 /* Extend the face to the end of the line. */
19769 extend_face_to_end_of_line (it);
19770
19771 /* Make sure we have the position. */
19772 if (used_before == 0)
19773 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19774
19775 /* Record the position of the newline, for use in
19776 find_row_edges. */
19777 it->eol_pos = it->current.pos;
19778
19779 /* Consume the line end. This skips over invisible lines. */
19780 set_iterator_to_next (it, 1);
19781 it->continuation_lines_width = 0;
19782 break;
19783 }
19784
19785 /* Proceed with next display element. Note that this skips
19786 over lines invisible because of selective display. */
19787 set_iterator_to_next (it, 1);
19788
19789 /* If we truncate lines, we are done when the last displayed
19790 glyphs reach past the right margin of the window. */
19791 if (it->line_wrap == TRUNCATE
19792 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19793 ? (it->current_x >= it->last_visible_x)
19794 : (it->current_x > it->last_visible_x)))
19795 {
19796 /* Maybe add truncation glyphs. */
19797 if (!FRAME_WINDOW_P (it->f)
19798 || (row->reversed_p
19799 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19800 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19801 {
19802 int i, n;
19803
19804 if (!row->reversed_p)
19805 {
19806 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19807 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19808 break;
19809 }
19810 else
19811 {
19812 for (i = 0; i < row->used[TEXT_AREA]; i++)
19813 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19814 break;
19815 /* Remove any padding glyphs at the front of ROW, to
19816 make room for the truncation glyphs we will be
19817 adding below. The loop below always inserts at
19818 least one truncation glyph, so also remove the
19819 last glyph added to ROW. */
19820 unproduce_glyphs (it, i + 1);
19821 /* Adjust i for the loop below. */
19822 i = row->used[TEXT_AREA] - (i + 1);
19823 }
19824
19825 it->current_x = x_before;
19826 if (!FRAME_WINDOW_P (it->f))
19827 {
19828 for (n = row->used[TEXT_AREA]; i < n; ++i)
19829 {
19830 row->used[TEXT_AREA] = i;
19831 produce_special_glyphs (it, IT_TRUNCATION);
19832 }
19833 }
19834 else
19835 {
19836 row->used[TEXT_AREA] = i;
19837 produce_special_glyphs (it, IT_TRUNCATION);
19838 }
19839 }
19840 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19841 {
19842 /* Don't truncate if we can overflow newline into fringe. */
19843 if (!get_next_display_element (it))
19844 {
19845 it->continuation_lines_width = 0;
19846 row->ends_at_zv_p = 1;
19847 row->exact_window_width_line_p = 1;
19848 break;
19849 }
19850 if (ITERATOR_AT_END_OF_LINE_P (it))
19851 {
19852 row->exact_window_width_line_p = 1;
19853 goto at_end_of_line;
19854 }
19855 it->current_x = x_before;
19856 }
19857
19858 row->truncated_on_right_p = 1;
19859 it->continuation_lines_width = 0;
19860 reseat_at_next_visible_line_start (it, 0);
19861 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19862 it->hpos = hpos_before;
19863 break;
19864 }
19865 }
19866
19867 if (wrap_data)
19868 bidi_unshelve_cache (wrap_data, 1);
19869
19870 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19871 at the left window margin. */
19872 if (it->first_visible_x
19873 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19874 {
19875 if (!FRAME_WINDOW_P (it->f)
19876 || (row->reversed_p
19877 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19878 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19879 insert_left_trunc_glyphs (it);
19880 row->truncated_on_left_p = 1;
19881 }
19882
19883 /* Remember the position at which this line ends.
19884
19885 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19886 cannot be before the call to find_row_edges below, since that is
19887 where these positions are determined. */
19888 row->end = it->current;
19889 if (!it->bidi_p)
19890 {
19891 row->minpos = row->start.pos;
19892 row->maxpos = row->end.pos;
19893 }
19894 else
19895 {
19896 /* ROW->minpos and ROW->maxpos must be the smallest and
19897 `1 + the largest' buffer positions in ROW. But if ROW was
19898 bidi-reordered, these two positions can be anywhere in the
19899 row, so we must determine them now. */
19900 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19901 }
19902
19903 /* If the start of this line is the overlay arrow-position, then
19904 mark this glyph row as the one containing the overlay arrow.
19905 This is clearly a mess with variable size fonts. It would be
19906 better to let it be displayed like cursors under X. */
19907 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19908 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19909 !NILP (overlay_arrow_string)))
19910 {
19911 /* Overlay arrow in window redisplay is a fringe bitmap. */
19912 if (STRINGP (overlay_arrow_string))
19913 {
19914 struct glyph_row *arrow_row
19915 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19916 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19917 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19918 struct glyph *p = row->glyphs[TEXT_AREA];
19919 struct glyph *p2, *end;
19920
19921 /* Copy the arrow glyphs. */
19922 while (glyph < arrow_end)
19923 *p++ = *glyph++;
19924
19925 /* Throw away padding glyphs. */
19926 p2 = p;
19927 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19928 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19929 ++p2;
19930 if (p2 > p)
19931 {
19932 while (p2 < end)
19933 *p++ = *p2++;
19934 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19935 }
19936 }
19937 else
19938 {
19939 eassert (INTEGERP (overlay_arrow_string));
19940 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19941 }
19942 overlay_arrow_seen = 1;
19943 }
19944
19945 /* Highlight trailing whitespace. */
19946 if (!NILP (Vshow_trailing_whitespace))
19947 highlight_trailing_whitespace (it->f, it->glyph_row);
19948
19949 /* Compute pixel dimensions of this line. */
19950 compute_line_metrics (it);
19951
19952 /* Implementation note: No changes in the glyphs of ROW or in their
19953 faces can be done past this point, because compute_line_metrics
19954 computes ROW's hash value and stores it within the glyph_row
19955 structure. */
19956
19957 /* Record whether this row ends inside an ellipsis. */
19958 row->ends_in_ellipsis_p
19959 = (it->method == GET_FROM_DISPLAY_VECTOR
19960 && it->ellipsis_p);
19961
19962 /* Save fringe bitmaps in this row. */
19963 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19964 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19965 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19966 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19967
19968 it->left_user_fringe_bitmap = 0;
19969 it->left_user_fringe_face_id = 0;
19970 it->right_user_fringe_bitmap = 0;
19971 it->right_user_fringe_face_id = 0;
19972
19973 /* Maybe set the cursor. */
19974 cvpos = it->w->cursor.vpos;
19975 if ((cvpos < 0
19976 /* In bidi-reordered rows, keep checking for proper cursor
19977 position even if one has been found already, because buffer
19978 positions in such rows change non-linearly with ROW->VPOS,
19979 when a line is continued. One exception: when we are at ZV,
19980 display cursor on the first suitable glyph row, since all
19981 the empty rows after that also have their position set to ZV. */
19982 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19983 lines' rows is implemented for bidi-reordered rows. */
19984 || (it->bidi_p
19985 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19986 && PT >= MATRIX_ROW_START_CHARPOS (row)
19987 && PT <= MATRIX_ROW_END_CHARPOS (row)
19988 && cursor_row_p (row))
19989 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19990
19991 /* Prepare for the next line. This line starts horizontally at (X
19992 HPOS) = (0 0). Vertical positions are incremented. As a
19993 convenience for the caller, IT->glyph_row is set to the next
19994 row to be used. */
19995 it->current_x = it->hpos = 0;
19996 it->current_y += row->height;
19997 SET_TEXT_POS (it->eol_pos, 0, 0);
19998 ++it->vpos;
19999 ++it->glyph_row;
20000 /* The next row should by default use the same value of the
20001 reversed_p flag as this one. set_iterator_to_next decides when
20002 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20003 the flag accordingly. */
20004 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20005 it->glyph_row->reversed_p = row->reversed_p;
20006 it->start = row->end;
20007 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
20008
20009 #undef RECORD_MAX_MIN_POS
20010 }
20011
20012 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20013 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20014 doc: /* Return paragraph direction at point in BUFFER.
20015 Value is either `left-to-right' or `right-to-left'.
20016 If BUFFER is omitted or nil, it defaults to the current buffer.
20017
20018 Paragraph direction determines how the text in the paragraph is displayed.
20019 In left-to-right paragraphs, text begins at the left margin of the window
20020 and the reading direction is generally left to right. In right-to-left
20021 paragraphs, text begins at the right margin and is read from right to left.
20022
20023 See also `bidi-paragraph-direction'. */)
20024 (Lisp_Object buffer)
20025 {
20026 struct buffer *buf = current_buffer;
20027 struct buffer *old = buf;
20028
20029 if (! NILP (buffer))
20030 {
20031 CHECK_BUFFER (buffer);
20032 buf = XBUFFER (buffer);
20033 }
20034
20035 if (NILP (BVAR (buf, bidi_display_reordering))
20036 || NILP (BVAR (buf, enable_multibyte_characters))
20037 /* When we are loading loadup.el, the character property tables
20038 needed for bidi iteration are not yet available. */
20039 || !NILP (Vpurify_flag))
20040 return Qleft_to_right;
20041 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20042 return BVAR (buf, bidi_paragraph_direction);
20043 else
20044 {
20045 /* Determine the direction from buffer text. We could try to
20046 use current_matrix if it is up to date, but this seems fast
20047 enough as it is. */
20048 struct bidi_it itb;
20049 ptrdiff_t pos = BUF_PT (buf);
20050 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20051 int c;
20052 void *itb_data = bidi_shelve_cache ();
20053
20054 set_buffer_temp (buf);
20055 /* bidi_paragraph_init finds the base direction of the paragraph
20056 by searching forward from paragraph start. We need the base
20057 direction of the current or _previous_ paragraph, so we need
20058 to make sure we are within that paragraph. To that end, find
20059 the previous non-empty line. */
20060 if (pos >= ZV && pos > BEGV)
20061 DEC_BOTH (pos, bytepos);
20062 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20063 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20064 {
20065 while ((c = FETCH_BYTE (bytepos)) == '\n'
20066 || c == ' ' || c == '\t' || c == '\f')
20067 {
20068 if (bytepos <= BEGV_BYTE)
20069 break;
20070 bytepos--;
20071 pos--;
20072 }
20073 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20074 bytepos--;
20075 }
20076 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20077 itb.paragraph_dir = NEUTRAL_DIR;
20078 itb.string.s = NULL;
20079 itb.string.lstring = Qnil;
20080 itb.string.bufpos = 0;
20081 itb.string.unibyte = 0;
20082 /* We have no window to use here for ignoring window-specific
20083 overlays. Using NULL for window pointer will cause
20084 compute_display_string_pos to use the current buffer. */
20085 itb.w = NULL;
20086 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20087 bidi_unshelve_cache (itb_data, 0);
20088 set_buffer_temp (old);
20089 switch (itb.paragraph_dir)
20090 {
20091 case L2R:
20092 return Qleft_to_right;
20093 break;
20094 case R2L:
20095 return Qright_to_left;
20096 break;
20097 default:
20098 emacs_abort ();
20099 }
20100 }
20101 }
20102
20103 DEFUN ("move-point-visually", Fmove_point_visually,
20104 Smove_point_visually, 1, 1, 0,
20105 doc: /* Move point in the visual order in the specified DIRECTION.
20106 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20107 left.
20108
20109 Value is the new character position of point. */)
20110 (Lisp_Object direction)
20111 {
20112 struct window *w = XWINDOW (selected_window);
20113 struct buffer *b = XBUFFER (w->contents);
20114 struct glyph_row *row;
20115 int dir;
20116 Lisp_Object paragraph_dir;
20117
20118 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20119 (!(ROW)->continued_p \
20120 && INTEGERP ((GLYPH)->object) \
20121 && (GLYPH)->type == CHAR_GLYPH \
20122 && (GLYPH)->u.ch == ' ' \
20123 && (GLYPH)->charpos >= 0 \
20124 && !(GLYPH)->avoid_cursor_p)
20125
20126 CHECK_NUMBER (direction);
20127 dir = XINT (direction);
20128 if (dir > 0)
20129 dir = 1;
20130 else
20131 dir = -1;
20132
20133 /* If current matrix is up-to-date, we can use the information
20134 recorded in the glyphs, at least as long as the goal is on the
20135 screen. */
20136 if (w->window_end_valid
20137 && !windows_or_buffers_changed
20138 && b
20139 && !b->clip_changed
20140 && !b->prevent_redisplay_optimizations_p
20141 && !window_outdated (w)
20142 && w->cursor.vpos >= 0
20143 && w->cursor.vpos < w->current_matrix->nrows
20144 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20145 {
20146 struct glyph *g = row->glyphs[TEXT_AREA];
20147 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20148 struct glyph *gpt = g + w->cursor.hpos;
20149
20150 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20151 {
20152 if (BUFFERP (g->object) && g->charpos != PT)
20153 {
20154 SET_PT (g->charpos);
20155 w->cursor.vpos = -1;
20156 return make_number (PT);
20157 }
20158 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20159 {
20160 ptrdiff_t new_pos;
20161
20162 if (BUFFERP (gpt->object))
20163 {
20164 new_pos = PT;
20165 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20166 new_pos += (row->reversed_p ? -dir : dir);
20167 else
20168 new_pos -= (row->reversed_p ? -dir : dir);;
20169 }
20170 else if (BUFFERP (g->object))
20171 new_pos = g->charpos;
20172 else
20173 break;
20174 SET_PT (new_pos);
20175 w->cursor.vpos = -1;
20176 return make_number (PT);
20177 }
20178 else if (ROW_GLYPH_NEWLINE_P (row, g))
20179 {
20180 /* Glyphs inserted at the end of a non-empty line for
20181 positioning the cursor have zero charpos, so we must
20182 deduce the value of point by other means. */
20183 if (g->charpos > 0)
20184 SET_PT (g->charpos);
20185 else if (row->ends_at_zv_p && PT != ZV)
20186 SET_PT (ZV);
20187 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20188 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20189 else
20190 break;
20191 w->cursor.vpos = -1;
20192 return make_number (PT);
20193 }
20194 }
20195 if (g == e || INTEGERP (g->object))
20196 {
20197 if (row->truncated_on_left_p || row->truncated_on_right_p)
20198 goto simulate_display;
20199 if (!row->reversed_p)
20200 row += dir;
20201 else
20202 row -= dir;
20203 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20204 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20205 goto simulate_display;
20206
20207 if (dir > 0)
20208 {
20209 if (row->reversed_p && !row->continued_p)
20210 {
20211 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20212 w->cursor.vpos = -1;
20213 return make_number (PT);
20214 }
20215 g = row->glyphs[TEXT_AREA];
20216 e = g + row->used[TEXT_AREA];
20217 for ( ; g < e; g++)
20218 {
20219 if (BUFFERP (g->object)
20220 /* Empty lines have only one glyph, which stands
20221 for the newline, and whose charpos is the
20222 buffer position of the newline. */
20223 || ROW_GLYPH_NEWLINE_P (row, g)
20224 /* When the buffer ends in a newline, the line at
20225 EOB also has one glyph, but its charpos is -1. */
20226 || (row->ends_at_zv_p
20227 && !row->reversed_p
20228 && INTEGERP (g->object)
20229 && g->type == CHAR_GLYPH
20230 && g->u.ch == ' '))
20231 {
20232 if (g->charpos > 0)
20233 SET_PT (g->charpos);
20234 else if (!row->reversed_p
20235 && row->ends_at_zv_p
20236 && PT != ZV)
20237 SET_PT (ZV);
20238 else
20239 continue;
20240 w->cursor.vpos = -1;
20241 return make_number (PT);
20242 }
20243 }
20244 }
20245 else
20246 {
20247 if (!row->reversed_p && !row->continued_p)
20248 {
20249 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20250 w->cursor.vpos = -1;
20251 return make_number (PT);
20252 }
20253 e = row->glyphs[TEXT_AREA];
20254 g = e + row->used[TEXT_AREA] - 1;
20255 for ( ; g >= e; g--)
20256 {
20257 if (BUFFERP (g->object)
20258 || (ROW_GLYPH_NEWLINE_P (row, g)
20259 && g->charpos > 0)
20260 /* Empty R2L lines on GUI frames have the buffer
20261 position of the newline stored in the stretch
20262 glyph. */
20263 || g->type == STRETCH_GLYPH
20264 || (row->ends_at_zv_p
20265 && row->reversed_p
20266 && INTEGERP (g->object)
20267 && g->type == CHAR_GLYPH
20268 && g->u.ch == ' '))
20269 {
20270 if (g->charpos > 0)
20271 SET_PT (g->charpos);
20272 else if (row->reversed_p
20273 && row->ends_at_zv_p
20274 && PT != ZV)
20275 SET_PT (ZV);
20276 else
20277 continue;
20278 w->cursor.vpos = -1;
20279 return make_number (PT);
20280 }
20281 }
20282 }
20283 }
20284 }
20285
20286 simulate_display:
20287
20288 /* If we wind up here, we failed to move by using the glyphs, so we
20289 need to simulate display instead. */
20290
20291 if (b)
20292 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
20293 else
20294 paragraph_dir = Qleft_to_right;
20295 if (EQ (paragraph_dir, Qright_to_left))
20296 dir = -dir;
20297 if (PT <= BEGV && dir < 0)
20298 xsignal0 (Qbeginning_of_buffer);
20299 else if (PT >= ZV && dir > 0)
20300 xsignal0 (Qend_of_buffer);
20301 else
20302 {
20303 struct text_pos pt;
20304 struct it it;
20305 int pt_x, target_x, pixel_width, pt_vpos;
20306 bool at_eol_p;
20307 bool overshoot_expected = false;
20308 bool target_is_eol_p = false;
20309
20310 /* Setup the arena. */
20311 SET_TEXT_POS (pt, PT, PT_BYTE);
20312 start_display (&it, w, pt);
20313
20314 if (it.cmp_it.id < 0
20315 && it.method == GET_FROM_STRING
20316 && it.area == TEXT_AREA
20317 && it.string_from_display_prop_p
20318 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
20319 overshoot_expected = true;
20320
20321 /* Find the X coordinate of point. We start from the beginning
20322 of this or previous line to make sure we are before point in
20323 the logical order (since the move_it_* functions can only
20324 move forward). */
20325 reseat_at_previous_visible_line_start (&it);
20326 it.current_x = it.hpos = it.current_y = it.vpos = 0;
20327 if (IT_CHARPOS (it) != PT)
20328 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
20329 -1, -1, -1, MOVE_TO_POS);
20330 pt_x = it.current_x;
20331 pt_vpos = it.vpos;
20332 if (dir > 0 || overshoot_expected)
20333 {
20334 struct glyph_row *row = it.glyph_row;
20335
20336 /* When point is at beginning of line, we don't have
20337 information about the glyph there loaded into struct
20338 it. Calling get_next_display_element fixes that. */
20339 if (pt_x == 0)
20340 get_next_display_element (&it);
20341 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20342 it.glyph_row = NULL;
20343 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
20344 it.glyph_row = row;
20345 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20346 it, lest it will become out of sync with it's buffer
20347 position. */
20348 it.current_x = pt_x;
20349 }
20350 else
20351 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20352 pixel_width = it.pixel_width;
20353 if (overshoot_expected && at_eol_p)
20354 pixel_width = 0;
20355 else if (pixel_width <= 0)
20356 pixel_width = 1;
20357
20358 /* If there's a display string at point, we are actually at the
20359 glyph to the left of point, so we need to correct the X
20360 coordinate. */
20361 if (overshoot_expected)
20362 pt_x += pixel_width;
20363
20364 /* Compute target X coordinate, either to the left or to the
20365 right of point. On TTY frames, all characters have the same
20366 pixel width of 1, so we can use that. On GUI frames we don't
20367 have an easy way of getting at the pixel width of the
20368 character to the left of point, so we use a different method
20369 of getting to that place. */
20370 if (dir > 0)
20371 target_x = pt_x + pixel_width;
20372 else
20373 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
20374
20375 /* Target X coordinate could be one line above or below the line
20376 of point, in which case we need to adjust the target X
20377 coordinate. Also, if moving to the left, we need to begin at
20378 the left edge of the point's screen line. */
20379 if (dir < 0)
20380 {
20381 if (pt_x > 0)
20382 {
20383 start_display (&it, w, pt);
20384 reseat_at_previous_visible_line_start (&it);
20385 it.current_x = it.current_y = it.hpos = 0;
20386 if (pt_vpos != 0)
20387 move_it_by_lines (&it, pt_vpos);
20388 }
20389 else
20390 {
20391 move_it_by_lines (&it, -1);
20392 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
20393 target_is_eol_p = true;
20394 }
20395 }
20396 else
20397 {
20398 if (at_eol_p
20399 || (target_x >= it.last_visible_x
20400 && it.line_wrap != TRUNCATE))
20401 {
20402 if (pt_x > 0)
20403 move_it_by_lines (&it, 0);
20404 move_it_by_lines (&it, 1);
20405 target_x = 0;
20406 }
20407 }
20408
20409 /* Move to the target X coordinate. */
20410 #ifdef HAVE_WINDOW_SYSTEM
20411 /* On GUI frames, as we don't know the X coordinate of the
20412 character to the left of point, moving point to the left
20413 requires walking, one grapheme cluster at a time, until we
20414 find ourself at a place immediately to the left of the
20415 character at point. */
20416 if (FRAME_WINDOW_P (it.f) && dir < 0)
20417 {
20418 struct text_pos new_pos = it.current.pos;
20419 enum move_it_result rc = MOVE_X_REACHED;
20420
20421 while (it.current_x + it.pixel_width <= target_x
20422 && rc == MOVE_X_REACHED)
20423 {
20424 int new_x = it.current_x + it.pixel_width;
20425
20426 new_pos = it.current.pos;
20427 if (new_x == it.current_x)
20428 new_x++;
20429 rc = move_it_in_display_line_to (&it, ZV, new_x,
20430 MOVE_TO_POS | MOVE_TO_X);
20431 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
20432 break;
20433 }
20434 /* If we ended up on a composed character inside
20435 bidi-reordered text (e.g., Hebrew text with diacritics),
20436 the iterator gives us the buffer position of the last (in
20437 logical order) character of the composed grapheme cluster,
20438 which is not what we want. So we cheat: we compute the
20439 character position of the character that follows (in the
20440 logical order) the one where the above loop stopped. That
20441 character will appear on display to the left of point. */
20442 if (it.bidi_p
20443 && it.bidi_it.scan_dir == -1
20444 && new_pos.charpos - IT_CHARPOS (it) > 1)
20445 {
20446 new_pos.charpos = IT_CHARPOS (it) + 1;
20447 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
20448 }
20449 it.current.pos = new_pos;
20450 }
20451 else
20452 #endif
20453 if (it.current_x != target_x)
20454 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
20455
20456 /* When lines are truncated, the above loop will stop at the
20457 window edge. But we want to get to the end of line, even if
20458 it is beyond the window edge; automatic hscroll will then
20459 scroll the window to show point as appropriate. */
20460 if (target_is_eol_p && it.line_wrap == TRUNCATE
20461 && get_next_display_element (&it))
20462 {
20463 struct text_pos new_pos = it.current.pos;
20464
20465 while (!ITERATOR_AT_END_OF_LINE_P (&it))
20466 {
20467 set_iterator_to_next (&it, 0);
20468 if (it.method == GET_FROM_BUFFER)
20469 new_pos = it.current.pos;
20470 if (!get_next_display_element (&it))
20471 break;
20472 }
20473
20474 it.current.pos = new_pos;
20475 }
20476
20477 /* If we ended up in a display string that covers point, move to
20478 buffer position to the right in the visual order. */
20479 if (dir > 0)
20480 {
20481 while (IT_CHARPOS (it) == PT)
20482 {
20483 set_iterator_to_next (&it, 0);
20484 if (!get_next_display_element (&it))
20485 break;
20486 }
20487 }
20488
20489 /* Move point to that position. */
20490 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
20491 }
20492
20493 return make_number (PT);
20494
20495 #undef ROW_GLYPH_NEWLINE_P
20496 }
20497
20498 \f
20499 /***********************************************************************
20500 Menu Bar
20501 ***********************************************************************/
20502
20503 /* Redisplay the menu bar in the frame for window W.
20504
20505 The menu bar of X frames that don't have X toolkit support is
20506 displayed in a special window W->frame->menu_bar_window.
20507
20508 The menu bar of terminal frames is treated specially as far as
20509 glyph matrices are concerned. Menu bar lines are not part of
20510 windows, so the update is done directly on the frame matrix rows
20511 for the menu bar. */
20512
20513 static void
20514 display_menu_bar (struct window *w)
20515 {
20516 struct frame *f = XFRAME (WINDOW_FRAME (w));
20517 struct it it;
20518 Lisp_Object items;
20519 int i;
20520
20521 /* Don't do all this for graphical frames. */
20522 #ifdef HAVE_NTGUI
20523 if (FRAME_W32_P (f))
20524 return;
20525 #endif
20526 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20527 if (FRAME_X_P (f))
20528 return;
20529 #endif
20530
20531 #ifdef HAVE_NS
20532 if (FRAME_NS_P (f))
20533 return;
20534 #endif /* HAVE_NS */
20535
20536 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20537 eassert (!FRAME_WINDOW_P (f));
20538 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20539 it.first_visible_x = 0;
20540 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20541 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20542 if (FRAME_WINDOW_P (f))
20543 {
20544 /* Menu bar lines are displayed in the desired matrix of the
20545 dummy window menu_bar_window. */
20546 struct window *menu_w;
20547 menu_w = XWINDOW (f->menu_bar_window);
20548 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20549 MENU_FACE_ID);
20550 it.first_visible_x = 0;
20551 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20552 }
20553 else
20554 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20555 {
20556 /* This is a TTY frame, i.e. character hpos/vpos are used as
20557 pixel x/y. */
20558 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20559 MENU_FACE_ID);
20560 it.first_visible_x = 0;
20561 it.last_visible_x = FRAME_COLS (f);
20562 }
20563
20564 /* FIXME: This should be controlled by a user option. See the
20565 comments in redisplay_tool_bar and display_mode_line about
20566 this. */
20567 it.paragraph_embedding = L2R;
20568
20569 /* Clear all rows of the menu bar. */
20570 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20571 {
20572 struct glyph_row *row = it.glyph_row + i;
20573 clear_glyph_row (row);
20574 row->enabled_p = 1;
20575 row->full_width_p = 1;
20576 }
20577
20578 /* Display all items of the menu bar. */
20579 items = FRAME_MENU_BAR_ITEMS (it.f);
20580 for (i = 0; i < ASIZE (items); i += 4)
20581 {
20582 Lisp_Object string;
20583
20584 /* Stop at nil string. */
20585 string = AREF (items, i + 1);
20586 if (NILP (string))
20587 break;
20588
20589 /* Remember where item was displayed. */
20590 ASET (items, i + 3, make_number (it.hpos));
20591
20592 /* Display the item, pad with one space. */
20593 if (it.current_x < it.last_visible_x)
20594 display_string (NULL, string, Qnil, 0, 0, &it,
20595 SCHARS (string) + 1, 0, 0, -1);
20596 }
20597
20598 /* Fill out the line with spaces. */
20599 if (it.current_x < it.last_visible_x)
20600 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20601
20602 /* Compute the total height of the lines. */
20603 compute_line_metrics (&it);
20604 }
20605
20606 #ifdef HAVE_MENUS
20607 /* Deep copy of a glyph row, including the glyphs. */
20608 static void
20609 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
20610 {
20611 struct glyph *pointers[1 + LAST_AREA];
20612 int to_used = to->used[TEXT_AREA];
20613
20614 /* Save glyph pointers of TO. */
20615 memcpy (pointers, to->glyphs, sizeof to->glyphs);
20616
20617 /* Do a structure assignment. */
20618 *to = *from;
20619
20620 /* Restore original glyph pointers of TO. */
20621 memcpy (to->glyphs, pointers, sizeof to->glyphs);
20622
20623 /* Copy the glyphs. */
20624 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
20625 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
20626
20627 /* If we filled only part of the TO row, fill the rest with
20628 space_glyph (which will display as empty space). */
20629 if (to_used > from->used[TEXT_AREA])
20630 fill_up_frame_row_with_spaces (to, to_used);
20631 }
20632
20633 /* Display one menu item on a TTY, by overwriting the glyphs in the
20634 frame F's desired glyph matrix with glyphs produced from the menu
20635 item text. Called from term.c to display TTY drop-down menus one
20636 item at a time.
20637
20638 ITEM_TEXT is the menu item text as a C string.
20639
20640 FACE_ID is the face ID to be used for this menu item. FACE_ID
20641 could specify one of 3 faces: a face for an enabled item, a face
20642 for a disabled item, or a face for a selected item.
20643
20644 X and Y are coordinates of the first glyph in the frame's desired
20645 matrix to be overwritten by the menu item. Since this is a TTY, Y
20646 is the zero-based number of the glyph row and X is the zero-based
20647 glyph number in the row, starting from left, where to start
20648 displaying the item.
20649
20650 SUBMENU non-zero means this menu item drops down a submenu, which
20651 should be indicated by displaying a proper visual cue after the
20652 item text. */
20653
20654 void
20655 display_tty_menu_item (const char *item_text, int width, int face_id,
20656 int x, int y, int submenu)
20657 {
20658 struct it it;
20659 struct frame *f = SELECTED_FRAME ();
20660 struct window *w = XWINDOW (f->selected_window);
20661 int saved_used, saved_truncated, saved_width, saved_reversed;
20662 struct glyph_row *row;
20663 size_t item_len = strlen (item_text);
20664
20665 eassert (FRAME_TERMCAP_P (f));
20666
20667 /* Don't write beyond the matrix's last row. This can happen for
20668 TTY screens that are not high enough to show the entire menu.
20669 (This is actually a bit of defensive programming, as
20670 tty_menu_display already limits the number of menu items to one
20671 less than the number of screen lines.) */
20672 if (y >= f->desired_matrix->nrows)
20673 return;
20674
20675 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
20676 it.first_visible_x = 0;
20677 it.last_visible_x = FRAME_COLS (f) - 1;
20678 row = it.glyph_row;
20679 /* Start with the row contents from the current matrix. */
20680 deep_copy_glyph_row (row, f->current_matrix->rows + y);
20681 saved_width = row->full_width_p;
20682 row->full_width_p = 1;
20683 saved_reversed = row->reversed_p;
20684 row->reversed_p = 0;
20685 row->enabled_p = 1;
20686
20687 /* Arrange for the menu item glyphs to start at (X,Y) and have the
20688 desired face. */
20689 eassert (x < f->desired_matrix->matrix_w);
20690 it.current_x = it.hpos = x;
20691 it.current_y = it.vpos = y;
20692 saved_used = row->used[TEXT_AREA];
20693 saved_truncated = row->truncated_on_right_p;
20694 row->used[TEXT_AREA] = x;
20695 it.face_id = face_id;
20696 it.line_wrap = TRUNCATE;
20697
20698 /* FIXME: This should be controlled by a user option. See the
20699 comments in redisplay_tool_bar and display_mode_line about this.
20700 Also, if paragraph_embedding could ever be R2L, changes will be
20701 needed to avoid shifting to the right the row characters in
20702 term.c:append_glyph. */
20703 it.paragraph_embedding = L2R;
20704
20705 /* Pad with a space on the left. */
20706 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
20707 width--;
20708 /* Display the menu item, pad with spaces to WIDTH. */
20709 if (submenu)
20710 {
20711 display_string (item_text, Qnil, Qnil, 0, 0, &it,
20712 item_len, 0, FRAME_COLS (f) - 1, -1);
20713 width -= item_len;
20714 /* Indicate with " >" that there's a submenu. */
20715 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
20716 FRAME_COLS (f) - 1, -1);
20717 }
20718 else
20719 display_string (item_text, Qnil, Qnil, 0, 0, &it,
20720 width, 0, FRAME_COLS (f) - 1, -1);
20721
20722 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
20723 row->truncated_on_right_p = saved_truncated;
20724 row->hash = row_hash (row);
20725 row->full_width_p = saved_width;
20726 row->reversed_p = saved_reversed;
20727 }
20728 #endif /* HAVE_MENUS */
20729 \f
20730 /***********************************************************************
20731 Mode Line
20732 ***********************************************************************/
20733
20734 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20735 FORCE is non-zero, redisplay mode lines unconditionally.
20736 Otherwise, redisplay only mode lines that are garbaged. Value is
20737 the number of windows whose mode lines were redisplayed. */
20738
20739 static int
20740 redisplay_mode_lines (Lisp_Object window, int force)
20741 {
20742 int nwindows = 0;
20743
20744 while (!NILP (window))
20745 {
20746 struct window *w = XWINDOW (window);
20747
20748 if (WINDOWP (w->contents))
20749 nwindows += redisplay_mode_lines (w->contents, force);
20750 else if (force
20751 || FRAME_GARBAGED_P (XFRAME (w->frame))
20752 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20753 {
20754 struct text_pos lpoint;
20755 struct buffer *old = current_buffer;
20756
20757 /* Set the window's buffer for the mode line display. */
20758 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20759 set_buffer_internal_1 (XBUFFER (w->contents));
20760
20761 /* Point refers normally to the selected window. For any
20762 other window, set up appropriate value. */
20763 if (!EQ (window, selected_window))
20764 {
20765 struct text_pos pt;
20766
20767 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
20768 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20769 }
20770
20771 /* Display mode lines. */
20772 clear_glyph_matrix (w->desired_matrix);
20773 if (display_mode_lines (w))
20774 {
20775 ++nwindows;
20776 w->must_be_updated_p = 1;
20777 }
20778
20779 /* Restore old settings. */
20780 set_buffer_internal_1 (old);
20781 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20782 }
20783
20784 window = w->next;
20785 }
20786
20787 return nwindows;
20788 }
20789
20790
20791 /* Display the mode and/or header line of window W. Value is the
20792 sum number of mode lines and header lines displayed. */
20793
20794 static int
20795 display_mode_lines (struct window *w)
20796 {
20797 Lisp_Object old_selected_window = selected_window;
20798 Lisp_Object old_selected_frame = selected_frame;
20799 Lisp_Object new_frame = w->frame;
20800 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20801 int n = 0;
20802
20803 selected_frame = new_frame;
20804 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20805 or window's point, then we'd need select_window_1 here as well. */
20806 XSETWINDOW (selected_window, w);
20807 XFRAME (new_frame)->selected_window = selected_window;
20808
20809 /* These will be set while the mode line specs are processed. */
20810 line_number_displayed = 0;
20811 w->column_number_displayed = -1;
20812
20813 if (WINDOW_WANTS_MODELINE_P (w))
20814 {
20815 struct window *sel_w = XWINDOW (old_selected_window);
20816
20817 /* Select mode line face based on the real selected window. */
20818 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20819 BVAR (current_buffer, mode_line_format));
20820 ++n;
20821 }
20822
20823 if (WINDOW_WANTS_HEADER_LINE_P (w))
20824 {
20825 display_mode_line (w, HEADER_LINE_FACE_ID,
20826 BVAR (current_buffer, header_line_format));
20827 ++n;
20828 }
20829
20830 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20831 selected_frame = old_selected_frame;
20832 selected_window = old_selected_window;
20833 return n;
20834 }
20835
20836
20837 /* Display mode or header line of window W. FACE_ID specifies which
20838 line to display; it is either MODE_LINE_FACE_ID or
20839 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20840 display. Value is the pixel height of the mode/header line
20841 displayed. */
20842
20843 static int
20844 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20845 {
20846 struct it it;
20847 struct face *face;
20848 ptrdiff_t count = SPECPDL_INDEX ();
20849
20850 init_iterator (&it, w, -1, -1, NULL, face_id);
20851 /* Don't extend on a previously drawn mode-line.
20852 This may happen if called from pos_visible_p. */
20853 it.glyph_row->enabled_p = 0;
20854 prepare_desired_row (it.glyph_row);
20855
20856 it.glyph_row->mode_line_p = 1;
20857
20858 /* FIXME: This should be controlled by a user option. But
20859 supporting such an option is not trivial, since the mode line is
20860 made up of many separate strings. */
20861 it.paragraph_embedding = L2R;
20862
20863 record_unwind_protect (unwind_format_mode_line,
20864 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20865
20866 mode_line_target = MODE_LINE_DISPLAY;
20867
20868 /* Temporarily make frame's keyboard the current kboard so that
20869 kboard-local variables in the mode_line_format will get the right
20870 values. */
20871 push_kboard (FRAME_KBOARD (it.f));
20872 record_unwind_save_match_data ();
20873 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20874 pop_kboard ();
20875
20876 unbind_to (count, Qnil);
20877
20878 /* Fill up with spaces. */
20879 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20880
20881 compute_line_metrics (&it);
20882 it.glyph_row->full_width_p = 1;
20883 it.glyph_row->continued_p = 0;
20884 it.glyph_row->truncated_on_left_p = 0;
20885 it.glyph_row->truncated_on_right_p = 0;
20886
20887 /* Make a 3D mode-line have a shadow at its right end. */
20888 face = FACE_FROM_ID (it.f, face_id);
20889 extend_face_to_end_of_line (&it);
20890 if (face->box != FACE_NO_BOX)
20891 {
20892 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20893 + it.glyph_row->used[TEXT_AREA] - 1);
20894 last->right_box_line_p = 1;
20895 }
20896
20897 return it.glyph_row->height;
20898 }
20899
20900 /* Move element ELT in LIST to the front of LIST.
20901 Return the updated list. */
20902
20903 static Lisp_Object
20904 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20905 {
20906 register Lisp_Object tail, prev;
20907 register Lisp_Object tem;
20908
20909 tail = list;
20910 prev = Qnil;
20911 while (CONSP (tail))
20912 {
20913 tem = XCAR (tail);
20914
20915 if (EQ (elt, tem))
20916 {
20917 /* Splice out the link TAIL. */
20918 if (NILP (prev))
20919 list = XCDR (tail);
20920 else
20921 Fsetcdr (prev, XCDR (tail));
20922
20923 /* Now make it the first. */
20924 Fsetcdr (tail, list);
20925 return tail;
20926 }
20927 else
20928 prev = tail;
20929 tail = XCDR (tail);
20930 QUIT;
20931 }
20932
20933 /* Not found--return unchanged LIST. */
20934 return list;
20935 }
20936
20937 /* Contribute ELT to the mode line for window IT->w. How it
20938 translates into text depends on its data type.
20939
20940 IT describes the display environment in which we display, as usual.
20941
20942 DEPTH is the depth in recursion. It is used to prevent
20943 infinite recursion here.
20944
20945 FIELD_WIDTH is the number of characters the display of ELT should
20946 occupy in the mode line, and PRECISION is the maximum number of
20947 characters to display from ELT's representation. See
20948 display_string for details.
20949
20950 Returns the hpos of the end of the text generated by ELT.
20951
20952 PROPS is a property list to add to any string we encounter.
20953
20954 If RISKY is nonzero, remove (disregard) any properties in any string
20955 we encounter, and ignore :eval and :propertize.
20956
20957 The global variable `mode_line_target' determines whether the
20958 output is passed to `store_mode_line_noprop',
20959 `store_mode_line_string', or `display_string'. */
20960
20961 static int
20962 display_mode_element (struct it *it, int depth, int field_width, int precision,
20963 Lisp_Object elt, Lisp_Object props, int risky)
20964 {
20965 int n = 0, field, prec;
20966 int literal = 0;
20967
20968 tail_recurse:
20969 if (depth > 100)
20970 elt = build_string ("*too-deep*");
20971
20972 depth++;
20973
20974 switch (XTYPE (elt))
20975 {
20976 case Lisp_String:
20977 {
20978 /* A string: output it and check for %-constructs within it. */
20979 unsigned char c;
20980 ptrdiff_t offset = 0;
20981
20982 if (SCHARS (elt) > 0
20983 && (!NILP (props) || risky))
20984 {
20985 Lisp_Object oprops, aelt;
20986 oprops = Ftext_properties_at (make_number (0), elt);
20987
20988 /* If the starting string's properties are not what
20989 we want, translate the string. Also, if the string
20990 is risky, do that anyway. */
20991
20992 if (NILP (Fequal (props, oprops)) || risky)
20993 {
20994 /* If the starting string has properties,
20995 merge the specified ones onto the existing ones. */
20996 if (! NILP (oprops) && !risky)
20997 {
20998 Lisp_Object tem;
20999
21000 oprops = Fcopy_sequence (oprops);
21001 tem = props;
21002 while (CONSP (tem))
21003 {
21004 oprops = Fplist_put (oprops, XCAR (tem),
21005 XCAR (XCDR (tem)));
21006 tem = XCDR (XCDR (tem));
21007 }
21008 props = oprops;
21009 }
21010
21011 aelt = Fassoc (elt, mode_line_proptrans_alist);
21012 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
21013 {
21014 /* AELT is what we want. Move it to the front
21015 without consing. */
21016 elt = XCAR (aelt);
21017 mode_line_proptrans_alist
21018 = move_elt_to_front (aelt, mode_line_proptrans_alist);
21019 }
21020 else
21021 {
21022 Lisp_Object tem;
21023
21024 /* If AELT has the wrong props, it is useless.
21025 so get rid of it. */
21026 if (! NILP (aelt))
21027 mode_line_proptrans_alist
21028 = Fdelq (aelt, mode_line_proptrans_alist);
21029
21030 elt = Fcopy_sequence (elt);
21031 Fset_text_properties (make_number (0), Flength (elt),
21032 props, elt);
21033 /* Add this item to mode_line_proptrans_alist. */
21034 mode_line_proptrans_alist
21035 = Fcons (Fcons (elt, props),
21036 mode_line_proptrans_alist);
21037 /* Truncate mode_line_proptrans_alist
21038 to at most 50 elements. */
21039 tem = Fnthcdr (make_number (50),
21040 mode_line_proptrans_alist);
21041 if (! NILP (tem))
21042 XSETCDR (tem, Qnil);
21043 }
21044 }
21045 }
21046
21047 offset = 0;
21048
21049 if (literal)
21050 {
21051 prec = precision - n;
21052 switch (mode_line_target)
21053 {
21054 case MODE_LINE_NOPROP:
21055 case MODE_LINE_TITLE:
21056 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
21057 break;
21058 case MODE_LINE_STRING:
21059 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
21060 break;
21061 case MODE_LINE_DISPLAY:
21062 n += display_string (NULL, elt, Qnil, 0, 0, it,
21063 0, prec, 0, STRING_MULTIBYTE (elt));
21064 break;
21065 }
21066
21067 break;
21068 }
21069
21070 /* Handle the non-literal case. */
21071
21072 while ((precision <= 0 || n < precision)
21073 && SREF (elt, offset) != 0
21074 && (mode_line_target != MODE_LINE_DISPLAY
21075 || it->current_x < it->last_visible_x))
21076 {
21077 ptrdiff_t last_offset = offset;
21078
21079 /* Advance to end of string or next format specifier. */
21080 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
21081 ;
21082
21083 if (offset - 1 != last_offset)
21084 {
21085 ptrdiff_t nchars, nbytes;
21086
21087 /* Output to end of string or up to '%'. Field width
21088 is length of string. Don't output more than
21089 PRECISION allows us. */
21090 offset--;
21091
21092 prec = c_string_width (SDATA (elt) + last_offset,
21093 offset - last_offset, precision - n,
21094 &nchars, &nbytes);
21095
21096 switch (mode_line_target)
21097 {
21098 case MODE_LINE_NOPROP:
21099 case MODE_LINE_TITLE:
21100 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
21101 break;
21102 case MODE_LINE_STRING:
21103 {
21104 ptrdiff_t bytepos = last_offset;
21105 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21106 ptrdiff_t endpos = (precision <= 0
21107 ? string_byte_to_char (elt, offset)
21108 : charpos + nchars);
21109
21110 n += store_mode_line_string (NULL,
21111 Fsubstring (elt, make_number (charpos),
21112 make_number (endpos)),
21113 0, 0, 0, Qnil);
21114 }
21115 break;
21116 case MODE_LINE_DISPLAY:
21117 {
21118 ptrdiff_t bytepos = last_offset;
21119 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21120
21121 if (precision <= 0)
21122 nchars = string_byte_to_char (elt, offset) - charpos;
21123 n += display_string (NULL, elt, Qnil, 0, charpos,
21124 it, 0, nchars, 0,
21125 STRING_MULTIBYTE (elt));
21126 }
21127 break;
21128 }
21129 }
21130 else /* c == '%' */
21131 {
21132 ptrdiff_t percent_position = offset;
21133
21134 /* Get the specified minimum width. Zero means
21135 don't pad. */
21136 field = 0;
21137 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
21138 field = field * 10 + c - '0';
21139
21140 /* Don't pad beyond the total padding allowed. */
21141 if (field_width - n > 0 && field > field_width - n)
21142 field = field_width - n;
21143
21144 /* Note that either PRECISION <= 0 or N < PRECISION. */
21145 prec = precision - n;
21146
21147 if (c == 'M')
21148 n += display_mode_element (it, depth, field, prec,
21149 Vglobal_mode_string, props,
21150 risky);
21151 else if (c != 0)
21152 {
21153 bool multibyte;
21154 ptrdiff_t bytepos, charpos;
21155 const char *spec;
21156 Lisp_Object string;
21157
21158 bytepos = percent_position;
21159 charpos = (STRING_MULTIBYTE (elt)
21160 ? string_byte_to_char (elt, bytepos)
21161 : bytepos);
21162 spec = decode_mode_spec (it->w, c, field, &string);
21163 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
21164
21165 switch (mode_line_target)
21166 {
21167 case MODE_LINE_NOPROP:
21168 case MODE_LINE_TITLE:
21169 n += store_mode_line_noprop (spec, field, prec);
21170 break;
21171 case MODE_LINE_STRING:
21172 {
21173 Lisp_Object tem = build_string (spec);
21174 props = Ftext_properties_at (make_number (charpos), elt);
21175 /* Should only keep face property in props */
21176 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21177 }
21178 break;
21179 case MODE_LINE_DISPLAY:
21180 {
21181 int nglyphs_before, nwritten;
21182
21183 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21184 nwritten = display_string (spec, string, elt,
21185 charpos, 0, it,
21186 field, prec, 0,
21187 multibyte);
21188
21189 /* Assign to the glyphs written above the
21190 string where the `%x' came from, position
21191 of the `%'. */
21192 if (nwritten > 0)
21193 {
21194 struct glyph *glyph
21195 = (it->glyph_row->glyphs[TEXT_AREA]
21196 + nglyphs_before);
21197 int i;
21198
21199 for (i = 0; i < nwritten; ++i)
21200 {
21201 glyph[i].object = elt;
21202 glyph[i].charpos = charpos;
21203 }
21204
21205 n += nwritten;
21206 }
21207 }
21208 break;
21209 }
21210 }
21211 else /* c == 0 */
21212 break;
21213 }
21214 }
21215 }
21216 break;
21217
21218 case Lisp_Symbol:
21219 /* A symbol: process the value of the symbol recursively
21220 as if it appeared here directly. Avoid error if symbol void.
21221 Special case: if value of symbol is a string, output the string
21222 literally. */
21223 {
21224 register Lisp_Object tem;
21225
21226 /* If the variable is not marked as risky to set
21227 then its contents are risky to use. */
21228 if (NILP (Fget (elt, Qrisky_local_variable)))
21229 risky = 1;
21230
21231 tem = Fboundp (elt);
21232 if (!NILP (tem))
21233 {
21234 tem = Fsymbol_value (elt);
21235 /* If value is a string, output that string literally:
21236 don't check for % within it. */
21237 if (STRINGP (tem))
21238 literal = 1;
21239
21240 if (!EQ (tem, elt))
21241 {
21242 /* Give up right away for nil or t. */
21243 elt = tem;
21244 goto tail_recurse;
21245 }
21246 }
21247 }
21248 break;
21249
21250 case Lisp_Cons:
21251 {
21252 register Lisp_Object car, tem;
21253
21254 /* A cons cell: five distinct cases.
21255 If first element is :eval or :propertize, do something special.
21256 If first element is a string or a cons, process all the elements
21257 and effectively concatenate them.
21258 If first element is a negative number, truncate displaying cdr to
21259 at most that many characters. If positive, pad (with spaces)
21260 to at least that many characters.
21261 If first element is a symbol, process the cadr or caddr recursively
21262 according to whether the symbol's value is non-nil or nil. */
21263 car = XCAR (elt);
21264 if (EQ (car, QCeval))
21265 {
21266 /* An element of the form (:eval FORM) means evaluate FORM
21267 and use the result as mode line elements. */
21268
21269 if (risky)
21270 break;
21271
21272 if (CONSP (XCDR (elt)))
21273 {
21274 Lisp_Object spec;
21275 spec = safe_eval (XCAR (XCDR (elt)));
21276 n += display_mode_element (it, depth, field_width - n,
21277 precision - n, spec, props,
21278 risky);
21279 }
21280 }
21281 else if (EQ (car, QCpropertize))
21282 {
21283 /* An element of the form (:propertize ELT PROPS...)
21284 means display ELT but applying properties PROPS. */
21285
21286 if (risky)
21287 break;
21288
21289 if (CONSP (XCDR (elt)))
21290 n += display_mode_element (it, depth, field_width - n,
21291 precision - n, XCAR (XCDR (elt)),
21292 XCDR (XCDR (elt)), risky);
21293 }
21294 else if (SYMBOLP (car))
21295 {
21296 tem = Fboundp (car);
21297 elt = XCDR (elt);
21298 if (!CONSP (elt))
21299 goto invalid;
21300 /* elt is now the cdr, and we know it is a cons cell.
21301 Use its car if CAR has a non-nil value. */
21302 if (!NILP (tem))
21303 {
21304 tem = Fsymbol_value (car);
21305 if (!NILP (tem))
21306 {
21307 elt = XCAR (elt);
21308 goto tail_recurse;
21309 }
21310 }
21311 /* Symbol's value is nil (or symbol is unbound)
21312 Get the cddr of the original list
21313 and if possible find the caddr and use that. */
21314 elt = XCDR (elt);
21315 if (NILP (elt))
21316 break;
21317 else if (!CONSP (elt))
21318 goto invalid;
21319 elt = XCAR (elt);
21320 goto tail_recurse;
21321 }
21322 else if (INTEGERP (car))
21323 {
21324 register int lim = XINT (car);
21325 elt = XCDR (elt);
21326 if (lim < 0)
21327 {
21328 /* Negative int means reduce maximum width. */
21329 if (precision <= 0)
21330 precision = -lim;
21331 else
21332 precision = min (precision, -lim);
21333 }
21334 else if (lim > 0)
21335 {
21336 /* Padding specified. Don't let it be more than
21337 current maximum. */
21338 if (precision > 0)
21339 lim = min (precision, lim);
21340
21341 /* If that's more padding than already wanted, queue it.
21342 But don't reduce padding already specified even if
21343 that is beyond the current truncation point. */
21344 field_width = max (lim, field_width);
21345 }
21346 goto tail_recurse;
21347 }
21348 else if (STRINGP (car) || CONSP (car))
21349 {
21350 Lisp_Object halftail = elt;
21351 int len = 0;
21352
21353 while (CONSP (elt)
21354 && (precision <= 0 || n < precision))
21355 {
21356 n += display_mode_element (it, depth,
21357 /* Do padding only after the last
21358 element in the list. */
21359 (! CONSP (XCDR (elt))
21360 ? field_width - n
21361 : 0),
21362 precision - n, XCAR (elt),
21363 props, risky);
21364 elt = XCDR (elt);
21365 len++;
21366 if ((len & 1) == 0)
21367 halftail = XCDR (halftail);
21368 /* Check for cycle. */
21369 if (EQ (halftail, elt))
21370 break;
21371 }
21372 }
21373 }
21374 break;
21375
21376 default:
21377 invalid:
21378 elt = build_string ("*invalid*");
21379 goto tail_recurse;
21380 }
21381
21382 /* Pad to FIELD_WIDTH. */
21383 if (field_width > 0 && n < field_width)
21384 {
21385 switch (mode_line_target)
21386 {
21387 case MODE_LINE_NOPROP:
21388 case MODE_LINE_TITLE:
21389 n += store_mode_line_noprop ("", field_width - n, 0);
21390 break;
21391 case MODE_LINE_STRING:
21392 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
21393 break;
21394 case MODE_LINE_DISPLAY:
21395 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
21396 0, 0, 0);
21397 break;
21398 }
21399 }
21400
21401 return n;
21402 }
21403
21404 /* Store a mode-line string element in mode_line_string_list.
21405
21406 If STRING is non-null, display that C string. Otherwise, the Lisp
21407 string LISP_STRING is displayed.
21408
21409 FIELD_WIDTH is the minimum number of output glyphs to produce.
21410 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21411 with spaces. FIELD_WIDTH <= 0 means don't pad.
21412
21413 PRECISION is the maximum number of characters to output from
21414 STRING. PRECISION <= 0 means don't truncate the string.
21415
21416 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21417 properties to the string.
21418
21419 PROPS are the properties to add to the string.
21420 The mode_line_string_face face property is always added to the string.
21421 */
21422
21423 static int
21424 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21425 int field_width, int precision, Lisp_Object props)
21426 {
21427 ptrdiff_t len;
21428 int n = 0;
21429
21430 if (string != NULL)
21431 {
21432 len = strlen (string);
21433 if (precision > 0 && len > precision)
21434 len = precision;
21435 lisp_string = make_string (string, len);
21436 if (NILP (props))
21437 props = mode_line_string_face_prop;
21438 else if (!NILP (mode_line_string_face))
21439 {
21440 Lisp_Object face = Fplist_get (props, Qface);
21441 props = Fcopy_sequence (props);
21442 if (NILP (face))
21443 face = mode_line_string_face;
21444 else
21445 face = list2 (face, mode_line_string_face);
21446 props = Fplist_put (props, Qface, face);
21447 }
21448 Fadd_text_properties (make_number (0), make_number (len),
21449 props, lisp_string);
21450 }
21451 else
21452 {
21453 len = XFASTINT (Flength (lisp_string));
21454 if (precision > 0 && len > precision)
21455 {
21456 len = precision;
21457 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21458 precision = -1;
21459 }
21460 if (!NILP (mode_line_string_face))
21461 {
21462 Lisp_Object face;
21463 if (NILP (props))
21464 props = Ftext_properties_at (make_number (0), lisp_string);
21465 face = Fplist_get (props, Qface);
21466 if (NILP (face))
21467 face = mode_line_string_face;
21468 else
21469 face = list2 (face, mode_line_string_face);
21470 props = list2 (Qface, face);
21471 if (copy_string)
21472 lisp_string = Fcopy_sequence (lisp_string);
21473 }
21474 if (!NILP (props))
21475 Fadd_text_properties (make_number (0), make_number (len),
21476 props, lisp_string);
21477 }
21478
21479 if (len > 0)
21480 {
21481 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21482 n += len;
21483 }
21484
21485 if (field_width > len)
21486 {
21487 field_width -= len;
21488 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21489 if (!NILP (props))
21490 Fadd_text_properties (make_number (0), make_number (field_width),
21491 props, lisp_string);
21492 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21493 n += field_width;
21494 }
21495
21496 return n;
21497 }
21498
21499
21500 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21501 1, 4, 0,
21502 doc: /* Format a string out of a mode line format specification.
21503 First arg FORMAT specifies the mode line format (see `mode-line-format'
21504 for details) to use.
21505
21506 By default, the format is evaluated for the currently selected window.
21507
21508 Optional second arg FACE specifies the face property to put on all
21509 characters for which no face is specified. The value nil means the
21510 default face. The value t means whatever face the window's mode line
21511 currently uses (either `mode-line' or `mode-line-inactive',
21512 depending on whether the window is the selected window or not).
21513 An integer value means the value string has no text
21514 properties.
21515
21516 Optional third and fourth args WINDOW and BUFFER specify the window
21517 and buffer to use as the context for the formatting (defaults
21518 are the selected window and the WINDOW's buffer). */)
21519 (Lisp_Object format, Lisp_Object face,
21520 Lisp_Object window, Lisp_Object buffer)
21521 {
21522 struct it it;
21523 int len;
21524 struct window *w;
21525 struct buffer *old_buffer = NULL;
21526 int face_id;
21527 int no_props = INTEGERP (face);
21528 ptrdiff_t count = SPECPDL_INDEX ();
21529 Lisp_Object str;
21530 int string_start = 0;
21531
21532 w = decode_any_window (window);
21533 XSETWINDOW (window, w);
21534
21535 if (NILP (buffer))
21536 buffer = w->contents;
21537 CHECK_BUFFER (buffer);
21538
21539 /* Make formatting the modeline a non-op when noninteractive, otherwise
21540 there will be problems later caused by a partially initialized frame. */
21541 if (NILP (format) || noninteractive)
21542 return empty_unibyte_string;
21543
21544 if (no_props)
21545 face = Qnil;
21546
21547 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21548 : EQ (face, Qt) ? (EQ (window, selected_window)
21549 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21550 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21551 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21552 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21553 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21554 : DEFAULT_FACE_ID;
21555
21556 old_buffer = current_buffer;
21557
21558 /* Save things including mode_line_proptrans_alist,
21559 and set that to nil so that we don't alter the outer value. */
21560 record_unwind_protect (unwind_format_mode_line,
21561 format_mode_line_unwind_data
21562 (XFRAME (WINDOW_FRAME (w)),
21563 old_buffer, selected_window, 1));
21564 mode_line_proptrans_alist = Qnil;
21565
21566 Fselect_window (window, Qt);
21567 set_buffer_internal_1 (XBUFFER (buffer));
21568
21569 init_iterator (&it, w, -1, -1, NULL, face_id);
21570
21571 if (no_props)
21572 {
21573 mode_line_target = MODE_LINE_NOPROP;
21574 mode_line_string_face_prop = Qnil;
21575 mode_line_string_list = Qnil;
21576 string_start = MODE_LINE_NOPROP_LEN (0);
21577 }
21578 else
21579 {
21580 mode_line_target = MODE_LINE_STRING;
21581 mode_line_string_list = Qnil;
21582 mode_line_string_face = face;
21583 mode_line_string_face_prop
21584 = NILP (face) ? Qnil : list2 (Qface, face);
21585 }
21586
21587 push_kboard (FRAME_KBOARD (it.f));
21588 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21589 pop_kboard ();
21590
21591 if (no_props)
21592 {
21593 len = MODE_LINE_NOPROP_LEN (string_start);
21594 str = make_string (mode_line_noprop_buf + string_start, len);
21595 }
21596 else
21597 {
21598 mode_line_string_list = Fnreverse (mode_line_string_list);
21599 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21600 empty_unibyte_string);
21601 }
21602
21603 unbind_to (count, Qnil);
21604 return str;
21605 }
21606
21607 /* Write a null-terminated, right justified decimal representation of
21608 the positive integer D to BUF using a minimal field width WIDTH. */
21609
21610 static void
21611 pint2str (register char *buf, register int width, register ptrdiff_t d)
21612 {
21613 register char *p = buf;
21614
21615 if (d <= 0)
21616 *p++ = '0';
21617 else
21618 {
21619 while (d > 0)
21620 {
21621 *p++ = d % 10 + '0';
21622 d /= 10;
21623 }
21624 }
21625
21626 for (width -= (int) (p - buf); width > 0; --width)
21627 *p++ = ' ';
21628 *p-- = '\0';
21629 while (p > buf)
21630 {
21631 d = *buf;
21632 *buf++ = *p;
21633 *p-- = d;
21634 }
21635 }
21636
21637 /* Write a null-terminated, right justified decimal and "human
21638 readable" representation of the nonnegative integer D to BUF using
21639 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21640
21641 static const char power_letter[] =
21642 {
21643 0, /* no letter */
21644 'k', /* kilo */
21645 'M', /* mega */
21646 'G', /* giga */
21647 'T', /* tera */
21648 'P', /* peta */
21649 'E', /* exa */
21650 'Z', /* zetta */
21651 'Y' /* yotta */
21652 };
21653
21654 static void
21655 pint2hrstr (char *buf, int width, ptrdiff_t d)
21656 {
21657 /* We aim to represent the nonnegative integer D as
21658 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21659 ptrdiff_t quotient = d;
21660 int remainder = 0;
21661 /* -1 means: do not use TENTHS. */
21662 int tenths = -1;
21663 int exponent = 0;
21664
21665 /* Length of QUOTIENT.TENTHS as a string. */
21666 int length;
21667
21668 char * psuffix;
21669 char * p;
21670
21671 if (quotient >= 1000)
21672 {
21673 /* Scale to the appropriate EXPONENT. */
21674 do
21675 {
21676 remainder = quotient % 1000;
21677 quotient /= 1000;
21678 exponent++;
21679 }
21680 while (quotient >= 1000);
21681
21682 /* Round to nearest and decide whether to use TENTHS or not. */
21683 if (quotient <= 9)
21684 {
21685 tenths = remainder / 100;
21686 if (remainder % 100 >= 50)
21687 {
21688 if (tenths < 9)
21689 tenths++;
21690 else
21691 {
21692 quotient++;
21693 if (quotient == 10)
21694 tenths = -1;
21695 else
21696 tenths = 0;
21697 }
21698 }
21699 }
21700 else
21701 if (remainder >= 500)
21702 {
21703 if (quotient < 999)
21704 quotient++;
21705 else
21706 {
21707 quotient = 1;
21708 exponent++;
21709 tenths = 0;
21710 }
21711 }
21712 }
21713
21714 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21715 if (tenths == -1 && quotient <= 99)
21716 if (quotient <= 9)
21717 length = 1;
21718 else
21719 length = 2;
21720 else
21721 length = 3;
21722 p = psuffix = buf + max (width, length);
21723
21724 /* Print EXPONENT. */
21725 *psuffix++ = power_letter[exponent];
21726 *psuffix = '\0';
21727
21728 /* Print TENTHS. */
21729 if (tenths >= 0)
21730 {
21731 *--p = '0' + tenths;
21732 *--p = '.';
21733 }
21734
21735 /* Print QUOTIENT. */
21736 do
21737 {
21738 int digit = quotient % 10;
21739 *--p = '0' + digit;
21740 }
21741 while ((quotient /= 10) != 0);
21742
21743 /* Print leading spaces. */
21744 while (buf < p)
21745 *--p = ' ';
21746 }
21747
21748 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21749 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21750 type of CODING_SYSTEM. Return updated pointer into BUF. */
21751
21752 static unsigned char invalid_eol_type[] = "(*invalid*)";
21753
21754 static char *
21755 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21756 {
21757 Lisp_Object val;
21758 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21759 const unsigned char *eol_str;
21760 int eol_str_len;
21761 /* The EOL conversion we are using. */
21762 Lisp_Object eoltype;
21763
21764 val = CODING_SYSTEM_SPEC (coding_system);
21765 eoltype = Qnil;
21766
21767 if (!VECTORP (val)) /* Not yet decided. */
21768 {
21769 *buf++ = multibyte ? '-' : ' ';
21770 if (eol_flag)
21771 eoltype = eol_mnemonic_undecided;
21772 /* Don't mention EOL conversion if it isn't decided. */
21773 }
21774 else
21775 {
21776 Lisp_Object attrs;
21777 Lisp_Object eolvalue;
21778
21779 attrs = AREF (val, 0);
21780 eolvalue = AREF (val, 2);
21781
21782 *buf++ = multibyte
21783 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21784 : ' ';
21785
21786 if (eol_flag)
21787 {
21788 /* The EOL conversion that is normal on this system. */
21789
21790 if (NILP (eolvalue)) /* Not yet decided. */
21791 eoltype = eol_mnemonic_undecided;
21792 else if (VECTORP (eolvalue)) /* Not yet decided. */
21793 eoltype = eol_mnemonic_undecided;
21794 else /* eolvalue is Qunix, Qdos, or Qmac. */
21795 eoltype = (EQ (eolvalue, Qunix)
21796 ? eol_mnemonic_unix
21797 : (EQ (eolvalue, Qdos) == 1
21798 ? eol_mnemonic_dos : eol_mnemonic_mac));
21799 }
21800 }
21801
21802 if (eol_flag)
21803 {
21804 /* Mention the EOL conversion if it is not the usual one. */
21805 if (STRINGP (eoltype))
21806 {
21807 eol_str = SDATA (eoltype);
21808 eol_str_len = SBYTES (eoltype);
21809 }
21810 else if (CHARACTERP (eoltype))
21811 {
21812 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21813 int c = XFASTINT (eoltype);
21814 eol_str_len = CHAR_STRING (c, tmp);
21815 eol_str = tmp;
21816 }
21817 else
21818 {
21819 eol_str = invalid_eol_type;
21820 eol_str_len = sizeof (invalid_eol_type) - 1;
21821 }
21822 memcpy (buf, eol_str, eol_str_len);
21823 buf += eol_str_len;
21824 }
21825
21826 return buf;
21827 }
21828
21829 /* Return a string for the output of a mode line %-spec for window W,
21830 generated by character C. FIELD_WIDTH > 0 means pad the string
21831 returned with spaces to that value. Return a Lisp string in
21832 *STRING if the resulting string is taken from that Lisp string.
21833
21834 Note we operate on the current buffer for most purposes. */
21835
21836 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21837
21838 static const char *
21839 decode_mode_spec (struct window *w, register int c, int field_width,
21840 Lisp_Object *string)
21841 {
21842 Lisp_Object obj;
21843 struct frame *f = XFRAME (WINDOW_FRAME (w));
21844 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21845 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21846 produce strings from numerical values, so limit preposterously
21847 large values of FIELD_WIDTH to avoid overrunning the buffer's
21848 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21849 bytes plus the terminating null. */
21850 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21851 struct buffer *b = current_buffer;
21852
21853 obj = Qnil;
21854 *string = Qnil;
21855
21856 switch (c)
21857 {
21858 case '*':
21859 if (!NILP (BVAR (b, read_only)))
21860 return "%";
21861 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21862 return "*";
21863 return "-";
21864
21865 case '+':
21866 /* This differs from %* only for a modified read-only buffer. */
21867 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21868 return "*";
21869 if (!NILP (BVAR (b, read_only)))
21870 return "%";
21871 return "-";
21872
21873 case '&':
21874 /* This differs from %* in ignoring read-only-ness. */
21875 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21876 return "*";
21877 return "-";
21878
21879 case '%':
21880 return "%";
21881
21882 case '[':
21883 {
21884 int i;
21885 char *p;
21886
21887 if (command_loop_level > 5)
21888 return "[[[... ";
21889 p = decode_mode_spec_buf;
21890 for (i = 0; i < command_loop_level; i++)
21891 *p++ = '[';
21892 *p = 0;
21893 return decode_mode_spec_buf;
21894 }
21895
21896 case ']':
21897 {
21898 int i;
21899 char *p;
21900
21901 if (command_loop_level > 5)
21902 return " ...]]]";
21903 p = decode_mode_spec_buf;
21904 for (i = 0; i < command_loop_level; i++)
21905 *p++ = ']';
21906 *p = 0;
21907 return decode_mode_spec_buf;
21908 }
21909
21910 case '-':
21911 {
21912 register int i;
21913
21914 /* Let lots_of_dashes be a string of infinite length. */
21915 if (mode_line_target == MODE_LINE_NOPROP
21916 || mode_line_target == MODE_LINE_STRING)
21917 return "--";
21918 if (field_width <= 0
21919 || field_width > sizeof (lots_of_dashes))
21920 {
21921 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21922 decode_mode_spec_buf[i] = '-';
21923 decode_mode_spec_buf[i] = '\0';
21924 return decode_mode_spec_buf;
21925 }
21926 else
21927 return lots_of_dashes;
21928 }
21929
21930 case 'b':
21931 obj = BVAR (b, name);
21932 break;
21933
21934 case 'c':
21935 /* %c and %l are ignored in `frame-title-format'.
21936 (In redisplay_internal, the frame title is drawn _before_ the
21937 windows are updated, so the stuff which depends on actual
21938 window contents (such as %l) may fail to render properly, or
21939 even crash emacs.) */
21940 if (mode_line_target == MODE_LINE_TITLE)
21941 return "";
21942 else
21943 {
21944 ptrdiff_t col = current_column ();
21945 w->column_number_displayed = col;
21946 pint2str (decode_mode_spec_buf, width, col);
21947 return decode_mode_spec_buf;
21948 }
21949
21950 case 'e':
21951 #ifndef SYSTEM_MALLOC
21952 {
21953 if (NILP (Vmemory_full))
21954 return "";
21955 else
21956 return "!MEM FULL! ";
21957 }
21958 #else
21959 return "";
21960 #endif
21961
21962 case 'F':
21963 /* %F displays the frame name. */
21964 if (!NILP (f->title))
21965 return SSDATA (f->title);
21966 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21967 return SSDATA (f->name);
21968 return "Emacs";
21969
21970 case 'f':
21971 obj = BVAR (b, filename);
21972 break;
21973
21974 case 'i':
21975 {
21976 ptrdiff_t size = ZV - BEGV;
21977 pint2str (decode_mode_spec_buf, width, size);
21978 return decode_mode_spec_buf;
21979 }
21980
21981 case 'I':
21982 {
21983 ptrdiff_t size = ZV - BEGV;
21984 pint2hrstr (decode_mode_spec_buf, width, size);
21985 return decode_mode_spec_buf;
21986 }
21987
21988 case 'l':
21989 {
21990 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21991 ptrdiff_t topline, nlines, height;
21992 ptrdiff_t junk;
21993
21994 /* %c and %l are ignored in `frame-title-format'. */
21995 if (mode_line_target == MODE_LINE_TITLE)
21996 return "";
21997
21998 startpos = marker_position (w->start);
21999 startpos_byte = marker_byte_position (w->start);
22000 height = WINDOW_TOTAL_LINES (w);
22001
22002 /* If we decided that this buffer isn't suitable for line numbers,
22003 don't forget that too fast. */
22004 if (w->base_line_pos == -1)
22005 goto no_value;
22006
22007 /* If the buffer is very big, don't waste time. */
22008 if (INTEGERP (Vline_number_display_limit)
22009 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
22010 {
22011 w->base_line_pos = 0;
22012 w->base_line_number = 0;
22013 goto no_value;
22014 }
22015
22016 if (w->base_line_number > 0
22017 && w->base_line_pos > 0
22018 && w->base_line_pos <= startpos)
22019 {
22020 line = w->base_line_number;
22021 linepos = w->base_line_pos;
22022 linepos_byte = buf_charpos_to_bytepos (b, linepos);
22023 }
22024 else
22025 {
22026 line = 1;
22027 linepos = BUF_BEGV (b);
22028 linepos_byte = BUF_BEGV_BYTE (b);
22029 }
22030
22031 /* Count lines from base line to window start position. */
22032 nlines = display_count_lines (linepos_byte,
22033 startpos_byte,
22034 startpos, &junk);
22035
22036 topline = nlines + line;
22037
22038 /* Determine a new base line, if the old one is too close
22039 or too far away, or if we did not have one.
22040 "Too close" means it's plausible a scroll-down would
22041 go back past it. */
22042 if (startpos == BUF_BEGV (b))
22043 {
22044 w->base_line_number = topline;
22045 w->base_line_pos = BUF_BEGV (b);
22046 }
22047 else if (nlines < height + 25 || nlines > height * 3 + 50
22048 || linepos == BUF_BEGV (b))
22049 {
22050 ptrdiff_t limit = BUF_BEGV (b);
22051 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
22052 ptrdiff_t position;
22053 ptrdiff_t distance =
22054 (height * 2 + 30) * line_number_display_limit_width;
22055
22056 if (startpos - distance > limit)
22057 {
22058 limit = startpos - distance;
22059 limit_byte = CHAR_TO_BYTE (limit);
22060 }
22061
22062 nlines = display_count_lines (startpos_byte,
22063 limit_byte,
22064 - (height * 2 + 30),
22065 &position);
22066 /* If we couldn't find the lines we wanted within
22067 line_number_display_limit_width chars per line,
22068 give up on line numbers for this window. */
22069 if (position == limit_byte && limit == startpos - distance)
22070 {
22071 w->base_line_pos = -1;
22072 w->base_line_number = 0;
22073 goto no_value;
22074 }
22075
22076 w->base_line_number = topline - nlines;
22077 w->base_line_pos = BYTE_TO_CHAR (position);
22078 }
22079
22080 /* Now count lines from the start pos to point. */
22081 nlines = display_count_lines (startpos_byte,
22082 PT_BYTE, PT, &junk);
22083
22084 /* Record that we did display the line number. */
22085 line_number_displayed = 1;
22086
22087 /* Make the string to show. */
22088 pint2str (decode_mode_spec_buf, width, topline + nlines);
22089 return decode_mode_spec_buf;
22090 no_value:
22091 {
22092 char* p = decode_mode_spec_buf;
22093 int pad = width - 2;
22094 while (pad-- > 0)
22095 *p++ = ' ';
22096 *p++ = '?';
22097 *p++ = '?';
22098 *p = '\0';
22099 return decode_mode_spec_buf;
22100 }
22101 }
22102 break;
22103
22104 case 'm':
22105 obj = BVAR (b, mode_name);
22106 break;
22107
22108 case 'n':
22109 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
22110 return " Narrow";
22111 break;
22112
22113 case 'p':
22114 {
22115 ptrdiff_t pos = marker_position (w->start);
22116 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22117
22118 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
22119 {
22120 if (pos <= BUF_BEGV (b))
22121 return "All";
22122 else
22123 return "Bottom";
22124 }
22125 else if (pos <= BUF_BEGV (b))
22126 return "Top";
22127 else
22128 {
22129 if (total > 1000000)
22130 /* Do it differently for a large value, to avoid overflow. */
22131 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22132 else
22133 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
22134 /* We can't normally display a 3-digit number,
22135 so get us a 2-digit number that is close. */
22136 if (total == 100)
22137 total = 99;
22138 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22139 return decode_mode_spec_buf;
22140 }
22141 }
22142
22143 /* Display percentage of size above the bottom of the screen. */
22144 case 'P':
22145 {
22146 ptrdiff_t toppos = marker_position (w->start);
22147 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
22148 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22149
22150 if (botpos >= BUF_ZV (b))
22151 {
22152 if (toppos <= BUF_BEGV (b))
22153 return "All";
22154 else
22155 return "Bottom";
22156 }
22157 else
22158 {
22159 if (total > 1000000)
22160 /* Do it differently for a large value, to avoid overflow. */
22161 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22162 else
22163 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
22164 /* We can't normally display a 3-digit number,
22165 so get us a 2-digit number that is close. */
22166 if (total == 100)
22167 total = 99;
22168 if (toppos <= BUF_BEGV (b))
22169 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22170 else
22171 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22172 return decode_mode_spec_buf;
22173 }
22174 }
22175
22176 case 's':
22177 /* status of process */
22178 obj = Fget_buffer_process (Fcurrent_buffer ());
22179 if (NILP (obj))
22180 return "no process";
22181 #ifndef MSDOS
22182 obj = Fsymbol_name (Fprocess_status (obj));
22183 #endif
22184 break;
22185
22186 case '@':
22187 {
22188 ptrdiff_t count = inhibit_garbage_collection ();
22189 Lisp_Object val = call1 (intern ("file-remote-p"),
22190 BVAR (current_buffer, directory));
22191 unbind_to (count, Qnil);
22192
22193 if (NILP (val))
22194 return "-";
22195 else
22196 return "@";
22197 }
22198
22199 case 'z':
22200 /* coding-system (not including end-of-line format) */
22201 case 'Z':
22202 /* coding-system (including end-of-line type) */
22203 {
22204 int eol_flag = (c == 'Z');
22205 char *p = decode_mode_spec_buf;
22206
22207 if (! FRAME_WINDOW_P (f))
22208 {
22209 /* No need to mention EOL here--the terminal never needs
22210 to do EOL conversion. */
22211 p = decode_mode_spec_coding (CODING_ID_NAME
22212 (FRAME_KEYBOARD_CODING (f)->id),
22213 p, 0);
22214 p = decode_mode_spec_coding (CODING_ID_NAME
22215 (FRAME_TERMINAL_CODING (f)->id),
22216 p, 0);
22217 }
22218 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
22219 p, eol_flag);
22220
22221 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22222 #ifdef subprocesses
22223 obj = Fget_buffer_process (Fcurrent_buffer ());
22224 if (PROCESSP (obj))
22225 {
22226 p = decode_mode_spec_coding
22227 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
22228 p = decode_mode_spec_coding
22229 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
22230 }
22231 #endif /* subprocesses */
22232 #endif /* 0 */
22233 *p = 0;
22234 return decode_mode_spec_buf;
22235 }
22236 }
22237
22238 if (STRINGP (obj))
22239 {
22240 *string = obj;
22241 return SSDATA (obj);
22242 }
22243 else
22244 return "";
22245 }
22246
22247
22248 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22249 means count lines back from START_BYTE. But don't go beyond
22250 LIMIT_BYTE. Return the number of lines thus found (always
22251 nonnegative).
22252
22253 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22254 either the position COUNT lines after/before START_BYTE, if we
22255 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22256 COUNT lines. */
22257
22258 static ptrdiff_t
22259 display_count_lines (ptrdiff_t start_byte,
22260 ptrdiff_t limit_byte, ptrdiff_t count,
22261 ptrdiff_t *byte_pos_ptr)
22262 {
22263 register unsigned char *cursor;
22264 unsigned char *base;
22265
22266 register ptrdiff_t ceiling;
22267 register unsigned char *ceiling_addr;
22268 ptrdiff_t orig_count = count;
22269
22270 /* If we are not in selective display mode,
22271 check only for newlines. */
22272 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
22273 && !INTEGERP (BVAR (current_buffer, selective_display)));
22274
22275 if (count > 0)
22276 {
22277 while (start_byte < limit_byte)
22278 {
22279 ceiling = BUFFER_CEILING_OF (start_byte);
22280 ceiling = min (limit_byte - 1, ceiling);
22281 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
22282 base = (cursor = BYTE_POS_ADDR (start_byte));
22283
22284 do
22285 {
22286 if (selective_display)
22287 {
22288 while (*cursor != '\n' && *cursor != 015
22289 && ++cursor != ceiling_addr)
22290 continue;
22291 if (cursor == ceiling_addr)
22292 break;
22293 }
22294 else
22295 {
22296 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
22297 if (! cursor)
22298 break;
22299 }
22300
22301 cursor++;
22302
22303 if (--count == 0)
22304 {
22305 start_byte += cursor - base;
22306 *byte_pos_ptr = start_byte;
22307 return orig_count;
22308 }
22309 }
22310 while (cursor < ceiling_addr);
22311
22312 start_byte += ceiling_addr - base;
22313 }
22314 }
22315 else
22316 {
22317 while (start_byte > limit_byte)
22318 {
22319 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
22320 ceiling = max (limit_byte, ceiling);
22321 ceiling_addr = BYTE_POS_ADDR (ceiling);
22322 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
22323 while (1)
22324 {
22325 if (selective_display)
22326 {
22327 while (--cursor >= ceiling_addr
22328 && *cursor != '\n' && *cursor != 015)
22329 continue;
22330 if (cursor < ceiling_addr)
22331 break;
22332 }
22333 else
22334 {
22335 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
22336 if (! cursor)
22337 break;
22338 }
22339
22340 if (++count == 0)
22341 {
22342 start_byte += cursor - base + 1;
22343 *byte_pos_ptr = start_byte;
22344 /* When scanning backwards, we should
22345 not count the newline posterior to which we stop. */
22346 return - orig_count - 1;
22347 }
22348 }
22349 start_byte += ceiling_addr - base;
22350 }
22351 }
22352
22353 *byte_pos_ptr = limit_byte;
22354
22355 if (count < 0)
22356 return - orig_count + count;
22357 return orig_count - count;
22358
22359 }
22360
22361
22362 \f
22363 /***********************************************************************
22364 Displaying strings
22365 ***********************************************************************/
22366
22367 /* Display a NUL-terminated string, starting with index START.
22368
22369 If STRING is non-null, display that C string. Otherwise, the Lisp
22370 string LISP_STRING is displayed. There's a case that STRING is
22371 non-null and LISP_STRING is not nil. It means STRING is a string
22372 data of LISP_STRING. In that case, we display LISP_STRING while
22373 ignoring its text properties.
22374
22375 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22376 FACE_STRING. Display STRING or LISP_STRING with the face at
22377 FACE_STRING_POS in FACE_STRING:
22378
22379 Display the string in the environment given by IT, but use the
22380 standard display table, temporarily.
22381
22382 FIELD_WIDTH is the minimum number of output glyphs to produce.
22383 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22384 with spaces. If STRING has more characters, more than FIELD_WIDTH
22385 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22386
22387 PRECISION is the maximum number of characters to output from
22388 STRING. PRECISION < 0 means don't truncate the string.
22389
22390 This is roughly equivalent to printf format specifiers:
22391
22392 FIELD_WIDTH PRECISION PRINTF
22393 ----------------------------------------
22394 -1 -1 %s
22395 -1 10 %.10s
22396 10 -1 %10s
22397 20 10 %20.10s
22398
22399 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22400 display them, and < 0 means obey the current buffer's value of
22401 enable_multibyte_characters.
22402
22403 Value is the number of columns displayed. */
22404
22405 static int
22406 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
22407 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
22408 int field_width, int precision, int max_x, int multibyte)
22409 {
22410 int hpos_at_start = it->hpos;
22411 int saved_face_id = it->face_id;
22412 struct glyph_row *row = it->glyph_row;
22413 ptrdiff_t it_charpos;
22414
22415 /* Initialize the iterator IT for iteration over STRING beginning
22416 with index START. */
22417 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22418 precision, field_width, multibyte);
22419 if (string && STRINGP (lisp_string))
22420 /* LISP_STRING is the one returned by decode_mode_spec. We should
22421 ignore its text properties. */
22422 it->stop_charpos = it->end_charpos;
22423
22424 /* If displaying STRING, set up the face of the iterator from
22425 FACE_STRING, if that's given. */
22426 if (STRINGP (face_string))
22427 {
22428 ptrdiff_t endptr;
22429 struct face *face;
22430
22431 it->face_id
22432 = face_at_string_position (it->w, face_string, face_string_pos,
22433 0, &endptr, it->base_face_id, 0);
22434 face = FACE_FROM_ID (it->f, it->face_id);
22435 it->face_box_p = face->box != FACE_NO_BOX;
22436 }
22437
22438 /* Set max_x to the maximum allowed X position. Don't let it go
22439 beyond the right edge of the window. */
22440 if (max_x <= 0)
22441 max_x = it->last_visible_x;
22442 else
22443 max_x = min (max_x, it->last_visible_x);
22444
22445 /* Skip over display elements that are not visible. because IT->w is
22446 hscrolled. */
22447 if (it->current_x < it->first_visible_x)
22448 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22449 MOVE_TO_POS | MOVE_TO_X);
22450
22451 row->ascent = it->max_ascent;
22452 row->height = it->max_ascent + it->max_descent;
22453 row->phys_ascent = it->max_phys_ascent;
22454 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22455 row->extra_line_spacing = it->max_extra_line_spacing;
22456
22457 if (STRINGP (it->string))
22458 it_charpos = IT_STRING_CHARPOS (*it);
22459 else
22460 it_charpos = IT_CHARPOS (*it);
22461
22462 /* This condition is for the case that we are called with current_x
22463 past last_visible_x. */
22464 while (it->current_x < max_x)
22465 {
22466 int x_before, x, n_glyphs_before, i, nglyphs;
22467
22468 /* Get the next display element. */
22469 if (!get_next_display_element (it))
22470 break;
22471
22472 /* Produce glyphs. */
22473 x_before = it->current_x;
22474 n_glyphs_before = row->used[TEXT_AREA];
22475 PRODUCE_GLYPHS (it);
22476
22477 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22478 i = 0;
22479 x = x_before;
22480 while (i < nglyphs)
22481 {
22482 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22483
22484 if (it->line_wrap != TRUNCATE
22485 && x + glyph->pixel_width > max_x)
22486 {
22487 /* End of continued line or max_x reached. */
22488 if (CHAR_GLYPH_PADDING_P (*glyph))
22489 {
22490 /* A wide character is unbreakable. */
22491 if (row->reversed_p)
22492 unproduce_glyphs (it, row->used[TEXT_AREA]
22493 - n_glyphs_before);
22494 row->used[TEXT_AREA] = n_glyphs_before;
22495 it->current_x = x_before;
22496 }
22497 else
22498 {
22499 if (row->reversed_p)
22500 unproduce_glyphs (it, row->used[TEXT_AREA]
22501 - (n_glyphs_before + i));
22502 row->used[TEXT_AREA] = n_glyphs_before + i;
22503 it->current_x = x;
22504 }
22505 break;
22506 }
22507 else if (x + glyph->pixel_width >= it->first_visible_x)
22508 {
22509 /* Glyph is at least partially visible. */
22510 ++it->hpos;
22511 if (x < it->first_visible_x)
22512 row->x = x - it->first_visible_x;
22513 }
22514 else
22515 {
22516 /* Glyph is off the left margin of the display area.
22517 Should not happen. */
22518 emacs_abort ();
22519 }
22520
22521 row->ascent = max (row->ascent, it->max_ascent);
22522 row->height = max (row->height, it->max_ascent + it->max_descent);
22523 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22524 row->phys_height = max (row->phys_height,
22525 it->max_phys_ascent + it->max_phys_descent);
22526 row->extra_line_spacing = max (row->extra_line_spacing,
22527 it->max_extra_line_spacing);
22528 x += glyph->pixel_width;
22529 ++i;
22530 }
22531
22532 /* Stop if max_x reached. */
22533 if (i < nglyphs)
22534 break;
22535
22536 /* Stop at line ends. */
22537 if (ITERATOR_AT_END_OF_LINE_P (it))
22538 {
22539 it->continuation_lines_width = 0;
22540 break;
22541 }
22542
22543 set_iterator_to_next (it, 1);
22544 if (STRINGP (it->string))
22545 it_charpos = IT_STRING_CHARPOS (*it);
22546 else
22547 it_charpos = IT_CHARPOS (*it);
22548
22549 /* Stop if truncating at the right edge. */
22550 if (it->line_wrap == TRUNCATE
22551 && it->current_x >= it->last_visible_x)
22552 {
22553 /* Add truncation mark, but don't do it if the line is
22554 truncated at a padding space. */
22555 if (it_charpos < it->string_nchars)
22556 {
22557 if (!FRAME_WINDOW_P (it->f))
22558 {
22559 int ii, n;
22560
22561 if (it->current_x > it->last_visible_x)
22562 {
22563 if (!row->reversed_p)
22564 {
22565 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22566 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22567 break;
22568 }
22569 else
22570 {
22571 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22572 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22573 break;
22574 unproduce_glyphs (it, ii + 1);
22575 ii = row->used[TEXT_AREA] - (ii + 1);
22576 }
22577 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22578 {
22579 row->used[TEXT_AREA] = ii;
22580 produce_special_glyphs (it, IT_TRUNCATION);
22581 }
22582 }
22583 produce_special_glyphs (it, IT_TRUNCATION);
22584 }
22585 row->truncated_on_right_p = 1;
22586 }
22587 break;
22588 }
22589 }
22590
22591 /* Maybe insert a truncation at the left. */
22592 if (it->first_visible_x
22593 && it_charpos > 0)
22594 {
22595 if (!FRAME_WINDOW_P (it->f)
22596 || (row->reversed_p
22597 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22598 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22599 insert_left_trunc_glyphs (it);
22600 row->truncated_on_left_p = 1;
22601 }
22602
22603 it->face_id = saved_face_id;
22604
22605 /* Value is number of columns displayed. */
22606 return it->hpos - hpos_at_start;
22607 }
22608
22609
22610 \f
22611 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22612 appears as an element of LIST or as the car of an element of LIST.
22613 If PROPVAL is a list, compare each element against LIST in that
22614 way, and return 1/2 if any element of PROPVAL is found in LIST.
22615 Otherwise return 0. This function cannot quit.
22616 The return value is 2 if the text is invisible but with an ellipsis
22617 and 1 if it's invisible and without an ellipsis. */
22618
22619 int
22620 invisible_p (register Lisp_Object propval, Lisp_Object list)
22621 {
22622 register Lisp_Object tail, proptail;
22623
22624 for (tail = list; CONSP (tail); tail = XCDR (tail))
22625 {
22626 register Lisp_Object tem;
22627 tem = XCAR (tail);
22628 if (EQ (propval, tem))
22629 return 1;
22630 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22631 return NILP (XCDR (tem)) ? 1 : 2;
22632 }
22633
22634 if (CONSP (propval))
22635 {
22636 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22637 {
22638 Lisp_Object propelt;
22639 propelt = XCAR (proptail);
22640 for (tail = list; CONSP (tail); tail = XCDR (tail))
22641 {
22642 register Lisp_Object tem;
22643 tem = XCAR (tail);
22644 if (EQ (propelt, tem))
22645 return 1;
22646 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22647 return NILP (XCDR (tem)) ? 1 : 2;
22648 }
22649 }
22650 }
22651
22652 return 0;
22653 }
22654
22655 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22656 doc: /* Non-nil if the property makes the text invisible.
22657 POS-OR-PROP can be a marker or number, in which case it is taken to be
22658 a position in the current buffer and the value of the `invisible' property
22659 is checked; or it can be some other value, which is then presumed to be the
22660 value of the `invisible' property of the text of interest.
22661 The non-nil value returned can be t for truly invisible text or something
22662 else if the text is replaced by an ellipsis. */)
22663 (Lisp_Object pos_or_prop)
22664 {
22665 Lisp_Object prop
22666 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22667 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22668 : pos_or_prop);
22669 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22670 return (invis == 0 ? Qnil
22671 : invis == 1 ? Qt
22672 : make_number (invis));
22673 }
22674
22675 /* Calculate a width or height in pixels from a specification using
22676 the following elements:
22677
22678 SPEC ::=
22679 NUM - a (fractional) multiple of the default font width/height
22680 (NUM) - specifies exactly NUM pixels
22681 UNIT - a fixed number of pixels, see below.
22682 ELEMENT - size of a display element in pixels, see below.
22683 (NUM . SPEC) - equals NUM * SPEC
22684 (+ SPEC SPEC ...) - add pixel values
22685 (- SPEC SPEC ...) - subtract pixel values
22686 (- SPEC) - negate pixel value
22687
22688 NUM ::=
22689 INT or FLOAT - a number constant
22690 SYMBOL - use symbol's (buffer local) variable binding.
22691
22692 UNIT ::=
22693 in - pixels per inch *)
22694 mm - pixels per 1/1000 meter *)
22695 cm - pixels per 1/100 meter *)
22696 width - width of current font in pixels.
22697 height - height of current font in pixels.
22698
22699 *) using the ratio(s) defined in display-pixels-per-inch.
22700
22701 ELEMENT ::=
22702
22703 left-fringe - left fringe width in pixels
22704 right-fringe - right fringe width in pixels
22705
22706 left-margin - left margin width in pixels
22707 right-margin - right margin width in pixels
22708
22709 scroll-bar - scroll-bar area width in pixels
22710
22711 Examples:
22712
22713 Pixels corresponding to 5 inches:
22714 (5 . in)
22715
22716 Total width of non-text areas on left side of window (if scroll-bar is on left):
22717 '(space :width (+ left-fringe left-margin scroll-bar))
22718
22719 Align to first text column (in header line):
22720 '(space :align-to 0)
22721
22722 Align to middle of text area minus half the width of variable `my-image'
22723 containing a loaded image:
22724 '(space :align-to (0.5 . (- text my-image)))
22725
22726 Width of left margin minus width of 1 character in the default font:
22727 '(space :width (- left-margin 1))
22728
22729 Width of left margin minus width of 2 characters in the current font:
22730 '(space :width (- left-margin (2 . width)))
22731
22732 Center 1 character over left-margin (in header line):
22733 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22734
22735 Different ways to express width of left fringe plus left margin minus one pixel:
22736 '(space :width (- (+ left-fringe left-margin) (1)))
22737 '(space :width (+ left-fringe left-margin (- (1))))
22738 '(space :width (+ left-fringe left-margin (-1)))
22739
22740 */
22741
22742 static int
22743 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22744 struct font *font, int width_p, int *align_to)
22745 {
22746 double pixels;
22747
22748 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22749 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22750
22751 if (NILP (prop))
22752 return OK_PIXELS (0);
22753
22754 eassert (FRAME_LIVE_P (it->f));
22755
22756 if (SYMBOLP (prop))
22757 {
22758 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22759 {
22760 char *unit = SSDATA (SYMBOL_NAME (prop));
22761
22762 if (unit[0] == 'i' && unit[1] == 'n')
22763 pixels = 1.0;
22764 else if (unit[0] == 'm' && unit[1] == 'm')
22765 pixels = 25.4;
22766 else if (unit[0] == 'c' && unit[1] == 'm')
22767 pixels = 2.54;
22768 else
22769 pixels = 0;
22770 if (pixels > 0)
22771 {
22772 double ppi = (width_p ? FRAME_RES_X (it->f)
22773 : FRAME_RES_Y (it->f));
22774
22775 if (ppi > 0)
22776 return OK_PIXELS (ppi / pixels);
22777 return 0;
22778 }
22779 }
22780
22781 #ifdef HAVE_WINDOW_SYSTEM
22782 if (EQ (prop, Qheight))
22783 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22784 if (EQ (prop, Qwidth))
22785 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22786 #else
22787 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22788 return OK_PIXELS (1);
22789 #endif
22790
22791 if (EQ (prop, Qtext))
22792 return OK_PIXELS (width_p
22793 ? window_box_width (it->w, TEXT_AREA)
22794 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22795
22796 if (align_to && *align_to < 0)
22797 {
22798 *res = 0;
22799 if (EQ (prop, Qleft))
22800 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22801 if (EQ (prop, Qright))
22802 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22803 if (EQ (prop, Qcenter))
22804 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22805 + window_box_width (it->w, TEXT_AREA) / 2);
22806 if (EQ (prop, Qleft_fringe))
22807 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22808 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22809 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22810 if (EQ (prop, Qright_fringe))
22811 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22812 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22813 : window_box_right_offset (it->w, TEXT_AREA));
22814 if (EQ (prop, Qleft_margin))
22815 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22816 if (EQ (prop, Qright_margin))
22817 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22818 if (EQ (prop, Qscroll_bar))
22819 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22820 ? 0
22821 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22822 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22823 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22824 : 0)));
22825 }
22826 else
22827 {
22828 if (EQ (prop, Qleft_fringe))
22829 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22830 if (EQ (prop, Qright_fringe))
22831 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22832 if (EQ (prop, Qleft_margin))
22833 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22834 if (EQ (prop, Qright_margin))
22835 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22836 if (EQ (prop, Qscroll_bar))
22837 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22838 }
22839
22840 prop = buffer_local_value_1 (prop, it->w->contents);
22841 if (EQ (prop, Qunbound))
22842 prop = Qnil;
22843 }
22844
22845 if (INTEGERP (prop) || FLOATP (prop))
22846 {
22847 int base_unit = (width_p
22848 ? FRAME_COLUMN_WIDTH (it->f)
22849 : FRAME_LINE_HEIGHT (it->f));
22850 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22851 }
22852
22853 if (CONSP (prop))
22854 {
22855 Lisp_Object car = XCAR (prop);
22856 Lisp_Object cdr = XCDR (prop);
22857
22858 if (SYMBOLP (car))
22859 {
22860 #ifdef HAVE_WINDOW_SYSTEM
22861 if (FRAME_WINDOW_P (it->f)
22862 && valid_image_p (prop))
22863 {
22864 ptrdiff_t id = lookup_image (it->f, prop);
22865 struct image *img = IMAGE_FROM_ID (it->f, id);
22866
22867 return OK_PIXELS (width_p ? img->width : img->height);
22868 }
22869 #endif
22870 if (EQ (car, Qplus) || EQ (car, Qminus))
22871 {
22872 int first = 1;
22873 double px;
22874
22875 pixels = 0;
22876 while (CONSP (cdr))
22877 {
22878 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22879 font, width_p, align_to))
22880 return 0;
22881 if (first)
22882 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22883 else
22884 pixels += px;
22885 cdr = XCDR (cdr);
22886 }
22887 if (EQ (car, Qminus))
22888 pixels = -pixels;
22889 return OK_PIXELS (pixels);
22890 }
22891
22892 car = buffer_local_value_1 (car, it->w->contents);
22893 if (EQ (car, Qunbound))
22894 car = Qnil;
22895 }
22896
22897 if (INTEGERP (car) || FLOATP (car))
22898 {
22899 double fact;
22900 pixels = XFLOATINT (car);
22901 if (NILP (cdr))
22902 return OK_PIXELS (pixels);
22903 if (calc_pixel_width_or_height (&fact, it, cdr,
22904 font, width_p, align_to))
22905 return OK_PIXELS (pixels * fact);
22906 return 0;
22907 }
22908
22909 return 0;
22910 }
22911
22912 return 0;
22913 }
22914
22915 \f
22916 /***********************************************************************
22917 Glyph Display
22918 ***********************************************************************/
22919
22920 #ifdef HAVE_WINDOW_SYSTEM
22921
22922 #ifdef GLYPH_DEBUG
22923
22924 void
22925 dump_glyph_string (struct glyph_string *s)
22926 {
22927 fprintf (stderr, "glyph string\n");
22928 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22929 s->x, s->y, s->width, s->height);
22930 fprintf (stderr, " ybase = %d\n", s->ybase);
22931 fprintf (stderr, " hl = %d\n", s->hl);
22932 fprintf (stderr, " left overhang = %d, right = %d\n",
22933 s->left_overhang, s->right_overhang);
22934 fprintf (stderr, " nchars = %d\n", s->nchars);
22935 fprintf (stderr, " extends to end of line = %d\n",
22936 s->extends_to_end_of_line_p);
22937 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22938 fprintf (stderr, " bg width = %d\n", s->background_width);
22939 }
22940
22941 #endif /* GLYPH_DEBUG */
22942
22943 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22944 of XChar2b structures for S; it can't be allocated in
22945 init_glyph_string because it must be allocated via `alloca'. W
22946 is the window on which S is drawn. ROW and AREA are the glyph row
22947 and area within the row from which S is constructed. START is the
22948 index of the first glyph structure covered by S. HL is a
22949 face-override for drawing S. */
22950
22951 #ifdef HAVE_NTGUI
22952 #define OPTIONAL_HDC(hdc) HDC hdc,
22953 #define DECLARE_HDC(hdc) HDC hdc;
22954 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22955 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22956 #endif
22957
22958 #ifndef OPTIONAL_HDC
22959 #define OPTIONAL_HDC(hdc)
22960 #define DECLARE_HDC(hdc)
22961 #define ALLOCATE_HDC(hdc, f)
22962 #define RELEASE_HDC(hdc, f)
22963 #endif
22964
22965 static void
22966 init_glyph_string (struct glyph_string *s,
22967 OPTIONAL_HDC (hdc)
22968 XChar2b *char2b, struct window *w, struct glyph_row *row,
22969 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22970 {
22971 memset (s, 0, sizeof *s);
22972 s->w = w;
22973 s->f = XFRAME (w->frame);
22974 #ifdef HAVE_NTGUI
22975 s->hdc = hdc;
22976 #endif
22977 s->display = FRAME_X_DISPLAY (s->f);
22978 s->window = FRAME_X_WINDOW (s->f);
22979 s->char2b = char2b;
22980 s->hl = hl;
22981 s->row = row;
22982 s->area = area;
22983 s->first_glyph = row->glyphs[area] + start;
22984 s->height = row->height;
22985 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22986 s->ybase = s->y + row->ascent;
22987 }
22988
22989
22990 /* Append the list of glyph strings with head H and tail T to the list
22991 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22992
22993 static void
22994 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22995 struct glyph_string *h, struct glyph_string *t)
22996 {
22997 if (h)
22998 {
22999 if (*head)
23000 (*tail)->next = h;
23001 else
23002 *head = h;
23003 h->prev = *tail;
23004 *tail = t;
23005 }
23006 }
23007
23008
23009 /* Prepend the list of glyph strings with head H and tail T to the
23010 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
23011 result. */
23012
23013 static void
23014 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
23015 struct glyph_string *h, struct glyph_string *t)
23016 {
23017 if (h)
23018 {
23019 if (*head)
23020 (*head)->prev = t;
23021 else
23022 *tail = t;
23023 t->next = *head;
23024 *head = h;
23025 }
23026 }
23027
23028
23029 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
23030 Set *HEAD and *TAIL to the resulting list. */
23031
23032 static void
23033 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
23034 struct glyph_string *s)
23035 {
23036 s->next = s->prev = NULL;
23037 append_glyph_string_lists (head, tail, s, s);
23038 }
23039
23040
23041 /* Get face and two-byte form of character C in face FACE_ID on frame F.
23042 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
23043 make sure that X resources for the face returned are allocated.
23044 Value is a pointer to a realized face that is ready for display if
23045 DISPLAY_P is non-zero. */
23046
23047 static struct face *
23048 get_char_face_and_encoding (struct frame *f, int c, int face_id,
23049 XChar2b *char2b, int display_p)
23050 {
23051 struct face *face = FACE_FROM_ID (f, face_id);
23052 unsigned code = 0;
23053
23054 if (face->font)
23055 {
23056 code = face->font->driver->encode_char (face->font, c);
23057
23058 if (code == FONT_INVALID_CODE)
23059 code = 0;
23060 }
23061 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23062
23063 /* Make sure X resources of the face are allocated. */
23064 #ifdef HAVE_X_WINDOWS
23065 if (display_p)
23066 #endif
23067 {
23068 eassert (face != NULL);
23069 PREPARE_FACE_FOR_DISPLAY (f, face);
23070 }
23071
23072 return face;
23073 }
23074
23075
23076 /* Get face and two-byte form of character glyph GLYPH on frame F.
23077 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
23078 a pointer to a realized face that is ready for display. */
23079
23080 static struct face *
23081 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
23082 XChar2b *char2b, int *two_byte_p)
23083 {
23084 struct face *face;
23085 unsigned code = 0;
23086
23087 eassert (glyph->type == CHAR_GLYPH);
23088 face = FACE_FROM_ID (f, glyph->face_id);
23089
23090 /* Make sure X resources of the face are allocated. */
23091 eassert (face != NULL);
23092 PREPARE_FACE_FOR_DISPLAY (f, face);
23093
23094 if (two_byte_p)
23095 *two_byte_p = 0;
23096
23097 if (face->font)
23098 {
23099 if (CHAR_BYTE8_P (glyph->u.ch))
23100 code = CHAR_TO_BYTE8 (glyph->u.ch);
23101 else
23102 code = face->font->driver->encode_char (face->font, glyph->u.ch);
23103
23104 if (code == FONT_INVALID_CODE)
23105 code = 0;
23106 }
23107
23108 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23109 return face;
23110 }
23111
23112
23113 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
23114 Return 1 if FONT has a glyph for C, otherwise return 0. */
23115
23116 static int
23117 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
23118 {
23119 unsigned code;
23120
23121 if (CHAR_BYTE8_P (c))
23122 code = CHAR_TO_BYTE8 (c);
23123 else
23124 code = font->driver->encode_char (font, c);
23125
23126 if (code == FONT_INVALID_CODE)
23127 return 0;
23128 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23129 return 1;
23130 }
23131
23132
23133 /* Fill glyph string S with composition components specified by S->cmp.
23134
23135 BASE_FACE is the base face of the composition.
23136 S->cmp_from is the index of the first component for S.
23137
23138 OVERLAPS non-zero means S should draw the foreground only, and use
23139 its physical height for clipping. See also draw_glyphs.
23140
23141 Value is the index of a component not in S. */
23142
23143 static int
23144 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
23145 int overlaps)
23146 {
23147 int i;
23148 /* For all glyphs of this composition, starting at the offset
23149 S->cmp_from, until we reach the end of the definition or encounter a
23150 glyph that requires the different face, add it to S. */
23151 struct face *face;
23152
23153 eassert (s);
23154
23155 s->for_overlaps = overlaps;
23156 s->face = NULL;
23157 s->font = NULL;
23158 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
23159 {
23160 int c = COMPOSITION_GLYPH (s->cmp, i);
23161
23162 /* TAB in a composition means display glyphs with padding space
23163 on the left or right. */
23164 if (c != '\t')
23165 {
23166 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23167 -1, Qnil);
23168
23169 face = get_char_face_and_encoding (s->f, c, face_id,
23170 s->char2b + i, 1);
23171 if (face)
23172 {
23173 if (! s->face)
23174 {
23175 s->face = face;
23176 s->font = s->face->font;
23177 }
23178 else if (s->face != face)
23179 break;
23180 }
23181 }
23182 ++s->nchars;
23183 }
23184 s->cmp_to = i;
23185
23186 if (s->face == NULL)
23187 {
23188 s->face = base_face->ascii_face;
23189 s->font = s->face->font;
23190 }
23191
23192 /* All glyph strings for the same composition has the same width,
23193 i.e. the width set for the first component of the composition. */
23194 s->width = s->first_glyph->pixel_width;
23195
23196 /* If the specified font could not be loaded, use the frame's
23197 default font, but record the fact that we couldn't load it in
23198 the glyph string so that we can draw rectangles for the
23199 characters of the glyph string. */
23200 if (s->font == NULL)
23201 {
23202 s->font_not_found_p = 1;
23203 s->font = FRAME_FONT (s->f);
23204 }
23205
23206 /* Adjust base line for subscript/superscript text. */
23207 s->ybase += s->first_glyph->voffset;
23208
23209 /* This glyph string must always be drawn with 16-bit functions. */
23210 s->two_byte_p = 1;
23211
23212 return s->cmp_to;
23213 }
23214
23215 static int
23216 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
23217 int start, int end, int overlaps)
23218 {
23219 struct glyph *glyph, *last;
23220 Lisp_Object lgstring;
23221 int i;
23222
23223 s->for_overlaps = overlaps;
23224 glyph = s->row->glyphs[s->area] + start;
23225 last = s->row->glyphs[s->area] + end;
23226 s->cmp_id = glyph->u.cmp.id;
23227 s->cmp_from = glyph->slice.cmp.from;
23228 s->cmp_to = glyph->slice.cmp.to + 1;
23229 s->face = FACE_FROM_ID (s->f, face_id);
23230 lgstring = composition_gstring_from_id (s->cmp_id);
23231 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
23232 glyph++;
23233 while (glyph < last
23234 && glyph->u.cmp.automatic
23235 && glyph->u.cmp.id == s->cmp_id
23236 && s->cmp_to == glyph->slice.cmp.from)
23237 s->cmp_to = (glyph++)->slice.cmp.to + 1;
23238
23239 for (i = s->cmp_from; i < s->cmp_to; i++)
23240 {
23241 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
23242 unsigned code = LGLYPH_CODE (lglyph);
23243
23244 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
23245 }
23246 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
23247 return glyph - s->row->glyphs[s->area];
23248 }
23249
23250
23251 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23252 See the comment of fill_glyph_string for arguments.
23253 Value is the index of the first glyph not in S. */
23254
23255
23256 static int
23257 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
23258 int start, int end, int overlaps)
23259 {
23260 struct glyph *glyph, *last;
23261 int voffset;
23262
23263 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
23264 s->for_overlaps = overlaps;
23265 glyph = s->row->glyphs[s->area] + start;
23266 last = s->row->glyphs[s->area] + end;
23267 voffset = glyph->voffset;
23268 s->face = FACE_FROM_ID (s->f, face_id);
23269 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
23270 s->nchars = 1;
23271 s->width = glyph->pixel_width;
23272 glyph++;
23273 while (glyph < last
23274 && glyph->type == GLYPHLESS_GLYPH
23275 && glyph->voffset == voffset
23276 && glyph->face_id == face_id)
23277 {
23278 s->nchars++;
23279 s->width += glyph->pixel_width;
23280 glyph++;
23281 }
23282 s->ybase += voffset;
23283 return glyph - s->row->glyphs[s->area];
23284 }
23285
23286
23287 /* Fill glyph string S from a sequence of character glyphs.
23288
23289 FACE_ID is the face id of the string. START is the index of the
23290 first glyph to consider, END is the index of the last + 1.
23291 OVERLAPS non-zero means S should draw the foreground only, and use
23292 its physical height for clipping. See also draw_glyphs.
23293
23294 Value is the index of the first glyph not in S. */
23295
23296 static int
23297 fill_glyph_string (struct glyph_string *s, int face_id,
23298 int start, int end, int overlaps)
23299 {
23300 struct glyph *glyph, *last;
23301 int voffset;
23302 int glyph_not_available_p;
23303
23304 eassert (s->f == XFRAME (s->w->frame));
23305 eassert (s->nchars == 0);
23306 eassert (start >= 0 && end > start);
23307
23308 s->for_overlaps = overlaps;
23309 glyph = s->row->glyphs[s->area] + start;
23310 last = s->row->glyphs[s->area] + end;
23311 voffset = glyph->voffset;
23312 s->padding_p = glyph->padding_p;
23313 glyph_not_available_p = glyph->glyph_not_available_p;
23314
23315 while (glyph < last
23316 && glyph->type == CHAR_GLYPH
23317 && glyph->voffset == voffset
23318 /* Same face id implies same font, nowadays. */
23319 && glyph->face_id == face_id
23320 && glyph->glyph_not_available_p == glyph_not_available_p)
23321 {
23322 int two_byte_p;
23323
23324 s->face = get_glyph_face_and_encoding (s->f, glyph,
23325 s->char2b + s->nchars,
23326 &two_byte_p);
23327 s->two_byte_p = two_byte_p;
23328 ++s->nchars;
23329 eassert (s->nchars <= end - start);
23330 s->width += glyph->pixel_width;
23331 if (glyph++->padding_p != s->padding_p)
23332 break;
23333 }
23334
23335 s->font = s->face->font;
23336
23337 /* If the specified font could not be loaded, use the frame's font,
23338 but record the fact that we couldn't load it in
23339 S->font_not_found_p so that we can draw rectangles for the
23340 characters of the glyph string. */
23341 if (s->font == NULL || glyph_not_available_p)
23342 {
23343 s->font_not_found_p = 1;
23344 s->font = FRAME_FONT (s->f);
23345 }
23346
23347 /* Adjust base line for subscript/superscript text. */
23348 s->ybase += voffset;
23349
23350 eassert (s->face && s->face->gc);
23351 return glyph - s->row->glyphs[s->area];
23352 }
23353
23354
23355 /* Fill glyph string S from image glyph S->first_glyph. */
23356
23357 static void
23358 fill_image_glyph_string (struct glyph_string *s)
23359 {
23360 eassert (s->first_glyph->type == IMAGE_GLYPH);
23361 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
23362 eassert (s->img);
23363 s->slice = s->first_glyph->slice.img;
23364 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
23365 s->font = s->face->font;
23366 s->width = s->first_glyph->pixel_width;
23367
23368 /* Adjust base line for subscript/superscript text. */
23369 s->ybase += s->first_glyph->voffset;
23370 }
23371
23372
23373 /* Fill glyph string S from a sequence of stretch glyphs.
23374
23375 START is the index of the first glyph to consider,
23376 END is the index of the last + 1.
23377
23378 Value is the index of the first glyph not in S. */
23379
23380 static int
23381 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23382 {
23383 struct glyph *glyph, *last;
23384 int voffset, face_id;
23385
23386 eassert (s->first_glyph->type == STRETCH_GLYPH);
23387
23388 glyph = s->row->glyphs[s->area] + start;
23389 last = s->row->glyphs[s->area] + end;
23390 face_id = glyph->face_id;
23391 s->face = FACE_FROM_ID (s->f, face_id);
23392 s->font = s->face->font;
23393 s->width = glyph->pixel_width;
23394 s->nchars = 1;
23395 voffset = glyph->voffset;
23396
23397 for (++glyph;
23398 (glyph < last
23399 && glyph->type == STRETCH_GLYPH
23400 && glyph->voffset == voffset
23401 && glyph->face_id == face_id);
23402 ++glyph)
23403 s->width += glyph->pixel_width;
23404
23405 /* Adjust base line for subscript/superscript text. */
23406 s->ybase += voffset;
23407
23408 /* The case that face->gc == 0 is handled when drawing the glyph
23409 string by calling PREPARE_FACE_FOR_DISPLAY. */
23410 eassert (s->face);
23411 return glyph - s->row->glyphs[s->area];
23412 }
23413
23414 static struct font_metrics *
23415 get_per_char_metric (struct font *font, XChar2b *char2b)
23416 {
23417 static struct font_metrics metrics;
23418 unsigned code;
23419
23420 if (! font)
23421 return NULL;
23422 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23423 if (code == FONT_INVALID_CODE)
23424 return NULL;
23425 font->driver->text_extents (font, &code, 1, &metrics);
23426 return &metrics;
23427 }
23428
23429 /* EXPORT for RIF:
23430 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23431 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23432 assumed to be zero. */
23433
23434 void
23435 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23436 {
23437 *left = *right = 0;
23438
23439 if (glyph->type == CHAR_GLYPH)
23440 {
23441 struct face *face;
23442 XChar2b char2b;
23443 struct font_metrics *pcm;
23444
23445 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23446 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23447 {
23448 if (pcm->rbearing > pcm->width)
23449 *right = pcm->rbearing - pcm->width;
23450 if (pcm->lbearing < 0)
23451 *left = -pcm->lbearing;
23452 }
23453 }
23454 else if (glyph->type == COMPOSITE_GLYPH)
23455 {
23456 if (! glyph->u.cmp.automatic)
23457 {
23458 struct composition *cmp = composition_table[glyph->u.cmp.id];
23459
23460 if (cmp->rbearing > cmp->pixel_width)
23461 *right = cmp->rbearing - cmp->pixel_width;
23462 if (cmp->lbearing < 0)
23463 *left = - cmp->lbearing;
23464 }
23465 else
23466 {
23467 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23468 struct font_metrics metrics;
23469
23470 composition_gstring_width (gstring, glyph->slice.cmp.from,
23471 glyph->slice.cmp.to + 1, &metrics);
23472 if (metrics.rbearing > metrics.width)
23473 *right = metrics.rbearing - metrics.width;
23474 if (metrics.lbearing < 0)
23475 *left = - metrics.lbearing;
23476 }
23477 }
23478 }
23479
23480
23481 /* Return the index of the first glyph preceding glyph string S that
23482 is overwritten by S because of S's left overhang. Value is -1
23483 if no glyphs are overwritten. */
23484
23485 static int
23486 left_overwritten (struct glyph_string *s)
23487 {
23488 int k;
23489
23490 if (s->left_overhang)
23491 {
23492 int x = 0, i;
23493 struct glyph *glyphs = s->row->glyphs[s->area];
23494 int first = s->first_glyph - glyphs;
23495
23496 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23497 x -= glyphs[i].pixel_width;
23498
23499 k = i + 1;
23500 }
23501 else
23502 k = -1;
23503
23504 return k;
23505 }
23506
23507
23508 /* Return the index of the first glyph preceding glyph string S that
23509 is overwriting S because of its right overhang. Value is -1 if no
23510 glyph in front of S overwrites S. */
23511
23512 static int
23513 left_overwriting (struct glyph_string *s)
23514 {
23515 int i, k, x;
23516 struct glyph *glyphs = s->row->glyphs[s->area];
23517 int first = s->first_glyph - glyphs;
23518
23519 k = -1;
23520 x = 0;
23521 for (i = first - 1; i >= 0; --i)
23522 {
23523 int left, right;
23524 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23525 if (x + right > 0)
23526 k = i;
23527 x -= glyphs[i].pixel_width;
23528 }
23529
23530 return k;
23531 }
23532
23533
23534 /* Return the index of the last glyph following glyph string S that is
23535 overwritten by S because of S's right overhang. Value is -1 if
23536 no such glyph is found. */
23537
23538 static int
23539 right_overwritten (struct glyph_string *s)
23540 {
23541 int k = -1;
23542
23543 if (s->right_overhang)
23544 {
23545 int x = 0, i;
23546 struct glyph *glyphs = s->row->glyphs[s->area];
23547 int first = (s->first_glyph - glyphs
23548 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23549 int end = s->row->used[s->area];
23550
23551 for (i = first; i < end && s->right_overhang > x; ++i)
23552 x += glyphs[i].pixel_width;
23553
23554 k = i;
23555 }
23556
23557 return k;
23558 }
23559
23560
23561 /* Return the index of the last glyph following glyph string S that
23562 overwrites S because of its left overhang. Value is negative
23563 if no such glyph is found. */
23564
23565 static int
23566 right_overwriting (struct glyph_string *s)
23567 {
23568 int i, k, x;
23569 int end = s->row->used[s->area];
23570 struct glyph *glyphs = s->row->glyphs[s->area];
23571 int first = (s->first_glyph - glyphs
23572 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23573
23574 k = -1;
23575 x = 0;
23576 for (i = first; i < end; ++i)
23577 {
23578 int left, right;
23579 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23580 if (x - left < 0)
23581 k = i;
23582 x += glyphs[i].pixel_width;
23583 }
23584
23585 return k;
23586 }
23587
23588
23589 /* Set background width of glyph string S. START is the index of the
23590 first glyph following S. LAST_X is the right-most x-position + 1
23591 in the drawing area. */
23592
23593 static void
23594 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23595 {
23596 /* If the face of this glyph string has to be drawn to the end of
23597 the drawing area, set S->extends_to_end_of_line_p. */
23598
23599 if (start == s->row->used[s->area]
23600 && s->area == TEXT_AREA
23601 && ((s->row->fill_line_p
23602 && (s->hl == DRAW_NORMAL_TEXT
23603 || s->hl == DRAW_IMAGE_RAISED
23604 || s->hl == DRAW_IMAGE_SUNKEN))
23605 || s->hl == DRAW_MOUSE_FACE))
23606 s->extends_to_end_of_line_p = 1;
23607
23608 /* If S extends its face to the end of the line, set its
23609 background_width to the distance to the right edge of the drawing
23610 area. */
23611 if (s->extends_to_end_of_line_p)
23612 s->background_width = last_x - s->x + 1;
23613 else
23614 s->background_width = s->width;
23615 }
23616
23617
23618 /* Compute overhangs and x-positions for glyph string S and its
23619 predecessors, or successors. X is the starting x-position for S.
23620 BACKWARD_P non-zero means process predecessors. */
23621
23622 static void
23623 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23624 {
23625 if (backward_p)
23626 {
23627 while (s)
23628 {
23629 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23630 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23631 x -= s->width;
23632 s->x = x;
23633 s = s->prev;
23634 }
23635 }
23636 else
23637 {
23638 while (s)
23639 {
23640 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23641 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23642 s->x = x;
23643 x += s->width;
23644 s = s->next;
23645 }
23646 }
23647 }
23648
23649
23650
23651 /* The following macros are only called from draw_glyphs below.
23652 They reference the following parameters of that function directly:
23653 `w', `row', `area', and `overlap_p'
23654 as well as the following local variables:
23655 `s', `f', and `hdc' (in W32) */
23656
23657 #ifdef HAVE_NTGUI
23658 /* On W32, silently add local `hdc' variable to argument list of
23659 init_glyph_string. */
23660 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23661 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23662 #else
23663 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23664 init_glyph_string (s, char2b, w, row, area, start, hl)
23665 #endif
23666
23667 /* Add a glyph string for a stretch glyph to the list of strings
23668 between HEAD and TAIL. START is the index of the stretch glyph in
23669 row area AREA of glyph row ROW. END is the index of the last glyph
23670 in that glyph row area. X is the current output position assigned
23671 to the new glyph string constructed. HL overrides that face of the
23672 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23673 is the right-most x-position of the drawing area. */
23674
23675 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23676 and below -- keep them on one line. */
23677 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23678 do \
23679 { \
23680 s = alloca (sizeof *s); \
23681 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23682 START = fill_stretch_glyph_string (s, START, END); \
23683 append_glyph_string (&HEAD, &TAIL, s); \
23684 s->x = (X); \
23685 } \
23686 while (0)
23687
23688
23689 /* Add a glyph string for an image glyph to the list of strings
23690 between HEAD and TAIL. START is the index of the image glyph in
23691 row area AREA of glyph row ROW. END is the index of the last glyph
23692 in that glyph row area. X is the current output position assigned
23693 to the new glyph string constructed. HL overrides that face of the
23694 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23695 is the right-most x-position of the drawing area. */
23696
23697 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23698 do \
23699 { \
23700 s = alloca (sizeof *s); \
23701 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23702 fill_image_glyph_string (s); \
23703 append_glyph_string (&HEAD, &TAIL, s); \
23704 ++START; \
23705 s->x = (X); \
23706 } \
23707 while (0)
23708
23709
23710 /* Add a glyph string for a sequence of character glyphs to the list
23711 of strings between HEAD and TAIL. START is the index of the first
23712 glyph in row area AREA of glyph row ROW that is part of the new
23713 glyph string. END is the index of the last glyph in that glyph row
23714 area. X is the current output position assigned to the new glyph
23715 string constructed. HL overrides that face of the glyph; e.g. it
23716 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23717 right-most x-position of the drawing area. */
23718
23719 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23720 do \
23721 { \
23722 int face_id; \
23723 XChar2b *char2b; \
23724 \
23725 face_id = (row)->glyphs[area][START].face_id; \
23726 \
23727 s = alloca (sizeof *s); \
23728 char2b = alloca ((END - START) * sizeof *char2b); \
23729 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23730 append_glyph_string (&HEAD, &TAIL, s); \
23731 s->x = (X); \
23732 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23733 } \
23734 while (0)
23735
23736
23737 /* Add a glyph string for a composite sequence to the list of strings
23738 between HEAD and TAIL. START is the index of the first glyph in
23739 row area AREA of glyph row ROW that is part of the new glyph
23740 string. END is the index of the last glyph in that glyph row area.
23741 X is the current output position assigned to the new glyph string
23742 constructed. HL overrides that face of the glyph; e.g. it is
23743 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23744 x-position of the drawing area. */
23745
23746 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23747 do { \
23748 int face_id = (row)->glyphs[area][START].face_id; \
23749 struct face *base_face = FACE_FROM_ID (f, face_id); \
23750 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23751 struct composition *cmp = composition_table[cmp_id]; \
23752 XChar2b *char2b; \
23753 struct glyph_string *first_s = NULL; \
23754 int n; \
23755 \
23756 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23757 \
23758 /* Make glyph_strings for each glyph sequence that is drawable by \
23759 the same face, and append them to HEAD/TAIL. */ \
23760 for (n = 0; n < cmp->glyph_len;) \
23761 { \
23762 s = alloca (sizeof *s); \
23763 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23764 append_glyph_string (&(HEAD), &(TAIL), s); \
23765 s->cmp = cmp; \
23766 s->cmp_from = n; \
23767 s->x = (X); \
23768 if (n == 0) \
23769 first_s = s; \
23770 n = fill_composite_glyph_string (s, base_face, overlaps); \
23771 } \
23772 \
23773 ++START; \
23774 s = first_s; \
23775 } while (0)
23776
23777
23778 /* Add a glyph string for a glyph-string sequence to the list of strings
23779 between HEAD and TAIL. */
23780
23781 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23782 do { \
23783 int face_id; \
23784 XChar2b *char2b; \
23785 Lisp_Object gstring; \
23786 \
23787 face_id = (row)->glyphs[area][START].face_id; \
23788 gstring = (composition_gstring_from_id \
23789 ((row)->glyphs[area][START].u.cmp.id)); \
23790 s = alloca (sizeof *s); \
23791 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23792 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23793 append_glyph_string (&(HEAD), &(TAIL), s); \
23794 s->x = (X); \
23795 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23796 } while (0)
23797
23798
23799 /* Add a glyph string for a sequence of glyphless character's glyphs
23800 to the list of strings between HEAD and TAIL. The meanings of
23801 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23802
23803 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23804 do \
23805 { \
23806 int face_id; \
23807 \
23808 face_id = (row)->glyphs[area][START].face_id; \
23809 \
23810 s = alloca (sizeof *s); \
23811 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23812 append_glyph_string (&HEAD, &TAIL, s); \
23813 s->x = (X); \
23814 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23815 overlaps); \
23816 } \
23817 while (0)
23818
23819
23820 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23821 of AREA of glyph row ROW on window W between indices START and END.
23822 HL overrides the face for drawing glyph strings, e.g. it is
23823 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23824 x-positions of the drawing area.
23825
23826 This is an ugly monster macro construct because we must use alloca
23827 to allocate glyph strings (because draw_glyphs can be called
23828 asynchronously). */
23829
23830 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23831 do \
23832 { \
23833 HEAD = TAIL = NULL; \
23834 while (START < END) \
23835 { \
23836 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23837 switch (first_glyph->type) \
23838 { \
23839 case CHAR_GLYPH: \
23840 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23841 HL, X, LAST_X); \
23842 break; \
23843 \
23844 case COMPOSITE_GLYPH: \
23845 if (first_glyph->u.cmp.automatic) \
23846 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23847 HL, X, LAST_X); \
23848 else \
23849 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23850 HL, X, LAST_X); \
23851 break; \
23852 \
23853 case STRETCH_GLYPH: \
23854 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23855 HL, X, LAST_X); \
23856 break; \
23857 \
23858 case IMAGE_GLYPH: \
23859 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23860 HL, X, LAST_X); \
23861 break; \
23862 \
23863 case GLYPHLESS_GLYPH: \
23864 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23865 HL, X, LAST_X); \
23866 break; \
23867 \
23868 default: \
23869 emacs_abort (); \
23870 } \
23871 \
23872 if (s) \
23873 { \
23874 set_glyph_string_background_width (s, START, LAST_X); \
23875 (X) += s->width; \
23876 } \
23877 } \
23878 } while (0)
23879
23880
23881 /* Draw glyphs between START and END in AREA of ROW on window W,
23882 starting at x-position X. X is relative to AREA in W. HL is a
23883 face-override with the following meaning:
23884
23885 DRAW_NORMAL_TEXT draw normally
23886 DRAW_CURSOR draw in cursor face
23887 DRAW_MOUSE_FACE draw in mouse face.
23888 DRAW_INVERSE_VIDEO draw in mode line face
23889 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23890 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23891
23892 If OVERLAPS is non-zero, draw only the foreground of characters and
23893 clip to the physical height of ROW. Non-zero value also defines
23894 the overlapping part to be drawn:
23895
23896 OVERLAPS_PRED overlap with preceding rows
23897 OVERLAPS_SUCC overlap with succeeding rows
23898 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23899 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23900
23901 Value is the x-position reached, relative to AREA of W. */
23902
23903 static int
23904 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23905 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23906 enum draw_glyphs_face hl, int overlaps)
23907 {
23908 struct glyph_string *head, *tail;
23909 struct glyph_string *s;
23910 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23911 int i, j, x_reached, last_x, area_left = 0;
23912 struct frame *f = XFRAME (WINDOW_FRAME (w));
23913 DECLARE_HDC (hdc);
23914
23915 ALLOCATE_HDC (hdc, f);
23916
23917 /* Let's rather be paranoid than getting a SEGV. */
23918 end = min (end, row->used[area]);
23919 start = clip_to_bounds (0, start, end);
23920
23921 /* Translate X to frame coordinates. Set last_x to the right
23922 end of the drawing area. */
23923 if (row->full_width_p)
23924 {
23925 /* X is relative to the left edge of W, without scroll bars
23926 or fringes. */
23927 area_left = WINDOW_LEFT_EDGE_X (w);
23928 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23929 }
23930 else
23931 {
23932 area_left = window_box_left (w, area);
23933 last_x = area_left + window_box_width (w, area);
23934 }
23935 x += area_left;
23936
23937 /* Build a doubly-linked list of glyph_string structures between
23938 head and tail from what we have to draw. Note that the macro
23939 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23940 the reason we use a separate variable `i'. */
23941 i = start;
23942 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23943 if (tail)
23944 x_reached = tail->x + tail->background_width;
23945 else
23946 x_reached = x;
23947
23948 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23949 the row, redraw some glyphs in front or following the glyph
23950 strings built above. */
23951 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23952 {
23953 struct glyph_string *h, *t;
23954 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23955 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23956 int check_mouse_face = 0;
23957 int dummy_x = 0;
23958
23959 /* If mouse highlighting is on, we may need to draw adjacent
23960 glyphs using mouse-face highlighting. */
23961 if (area == TEXT_AREA && row->mouse_face_p
23962 && hlinfo->mouse_face_beg_row >= 0
23963 && hlinfo->mouse_face_end_row >= 0)
23964 {
23965 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
23966
23967 if (row_vpos >= hlinfo->mouse_face_beg_row
23968 && row_vpos <= hlinfo->mouse_face_end_row)
23969 {
23970 check_mouse_face = 1;
23971 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
23972 ? hlinfo->mouse_face_beg_col : 0;
23973 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
23974 ? hlinfo->mouse_face_end_col
23975 : row->used[TEXT_AREA];
23976 }
23977 }
23978
23979 /* Compute overhangs for all glyph strings. */
23980 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23981 for (s = head; s; s = s->next)
23982 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23983
23984 /* Prepend glyph strings for glyphs in front of the first glyph
23985 string that are overwritten because of the first glyph
23986 string's left overhang. The background of all strings
23987 prepended must be drawn because the first glyph string
23988 draws over it. */
23989 i = left_overwritten (head);
23990 if (i >= 0)
23991 {
23992 enum draw_glyphs_face overlap_hl;
23993
23994 /* If this row contains mouse highlighting, attempt to draw
23995 the overlapped glyphs with the correct highlight. This
23996 code fails if the overlap encompasses more than one glyph
23997 and mouse-highlight spans only some of these glyphs.
23998 However, making it work perfectly involves a lot more
23999 code, and I don't know if the pathological case occurs in
24000 practice, so we'll stick to this for now. --- cyd */
24001 if (check_mouse_face
24002 && mouse_beg_col < start && mouse_end_col > i)
24003 overlap_hl = DRAW_MOUSE_FACE;
24004 else
24005 overlap_hl = DRAW_NORMAL_TEXT;
24006
24007 j = i;
24008 BUILD_GLYPH_STRINGS (j, start, h, t,
24009 overlap_hl, dummy_x, last_x);
24010 start = i;
24011 compute_overhangs_and_x (t, head->x, 1);
24012 prepend_glyph_string_lists (&head, &tail, h, t);
24013 clip_head = head;
24014 }
24015
24016 /* Prepend glyph strings for glyphs in front of the first glyph
24017 string that overwrite that glyph string because of their
24018 right overhang. For these strings, only the foreground must
24019 be drawn, because it draws over the glyph string at `head'.
24020 The background must not be drawn because this would overwrite
24021 right overhangs of preceding glyphs for which no glyph
24022 strings exist. */
24023 i = left_overwriting (head);
24024 if (i >= 0)
24025 {
24026 enum draw_glyphs_face overlap_hl;
24027
24028 if (check_mouse_face
24029 && mouse_beg_col < start && mouse_end_col > i)
24030 overlap_hl = DRAW_MOUSE_FACE;
24031 else
24032 overlap_hl = DRAW_NORMAL_TEXT;
24033
24034 clip_head = head;
24035 BUILD_GLYPH_STRINGS (i, start, h, t,
24036 overlap_hl, dummy_x, last_x);
24037 for (s = h; s; s = s->next)
24038 s->background_filled_p = 1;
24039 compute_overhangs_and_x (t, head->x, 1);
24040 prepend_glyph_string_lists (&head, &tail, h, t);
24041 }
24042
24043 /* Append glyphs strings for glyphs following the last glyph
24044 string tail that are overwritten by tail. The background of
24045 these strings has to be drawn because tail's foreground draws
24046 over it. */
24047 i = right_overwritten (tail);
24048 if (i >= 0)
24049 {
24050 enum draw_glyphs_face overlap_hl;
24051
24052 if (check_mouse_face
24053 && mouse_beg_col < i && mouse_end_col > end)
24054 overlap_hl = DRAW_MOUSE_FACE;
24055 else
24056 overlap_hl = DRAW_NORMAL_TEXT;
24057
24058 BUILD_GLYPH_STRINGS (end, i, h, t,
24059 overlap_hl, x, last_x);
24060 /* Because BUILD_GLYPH_STRINGS updates the first argument,
24061 we don't have `end = i;' here. */
24062 compute_overhangs_and_x (h, tail->x + tail->width, 0);
24063 append_glyph_string_lists (&head, &tail, h, t);
24064 clip_tail = tail;
24065 }
24066
24067 /* Append glyph strings for glyphs following the last glyph
24068 string tail that overwrite tail. The foreground of such
24069 glyphs has to be drawn because it writes into the background
24070 of tail. The background must not be drawn because it could
24071 paint over the foreground of following glyphs. */
24072 i = right_overwriting (tail);
24073 if (i >= 0)
24074 {
24075 enum draw_glyphs_face overlap_hl;
24076 if (check_mouse_face
24077 && mouse_beg_col < i && mouse_end_col > end)
24078 overlap_hl = DRAW_MOUSE_FACE;
24079 else
24080 overlap_hl = DRAW_NORMAL_TEXT;
24081
24082 clip_tail = tail;
24083 i++; /* We must include the Ith glyph. */
24084 BUILD_GLYPH_STRINGS (end, i, h, t,
24085 overlap_hl, x, last_x);
24086 for (s = h; s; s = s->next)
24087 s->background_filled_p = 1;
24088 compute_overhangs_and_x (h, tail->x + tail->width, 0);
24089 append_glyph_string_lists (&head, &tail, h, t);
24090 }
24091 if (clip_head || clip_tail)
24092 for (s = head; s; s = s->next)
24093 {
24094 s->clip_head = clip_head;
24095 s->clip_tail = clip_tail;
24096 }
24097 }
24098
24099 /* Draw all strings. */
24100 for (s = head; s; s = s->next)
24101 FRAME_RIF (f)->draw_glyph_string (s);
24102
24103 #ifndef HAVE_NS
24104 /* When focus a sole frame and move horizontally, this sets on_p to 0
24105 causing a failure to erase prev cursor position. */
24106 if (area == TEXT_AREA
24107 && !row->full_width_p
24108 /* When drawing overlapping rows, only the glyph strings'
24109 foreground is drawn, which doesn't erase a cursor
24110 completely. */
24111 && !overlaps)
24112 {
24113 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
24114 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
24115 : (tail ? tail->x + tail->background_width : x));
24116 x0 -= area_left;
24117 x1 -= area_left;
24118
24119 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
24120 row->y, MATRIX_ROW_BOTTOM_Y (row));
24121 }
24122 #endif
24123
24124 /* Value is the x-position up to which drawn, relative to AREA of W.
24125 This doesn't include parts drawn because of overhangs. */
24126 if (row->full_width_p)
24127 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
24128 else
24129 x_reached -= area_left;
24130
24131 RELEASE_HDC (hdc, f);
24132
24133 return x_reached;
24134 }
24135
24136 /* Expand row matrix if too narrow. Don't expand if area
24137 is not present. */
24138
24139 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
24140 { \
24141 if (!it->f->fonts_changed \
24142 && (it->glyph_row->glyphs[area] \
24143 < it->glyph_row->glyphs[area + 1])) \
24144 { \
24145 it->w->ncols_scale_factor++; \
24146 it->f->fonts_changed = 1; \
24147 } \
24148 }
24149
24150 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24151 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24152
24153 static void
24154 append_glyph (struct it *it)
24155 {
24156 struct glyph *glyph;
24157 enum glyph_row_area area = it->area;
24158
24159 eassert (it->glyph_row);
24160 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
24161
24162 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24163 if (glyph < it->glyph_row->glyphs[area + 1])
24164 {
24165 /* If the glyph row is reversed, we need to prepend the glyph
24166 rather than append it. */
24167 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24168 {
24169 struct glyph *g;
24170
24171 /* Make room for the additional glyph. */
24172 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24173 g[1] = *g;
24174 glyph = it->glyph_row->glyphs[area];
24175 }
24176 glyph->charpos = CHARPOS (it->position);
24177 glyph->object = it->object;
24178 if (it->pixel_width > 0)
24179 {
24180 glyph->pixel_width = it->pixel_width;
24181 glyph->padding_p = 0;
24182 }
24183 else
24184 {
24185 /* Assure at least 1-pixel width. Otherwise, cursor can't
24186 be displayed correctly. */
24187 glyph->pixel_width = 1;
24188 glyph->padding_p = 1;
24189 }
24190 glyph->ascent = it->ascent;
24191 glyph->descent = it->descent;
24192 glyph->voffset = it->voffset;
24193 glyph->type = CHAR_GLYPH;
24194 glyph->avoid_cursor_p = it->avoid_cursor_p;
24195 glyph->multibyte_p = it->multibyte_p;
24196 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24197 {
24198 /* In R2L rows, the left and the right box edges need to be
24199 drawn in reverse direction. */
24200 glyph->right_box_line_p = it->start_of_box_run_p;
24201 glyph->left_box_line_p = it->end_of_box_run_p;
24202 }
24203 else
24204 {
24205 glyph->left_box_line_p = it->start_of_box_run_p;
24206 glyph->right_box_line_p = it->end_of_box_run_p;
24207 }
24208 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24209 || it->phys_descent > it->descent);
24210 glyph->glyph_not_available_p = it->glyph_not_available_p;
24211 glyph->face_id = it->face_id;
24212 glyph->u.ch = it->char_to_display;
24213 glyph->slice.img = null_glyph_slice;
24214 glyph->font_type = FONT_TYPE_UNKNOWN;
24215 if (it->bidi_p)
24216 {
24217 glyph->resolved_level = it->bidi_it.resolved_level;
24218 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24219 emacs_abort ();
24220 glyph->bidi_type = it->bidi_it.type;
24221 }
24222 else
24223 {
24224 glyph->resolved_level = 0;
24225 glyph->bidi_type = UNKNOWN_BT;
24226 }
24227 ++it->glyph_row->used[area];
24228 }
24229 else
24230 IT_EXPAND_MATRIX_WIDTH (it, area);
24231 }
24232
24233 /* Store one glyph for the composition IT->cmp_it.id in
24234 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24235 non-null. */
24236
24237 static void
24238 append_composite_glyph (struct it *it)
24239 {
24240 struct glyph *glyph;
24241 enum glyph_row_area area = it->area;
24242
24243 eassert (it->glyph_row);
24244
24245 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24246 if (glyph < it->glyph_row->glyphs[area + 1])
24247 {
24248 /* If the glyph row is reversed, we need to prepend the glyph
24249 rather than append it. */
24250 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
24251 {
24252 struct glyph *g;
24253
24254 /* Make room for the new glyph. */
24255 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
24256 g[1] = *g;
24257 glyph = it->glyph_row->glyphs[it->area];
24258 }
24259 glyph->charpos = it->cmp_it.charpos;
24260 glyph->object = it->object;
24261 glyph->pixel_width = it->pixel_width;
24262 glyph->ascent = it->ascent;
24263 glyph->descent = it->descent;
24264 glyph->voffset = it->voffset;
24265 glyph->type = COMPOSITE_GLYPH;
24266 if (it->cmp_it.ch < 0)
24267 {
24268 glyph->u.cmp.automatic = 0;
24269 glyph->u.cmp.id = it->cmp_it.id;
24270 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
24271 }
24272 else
24273 {
24274 glyph->u.cmp.automatic = 1;
24275 glyph->u.cmp.id = it->cmp_it.id;
24276 glyph->slice.cmp.from = it->cmp_it.from;
24277 glyph->slice.cmp.to = it->cmp_it.to - 1;
24278 }
24279 glyph->avoid_cursor_p = it->avoid_cursor_p;
24280 glyph->multibyte_p = it->multibyte_p;
24281 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24282 {
24283 /* In R2L rows, the left and the right box edges need to be
24284 drawn in reverse direction. */
24285 glyph->right_box_line_p = it->start_of_box_run_p;
24286 glyph->left_box_line_p = it->end_of_box_run_p;
24287 }
24288 else
24289 {
24290 glyph->left_box_line_p = it->start_of_box_run_p;
24291 glyph->right_box_line_p = it->end_of_box_run_p;
24292 }
24293 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24294 || it->phys_descent > it->descent);
24295 glyph->padding_p = 0;
24296 glyph->glyph_not_available_p = 0;
24297 glyph->face_id = it->face_id;
24298 glyph->font_type = FONT_TYPE_UNKNOWN;
24299 if (it->bidi_p)
24300 {
24301 glyph->resolved_level = it->bidi_it.resolved_level;
24302 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24303 emacs_abort ();
24304 glyph->bidi_type = it->bidi_it.type;
24305 }
24306 ++it->glyph_row->used[area];
24307 }
24308 else
24309 IT_EXPAND_MATRIX_WIDTH (it, area);
24310 }
24311
24312
24313 /* Change IT->ascent and IT->height according to the setting of
24314 IT->voffset. */
24315
24316 static void
24317 take_vertical_position_into_account (struct it *it)
24318 {
24319 if (it->voffset)
24320 {
24321 if (it->voffset < 0)
24322 /* Increase the ascent so that we can display the text higher
24323 in the line. */
24324 it->ascent -= it->voffset;
24325 else
24326 /* Increase the descent so that we can display the text lower
24327 in the line. */
24328 it->descent += it->voffset;
24329 }
24330 }
24331
24332
24333 /* Produce glyphs/get display metrics for the image IT is loaded with.
24334 See the description of struct display_iterator in dispextern.h for
24335 an overview of struct display_iterator. */
24336
24337 static void
24338 produce_image_glyph (struct it *it)
24339 {
24340 struct image *img;
24341 struct face *face;
24342 int glyph_ascent, crop;
24343 struct glyph_slice slice;
24344
24345 eassert (it->what == IT_IMAGE);
24346
24347 face = FACE_FROM_ID (it->f, it->face_id);
24348 eassert (face);
24349 /* Make sure X resources of the face is loaded. */
24350 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24351
24352 if (it->image_id < 0)
24353 {
24354 /* Fringe bitmap. */
24355 it->ascent = it->phys_ascent = 0;
24356 it->descent = it->phys_descent = 0;
24357 it->pixel_width = 0;
24358 it->nglyphs = 0;
24359 return;
24360 }
24361
24362 img = IMAGE_FROM_ID (it->f, it->image_id);
24363 eassert (img);
24364 /* Make sure X resources of the image is loaded. */
24365 prepare_image_for_display (it->f, img);
24366
24367 slice.x = slice.y = 0;
24368 slice.width = img->width;
24369 slice.height = img->height;
24370
24371 if (INTEGERP (it->slice.x))
24372 slice.x = XINT (it->slice.x);
24373 else if (FLOATP (it->slice.x))
24374 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24375
24376 if (INTEGERP (it->slice.y))
24377 slice.y = XINT (it->slice.y);
24378 else if (FLOATP (it->slice.y))
24379 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24380
24381 if (INTEGERP (it->slice.width))
24382 slice.width = XINT (it->slice.width);
24383 else if (FLOATP (it->slice.width))
24384 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24385
24386 if (INTEGERP (it->slice.height))
24387 slice.height = XINT (it->slice.height);
24388 else if (FLOATP (it->slice.height))
24389 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24390
24391 if (slice.x >= img->width)
24392 slice.x = img->width;
24393 if (slice.y >= img->height)
24394 slice.y = img->height;
24395 if (slice.x + slice.width >= img->width)
24396 slice.width = img->width - slice.x;
24397 if (slice.y + slice.height > img->height)
24398 slice.height = img->height - slice.y;
24399
24400 if (slice.width == 0 || slice.height == 0)
24401 return;
24402
24403 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24404
24405 it->descent = slice.height - glyph_ascent;
24406 if (slice.y == 0)
24407 it->descent += img->vmargin;
24408 if (slice.y + slice.height == img->height)
24409 it->descent += img->vmargin;
24410 it->phys_descent = it->descent;
24411
24412 it->pixel_width = slice.width;
24413 if (slice.x == 0)
24414 it->pixel_width += img->hmargin;
24415 if (slice.x + slice.width == img->width)
24416 it->pixel_width += img->hmargin;
24417
24418 /* It's quite possible for images to have an ascent greater than
24419 their height, so don't get confused in that case. */
24420 if (it->descent < 0)
24421 it->descent = 0;
24422
24423 it->nglyphs = 1;
24424
24425 if (face->box != FACE_NO_BOX)
24426 {
24427 if (face->box_line_width > 0)
24428 {
24429 if (slice.y == 0)
24430 it->ascent += face->box_line_width;
24431 if (slice.y + slice.height == img->height)
24432 it->descent += face->box_line_width;
24433 }
24434
24435 if (it->start_of_box_run_p && slice.x == 0)
24436 it->pixel_width += eabs (face->box_line_width);
24437 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24438 it->pixel_width += eabs (face->box_line_width);
24439 }
24440
24441 take_vertical_position_into_account (it);
24442
24443 /* Automatically crop wide image glyphs at right edge so we can
24444 draw the cursor on same display row. */
24445 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24446 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24447 {
24448 it->pixel_width -= crop;
24449 slice.width -= crop;
24450 }
24451
24452 if (it->glyph_row)
24453 {
24454 struct glyph *glyph;
24455 enum glyph_row_area area = it->area;
24456
24457 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24458 if (glyph < it->glyph_row->glyphs[area + 1])
24459 {
24460 glyph->charpos = CHARPOS (it->position);
24461 glyph->object = it->object;
24462 glyph->pixel_width = it->pixel_width;
24463 glyph->ascent = glyph_ascent;
24464 glyph->descent = it->descent;
24465 glyph->voffset = it->voffset;
24466 glyph->type = IMAGE_GLYPH;
24467 glyph->avoid_cursor_p = it->avoid_cursor_p;
24468 glyph->multibyte_p = it->multibyte_p;
24469 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24470 {
24471 /* In R2L rows, the left and the right box edges need to be
24472 drawn in reverse direction. */
24473 glyph->right_box_line_p = it->start_of_box_run_p;
24474 glyph->left_box_line_p = it->end_of_box_run_p;
24475 }
24476 else
24477 {
24478 glyph->left_box_line_p = it->start_of_box_run_p;
24479 glyph->right_box_line_p = it->end_of_box_run_p;
24480 }
24481 glyph->overlaps_vertically_p = 0;
24482 glyph->padding_p = 0;
24483 glyph->glyph_not_available_p = 0;
24484 glyph->face_id = it->face_id;
24485 glyph->u.img_id = img->id;
24486 glyph->slice.img = slice;
24487 glyph->font_type = FONT_TYPE_UNKNOWN;
24488 if (it->bidi_p)
24489 {
24490 glyph->resolved_level = it->bidi_it.resolved_level;
24491 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24492 emacs_abort ();
24493 glyph->bidi_type = it->bidi_it.type;
24494 }
24495 ++it->glyph_row->used[area];
24496 }
24497 else
24498 IT_EXPAND_MATRIX_WIDTH (it, area);
24499 }
24500 }
24501
24502
24503 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24504 of the glyph, WIDTH and HEIGHT are the width and height of the
24505 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24506
24507 static void
24508 append_stretch_glyph (struct it *it, Lisp_Object object,
24509 int width, int height, int ascent)
24510 {
24511 struct glyph *glyph;
24512 enum glyph_row_area area = it->area;
24513
24514 eassert (ascent >= 0 && ascent <= height);
24515
24516 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24517 if (glyph < it->glyph_row->glyphs[area + 1])
24518 {
24519 /* If the glyph row is reversed, we need to prepend the glyph
24520 rather than append it. */
24521 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24522 {
24523 struct glyph *g;
24524
24525 /* Make room for the additional glyph. */
24526 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24527 g[1] = *g;
24528 glyph = it->glyph_row->glyphs[area];
24529 }
24530 glyph->charpos = CHARPOS (it->position);
24531 glyph->object = object;
24532 glyph->pixel_width = width;
24533 glyph->ascent = ascent;
24534 glyph->descent = height - ascent;
24535 glyph->voffset = it->voffset;
24536 glyph->type = STRETCH_GLYPH;
24537 glyph->avoid_cursor_p = it->avoid_cursor_p;
24538 glyph->multibyte_p = it->multibyte_p;
24539 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24540 {
24541 /* In R2L rows, the left and the right box edges need to be
24542 drawn in reverse direction. */
24543 glyph->right_box_line_p = it->start_of_box_run_p;
24544 glyph->left_box_line_p = it->end_of_box_run_p;
24545 }
24546 else
24547 {
24548 glyph->left_box_line_p = it->start_of_box_run_p;
24549 glyph->right_box_line_p = it->end_of_box_run_p;
24550 }
24551 glyph->overlaps_vertically_p = 0;
24552 glyph->padding_p = 0;
24553 glyph->glyph_not_available_p = 0;
24554 glyph->face_id = it->face_id;
24555 glyph->u.stretch.ascent = ascent;
24556 glyph->u.stretch.height = height;
24557 glyph->slice.img = null_glyph_slice;
24558 glyph->font_type = FONT_TYPE_UNKNOWN;
24559 if (it->bidi_p)
24560 {
24561 glyph->resolved_level = it->bidi_it.resolved_level;
24562 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24563 emacs_abort ();
24564 glyph->bidi_type = it->bidi_it.type;
24565 }
24566 else
24567 {
24568 glyph->resolved_level = 0;
24569 glyph->bidi_type = UNKNOWN_BT;
24570 }
24571 ++it->glyph_row->used[area];
24572 }
24573 else
24574 IT_EXPAND_MATRIX_WIDTH (it, area);
24575 }
24576
24577 #endif /* HAVE_WINDOW_SYSTEM */
24578
24579 /* Produce a stretch glyph for iterator IT. IT->object is the value
24580 of the glyph property displayed. The value must be a list
24581 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24582 being recognized:
24583
24584 1. `:width WIDTH' specifies that the space should be WIDTH *
24585 canonical char width wide. WIDTH may be an integer or floating
24586 point number.
24587
24588 2. `:relative-width FACTOR' specifies that the width of the stretch
24589 should be computed from the width of the first character having the
24590 `glyph' property, and should be FACTOR times that width.
24591
24592 3. `:align-to HPOS' specifies that the space should be wide enough
24593 to reach HPOS, a value in canonical character units.
24594
24595 Exactly one of the above pairs must be present.
24596
24597 4. `:height HEIGHT' specifies that the height of the stretch produced
24598 should be HEIGHT, measured in canonical character units.
24599
24600 5. `:relative-height FACTOR' specifies that the height of the
24601 stretch should be FACTOR times the height of the characters having
24602 the glyph property.
24603
24604 Either none or exactly one of 4 or 5 must be present.
24605
24606 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24607 of the stretch should be used for the ascent of the stretch.
24608 ASCENT must be in the range 0 <= ASCENT <= 100. */
24609
24610 void
24611 produce_stretch_glyph (struct it *it)
24612 {
24613 /* (space :width WIDTH :height HEIGHT ...) */
24614 Lisp_Object prop, plist;
24615 int width = 0, height = 0, align_to = -1;
24616 int zero_width_ok_p = 0;
24617 double tem;
24618 struct font *font = NULL;
24619
24620 #ifdef HAVE_WINDOW_SYSTEM
24621 int ascent = 0;
24622 int zero_height_ok_p = 0;
24623
24624 if (FRAME_WINDOW_P (it->f))
24625 {
24626 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24627 font = face->font ? face->font : FRAME_FONT (it->f);
24628 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24629 }
24630 #endif
24631
24632 /* List should start with `space'. */
24633 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24634 plist = XCDR (it->object);
24635
24636 /* Compute the width of the stretch. */
24637 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24638 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24639 {
24640 /* Absolute width `:width WIDTH' specified and valid. */
24641 zero_width_ok_p = 1;
24642 width = (int)tem;
24643 }
24644 #ifdef HAVE_WINDOW_SYSTEM
24645 else if (FRAME_WINDOW_P (it->f)
24646 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24647 {
24648 /* Relative width `:relative-width FACTOR' specified and valid.
24649 Compute the width of the characters having the `glyph'
24650 property. */
24651 struct it it2;
24652 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24653
24654 it2 = *it;
24655 if (it->multibyte_p)
24656 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24657 else
24658 {
24659 it2.c = it2.char_to_display = *p, it2.len = 1;
24660 if (! ASCII_CHAR_P (it2.c))
24661 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24662 }
24663
24664 it2.glyph_row = NULL;
24665 it2.what = IT_CHARACTER;
24666 x_produce_glyphs (&it2);
24667 width = NUMVAL (prop) * it2.pixel_width;
24668 }
24669 #endif /* HAVE_WINDOW_SYSTEM */
24670 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24671 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24672 {
24673 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24674 align_to = (align_to < 0
24675 ? 0
24676 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24677 else if (align_to < 0)
24678 align_to = window_box_left_offset (it->w, TEXT_AREA);
24679 width = max (0, (int)tem + align_to - it->current_x);
24680 zero_width_ok_p = 1;
24681 }
24682 else
24683 /* Nothing specified -> width defaults to canonical char width. */
24684 width = FRAME_COLUMN_WIDTH (it->f);
24685
24686 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24687 width = 1;
24688
24689 #ifdef HAVE_WINDOW_SYSTEM
24690 /* Compute height. */
24691 if (FRAME_WINDOW_P (it->f))
24692 {
24693 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24694 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24695 {
24696 height = (int)tem;
24697 zero_height_ok_p = 1;
24698 }
24699 else if (prop = Fplist_get (plist, QCrelative_height),
24700 NUMVAL (prop) > 0)
24701 height = FONT_HEIGHT (font) * NUMVAL (prop);
24702 else
24703 height = FONT_HEIGHT (font);
24704
24705 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24706 height = 1;
24707
24708 /* Compute percentage of height used for ascent. If
24709 `:ascent ASCENT' is present and valid, use that. Otherwise,
24710 derive the ascent from the font in use. */
24711 if (prop = Fplist_get (plist, QCascent),
24712 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24713 ascent = height * NUMVAL (prop) / 100.0;
24714 else if (!NILP (prop)
24715 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24716 ascent = min (max (0, (int)tem), height);
24717 else
24718 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24719 }
24720 else
24721 #endif /* HAVE_WINDOW_SYSTEM */
24722 height = 1;
24723
24724 if (width > 0 && it->line_wrap != TRUNCATE
24725 && it->current_x + width > it->last_visible_x)
24726 {
24727 width = it->last_visible_x - it->current_x;
24728 #ifdef HAVE_WINDOW_SYSTEM
24729 /* Subtract one more pixel from the stretch width, but only on
24730 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24731 width -= FRAME_WINDOW_P (it->f);
24732 #endif
24733 }
24734
24735 if (width > 0 && height > 0 && it->glyph_row)
24736 {
24737 Lisp_Object o_object = it->object;
24738 Lisp_Object object = it->stack[it->sp - 1].string;
24739 int n = width;
24740
24741 if (!STRINGP (object))
24742 object = it->w->contents;
24743 #ifdef HAVE_WINDOW_SYSTEM
24744 if (FRAME_WINDOW_P (it->f))
24745 append_stretch_glyph (it, object, width, height, ascent);
24746 else
24747 #endif
24748 {
24749 it->object = object;
24750 it->char_to_display = ' ';
24751 it->pixel_width = it->len = 1;
24752 while (n--)
24753 tty_append_glyph (it);
24754 it->object = o_object;
24755 }
24756 }
24757
24758 it->pixel_width = width;
24759 #ifdef HAVE_WINDOW_SYSTEM
24760 if (FRAME_WINDOW_P (it->f))
24761 {
24762 it->ascent = it->phys_ascent = ascent;
24763 it->descent = it->phys_descent = height - it->ascent;
24764 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24765 take_vertical_position_into_account (it);
24766 }
24767 else
24768 #endif
24769 it->nglyphs = width;
24770 }
24771
24772 /* Get information about special display element WHAT in an
24773 environment described by IT. WHAT is one of IT_TRUNCATION or
24774 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24775 non-null glyph_row member. This function ensures that fields like
24776 face_id, c, len of IT are left untouched. */
24777
24778 static void
24779 produce_special_glyphs (struct it *it, enum display_element_type what)
24780 {
24781 struct it temp_it;
24782 Lisp_Object gc;
24783 GLYPH glyph;
24784
24785 temp_it = *it;
24786 temp_it.object = make_number (0);
24787 memset (&temp_it.current, 0, sizeof temp_it.current);
24788
24789 if (what == IT_CONTINUATION)
24790 {
24791 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24792 if (it->bidi_it.paragraph_dir == R2L)
24793 SET_GLYPH_FROM_CHAR (glyph, '/');
24794 else
24795 SET_GLYPH_FROM_CHAR (glyph, '\\');
24796 if (it->dp
24797 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24798 {
24799 /* FIXME: Should we mirror GC for R2L lines? */
24800 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24801 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24802 }
24803 }
24804 else if (what == IT_TRUNCATION)
24805 {
24806 /* Truncation glyph. */
24807 SET_GLYPH_FROM_CHAR (glyph, '$');
24808 if (it->dp
24809 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24810 {
24811 /* FIXME: Should we mirror GC for R2L lines? */
24812 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24813 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24814 }
24815 }
24816 else
24817 emacs_abort ();
24818
24819 #ifdef HAVE_WINDOW_SYSTEM
24820 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24821 is turned off, we precede the truncation/continuation glyphs by a
24822 stretch glyph whose width is computed such that these special
24823 glyphs are aligned at the window margin, even when very different
24824 fonts are used in different glyph rows. */
24825 if (FRAME_WINDOW_P (temp_it.f)
24826 /* init_iterator calls this with it->glyph_row == NULL, and it
24827 wants only the pixel width of the truncation/continuation
24828 glyphs. */
24829 && temp_it.glyph_row
24830 /* insert_left_trunc_glyphs calls us at the beginning of the
24831 row, and it has its own calculation of the stretch glyph
24832 width. */
24833 && temp_it.glyph_row->used[TEXT_AREA] > 0
24834 && (temp_it.glyph_row->reversed_p
24835 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24836 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24837 {
24838 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24839
24840 if (stretch_width > 0)
24841 {
24842 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24843 struct font *font =
24844 face->font ? face->font : FRAME_FONT (temp_it.f);
24845 int stretch_ascent =
24846 (((temp_it.ascent + temp_it.descent)
24847 * FONT_BASE (font)) / FONT_HEIGHT (font));
24848
24849 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24850 temp_it.ascent + temp_it.descent,
24851 stretch_ascent);
24852 }
24853 }
24854 #endif
24855
24856 temp_it.dp = NULL;
24857 temp_it.what = IT_CHARACTER;
24858 temp_it.len = 1;
24859 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24860 temp_it.face_id = GLYPH_FACE (glyph);
24861 temp_it.len = CHAR_BYTES (temp_it.c);
24862
24863 PRODUCE_GLYPHS (&temp_it);
24864 it->pixel_width = temp_it.pixel_width;
24865 it->nglyphs = temp_it.pixel_width;
24866 }
24867
24868 #ifdef HAVE_WINDOW_SYSTEM
24869
24870 /* Calculate line-height and line-spacing properties.
24871 An integer value specifies explicit pixel value.
24872 A float value specifies relative value to current face height.
24873 A cons (float . face-name) specifies relative value to
24874 height of specified face font.
24875
24876 Returns height in pixels, or nil. */
24877
24878
24879 static Lisp_Object
24880 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24881 int boff, int override)
24882 {
24883 Lisp_Object face_name = Qnil;
24884 int ascent, descent, height;
24885
24886 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24887 return val;
24888
24889 if (CONSP (val))
24890 {
24891 face_name = XCAR (val);
24892 val = XCDR (val);
24893 if (!NUMBERP (val))
24894 val = make_number (1);
24895 if (NILP (face_name))
24896 {
24897 height = it->ascent + it->descent;
24898 goto scale;
24899 }
24900 }
24901
24902 if (NILP (face_name))
24903 {
24904 font = FRAME_FONT (it->f);
24905 boff = FRAME_BASELINE_OFFSET (it->f);
24906 }
24907 else if (EQ (face_name, Qt))
24908 {
24909 override = 0;
24910 }
24911 else
24912 {
24913 int face_id;
24914 struct face *face;
24915
24916 face_id = lookup_named_face (it->f, face_name, 0);
24917 if (face_id < 0)
24918 return make_number (-1);
24919
24920 face = FACE_FROM_ID (it->f, face_id);
24921 font = face->font;
24922 if (font == NULL)
24923 return make_number (-1);
24924 boff = font->baseline_offset;
24925 if (font->vertical_centering)
24926 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24927 }
24928
24929 ascent = FONT_BASE (font) + boff;
24930 descent = FONT_DESCENT (font) - boff;
24931
24932 if (override)
24933 {
24934 it->override_ascent = ascent;
24935 it->override_descent = descent;
24936 it->override_boff = boff;
24937 }
24938
24939 height = ascent + descent;
24940
24941 scale:
24942 if (FLOATP (val))
24943 height = (int)(XFLOAT_DATA (val) * height);
24944 else if (INTEGERP (val))
24945 height *= XINT (val);
24946
24947 return make_number (height);
24948 }
24949
24950
24951 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24952 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24953 and only if this is for a character for which no font was found.
24954
24955 If the display method (it->glyphless_method) is
24956 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24957 length of the acronym or the hexadecimal string, UPPER_XOFF and
24958 UPPER_YOFF are pixel offsets for the upper part of the string,
24959 LOWER_XOFF and LOWER_YOFF are for the lower part.
24960
24961 For the other display methods, LEN through LOWER_YOFF are zero. */
24962
24963 static void
24964 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24965 short upper_xoff, short upper_yoff,
24966 short lower_xoff, short lower_yoff)
24967 {
24968 struct glyph *glyph;
24969 enum glyph_row_area area = it->area;
24970
24971 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24972 if (glyph < it->glyph_row->glyphs[area + 1])
24973 {
24974 /* If the glyph row is reversed, we need to prepend the glyph
24975 rather than append it. */
24976 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24977 {
24978 struct glyph *g;
24979
24980 /* Make room for the additional glyph. */
24981 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24982 g[1] = *g;
24983 glyph = it->glyph_row->glyphs[area];
24984 }
24985 glyph->charpos = CHARPOS (it->position);
24986 glyph->object = it->object;
24987 glyph->pixel_width = it->pixel_width;
24988 glyph->ascent = it->ascent;
24989 glyph->descent = it->descent;
24990 glyph->voffset = it->voffset;
24991 glyph->type = GLYPHLESS_GLYPH;
24992 glyph->u.glyphless.method = it->glyphless_method;
24993 glyph->u.glyphless.for_no_font = for_no_font;
24994 glyph->u.glyphless.len = len;
24995 glyph->u.glyphless.ch = it->c;
24996 glyph->slice.glyphless.upper_xoff = upper_xoff;
24997 glyph->slice.glyphless.upper_yoff = upper_yoff;
24998 glyph->slice.glyphless.lower_xoff = lower_xoff;
24999 glyph->slice.glyphless.lower_yoff = lower_yoff;
25000 glyph->avoid_cursor_p = it->avoid_cursor_p;
25001 glyph->multibyte_p = it->multibyte_p;
25002 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25003 {
25004 /* In R2L rows, the left and the right box edges need to be
25005 drawn in reverse direction. */
25006 glyph->right_box_line_p = it->start_of_box_run_p;
25007 glyph->left_box_line_p = it->end_of_box_run_p;
25008 }
25009 else
25010 {
25011 glyph->left_box_line_p = it->start_of_box_run_p;
25012 glyph->right_box_line_p = it->end_of_box_run_p;
25013 }
25014 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25015 || it->phys_descent > it->descent);
25016 glyph->padding_p = 0;
25017 glyph->glyph_not_available_p = 0;
25018 glyph->face_id = face_id;
25019 glyph->font_type = FONT_TYPE_UNKNOWN;
25020 if (it->bidi_p)
25021 {
25022 glyph->resolved_level = it->bidi_it.resolved_level;
25023 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25024 emacs_abort ();
25025 glyph->bidi_type = it->bidi_it.type;
25026 }
25027 ++it->glyph_row->used[area];
25028 }
25029 else
25030 IT_EXPAND_MATRIX_WIDTH (it, area);
25031 }
25032
25033
25034 /* Produce a glyph for a glyphless character for iterator IT.
25035 IT->glyphless_method specifies which method to use for displaying
25036 the character. See the description of enum
25037 glyphless_display_method in dispextern.h for the detail.
25038
25039 FOR_NO_FONT is nonzero if and only if this is for a character for
25040 which no font was found. ACRONYM, if non-nil, is an acronym string
25041 for the character. */
25042
25043 static void
25044 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
25045 {
25046 int face_id;
25047 struct face *face;
25048 struct font *font;
25049 int base_width, base_height, width, height;
25050 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
25051 int len;
25052
25053 /* Get the metrics of the base font. We always refer to the current
25054 ASCII face. */
25055 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
25056 font = face->font ? face->font : FRAME_FONT (it->f);
25057 it->ascent = FONT_BASE (font) + font->baseline_offset;
25058 it->descent = FONT_DESCENT (font) - font->baseline_offset;
25059 base_height = it->ascent + it->descent;
25060 base_width = font->average_width;
25061
25062 face_id = merge_glyphless_glyph_face (it);
25063
25064 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
25065 {
25066 it->pixel_width = THIN_SPACE_WIDTH;
25067 len = 0;
25068 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
25069 }
25070 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
25071 {
25072 width = CHAR_WIDTH (it->c);
25073 if (width == 0)
25074 width = 1;
25075 else if (width > 4)
25076 width = 4;
25077 it->pixel_width = base_width * width;
25078 len = 0;
25079 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
25080 }
25081 else
25082 {
25083 char buf[7];
25084 const char *str;
25085 unsigned int code[6];
25086 int upper_len;
25087 int ascent, descent;
25088 struct font_metrics metrics_upper, metrics_lower;
25089
25090 face = FACE_FROM_ID (it->f, face_id);
25091 font = face->font ? face->font : FRAME_FONT (it->f);
25092 PREPARE_FACE_FOR_DISPLAY (it->f, face);
25093
25094 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
25095 {
25096 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
25097 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
25098 if (CONSP (acronym))
25099 acronym = XCAR (acronym);
25100 str = STRINGP (acronym) ? SSDATA (acronym) : "";
25101 }
25102 else
25103 {
25104 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
25105 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
25106 str = buf;
25107 }
25108 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
25109 code[len] = font->driver->encode_char (font, str[len]);
25110 upper_len = (len + 1) / 2;
25111 font->driver->text_extents (font, code, upper_len,
25112 &metrics_upper);
25113 font->driver->text_extents (font, code + upper_len, len - upper_len,
25114 &metrics_lower);
25115
25116
25117
25118 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
25119 width = max (metrics_upper.width, metrics_lower.width) + 4;
25120 upper_xoff = upper_yoff = 2; /* the typical case */
25121 if (base_width >= width)
25122 {
25123 /* Align the upper to the left, the lower to the right. */
25124 it->pixel_width = base_width;
25125 lower_xoff = base_width - 2 - metrics_lower.width;
25126 }
25127 else
25128 {
25129 /* Center the shorter one. */
25130 it->pixel_width = width;
25131 if (metrics_upper.width >= metrics_lower.width)
25132 lower_xoff = (width - metrics_lower.width) / 2;
25133 else
25134 {
25135 /* FIXME: This code doesn't look right. It formerly was
25136 missing the "lower_xoff = 0;", which couldn't have
25137 been right since it left lower_xoff uninitialized. */
25138 lower_xoff = 0;
25139 upper_xoff = (width - metrics_upper.width) / 2;
25140 }
25141 }
25142
25143 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
25144 top, bottom, and between upper and lower strings. */
25145 height = (metrics_upper.ascent + metrics_upper.descent
25146 + metrics_lower.ascent + metrics_lower.descent) + 5;
25147 /* Center vertically.
25148 H:base_height, D:base_descent
25149 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25150
25151 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25152 descent = D - H/2 + h/2;
25153 lower_yoff = descent - 2 - ld;
25154 upper_yoff = lower_yoff - la - 1 - ud; */
25155 ascent = - (it->descent - (base_height + height + 1) / 2);
25156 descent = it->descent - (base_height - height) / 2;
25157 lower_yoff = descent - 2 - metrics_lower.descent;
25158 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
25159 - metrics_upper.descent);
25160 /* Don't make the height shorter than the base height. */
25161 if (height > base_height)
25162 {
25163 it->ascent = ascent;
25164 it->descent = descent;
25165 }
25166 }
25167
25168 it->phys_ascent = it->ascent;
25169 it->phys_descent = it->descent;
25170 if (it->glyph_row)
25171 append_glyphless_glyph (it, face_id, for_no_font, len,
25172 upper_xoff, upper_yoff,
25173 lower_xoff, lower_yoff);
25174 it->nglyphs = 1;
25175 take_vertical_position_into_account (it);
25176 }
25177
25178
25179 /* RIF:
25180 Produce glyphs/get display metrics for the display element IT is
25181 loaded with. See the description of struct it in dispextern.h
25182 for an overview of struct it. */
25183
25184 void
25185 x_produce_glyphs (struct it *it)
25186 {
25187 int extra_line_spacing = it->extra_line_spacing;
25188
25189 it->glyph_not_available_p = 0;
25190
25191 if (it->what == IT_CHARACTER)
25192 {
25193 XChar2b char2b;
25194 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25195 struct font *font = face->font;
25196 struct font_metrics *pcm = NULL;
25197 int boff; /* Baseline offset. */
25198
25199 if (font == NULL)
25200 {
25201 /* When no suitable font is found, display this character by
25202 the method specified in the first extra slot of
25203 Vglyphless_char_display. */
25204 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
25205
25206 eassert (it->what == IT_GLYPHLESS);
25207 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
25208 goto done;
25209 }
25210
25211 boff = font->baseline_offset;
25212 if (font->vertical_centering)
25213 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25214
25215 if (it->char_to_display != '\n' && it->char_to_display != '\t')
25216 {
25217 int stretched_p;
25218
25219 it->nglyphs = 1;
25220
25221 if (it->override_ascent >= 0)
25222 {
25223 it->ascent = it->override_ascent;
25224 it->descent = it->override_descent;
25225 boff = it->override_boff;
25226 }
25227 else
25228 {
25229 it->ascent = FONT_BASE (font) + boff;
25230 it->descent = FONT_DESCENT (font) - boff;
25231 }
25232
25233 if (get_char_glyph_code (it->char_to_display, font, &char2b))
25234 {
25235 pcm = get_per_char_metric (font, &char2b);
25236 if (pcm->width == 0
25237 && pcm->rbearing == 0 && pcm->lbearing == 0)
25238 pcm = NULL;
25239 }
25240
25241 if (pcm)
25242 {
25243 it->phys_ascent = pcm->ascent + boff;
25244 it->phys_descent = pcm->descent - boff;
25245 it->pixel_width = pcm->width;
25246 }
25247 else
25248 {
25249 it->glyph_not_available_p = 1;
25250 it->phys_ascent = it->ascent;
25251 it->phys_descent = it->descent;
25252 it->pixel_width = font->space_width;
25253 }
25254
25255 if (it->constrain_row_ascent_descent_p)
25256 {
25257 if (it->descent > it->max_descent)
25258 {
25259 it->ascent += it->descent - it->max_descent;
25260 it->descent = it->max_descent;
25261 }
25262 if (it->ascent > it->max_ascent)
25263 {
25264 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25265 it->ascent = it->max_ascent;
25266 }
25267 it->phys_ascent = min (it->phys_ascent, it->ascent);
25268 it->phys_descent = min (it->phys_descent, it->descent);
25269 extra_line_spacing = 0;
25270 }
25271
25272 /* If this is a space inside a region of text with
25273 `space-width' property, change its width. */
25274 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
25275 if (stretched_p)
25276 it->pixel_width *= XFLOATINT (it->space_width);
25277
25278 /* If face has a box, add the box thickness to the character
25279 height. If character has a box line to the left and/or
25280 right, add the box line width to the character's width. */
25281 if (face->box != FACE_NO_BOX)
25282 {
25283 int thick = face->box_line_width;
25284
25285 if (thick > 0)
25286 {
25287 it->ascent += thick;
25288 it->descent += thick;
25289 }
25290 else
25291 thick = -thick;
25292
25293 if (it->start_of_box_run_p)
25294 it->pixel_width += thick;
25295 if (it->end_of_box_run_p)
25296 it->pixel_width += thick;
25297 }
25298
25299 /* If face has an overline, add the height of the overline
25300 (1 pixel) and a 1 pixel margin to the character height. */
25301 if (face->overline_p)
25302 it->ascent += overline_margin;
25303
25304 if (it->constrain_row_ascent_descent_p)
25305 {
25306 if (it->ascent > it->max_ascent)
25307 it->ascent = it->max_ascent;
25308 if (it->descent > it->max_descent)
25309 it->descent = it->max_descent;
25310 }
25311
25312 take_vertical_position_into_account (it);
25313
25314 /* If we have to actually produce glyphs, do it. */
25315 if (it->glyph_row)
25316 {
25317 if (stretched_p)
25318 {
25319 /* Translate a space with a `space-width' property
25320 into a stretch glyph. */
25321 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25322 / FONT_HEIGHT (font));
25323 append_stretch_glyph (it, it->object, it->pixel_width,
25324 it->ascent + it->descent, ascent);
25325 }
25326 else
25327 append_glyph (it);
25328
25329 /* If characters with lbearing or rbearing are displayed
25330 in this line, record that fact in a flag of the
25331 glyph row. This is used to optimize X output code. */
25332 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25333 it->glyph_row->contains_overlapping_glyphs_p = 1;
25334 }
25335 if (! stretched_p && it->pixel_width == 0)
25336 /* We assure that all visible glyphs have at least 1-pixel
25337 width. */
25338 it->pixel_width = 1;
25339 }
25340 else if (it->char_to_display == '\n')
25341 {
25342 /* A newline has no width, but we need the height of the
25343 line. But if previous part of the line sets a height,
25344 don't increase that height. */
25345
25346 Lisp_Object height;
25347 Lisp_Object total_height = Qnil;
25348
25349 it->override_ascent = -1;
25350 it->pixel_width = 0;
25351 it->nglyphs = 0;
25352
25353 height = get_it_property (it, Qline_height);
25354 /* Split (line-height total-height) list. */
25355 if (CONSP (height)
25356 && CONSP (XCDR (height))
25357 && NILP (XCDR (XCDR (height))))
25358 {
25359 total_height = XCAR (XCDR (height));
25360 height = XCAR (height);
25361 }
25362 height = calc_line_height_property (it, height, font, boff, 1);
25363
25364 if (it->override_ascent >= 0)
25365 {
25366 it->ascent = it->override_ascent;
25367 it->descent = it->override_descent;
25368 boff = it->override_boff;
25369 }
25370 else
25371 {
25372 it->ascent = FONT_BASE (font) + boff;
25373 it->descent = FONT_DESCENT (font) - boff;
25374 }
25375
25376 if (EQ (height, Qt))
25377 {
25378 if (it->descent > it->max_descent)
25379 {
25380 it->ascent += it->descent - it->max_descent;
25381 it->descent = it->max_descent;
25382 }
25383 if (it->ascent > it->max_ascent)
25384 {
25385 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25386 it->ascent = it->max_ascent;
25387 }
25388 it->phys_ascent = min (it->phys_ascent, it->ascent);
25389 it->phys_descent = min (it->phys_descent, it->descent);
25390 it->constrain_row_ascent_descent_p = 1;
25391 extra_line_spacing = 0;
25392 }
25393 else
25394 {
25395 Lisp_Object spacing;
25396
25397 it->phys_ascent = it->ascent;
25398 it->phys_descent = it->descent;
25399
25400 if ((it->max_ascent > 0 || it->max_descent > 0)
25401 && face->box != FACE_NO_BOX
25402 && face->box_line_width > 0)
25403 {
25404 it->ascent += face->box_line_width;
25405 it->descent += face->box_line_width;
25406 }
25407 if (!NILP (height)
25408 && XINT (height) > it->ascent + it->descent)
25409 it->ascent = XINT (height) - it->descent;
25410
25411 if (!NILP (total_height))
25412 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25413 else
25414 {
25415 spacing = get_it_property (it, Qline_spacing);
25416 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25417 }
25418 if (INTEGERP (spacing))
25419 {
25420 extra_line_spacing = XINT (spacing);
25421 if (!NILP (total_height))
25422 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25423 }
25424 }
25425 }
25426 else /* i.e. (it->char_to_display == '\t') */
25427 {
25428 if (font->space_width > 0)
25429 {
25430 int tab_width = it->tab_width * font->space_width;
25431 int x = it->current_x + it->continuation_lines_width;
25432 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25433
25434 /* If the distance from the current position to the next tab
25435 stop is less than a space character width, use the
25436 tab stop after that. */
25437 if (next_tab_x - x < font->space_width)
25438 next_tab_x += tab_width;
25439
25440 it->pixel_width = next_tab_x - x;
25441 it->nglyphs = 1;
25442 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25443 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25444
25445 if (it->glyph_row)
25446 {
25447 append_stretch_glyph (it, it->object, it->pixel_width,
25448 it->ascent + it->descent, it->ascent);
25449 }
25450 }
25451 else
25452 {
25453 it->pixel_width = 0;
25454 it->nglyphs = 1;
25455 }
25456 }
25457 }
25458 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25459 {
25460 /* A static composition.
25461
25462 Note: A composition is represented as one glyph in the
25463 glyph matrix. There are no padding glyphs.
25464
25465 Important note: pixel_width, ascent, and descent are the
25466 values of what is drawn by draw_glyphs (i.e. the values of
25467 the overall glyphs composed). */
25468 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25469 int boff; /* baseline offset */
25470 struct composition *cmp = composition_table[it->cmp_it.id];
25471 int glyph_len = cmp->glyph_len;
25472 struct font *font = face->font;
25473
25474 it->nglyphs = 1;
25475
25476 /* If we have not yet calculated pixel size data of glyphs of
25477 the composition for the current face font, calculate them
25478 now. Theoretically, we have to check all fonts for the
25479 glyphs, but that requires much time and memory space. So,
25480 here we check only the font of the first glyph. This may
25481 lead to incorrect display, but it's very rare, and C-l
25482 (recenter-top-bottom) can correct the display anyway. */
25483 if (! cmp->font || cmp->font != font)
25484 {
25485 /* Ascent and descent of the font of the first character
25486 of this composition (adjusted by baseline offset).
25487 Ascent and descent of overall glyphs should not be less
25488 than these, respectively. */
25489 int font_ascent, font_descent, font_height;
25490 /* Bounding box of the overall glyphs. */
25491 int leftmost, rightmost, lowest, highest;
25492 int lbearing, rbearing;
25493 int i, width, ascent, descent;
25494 int left_padded = 0, right_padded = 0;
25495 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25496 XChar2b char2b;
25497 struct font_metrics *pcm;
25498 int font_not_found_p;
25499 ptrdiff_t pos;
25500
25501 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25502 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25503 break;
25504 if (glyph_len < cmp->glyph_len)
25505 right_padded = 1;
25506 for (i = 0; i < glyph_len; i++)
25507 {
25508 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25509 break;
25510 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25511 }
25512 if (i > 0)
25513 left_padded = 1;
25514
25515 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25516 : IT_CHARPOS (*it));
25517 /* If no suitable font is found, use the default font. */
25518 font_not_found_p = font == NULL;
25519 if (font_not_found_p)
25520 {
25521 face = face->ascii_face;
25522 font = face->font;
25523 }
25524 boff = font->baseline_offset;
25525 if (font->vertical_centering)
25526 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25527 font_ascent = FONT_BASE (font) + boff;
25528 font_descent = FONT_DESCENT (font) - boff;
25529 font_height = FONT_HEIGHT (font);
25530
25531 cmp->font = font;
25532
25533 pcm = NULL;
25534 if (! font_not_found_p)
25535 {
25536 get_char_face_and_encoding (it->f, c, it->face_id,
25537 &char2b, 0);
25538 pcm = get_per_char_metric (font, &char2b);
25539 }
25540
25541 /* Initialize the bounding box. */
25542 if (pcm)
25543 {
25544 width = cmp->glyph_len > 0 ? pcm->width : 0;
25545 ascent = pcm->ascent;
25546 descent = pcm->descent;
25547 lbearing = pcm->lbearing;
25548 rbearing = pcm->rbearing;
25549 }
25550 else
25551 {
25552 width = cmp->glyph_len > 0 ? font->space_width : 0;
25553 ascent = FONT_BASE (font);
25554 descent = FONT_DESCENT (font);
25555 lbearing = 0;
25556 rbearing = width;
25557 }
25558
25559 rightmost = width;
25560 leftmost = 0;
25561 lowest = - descent + boff;
25562 highest = ascent + boff;
25563
25564 if (! font_not_found_p
25565 && font->default_ascent
25566 && CHAR_TABLE_P (Vuse_default_ascent)
25567 && !NILP (Faref (Vuse_default_ascent,
25568 make_number (it->char_to_display))))
25569 highest = font->default_ascent + boff;
25570
25571 /* Draw the first glyph at the normal position. It may be
25572 shifted to right later if some other glyphs are drawn
25573 at the left. */
25574 cmp->offsets[i * 2] = 0;
25575 cmp->offsets[i * 2 + 1] = boff;
25576 cmp->lbearing = lbearing;
25577 cmp->rbearing = rbearing;
25578
25579 /* Set cmp->offsets for the remaining glyphs. */
25580 for (i++; i < glyph_len; i++)
25581 {
25582 int left, right, btm, top;
25583 int ch = COMPOSITION_GLYPH (cmp, i);
25584 int face_id;
25585 struct face *this_face;
25586
25587 if (ch == '\t')
25588 ch = ' ';
25589 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25590 this_face = FACE_FROM_ID (it->f, face_id);
25591 font = this_face->font;
25592
25593 if (font == NULL)
25594 pcm = NULL;
25595 else
25596 {
25597 get_char_face_and_encoding (it->f, ch, face_id,
25598 &char2b, 0);
25599 pcm = get_per_char_metric (font, &char2b);
25600 }
25601 if (! pcm)
25602 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25603 else
25604 {
25605 width = pcm->width;
25606 ascent = pcm->ascent;
25607 descent = pcm->descent;
25608 lbearing = pcm->lbearing;
25609 rbearing = pcm->rbearing;
25610 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25611 {
25612 /* Relative composition with or without
25613 alternate chars. */
25614 left = (leftmost + rightmost - width) / 2;
25615 btm = - descent + boff;
25616 if (font->relative_compose
25617 && (! CHAR_TABLE_P (Vignore_relative_composition)
25618 || NILP (Faref (Vignore_relative_composition,
25619 make_number (ch)))))
25620 {
25621
25622 if (- descent >= font->relative_compose)
25623 /* One extra pixel between two glyphs. */
25624 btm = highest + 1;
25625 else if (ascent <= 0)
25626 /* One extra pixel between two glyphs. */
25627 btm = lowest - 1 - ascent - descent;
25628 }
25629 }
25630 else
25631 {
25632 /* A composition rule is specified by an integer
25633 value that encodes global and new reference
25634 points (GREF and NREF). GREF and NREF are
25635 specified by numbers as below:
25636
25637 0---1---2 -- ascent
25638 | |
25639 | |
25640 | |
25641 9--10--11 -- center
25642 | |
25643 ---3---4---5--- baseline
25644 | |
25645 6---7---8 -- descent
25646 */
25647 int rule = COMPOSITION_RULE (cmp, i);
25648 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25649
25650 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25651 grefx = gref % 3, nrefx = nref % 3;
25652 grefy = gref / 3, nrefy = nref / 3;
25653 if (xoff)
25654 xoff = font_height * (xoff - 128) / 256;
25655 if (yoff)
25656 yoff = font_height * (yoff - 128) / 256;
25657
25658 left = (leftmost
25659 + grefx * (rightmost - leftmost) / 2
25660 - nrefx * width / 2
25661 + xoff);
25662
25663 btm = ((grefy == 0 ? highest
25664 : grefy == 1 ? 0
25665 : grefy == 2 ? lowest
25666 : (highest + lowest) / 2)
25667 - (nrefy == 0 ? ascent + descent
25668 : nrefy == 1 ? descent - boff
25669 : nrefy == 2 ? 0
25670 : (ascent + descent) / 2)
25671 + yoff);
25672 }
25673
25674 cmp->offsets[i * 2] = left;
25675 cmp->offsets[i * 2 + 1] = btm + descent;
25676
25677 /* Update the bounding box of the overall glyphs. */
25678 if (width > 0)
25679 {
25680 right = left + width;
25681 if (left < leftmost)
25682 leftmost = left;
25683 if (right > rightmost)
25684 rightmost = right;
25685 }
25686 top = btm + descent + ascent;
25687 if (top > highest)
25688 highest = top;
25689 if (btm < lowest)
25690 lowest = btm;
25691
25692 if (cmp->lbearing > left + lbearing)
25693 cmp->lbearing = left + lbearing;
25694 if (cmp->rbearing < left + rbearing)
25695 cmp->rbearing = left + rbearing;
25696 }
25697 }
25698
25699 /* If there are glyphs whose x-offsets are negative,
25700 shift all glyphs to the right and make all x-offsets
25701 non-negative. */
25702 if (leftmost < 0)
25703 {
25704 for (i = 0; i < cmp->glyph_len; i++)
25705 cmp->offsets[i * 2] -= leftmost;
25706 rightmost -= leftmost;
25707 cmp->lbearing -= leftmost;
25708 cmp->rbearing -= leftmost;
25709 }
25710
25711 if (left_padded && cmp->lbearing < 0)
25712 {
25713 for (i = 0; i < cmp->glyph_len; i++)
25714 cmp->offsets[i * 2] -= cmp->lbearing;
25715 rightmost -= cmp->lbearing;
25716 cmp->rbearing -= cmp->lbearing;
25717 cmp->lbearing = 0;
25718 }
25719 if (right_padded && rightmost < cmp->rbearing)
25720 {
25721 rightmost = cmp->rbearing;
25722 }
25723
25724 cmp->pixel_width = rightmost;
25725 cmp->ascent = highest;
25726 cmp->descent = - lowest;
25727 if (cmp->ascent < font_ascent)
25728 cmp->ascent = font_ascent;
25729 if (cmp->descent < font_descent)
25730 cmp->descent = font_descent;
25731 }
25732
25733 if (it->glyph_row
25734 && (cmp->lbearing < 0
25735 || cmp->rbearing > cmp->pixel_width))
25736 it->glyph_row->contains_overlapping_glyphs_p = 1;
25737
25738 it->pixel_width = cmp->pixel_width;
25739 it->ascent = it->phys_ascent = cmp->ascent;
25740 it->descent = it->phys_descent = cmp->descent;
25741 if (face->box != FACE_NO_BOX)
25742 {
25743 int thick = face->box_line_width;
25744
25745 if (thick > 0)
25746 {
25747 it->ascent += thick;
25748 it->descent += thick;
25749 }
25750 else
25751 thick = - thick;
25752
25753 if (it->start_of_box_run_p)
25754 it->pixel_width += thick;
25755 if (it->end_of_box_run_p)
25756 it->pixel_width += thick;
25757 }
25758
25759 /* If face has an overline, add the height of the overline
25760 (1 pixel) and a 1 pixel margin to the character height. */
25761 if (face->overline_p)
25762 it->ascent += overline_margin;
25763
25764 take_vertical_position_into_account (it);
25765 if (it->ascent < 0)
25766 it->ascent = 0;
25767 if (it->descent < 0)
25768 it->descent = 0;
25769
25770 if (it->glyph_row && cmp->glyph_len > 0)
25771 append_composite_glyph (it);
25772 }
25773 else if (it->what == IT_COMPOSITION)
25774 {
25775 /* A dynamic (automatic) composition. */
25776 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25777 Lisp_Object gstring;
25778 struct font_metrics metrics;
25779
25780 it->nglyphs = 1;
25781
25782 gstring = composition_gstring_from_id (it->cmp_it.id);
25783 it->pixel_width
25784 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25785 &metrics);
25786 if (it->glyph_row
25787 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25788 it->glyph_row->contains_overlapping_glyphs_p = 1;
25789 it->ascent = it->phys_ascent = metrics.ascent;
25790 it->descent = it->phys_descent = metrics.descent;
25791 if (face->box != FACE_NO_BOX)
25792 {
25793 int thick = face->box_line_width;
25794
25795 if (thick > 0)
25796 {
25797 it->ascent += thick;
25798 it->descent += thick;
25799 }
25800 else
25801 thick = - thick;
25802
25803 if (it->start_of_box_run_p)
25804 it->pixel_width += thick;
25805 if (it->end_of_box_run_p)
25806 it->pixel_width += thick;
25807 }
25808 /* If face has an overline, add the height of the overline
25809 (1 pixel) and a 1 pixel margin to the character height. */
25810 if (face->overline_p)
25811 it->ascent += overline_margin;
25812 take_vertical_position_into_account (it);
25813 if (it->ascent < 0)
25814 it->ascent = 0;
25815 if (it->descent < 0)
25816 it->descent = 0;
25817
25818 if (it->glyph_row)
25819 append_composite_glyph (it);
25820 }
25821 else if (it->what == IT_GLYPHLESS)
25822 produce_glyphless_glyph (it, 0, Qnil);
25823 else if (it->what == IT_IMAGE)
25824 produce_image_glyph (it);
25825 else if (it->what == IT_STRETCH)
25826 produce_stretch_glyph (it);
25827
25828 done:
25829 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25830 because this isn't true for images with `:ascent 100'. */
25831 eassert (it->ascent >= 0 && it->descent >= 0);
25832 if (it->area == TEXT_AREA)
25833 it->current_x += it->pixel_width;
25834
25835 if (extra_line_spacing > 0)
25836 {
25837 it->descent += extra_line_spacing;
25838 if (extra_line_spacing > it->max_extra_line_spacing)
25839 it->max_extra_line_spacing = extra_line_spacing;
25840 }
25841
25842 it->max_ascent = max (it->max_ascent, it->ascent);
25843 it->max_descent = max (it->max_descent, it->descent);
25844 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25845 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25846 }
25847
25848 /* EXPORT for RIF:
25849 Output LEN glyphs starting at START at the nominal cursor position.
25850 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
25851 being updated, and UPDATED_AREA is the area of that row being updated. */
25852
25853 void
25854 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
25855 struct glyph *start, enum glyph_row_area updated_area, int len)
25856 {
25857 int x, hpos, chpos = w->phys_cursor.hpos;
25858
25859 eassert (updated_row);
25860 /* When the window is hscrolled, cursor hpos can legitimately be out
25861 of bounds, but we draw the cursor at the corresponding window
25862 margin in that case. */
25863 if (!updated_row->reversed_p && chpos < 0)
25864 chpos = 0;
25865 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25866 chpos = updated_row->used[TEXT_AREA] - 1;
25867
25868 block_input ();
25869
25870 /* Write glyphs. */
25871
25872 hpos = start - updated_row->glyphs[updated_area];
25873 x = draw_glyphs (w, w->output_cursor.x,
25874 updated_row, updated_area,
25875 hpos, hpos + len,
25876 DRAW_NORMAL_TEXT, 0);
25877
25878 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25879 if (updated_area == TEXT_AREA
25880 && w->phys_cursor_on_p
25881 && w->phys_cursor.vpos == w->output_cursor.vpos
25882 && chpos >= hpos
25883 && chpos < hpos + len)
25884 w->phys_cursor_on_p = 0;
25885
25886 unblock_input ();
25887
25888 /* Advance the output cursor. */
25889 w->output_cursor.hpos += len;
25890 w->output_cursor.x = x;
25891 }
25892
25893
25894 /* EXPORT for RIF:
25895 Insert LEN glyphs from START at the nominal cursor position. */
25896
25897 void
25898 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
25899 struct glyph *start, enum glyph_row_area updated_area, int len)
25900 {
25901 struct frame *f;
25902 int line_height, shift_by_width, shifted_region_width;
25903 struct glyph_row *row;
25904 struct glyph *glyph;
25905 int frame_x, frame_y;
25906 ptrdiff_t hpos;
25907
25908 eassert (updated_row);
25909 block_input ();
25910 f = XFRAME (WINDOW_FRAME (w));
25911
25912 /* Get the height of the line we are in. */
25913 row = updated_row;
25914 line_height = row->height;
25915
25916 /* Get the width of the glyphs to insert. */
25917 shift_by_width = 0;
25918 for (glyph = start; glyph < start + len; ++glyph)
25919 shift_by_width += glyph->pixel_width;
25920
25921 /* Get the width of the region to shift right. */
25922 shifted_region_width = (window_box_width (w, updated_area)
25923 - w->output_cursor.x
25924 - shift_by_width);
25925
25926 /* Shift right. */
25927 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
25928 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
25929
25930 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25931 line_height, shift_by_width);
25932
25933 /* Write the glyphs. */
25934 hpos = start - row->glyphs[updated_area];
25935 draw_glyphs (w, w->output_cursor.x, row, updated_area,
25936 hpos, hpos + len,
25937 DRAW_NORMAL_TEXT, 0);
25938
25939 /* Advance the output cursor. */
25940 w->output_cursor.hpos += len;
25941 w->output_cursor.x += shift_by_width;
25942 unblock_input ();
25943 }
25944
25945
25946 /* EXPORT for RIF:
25947 Erase the current text line from the nominal cursor position
25948 (inclusive) to pixel column TO_X (exclusive). The idea is that
25949 everything from TO_X onward is already erased.
25950
25951 TO_X is a pixel position relative to UPDATED_AREA of currently
25952 updated window W. TO_X == -1 means clear to the end of this area. */
25953
25954 void
25955 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
25956 enum glyph_row_area updated_area, int to_x)
25957 {
25958 struct frame *f;
25959 int max_x, min_y, max_y;
25960 int from_x, from_y, to_y;
25961
25962 eassert (updated_row);
25963 f = XFRAME (w->frame);
25964
25965 if (updated_row->full_width_p)
25966 max_x = WINDOW_TOTAL_WIDTH (w);
25967 else
25968 max_x = window_box_width (w, updated_area);
25969 max_y = window_text_bottom_y (w);
25970
25971 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25972 of window. For TO_X > 0, truncate to end of drawing area. */
25973 if (to_x == 0)
25974 return;
25975 else if (to_x < 0)
25976 to_x = max_x;
25977 else
25978 to_x = min (to_x, max_x);
25979
25980 to_y = min (max_y, w->output_cursor.y + updated_row->height);
25981
25982 /* Notice if the cursor will be cleared by this operation. */
25983 if (!updated_row->full_width_p)
25984 notice_overwritten_cursor (w, updated_area,
25985 w->output_cursor.x, -1,
25986 updated_row->y,
25987 MATRIX_ROW_BOTTOM_Y (updated_row));
25988
25989 from_x = w->output_cursor.x;
25990
25991 /* Translate to frame coordinates. */
25992 if (updated_row->full_width_p)
25993 {
25994 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25995 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25996 }
25997 else
25998 {
25999 int area_left = window_box_left (w, updated_area);
26000 from_x += area_left;
26001 to_x += area_left;
26002 }
26003
26004 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
26005 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
26006 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
26007
26008 /* Prevent inadvertently clearing to end of the X window. */
26009 if (to_x > from_x && to_y > from_y)
26010 {
26011 block_input ();
26012 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
26013 to_x - from_x, to_y - from_y);
26014 unblock_input ();
26015 }
26016 }
26017
26018 #endif /* HAVE_WINDOW_SYSTEM */
26019
26020
26021 \f
26022 /***********************************************************************
26023 Cursor types
26024 ***********************************************************************/
26025
26026 /* Value is the internal representation of the specified cursor type
26027 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
26028 of the bar cursor. */
26029
26030 static enum text_cursor_kinds
26031 get_specified_cursor_type (Lisp_Object arg, int *width)
26032 {
26033 enum text_cursor_kinds type;
26034
26035 if (NILP (arg))
26036 return NO_CURSOR;
26037
26038 if (EQ (arg, Qbox))
26039 return FILLED_BOX_CURSOR;
26040
26041 if (EQ (arg, Qhollow))
26042 return HOLLOW_BOX_CURSOR;
26043
26044 if (EQ (arg, Qbar))
26045 {
26046 *width = 2;
26047 return BAR_CURSOR;
26048 }
26049
26050 if (CONSP (arg)
26051 && EQ (XCAR (arg), Qbar)
26052 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
26053 {
26054 *width = XINT (XCDR (arg));
26055 return BAR_CURSOR;
26056 }
26057
26058 if (EQ (arg, Qhbar))
26059 {
26060 *width = 2;
26061 return HBAR_CURSOR;
26062 }
26063
26064 if (CONSP (arg)
26065 && EQ (XCAR (arg), Qhbar)
26066 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
26067 {
26068 *width = XINT (XCDR (arg));
26069 return HBAR_CURSOR;
26070 }
26071
26072 /* Treat anything unknown as "hollow box cursor".
26073 It was bad to signal an error; people have trouble fixing
26074 .Xdefaults with Emacs, when it has something bad in it. */
26075 type = HOLLOW_BOX_CURSOR;
26076
26077 return type;
26078 }
26079
26080 /* Set the default cursor types for specified frame. */
26081 void
26082 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
26083 {
26084 int width = 1;
26085 Lisp_Object tem;
26086
26087 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
26088 FRAME_CURSOR_WIDTH (f) = width;
26089
26090 /* By default, set up the blink-off state depending on the on-state. */
26091
26092 tem = Fassoc (arg, Vblink_cursor_alist);
26093 if (!NILP (tem))
26094 {
26095 FRAME_BLINK_OFF_CURSOR (f)
26096 = get_specified_cursor_type (XCDR (tem), &width);
26097 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
26098 }
26099 else
26100 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
26101
26102 /* Make sure the cursor gets redrawn. */
26103 f->cursor_type_changed = 1;
26104 }
26105
26106
26107 #ifdef HAVE_WINDOW_SYSTEM
26108
26109 /* Return the cursor we want to be displayed in window W. Return
26110 width of bar/hbar cursor through WIDTH arg. Return with
26111 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
26112 (i.e. if the `system caret' should track this cursor).
26113
26114 In a mini-buffer window, we want the cursor only to appear if we
26115 are reading input from this window. For the selected window, we
26116 want the cursor type given by the frame parameter or buffer local
26117 setting of cursor-type. If explicitly marked off, draw no cursor.
26118 In all other cases, we want a hollow box cursor. */
26119
26120 static enum text_cursor_kinds
26121 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
26122 int *active_cursor)
26123 {
26124 struct frame *f = XFRAME (w->frame);
26125 struct buffer *b = XBUFFER (w->contents);
26126 int cursor_type = DEFAULT_CURSOR;
26127 Lisp_Object alt_cursor;
26128 int non_selected = 0;
26129
26130 *active_cursor = 1;
26131
26132 /* Echo area */
26133 if (cursor_in_echo_area
26134 && FRAME_HAS_MINIBUF_P (f)
26135 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
26136 {
26137 if (w == XWINDOW (echo_area_window))
26138 {
26139 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
26140 {
26141 *width = FRAME_CURSOR_WIDTH (f);
26142 return FRAME_DESIRED_CURSOR (f);
26143 }
26144 else
26145 return get_specified_cursor_type (BVAR (b, cursor_type), width);
26146 }
26147
26148 *active_cursor = 0;
26149 non_selected = 1;
26150 }
26151
26152 /* Detect a nonselected window or nonselected frame. */
26153 else if (w != XWINDOW (f->selected_window)
26154 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
26155 {
26156 *active_cursor = 0;
26157
26158 if (MINI_WINDOW_P (w) && minibuf_level == 0)
26159 return NO_CURSOR;
26160
26161 non_selected = 1;
26162 }
26163
26164 /* Never display a cursor in a window in which cursor-type is nil. */
26165 if (NILP (BVAR (b, cursor_type)))
26166 return NO_CURSOR;
26167
26168 /* Get the normal cursor type for this window. */
26169 if (EQ (BVAR (b, cursor_type), Qt))
26170 {
26171 cursor_type = FRAME_DESIRED_CURSOR (f);
26172 *width = FRAME_CURSOR_WIDTH (f);
26173 }
26174 else
26175 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
26176
26177 /* Use cursor-in-non-selected-windows instead
26178 for non-selected window or frame. */
26179 if (non_selected)
26180 {
26181 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
26182 if (!EQ (Qt, alt_cursor))
26183 return get_specified_cursor_type (alt_cursor, width);
26184 /* t means modify the normal cursor type. */
26185 if (cursor_type == FILLED_BOX_CURSOR)
26186 cursor_type = HOLLOW_BOX_CURSOR;
26187 else if (cursor_type == BAR_CURSOR && *width > 1)
26188 --*width;
26189 return cursor_type;
26190 }
26191
26192 /* Use normal cursor if not blinked off. */
26193 if (!w->cursor_off_p)
26194 {
26195 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26196 {
26197 if (cursor_type == FILLED_BOX_CURSOR)
26198 {
26199 /* Using a block cursor on large images can be very annoying.
26200 So use a hollow cursor for "large" images.
26201 If image is not transparent (no mask), also use hollow cursor. */
26202 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26203 if (img != NULL && IMAGEP (img->spec))
26204 {
26205 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26206 where N = size of default frame font size.
26207 This should cover most of the "tiny" icons people may use. */
26208 if (!img->mask
26209 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
26210 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
26211 cursor_type = HOLLOW_BOX_CURSOR;
26212 }
26213 }
26214 else if (cursor_type != NO_CURSOR)
26215 {
26216 /* Display current only supports BOX and HOLLOW cursors for images.
26217 So for now, unconditionally use a HOLLOW cursor when cursor is
26218 not a solid box cursor. */
26219 cursor_type = HOLLOW_BOX_CURSOR;
26220 }
26221 }
26222 return cursor_type;
26223 }
26224
26225 /* Cursor is blinked off, so determine how to "toggle" it. */
26226
26227 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26228 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
26229 return get_specified_cursor_type (XCDR (alt_cursor), width);
26230
26231 /* Then see if frame has specified a specific blink off cursor type. */
26232 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
26233 {
26234 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
26235 return FRAME_BLINK_OFF_CURSOR (f);
26236 }
26237
26238 #if 0
26239 /* Some people liked having a permanently visible blinking cursor,
26240 while others had very strong opinions against it. So it was
26241 decided to remove it. KFS 2003-09-03 */
26242
26243 /* Finally perform built-in cursor blinking:
26244 filled box <-> hollow box
26245 wide [h]bar <-> narrow [h]bar
26246 narrow [h]bar <-> no cursor
26247 other type <-> no cursor */
26248
26249 if (cursor_type == FILLED_BOX_CURSOR)
26250 return HOLLOW_BOX_CURSOR;
26251
26252 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
26253 {
26254 *width = 1;
26255 return cursor_type;
26256 }
26257 #endif
26258
26259 return NO_CURSOR;
26260 }
26261
26262
26263 /* Notice when the text cursor of window W has been completely
26264 overwritten by a drawing operation that outputs glyphs in AREA
26265 starting at X0 and ending at X1 in the line starting at Y0 and
26266 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26267 the rest of the line after X0 has been written. Y coordinates
26268 are window-relative. */
26269
26270 static void
26271 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
26272 int x0, int x1, int y0, int y1)
26273 {
26274 int cx0, cx1, cy0, cy1;
26275 struct glyph_row *row;
26276
26277 if (!w->phys_cursor_on_p)
26278 return;
26279 if (area != TEXT_AREA)
26280 return;
26281
26282 if (w->phys_cursor.vpos < 0
26283 || w->phys_cursor.vpos >= w->current_matrix->nrows
26284 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
26285 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
26286 return;
26287
26288 if (row->cursor_in_fringe_p)
26289 {
26290 row->cursor_in_fringe_p = 0;
26291 draw_fringe_bitmap (w, row, row->reversed_p);
26292 w->phys_cursor_on_p = 0;
26293 return;
26294 }
26295
26296 cx0 = w->phys_cursor.x;
26297 cx1 = cx0 + w->phys_cursor_width;
26298 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26299 return;
26300
26301 /* The cursor image will be completely removed from the
26302 screen if the output area intersects the cursor area in
26303 y-direction. When we draw in [y0 y1[, and some part of
26304 the cursor is at y < y0, that part must have been drawn
26305 before. When scrolling, the cursor is erased before
26306 actually scrolling, so we don't come here. When not
26307 scrolling, the rows above the old cursor row must have
26308 changed, and in this case these rows must have written
26309 over the cursor image.
26310
26311 Likewise if part of the cursor is below y1, with the
26312 exception of the cursor being in the first blank row at
26313 the buffer and window end because update_text_area
26314 doesn't draw that row. (Except when it does, but
26315 that's handled in update_text_area.) */
26316
26317 cy0 = w->phys_cursor.y;
26318 cy1 = cy0 + w->phys_cursor_height;
26319 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26320 return;
26321
26322 w->phys_cursor_on_p = 0;
26323 }
26324
26325 #endif /* HAVE_WINDOW_SYSTEM */
26326
26327 \f
26328 /************************************************************************
26329 Mouse Face
26330 ************************************************************************/
26331
26332 #ifdef HAVE_WINDOW_SYSTEM
26333
26334 /* EXPORT for RIF:
26335 Fix the display of area AREA of overlapping row ROW in window W
26336 with respect to the overlapping part OVERLAPS. */
26337
26338 void
26339 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26340 enum glyph_row_area area, int overlaps)
26341 {
26342 int i, x;
26343
26344 block_input ();
26345
26346 x = 0;
26347 for (i = 0; i < row->used[area];)
26348 {
26349 if (row->glyphs[area][i].overlaps_vertically_p)
26350 {
26351 int start = i, start_x = x;
26352
26353 do
26354 {
26355 x += row->glyphs[area][i].pixel_width;
26356 ++i;
26357 }
26358 while (i < row->used[area]
26359 && row->glyphs[area][i].overlaps_vertically_p);
26360
26361 draw_glyphs (w, start_x, row, area,
26362 start, i,
26363 DRAW_NORMAL_TEXT, overlaps);
26364 }
26365 else
26366 {
26367 x += row->glyphs[area][i].pixel_width;
26368 ++i;
26369 }
26370 }
26371
26372 unblock_input ();
26373 }
26374
26375
26376 /* EXPORT:
26377 Draw the cursor glyph of window W in glyph row ROW. See the
26378 comment of draw_glyphs for the meaning of HL. */
26379
26380 void
26381 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26382 enum draw_glyphs_face hl)
26383 {
26384 /* If cursor hpos is out of bounds, don't draw garbage. This can
26385 happen in mini-buffer windows when switching between echo area
26386 glyphs and mini-buffer. */
26387 if ((row->reversed_p
26388 ? (w->phys_cursor.hpos >= 0)
26389 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26390 {
26391 int on_p = w->phys_cursor_on_p;
26392 int x1;
26393 int hpos = w->phys_cursor.hpos;
26394
26395 /* When the window is hscrolled, cursor hpos can legitimately be
26396 out of bounds, but we draw the cursor at the corresponding
26397 window margin in that case. */
26398 if (!row->reversed_p && hpos < 0)
26399 hpos = 0;
26400 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26401 hpos = row->used[TEXT_AREA] - 1;
26402
26403 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26404 hl, 0);
26405 w->phys_cursor_on_p = on_p;
26406
26407 if (hl == DRAW_CURSOR)
26408 w->phys_cursor_width = x1 - w->phys_cursor.x;
26409 /* When we erase the cursor, and ROW is overlapped by other
26410 rows, make sure that these overlapping parts of other rows
26411 are redrawn. */
26412 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26413 {
26414 w->phys_cursor_width = x1 - w->phys_cursor.x;
26415
26416 if (row > w->current_matrix->rows
26417 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26418 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26419 OVERLAPS_ERASED_CURSOR);
26420
26421 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26422 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26423 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26424 OVERLAPS_ERASED_CURSOR);
26425 }
26426 }
26427 }
26428
26429
26430 /* Erase the image of a cursor of window W from the screen. */
26431
26432 #ifndef HAVE_NTGUI
26433 static
26434 #endif
26435 void
26436 erase_phys_cursor (struct window *w)
26437 {
26438 struct frame *f = XFRAME (w->frame);
26439 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26440 int hpos = w->phys_cursor.hpos;
26441 int vpos = w->phys_cursor.vpos;
26442 int mouse_face_here_p = 0;
26443 struct glyph_matrix *active_glyphs = w->current_matrix;
26444 struct glyph_row *cursor_row;
26445 struct glyph *cursor_glyph;
26446 enum draw_glyphs_face hl;
26447
26448 /* No cursor displayed or row invalidated => nothing to do on the
26449 screen. */
26450 if (w->phys_cursor_type == NO_CURSOR)
26451 goto mark_cursor_off;
26452
26453 /* VPOS >= active_glyphs->nrows means that window has been resized.
26454 Don't bother to erase the cursor. */
26455 if (vpos >= active_glyphs->nrows)
26456 goto mark_cursor_off;
26457
26458 /* If row containing cursor is marked invalid, there is nothing we
26459 can do. */
26460 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26461 if (!cursor_row->enabled_p)
26462 goto mark_cursor_off;
26463
26464 /* If line spacing is > 0, old cursor may only be partially visible in
26465 window after split-window. So adjust visible height. */
26466 cursor_row->visible_height = min (cursor_row->visible_height,
26467 window_text_bottom_y (w) - cursor_row->y);
26468
26469 /* If row is completely invisible, don't attempt to delete a cursor which
26470 isn't there. This can happen if cursor is at top of a window, and
26471 we switch to a buffer with a header line in that window. */
26472 if (cursor_row->visible_height <= 0)
26473 goto mark_cursor_off;
26474
26475 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26476 if (cursor_row->cursor_in_fringe_p)
26477 {
26478 cursor_row->cursor_in_fringe_p = 0;
26479 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26480 goto mark_cursor_off;
26481 }
26482
26483 /* This can happen when the new row is shorter than the old one.
26484 In this case, either draw_glyphs or clear_end_of_line
26485 should have cleared the cursor. Note that we wouldn't be
26486 able to erase the cursor in this case because we don't have a
26487 cursor glyph at hand. */
26488 if ((cursor_row->reversed_p
26489 ? (w->phys_cursor.hpos < 0)
26490 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26491 goto mark_cursor_off;
26492
26493 /* When the window is hscrolled, cursor hpos can legitimately be out
26494 of bounds, but we draw the cursor at the corresponding window
26495 margin in that case. */
26496 if (!cursor_row->reversed_p && hpos < 0)
26497 hpos = 0;
26498 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26499 hpos = cursor_row->used[TEXT_AREA] - 1;
26500
26501 /* If the cursor is in the mouse face area, redisplay that when
26502 we clear the cursor. */
26503 if (! NILP (hlinfo->mouse_face_window)
26504 && coords_in_mouse_face_p (w, hpos, vpos)
26505 /* Don't redraw the cursor's spot in mouse face if it is at the
26506 end of a line (on a newline). The cursor appears there, but
26507 mouse highlighting does not. */
26508 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26509 mouse_face_here_p = 1;
26510
26511 /* Maybe clear the display under the cursor. */
26512 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26513 {
26514 int x, y, left_x;
26515 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26516 int width;
26517
26518 cursor_glyph = get_phys_cursor_glyph (w);
26519 if (cursor_glyph == NULL)
26520 goto mark_cursor_off;
26521
26522 width = cursor_glyph->pixel_width;
26523 left_x = window_box_left_offset (w, TEXT_AREA);
26524 x = w->phys_cursor.x;
26525 if (x < left_x)
26526 width -= left_x - x;
26527 width = min (width, window_box_width (w, TEXT_AREA) - x);
26528 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26529 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26530
26531 if (width > 0)
26532 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26533 }
26534
26535 /* Erase the cursor by redrawing the character underneath it. */
26536 if (mouse_face_here_p)
26537 hl = DRAW_MOUSE_FACE;
26538 else
26539 hl = DRAW_NORMAL_TEXT;
26540 draw_phys_cursor_glyph (w, cursor_row, hl);
26541
26542 mark_cursor_off:
26543 w->phys_cursor_on_p = 0;
26544 w->phys_cursor_type = NO_CURSOR;
26545 }
26546
26547
26548 /* EXPORT:
26549 Display or clear cursor of window W. If ON is zero, clear the
26550 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26551 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26552
26553 void
26554 display_and_set_cursor (struct window *w, bool on,
26555 int hpos, int vpos, int x, int y)
26556 {
26557 struct frame *f = XFRAME (w->frame);
26558 int new_cursor_type;
26559 int new_cursor_width;
26560 int active_cursor;
26561 struct glyph_row *glyph_row;
26562 struct glyph *glyph;
26563
26564 /* This is pointless on invisible frames, and dangerous on garbaged
26565 windows and frames; in the latter case, the frame or window may
26566 be in the midst of changing its size, and x and y may be off the
26567 window. */
26568 if (! FRAME_VISIBLE_P (f)
26569 || FRAME_GARBAGED_P (f)
26570 || vpos >= w->current_matrix->nrows
26571 || hpos >= w->current_matrix->matrix_w)
26572 return;
26573
26574 /* If cursor is off and we want it off, return quickly. */
26575 if (!on && !w->phys_cursor_on_p)
26576 return;
26577
26578 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26579 /* If cursor row is not enabled, we don't really know where to
26580 display the cursor. */
26581 if (!glyph_row->enabled_p)
26582 {
26583 w->phys_cursor_on_p = 0;
26584 return;
26585 }
26586
26587 glyph = NULL;
26588 if (!glyph_row->exact_window_width_line_p
26589 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26590 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26591
26592 eassert (input_blocked_p ());
26593
26594 /* Set new_cursor_type to the cursor we want to be displayed. */
26595 new_cursor_type = get_window_cursor_type (w, glyph,
26596 &new_cursor_width, &active_cursor);
26597
26598 /* If cursor is currently being shown and we don't want it to be or
26599 it is in the wrong place, or the cursor type is not what we want,
26600 erase it. */
26601 if (w->phys_cursor_on_p
26602 && (!on
26603 || w->phys_cursor.x != x
26604 || w->phys_cursor.y != y
26605 || new_cursor_type != w->phys_cursor_type
26606 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26607 && new_cursor_width != w->phys_cursor_width)))
26608 erase_phys_cursor (w);
26609
26610 /* Don't check phys_cursor_on_p here because that flag is only set
26611 to zero in some cases where we know that the cursor has been
26612 completely erased, to avoid the extra work of erasing the cursor
26613 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26614 still not be visible, or it has only been partly erased. */
26615 if (on)
26616 {
26617 w->phys_cursor_ascent = glyph_row->ascent;
26618 w->phys_cursor_height = glyph_row->height;
26619
26620 /* Set phys_cursor_.* before x_draw_.* is called because some
26621 of them may need the information. */
26622 w->phys_cursor.x = x;
26623 w->phys_cursor.y = glyph_row->y;
26624 w->phys_cursor.hpos = hpos;
26625 w->phys_cursor.vpos = vpos;
26626 }
26627
26628 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26629 new_cursor_type, new_cursor_width,
26630 on, active_cursor);
26631 }
26632
26633
26634 /* Switch the display of W's cursor on or off, according to the value
26635 of ON. */
26636
26637 static void
26638 update_window_cursor (struct window *w, bool on)
26639 {
26640 /* Don't update cursor in windows whose frame is in the process
26641 of being deleted. */
26642 if (w->current_matrix)
26643 {
26644 int hpos = w->phys_cursor.hpos;
26645 int vpos = w->phys_cursor.vpos;
26646 struct glyph_row *row;
26647
26648 if (vpos >= w->current_matrix->nrows
26649 || hpos >= w->current_matrix->matrix_w)
26650 return;
26651
26652 row = MATRIX_ROW (w->current_matrix, vpos);
26653
26654 /* When the window is hscrolled, cursor hpos can legitimately be
26655 out of bounds, but we draw the cursor at the corresponding
26656 window margin in that case. */
26657 if (!row->reversed_p && hpos < 0)
26658 hpos = 0;
26659 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26660 hpos = row->used[TEXT_AREA] - 1;
26661
26662 block_input ();
26663 display_and_set_cursor (w, on, hpos, vpos,
26664 w->phys_cursor.x, w->phys_cursor.y);
26665 unblock_input ();
26666 }
26667 }
26668
26669
26670 /* Call update_window_cursor with parameter ON_P on all leaf windows
26671 in the window tree rooted at W. */
26672
26673 static void
26674 update_cursor_in_window_tree (struct window *w, bool on_p)
26675 {
26676 while (w)
26677 {
26678 if (WINDOWP (w->contents))
26679 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26680 else
26681 update_window_cursor (w, on_p);
26682
26683 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26684 }
26685 }
26686
26687
26688 /* EXPORT:
26689 Display the cursor on window W, or clear it, according to ON_P.
26690 Don't change the cursor's position. */
26691
26692 void
26693 x_update_cursor (struct frame *f, bool on_p)
26694 {
26695 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26696 }
26697
26698
26699 /* EXPORT:
26700 Clear the cursor of window W to background color, and mark the
26701 cursor as not shown. This is used when the text where the cursor
26702 is about to be rewritten. */
26703
26704 void
26705 x_clear_cursor (struct window *w)
26706 {
26707 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26708 update_window_cursor (w, 0);
26709 }
26710
26711 #endif /* HAVE_WINDOW_SYSTEM */
26712
26713 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26714 and MSDOS. */
26715 static void
26716 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26717 int start_hpos, int end_hpos,
26718 enum draw_glyphs_face draw)
26719 {
26720 #ifdef HAVE_WINDOW_SYSTEM
26721 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26722 {
26723 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26724 return;
26725 }
26726 #endif
26727 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26728 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26729 #endif
26730 }
26731
26732 /* Display the active region described by mouse_face_* according to DRAW. */
26733
26734 static void
26735 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26736 {
26737 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26738 struct frame *f = XFRAME (WINDOW_FRAME (w));
26739
26740 if (/* If window is in the process of being destroyed, don't bother
26741 to do anything. */
26742 w->current_matrix != NULL
26743 /* Don't update mouse highlight if hidden */
26744 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26745 /* Recognize when we are called to operate on rows that don't exist
26746 anymore. This can happen when a window is split. */
26747 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26748 {
26749 int phys_cursor_on_p = w->phys_cursor_on_p;
26750 struct glyph_row *row, *first, *last;
26751
26752 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26753 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26754
26755 for (row = first; row <= last && row->enabled_p; ++row)
26756 {
26757 int start_hpos, end_hpos, start_x;
26758
26759 /* For all but the first row, the highlight starts at column 0. */
26760 if (row == first)
26761 {
26762 /* R2L rows have BEG and END in reversed order, but the
26763 screen drawing geometry is always left to right. So
26764 we need to mirror the beginning and end of the
26765 highlighted area in R2L rows. */
26766 if (!row->reversed_p)
26767 {
26768 start_hpos = hlinfo->mouse_face_beg_col;
26769 start_x = hlinfo->mouse_face_beg_x;
26770 }
26771 else if (row == last)
26772 {
26773 start_hpos = hlinfo->mouse_face_end_col;
26774 start_x = hlinfo->mouse_face_end_x;
26775 }
26776 else
26777 {
26778 start_hpos = 0;
26779 start_x = 0;
26780 }
26781 }
26782 else if (row->reversed_p && row == last)
26783 {
26784 start_hpos = hlinfo->mouse_face_end_col;
26785 start_x = hlinfo->mouse_face_end_x;
26786 }
26787 else
26788 {
26789 start_hpos = 0;
26790 start_x = 0;
26791 }
26792
26793 if (row == last)
26794 {
26795 if (!row->reversed_p)
26796 end_hpos = hlinfo->mouse_face_end_col;
26797 else if (row == first)
26798 end_hpos = hlinfo->mouse_face_beg_col;
26799 else
26800 {
26801 end_hpos = row->used[TEXT_AREA];
26802 if (draw == DRAW_NORMAL_TEXT)
26803 row->fill_line_p = 1; /* Clear to end of line */
26804 }
26805 }
26806 else if (row->reversed_p && row == first)
26807 end_hpos = hlinfo->mouse_face_beg_col;
26808 else
26809 {
26810 end_hpos = row->used[TEXT_AREA];
26811 if (draw == DRAW_NORMAL_TEXT)
26812 row->fill_line_p = 1; /* Clear to end of line */
26813 }
26814
26815 if (end_hpos > start_hpos)
26816 {
26817 draw_row_with_mouse_face (w, start_x, row,
26818 start_hpos, end_hpos, draw);
26819
26820 row->mouse_face_p
26821 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26822 }
26823 }
26824
26825 #ifdef HAVE_WINDOW_SYSTEM
26826 /* When we've written over the cursor, arrange for it to
26827 be displayed again. */
26828 if (FRAME_WINDOW_P (f)
26829 && phys_cursor_on_p && !w->phys_cursor_on_p)
26830 {
26831 int hpos = w->phys_cursor.hpos;
26832
26833 /* When the window is hscrolled, cursor hpos can legitimately be
26834 out of bounds, but we draw the cursor at the corresponding
26835 window margin in that case. */
26836 if (!row->reversed_p && hpos < 0)
26837 hpos = 0;
26838 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26839 hpos = row->used[TEXT_AREA] - 1;
26840
26841 block_input ();
26842 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26843 w->phys_cursor.x, w->phys_cursor.y);
26844 unblock_input ();
26845 }
26846 #endif /* HAVE_WINDOW_SYSTEM */
26847 }
26848
26849 #ifdef HAVE_WINDOW_SYSTEM
26850 /* Change the mouse cursor. */
26851 if (FRAME_WINDOW_P (f))
26852 {
26853 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
26854 if (draw == DRAW_NORMAL_TEXT
26855 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26856 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26857 else
26858 #endif
26859 if (draw == DRAW_MOUSE_FACE)
26860 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26861 else
26862 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26863 }
26864 #endif /* HAVE_WINDOW_SYSTEM */
26865 }
26866
26867 /* EXPORT:
26868 Clear out the mouse-highlighted active region.
26869 Redraw it un-highlighted first. Value is non-zero if mouse
26870 face was actually drawn unhighlighted. */
26871
26872 int
26873 clear_mouse_face (Mouse_HLInfo *hlinfo)
26874 {
26875 int cleared = 0;
26876
26877 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26878 {
26879 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26880 cleared = 1;
26881 }
26882
26883 reset_mouse_highlight (hlinfo);
26884 return cleared;
26885 }
26886
26887 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26888 within the mouse face on that window. */
26889 static int
26890 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26891 {
26892 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26893
26894 /* Quickly resolve the easy cases. */
26895 if (!(WINDOWP (hlinfo->mouse_face_window)
26896 && XWINDOW (hlinfo->mouse_face_window) == w))
26897 return 0;
26898 if (vpos < hlinfo->mouse_face_beg_row
26899 || vpos > hlinfo->mouse_face_end_row)
26900 return 0;
26901 if (vpos > hlinfo->mouse_face_beg_row
26902 && vpos < hlinfo->mouse_face_end_row)
26903 return 1;
26904
26905 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26906 {
26907 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26908 {
26909 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26910 return 1;
26911 }
26912 else if ((vpos == hlinfo->mouse_face_beg_row
26913 && hpos >= hlinfo->mouse_face_beg_col)
26914 || (vpos == hlinfo->mouse_face_end_row
26915 && hpos < hlinfo->mouse_face_end_col))
26916 return 1;
26917 }
26918 else
26919 {
26920 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26921 {
26922 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26923 return 1;
26924 }
26925 else if ((vpos == hlinfo->mouse_face_beg_row
26926 && hpos <= hlinfo->mouse_face_beg_col)
26927 || (vpos == hlinfo->mouse_face_end_row
26928 && hpos > hlinfo->mouse_face_end_col))
26929 return 1;
26930 }
26931 return 0;
26932 }
26933
26934
26935 /* EXPORT:
26936 Non-zero if physical cursor of window W is within mouse face. */
26937
26938 int
26939 cursor_in_mouse_face_p (struct window *w)
26940 {
26941 int hpos = w->phys_cursor.hpos;
26942 int vpos = w->phys_cursor.vpos;
26943 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26944
26945 /* When the window is hscrolled, cursor hpos can legitimately be out
26946 of bounds, but we draw the cursor at the corresponding window
26947 margin in that case. */
26948 if (!row->reversed_p && hpos < 0)
26949 hpos = 0;
26950 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26951 hpos = row->used[TEXT_AREA] - 1;
26952
26953 return coords_in_mouse_face_p (w, hpos, vpos);
26954 }
26955
26956
26957 \f
26958 /* Find the glyph rows START_ROW and END_ROW of window W that display
26959 characters between buffer positions START_CHARPOS and END_CHARPOS
26960 (excluding END_CHARPOS). DISP_STRING is a display string that
26961 covers these buffer positions. This is similar to
26962 row_containing_pos, but is more accurate when bidi reordering makes
26963 buffer positions change non-linearly with glyph rows. */
26964 static void
26965 rows_from_pos_range (struct window *w,
26966 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26967 Lisp_Object disp_string,
26968 struct glyph_row **start, struct glyph_row **end)
26969 {
26970 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26971 int last_y = window_text_bottom_y (w);
26972 struct glyph_row *row;
26973
26974 *start = NULL;
26975 *end = NULL;
26976
26977 while (!first->enabled_p
26978 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26979 first++;
26980
26981 /* Find the START row. */
26982 for (row = first;
26983 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26984 row++)
26985 {
26986 /* A row can potentially be the START row if the range of the
26987 characters it displays intersects the range
26988 [START_CHARPOS..END_CHARPOS). */
26989 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26990 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26991 /* See the commentary in row_containing_pos, for the
26992 explanation of the complicated way to check whether
26993 some position is beyond the end of the characters
26994 displayed by a row. */
26995 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26996 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26997 && !row->ends_at_zv_p
26998 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26999 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
27000 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
27001 && !row->ends_at_zv_p
27002 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
27003 {
27004 /* Found a candidate row. Now make sure at least one of the
27005 glyphs it displays has a charpos from the range
27006 [START_CHARPOS..END_CHARPOS).
27007
27008 This is not obvious because bidi reordering could make
27009 buffer positions of a row be 1,2,3,102,101,100, and if we
27010 want to highlight characters in [50..60), we don't want
27011 this row, even though [50..60) does intersect [1..103),
27012 the range of character positions given by the row's start
27013 and end positions. */
27014 struct glyph *g = row->glyphs[TEXT_AREA];
27015 struct glyph *e = g + row->used[TEXT_AREA];
27016
27017 while (g < e)
27018 {
27019 if (((BUFFERP (g->object) || INTEGERP (g->object))
27020 && start_charpos <= g->charpos && g->charpos < end_charpos)
27021 /* A glyph that comes from DISP_STRING is by
27022 definition to be highlighted. */
27023 || EQ (g->object, disp_string))
27024 *start = row;
27025 g++;
27026 }
27027 if (*start)
27028 break;
27029 }
27030 }
27031
27032 /* Find the END row. */
27033 if (!*start
27034 /* If the last row is partially visible, start looking for END
27035 from that row, instead of starting from FIRST. */
27036 && !(row->enabled_p
27037 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
27038 row = first;
27039 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
27040 {
27041 struct glyph_row *next = row + 1;
27042 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
27043
27044 if (!next->enabled_p
27045 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
27046 /* The first row >= START whose range of displayed characters
27047 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
27048 is the row END + 1. */
27049 || (start_charpos < next_start
27050 && end_charpos < next_start)
27051 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
27052 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
27053 && !next->ends_at_zv_p
27054 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
27055 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
27056 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
27057 && !next->ends_at_zv_p
27058 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
27059 {
27060 *end = row;
27061 break;
27062 }
27063 else
27064 {
27065 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
27066 but none of the characters it displays are in the range, it is
27067 also END + 1. */
27068 struct glyph *g = next->glyphs[TEXT_AREA];
27069 struct glyph *s = g;
27070 struct glyph *e = g + next->used[TEXT_AREA];
27071
27072 while (g < e)
27073 {
27074 if (((BUFFERP (g->object) || INTEGERP (g->object))
27075 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
27076 /* If the buffer position of the first glyph in
27077 the row is equal to END_CHARPOS, it means
27078 the last character to be highlighted is the
27079 newline of ROW, and we must consider NEXT as
27080 END, not END+1. */
27081 || (((!next->reversed_p && g == s)
27082 || (next->reversed_p && g == e - 1))
27083 && (g->charpos == end_charpos
27084 /* Special case for when NEXT is an
27085 empty line at ZV. */
27086 || (g->charpos == -1
27087 && !row->ends_at_zv_p
27088 && next_start == end_charpos)))))
27089 /* A glyph that comes from DISP_STRING is by
27090 definition to be highlighted. */
27091 || EQ (g->object, disp_string))
27092 break;
27093 g++;
27094 }
27095 if (g == e)
27096 {
27097 *end = row;
27098 break;
27099 }
27100 /* The first row that ends at ZV must be the last to be
27101 highlighted. */
27102 else if (next->ends_at_zv_p)
27103 {
27104 *end = next;
27105 break;
27106 }
27107 }
27108 }
27109 }
27110
27111 /* This function sets the mouse_face_* elements of HLINFO, assuming
27112 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
27113 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
27114 for the overlay or run of text properties specifying the mouse
27115 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
27116 before-string and after-string that must also be highlighted.
27117 DISP_STRING, if non-nil, is a display string that may cover some
27118 or all of the highlighted text. */
27119
27120 static void
27121 mouse_face_from_buffer_pos (Lisp_Object window,
27122 Mouse_HLInfo *hlinfo,
27123 ptrdiff_t mouse_charpos,
27124 ptrdiff_t start_charpos,
27125 ptrdiff_t end_charpos,
27126 Lisp_Object before_string,
27127 Lisp_Object after_string,
27128 Lisp_Object disp_string)
27129 {
27130 struct window *w = XWINDOW (window);
27131 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27132 struct glyph_row *r1, *r2;
27133 struct glyph *glyph, *end;
27134 ptrdiff_t ignore, pos;
27135 int x;
27136
27137 eassert (NILP (disp_string) || STRINGP (disp_string));
27138 eassert (NILP (before_string) || STRINGP (before_string));
27139 eassert (NILP (after_string) || STRINGP (after_string));
27140
27141 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
27142 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
27143 if (r1 == NULL)
27144 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27145 /* If the before-string or display-string contains newlines,
27146 rows_from_pos_range skips to its last row. Move back. */
27147 if (!NILP (before_string) || !NILP (disp_string))
27148 {
27149 struct glyph_row *prev;
27150 while ((prev = r1 - 1, prev >= first)
27151 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
27152 && prev->used[TEXT_AREA] > 0)
27153 {
27154 struct glyph *beg = prev->glyphs[TEXT_AREA];
27155 glyph = beg + prev->used[TEXT_AREA];
27156 while (--glyph >= beg && INTEGERP (glyph->object));
27157 if (glyph < beg
27158 || !(EQ (glyph->object, before_string)
27159 || EQ (glyph->object, disp_string)))
27160 break;
27161 r1 = prev;
27162 }
27163 }
27164 if (r2 == NULL)
27165 {
27166 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27167 hlinfo->mouse_face_past_end = 1;
27168 }
27169 else if (!NILP (after_string))
27170 {
27171 /* If the after-string has newlines, advance to its last row. */
27172 struct glyph_row *next;
27173 struct glyph_row *last
27174 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27175
27176 for (next = r2 + 1;
27177 next <= last
27178 && next->used[TEXT_AREA] > 0
27179 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
27180 ++next)
27181 r2 = next;
27182 }
27183 /* The rest of the display engine assumes that mouse_face_beg_row is
27184 either above mouse_face_end_row or identical to it. But with
27185 bidi-reordered continued lines, the row for START_CHARPOS could
27186 be below the row for END_CHARPOS. If so, swap the rows and store
27187 them in correct order. */
27188 if (r1->y > r2->y)
27189 {
27190 struct glyph_row *tem = r2;
27191
27192 r2 = r1;
27193 r1 = tem;
27194 }
27195
27196 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27197 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27198
27199 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27200 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27201 could be anywhere in the row and in any order. The strategy
27202 below is to find the leftmost and the rightmost glyph that
27203 belongs to either of these 3 strings, or whose position is
27204 between START_CHARPOS and END_CHARPOS, and highlight all the
27205 glyphs between those two. This may cover more than just the text
27206 between START_CHARPOS and END_CHARPOS if the range of characters
27207 strides the bidi level boundary, e.g. if the beginning is in R2L
27208 text while the end is in L2R text or vice versa. */
27209 if (!r1->reversed_p)
27210 {
27211 /* This row is in a left to right paragraph. Scan it left to
27212 right. */
27213 glyph = r1->glyphs[TEXT_AREA];
27214 end = glyph + r1->used[TEXT_AREA];
27215 x = r1->x;
27216
27217 /* Skip truncation glyphs at the start of the glyph row. */
27218 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27219 for (; glyph < end
27220 && INTEGERP (glyph->object)
27221 && glyph->charpos < 0;
27222 ++glyph)
27223 x += glyph->pixel_width;
27224
27225 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27226 or DISP_STRING, and the first glyph from buffer whose
27227 position is between START_CHARPOS and END_CHARPOS. */
27228 for (; glyph < end
27229 && !INTEGERP (glyph->object)
27230 && !EQ (glyph->object, disp_string)
27231 && !(BUFFERP (glyph->object)
27232 && (glyph->charpos >= start_charpos
27233 && glyph->charpos < end_charpos));
27234 ++glyph)
27235 {
27236 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27237 are present at buffer positions between START_CHARPOS and
27238 END_CHARPOS, or if they come from an overlay. */
27239 if (EQ (glyph->object, before_string))
27240 {
27241 pos = string_buffer_position (before_string,
27242 start_charpos);
27243 /* If pos == 0, it means before_string came from an
27244 overlay, not from a buffer position. */
27245 if (!pos || (pos >= start_charpos && pos < end_charpos))
27246 break;
27247 }
27248 else if (EQ (glyph->object, after_string))
27249 {
27250 pos = string_buffer_position (after_string, end_charpos);
27251 if (!pos || (pos >= start_charpos && pos < end_charpos))
27252 break;
27253 }
27254 x += glyph->pixel_width;
27255 }
27256 hlinfo->mouse_face_beg_x = x;
27257 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27258 }
27259 else
27260 {
27261 /* This row is in a right to left paragraph. Scan it right to
27262 left. */
27263 struct glyph *g;
27264
27265 end = r1->glyphs[TEXT_AREA] - 1;
27266 glyph = end + r1->used[TEXT_AREA];
27267
27268 /* Skip truncation glyphs at the start of the glyph row. */
27269 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27270 for (; glyph > end
27271 && INTEGERP (glyph->object)
27272 && glyph->charpos < 0;
27273 --glyph)
27274 ;
27275
27276 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27277 or DISP_STRING, and the first glyph from buffer whose
27278 position is between START_CHARPOS and END_CHARPOS. */
27279 for (; glyph > end
27280 && !INTEGERP (glyph->object)
27281 && !EQ (glyph->object, disp_string)
27282 && !(BUFFERP (glyph->object)
27283 && (glyph->charpos >= start_charpos
27284 && glyph->charpos < end_charpos));
27285 --glyph)
27286 {
27287 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27288 are present at buffer positions between START_CHARPOS and
27289 END_CHARPOS, or if they come from an overlay. */
27290 if (EQ (glyph->object, before_string))
27291 {
27292 pos = string_buffer_position (before_string, start_charpos);
27293 /* If pos == 0, it means before_string came from an
27294 overlay, not from a buffer position. */
27295 if (!pos || (pos >= start_charpos && pos < end_charpos))
27296 break;
27297 }
27298 else if (EQ (glyph->object, after_string))
27299 {
27300 pos = string_buffer_position (after_string, end_charpos);
27301 if (!pos || (pos >= start_charpos && pos < end_charpos))
27302 break;
27303 }
27304 }
27305
27306 glyph++; /* first glyph to the right of the highlighted area */
27307 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27308 x += g->pixel_width;
27309 hlinfo->mouse_face_beg_x = x;
27310 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27311 }
27312
27313 /* If the highlight ends in a different row, compute GLYPH and END
27314 for the end row. Otherwise, reuse the values computed above for
27315 the row where the highlight begins. */
27316 if (r2 != r1)
27317 {
27318 if (!r2->reversed_p)
27319 {
27320 glyph = r2->glyphs[TEXT_AREA];
27321 end = glyph + r2->used[TEXT_AREA];
27322 x = r2->x;
27323 }
27324 else
27325 {
27326 end = r2->glyphs[TEXT_AREA] - 1;
27327 glyph = end + r2->used[TEXT_AREA];
27328 }
27329 }
27330
27331 if (!r2->reversed_p)
27332 {
27333 /* Skip truncation and continuation glyphs near the end of the
27334 row, and also blanks and stretch glyphs inserted by
27335 extend_face_to_end_of_line. */
27336 while (end > glyph
27337 && INTEGERP ((end - 1)->object))
27338 --end;
27339 /* Scan the rest of the glyph row from the end, looking for the
27340 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27341 DISP_STRING, or whose position is between START_CHARPOS
27342 and END_CHARPOS */
27343 for (--end;
27344 end > glyph
27345 && !INTEGERP (end->object)
27346 && !EQ (end->object, disp_string)
27347 && !(BUFFERP (end->object)
27348 && (end->charpos >= start_charpos
27349 && end->charpos < end_charpos));
27350 --end)
27351 {
27352 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27353 are present at buffer positions between START_CHARPOS and
27354 END_CHARPOS, or if they come from an overlay. */
27355 if (EQ (end->object, before_string))
27356 {
27357 pos = string_buffer_position (before_string, start_charpos);
27358 if (!pos || (pos >= start_charpos && pos < end_charpos))
27359 break;
27360 }
27361 else if (EQ (end->object, after_string))
27362 {
27363 pos = string_buffer_position (after_string, end_charpos);
27364 if (!pos || (pos >= start_charpos && pos < end_charpos))
27365 break;
27366 }
27367 }
27368 /* Find the X coordinate of the last glyph to be highlighted. */
27369 for (; glyph <= end; ++glyph)
27370 x += glyph->pixel_width;
27371
27372 hlinfo->mouse_face_end_x = x;
27373 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27374 }
27375 else
27376 {
27377 /* Skip truncation and continuation glyphs near the end of the
27378 row, and also blanks and stretch glyphs inserted by
27379 extend_face_to_end_of_line. */
27380 x = r2->x;
27381 end++;
27382 while (end < glyph
27383 && INTEGERP (end->object))
27384 {
27385 x += end->pixel_width;
27386 ++end;
27387 }
27388 /* Scan the rest of the glyph row from the end, looking for the
27389 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27390 DISP_STRING, or whose position is between START_CHARPOS
27391 and END_CHARPOS */
27392 for ( ;
27393 end < glyph
27394 && !INTEGERP (end->object)
27395 && !EQ (end->object, disp_string)
27396 && !(BUFFERP (end->object)
27397 && (end->charpos >= start_charpos
27398 && end->charpos < end_charpos));
27399 ++end)
27400 {
27401 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27402 are present at buffer positions between START_CHARPOS and
27403 END_CHARPOS, or if they come from an overlay. */
27404 if (EQ (end->object, before_string))
27405 {
27406 pos = string_buffer_position (before_string, start_charpos);
27407 if (!pos || (pos >= start_charpos && pos < end_charpos))
27408 break;
27409 }
27410 else if (EQ (end->object, after_string))
27411 {
27412 pos = string_buffer_position (after_string, end_charpos);
27413 if (!pos || (pos >= start_charpos && pos < end_charpos))
27414 break;
27415 }
27416 x += end->pixel_width;
27417 }
27418 /* If we exited the above loop because we arrived at the last
27419 glyph of the row, and its buffer position is still not in
27420 range, it means the last character in range is the preceding
27421 newline. Bump the end column and x values to get past the
27422 last glyph. */
27423 if (end == glyph
27424 && BUFFERP (end->object)
27425 && (end->charpos < start_charpos
27426 || end->charpos >= end_charpos))
27427 {
27428 x += end->pixel_width;
27429 ++end;
27430 }
27431 hlinfo->mouse_face_end_x = x;
27432 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27433 }
27434
27435 hlinfo->mouse_face_window = window;
27436 hlinfo->mouse_face_face_id
27437 = face_at_buffer_position (w, mouse_charpos, &ignore,
27438 mouse_charpos + 1,
27439 !hlinfo->mouse_face_hidden, -1);
27440 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27441 }
27442
27443 /* The following function is not used anymore (replaced with
27444 mouse_face_from_string_pos), but I leave it here for the time
27445 being, in case someone would. */
27446
27447 #if 0 /* not used */
27448
27449 /* Find the position of the glyph for position POS in OBJECT in
27450 window W's current matrix, and return in *X, *Y the pixel
27451 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27452
27453 RIGHT_P non-zero means return the position of the right edge of the
27454 glyph, RIGHT_P zero means return the left edge position.
27455
27456 If no glyph for POS exists in the matrix, return the position of
27457 the glyph with the next smaller position that is in the matrix, if
27458 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27459 exists in the matrix, return the position of the glyph with the
27460 next larger position in OBJECT.
27461
27462 Value is non-zero if a glyph was found. */
27463
27464 static int
27465 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27466 int *hpos, int *vpos, int *x, int *y, int right_p)
27467 {
27468 int yb = window_text_bottom_y (w);
27469 struct glyph_row *r;
27470 struct glyph *best_glyph = NULL;
27471 struct glyph_row *best_row = NULL;
27472 int best_x = 0;
27473
27474 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27475 r->enabled_p && r->y < yb;
27476 ++r)
27477 {
27478 struct glyph *g = r->glyphs[TEXT_AREA];
27479 struct glyph *e = g + r->used[TEXT_AREA];
27480 int gx;
27481
27482 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27483 if (EQ (g->object, object))
27484 {
27485 if (g->charpos == pos)
27486 {
27487 best_glyph = g;
27488 best_x = gx;
27489 best_row = r;
27490 goto found;
27491 }
27492 else if (best_glyph == NULL
27493 || ((eabs (g->charpos - pos)
27494 < eabs (best_glyph->charpos - pos))
27495 && (right_p
27496 ? g->charpos < pos
27497 : g->charpos > pos)))
27498 {
27499 best_glyph = g;
27500 best_x = gx;
27501 best_row = r;
27502 }
27503 }
27504 }
27505
27506 found:
27507
27508 if (best_glyph)
27509 {
27510 *x = best_x;
27511 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27512
27513 if (right_p)
27514 {
27515 *x += best_glyph->pixel_width;
27516 ++*hpos;
27517 }
27518
27519 *y = best_row->y;
27520 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
27521 }
27522
27523 return best_glyph != NULL;
27524 }
27525 #endif /* not used */
27526
27527 /* Find the positions of the first and the last glyphs in window W's
27528 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
27529 (assumed to be a string), and return in HLINFO's mouse_face_*
27530 members the pixel and column/row coordinates of those glyphs. */
27531
27532 static void
27533 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27534 Lisp_Object object,
27535 ptrdiff_t startpos, ptrdiff_t endpos)
27536 {
27537 int yb = window_text_bottom_y (w);
27538 struct glyph_row *r;
27539 struct glyph *g, *e;
27540 int gx;
27541 int found = 0;
27542
27543 /* Find the glyph row with at least one position in the range
27544 [STARTPOS..ENDPOS), and the first glyph in that row whose
27545 position belongs to that range. */
27546 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27547 r->enabled_p && r->y < yb;
27548 ++r)
27549 {
27550 if (!r->reversed_p)
27551 {
27552 g = r->glyphs[TEXT_AREA];
27553 e = g + r->used[TEXT_AREA];
27554 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27555 if (EQ (g->object, object)
27556 && startpos <= g->charpos && g->charpos < endpos)
27557 {
27558 hlinfo->mouse_face_beg_row
27559 = MATRIX_ROW_VPOS (r, w->current_matrix);
27560 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27561 hlinfo->mouse_face_beg_x = gx;
27562 found = 1;
27563 break;
27564 }
27565 }
27566 else
27567 {
27568 struct glyph *g1;
27569
27570 e = r->glyphs[TEXT_AREA];
27571 g = e + r->used[TEXT_AREA];
27572 for ( ; g > e; --g)
27573 if (EQ ((g-1)->object, object)
27574 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
27575 {
27576 hlinfo->mouse_face_beg_row
27577 = MATRIX_ROW_VPOS (r, w->current_matrix);
27578 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27579 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27580 gx += g1->pixel_width;
27581 hlinfo->mouse_face_beg_x = gx;
27582 found = 1;
27583 break;
27584 }
27585 }
27586 if (found)
27587 break;
27588 }
27589
27590 if (!found)
27591 return;
27592
27593 /* Starting with the next row, look for the first row which does NOT
27594 include any glyphs whose positions are in the range. */
27595 for (++r; r->enabled_p && r->y < yb; ++r)
27596 {
27597 g = r->glyphs[TEXT_AREA];
27598 e = g + r->used[TEXT_AREA];
27599 found = 0;
27600 for ( ; g < e; ++g)
27601 if (EQ (g->object, object)
27602 && startpos <= g->charpos && g->charpos < endpos)
27603 {
27604 found = 1;
27605 break;
27606 }
27607 if (!found)
27608 break;
27609 }
27610
27611 /* The highlighted region ends on the previous row. */
27612 r--;
27613
27614 /* Set the end row. */
27615 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27616
27617 /* Compute and set the end column and the end column's horizontal
27618 pixel coordinate. */
27619 if (!r->reversed_p)
27620 {
27621 g = r->glyphs[TEXT_AREA];
27622 e = g + r->used[TEXT_AREA];
27623 for ( ; e > g; --e)
27624 if (EQ ((e-1)->object, object)
27625 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
27626 break;
27627 hlinfo->mouse_face_end_col = e - g;
27628
27629 for (gx = r->x; g < e; ++g)
27630 gx += g->pixel_width;
27631 hlinfo->mouse_face_end_x = gx;
27632 }
27633 else
27634 {
27635 e = r->glyphs[TEXT_AREA];
27636 g = e + r->used[TEXT_AREA];
27637 for (gx = r->x ; e < g; ++e)
27638 {
27639 if (EQ (e->object, object)
27640 && startpos <= e->charpos && e->charpos < endpos)
27641 break;
27642 gx += e->pixel_width;
27643 }
27644 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27645 hlinfo->mouse_face_end_x = gx;
27646 }
27647 }
27648
27649 #ifdef HAVE_WINDOW_SYSTEM
27650
27651 /* See if position X, Y is within a hot-spot of an image. */
27652
27653 static int
27654 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27655 {
27656 if (!CONSP (hot_spot))
27657 return 0;
27658
27659 if (EQ (XCAR (hot_spot), Qrect))
27660 {
27661 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27662 Lisp_Object rect = XCDR (hot_spot);
27663 Lisp_Object tem;
27664 if (!CONSP (rect))
27665 return 0;
27666 if (!CONSP (XCAR (rect)))
27667 return 0;
27668 if (!CONSP (XCDR (rect)))
27669 return 0;
27670 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27671 return 0;
27672 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27673 return 0;
27674 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27675 return 0;
27676 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27677 return 0;
27678 return 1;
27679 }
27680 else if (EQ (XCAR (hot_spot), Qcircle))
27681 {
27682 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27683 Lisp_Object circ = XCDR (hot_spot);
27684 Lisp_Object lr, lx0, ly0;
27685 if (CONSP (circ)
27686 && CONSP (XCAR (circ))
27687 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27688 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27689 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27690 {
27691 double r = XFLOATINT (lr);
27692 double dx = XINT (lx0) - x;
27693 double dy = XINT (ly0) - y;
27694 return (dx * dx + dy * dy <= r * r);
27695 }
27696 }
27697 else if (EQ (XCAR (hot_spot), Qpoly))
27698 {
27699 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27700 if (VECTORP (XCDR (hot_spot)))
27701 {
27702 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27703 Lisp_Object *poly = v->contents;
27704 ptrdiff_t n = v->header.size;
27705 ptrdiff_t i;
27706 int inside = 0;
27707 Lisp_Object lx, ly;
27708 int x0, y0;
27709
27710 /* Need an even number of coordinates, and at least 3 edges. */
27711 if (n < 6 || n & 1)
27712 return 0;
27713
27714 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27715 If count is odd, we are inside polygon. Pixels on edges
27716 may or may not be included depending on actual geometry of the
27717 polygon. */
27718 if ((lx = poly[n-2], !INTEGERP (lx))
27719 || (ly = poly[n-1], !INTEGERP (lx)))
27720 return 0;
27721 x0 = XINT (lx), y0 = XINT (ly);
27722 for (i = 0; i < n; i += 2)
27723 {
27724 int x1 = x0, y1 = y0;
27725 if ((lx = poly[i], !INTEGERP (lx))
27726 || (ly = poly[i+1], !INTEGERP (ly)))
27727 return 0;
27728 x0 = XINT (lx), y0 = XINT (ly);
27729
27730 /* Does this segment cross the X line? */
27731 if (x0 >= x)
27732 {
27733 if (x1 >= x)
27734 continue;
27735 }
27736 else if (x1 < x)
27737 continue;
27738 if (y > y0 && y > y1)
27739 continue;
27740 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27741 inside = !inside;
27742 }
27743 return inside;
27744 }
27745 }
27746 return 0;
27747 }
27748
27749 Lisp_Object
27750 find_hot_spot (Lisp_Object map, int x, int y)
27751 {
27752 while (CONSP (map))
27753 {
27754 if (CONSP (XCAR (map))
27755 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27756 return XCAR (map);
27757 map = XCDR (map);
27758 }
27759
27760 return Qnil;
27761 }
27762
27763 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27764 3, 3, 0,
27765 doc: /* Lookup in image map MAP coordinates X and Y.
27766 An image map is an alist where each element has the format (AREA ID PLIST).
27767 An AREA is specified as either a rectangle, a circle, or a polygon:
27768 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27769 pixel coordinates of the upper left and bottom right corners.
27770 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27771 and the radius of the circle; r may be a float or integer.
27772 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27773 vector describes one corner in the polygon.
27774 Returns the alist element for the first matching AREA in MAP. */)
27775 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27776 {
27777 if (NILP (map))
27778 return Qnil;
27779
27780 CHECK_NUMBER (x);
27781 CHECK_NUMBER (y);
27782
27783 return find_hot_spot (map,
27784 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27785 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27786 }
27787
27788
27789 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27790 static void
27791 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27792 {
27793 /* Do not change cursor shape while dragging mouse. */
27794 if (!NILP (do_mouse_tracking))
27795 return;
27796
27797 if (!NILP (pointer))
27798 {
27799 if (EQ (pointer, Qarrow))
27800 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27801 else if (EQ (pointer, Qhand))
27802 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27803 else if (EQ (pointer, Qtext))
27804 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27805 else if (EQ (pointer, intern ("hdrag")))
27806 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27807 #ifdef HAVE_X_WINDOWS
27808 else if (EQ (pointer, intern ("vdrag")))
27809 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27810 #endif
27811 else if (EQ (pointer, intern ("hourglass")))
27812 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27813 else if (EQ (pointer, Qmodeline))
27814 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27815 else
27816 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27817 }
27818
27819 if (cursor != No_Cursor)
27820 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27821 }
27822
27823 #endif /* HAVE_WINDOW_SYSTEM */
27824
27825 /* Take proper action when mouse has moved to the mode or header line
27826 or marginal area AREA of window W, x-position X and y-position Y.
27827 X is relative to the start of the text display area of W, so the
27828 width of bitmap areas and scroll bars must be subtracted to get a
27829 position relative to the start of the mode line. */
27830
27831 static void
27832 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27833 enum window_part area)
27834 {
27835 struct window *w = XWINDOW (window);
27836 struct frame *f = XFRAME (w->frame);
27837 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27838 #ifdef HAVE_WINDOW_SYSTEM
27839 Display_Info *dpyinfo;
27840 #endif
27841 Cursor cursor = No_Cursor;
27842 Lisp_Object pointer = Qnil;
27843 int dx, dy, width, height;
27844 ptrdiff_t charpos;
27845 Lisp_Object string, object = Qnil;
27846 Lisp_Object pos IF_LINT (= Qnil), help;
27847
27848 Lisp_Object mouse_face;
27849 int original_x_pixel = x;
27850 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27851 struct glyph_row *row IF_LINT (= 0);
27852
27853 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27854 {
27855 int x0;
27856 struct glyph *end;
27857
27858 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27859 returns them in row/column units! */
27860 string = mode_line_string (w, area, &x, &y, &charpos,
27861 &object, &dx, &dy, &width, &height);
27862
27863 row = (area == ON_MODE_LINE
27864 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27865 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27866
27867 /* Find the glyph under the mouse pointer. */
27868 if (row->mode_line_p && row->enabled_p)
27869 {
27870 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27871 end = glyph + row->used[TEXT_AREA];
27872
27873 for (x0 = original_x_pixel;
27874 glyph < end && x0 >= glyph->pixel_width;
27875 ++glyph)
27876 x0 -= glyph->pixel_width;
27877
27878 if (glyph >= end)
27879 glyph = NULL;
27880 }
27881 }
27882 else
27883 {
27884 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27885 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27886 returns them in row/column units! */
27887 string = marginal_area_string (w, area, &x, &y, &charpos,
27888 &object, &dx, &dy, &width, &height);
27889 }
27890
27891 help = Qnil;
27892
27893 #ifdef HAVE_WINDOW_SYSTEM
27894 if (IMAGEP (object))
27895 {
27896 Lisp_Object image_map, hotspot;
27897 if ((image_map = Fplist_get (XCDR (object), QCmap),
27898 !NILP (image_map))
27899 && (hotspot = find_hot_spot (image_map, dx, dy),
27900 CONSP (hotspot))
27901 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27902 {
27903 Lisp_Object plist;
27904
27905 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27906 If so, we could look for mouse-enter, mouse-leave
27907 properties in PLIST (and do something...). */
27908 hotspot = XCDR (hotspot);
27909 if (CONSP (hotspot)
27910 && (plist = XCAR (hotspot), CONSP (plist)))
27911 {
27912 pointer = Fplist_get (plist, Qpointer);
27913 if (NILP (pointer))
27914 pointer = Qhand;
27915 help = Fplist_get (plist, Qhelp_echo);
27916 if (!NILP (help))
27917 {
27918 help_echo_string = help;
27919 XSETWINDOW (help_echo_window, w);
27920 help_echo_object = w->contents;
27921 help_echo_pos = charpos;
27922 }
27923 }
27924 }
27925 if (NILP (pointer))
27926 pointer = Fplist_get (XCDR (object), QCpointer);
27927 }
27928 #endif /* HAVE_WINDOW_SYSTEM */
27929
27930 if (STRINGP (string))
27931 pos = make_number (charpos);
27932
27933 /* Set the help text and mouse pointer. If the mouse is on a part
27934 of the mode line without any text (e.g. past the right edge of
27935 the mode line text), use the default help text and pointer. */
27936 if (STRINGP (string) || area == ON_MODE_LINE)
27937 {
27938 /* Arrange to display the help by setting the global variables
27939 help_echo_string, help_echo_object, and help_echo_pos. */
27940 if (NILP (help))
27941 {
27942 if (STRINGP (string))
27943 help = Fget_text_property (pos, Qhelp_echo, string);
27944
27945 if (!NILP (help))
27946 {
27947 help_echo_string = help;
27948 XSETWINDOW (help_echo_window, w);
27949 help_echo_object = string;
27950 help_echo_pos = charpos;
27951 }
27952 else if (area == ON_MODE_LINE)
27953 {
27954 Lisp_Object default_help
27955 = buffer_local_value_1 (Qmode_line_default_help_echo,
27956 w->contents);
27957
27958 if (STRINGP (default_help))
27959 {
27960 help_echo_string = default_help;
27961 XSETWINDOW (help_echo_window, w);
27962 help_echo_object = Qnil;
27963 help_echo_pos = -1;
27964 }
27965 }
27966 }
27967
27968 #ifdef HAVE_WINDOW_SYSTEM
27969 /* Change the mouse pointer according to what is under it. */
27970 if (FRAME_WINDOW_P (f))
27971 {
27972 dpyinfo = FRAME_DISPLAY_INFO (f);
27973 if (STRINGP (string))
27974 {
27975 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27976
27977 if (NILP (pointer))
27978 pointer = Fget_text_property (pos, Qpointer, string);
27979
27980 /* Change the mouse pointer according to what is under X/Y. */
27981 if (NILP (pointer)
27982 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27983 {
27984 Lisp_Object map;
27985 map = Fget_text_property (pos, Qlocal_map, string);
27986 if (!KEYMAPP (map))
27987 map = Fget_text_property (pos, Qkeymap, string);
27988 if (!KEYMAPP (map))
27989 cursor = dpyinfo->vertical_scroll_bar_cursor;
27990 }
27991 }
27992 else
27993 /* Default mode-line pointer. */
27994 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27995 }
27996 #endif
27997 }
27998
27999 /* Change the mouse face according to what is under X/Y. */
28000 if (STRINGP (string))
28001 {
28002 mouse_face = Fget_text_property (pos, Qmouse_face, string);
28003 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
28004 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28005 && glyph)
28006 {
28007 Lisp_Object b, e;
28008
28009 struct glyph * tmp_glyph;
28010
28011 int gpos;
28012 int gseq_length;
28013 int total_pixel_width;
28014 ptrdiff_t begpos, endpos, ignore;
28015
28016 int vpos, hpos;
28017
28018 b = Fprevious_single_property_change (make_number (charpos + 1),
28019 Qmouse_face, string, Qnil);
28020 if (NILP (b))
28021 begpos = 0;
28022 else
28023 begpos = XINT (b);
28024
28025 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
28026 if (NILP (e))
28027 endpos = SCHARS (string);
28028 else
28029 endpos = XINT (e);
28030
28031 /* Calculate the glyph position GPOS of GLYPH in the
28032 displayed string, relative to the beginning of the
28033 highlighted part of the string.
28034
28035 Note: GPOS is different from CHARPOS. CHARPOS is the
28036 position of GLYPH in the internal string object. A mode
28037 line string format has structures which are converted to
28038 a flattened string by the Emacs Lisp interpreter. The
28039 internal string is an element of those structures. The
28040 displayed string is the flattened string. */
28041 tmp_glyph = row_start_glyph;
28042 while (tmp_glyph < glyph
28043 && (!(EQ (tmp_glyph->object, glyph->object)
28044 && begpos <= tmp_glyph->charpos
28045 && tmp_glyph->charpos < endpos)))
28046 tmp_glyph++;
28047 gpos = glyph - tmp_glyph;
28048
28049 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
28050 the highlighted part of the displayed string to which
28051 GLYPH belongs. Note: GSEQ_LENGTH is different from
28052 SCHARS (STRING), because the latter returns the length of
28053 the internal string. */
28054 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
28055 tmp_glyph > glyph
28056 && (!(EQ (tmp_glyph->object, glyph->object)
28057 && begpos <= tmp_glyph->charpos
28058 && tmp_glyph->charpos < endpos));
28059 tmp_glyph--)
28060 ;
28061 gseq_length = gpos + (tmp_glyph - glyph) + 1;
28062
28063 /* Calculate the total pixel width of all the glyphs between
28064 the beginning of the highlighted area and GLYPH. */
28065 total_pixel_width = 0;
28066 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
28067 total_pixel_width += tmp_glyph->pixel_width;
28068
28069 /* Pre calculation of re-rendering position. Note: X is in
28070 column units here, after the call to mode_line_string or
28071 marginal_area_string. */
28072 hpos = x - gpos;
28073 vpos = (area == ON_MODE_LINE
28074 ? (w->current_matrix)->nrows - 1
28075 : 0);
28076
28077 /* If GLYPH's position is included in the region that is
28078 already drawn in mouse face, we have nothing to do. */
28079 if ( EQ (window, hlinfo->mouse_face_window)
28080 && (!row->reversed_p
28081 ? (hlinfo->mouse_face_beg_col <= hpos
28082 && hpos < hlinfo->mouse_face_end_col)
28083 /* In R2L rows we swap BEG and END, see below. */
28084 : (hlinfo->mouse_face_end_col <= hpos
28085 && hpos < hlinfo->mouse_face_beg_col))
28086 && hlinfo->mouse_face_beg_row == vpos )
28087 return;
28088
28089 if (clear_mouse_face (hlinfo))
28090 cursor = No_Cursor;
28091
28092 if (!row->reversed_p)
28093 {
28094 hlinfo->mouse_face_beg_col = hpos;
28095 hlinfo->mouse_face_beg_x = original_x_pixel
28096 - (total_pixel_width + dx);
28097 hlinfo->mouse_face_end_col = hpos + gseq_length;
28098 hlinfo->mouse_face_end_x = 0;
28099 }
28100 else
28101 {
28102 /* In R2L rows, show_mouse_face expects BEG and END
28103 coordinates to be swapped. */
28104 hlinfo->mouse_face_end_col = hpos;
28105 hlinfo->mouse_face_end_x = original_x_pixel
28106 - (total_pixel_width + dx);
28107 hlinfo->mouse_face_beg_col = hpos + gseq_length;
28108 hlinfo->mouse_face_beg_x = 0;
28109 }
28110
28111 hlinfo->mouse_face_beg_row = vpos;
28112 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
28113 hlinfo->mouse_face_past_end = 0;
28114 hlinfo->mouse_face_window = window;
28115
28116 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
28117 charpos,
28118 0, &ignore,
28119 glyph->face_id,
28120 1);
28121 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28122
28123 if (NILP (pointer))
28124 pointer = Qhand;
28125 }
28126 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28127 clear_mouse_face (hlinfo);
28128 }
28129 #ifdef HAVE_WINDOW_SYSTEM
28130 if (FRAME_WINDOW_P (f))
28131 define_frame_cursor1 (f, cursor, pointer);
28132 #endif
28133 }
28134
28135
28136 /* EXPORT:
28137 Take proper action when the mouse has moved to position X, Y on
28138 frame F with regards to highlighting portions of display that have
28139 mouse-face properties. Also de-highlight portions of display where
28140 the mouse was before, set the mouse pointer shape as appropriate
28141 for the mouse coordinates, and activate help echo (tooltips).
28142 X and Y can be negative or out of range. */
28143
28144 void
28145 note_mouse_highlight (struct frame *f, int x, int y)
28146 {
28147 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28148 enum window_part part = ON_NOTHING;
28149 Lisp_Object window;
28150 struct window *w;
28151 Cursor cursor = No_Cursor;
28152 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
28153 struct buffer *b;
28154
28155 /* When a menu is active, don't highlight because this looks odd. */
28156 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28157 if (popup_activated ())
28158 return;
28159 #endif
28160
28161 if (!f->glyphs_initialized_p
28162 || f->pointer_invisible)
28163 return;
28164
28165 hlinfo->mouse_face_mouse_x = x;
28166 hlinfo->mouse_face_mouse_y = y;
28167 hlinfo->mouse_face_mouse_frame = f;
28168
28169 if (hlinfo->mouse_face_defer)
28170 return;
28171
28172 /* Which window is that in? */
28173 window = window_from_coordinates (f, x, y, &part, 1);
28174
28175 /* If displaying active text in another window, clear that. */
28176 if (! EQ (window, hlinfo->mouse_face_window)
28177 /* Also clear if we move out of text area in same window. */
28178 || (!NILP (hlinfo->mouse_face_window)
28179 && !NILP (window)
28180 && part != ON_TEXT
28181 && part != ON_MODE_LINE
28182 && part != ON_HEADER_LINE))
28183 clear_mouse_face (hlinfo);
28184
28185 /* Not on a window -> return. */
28186 if (!WINDOWP (window))
28187 return;
28188
28189 /* Reset help_echo_string. It will get recomputed below. */
28190 help_echo_string = Qnil;
28191
28192 /* Convert to window-relative pixel coordinates. */
28193 w = XWINDOW (window);
28194 frame_to_window_pixel_xy (w, &x, &y);
28195
28196 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
28197 /* Handle tool-bar window differently since it doesn't display a
28198 buffer. */
28199 if (EQ (window, f->tool_bar_window))
28200 {
28201 note_tool_bar_highlight (f, x, y);
28202 return;
28203 }
28204 #endif
28205
28206 /* Mouse is on the mode, header line or margin? */
28207 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
28208 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
28209 {
28210 note_mode_line_or_margin_highlight (window, x, y, part);
28211 return;
28212 }
28213
28214 #ifdef HAVE_WINDOW_SYSTEM
28215 if (part == ON_VERTICAL_BORDER)
28216 {
28217 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28218 help_echo_string = build_string ("drag-mouse-1: resize");
28219 }
28220 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28221 || part == ON_SCROLL_BAR)
28222 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28223 else
28224 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28225 #endif
28226
28227 /* Are we in a window whose display is up to date?
28228 And verify the buffer's text has not changed. */
28229 b = XBUFFER (w->contents);
28230 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28231 {
28232 int hpos, vpos, dx, dy, area = LAST_AREA;
28233 ptrdiff_t pos;
28234 struct glyph *glyph;
28235 Lisp_Object object;
28236 Lisp_Object mouse_face = Qnil, position;
28237 Lisp_Object *overlay_vec = NULL;
28238 ptrdiff_t i, noverlays;
28239 struct buffer *obuf;
28240 ptrdiff_t obegv, ozv;
28241 int same_region;
28242
28243 /* Find the glyph under X/Y. */
28244 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
28245
28246 #ifdef HAVE_WINDOW_SYSTEM
28247 /* Look for :pointer property on image. */
28248 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28249 {
28250 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
28251 if (img != NULL && IMAGEP (img->spec))
28252 {
28253 Lisp_Object image_map, hotspot;
28254 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
28255 !NILP (image_map))
28256 && (hotspot = find_hot_spot (image_map,
28257 glyph->slice.img.x + dx,
28258 glyph->slice.img.y + dy),
28259 CONSP (hotspot))
28260 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28261 {
28262 Lisp_Object plist;
28263
28264 /* Could check XCAR (hotspot) to see if we enter/leave
28265 this hot-spot.
28266 If so, we could look for mouse-enter, mouse-leave
28267 properties in PLIST (and do something...). */
28268 hotspot = XCDR (hotspot);
28269 if (CONSP (hotspot)
28270 && (plist = XCAR (hotspot), CONSP (plist)))
28271 {
28272 pointer = Fplist_get (plist, Qpointer);
28273 if (NILP (pointer))
28274 pointer = Qhand;
28275 help_echo_string = Fplist_get (plist, Qhelp_echo);
28276 if (!NILP (help_echo_string))
28277 {
28278 help_echo_window = window;
28279 help_echo_object = glyph->object;
28280 help_echo_pos = glyph->charpos;
28281 }
28282 }
28283 }
28284 if (NILP (pointer))
28285 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28286 }
28287 }
28288 #endif /* HAVE_WINDOW_SYSTEM */
28289
28290 /* Clear mouse face if X/Y not over text. */
28291 if (glyph == NULL
28292 || area != TEXT_AREA
28293 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
28294 /* Glyph's OBJECT is an integer for glyphs inserted by the
28295 display engine for its internal purposes, like truncation
28296 and continuation glyphs and blanks beyond the end of
28297 line's text on text terminals. If we are over such a
28298 glyph, we are not over any text. */
28299 || INTEGERP (glyph->object)
28300 /* R2L rows have a stretch glyph at their front, which
28301 stands for no text, whereas L2R rows have no glyphs at
28302 all beyond the end of text. Treat such stretch glyphs
28303 like we do with NULL glyphs in L2R rows. */
28304 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28305 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
28306 && glyph->type == STRETCH_GLYPH
28307 && glyph->avoid_cursor_p))
28308 {
28309 if (clear_mouse_face (hlinfo))
28310 cursor = No_Cursor;
28311 #ifdef HAVE_WINDOW_SYSTEM
28312 if (FRAME_WINDOW_P (f) && NILP (pointer))
28313 {
28314 if (area != TEXT_AREA)
28315 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28316 else
28317 pointer = Vvoid_text_area_pointer;
28318 }
28319 #endif
28320 goto set_cursor;
28321 }
28322
28323 pos = glyph->charpos;
28324 object = glyph->object;
28325 if (!STRINGP (object) && !BUFFERP (object))
28326 goto set_cursor;
28327
28328 /* If we get an out-of-range value, return now; avoid an error. */
28329 if (BUFFERP (object) && pos > BUF_Z (b))
28330 goto set_cursor;
28331
28332 /* Make the window's buffer temporarily current for
28333 overlays_at and compute_char_face. */
28334 obuf = current_buffer;
28335 current_buffer = b;
28336 obegv = BEGV;
28337 ozv = ZV;
28338 BEGV = BEG;
28339 ZV = Z;
28340
28341 /* Is this char mouse-active or does it have help-echo? */
28342 position = make_number (pos);
28343
28344 if (BUFFERP (object))
28345 {
28346 /* Put all the overlays we want in a vector in overlay_vec. */
28347 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28348 /* Sort overlays into increasing priority order. */
28349 noverlays = sort_overlays (overlay_vec, noverlays, w);
28350 }
28351 else
28352 noverlays = 0;
28353
28354 if (NILP (Vmouse_highlight))
28355 {
28356 clear_mouse_face (hlinfo);
28357 goto check_help_echo;
28358 }
28359
28360 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28361
28362 if (same_region)
28363 cursor = No_Cursor;
28364
28365 /* Check mouse-face highlighting. */
28366 if (! same_region
28367 /* If there exists an overlay with mouse-face overlapping
28368 the one we are currently highlighting, we have to
28369 check if we enter the overlapping overlay, and then
28370 highlight only that. */
28371 || (OVERLAYP (hlinfo->mouse_face_overlay)
28372 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28373 {
28374 /* Find the highest priority overlay with a mouse-face. */
28375 Lisp_Object overlay = Qnil;
28376 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28377 {
28378 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28379 if (!NILP (mouse_face))
28380 overlay = overlay_vec[i];
28381 }
28382
28383 /* If we're highlighting the same overlay as before, there's
28384 no need to do that again. */
28385 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28386 goto check_help_echo;
28387 hlinfo->mouse_face_overlay = overlay;
28388
28389 /* Clear the display of the old active region, if any. */
28390 if (clear_mouse_face (hlinfo))
28391 cursor = No_Cursor;
28392
28393 /* If no overlay applies, get a text property. */
28394 if (NILP (overlay))
28395 mouse_face = Fget_text_property (position, Qmouse_face, object);
28396
28397 /* Next, compute the bounds of the mouse highlighting and
28398 display it. */
28399 if (!NILP (mouse_face) && STRINGP (object))
28400 {
28401 /* The mouse-highlighting comes from a display string
28402 with a mouse-face. */
28403 Lisp_Object s, e;
28404 ptrdiff_t ignore;
28405
28406 s = Fprevious_single_property_change
28407 (make_number (pos + 1), Qmouse_face, object, Qnil);
28408 e = Fnext_single_property_change
28409 (position, Qmouse_face, object, Qnil);
28410 if (NILP (s))
28411 s = make_number (0);
28412 if (NILP (e))
28413 e = make_number (SCHARS (object));
28414 mouse_face_from_string_pos (w, hlinfo, object,
28415 XINT (s), XINT (e));
28416 hlinfo->mouse_face_past_end = 0;
28417 hlinfo->mouse_face_window = window;
28418 hlinfo->mouse_face_face_id
28419 = face_at_string_position (w, object, pos, 0, &ignore,
28420 glyph->face_id, 1);
28421 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28422 cursor = No_Cursor;
28423 }
28424 else
28425 {
28426 /* The mouse-highlighting, if any, comes from an overlay
28427 or text property in the buffer. */
28428 Lisp_Object buffer IF_LINT (= Qnil);
28429 Lisp_Object disp_string IF_LINT (= Qnil);
28430
28431 if (STRINGP (object))
28432 {
28433 /* If we are on a display string with no mouse-face,
28434 check if the text under it has one. */
28435 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28436 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28437 pos = string_buffer_position (object, start);
28438 if (pos > 0)
28439 {
28440 mouse_face = get_char_property_and_overlay
28441 (make_number (pos), Qmouse_face, w->contents, &overlay);
28442 buffer = w->contents;
28443 disp_string = object;
28444 }
28445 }
28446 else
28447 {
28448 buffer = object;
28449 disp_string = Qnil;
28450 }
28451
28452 if (!NILP (mouse_face))
28453 {
28454 Lisp_Object before, after;
28455 Lisp_Object before_string, after_string;
28456 /* To correctly find the limits of mouse highlight
28457 in a bidi-reordered buffer, we must not use the
28458 optimization of limiting the search in
28459 previous-single-property-change and
28460 next-single-property-change, because
28461 rows_from_pos_range needs the real start and end
28462 positions to DTRT in this case. That's because
28463 the first row visible in a window does not
28464 necessarily display the character whose position
28465 is the smallest. */
28466 Lisp_Object lim1
28467 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28468 ? Fmarker_position (w->start)
28469 : Qnil;
28470 Lisp_Object lim2
28471 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28472 ? make_number (BUF_Z (XBUFFER (buffer))
28473 - w->window_end_pos)
28474 : Qnil;
28475
28476 if (NILP (overlay))
28477 {
28478 /* Handle the text property case. */
28479 before = Fprevious_single_property_change
28480 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28481 after = Fnext_single_property_change
28482 (make_number (pos), Qmouse_face, buffer, lim2);
28483 before_string = after_string = Qnil;
28484 }
28485 else
28486 {
28487 /* Handle the overlay case. */
28488 before = Foverlay_start (overlay);
28489 after = Foverlay_end (overlay);
28490 before_string = Foverlay_get (overlay, Qbefore_string);
28491 after_string = Foverlay_get (overlay, Qafter_string);
28492
28493 if (!STRINGP (before_string)) before_string = Qnil;
28494 if (!STRINGP (after_string)) after_string = Qnil;
28495 }
28496
28497 mouse_face_from_buffer_pos (window, hlinfo, pos,
28498 NILP (before)
28499 ? 1
28500 : XFASTINT (before),
28501 NILP (after)
28502 ? BUF_Z (XBUFFER (buffer))
28503 : XFASTINT (after),
28504 before_string, after_string,
28505 disp_string);
28506 cursor = No_Cursor;
28507 }
28508 }
28509 }
28510
28511 check_help_echo:
28512
28513 /* Look for a `help-echo' property. */
28514 if (NILP (help_echo_string)) {
28515 Lisp_Object help, overlay;
28516
28517 /* Check overlays first. */
28518 help = overlay = Qnil;
28519 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28520 {
28521 overlay = overlay_vec[i];
28522 help = Foverlay_get (overlay, Qhelp_echo);
28523 }
28524
28525 if (!NILP (help))
28526 {
28527 help_echo_string = help;
28528 help_echo_window = window;
28529 help_echo_object = overlay;
28530 help_echo_pos = pos;
28531 }
28532 else
28533 {
28534 Lisp_Object obj = glyph->object;
28535 ptrdiff_t charpos = glyph->charpos;
28536
28537 /* Try text properties. */
28538 if (STRINGP (obj)
28539 && charpos >= 0
28540 && charpos < SCHARS (obj))
28541 {
28542 help = Fget_text_property (make_number (charpos),
28543 Qhelp_echo, obj);
28544 if (NILP (help))
28545 {
28546 /* If the string itself doesn't specify a help-echo,
28547 see if the buffer text ``under'' it does. */
28548 struct glyph_row *r
28549 = MATRIX_ROW (w->current_matrix, vpos);
28550 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28551 ptrdiff_t p = string_buffer_position (obj, start);
28552 if (p > 0)
28553 {
28554 help = Fget_char_property (make_number (p),
28555 Qhelp_echo, w->contents);
28556 if (!NILP (help))
28557 {
28558 charpos = p;
28559 obj = w->contents;
28560 }
28561 }
28562 }
28563 }
28564 else if (BUFFERP (obj)
28565 && charpos >= BEGV
28566 && charpos < ZV)
28567 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28568 obj);
28569
28570 if (!NILP (help))
28571 {
28572 help_echo_string = help;
28573 help_echo_window = window;
28574 help_echo_object = obj;
28575 help_echo_pos = charpos;
28576 }
28577 }
28578 }
28579
28580 #ifdef HAVE_WINDOW_SYSTEM
28581 /* Look for a `pointer' property. */
28582 if (FRAME_WINDOW_P (f) && NILP (pointer))
28583 {
28584 /* Check overlays first. */
28585 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28586 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28587
28588 if (NILP (pointer))
28589 {
28590 Lisp_Object obj = glyph->object;
28591 ptrdiff_t charpos = glyph->charpos;
28592
28593 /* Try text properties. */
28594 if (STRINGP (obj)
28595 && charpos >= 0
28596 && charpos < SCHARS (obj))
28597 {
28598 pointer = Fget_text_property (make_number (charpos),
28599 Qpointer, obj);
28600 if (NILP (pointer))
28601 {
28602 /* If the string itself doesn't specify a pointer,
28603 see if the buffer text ``under'' it does. */
28604 struct glyph_row *r
28605 = MATRIX_ROW (w->current_matrix, vpos);
28606 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28607 ptrdiff_t p = string_buffer_position (obj, start);
28608 if (p > 0)
28609 pointer = Fget_char_property (make_number (p),
28610 Qpointer, w->contents);
28611 }
28612 }
28613 else if (BUFFERP (obj)
28614 && charpos >= BEGV
28615 && charpos < ZV)
28616 pointer = Fget_text_property (make_number (charpos),
28617 Qpointer, obj);
28618 }
28619 }
28620 #endif /* HAVE_WINDOW_SYSTEM */
28621
28622 BEGV = obegv;
28623 ZV = ozv;
28624 current_buffer = obuf;
28625 }
28626
28627 set_cursor:
28628
28629 #ifdef HAVE_WINDOW_SYSTEM
28630 if (FRAME_WINDOW_P (f))
28631 define_frame_cursor1 (f, cursor, pointer);
28632 #else
28633 /* This is here to prevent a compiler error, about "label at end of
28634 compound statement". */
28635 return;
28636 #endif
28637 }
28638
28639
28640 /* EXPORT for RIF:
28641 Clear any mouse-face on window W. This function is part of the
28642 redisplay interface, and is called from try_window_id and similar
28643 functions to ensure the mouse-highlight is off. */
28644
28645 void
28646 x_clear_window_mouse_face (struct window *w)
28647 {
28648 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28649 Lisp_Object window;
28650
28651 block_input ();
28652 XSETWINDOW (window, w);
28653 if (EQ (window, hlinfo->mouse_face_window))
28654 clear_mouse_face (hlinfo);
28655 unblock_input ();
28656 }
28657
28658
28659 /* EXPORT:
28660 Just discard the mouse face information for frame F, if any.
28661 This is used when the size of F is changed. */
28662
28663 void
28664 cancel_mouse_face (struct frame *f)
28665 {
28666 Lisp_Object window;
28667 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28668
28669 window = hlinfo->mouse_face_window;
28670 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28671 reset_mouse_highlight (hlinfo);
28672 }
28673
28674
28675 \f
28676 /***********************************************************************
28677 Exposure Events
28678 ***********************************************************************/
28679
28680 #ifdef HAVE_WINDOW_SYSTEM
28681
28682 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28683 which intersects rectangle R. R is in window-relative coordinates. */
28684
28685 static void
28686 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28687 enum glyph_row_area area)
28688 {
28689 struct glyph *first = row->glyphs[area];
28690 struct glyph *end = row->glyphs[area] + row->used[area];
28691 struct glyph *last;
28692 int first_x, start_x, x;
28693
28694 if (area == TEXT_AREA && row->fill_line_p)
28695 /* If row extends face to end of line write the whole line. */
28696 draw_glyphs (w, 0, row, area,
28697 0, row->used[area],
28698 DRAW_NORMAL_TEXT, 0);
28699 else
28700 {
28701 /* Set START_X to the window-relative start position for drawing glyphs of
28702 AREA. The first glyph of the text area can be partially visible.
28703 The first glyphs of other areas cannot. */
28704 start_x = window_box_left_offset (w, area);
28705 x = start_x;
28706 if (area == TEXT_AREA)
28707 x += row->x;
28708
28709 /* Find the first glyph that must be redrawn. */
28710 while (first < end
28711 && x + first->pixel_width < r->x)
28712 {
28713 x += first->pixel_width;
28714 ++first;
28715 }
28716
28717 /* Find the last one. */
28718 last = first;
28719 first_x = x;
28720 while (last < end
28721 && x < r->x + r->width)
28722 {
28723 x += last->pixel_width;
28724 ++last;
28725 }
28726
28727 /* Repaint. */
28728 if (last > first)
28729 draw_glyphs (w, first_x - start_x, row, area,
28730 first - row->glyphs[area], last - row->glyphs[area],
28731 DRAW_NORMAL_TEXT, 0);
28732 }
28733 }
28734
28735
28736 /* Redraw the parts of the glyph row ROW on window W intersecting
28737 rectangle R. R is in window-relative coordinates. Value is
28738 non-zero if mouse-face was overwritten. */
28739
28740 static int
28741 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28742 {
28743 eassert (row->enabled_p);
28744
28745 if (row->mode_line_p || w->pseudo_window_p)
28746 draw_glyphs (w, 0, row, TEXT_AREA,
28747 0, row->used[TEXT_AREA],
28748 DRAW_NORMAL_TEXT, 0);
28749 else
28750 {
28751 if (row->used[LEFT_MARGIN_AREA])
28752 expose_area (w, row, r, LEFT_MARGIN_AREA);
28753 if (row->used[TEXT_AREA])
28754 expose_area (w, row, r, TEXT_AREA);
28755 if (row->used[RIGHT_MARGIN_AREA])
28756 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28757 draw_row_fringe_bitmaps (w, row);
28758 }
28759
28760 return row->mouse_face_p;
28761 }
28762
28763
28764 /* Redraw those parts of glyphs rows during expose event handling that
28765 overlap other rows. Redrawing of an exposed line writes over parts
28766 of lines overlapping that exposed line; this function fixes that.
28767
28768 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28769 row in W's current matrix that is exposed and overlaps other rows.
28770 LAST_OVERLAPPING_ROW is the last such row. */
28771
28772 static void
28773 expose_overlaps (struct window *w,
28774 struct glyph_row *first_overlapping_row,
28775 struct glyph_row *last_overlapping_row,
28776 XRectangle *r)
28777 {
28778 struct glyph_row *row;
28779
28780 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28781 if (row->overlapping_p)
28782 {
28783 eassert (row->enabled_p && !row->mode_line_p);
28784
28785 row->clip = r;
28786 if (row->used[LEFT_MARGIN_AREA])
28787 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28788
28789 if (row->used[TEXT_AREA])
28790 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28791
28792 if (row->used[RIGHT_MARGIN_AREA])
28793 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28794 row->clip = NULL;
28795 }
28796 }
28797
28798
28799 /* Return non-zero if W's cursor intersects rectangle R. */
28800
28801 static int
28802 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28803 {
28804 XRectangle cr, result;
28805 struct glyph *cursor_glyph;
28806 struct glyph_row *row;
28807
28808 if (w->phys_cursor.vpos >= 0
28809 && w->phys_cursor.vpos < w->current_matrix->nrows
28810 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28811 row->enabled_p)
28812 && row->cursor_in_fringe_p)
28813 {
28814 /* Cursor is in the fringe. */
28815 cr.x = window_box_right_offset (w,
28816 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28817 ? RIGHT_MARGIN_AREA
28818 : TEXT_AREA));
28819 cr.y = row->y;
28820 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28821 cr.height = row->height;
28822 return x_intersect_rectangles (&cr, r, &result);
28823 }
28824
28825 cursor_glyph = get_phys_cursor_glyph (w);
28826 if (cursor_glyph)
28827 {
28828 /* r is relative to W's box, but w->phys_cursor.x is relative
28829 to left edge of W's TEXT area. Adjust it. */
28830 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28831 cr.y = w->phys_cursor.y;
28832 cr.width = cursor_glyph->pixel_width;
28833 cr.height = w->phys_cursor_height;
28834 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28835 I assume the effect is the same -- and this is portable. */
28836 return x_intersect_rectangles (&cr, r, &result);
28837 }
28838 /* If we don't understand the format, pretend we're not in the hot-spot. */
28839 return 0;
28840 }
28841
28842
28843 /* EXPORT:
28844 Draw a vertical window border to the right of window W if W doesn't
28845 have vertical scroll bars. */
28846
28847 void
28848 x_draw_vertical_border (struct window *w)
28849 {
28850 struct frame *f = XFRAME (WINDOW_FRAME (w));
28851
28852 /* We could do better, if we knew what type of scroll-bar the adjacent
28853 windows (on either side) have... But we don't :-(
28854 However, I think this works ok. ++KFS 2003-04-25 */
28855
28856 /* Redraw borders between horizontally adjacent windows. Don't
28857 do it for frames with vertical scroll bars because either the
28858 right scroll bar of a window, or the left scroll bar of its
28859 neighbor will suffice as a border. */
28860 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28861 return;
28862
28863 /* Note: It is necessary to redraw both the left and the right
28864 borders, for when only this single window W is being
28865 redisplayed. */
28866 if (!WINDOW_RIGHTMOST_P (w)
28867 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28868 {
28869 int x0, x1, y0, y1;
28870
28871 window_box_edges (w, &x0, &y0, &x1, &y1);
28872 y1 -= 1;
28873
28874 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28875 x1 -= 1;
28876
28877 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28878 }
28879 if (!WINDOW_LEFTMOST_P (w)
28880 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28881 {
28882 int x0, x1, y0, y1;
28883
28884 window_box_edges (w, &x0, &y0, &x1, &y1);
28885 y1 -= 1;
28886
28887 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28888 x0 -= 1;
28889
28890 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28891 }
28892 }
28893
28894
28895 /* Redraw the part of window W intersection rectangle FR. Pixel
28896 coordinates in FR are frame-relative. Call this function with
28897 input blocked. Value is non-zero if the exposure overwrites
28898 mouse-face. */
28899
28900 static int
28901 expose_window (struct window *w, XRectangle *fr)
28902 {
28903 struct frame *f = XFRAME (w->frame);
28904 XRectangle wr, r;
28905 int mouse_face_overwritten_p = 0;
28906
28907 /* If window is not yet fully initialized, do nothing. This can
28908 happen when toolkit scroll bars are used and a window is split.
28909 Reconfiguring the scroll bar will generate an expose for a newly
28910 created window. */
28911 if (w->current_matrix == NULL)
28912 return 0;
28913
28914 /* When we're currently updating the window, display and current
28915 matrix usually don't agree. Arrange for a thorough display
28916 later. */
28917 if (w->must_be_updated_p)
28918 {
28919 SET_FRAME_GARBAGED (f);
28920 return 0;
28921 }
28922
28923 /* Frame-relative pixel rectangle of W. */
28924 wr.x = WINDOW_LEFT_EDGE_X (w);
28925 wr.y = WINDOW_TOP_EDGE_Y (w);
28926 wr.width = WINDOW_TOTAL_WIDTH (w);
28927 wr.height = WINDOW_TOTAL_HEIGHT (w);
28928
28929 if (x_intersect_rectangles (fr, &wr, &r))
28930 {
28931 int yb = window_text_bottom_y (w);
28932 struct glyph_row *row;
28933 int cursor_cleared_p, phys_cursor_on_p;
28934 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28935
28936 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28937 r.x, r.y, r.width, r.height));
28938
28939 /* Convert to window coordinates. */
28940 r.x -= WINDOW_LEFT_EDGE_X (w);
28941 r.y -= WINDOW_TOP_EDGE_Y (w);
28942
28943 /* Turn off the cursor. */
28944 if (!w->pseudo_window_p
28945 && phys_cursor_in_rect_p (w, &r))
28946 {
28947 x_clear_cursor (w);
28948 cursor_cleared_p = 1;
28949 }
28950 else
28951 cursor_cleared_p = 0;
28952
28953 /* If the row containing the cursor extends face to end of line,
28954 then expose_area might overwrite the cursor outside the
28955 rectangle and thus notice_overwritten_cursor might clear
28956 w->phys_cursor_on_p. We remember the original value and
28957 check later if it is changed. */
28958 phys_cursor_on_p = w->phys_cursor_on_p;
28959
28960 /* Update lines intersecting rectangle R. */
28961 first_overlapping_row = last_overlapping_row = NULL;
28962 for (row = w->current_matrix->rows;
28963 row->enabled_p;
28964 ++row)
28965 {
28966 int y0 = row->y;
28967 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28968
28969 if ((y0 >= r.y && y0 < r.y + r.height)
28970 || (y1 > r.y && y1 < r.y + r.height)
28971 || (r.y >= y0 && r.y < y1)
28972 || (r.y + r.height > y0 && r.y + r.height < y1))
28973 {
28974 /* A header line may be overlapping, but there is no need
28975 to fix overlapping areas for them. KFS 2005-02-12 */
28976 if (row->overlapping_p && !row->mode_line_p)
28977 {
28978 if (first_overlapping_row == NULL)
28979 first_overlapping_row = row;
28980 last_overlapping_row = row;
28981 }
28982
28983 row->clip = fr;
28984 if (expose_line (w, row, &r))
28985 mouse_face_overwritten_p = 1;
28986 row->clip = NULL;
28987 }
28988 else if (row->overlapping_p)
28989 {
28990 /* We must redraw a row overlapping the exposed area. */
28991 if (y0 < r.y
28992 ? y0 + row->phys_height > r.y
28993 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28994 {
28995 if (first_overlapping_row == NULL)
28996 first_overlapping_row = row;
28997 last_overlapping_row = row;
28998 }
28999 }
29000
29001 if (y1 >= yb)
29002 break;
29003 }
29004
29005 /* Display the mode line if there is one. */
29006 if (WINDOW_WANTS_MODELINE_P (w)
29007 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
29008 row->enabled_p)
29009 && row->y < r.y + r.height)
29010 {
29011 if (expose_line (w, row, &r))
29012 mouse_face_overwritten_p = 1;
29013 }
29014
29015 if (!w->pseudo_window_p)
29016 {
29017 /* Fix the display of overlapping rows. */
29018 if (first_overlapping_row)
29019 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
29020 fr);
29021
29022 /* Draw border between windows. */
29023 x_draw_vertical_border (w);
29024
29025 /* Turn the cursor on again. */
29026 if (cursor_cleared_p
29027 || (phys_cursor_on_p && !w->phys_cursor_on_p))
29028 update_window_cursor (w, 1);
29029 }
29030 }
29031
29032 return mouse_face_overwritten_p;
29033 }
29034
29035
29036
29037 /* Redraw (parts) of all windows in the window tree rooted at W that
29038 intersect R. R contains frame pixel coordinates. Value is
29039 non-zero if the exposure overwrites mouse-face. */
29040
29041 static int
29042 expose_window_tree (struct window *w, XRectangle *r)
29043 {
29044 struct frame *f = XFRAME (w->frame);
29045 int mouse_face_overwritten_p = 0;
29046
29047 while (w && !FRAME_GARBAGED_P (f))
29048 {
29049 if (WINDOWP (w->contents))
29050 mouse_face_overwritten_p
29051 |= expose_window_tree (XWINDOW (w->contents), r);
29052 else
29053 mouse_face_overwritten_p |= expose_window (w, r);
29054
29055 w = NILP (w->next) ? NULL : XWINDOW (w->next);
29056 }
29057
29058 return mouse_face_overwritten_p;
29059 }
29060
29061
29062 /* EXPORT:
29063 Redisplay an exposed area of frame F. X and Y are the upper-left
29064 corner of the exposed rectangle. W and H are width and height of
29065 the exposed area. All are pixel values. W or H zero means redraw
29066 the entire frame. */
29067
29068 void
29069 expose_frame (struct frame *f, int x, int y, int w, int h)
29070 {
29071 XRectangle r;
29072 int mouse_face_overwritten_p = 0;
29073
29074 TRACE ((stderr, "expose_frame "));
29075
29076 /* No need to redraw if frame will be redrawn soon. */
29077 if (FRAME_GARBAGED_P (f))
29078 {
29079 TRACE ((stderr, " garbaged\n"));
29080 return;
29081 }
29082
29083 /* If basic faces haven't been realized yet, there is no point in
29084 trying to redraw anything. This can happen when we get an expose
29085 event while Emacs is starting, e.g. by moving another window. */
29086 if (FRAME_FACE_CACHE (f) == NULL
29087 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
29088 {
29089 TRACE ((stderr, " no faces\n"));
29090 return;
29091 }
29092
29093 if (w == 0 || h == 0)
29094 {
29095 r.x = r.y = 0;
29096 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
29097 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
29098 }
29099 else
29100 {
29101 r.x = x;
29102 r.y = y;
29103 r.width = w;
29104 r.height = h;
29105 }
29106
29107 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
29108 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
29109
29110 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29111 if (WINDOWP (f->tool_bar_window))
29112 mouse_face_overwritten_p
29113 |= expose_window (XWINDOW (f->tool_bar_window), &r);
29114 #endif
29115
29116 #ifdef HAVE_X_WINDOWS
29117 #ifndef MSDOS
29118 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
29119 if (WINDOWP (f->menu_bar_window))
29120 mouse_face_overwritten_p
29121 |= expose_window (XWINDOW (f->menu_bar_window), &r);
29122 #endif /* not USE_X_TOOLKIT and not USE_GTK */
29123 #endif
29124 #endif
29125
29126 /* Some window managers support a focus-follows-mouse style with
29127 delayed raising of frames. Imagine a partially obscured frame,
29128 and moving the mouse into partially obscured mouse-face on that
29129 frame. The visible part of the mouse-face will be highlighted,
29130 then the WM raises the obscured frame. With at least one WM, KDE
29131 2.1, Emacs is not getting any event for the raising of the frame
29132 (even tried with SubstructureRedirectMask), only Expose events.
29133 These expose events will draw text normally, i.e. not
29134 highlighted. Which means we must redo the highlight here.
29135 Subsume it under ``we love X''. --gerd 2001-08-15 */
29136 /* Included in Windows version because Windows most likely does not
29137 do the right thing if any third party tool offers
29138 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
29139 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
29140 {
29141 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29142 if (f == hlinfo->mouse_face_mouse_frame)
29143 {
29144 int mouse_x = hlinfo->mouse_face_mouse_x;
29145 int mouse_y = hlinfo->mouse_face_mouse_y;
29146 clear_mouse_face (hlinfo);
29147 note_mouse_highlight (f, mouse_x, mouse_y);
29148 }
29149 }
29150 }
29151
29152
29153 /* EXPORT:
29154 Determine the intersection of two rectangles R1 and R2. Return
29155 the intersection in *RESULT. Value is non-zero if RESULT is not
29156 empty. */
29157
29158 int
29159 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
29160 {
29161 XRectangle *left, *right;
29162 XRectangle *upper, *lower;
29163 int intersection_p = 0;
29164
29165 /* Rearrange so that R1 is the left-most rectangle. */
29166 if (r1->x < r2->x)
29167 left = r1, right = r2;
29168 else
29169 left = r2, right = r1;
29170
29171 /* X0 of the intersection is right.x0, if this is inside R1,
29172 otherwise there is no intersection. */
29173 if (right->x <= left->x + left->width)
29174 {
29175 result->x = right->x;
29176
29177 /* The right end of the intersection is the minimum of
29178 the right ends of left and right. */
29179 result->width = (min (left->x + left->width, right->x + right->width)
29180 - result->x);
29181
29182 /* Same game for Y. */
29183 if (r1->y < r2->y)
29184 upper = r1, lower = r2;
29185 else
29186 upper = r2, lower = r1;
29187
29188 /* The upper end of the intersection is lower.y0, if this is inside
29189 of upper. Otherwise, there is no intersection. */
29190 if (lower->y <= upper->y + upper->height)
29191 {
29192 result->y = lower->y;
29193
29194 /* The lower end of the intersection is the minimum of the lower
29195 ends of upper and lower. */
29196 result->height = (min (lower->y + lower->height,
29197 upper->y + upper->height)
29198 - result->y);
29199 intersection_p = 1;
29200 }
29201 }
29202
29203 return intersection_p;
29204 }
29205
29206 #endif /* HAVE_WINDOW_SYSTEM */
29207
29208 \f
29209 /***********************************************************************
29210 Initialization
29211 ***********************************************************************/
29212
29213 void
29214 syms_of_xdisp (void)
29215 {
29216 Vwith_echo_area_save_vector = Qnil;
29217 staticpro (&Vwith_echo_area_save_vector);
29218
29219 Vmessage_stack = Qnil;
29220 staticpro (&Vmessage_stack);
29221
29222 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
29223 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
29224
29225 message_dolog_marker1 = Fmake_marker ();
29226 staticpro (&message_dolog_marker1);
29227 message_dolog_marker2 = Fmake_marker ();
29228 staticpro (&message_dolog_marker2);
29229 message_dolog_marker3 = Fmake_marker ();
29230 staticpro (&message_dolog_marker3);
29231
29232 #ifdef GLYPH_DEBUG
29233 defsubr (&Sdump_frame_glyph_matrix);
29234 defsubr (&Sdump_glyph_matrix);
29235 defsubr (&Sdump_glyph_row);
29236 defsubr (&Sdump_tool_bar_row);
29237 defsubr (&Strace_redisplay);
29238 defsubr (&Strace_to_stderr);
29239 #endif
29240 #ifdef HAVE_WINDOW_SYSTEM
29241 defsubr (&Stool_bar_lines_needed);
29242 defsubr (&Slookup_image_map);
29243 #endif
29244 defsubr (&Sline_pixel_height);
29245 defsubr (&Sformat_mode_line);
29246 defsubr (&Sinvisible_p);
29247 defsubr (&Scurrent_bidi_paragraph_direction);
29248 defsubr (&Smove_point_visually);
29249
29250 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
29251 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
29252 DEFSYM (Qoverriding_local_map, "overriding-local-map");
29253 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
29254 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
29255 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
29256 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
29257 DEFSYM (Qeval, "eval");
29258 DEFSYM (QCdata, ":data");
29259 DEFSYM (Qdisplay, "display");
29260 DEFSYM (Qspace_width, "space-width");
29261 DEFSYM (Qraise, "raise");
29262 DEFSYM (Qslice, "slice");
29263 DEFSYM (Qspace, "space");
29264 DEFSYM (Qmargin, "margin");
29265 DEFSYM (Qpointer, "pointer");
29266 DEFSYM (Qleft_margin, "left-margin");
29267 DEFSYM (Qright_margin, "right-margin");
29268 DEFSYM (Qcenter, "center");
29269 DEFSYM (Qline_height, "line-height");
29270 DEFSYM (QCalign_to, ":align-to");
29271 DEFSYM (QCrelative_width, ":relative-width");
29272 DEFSYM (QCrelative_height, ":relative-height");
29273 DEFSYM (QCeval, ":eval");
29274 DEFSYM (QCpropertize, ":propertize");
29275 DEFSYM (QCfile, ":file");
29276 DEFSYM (Qfontified, "fontified");
29277 DEFSYM (Qfontification_functions, "fontification-functions");
29278 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
29279 DEFSYM (Qescape_glyph, "escape-glyph");
29280 DEFSYM (Qnobreak_space, "nobreak-space");
29281 DEFSYM (Qimage, "image");
29282 DEFSYM (Qtext, "text");
29283 DEFSYM (Qboth, "both");
29284 DEFSYM (Qboth_horiz, "both-horiz");
29285 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29286 DEFSYM (QCmap, ":map");
29287 DEFSYM (QCpointer, ":pointer");
29288 DEFSYM (Qrect, "rect");
29289 DEFSYM (Qcircle, "circle");
29290 DEFSYM (Qpoly, "poly");
29291 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29292 DEFSYM (Qgrow_only, "grow-only");
29293 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29294 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29295 DEFSYM (Qposition, "position");
29296 DEFSYM (Qbuffer_position, "buffer-position");
29297 DEFSYM (Qobject, "object");
29298 DEFSYM (Qbar, "bar");
29299 DEFSYM (Qhbar, "hbar");
29300 DEFSYM (Qbox, "box");
29301 DEFSYM (Qhollow, "hollow");
29302 DEFSYM (Qhand, "hand");
29303 DEFSYM (Qarrow, "arrow");
29304 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29305
29306 list_of_error = list1 (list2 (intern_c_string ("error"),
29307 intern_c_string ("void-variable")));
29308 staticpro (&list_of_error);
29309
29310 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29311 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29312 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29313 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29314
29315 echo_buffer[0] = echo_buffer[1] = Qnil;
29316 staticpro (&echo_buffer[0]);
29317 staticpro (&echo_buffer[1]);
29318
29319 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29320 staticpro (&echo_area_buffer[0]);
29321 staticpro (&echo_area_buffer[1]);
29322
29323 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29324 staticpro (&Vmessages_buffer_name);
29325
29326 mode_line_proptrans_alist = Qnil;
29327 staticpro (&mode_line_proptrans_alist);
29328 mode_line_string_list = Qnil;
29329 staticpro (&mode_line_string_list);
29330 mode_line_string_face = Qnil;
29331 staticpro (&mode_line_string_face);
29332 mode_line_string_face_prop = Qnil;
29333 staticpro (&mode_line_string_face_prop);
29334 Vmode_line_unwind_vector = Qnil;
29335 staticpro (&Vmode_line_unwind_vector);
29336
29337 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29338
29339 help_echo_string = Qnil;
29340 staticpro (&help_echo_string);
29341 help_echo_object = Qnil;
29342 staticpro (&help_echo_object);
29343 help_echo_window = Qnil;
29344 staticpro (&help_echo_window);
29345 previous_help_echo_string = Qnil;
29346 staticpro (&previous_help_echo_string);
29347 help_echo_pos = -1;
29348
29349 DEFSYM (Qright_to_left, "right-to-left");
29350 DEFSYM (Qleft_to_right, "left-to-right");
29351
29352 #ifdef HAVE_WINDOW_SYSTEM
29353 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29354 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29355 For example, if a block cursor is over a tab, it will be drawn as
29356 wide as that tab on the display. */);
29357 x_stretch_cursor_p = 0;
29358 #endif
29359
29360 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29361 doc: /* Non-nil means highlight trailing whitespace.
29362 The face used for trailing whitespace is `trailing-whitespace'. */);
29363 Vshow_trailing_whitespace = Qnil;
29364
29365 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29366 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29367 If the value is t, Emacs highlights non-ASCII chars which have the
29368 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29369 or `escape-glyph' face respectively.
29370
29371 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29372 U+2011 (non-breaking hyphen) are affected.
29373
29374 Any other non-nil value means to display these characters as a escape
29375 glyph followed by an ordinary space or hyphen.
29376
29377 A value of nil means no special handling of these characters. */);
29378 Vnobreak_char_display = Qt;
29379
29380 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29381 doc: /* The pointer shape to show in void text areas.
29382 A value of nil means to show the text pointer. Other options are `arrow',
29383 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29384 Vvoid_text_area_pointer = Qarrow;
29385
29386 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29387 doc: /* Non-nil means don't actually do any redisplay.
29388 This is used for internal purposes. */);
29389 Vinhibit_redisplay = Qnil;
29390
29391 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29392 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29393 Vglobal_mode_string = Qnil;
29394
29395 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29396 doc: /* Marker for where to display an arrow on top of the buffer text.
29397 This must be the beginning of a line in order to work.
29398 See also `overlay-arrow-string'. */);
29399 Voverlay_arrow_position = Qnil;
29400
29401 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29402 doc: /* String to display as an arrow in non-window frames.
29403 See also `overlay-arrow-position'. */);
29404 Voverlay_arrow_string = build_pure_c_string ("=>");
29405
29406 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29407 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29408 The symbols on this list are examined during redisplay to determine
29409 where to display overlay arrows. */);
29410 Voverlay_arrow_variable_list
29411 = list1 (intern_c_string ("overlay-arrow-position"));
29412
29413 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29414 doc: /* The number of lines to try scrolling a window by when point moves out.
29415 If that fails to bring point back on frame, point is centered instead.
29416 If this is zero, point is always centered after it moves off frame.
29417 If you want scrolling to always be a line at a time, you should set
29418 `scroll-conservatively' to a large value rather than set this to 1. */);
29419
29420 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29421 doc: /* Scroll up to this many lines, to bring point back on screen.
29422 If point moves off-screen, redisplay will scroll by up to
29423 `scroll-conservatively' lines in order to bring point just barely
29424 onto the screen again. If that cannot be done, then redisplay
29425 recenters point as usual.
29426
29427 If the value is greater than 100, redisplay will never recenter point,
29428 but will always scroll just enough text to bring point into view, even
29429 if you move far away.
29430
29431 A value of zero means always recenter point if it moves off screen. */);
29432 scroll_conservatively = 0;
29433
29434 DEFVAR_INT ("scroll-margin", scroll_margin,
29435 doc: /* Number of lines of margin at the top and bottom of a window.
29436 Recenter the window whenever point gets within this many lines
29437 of the top or bottom of the window. */);
29438 scroll_margin = 0;
29439
29440 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29441 doc: /* Pixels per inch value for non-window system displays.
29442 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29443 Vdisplay_pixels_per_inch = make_float (72.0);
29444
29445 #ifdef GLYPH_DEBUG
29446 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29447 #endif
29448
29449 DEFVAR_LISP ("truncate-partial-width-windows",
29450 Vtruncate_partial_width_windows,
29451 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29452 For an integer value, truncate lines in each window narrower than the
29453 full frame width, provided the window width is less than that integer;
29454 otherwise, respect the value of `truncate-lines'.
29455
29456 For any other non-nil value, truncate lines in all windows that do
29457 not span the full frame width.
29458
29459 A value of nil means to respect the value of `truncate-lines'.
29460
29461 If `word-wrap' is enabled, you might want to reduce this. */);
29462 Vtruncate_partial_width_windows = make_number (50);
29463
29464 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29465 doc: /* Maximum buffer size for which line number should be displayed.
29466 If the buffer is bigger than this, the line number does not appear
29467 in the mode line. A value of nil means no limit. */);
29468 Vline_number_display_limit = Qnil;
29469
29470 DEFVAR_INT ("line-number-display-limit-width",
29471 line_number_display_limit_width,
29472 doc: /* Maximum line width (in characters) for line number display.
29473 If the average length of the lines near point is bigger than this, then the
29474 line number may be omitted from the mode line. */);
29475 line_number_display_limit_width = 200;
29476
29477 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29478 doc: /* Non-nil means highlight region even in nonselected windows. */);
29479 highlight_nonselected_windows = 0;
29480
29481 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29482 doc: /* Non-nil if more than one frame is visible on this display.
29483 Minibuffer-only frames don't count, but iconified frames do.
29484 This variable is not guaranteed to be accurate except while processing
29485 `frame-title-format' and `icon-title-format'. */);
29486
29487 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29488 doc: /* Template for displaying the title bar of visible frames.
29489 \(Assuming the window manager supports this feature.)
29490
29491 This variable has the same structure as `mode-line-format', except that
29492 the %c and %l constructs are ignored. It is used only on frames for
29493 which no explicit name has been set \(see `modify-frame-parameters'). */);
29494
29495 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29496 doc: /* Template for displaying the title bar of an iconified frame.
29497 \(Assuming the window manager supports this feature.)
29498 This variable has the same structure as `mode-line-format' (which see),
29499 and is used only on frames for which no explicit name has been set
29500 \(see `modify-frame-parameters'). */);
29501 Vicon_title_format
29502 = Vframe_title_format
29503 = listn (CONSTYPE_PURE, 3,
29504 intern_c_string ("multiple-frames"),
29505 build_pure_c_string ("%b"),
29506 listn (CONSTYPE_PURE, 4,
29507 empty_unibyte_string,
29508 intern_c_string ("invocation-name"),
29509 build_pure_c_string ("@"),
29510 intern_c_string ("system-name")));
29511
29512 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29513 doc: /* Maximum number of lines to keep in the message log buffer.
29514 If nil, disable message logging. If t, log messages but don't truncate
29515 the buffer when it becomes large. */);
29516 Vmessage_log_max = make_number (1000);
29517
29518 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29519 doc: /* Functions called before redisplay, if window sizes have changed.
29520 The value should be a list of functions that take one argument.
29521 Just before redisplay, for each frame, if any of its windows have changed
29522 size since the last redisplay, or have been split or deleted,
29523 all the functions in the list are called, with the frame as argument. */);
29524 Vwindow_size_change_functions = Qnil;
29525
29526 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29527 doc: /* List of functions to call before redisplaying a window with scrolling.
29528 Each function is called with two arguments, the window and its new
29529 display-start position. Note that these functions are also called by
29530 `set-window-buffer'. Also note that the value of `window-end' is not
29531 valid when these functions are called.
29532
29533 Warning: Do not use this feature to alter the way the window
29534 is scrolled. It is not designed for that, and such use probably won't
29535 work. */);
29536 Vwindow_scroll_functions = Qnil;
29537
29538 DEFVAR_LISP ("window-text-change-functions",
29539 Vwindow_text_change_functions,
29540 doc: /* Functions to call in redisplay when text in the window might change. */);
29541 Vwindow_text_change_functions = Qnil;
29542
29543 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29544 doc: /* Functions called when redisplay of a window reaches the end trigger.
29545 Each function is called with two arguments, the window and the end trigger value.
29546 See `set-window-redisplay-end-trigger'. */);
29547 Vredisplay_end_trigger_functions = Qnil;
29548
29549 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29550 doc: /* Non-nil means autoselect window with mouse pointer.
29551 If nil, do not autoselect windows.
29552 A positive number means delay autoselection by that many seconds: a
29553 window is autoselected only after the mouse has remained in that
29554 window for the duration of the delay.
29555 A negative number has a similar effect, but causes windows to be
29556 autoselected only after the mouse has stopped moving. \(Because of
29557 the way Emacs compares mouse events, you will occasionally wait twice
29558 that time before the window gets selected.\)
29559 Any other value means to autoselect window instantaneously when the
29560 mouse pointer enters it.
29561
29562 Autoselection selects the minibuffer only if it is active, and never
29563 unselects the minibuffer if it is active.
29564
29565 When customizing this variable make sure that the actual value of
29566 `focus-follows-mouse' matches the behavior of your window manager. */);
29567 Vmouse_autoselect_window = Qnil;
29568
29569 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29570 doc: /* Non-nil means automatically resize tool-bars.
29571 This dynamically changes the tool-bar's height to the minimum height
29572 that is needed to make all tool-bar items visible.
29573 If value is `grow-only', the tool-bar's height is only increased
29574 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29575 Vauto_resize_tool_bars = Qt;
29576
29577 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29578 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29579 auto_raise_tool_bar_buttons_p = 1;
29580
29581 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29582 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29583 make_cursor_line_fully_visible_p = 1;
29584
29585 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29586 doc: /* Border below tool-bar in pixels.
29587 If an integer, use it as the height of the border.
29588 If it is one of `internal-border-width' or `border-width', use the
29589 value of the corresponding frame parameter.
29590 Otherwise, no border is added below the tool-bar. */);
29591 Vtool_bar_border = Qinternal_border_width;
29592
29593 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29594 doc: /* Margin around tool-bar buttons in pixels.
29595 If an integer, use that for both horizontal and vertical margins.
29596 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29597 HORZ specifying the horizontal margin, and VERT specifying the
29598 vertical margin. */);
29599 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29600
29601 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29602 doc: /* Relief thickness of tool-bar buttons. */);
29603 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29604
29605 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29606 doc: /* Tool bar style to use.
29607 It can be one of
29608 image - show images only
29609 text - show text only
29610 both - show both, text below image
29611 both-horiz - show text to the right of the image
29612 text-image-horiz - show text to the left of the image
29613 any other - use system default or image if no system default.
29614
29615 This variable only affects the GTK+ toolkit version of Emacs. */);
29616 Vtool_bar_style = Qnil;
29617
29618 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29619 doc: /* Maximum number of characters a label can have to be shown.
29620 The tool bar style must also show labels for this to have any effect, see
29621 `tool-bar-style'. */);
29622 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29623
29624 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29625 doc: /* List of functions to call to fontify regions of text.
29626 Each function is called with one argument POS. Functions must
29627 fontify a region starting at POS in the current buffer, and give
29628 fontified regions the property `fontified'. */);
29629 Vfontification_functions = Qnil;
29630 Fmake_variable_buffer_local (Qfontification_functions);
29631
29632 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29633 unibyte_display_via_language_environment,
29634 doc: /* Non-nil means display unibyte text according to language environment.
29635 Specifically, this means that raw bytes in the range 160-255 decimal
29636 are displayed by converting them to the equivalent multibyte characters
29637 according to the current language environment. As a result, they are
29638 displayed according to the current fontset.
29639
29640 Note that this variable affects only how these bytes are displayed,
29641 but does not change the fact they are interpreted as raw bytes. */);
29642 unibyte_display_via_language_environment = 0;
29643
29644 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29645 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29646 If a float, it specifies a fraction of the mini-window frame's height.
29647 If an integer, it specifies a number of lines. */);
29648 Vmax_mini_window_height = make_float (0.25);
29649
29650 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29651 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29652 A value of nil means don't automatically resize mini-windows.
29653 A value of t means resize them to fit the text displayed in them.
29654 A value of `grow-only', the default, means let mini-windows grow only;
29655 they return to their normal size when the minibuffer is closed, or the
29656 echo area becomes empty. */);
29657 Vresize_mini_windows = Qgrow_only;
29658
29659 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29660 doc: /* Alist specifying how to blink the cursor off.
29661 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29662 `cursor-type' frame-parameter or variable equals ON-STATE,
29663 comparing using `equal', Emacs uses OFF-STATE to specify
29664 how to blink it off. ON-STATE and OFF-STATE are values for
29665 the `cursor-type' frame parameter.
29666
29667 If a frame's ON-STATE has no entry in this list,
29668 the frame's other specifications determine how to blink the cursor off. */);
29669 Vblink_cursor_alist = Qnil;
29670
29671 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29672 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29673 If non-nil, windows are automatically scrolled horizontally to make
29674 point visible. */);
29675 automatic_hscrolling_p = 1;
29676 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29677
29678 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29679 doc: /* How many columns away from the window edge point is allowed to get
29680 before automatic hscrolling will horizontally scroll the window. */);
29681 hscroll_margin = 5;
29682
29683 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29684 doc: /* How many columns to scroll the window when point gets too close to the edge.
29685 When point is less than `hscroll-margin' columns from the window
29686 edge, automatic hscrolling will scroll the window by the amount of columns
29687 determined by this variable. If its value is a positive integer, scroll that
29688 many columns. If it's a positive floating-point number, it specifies the
29689 fraction of the window's width to scroll. If it's nil or zero, point will be
29690 centered horizontally after the scroll. Any other value, including negative
29691 numbers, are treated as if the value were zero.
29692
29693 Automatic hscrolling always moves point outside the scroll margin, so if
29694 point was more than scroll step columns inside the margin, the window will
29695 scroll more than the value given by the scroll step.
29696
29697 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29698 and `scroll-right' overrides this variable's effect. */);
29699 Vhscroll_step = make_number (0);
29700
29701 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29702 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29703 Bind this around calls to `message' to let it take effect. */);
29704 message_truncate_lines = 0;
29705
29706 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29707 doc: /* Normal hook run to update the menu bar definitions.
29708 Redisplay runs this hook before it redisplays the menu bar.
29709 This is used to update submenus such as Buffers,
29710 whose contents depend on various data. */);
29711 Vmenu_bar_update_hook = Qnil;
29712
29713 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29714 doc: /* Frame for which we are updating a menu.
29715 The enable predicate for a menu binding should check this variable. */);
29716 Vmenu_updating_frame = Qnil;
29717
29718 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29719 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29720 inhibit_menubar_update = 0;
29721
29722 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29723 doc: /* Prefix prepended to all continuation lines at display time.
29724 The value may be a string, an image, or a stretch-glyph; it is
29725 interpreted in the same way as the value of a `display' text property.
29726
29727 This variable is overridden by any `wrap-prefix' text or overlay
29728 property.
29729
29730 To add a prefix to non-continuation lines, use `line-prefix'. */);
29731 Vwrap_prefix = Qnil;
29732 DEFSYM (Qwrap_prefix, "wrap-prefix");
29733 Fmake_variable_buffer_local (Qwrap_prefix);
29734
29735 DEFVAR_LISP ("line-prefix", Vline_prefix,
29736 doc: /* Prefix prepended to all non-continuation lines at display time.
29737 The value may be a string, an image, or a stretch-glyph; it is
29738 interpreted in the same way as the value of a `display' text property.
29739
29740 This variable is overridden by any `line-prefix' text or overlay
29741 property.
29742
29743 To add a prefix to continuation lines, use `wrap-prefix'. */);
29744 Vline_prefix = Qnil;
29745 DEFSYM (Qline_prefix, "line-prefix");
29746 Fmake_variable_buffer_local (Qline_prefix);
29747
29748 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29749 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29750 inhibit_eval_during_redisplay = 0;
29751
29752 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29753 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29754 inhibit_free_realized_faces = 0;
29755
29756 #ifdef GLYPH_DEBUG
29757 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29758 doc: /* Inhibit try_window_id display optimization. */);
29759 inhibit_try_window_id = 0;
29760
29761 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29762 doc: /* Inhibit try_window_reusing display optimization. */);
29763 inhibit_try_window_reusing = 0;
29764
29765 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29766 doc: /* Inhibit try_cursor_movement display optimization. */);
29767 inhibit_try_cursor_movement = 0;
29768 #endif /* GLYPH_DEBUG */
29769
29770 DEFVAR_INT ("overline-margin", overline_margin,
29771 doc: /* Space between overline and text, in pixels.
29772 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29773 margin to the character height. */);
29774 overline_margin = 2;
29775
29776 DEFVAR_INT ("underline-minimum-offset",
29777 underline_minimum_offset,
29778 doc: /* Minimum distance between baseline and underline.
29779 This can improve legibility of underlined text at small font sizes,
29780 particularly when using variable `x-use-underline-position-properties'
29781 with fonts that specify an UNDERLINE_POSITION relatively close to the
29782 baseline. The default value is 1. */);
29783 underline_minimum_offset = 1;
29784
29785 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29786 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29787 This feature only works when on a window system that can change
29788 cursor shapes. */);
29789 display_hourglass_p = 1;
29790
29791 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29792 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29793 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29794
29795 #ifdef HAVE_WINDOW_SYSTEM
29796 hourglass_atimer = NULL;
29797 hourglass_shown_p = 0;
29798 #endif /* HAVE_WINDOW_SYSTEM */
29799
29800 DEFSYM (Qglyphless_char, "glyphless-char");
29801 DEFSYM (Qhex_code, "hex-code");
29802 DEFSYM (Qempty_box, "empty-box");
29803 DEFSYM (Qthin_space, "thin-space");
29804 DEFSYM (Qzero_width, "zero-width");
29805
29806 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
29807 doc: /* Function run just before redisplay.
29808 It is called with one argument, which is the set of windows that are to
29809 be redisplayed. This set can be nil (meaning, only the selected window),
29810 or t (meaning all windows). */);
29811 Vpre_redisplay_function = intern ("ignore");
29812
29813 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29814 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29815
29816 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29817 doc: /* Char-table defining glyphless characters.
29818 Each element, if non-nil, should be one of the following:
29819 an ASCII acronym string: display this string in a box
29820 `hex-code': display the hexadecimal code of a character in a box
29821 `empty-box': display as an empty box
29822 `thin-space': display as 1-pixel width space
29823 `zero-width': don't display
29824 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29825 display method for graphical terminals and text terminals respectively.
29826 GRAPHICAL and TEXT should each have one of the values listed above.
29827
29828 The char-table has one extra slot to control the display of a character for
29829 which no font is found. This slot only takes effect on graphical terminals.
29830 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29831 `thin-space'. The default is `empty-box'.
29832
29833 If a character has a non-nil entry in an active display table, the
29834 display table takes effect; in this case, Emacs does not consult
29835 `glyphless-char-display' at all. */);
29836 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29837 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29838 Qempty_box);
29839
29840 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29841 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29842 Vdebug_on_message = Qnil;
29843
29844 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
29845 doc: /* */);
29846 Vredisplay__all_windows_cause
29847 = Fmake_vector (make_number (100), make_number (0));
29848
29849 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
29850 doc: /* */);
29851 Vredisplay__mode_lines_cause
29852 = Fmake_vector (make_number (100), make_number (0));
29853 }
29854
29855
29856 /* Initialize this module when Emacs starts. */
29857
29858 void
29859 init_xdisp (void)
29860 {
29861 CHARPOS (this_line_start_pos) = 0;
29862
29863 if (!noninteractive)
29864 {
29865 struct window *m = XWINDOW (minibuf_window);
29866 Lisp_Object frame = m->frame;
29867 struct frame *f = XFRAME (frame);
29868 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29869 struct window *r = XWINDOW (root);
29870 int i;
29871
29872 echo_area_window = minibuf_window;
29873
29874 r->top_line = FRAME_TOP_MARGIN (f);
29875 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29876 r->total_cols = FRAME_COLS (f);
29877
29878 m->top_line = FRAME_LINES (f) - 1;
29879 m->total_lines = 1;
29880 m->total_cols = FRAME_COLS (f);
29881
29882 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29883 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29884 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29885
29886 /* The default ellipsis glyphs `...'. */
29887 for (i = 0; i < 3; ++i)
29888 default_invis_vector[i] = make_number ('.');
29889 }
29890
29891 {
29892 /* Allocate the buffer for frame titles.
29893 Also used for `format-mode-line'. */
29894 int size = 100;
29895 mode_line_noprop_buf = xmalloc (size);
29896 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29897 mode_line_noprop_ptr = mode_line_noprop_buf;
29898 mode_line_target = MODE_LINE_DISPLAY;
29899 }
29900
29901 help_echo_showing_p = 0;
29902 }
29903
29904 #ifdef HAVE_WINDOW_SYSTEM
29905
29906 /* Platform-independent portion of hourglass implementation. */
29907
29908 /* Cancel a currently active hourglass timer, and start a new one. */
29909 void
29910 start_hourglass (void)
29911 {
29912 struct timespec delay;
29913
29914 cancel_hourglass ();
29915
29916 if (INTEGERP (Vhourglass_delay)
29917 && XINT (Vhourglass_delay) > 0)
29918 delay = make_timespec (min (XINT (Vhourglass_delay),
29919 TYPE_MAXIMUM (time_t)),
29920 0);
29921 else if (FLOATP (Vhourglass_delay)
29922 && XFLOAT_DATA (Vhourglass_delay) > 0)
29923 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
29924 else
29925 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
29926
29927 #ifdef HAVE_NTGUI
29928 {
29929 extern void w32_note_current_window (void);
29930 w32_note_current_window ();
29931 }
29932 #endif /* HAVE_NTGUI */
29933
29934 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29935 show_hourglass, NULL);
29936 }
29937
29938
29939 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29940 shown. */
29941 void
29942 cancel_hourglass (void)
29943 {
29944 if (hourglass_atimer)
29945 {
29946 cancel_atimer (hourglass_atimer);
29947 hourglass_atimer = NULL;
29948 }
29949
29950 if (hourglass_shown_p)
29951 hide_hourglass ();
29952 }
29953
29954 #endif /* HAVE_WINDOW_SYSTEM */