]> code.delx.au - gnu-emacs/blob - src/xdisp.c
Merge from emacs-24; up to 2014-07-08T06:24:07Z!eggert@cs.ucla.edu
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2
3 Copyright (C) 1985-1988, 1993-1995, 1997-2014 Free Software Foundation,
4 Inc.
5
6 This file is part of GNU Emacs.
7
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
22
23 Redisplay.
24
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
29
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
35
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa. Under window systems
38 like X, some portions of the redisplay code are also called
39 asynchronously during mouse movement or expose events. It is very
40 important that these code parts do NOT use the C library (malloc,
41 free) because many C libraries under Unix are not reentrant. They
42 may also NOT call functions of the Lisp interpreter which could
43 change the interpreter's state. If you don't follow these rules,
44 you will encounter bugs which are very hard to explain.
45
46 +--------------+ redisplay +----------------+
47 | Lisp machine |---------------->| Redisplay code |<--+
48 +--------------+ (xdisp.c) +----------------+ |
49 ^ | |
50 +----------------------------------+ |
51 Don't use this path when called |
52 asynchronously! |
53 |
54 expose_window (asynchronous) |
55 |
56 X expose events -----+
57
58 What does redisplay do? Obviously, it has to figure out somehow what
59 has been changed since the last time the display has been updated,
60 and to make these changes visible. Preferably it would do that in
61 a moderately intelligent way, i.e. fast.
62
63 Changes in buffer text can be deduced from window and buffer
64 structures, and from some global variables like `beg_unchanged' and
65 `end_unchanged'. The contents of the display are additionally
66 recorded in a `glyph matrix', a two-dimensional matrix of glyph
67 structures. Each row in such a matrix corresponds to a line on the
68 display, and each glyph in a row corresponds to a column displaying
69 a character, an image, or what else. This matrix is called the
70 `current glyph matrix' or `current matrix' in redisplay
71 terminology.
72
73 For buffer parts that have been changed since the last update, a
74 second glyph matrix is constructed, the so called `desired glyph
75 matrix' or short `desired matrix'. Current and desired matrix are
76 then compared to find a cheap way to update the display, e.g. by
77 reusing part of the display by scrolling lines.
78
79 You will find a lot of redisplay optimizations when you start
80 looking at the innards of redisplay. The overall goal of all these
81 optimizations is to make redisplay fast because it is done
82 frequently. Some of these optimizations are implemented by the
83 following functions:
84
85 . try_cursor_movement
86
87 This function tries to update the display if the text in the
88 window did not change and did not scroll, only point moved, and
89 it did not move off the displayed portion of the text.
90
91 . try_window_reusing_current_matrix
92
93 This function reuses the current matrix of a window when text
94 has not changed, but the window start changed (e.g., due to
95 scrolling).
96
97 . try_window_id
98
99 This function attempts to redisplay a window by reusing parts of
100 its existing display. It finds and reuses the part that was not
101 changed, and redraws the rest. (The "id" part in the function's
102 name stands for "insert/delete", not for "identification" or
103 somesuch.)
104
105 . try_window
106
107 This function performs the full redisplay of a single window
108 assuming that its fonts were not changed and that the cursor
109 will not end up in the scroll margins. (Loading fonts requires
110 re-adjustment of dimensions of glyph matrices, which makes this
111 method impossible to use.)
112
113 These optimizations are tried in sequence (some can be skipped if
114 it is known that they are not applicable). If none of the
115 optimizations were successful, redisplay calls redisplay_windows,
116 which performs a full redisplay of all windows.
117
118 Note that there's one more important optimization up Emacs's
119 sleeve, but it is related to actually redrawing the potentially
120 changed portions of the window/frame, not to reproducing the
121 desired matrices of those potentially changed portions. Namely,
122 the function update_frame and its subroutines, which you will find
123 in dispnew.c, compare the desired matrices with the current
124 matrices, and only redraw the portions that changed. So it could
125 happen that the functions in this file for some reason decide that
126 the entire desired matrix needs to be regenerated from scratch, and
127 still only parts of the Emacs display, or even nothing at all, will
128 be actually delivered to the glass, because update_frame has found
129 that the new and the old screen contents are similar or identical.
130
131 Desired matrices.
132
133 Desired matrices are always built per Emacs window. The function
134 `display_line' is the central function to look at if you are
135 interested. It constructs one row in a desired matrix given an
136 iterator structure containing both a buffer position and a
137 description of the environment in which the text is to be
138 displayed. But this is too early, read on.
139
140 Characters and pixmaps displayed for a range of buffer text depend
141 on various settings of buffers and windows, on overlays and text
142 properties, on display tables, on selective display. The good news
143 is that all this hairy stuff is hidden behind a small set of
144 interface functions taking an iterator structure (struct it)
145 argument.
146
147 Iteration over things to be displayed is then simple. It is
148 started by initializing an iterator with a call to init_iterator,
149 passing it the buffer position where to start iteration. For
150 iteration over strings, pass -1 as the position to init_iterator,
151 and call reseat_to_string when the string is ready, to initialize
152 the iterator for that string. Thereafter, calls to
153 get_next_display_element fill the iterator structure with relevant
154 information about the next thing to display. Calls to
155 set_iterator_to_next move the iterator to the next thing.
156
157 Besides this, an iterator also contains information about the
158 display environment in which glyphs for display elements are to be
159 produced. It has fields for the width and height of the display,
160 the information whether long lines are truncated or continued, a
161 current X and Y position, and lots of other stuff you can better
162 see in dispextern.h.
163
164 Glyphs in a desired matrix are normally constructed in a loop
165 calling get_next_display_element and then PRODUCE_GLYPHS. The call
166 to PRODUCE_GLYPHS will fill the iterator structure with pixel
167 information about the element being displayed and at the same time
168 produce glyphs for it. If the display element fits on the line
169 being displayed, set_iterator_to_next is called next, otherwise the
170 glyphs produced are discarded. The function display_line is the
171 workhorse of filling glyph rows in the desired matrix with glyphs.
172 In addition to producing glyphs, it also handles line truncation
173 and continuation, word wrap, and cursor positioning (for the
174 latter, see also set_cursor_from_row).
175
176 Frame matrices.
177
178 That just couldn't be all, could it? What about terminal types not
179 supporting operations on sub-windows of the screen? To update the
180 display on such a terminal, window-based glyph matrices are not
181 well suited. To be able to reuse part of the display (scrolling
182 lines up and down), we must instead have a view of the whole
183 screen. This is what `frame matrices' are for. They are a trick.
184
185 Frames on terminals like above have a glyph pool. Windows on such
186 a frame sub-allocate their glyph memory from their frame's glyph
187 pool. The frame itself is given its own glyph matrices. By
188 coincidence---or maybe something else---rows in window glyph
189 matrices are slices of corresponding rows in frame matrices. Thus
190 writing to window matrices implicitly updates a frame matrix which
191 provides us with the view of the whole screen that we originally
192 wanted to have without having to move many bytes around. To be
193 honest, there is a little bit more done, but not much more. If you
194 plan to extend that code, take a look at dispnew.c. The function
195 build_frame_matrix is a good starting point.
196
197 Bidirectional display.
198
199 Bidirectional display adds quite some hair to this already complex
200 design. The good news are that a large portion of that hairy stuff
201 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
202 reordering engine which is called by set_iterator_to_next and
203 returns the next character to display in the visual order. See
204 commentary on bidi.c for more details. As far as redisplay is
205 concerned, the effect of calling bidi_move_to_visually_next, the
206 main interface of the reordering engine, is that the iterator gets
207 magically placed on the buffer or string position that is to be
208 displayed next. In other words, a linear iteration through the
209 buffer/string is replaced with a non-linear one. All the rest of
210 the redisplay is oblivious to the bidi reordering.
211
212 Well, almost oblivious---there are still complications, most of
213 them due to the fact that buffer and string positions no longer
214 change monotonously with glyph indices in a glyph row. Moreover,
215 for continued lines, the buffer positions may not even be
216 monotonously changing with vertical positions. Also, accounting
217 for face changes, overlays, etc. becomes more complex because
218 non-linear iteration could potentially skip many positions with
219 changes, and then cross them again on the way back...
220
221 One other prominent effect of bidirectional display is that some
222 paragraphs of text need to be displayed starting at the right
223 margin of the window---the so-called right-to-left, or R2L
224 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
225 which have their reversed_p flag set. The bidi reordering engine
226 produces characters in such rows starting from the character which
227 should be the rightmost on display. PRODUCE_GLYPHS then reverses
228 the order, when it fills up the glyph row whose reversed_p flag is
229 set, by prepending each new glyph to what is already there, instead
230 of appending it. When the glyph row is complete, the function
231 extend_face_to_end_of_line fills the empty space to the left of the
232 leftmost character with special glyphs, which will display as,
233 well, empty. On text terminals, these special glyphs are simply
234 blank characters. On graphics terminals, there's a single stretch
235 glyph of a suitably computed width. Both the blanks and the
236 stretch glyph are given the face of the background of the line.
237 This way, the terminal-specific back-end can still draw the glyphs
238 left to right, even for R2L lines.
239
240 Bidirectional display and character compositions
241
242 Some scripts cannot be displayed by drawing each character
243 individually, because adjacent characters change each other's shape
244 on display. For example, Arabic and Indic scripts belong to this
245 category.
246
247 Emacs display supports this by providing "character compositions",
248 most of which is implemented in composite.c. During the buffer
249 scan that delivers characters to PRODUCE_GLYPHS, if the next
250 character to be delivered is a composed character, the iteration
251 calls composition_reseat_it and next_element_from_composition. If
252 they succeed to compose the character with one or more of the
253 following characters, the whole sequence of characters that where
254 composed is recorded in the `struct composition_it' object that is
255 part of the buffer iterator. The composed sequence could produce
256 one or more font glyphs (called "grapheme clusters") on the screen.
257 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
258 in the direction corresponding to the current bidi scan direction
259 (recorded in the scan_dir member of the `struct bidi_it' object
260 that is part of the buffer iterator). In particular, if the bidi
261 iterator currently scans the buffer backwards, the grapheme
262 clusters are delivered back to front. This reorders the grapheme
263 clusters as appropriate for the current bidi context. Note that
264 this means that the grapheme clusters are always stored in the
265 LGSTRING object (see composite.c) in the logical order.
266
267 Moving an iterator in bidirectional text
268 without producing glyphs
269
270 Note one important detail mentioned above: that the bidi reordering
271 engine, driven by the iterator, produces characters in R2L rows
272 starting at the character that will be the rightmost on display.
273 As far as the iterator is concerned, the geometry of such rows is
274 still left to right, i.e. the iterator "thinks" the first character
275 is at the leftmost pixel position. The iterator does not know that
276 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
277 delivers. This is important when functions from the move_it_*
278 family are used to get to certain screen position or to match
279 screen coordinates with buffer coordinates: these functions use the
280 iterator geometry, which is left to right even in R2L paragraphs.
281 This works well with most callers of move_it_*, because they need
282 to get to a specific column, and columns are still numbered in the
283 reading order, i.e. the rightmost character in a R2L paragraph is
284 still column zero. But some callers do not get well with this; a
285 notable example is mouse clicks that need to find the character
286 that corresponds to certain pixel coordinates. See
287 buffer_posn_from_coords in dispnew.c for how this is handled. */
288
289 #include <config.h>
290 #include <stdio.h>
291 #include <limits.h>
292
293 #include "lisp.h"
294 #include "atimer.h"
295 #include "keyboard.h"
296 #include "frame.h"
297 #include "window.h"
298 #include "termchar.h"
299 #include "dispextern.h"
300 #include "character.h"
301 #include "buffer.h"
302 #include "charset.h"
303 #include "indent.h"
304 #include "commands.h"
305 #include "keymap.h"
306 #include "macros.h"
307 #include "disptab.h"
308 #include "termhooks.h"
309 #include "termopts.h"
310 #include "intervals.h"
311 #include "coding.h"
312 #include "process.h"
313 #include "region-cache.h"
314 #include "font.h"
315 #include "fontset.h"
316 #include "blockinput.h"
317 #ifdef HAVE_WINDOW_SYSTEM
318 #include TERM_HEADER
319 #endif /* HAVE_WINDOW_SYSTEM */
320
321 #ifndef FRAME_X_OUTPUT
322 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
323 #endif
324
325 #define INFINITY 10000000
326
327 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
328 Lisp_Object Qwindow_scroll_functions;
329 static Lisp_Object Qwindow_text_change_functions;
330 static Lisp_Object Qredisplay_end_trigger_functions;
331 Lisp_Object Qinhibit_point_motion_hooks;
332 static Lisp_Object QCeval, QCpropertize;
333 Lisp_Object QCfile, QCdata;
334 static Lisp_Object Qfontified;
335 static Lisp_Object Qgrow_only;
336 static Lisp_Object Qinhibit_eval_during_redisplay;
337 static Lisp_Object Qbuffer_position, Qposition, Qobject;
338 static Lisp_Object Qright_to_left, Qleft_to_right;
339
340 /* Cursor shapes. */
341 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
342
343 /* Pointer shapes. */
344 static Lisp_Object Qarrow, Qhand;
345 Lisp_Object Qtext;
346
347 /* Holds the list (error). */
348 static Lisp_Object list_of_error;
349
350 static Lisp_Object Qfontification_functions;
351
352 static Lisp_Object Qwrap_prefix;
353 static Lisp_Object Qline_prefix;
354 static Lisp_Object Qredisplay_internal;
355
356 /* Non-nil means don't actually do any redisplay. */
357
358 Lisp_Object Qinhibit_redisplay;
359
360 /* Names of text properties relevant for redisplay. */
361
362 Lisp_Object Qdisplay;
363
364 Lisp_Object Qspace, QCalign_to;
365 static Lisp_Object QCrelative_width, QCrelative_height;
366 Lisp_Object Qleft_margin, Qright_margin;
367 static Lisp_Object Qspace_width, Qraise;
368 static Lisp_Object Qslice;
369 Lisp_Object Qcenter;
370 static Lisp_Object Qmargin, Qpointer;
371 static Lisp_Object Qline_height;
372
373 #ifdef HAVE_WINDOW_SYSTEM
374
375 /* Test if overflow newline into fringe. Called with iterator IT
376 at or past right window margin, and with IT->current_x set. */
377
378 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
379 (!NILP (Voverflow_newline_into_fringe) \
380 && FRAME_WINDOW_P ((IT)->f) \
381 && ((IT)->bidi_it.paragraph_dir == R2L \
382 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
383 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
384 && (IT)->current_x == (IT)->last_visible_x)
385
386 #else /* !HAVE_WINDOW_SYSTEM */
387 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
388 #endif /* HAVE_WINDOW_SYSTEM */
389
390 /* Test if the display element loaded in IT, or the underlying buffer
391 or string character, is a space or a TAB character. This is used
392 to determine where word wrapping can occur. */
393
394 #define IT_DISPLAYING_WHITESPACE(it) \
395 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
396 || ((STRINGP (it->string) \
397 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
398 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
399 || (it->s \
400 && (it->s[IT_BYTEPOS (*it)] == ' ' \
401 || it->s[IT_BYTEPOS (*it)] == '\t')) \
402 || (IT_BYTEPOS (*it) < ZV_BYTE \
403 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
404 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
405
406 /* Name of the face used to highlight trailing whitespace. */
407
408 static Lisp_Object Qtrailing_whitespace;
409
410 /* Name and number of the face used to highlight escape glyphs. */
411
412 static Lisp_Object Qescape_glyph;
413
414 /* Name and number of the face used to highlight non-breaking spaces. */
415
416 static Lisp_Object Qnobreak_space;
417
418 /* The symbol `image' which is the car of the lists used to represent
419 images in Lisp. Also a tool bar style. */
420
421 Lisp_Object Qimage;
422
423 /* The image map types. */
424 Lisp_Object QCmap;
425 static Lisp_Object QCpointer;
426 static Lisp_Object Qrect, Qcircle, Qpoly;
427
428 /* Tool bar styles */
429 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
430
431 /* Non-zero means print newline to stdout before next mini-buffer
432 message. */
433
434 bool noninteractive_need_newline;
435
436 /* Non-zero means print newline to message log before next message. */
437
438 static bool message_log_need_newline;
439
440 /* Three markers that message_dolog uses.
441 It could allocate them itself, but that causes trouble
442 in handling memory-full errors. */
443 static Lisp_Object message_dolog_marker1;
444 static Lisp_Object message_dolog_marker2;
445 static Lisp_Object message_dolog_marker3;
446 \f
447 /* The buffer position of the first character appearing entirely or
448 partially on the line of the selected window which contains the
449 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
450 redisplay optimization in redisplay_internal. */
451
452 static struct text_pos this_line_start_pos;
453
454 /* Number of characters past the end of the line above, including the
455 terminating newline. */
456
457 static struct text_pos this_line_end_pos;
458
459 /* The vertical positions and the height of this line. */
460
461 static int this_line_vpos;
462 static int this_line_y;
463 static int this_line_pixel_height;
464
465 /* X position at which this display line starts. Usually zero;
466 negative if first character is partially visible. */
467
468 static int this_line_start_x;
469
470 /* The smallest character position seen by move_it_* functions as they
471 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
472 hscrolled lines, see display_line. */
473
474 static struct text_pos this_line_min_pos;
475
476 /* Buffer that this_line_.* variables are referring to. */
477
478 static struct buffer *this_line_buffer;
479
480
481 /* Values of those variables at last redisplay are stored as
482 properties on `overlay-arrow-position' symbol. However, if
483 Voverlay_arrow_position is a marker, last-arrow-position is its
484 numerical position. */
485
486 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
487
488 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
489 properties on a symbol in overlay-arrow-variable-list. */
490
491 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
492
493 Lisp_Object Qmenu_bar_update_hook;
494
495 /* Nonzero if an overlay arrow has been displayed in this window. */
496
497 static bool overlay_arrow_seen;
498
499 /* Vector containing glyphs for an ellipsis `...'. */
500
501 static Lisp_Object default_invis_vector[3];
502
503 /* This is the window where the echo area message was displayed. It
504 is always a mini-buffer window, but it may not be the same window
505 currently active as a mini-buffer. */
506
507 Lisp_Object echo_area_window;
508
509 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
510 pushes the current message and the value of
511 message_enable_multibyte on the stack, the function restore_message
512 pops the stack and displays MESSAGE again. */
513
514 static Lisp_Object Vmessage_stack;
515
516 /* Nonzero means multibyte characters were enabled when the echo area
517 message was specified. */
518
519 static bool message_enable_multibyte;
520
521 /* Nonzero if we should redraw the mode lines on the next redisplay.
522 If it has value REDISPLAY_SOME, then only redisplay the mode lines where
523 the `redisplay' bit has been set. Otherwise, redisplay all mode lines
524 (the number used is then only used to track down the cause for this
525 full-redisplay). */
526
527 int update_mode_lines;
528
529 /* Nonzero if window sizes or contents other than selected-window have changed
530 since last redisplay that finished.
531 If it has value REDISPLAY_SOME, then only redisplay the windows where
532 the `redisplay' bit has been set. Otherwise, redisplay all windows
533 (the number used is then only used to track down the cause for this
534 full-redisplay). */
535
536 int windows_or_buffers_changed;
537
538 /* Nonzero after display_mode_line if %l was used and it displayed a
539 line number. */
540
541 static bool line_number_displayed;
542
543 /* The name of the *Messages* buffer, a string. */
544
545 static Lisp_Object Vmessages_buffer_name;
546
547 /* Current, index 0, and last displayed echo area message. Either
548 buffers from echo_buffers, or nil to indicate no message. */
549
550 Lisp_Object echo_area_buffer[2];
551
552 /* The buffers referenced from echo_area_buffer. */
553
554 static Lisp_Object echo_buffer[2];
555
556 /* A vector saved used in with_area_buffer to reduce consing. */
557
558 static Lisp_Object Vwith_echo_area_save_vector;
559
560 /* Non-zero means display_echo_area should display the last echo area
561 message again. Set by redisplay_preserve_echo_area. */
562
563 static bool display_last_displayed_message_p;
564
565 /* Nonzero if echo area is being used by print; zero if being used by
566 message. */
567
568 static bool message_buf_print;
569
570 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
571
572 static Lisp_Object Qinhibit_menubar_update;
573 static Lisp_Object Qmessage_truncate_lines;
574
575 /* Set to 1 in clear_message to make redisplay_internal aware
576 of an emptied echo area. */
577
578 static bool message_cleared_p;
579
580 /* A scratch glyph row with contents used for generating truncation
581 glyphs. Also used in direct_output_for_insert. */
582
583 #define MAX_SCRATCH_GLYPHS 100
584 static struct glyph_row scratch_glyph_row;
585 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
586
587 /* Ascent and height of the last line processed by move_it_to. */
588
589 static int last_height;
590
591 /* Non-zero if there's a help-echo in the echo area. */
592
593 bool help_echo_showing_p;
594
595 /* The maximum distance to look ahead for text properties. Values
596 that are too small let us call compute_char_face and similar
597 functions too often which is expensive. Values that are too large
598 let us call compute_char_face and alike too often because we
599 might not be interested in text properties that far away. */
600
601 #define TEXT_PROP_DISTANCE_LIMIT 100
602
603 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
604 iterator state and later restore it. This is needed because the
605 bidi iterator on bidi.c keeps a stacked cache of its states, which
606 is really a singleton. When we use scratch iterator objects to
607 move around the buffer, we can cause the bidi cache to be pushed or
608 popped, and therefore we need to restore the cache state when we
609 return to the original iterator. */
610 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
611 do { \
612 if (CACHE) \
613 bidi_unshelve_cache (CACHE, 1); \
614 ITCOPY = ITORIG; \
615 CACHE = bidi_shelve_cache (); \
616 } while (0)
617
618 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
619 do { \
620 if (pITORIG != pITCOPY) \
621 *(pITORIG) = *(pITCOPY); \
622 bidi_unshelve_cache (CACHE, 0); \
623 CACHE = NULL; \
624 } while (0)
625
626 /* Functions to mark elements as needing redisplay. */
627 enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
628
629 void
630 redisplay_other_windows (void)
631 {
632 if (!windows_or_buffers_changed)
633 windows_or_buffers_changed = REDISPLAY_SOME;
634 }
635
636 void
637 wset_redisplay (struct window *w)
638 {
639 /* Beware: selected_window can be nil during early stages. */
640 if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
641 redisplay_other_windows ();
642 w->redisplay = true;
643 }
644
645 void
646 fset_redisplay (struct frame *f)
647 {
648 redisplay_other_windows ();
649 f->redisplay = true;
650 }
651
652 void
653 bset_redisplay (struct buffer *b)
654 {
655 int count = buffer_window_count (b);
656 if (count > 0)
657 {
658 /* ... it's visible in other window than selected, */
659 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
660 redisplay_other_windows ();
661 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
662 so that if we later set windows_or_buffers_changed, this buffer will
663 not be omitted. */
664 b->text->redisplay = true;
665 }
666 }
667
668 void
669 bset_update_mode_line (struct buffer *b)
670 {
671 if (!update_mode_lines)
672 update_mode_lines = REDISPLAY_SOME;
673 b->text->redisplay = true;
674 }
675
676 #ifdef GLYPH_DEBUG
677
678 /* Non-zero means print traces of redisplay if compiled with
679 GLYPH_DEBUG defined. */
680
681 bool trace_redisplay_p;
682
683 #endif /* GLYPH_DEBUG */
684
685 #ifdef DEBUG_TRACE_MOVE
686 /* Non-zero means trace with TRACE_MOVE to stderr. */
687 int trace_move;
688
689 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
690 #else
691 #define TRACE_MOVE(x) (void) 0
692 #endif
693
694 static Lisp_Object Qauto_hscroll_mode;
695
696 /* Buffer being redisplayed -- for redisplay_window_error. */
697
698 static struct buffer *displayed_buffer;
699
700 /* Value returned from text property handlers (see below). */
701
702 enum prop_handled
703 {
704 HANDLED_NORMALLY,
705 HANDLED_RECOMPUTE_PROPS,
706 HANDLED_OVERLAY_STRING_CONSUMED,
707 HANDLED_RETURN
708 };
709
710 /* A description of text properties that redisplay is interested
711 in. */
712
713 struct props
714 {
715 /* The name of the property. */
716 Lisp_Object *name;
717
718 /* A unique index for the property. */
719 enum prop_idx idx;
720
721 /* A handler function called to set up iterator IT from the property
722 at IT's current position. Value is used to steer handle_stop. */
723 enum prop_handled (*handler) (struct it *it);
724 };
725
726 static enum prop_handled handle_face_prop (struct it *);
727 static enum prop_handled handle_invisible_prop (struct it *);
728 static enum prop_handled handle_display_prop (struct it *);
729 static enum prop_handled handle_composition_prop (struct it *);
730 static enum prop_handled handle_overlay_change (struct it *);
731 static enum prop_handled handle_fontified_prop (struct it *);
732
733 /* Properties handled by iterators. */
734
735 static struct props it_props[] =
736 {
737 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
738 /* Handle `face' before `display' because some sub-properties of
739 `display' need to know the face. */
740 {&Qface, FACE_PROP_IDX, handle_face_prop},
741 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
742 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
743 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
744 {NULL, 0, NULL}
745 };
746
747 /* Value is the position described by X. If X is a marker, value is
748 the marker_position of X. Otherwise, value is X. */
749
750 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
751
752 /* Enumeration returned by some move_it_.* functions internally. */
753
754 enum move_it_result
755 {
756 /* Not used. Undefined value. */
757 MOVE_UNDEFINED,
758
759 /* Move ended at the requested buffer position or ZV. */
760 MOVE_POS_MATCH_OR_ZV,
761
762 /* Move ended at the requested X pixel position. */
763 MOVE_X_REACHED,
764
765 /* Move within a line ended at the end of a line that must be
766 continued. */
767 MOVE_LINE_CONTINUED,
768
769 /* Move within a line ended at the end of a line that would
770 be displayed truncated. */
771 MOVE_LINE_TRUNCATED,
772
773 /* Move within a line ended at a line end. */
774 MOVE_NEWLINE_OR_CR
775 };
776
777 /* This counter is used to clear the face cache every once in a while
778 in redisplay_internal. It is incremented for each redisplay.
779 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
780 cleared. */
781
782 #define CLEAR_FACE_CACHE_COUNT 500
783 static int clear_face_cache_count;
784
785 /* Similarly for the image cache. */
786
787 #ifdef HAVE_WINDOW_SYSTEM
788 #define CLEAR_IMAGE_CACHE_COUNT 101
789 static int clear_image_cache_count;
790
791 /* Null glyph slice */
792 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
793 #endif
794
795 /* True while redisplay_internal is in progress. */
796
797 bool redisplaying_p;
798
799 static Lisp_Object Qinhibit_free_realized_faces;
800 static Lisp_Object Qmode_line_default_help_echo;
801
802 /* If a string, XTread_socket generates an event to display that string.
803 (The display is done in read_char.) */
804
805 Lisp_Object help_echo_string;
806 Lisp_Object help_echo_window;
807 Lisp_Object help_echo_object;
808 ptrdiff_t help_echo_pos;
809
810 /* Temporary variable for XTread_socket. */
811
812 Lisp_Object previous_help_echo_string;
813
814 /* Platform-independent portion of hourglass implementation. */
815
816 #ifdef HAVE_WINDOW_SYSTEM
817
818 /* Non-zero means an hourglass cursor is currently shown. */
819 static bool hourglass_shown_p;
820
821 /* If non-null, an asynchronous timer that, when it expires, displays
822 an hourglass cursor on all frames. */
823 static struct atimer *hourglass_atimer;
824
825 #endif /* HAVE_WINDOW_SYSTEM */
826
827 /* Name of the face used to display glyphless characters. */
828 static Lisp_Object Qglyphless_char;
829
830 /* Symbol for the purpose of Vglyphless_char_display. */
831 static Lisp_Object Qglyphless_char_display;
832
833 /* Method symbols for Vglyphless_char_display. */
834 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
835
836 /* Default number of seconds to wait before displaying an hourglass
837 cursor. */
838 #define DEFAULT_HOURGLASS_DELAY 1
839
840 #ifdef HAVE_WINDOW_SYSTEM
841
842 /* Default pixel width of `thin-space' display method. */
843 #define THIN_SPACE_WIDTH 1
844
845 #endif /* HAVE_WINDOW_SYSTEM */
846
847 /* Function prototypes. */
848
849 static void setup_for_ellipsis (struct it *, int);
850 static void set_iterator_to_next (struct it *, int);
851 static void mark_window_display_accurate_1 (struct window *, int);
852 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
853 static int display_prop_string_p (Lisp_Object, Lisp_Object);
854 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
855 static int cursor_row_p (struct glyph_row *);
856 static int redisplay_mode_lines (Lisp_Object, bool);
857 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
858
859 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
860
861 static void handle_line_prefix (struct it *);
862
863 static void pint2str (char *, int, ptrdiff_t);
864 static void pint2hrstr (char *, int, ptrdiff_t);
865 static struct text_pos run_window_scroll_functions (Lisp_Object,
866 struct text_pos);
867 static int text_outside_line_unchanged_p (struct window *,
868 ptrdiff_t, ptrdiff_t);
869 static void store_mode_line_noprop_char (char);
870 static int store_mode_line_noprop (const char *, int, int);
871 static void handle_stop (struct it *);
872 static void handle_stop_backwards (struct it *, ptrdiff_t);
873 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
874 static void ensure_echo_area_buffers (void);
875 static void unwind_with_echo_area_buffer (Lisp_Object);
876 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
877 static int with_echo_area_buffer (struct window *, int,
878 int (*) (ptrdiff_t, Lisp_Object),
879 ptrdiff_t, Lisp_Object);
880 static void clear_garbaged_frames (void);
881 static int current_message_1 (ptrdiff_t, Lisp_Object);
882 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
883 static void set_message (Lisp_Object);
884 static int set_message_1 (ptrdiff_t, Lisp_Object);
885 static int display_echo_area (struct window *);
886 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
887 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
888 static void unwind_redisplay (void);
889 static int string_char_and_length (const unsigned char *, int *);
890 static struct text_pos display_prop_end (struct it *, Lisp_Object,
891 struct text_pos);
892 static int compute_window_start_on_continuation_line (struct window *);
893 static void insert_left_trunc_glyphs (struct it *);
894 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
895 Lisp_Object);
896 static void extend_face_to_end_of_line (struct it *);
897 static int append_space_for_newline (struct it *, int);
898 static int cursor_row_fully_visible_p (struct window *, int, int);
899 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
900 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
901 static int trailing_whitespace_p (ptrdiff_t);
902 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
903 static void push_it (struct it *, struct text_pos *);
904 static void iterate_out_of_display_property (struct it *);
905 static void pop_it (struct it *);
906 static void sync_frame_with_window_matrix_rows (struct window *);
907 static void redisplay_internal (void);
908 static int echo_area_display (int);
909 static void redisplay_windows (Lisp_Object);
910 static void redisplay_window (Lisp_Object, bool);
911 static Lisp_Object redisplay_window_error (Lisp_Object);
912 static Lisp_Object redisplay_window_0 (Lisp_Object);
913 static Lisp_Object redisplay_window_1 (Lisp_Object);
914 static int set_cursor_from_row (struct window *, struct glyph_row *,
915 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
916 int, int);
917 static int update_menu_bar (struct frame *, int, int);
918 static int try_window_reusing_current_matrix (struct window *);
919 static int try_window_id (struct window *);
920 static int display_line (struct it *);
921 static int display_mode_lines (struct window *);
922 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
923 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
924 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
925 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
926 static void display_menu_bar (struct window *);
927 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
928 ptrdiff_t *);
929 static int display_string (const char *, Lisp_Object, Lisp_Object,
930 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
931 static void compute_line_metrics (struct it *);
932 static void run_redisplay_end_trigger_hook (struct it *);
933 static int get_overlay_strings (struct it *, ptrdiff_t);
934 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
935 static void next_overlay_string (struct it *);
936 static void reseat (struct it *, struct text_pos, int);
937 static void reseat_1 (struct it *, struct text_pos, int);
938 static void back_to_previous_visible_line_start (struct it *);
939 static void reseat_at_next_visible_line_start (struct it *, int);
940 static int next_element_from_ellipsis (struct it *);
941 static int next_element_from_display_vector (struct it *);
942 static int next_element_from_string (struct it *);
943 static int next_element_from_c_string (struct it *);
944 static int next_element_from_buffer (struct it *);
945 static int next_element_from_composition (struct it *);
946 static int next_element_from_image (struct it *);
947 static int next_element_from_stretch (struct it *);
948 static void load_overlay_strings (struct it *, ptrdiff_t);
949 static int init_from_display_pos (struct it *, struct window *,
950 struct display_pos *);
951 static void reseat_to_string (struct it *, const char *,
952 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
953 static int get_next_display_element (struct it *);
954 static enum move_it_result
955 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
956 enum move_operation_enum);
957 static void get_visually_first_element (struct it *);
958 static void init_to_row_start (struct it *, struct window *,
959 struct glyph_row *);
960 static int init_to_row_end (struct it *, struct window *,
961 struct glyph_row *);
962 static void back_to_previous_line_start (struct it *);
963 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
964 static struct text_pos string_pos_nchars_ahead (struct text_pos,
965 Lisp_Object, ptrdiff_t);
966 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
967 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
968 static ptrdiff_t number_of_chars (const char *, bool);
969 static void compute_stop_pos (struct it *);
970 static void compute_string_pos (struct text_pos *, struct text_pos,
971 Lisp_Object);
972 static int face_before_or_after_it_pos (struct it *, int);
973 static ptrdiff_t next_overlay_change (ptrdiff_t);
974 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
975 Lisp_Object, struct text_pos *, ptrdiff_t, int);
976 static int handle_single_display_spec (struct it *, Lisp_Object,
977 Lisp_Object, Lisp_Object,
978 struct text_pos *, ptrdiff_t, int, int);
979 static int underlying_face_id (struct it *);
980 static int in_ellipses_for_invisible_text_p (struct display_pos *,
981 struct window *);
982
983 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
984 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
985
986 #ifdef HAVE_WINDOW_SYSTEM
987
988 static void x_consider_frame_title (Lisp_Object);
989 static void update_tool_bar (struct frame *, int);
990 static int redisplay_tool_bar (struct frame *);
991 static void x_draw_bottom_divider (struct window *w);
992 static void notice_overwritten_cursor (struct window *,
993 enum glyph_row_area,
994 int, int, int, int);
995 static void append_stretch_glyph (struct it *, Lisp_Object,
996 int, int, int);
997
998
999 #endif /* HAVE_WINDOW_SYSTEM */
1000
1001 static void produce_special_glyphs (struct it *, enum display_element_type);
1002 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
1003 static bool coords_in_mouse_face_p (struct window *, int, int);
1004
1005
1006 \f
1007 /***********************************************************************
1008 Window display dimensions
1009 ***********************************************************************/
1010
1011 /* Return the bottom boundary y-position for text lines in window W.
1012 This is the first y position at which a line cannot start.
1013 It is relative to the top of the window.
1014
1015 This is the height of W minus the height of a mode line, if any. */
1016
1017 int
1018 window_text_bottom_y (struct window *w)
1019 {
1020 int height = WINDOW_PIXEL_HEIGHT (w);
1021
1022 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
1023
1024 if (WINDOW_WANTS_MODELINE_P (w))
1025 height -= CURRENT_MODE_LINE_HEIGHT (w);
1026
1027 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
1028
1029 return height;
1030 }
1031
1032 /* Return the pixel width of display area AREA of window W.
1033 ANY_AREA means return the total width of W, not including
1034 fringes to the left and right of the window. */
1035
1036 int
1037 window_box_width (struct window *w, enum glyph_row_area area)
1038 {
1039 int width = w->pixel_width;
1040
1041 if (!w->pseudo_window_p)
1042 {
1043 width -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
1044 width -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
1045
1046 if (area == TEXT_AREA)
1047 width -= (WINDOW_MARGINS_WIDTH (w)
1048 + WINDOW_FRINGES_WIDTH (w));
1049 else if (area == LEFT_MARGIN_AREA)
1050 width = WINDOW_LEFT_MARGIN_WIDTH (w);
1051 else if (area == RIGHT_MARGIN_AREA)
1052 width = WINDOW_RIGHT_MARGIN_WIDTH (w);
1053 }
1054
1055 /* With wide margins, fringes, etc. we might end up with a negative
1056 width, correct that here. */
1057 return max (0, width);
1058 }
1059
1060
1061 /* Return the pixel height of the display area of window W, not
1062 including mode lines of W, if any. */
1063
1064 int
1065 window_box_height (struct window *w)
1066 {
1067 struct frame *f = XFRAME (w->frame);
1068 int height = WINDOW_PIXEL_HEIGHT (w);
1069
1070 eassert (height >= 0);
1071
1072 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
1073 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
1074
1075 /* Note: the code below that determines the mode-line/header-line
1076 height is essentially the same as that contained in the macro
1077 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1078 the appropriate glyph row has its `mode_line_p' flag set,
1079 and if it doesn't, uses estimate_mode_line_height instead. */
1080
1081 if (WINDOW_WANTS_MODELINE_P (w))
1082 {
1083 struct glyph_row *ml_row
1084 = (w->current_matrix && w->current_matrix->rows
1085 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1086 : 0);
1087 if (ml_row && ml_row->mode_line_p)
1088 height -= ml_row->height;
1089 else
1090 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1091 }
1092
1093 if (WINDOW_WANTS_HEADER_LINE_P (w))
1094 {
1095 struct glyph_row *hl_row
1096 = (w->current_matrix && w->current_matrix->rows
1097 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1098 : 0);
1099 if (hl_row && hl_row->mode_line_p)
1100 height -= hl_row->height;
1101 else
1102 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1103 }
1104
1105 /* With a very small font and a mode-line that's taller than
1106 default, we might end up with a negative height. */
1107 return max (0, height);
1108 }
1109
1110 /* Return the window-relative coordinate of the left edge of display
1111 area AREA of window W. ANY_AREA means return the left edge of the
1112 whole window, to the right of the left fringe of W. */
1113
1114 int
1115 window_box_left_offset (struct window *w, enum glyph_row_area area)
1116 {
1117 int x;
1118
1119 if (w->pseudo_window_p)
1120 return 0;
1121
1122 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1123
1124 if (area == TEXT_AREA)
1125 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1126 + window_box_width (w, LEFT_MARGIN_AREA));
1127 else if (area == RIGHT_MARGIN_AREA)
1128 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1129 + window_box_width (w, LEFT_MARGIN_AREA)
1130 + window_box_width (w, TEXT_AREA)
1131 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1132 ? 0
1133 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1134 else if (area == LEFT_MARGIN_AREA
1135 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1136 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1137
1138 /* Don't return more than the window's pixel width. */
1139 return min (x, w->pixel_width);
1140 }
1141
1142
1143 /* Return the window-relative coordinate of the right edge of display
1144 area AREA of window W. ANY_AREA means return the right edge of the
1145 whole window, to the left of the right fringe of W. */
1146
1147 int
1148 window_box_right_offset (struct window *w, enum glyph_row_area area)
1149 {
1150 /* Don't return more than the window's pixel width. */
1151 return min (window_box_left_offset (w, area) + window_box_width (w, area),
1152 w->pixel_width);
1153 }
1154
1155 /* Return the frame-relative coordinate of the left edge of display
1156 area AREA of window W. ANY_AREA means return the left edge of the
1157 whole window, to the right of the left fringe of W. */
1158
1159 int
1160 window_box_left (struct window *w, enum glyph_row_area area)
1161 {
1162 struct frame *f = XFRAME (w->frame);
1163 int x;
1164
1165 if (w->pseudo_window_p)
1166 return FRAME_INTERNAL_BORDER_WIDTH (f);
1167
1168 x = (WINDOW_LEFT_EDGE_X (w)
1169 + window_box_left_offset (w, area));
1170
1171 return x;
1172 }
1173
1174
1175 /* Return the frame-relative coordinate of the right edge of display
1176 area AREA of window W. ANY_AREA means return the right edge of the
1177 whole window, to the left of the right fringe of W. */
1178
1179 int
1180 window_box_right (struct window *w, enum glyph_row_area area)
1181 {
1182 return window_box_left (w, area) + window_box_width (w, area);
1183 }
1184
1185 /* Get the bounding box of the display area AREA of window W, without
1186 mode lines, in frame-relative coordinates. ANY_AREA means the
1187 whole window, not including the left and right fringes of
1188 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1189 coordinates of the upper-left corner of the box. Return in
1190 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1191
1192 void
1193 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1194 int *box_y, int *box_width, int *box_height)
1195 {
1196 if (box_width)
1197 *box_width = window_box_width (w, area);
1198 if (box_height)
1199 *box_height = window_box_height (w);
1200 if (box_x)
1201 *box_x = window_box_left (w, area);
1202 if (box_y)
1203 {
1204 *box_y = WINDOW_TOP_EDGE_Y (w);
1205 if (WINDOW_WANTS_HEADER_LINE_P (w))
1206 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1207 }
1208 }
1209
1210 #ifdef HAVE_WINDOW_SYSTEM
1211
1212 /* Get the bounding box of the display area AREA of window W, without
1213 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1214 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1215 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1216 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1217 box. */
1218
1219 static void
1220 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1221 int *bottom_right_x, int *bottom_right_y)
1222 {
1223 window_box (w, ANY_AREA, top_left_x, top_left_y,
1224 bottom_right_x, bottom_right_y);
1225 *bottom_right_x += *top_left_x;
1226 *bottom_right_y += *top_left_y;
1227 }
1228
1229 #endif /* HAVE_WINDOW_SYSTEM */
1230
1231 /***********************************************************************
1232 Utilities
1233 ***********************************************************************/
1234
1235 /* Return the bottom y-position of the line the iterator IT is in.
1236 This can modify IT's settings. */
1237
1238 int
1239 line_bottom_y (struct it *it)
1240 {
1241 int line_height = it->max_ascent + it->max_descent;
1242 int line_top_y = it->current_y;
1243
1244 if (line_height == 0)
1245 {
1246 if (last_height)
1247 line_height = last_height;
1248 else if (IT_CHARPOS (*it) < ZV)
1249 {
1250 move_it_by_lines (it, 1);
1251 line_height = (it->max_ascent || it->max_descent
1252 ? it->max_ascent + it->max_descent
1253 : last_height);
1254 }
1255 else
1256 {
1257 struct glyph_row *row = it->glyph_row;
1258
1259 /* Use the default character height. */
1260 it->glyph_row = NULL;
1261 it->what = IT_CHARACTER;
1262 it->c = ' ';
1263 it->len = 1;
1264 PRODUCE_GLYPHS (it);
1265 line_height = it->ascent + it->descent;
1266 it->glyph_row = row;
1267 }
1268 }
1269
1270 return line_top_y + line_height;
1271 }
1272
1273 DEFUN ("line-pixel-height", Fline_pixel_height,
1274 Sline_pixel_height, 0, 0, 0,
1275 doc: /* Return height in pixels of text line in the selected window.
1276
1277 Value is the height in pixels of the line at point. */)
1278 (void)
1279 {
1280 struct it it;
1281 struct text_pos pt;
1282 struct window *w = XWINDOW (selected_window);
1283 struct buffer *old_buffer = NULL;
1284 Lisp_Object result;
1285
1286 if (XBUFFER (w->contents) != current_buffer)
1287 {
1288 old_buffer = current_buffer;
1289 set_buffer_internal_1 (XBUFFER (w->contents));
1290 }
1291 SET_TEXT_POS (pt, PT, PT_BYTE);
1292 start_display (&it, w, pt);
1293 it.vpos = it.current_y = 0;
1294 last_height = 0;
1295 result = make_number (line_bottom_y (&it));
1296 if (old_buffer)
1297 set_buffer_internal_1 (old_buffer);
1298
1299 return result;
1300 }
1301
1302 /* Return the default pixel height of text lines in window W. The
1303 value is the canonical height of the W frame's default font, plus
1304 any extra space required by the line-spacing variable or frame
1305 parameter.
1306
1307 Implementation note: this ignores any line-spacing text properties
1308 put on the newline characters. This is because those properties
1309 only affect the _screen_ line ending in the newline (i.e., in a
1310 continued line, only the last screen line will be affected), which
1311 means only a small number of lines in a buffer can ever use this
1312 feature. Since this function is used to compute the default pixel
1313 equivalent of text lines in a window, we can safely ignore those
1314 few lines. For the same reasons, we ignore the line-height
1315 properties. */
1316 int
1317 default_line_pixel_height (struct window *w)
1318 {
1319 struct frame *f = WINDOW_XFRAME (w);
1320 int height = FRAME_LINE_HEIGHT (f);
1321
1322 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1323 {
1324 struct buffer *b = XBUFFER (w->contents);
1325 Lisp_Object val = BVAR (b, extra_line_spacing);
1326
1327 if (NILP (val))
1328 val = BVAR (&buffer_defaults, extra_line_spacing);
1329 if (!NILP (val))
1330 {
1331 if (RANGED_INTEGERP (0, val, INT_MAX))
1332 height += XFASTINT (val);
1333 else if (FLOATP (val))
1334 {
1335 int addon = XFLOAT_DATA (val) * height + 0.5;
1336
1337 if (addon >= 0)
1338 height += addon;
1339 }
1340 }
1341 else
1342 height += f->extra_line_spacing;
1343 }
1344
1345 return height;
1346 }
1347
1348 /* Subroutine of pos_visible_p below. Extracts a display string, if
1349 any, from the display spec given as its argument. */
1350 static Lisp_Object
1351 string_from_display_spec (Lisp_Object spec)
1352 {
1353 if (CONSP (spec))
1354 {
1355 while (CONSP (spec))
1356 {
1357 if (STRINGP (XCAR (spec)))
1358 return XCAR (spec);
1359 spec = XCDR (spec);
1360 }
1361 }
1362 else if (VECTORP (spec))
1363 {
1364 ptrdiff_t i;
1365
1366 for (i = 0; i < ASIZE (spec); i++)
1367 {
1368 if (STRINGP (AREF (spec, i)))
1369 return AREF (spec, i);
1370 }
1371 return Qnil;
1372 }
1373
1374 return spec;
1375 }
1376
1377
1378 /* Limit insanely large values of W->hscroll on frame F to the largest
1379 value that will still prevent first_visible_x and last_visible_x of
1380 'struct it' from overflowing an int. */
1381 static int
1382 window_hscroll_limited (struct window *w, struct frame *f)
1383 {
1384 ptrdiff_t window_hscroll = w->hscroll;
1385 int window_text_width = window_box_width (w, TEXT_AREA);
1386 int colwidth = FRAME_COLUMN_WIDTH (f);
1387
1388 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1389 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1390
1391 return window_hscroll;
1392 }
1393
1394 /* Return 1 if position CHARPOS is visible in window W.
1395 CHARPOS < 0 means return info about WINDOW_END position.
1396 If visible, set *X and *Y to pixel coordinates of top left corner.
1397 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1398 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1399
1400 int
1401 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1402 int *rtop, int *rbot, int *rowh, int *vpos)
1403 {
1404 struct it it;
1405 void *itdata = bidi_shelve_cache ();
1406 struct text_pos top;
1407 int visible_p = 0;
1408 struct buffer *old_buffer = NULL;
1409
1410 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1411 return visible_p;
1412
1413 if (XBUFFER (w->contents) != current_buffer)
1414 {
1415 old_buffer = current_buffer;
1416 set_buffer_internal_1 (XBUFFER (w->contents));
1417 }
1418
1419 SET_TEXT_POS_FROM_MARKER (top, w->start);
1420 /* Scrolling a minibuffer window via scroll bar when the echo area
1421 shows long text sometimes resets the minibuffer contents behind
1422 our backs. */
1423 if (CHARPOS (top) > ZV)
1424 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1425
1426 /* Compute exact mode line heights. */
1427 if (WINDOW_WANTS_MODELINE_P (w))
1428 w->mode_line_height
1429 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1430 BVAR (current_buffer, mode_line_format));
1431
1432 if (WINDOW_WANTS_HEADER_LINE_P (w))
1433 w->header_line_height
1434 = display_mode_line (w, HEADER_LINE_FACE_ID,
1435 BVAR (current_buffer, header_line_format));
1436
1437 start_display (&it, w, top);
1438 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1439 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1440
1441 if (charpos >= 0
1442 && (((!it.bidi_p || it.bidi_it.scan_dir != -1)
1443 && IT_CHARPOS (it) >= charpos)
1444 /* When scanning backwards under bidi iteration, move_it_to
1445 stops at or _before_ CHARPOS, because it stops at or to
1446 the _right_ of the character at CHARPOS. */
1447 || (it.bidi_p && it.bidi_it.scan_dir == -1
1448 && IT_CHARPOS (it) <= charpos)))
1449 {
1450 /* We have reached CHARPOS, or passed it. How the call to
1451 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1452 or covered by a display property, move_it_to stops at the end
1453 of the invisible text, to the right of CHARPOS. (ii) If
1454 CHARPOS is in a display vector, move_it_to stops on its last
1455 glyph. */
1456 int top_x = it.current_x;
1457 int top_y = it.current_y;
1458 /* Calling line_bottom_y may change it.method, it.position, etc. */
1459 enum it_method it_method = it.method;
1460 int bottom_y = (last_height = 0, line_bottom_y (&it));
1461 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1462
1463 if (top_y < window_top_y)
1464 visible_p = bottom_y > window_top_y;
1465 else if (top_y < it.last_visible_y)
1466 visible_p = true;
1467 if (bottom_y >= it.last_visible_y
1468 && it.bidi_p && it.bidi_it.scan_dir == -1
1469 && IT_CHARPOS (it) < charpos)
1470 {
1471 /* When the last line of the window is scanned backwards
1472 under bidi iteration, we could be duped into thinking
1473 that we have passed CHARPOS, when in fact move_it_to
1474 simply stopped short of CHARPOS because it reached
1475 last_visible_y. To see if that's what happened, we call
1476 move_it_to again with a slightly larger vertical limit,
1477 and see if it actually moved vertically; if it did, we
1478 didn't really reach CHARPOS, which is beyond window end. */
1479 struct it save_it = it;
1480 /* Why 10? because we don't know how many canonical lines
1481 will the height of the next line(s) be. So we guess. */
1482 int ten_more_lines = 10 * default_line_pixel_height (w);
1483
1484 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1485 MOVE_TO_POS | MOVE_TO_Y);
1486 if (it.current_y > top_y)
1487 visible_p = 0;
1488
1489 it = save_it;
1490 }
1491 if (visible_p)
1492 {
1493 if (it_method == GET_FROM_DISPLAY_VECTOR)
1494 {
1495 /* We stopped on the last glyph of a display vector.
1496 Try and recompute. Hack alert! */
1497 if (charpos < 2 || top.charpos >= charpos)
1498 top_x = it.glyph_row->x;
1499 else
1500 {
1501 struct it it2, it2_prev;
1502 /* The idea is to get to the previous buffer
1503 position, consume the character there, and use
1504 the pixel coordinates we get after that. But if
1505 the previous buffer position is also displayed
1506 from a display vector, we need to consume all of
1507 the glyphs from that display vector. */
1508 start_display (&it2, w, top);
1509 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1510 /* If we didn't get to CHARPOS - 1, there's some
1511 replacing display property at that position, and
1512 we stopped after it. That is exactly the place
1513 whose coordinates we want. */
1514 if (IT_CHARPOS (it2) != charpos - 1)
1515 it2_prev = it2;
1516 else
1517 {
1518 /* Iterate until we get out of the display
1519 vector that displays the character at
1520 CHARPOS - 1. */
1521 do {
1522 get_next_display_element (&it2);
1523 PRODUCE_GLYPHS (&it2);
1524 it2_prev = it2;
1525 set_iterator_to_next (&it2, 1);
1526 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1527 && IT_CHARPOS (it2) < charpos);
1528 }
1529 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1530 || it2_prev.current_x > it2_prev.last_visible_x)
1531 top_x = it.glyph_row->x;
1532 else
1533 {
1534 top_x = it2_prev.current_x;
1535 top_y = it2_prev.current_y;
1536 }
1537 }
1538 }
1539 else if (IT_CHARPOS (it) != charpos)
1540 {
1541 Lisp_Object cpos = make_number (charpos);
1542 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1543 Lisp_Object string = string_from_display_spec (spec);
1544 struct text_pos tpos;
1545 int replacing_spec_p;
1546 bool newline_in_string
1547 = (STRINGP (string)
1548 && memchr (SDATA (string), '\n', SBYTES (string)));
1549
1550 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1551 replacing_spec_p
1552 = (!NILP (spec)
1553 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1554 charpos, FRAME_WINDOW_P (it.f)));
1555 /* The tricky code below is needed because there's a
1556 discrepancy between move_it_to and how we set cursor
1557 when PT is at the beginning of a portion of text
1558 covered by a display property or an overlay with a
1559 display property, or the display line ends in a
1560 newline from a display string. move_it_to will stop
1561 _after_ such display strings, whereas
1562 set_cursor_from_row conspires with cursor_row_p to
1563 place the cursor on the first glyph produced from the
1564 display string. */
1565
1566 /* We have overshoot PT because it is covered by a
1567 display property that replaces the text it covers.
1568 If the string includes embedded newlines, we are also
1569 in the wrong display line. Backtrack to the correct
1570 line, where the display property begins. */
1571 if (replacing_spec_p)
1572 {
1573 Lisp_Object startpos, endpos;
1574 EMACS_INT start, end;
1575 struct it it3;
1576 int it3_moved;
1577
1578 /* Find the first and the last buffer positions
1579 covered by the display string. */
1580 endpos =
1581 Fnext_single_char_property_change (cpos, Qdisplay,
1582 Qnil, Qnil);
1583 startpos =
1584 Fprevious_single_char_property_change (endpos, Qdisplay,
1585 Qnil, Qnil);
1586 start = XFASTINT (startpos);
1587 end = XFASTINT (endpos);
1588 /* Move to the last buffer position before the
1589 display property. */
1590 start_display (&it3, w, top);
1591 if (start > CHARPOS (top))
1592 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1593 /* Move forward one more line if the position before
1594 the display string is a newline or if it is the
1595 rightmost character on a line that is
1596 continued or word-wrapped. */
1597 if (it3.method == GET_FROM_BUFFER
1598 && (it3.c == '\n'
1599 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1600 move_it_by_lines (&it3, 1);
1601 else if (move_it_in_display_line_to (&it3, -1,
1602 it3.current_x
1603 + it3.pixel_width,
1604 MOVE_TO_X)
1605 == MOVE_LINE_CONTINUED)
1606 {
1607 move_it_by_lines (&it3, 1);
1608 /* When we are under word-wrap, the #$@%!
1609 move_it_by_lines moves 2 lines, so we need to
1610 fix that up. */
1611 if (it3.line_wrap == WORD_WRAP)
1612 move_it_by_lines (&it3, -1);
1613 }
1614
1615 /* Record the vertical coordinate of the display
1616 line where we wound up. */
1617 top_y = it3.current_y;
1618 if (it3.bidi_p)
1619 {
1620 /* When characters are reordered for display,
1621 the character displayed to the left of the
1622 display string could be _after_ the display
1623 property in the logical order. Use the
1624 smallest vertical position of these two. */
1625 start_display (&it3, w, top);
1626 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1627 if (it3.current_y < top_y)
1628 top_y = it3.current_y;
1629 }
1630 /* Move from the top of the window to the beginning
1631 of the display line where the display string
1632 begins. */
1633 start_display (&it3, w, top);
1634 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1635 /* If it3_moved stays zero after the 'while' loop
1636 below, that means we already were at a newline
1637 before the loop (e.g., the display string begins
1638 with a newline), so we don't need to (and cannot)
1639 inspect the glyphs of it3.glyph_row, because
1640 PRODUCE_GLYPHS will not produce anything for a
1641 newline, and thus it3.glyph_row stays at its
1642 stale content it got at top of the window. */
1643 it3_moved = 0;
1644 /* Finally, advance the iterator until we hit the
1645 first display element whose character position is
1646 CHARPOS, or until the first newline from the
1647 display string, which signals the end of the
1648 display line. */
1649 while (get_next_display_element (&it3))
1650 {
1651 PRODUCE_GLYPHS (&it3);
1652 if (IT_CHARPOS (it3) == charpos
1653 || ITERATOR_AT_END_OF_LINE_P (&it3))
1654 break;
1655 it3_moved = 1;
1656 set_iterator_to_next (&it3, 0);
1657 }
1658 top_x = it3.current_x - it3.pixel_width;
1659 /* Normally, we would exit the above loop because we
1660 found the display element whose character
1661 position is CHARPOS. For the contingency that we
1662 didn't, and stopped at the first newline from the
1663 display string, move back over the glyphs
1664 produced from the string, until we find the
1665 rightmost glyph not from the string. */
1666 if (it3_moved
1667 && newline_in_string
1668 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1669 {
1670 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1671 + it3.glyph_row->used[TEXT_AREA];
1672
1673 while (EQ ((g - 1)->object, string))
1674 {
1675 --g;
1676 top_x -= g->pixel_width;
1677 }
1678 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1679 + it3.glyph_row->used[TEXT_AREA]);
1680 }
1681 }
1682 }
1683
1684 *x = top_x;
1685 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1686 *rtop = max (0, window_top_y - top_y);
1687 *rbot = max (0, bottom_y - it.last_visible_y);
1688 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1689 - max (top_y, window_top_y)));
1690 *vpos = it.vpos;
1691 }
1692 }
1693 else
1694 {
1695 /* Either we were asked to provide info about WINDOW_END, or
1696 CHARPOS is in the partially visible glyph row at end of
1697 window. */
1698 struct it it2;
1699 void *it2data = NULL;
1700
1701 SAVE_IT (it2, it, it2data);
1702 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1703 move_it_by_lines (&it, 1);
1704 if (charpos < IT_CHARPOS (it)
1705 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1706 {
1707 visible_p = true;
1708 RESTORE_IT (&it2, &it2, it2data);
1709 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1710 *x = it2.current_x;
1711 *y = it2.current_y + it2.max_ascent - it2.ascent;
1712 *rtop = max (0, -it2.current_y);
1713 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1714 - it.last_visible_y));
1715 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1716 it.last_visible_y)
1717 - max (it2.current_y,
1718 WINDOW_HEADER_LINE_HEIGHT (w))));
1719 *vpos = it2.vpos;
1720 }
1721 else
1722 bidi_unshelve_cache (it2data, 1);
1723 }
1724 bidi_unshelve_cache (itdata, 0);
1725
1726 if (old_buffer)
1727 set_buffer_internal_1 (old_buffer);
1728
1729 if (visible_p && w->hscroll > 0)
1730 *x -=
1731 window_hscroll_limited (w, WINDOW_XFRAME (w))
1732 * WINDOW_FRAME_COLUMN_WIDTH (w);
1733
1734 #if 0
1735 /* Debugging code. */
1736 if (visible_p)
1737 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1738 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1739 else
1740 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1741 #endif
1742
1743 return visible_p;
1744 }
1745
1746
1747 /* Return the next character from STR. Return in *LEN the length of
1748 the character. This is like STRING_CHAR_AND_LENGTH but never
1749 returns an invalid character. If we find one, we return a `?', but
1750 with the length of the invalid character. */
1751
1752 static int
1753 string_char_and_length (const unsigned char *str, int *len)
1754 {
1755 int c;
1756
1757 c = STRING_CHAR_AND_LENGTH (str, *len);
1758 if (!CHAR_VALID_P (c))
1759 /* We may not change the length here because other places in Emacs
1760 don't use this function, i.e. they silently accept invalid
1761 characters. */
1762 c = '?';
1763
1764 return c;
1765 }
1766
1767
1768
1769 /* Given a position POS containing a valid character and byte position
1770 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1771
1772 static struct text_pos
1773 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1774 {
1775 eassert (STRINGP (string) && nchars >= 0);
1776
1777 if (STRING_MULTIBYTE (string))
1778 {
1779 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1780 int len;
1781
1782 while (nchars--)
1783 {
1784 string_char_and_length (p, &len);
1785 p += len;
1786 CHARPOS (pos) += 1;
1787 BYTEPOS (pos) += len;
1788 }
1789 }
1790 else
1791 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1792
1793 return pos;
1794 }
1795
1796
1797 /* Value is the text position, i.e. character and byte position,
1798 for character position CHARPOS in STRING. */
1799
1800 static struct text_pos
1801 string_pos (ptrdiff_t charpos, Lisp_Object string)
1802 {
1803 struct text_pos pos;
1804 eassert (STRINGP (string));
1805 eassert (charpos >= 0);
1806 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1807 return pos;
1808 }
1809
1810
1811 /* Value is a text position, i.e. character and byte position, for
1812 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1813 means recognize multibyte characters. */
1814
1815 static struct text_pos
1816 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1817 {
1818 struct text_pos pos;
1819
1820 eassert (s != NULL);
1821 eassert (charpos >= 0);
1822
1823 if (multibyte_p)
1824 {
1825 int len;
1826
1827 SET_TEXT_POS (pos, 0, 0);
1828 while (charpos--)
1829 {
1830 string_char_and_length ((const unsigned char *) s, &len);
1831 s += len;
1832 CHARPOS (pos) += 1;
1833 BYTEPOS (pos) += len;
1834 }
1835 }
1836 else
1837 SET_TEXT_POS (pos, charpos, charpos);
1838
1839 return pos;
1840 }
1841
1842
1843 /* Value is the number of characters in C string S. MULTIBYTE_P
1844 non-zero means recognize multibyte characters. */
1845
1846 static ptrdiff_t
1847 number_of_chars (const char *s, bool multibyte_p)
1848 {
1849 ptrdiff_t nchars;
1850
1851 if (multibyte_p)
1852 {
1853 ptrdiff_t rest = strlen (s);
1854 int len;
1855 const unsigned char *p = (const unsigned char *) s;
1856
1857 for (nchars = 0; rest > 0; ++nchars)
1858 {
1859 string_char_and_length (p, &len);
1860 rest -= len, p += len;
1861 }
1862 }
1863 else
1864 nchars = strlen (s);
1865
1866 return nchars;
1867 }
1868
1869
1870 /* Compute byte position NEWPOS->bytepos corresponding to
1871 NEWPOS->charpos. POS is a known position in string STRING.
1872 NEWPOS->charpos must be >= POS.charpos. */
1873
1874 static void
1875 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1876 {
1877 eassert (STRINGP (string));
1878 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1879
1880 if (STRING_MULTIBYTE (string))
1881 *newpos = string_pos_nchars_ahead (pos, string,
1882 CHARPOS (*newpos) - CHARPOS (pos));
1883 else
1884 BYTEPOS (*newpos) = CHARPOS (*newpos);
1885 }
1886
1887 /* EXPORT:
1888 Return an estimation of the pixel height of mode or header lines on
1889 frame F. FACE_ID specifies what line's height to estimate. */
1890
1891 int
1892 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1893 {
1894 #ifdef HAVE_WINDOW_SYSTEM
1895 if (FRAME_WINDOW_P (f))
1896 {
1897 int height = FONT_HEIGHT (FRAME_FONT (f));
1898
1899 /* This function is called so early when Emacs starts that the face
1900 cache and mode line face are not yet initialized. */
1901 if (FRAME_FACE_CACHE (f))
1902 {
1903 struct face *face = FACE_FROM_ID (f, face_id);
1904 if (face)
1905 {
1906 if (face->font)
1907 height = FONT_HEIGHT (face->font);
1908 if (face->box_line_width > 0)
1909 height += 2 * face->box_line_width;
1910 }
1911 }
1912
1913 return height;
1914 }
1915 #endif
1916
1917 return 1;
1918 }
1919
1920 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1921 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1922 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1923 not force the value into range. */
1924
1925 void
1926 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1927 int *x, int *y, NativeRectangle *bounds, int noclip)
1928 {
1929
1930 #ifdef HAVE_WINDOW_SYSTEM
1931 if (FRAME_WINDOW_P (f))
1932 {
1933 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1934 even for negative values. */
1935 if (pix_x < 0)
1936 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1937 if (pix_y < 0)
1938 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1939
1940 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1941 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1942
1943 if (bounds)
1944 STORE_NATIVE_RECT (*bounds,
1945 FRAME_COL_TO_PIXEL_X (f, pix_x),
1946 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1947 FRAME_COLUMN_WIDTH (f) - 1,
1948 FRAME_LINE_HEIGHT (f) - 1);
1949
1950 /* PXW: Should we clip pixels before converting to columns/lines? */
1951 if (!noclip)
1952 {
1953 if (pix_x < 0)
1954 pix_x = 0;
1955 else if (pix_x > FRAME_TOTAL_COLS (f))
1956 pix_x = FRAME_TOTAL_COLS (f);
1957
1958 if (pix_y < 0)
1959 pix_y = 0;
1960 else if (pix_y > FRAME_TOTAL_LINES (f))
1961 pix_y = FRAME_TOTAL_LINES (f);
1962 }
1963 }
1964 #endif
1965
1966 *x = pix_x;
1967 *y = pix_y;
1968 }
1969
1970
1971 /* Find the glyph under window-relative coordinates X/Y in window W.
1972 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1973 strings. Return in *HPOS and *VPOS the row and column number of
1974 the glyph found. Return in *AREA the glyph area containing X.
1975 Value is a pointer to the glyph found or null if X/Y is not on
1976 text, or we can't tell because W's current matrix is not up to
1977 date. */
1978
1979 static struct glyph *
1980 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1981 int *dx, int *dy, int *area)
1982 {
1983 struct glyph *glyph, *end;
1984 struct glyph_row *row = NULL;
1985 int x0, i;
1986
1987 /* Find row containing Y. Give up if some row is not enabled. */
1988 for (i = 0; i < w->current_matrix->nrows; ++i)
1989 {
1990 row = MATRIX_ROW (w->current_matrix, i);
1991 if (!row->enabled_p)
1992 return NULL;
1993 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1994 break;
1995 }
1996
1997 *vpos = i;
1998 *hpos = 0;
1999
2000 /* Give up if Y is not in the window. */
2001 if (i == w->current_matrix->nrows)
2002 return NULL;
2003
2004 /* Get the glyph area containing X. */
2005 if (w->pseudo_window_p)
2006 {
2007 *area = TEXT_AREA;
2008 x0 = 0;
2009 }
2010 else
2011 {
2012 if (x < window_box_left_offset (w, TEXT_AREA))
2013 {
2014 *area = LEFT_MARGIN_AREA;
2015 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
2016 }
2017 else if (x < window_box_right_offset (w, TEXT_AREA))
2018 {
2019 *area = TEXT_AREA;
2020 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
2021 }
2022 else
2023 {
2024 *area = RIGHT_MARGIN_AREA;
2025 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
2026 }
2027 }
2028
2029 /* Find glyph containing X. */
2030 glyph = row->glyphs[*area];
2031 end = glyph + row->used[*area];
2032 x -= x0;
2033 while (glyph < end && x >= glyph->pixel_width)
2034 {
2035 x -= glyph->pixel_width;
2036 ++glyph;
2037 }
2038
2039 if (glyph == end)
2040 return NULL;
2041
2042 if (dx)
2043 {
2044 *dx = x;
2045 *dy = y - (row->y + row->ascent - glyph->ascent);
2046 }
2047
2048 *hpos = glyph - row->glyphs[*area];
2049 return glyph;
2050 }
2051
2052 /* Convert frame-relative x/y to coordinates relative to window W.
2053 Takes pseudo-windows into account. */
2054
2055 static void
2056 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2057 {
2058 if (w->pseudo_window_p)
2059 {
2060 /* A pseudo-window is always full-width, and starts at the
2061 left edge of the frame, plus a frame border. */
2062 struct frame *f = XFRAME (w->frame);
2063 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2064 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2065 }
2066 else
2067 {
2068 *x -= WINDOW_LEFT_EDGE_X (w);
2069 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2070 }
2071 }
2072
2073 #ifdef HAVE_WINDOW_SYSTEM
2074
2075 /* EXPORT:
2076 Return in RECTS[] at most N clipping rectangles for glyph string S.
2077 Return the number of stored rectangles. */
2078
2079 int
2080 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2081 {
2082 XRectangle r;
2083
2084 if (n <= 0)
2085 return 0;
2086
2087 if (s->row->full_width_p)
2088 {
2089 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2090 r.x = WINDOW_LEFT_EDGE_X (s->w);
2091 if (s->row->mode_line_p)
2092 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2093 else
2094 r.width = WINDOW_PIXEL_WIDTH (s->w);
2095
2096 /* Unless displaying a mode or menu bar line, which are always
2097 fully visible, clip to the visible part of the row. */
2098 if (s->w->pseudo_window_p)
2099 r.height = s->row->visible_height;
2100 else
2101 r.height = s->height;
2102 }
2103 else
2104 {
2105 /* This is a text line that may be partially visible. */
2106 r.x = window_box_left (s->w, s->area);
2107 r.width = window_box_width (s->w, s->area);
2108 r.height = s->row->visible_height;
2109 }
2110
2111 if (s->clip_head)
2112 if (r.x < s->clip_head->x)
2113 {
2114 if (r.width >= s->clip_head->x - r.x)
2115 r.width -= s->clip_head->x - r.x;
2116 else
2117 r.width = 0;
2118 r.x = s->clip_head->x;
2119 }
2120 if (s->clip_tail)
2121 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2122 {
2123 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2124 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2125 else
2126 r.width = 0;
2127 }
2128
2129 /* If S draws overlapping rows, it's sufficient to use the top and
2130 bottom of the window for clipping because this glyph string
2131 intentionally draws over other lines. */
2132 if (s->for_overlaps)
2133 {
2134 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2135 r.height = window_text_bottom_y (s->w) - r.y;
2136
2137 /* Alas, the above simple strategy does not work for the
2138 environments with anti-aliased text: if the same text is
2139 drawn onto the same place multiple times, it gets thicker.
2140 If the overlap we are processing is for the erased cursor, we
2141 take the intersection with the rectangle of the cursor. */
2142 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2143 {
2144 XRectangle rc, r_save = r;
2145
2146 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2147 rc.y = s->w->phys_cursor.y;
2148 rc.width = s->w->phys_cursor_width;
2149 rc.height = s->w->phys_cursor_height;
2150
2151 x_intersect_rectangles (&r_save, &rc, &r);
2152 }
2153 }
2154 else
2155 {
2156 /* Don't use S->y for clipping because it doesn't take partially
2157 visible lines into account. For example, it can be negative for
2158 partially visible lines at the top of a window. */
2159 if (!s->row->full_width_p
2160 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2161 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2162 else
2163 r.y = max (0, s->row->y);
2164 }
2165
2166 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2167
2168 /* If drawing the cursor, don't let glyph draw outside its
2169 advertised boundaries. Cleartype does this under some circumstances. */
2170 if (s->hl == DRAW_CURSOR)
2171 {
2172 struct glyph *glyph = s->first_glyph;
2173 int height, max_y;
2174
2175 if (s->x > r.x)
2176 {
2177 if (r.width >= s->x - r.x)
2178 r.width -= s->x - r.x;
2179 else /* R2L hscrolled row with cursor outside text area */
2180 r.width = 0;
2181 r.x = s->x;
2182 }
2183 r.width = min (r.width, glyph->pixel_width);
2184
2185 /* If r.y is below window bottom, ensure that we still see a cursor. */
2186 height = min (glyph->ascent + glyph->descent,
2187 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2188 max_y = window_text_bottom_y (s->w) - height;
2189 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2190 if (s->ybase - glyph->ascent > max_y)
2191 {
2192 r.y = max_y;
2193 r.height = height;
2194 }
2195 else
2196 {
2197 /* Don't draw cursor glyph taller than our actual glyph. */
2198 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2199 if (height < r.height)
2200 {
2201 max_y = r.y + r.height;
2202 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2203 r.height = min (max_y - r.y, height);
2204 }
2205 }
2206 }
2207
2208 if (s->row->clip)
2209 {
2210 XRectangle r_save = r;
2211
2212 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2213 r.width = 0;
2214 }
2215
2216 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2217 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2218 {
2219 #ifdef CONVERT_FROM_XRECT
2220 CONVERT_FROM_XRECT (r, *rects);
2221 #else
2222 *rects = r;
2223 #endif
2224 return 1;
2225 }
2226 else
2227 {
2228 /* If we are processing overlapping and allowed to return
2229 multiple clipping rectangles, we exclude the row of the glyph
2230 string from the clipping rectangle. This is to avoid drawing
2231 the same text on the environment with anti-aliasing. */
2232 #ifdef CONVERT_FROM_XRECT
2233 XRectangle rs[2];
2234 #else
2235 XRectangle *rs = rects;
2236 #endif
2237 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2238
2239 if (s->for_overlaps & OVERLAPS_PRED)
2240 {
2241 rs[i] = r;
2242 if (r.y + r.height > row_y)
2243 {
2244 if (r.y < row_y)
2245 rs[i].height = row_y - r.y;
2246 else
2247 rs[i].height = 0;
2248 }
2249 i++;
2250 }
2251 if (s->for_overlaps & OVERLAPS_SUCC)
2252 {
2253 rs[i] = r;
2254 if (r.y < row_y + s->row->visible_height)
2255 {
2256 if (r.y + r.height > row_y + s->row->visible_height)
2257 {
2258 rs[i].y = row_y + s->row->visible_height;
2259 rs[i].height = r.y + r.height - rs[i].y;
2260 }
2261 else
2262 rs[i].height = 0;
2263 }
2264 i++;
2265 }
2266
2267 n = i;
2268 #ifdef CONVERT_FROM_XRECT
2269 for (i = 0; i < n; i++)
2270 CONVERT_FROM_XRECT (rs[i], rects[i]);
2271 #endif
2272 return n;
2273 }
2274 }
2275
2276 /* EXPORT:
2277 Return in *NR the clipping rectangle for glyph string S. */
2278
2279 void
2280 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2281 {
2282 get_glyph_string_clip_rects (s, nr, 1);
2283 }
2284
2285
2286 /* EXPORT:
2287 Return the position and height of the phys cursor in window W.
2288 Set w->phys_cursor_width to width of phys cursor.
2289 */
2290
2291 void
2292 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2293 struct glyph *glyph, int *xp, int *yp, int *heightp)
2294 {
2295 struct frame *f = XFRAME (WINDOW_FRAME (w));
2296 int x, y, wd, h, h0, y0;
2297
2298 /* Compute the width of the rectangle to draw. If on a stretch
2299 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2300 rectangle as wide as the glyph, but use a canonical character
2301 width instead. */
2302 wd = glyph->pixel_width - 1;
2303 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2304 wd++; /* Why? */
2305 #endif
2306
2307 x = w->phys_cursor.x;
2308 if (x < 0)
2309 {
2310 wd += x;
2311 x = 0;
2312 }
2313
2314 if (glyph->type == STRETCH_GLYPH
2315 && !x_stretch_cursor_p)
2316 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2317 w->phys_cursor_width = wd;
2318
2319 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2320
2321 /* If y is below window bottom, ensure that we still see a cursor. */
2322 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2323
2324 h = max (h0, glyph->ascent + glyph->descent);
2325 h0 = min (h0, glyph->ascent + glyph->descent);
2326
2327 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2328 if (y < y0)
2329 {
2330 h = max (h - (y0 - y) + 1, h0);
2331 y = y0 - 1;
2332 }
2333 else
2334 {
2335 y0 = window_text_bottom_y (w) - h0;
2336 if (y > y0)
2337 {
2338 h += y - y0;
2339 y = y0;
2340 }
2341 }
2342
2343 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2344 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2345 *heightp = h;
2346 }
2347
2348 /*
2349 * Remember which glyph the mouse is over.
2350 */
2351
2352 void
2353 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2354 {
2355 Lisp_Object window;
2356 struct window *w;
2357 struct glyph_row *r, *gr, *end_row;
2358 enum window_part part;
2359 enum glyph_row_area area;
2360 int x, y, width, height;
2361
2362 /* Try to determine frame pixel position and size of the glyph under
2363 frame pixel coordinates X/Y on frame F. */
2364
2365 if (window_resize_pixelwise)
2366 {
2367 width = height = 1;
2368 goto virtual_glyph;
2369 }
2370 else if (!f->glyphs_initialized_p
2371 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2372 NILP (window)))
2373 {
2374 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2375 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2376 goto virtual_glyph;
2377 }
2378
2379 w = XWINDOW (window);
2380 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2381 height = WINDOW_FRAME_LINE_HEIGHT (w);
2382
2383 x = window_relative_x_coord (w, part, gx);
2384 y = gy - WINDOW_TOP_EDGE_Y (w);
2385
2386 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2387 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2388
2389 if (w->pseudo_window_p)
2390 {
2391 area = TEXT_AREA;
2392 part = ON_MODE_LINE; /* Don't adjust margin. */
2393 goto text_glyph;
2394 }
2395
2396 switch (part)
2397 {
2398 case ON_LEFT_MARGIN:
2399 area = LEFT_MARGIN_AREA;
2400 goto text_glyph;
2401
2402 case ON_RIGHT_MARGIN:
2403 area = RIGHT_MARGIN_AREA;
2404 goto text_glyph;
2405
2406 case ON_HEADER_LINE:
2407 case ON_MODE_LINE:
2408 gr = (part == ON_HEADER_LINE
2409 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2410 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2411 gy = gr->y;
2412 area = TEXT_AREA;
2413 goto text_glyph_row_found;
2414
2415 case ON_TEXT:
2416 area = TEXT_AREA;
2417
2418 text_glyph:
2419 gr = 0; gy = 0;
2420 for (; r <= end_row && r->enabled_p; ++r)
2421 if (r->y + r->height > y)
2422 {
2423 gr = r; gy = r->y;
2424 break;
2425 }
2426
2427 text_glyph_row_found:
2428 if (gr && gy <= y)
2429 {
2430 struct glyph *g = gr->glyphs[area];
2431 struct glyph *end = g + gr->used[area];
2432
2433 height = gr->height;
2434 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2435 if (gx + g->pixel_width > x)
2436 break;
2437
2438 if (g < end)
2439 {
2440 if (g->type == IMAGE_GLYPH)
2441 {
2442 /* Don't remember when mouse is over image, as
2443 image may have hot-spots. */
2444 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2445 return;
2446 }
2447 width = g->pixel_width;
2448 }
2449 else
2450 {
2451 /* Use nominal char spacing at end of line. */
2452 x -= gx;
2453 gx += (x / width) * width;
2454 }
2455
2456 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2457 {
2458 gx += window_box_left_offset (w, area);
2459 /* Don't expand over the modeline to make sure the vertical
2460 drag cursor is shown early enough. */
2461 height = min (height,
2462 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2463 }
2464 }
2465 else
2466 {
2467 /* Use nominal line height at end of window. */
2468 gx = (x / width) * width;
2469 y -= gy;
2470 gy += (y / height) * height;
2471 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2472 /* See comment above. */
2473 height = min (height,
2474 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2475 }
2476 break;
2477
2478 case ON_LEFT_FRINGE:
2479 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2480 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2481 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2482 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2483 goto row_glyph;
2484
2485 case ON_RIGHT_FRINGE:
2486 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2487 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2488 : window_box_right_offset (w, TEXT_AREA));
2489 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2490 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2491 && !WINDOW_RIGHTMOST_P (w))
2492 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2493 /* Make sure the vertical border can get her own glyph to the
2494 right of the one we build here. */
2495 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2496 else
2497 width = WINDOW_PIXEL_WIDTH (w) - gx;
2498 else
2499 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2500
2501 goto row_glyph;
2502
2503 case ON_VERTICAL_BORDER:
2504 gx = WINDOW_PIXEL_WIDTH (w) - width;
2505 goto row_glyph;
2506
2507 case ON_VERTICAL_SCROLL_BAR:
2508 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2509 ? 0
2510 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2511 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2512 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2513 : 0)));
2514 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2515
2516 row_glyph:
2517 gr = 0, gy = 0;
2518 for (; r <= end_row && r->enabled_p; ++r)
2519 if (r->y + r->height > y)
2520 {
2521 gr = r; gy = r->y;
2522 break;
2523 }
2524
2525 if (gr && gy <= y)
2526 height = gr->height;
2527 else
2528 {
2529 /* Use nominal line height at end of window. */
2530 y -= gy;
2531 gy += (y / height) * height;
2532 }
2533 break;
2534
2535 case ON_RIGHT_DIVIDER:
2536 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2537 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2538 gy = 0;
2539 /* The bottom divider prevails. */
2540 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2541 goto add_edge;
2542
2543 case ON_BOTTOM_DIVIDER:
2544 gx = 0;
2545 width = WINDOW_PIXEL_WIDTH (w);
2546 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2547 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2548 goto add_edge;
2549
2550 default:
2551 ;
2552 virtual_glyph:
2553 /* If there is no glyph under the mouse, then we divide the screen
2554 into a grid of the smallest glyph in the frame, and use that
2555 as our "glyph". */
2556
2557 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2558 round down even for negative values. */
2559 if (gx < 0)
2560 gx -= width - 1;
2561 if (gy < 0)
2562 gy -= height - 1;
2563
2564 gx = (gx / width) * width;
2565 gy = (gy / height) * height;
2566
2567 goto store_rect;
2568 }
2569
2570 add_edge:
2571 gx += WINDOW_LEFT_EDGE_X (w);
2572 gy += WINDOW_TOP_EDGE_Y (w);
2573
2574 store_rect:
2575 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2576
2577 /* Visible feedback for debugging. */
2578 #if 0
2579 #if HAVE_X_WINDOWS
2580 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2581 f->output_data.x->normal_gc,
2582 gx, gy, width, height);
2583 #endif
2584 #endif
2585 }
2586
2587
2588 #endif /* HAVE_WINDOW_SYSTEM */
2589
2590 static void
2591 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2592 {
2593 eassert (w);
2594 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2595 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2596 w->window_end_vpos
2597 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2598 }
2599
2600 /***********************************************************************
2601 Lisp form evaluation
2602 ***********************************************************************/
2603
2604 /* Error handler for safe_eval and safe_call. */
2605
2606 static Lisp_Object
2607 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2608 {
2609 add_to_log ("Error during redisplay: %S signaled %S",
2610 Flist (nargs, args), arg);
2611 return Qnil;
2612 }
2613
2614 /* Call function FUNC with the rest of NARGS - 1 arguments
2615 following. Return the result, or nil if something went
2616 wrong. Prevent redisplay during the evaluation. */
2617
2618 static Lisp_Object
2619 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2620 {
2621 Lisp_Object val;
2622
2623 if (inhibit_eval_during_redisplay)
2624 val = Qnil;
2625 else
2626 {
2627 ptrdiff_t i;
2628 ptrdiff_t count = SPECPDL_INDEX ();
2629 Lisp_Object *args;
2630 USE_SAFE_ALLOCA;
2631 SAFE_ALLOCA_LISP (args, nargs);
2632
2633 args[0] = func;
2634 for (i = 1; i < nargs; i++)
2635 args[i] = va_arg (ap, Lisp_Object);
2636
2637 specbind (Qinhibit_redisplay, Qt);
2638 if (inhibit_quit)
2639 specbind (Qinhibit_quit, Qt);
2640 /* Use Qt to ensure debugger does not run,
2641 so there is no possibility of wanting to redisplay. */
2642 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2643 safe_eval_handler);
2644 SAFE_FREE ();
2645 val = unbind_to (count, val);
2646 }
2647
2648 return val;
2649 }
2650
2651 Lisp_Object
2652 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2653 {
2654 Lisp_Object retval;
2655 va_list ap;
2656
2657 va_start (ap, func);
2658 retval = safe__call (false, nargs, func, ap);
2659 va_end (ap);
2660 return retval;
2661 }
2662
2663 /* Call function FN with one argument ARG.
2664 Return the result, or nil if something went wrong. */
2665
2666 Lisp_Object
2667 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2668 {
2669 return safe_call (2, fn, arg);
2670 }
2671
2672 static Lisp_Object
2673 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2674 {
2675 Lisp_Object retval;
2676 va_list ap;
2677
2678 va_start (ap, fn);
2679 retval = safe__call (inhibit_quit, 2, fn, ap);
2680 va_end (ap);
2681 return retval;
2682 }
2683
2684 static Lisp_Object Qeval;
2685
2686 Lisp_Object
2687 safe_eval (Lisp_Object sexpr)
2688 {
2689 return safe__call1 (false, Qeval, sexpr);
2690 }
2691
2692 static Lisp_Object
2693 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2694 {
2695 return safe__call1 (inhibit_quit, Qeval, sexpr);
2696 }
2697
2698 /* Call function FN with two arguments ARG1 and ARG2.
2699 Return the result, or nil if something went wrong. */
2700
2701 Lisp_Object
2702 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2703 {
2704 return safe_call (3, fn, arg1, arg2);
2705 }
2706
2707
2708 \f
2709 /***********************************************************************
2710 Debugging
2711 ***********************************************************************/
2712
2713 #if 0
2714
2715 /* Define CHECK_IT to perform sanity checks on iterators.
2716 This is for debugging. It is too slow to do unconditionally. */
2717
2718 static void
2719 check_it (struct it *it)
2720 {
2721 if (it->method == GET_FROM_STRING)
2722 {
2723 eassert (STRINGP (it->string));
2724 eassert (IT_STRING_CHARPOS (*it) >= 0);
2725 }
2726 else
2727 {
2728 eassert (IT_STRING_CHARPOS (*it) < 0);
2729 if (it->method == GET_FROM_BUFFER)
2730 {
2731 /* Check that character and byte positions agree. */
2732 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2733 }
2734 }
2735
2736 if (it->dpvec)
2737 eassert (it->current.dpvec_index >= 0);
2738 else
2739 eassert (it->current.dpvec_index < 0);
2740 }
2741
2742 #define CHECK_IT(IT) check_it ((IT))
2743
2744 #else /* not 0 */
2745
2746 #define CHECK_IT(IT) (void) 0
2747
2748 #endif /* not 0 */
2749
2750
2751 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2752
2753 /* Check that the window end of window W is what we expect it
2754 to be---the last row in the current matrix displaying text. */
2755
2756 static void
2757 check_window_end (struct window *w)
2758 {
2759 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2760 {
2761 struct glyph_row *row;
2762 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2763 !row->enabled_p
2764 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2765 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2766 }
2767 }
2768
2769 #define CHECK_WINDOW_END(W) check_window_end ((W))
2770
2771 #else
2772
2773 #define CHECK_WINDOW_END(W) (void) 0
2774
2775 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2776
2777 /***********************************************************************
2778 Iterator initialization
2779 ***********************************************************************/
2780
2781 /* Initialize IT for displaying current_buffer in window W, starting
2782 at character position CHARPOS. CHARPOS < 0 means that no buffer
2783 position is specified which is useful when the iterator is assigned
2784 a position later. BYTEPOS is the byte position corresponding to
2785 CHARPOS.
2786
2787 If ROW is not null, calls to produce_glyphs with IT as parameter
2788 will produce glyphs in that row.
2789
2790 BASE_FACE_ID is the id of a base face to use. It must be one of
2791 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2792 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2793 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2794
2795 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2796 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2797 will be initialized to use the corresponding mode line glyph row of
2798 the desired matrix of W. */
2799
2800 void
2801 init_iterator (struct it *it, struct window *w,
2802 ptrdiff_t charpos, ptrdiff_t bytepos,
2803 struct glyph_row *row, enum face_id base_face_id)
2804 {
2805 enum face_id remapped_base_face_id = base_face_id;
2806
2807 /* Some precondition checks. */
2808 eassert (w != NULL && it != NULL);
2809 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2810 && charpos <= ZV));
2811
2812 /* If face attributes have been changed since the last redisplay,
2813 free realized faces now because they depend on face definitions
2814 that might have changed. Don't free faces while there might be
2815 desired matrices pending which reference these faces. */
2816 if (face_change_count && !inhibit_free_realized_faces)
2817 {
2818 face_change_count = 0;
2819 free_all_realized_faces (Qnil);
2820 }
2821
2822 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2823 if (! NILP (Vface_remapping_alist))
2824 remapped_base_face_id
2825 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2826
2827 /* Use one of the mode line rows of W's desired matrix if
2828 appropriate. */
2829 if (row == NULL)
2830 {
2831 if (base_face_id == MODE_LINE_FACE_ID
2832 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2833 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2834 else if (base_face_id == HEADER_LINE_FACE_ID)
2835 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2836 }
2837
2838 /* Clear IT. */
2839 memset (it, 0, sizeof *it);
2840 it->current.overlay_string_index = -1;
2841 it->current.dpvec_index = -1;
2842 it->base_face_id = remapped_base_face_id;
2843 it->string = Qnil;
2844 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2845 it->paragraph_embedding = L2R;
2846 it->bidi_it.string.lstring = Qnil;
2847 it->bidi_it.string.s = NULL;
2848 it->bidi_it.string.bufpos = 0;
2849 it->bidi_it.w = w;
2850
2851 /* The window in which we iterate over current_buffer: */
2852 XSETWINDOW (it->window, w);
2853 it->w = w;
2854 it->f = XFRAME (w->frame);
2855
2856 it->cmp_it.id = -1;
2857
2858 /* Extra space between lines (on window systems only). */
2859 if (base_face_id == DEFAULT_FACE_ID
2860 && FRAME_WINDOW_P (it->f))
2861 {
2862 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2863 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2864 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2865 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2866 * FRAME_LINE_HEIGHT (it->f));
2867 else if (it->f->extra_line_spacing > 0)
2868 it->extra_line_spacing = it->f->extra_line_spacing;
2869 it->max_extra_line_spacing = 0;
2870 }
2871
2872 /* If realized faces have been removed, e.g. because of face
2873 attribute changes of named faces, recompute them. When running
2874 in batch mode, the face cache of the initial frame is null. If
2875 we happen to get called, make a dummy face cache. */
2876 if (FRAME_FACE_CACHE (it->f) == NULL)
2877 init_frame_faces (it->f);
2878 if (FRAME_FACE_CACHE (it->f)->used == 0)
2879 recompute_basic_faces (it->f);
2880
2881 /* Current value of the `slice', `space-width', and 'height' properties. */
2882 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2883 it->space_width = Qnil;
2884 it->font_height = Qnil;
2885 it->override_ascent = -1;
2886
2887 /* Are control characters displayed as `^C'? */
2888 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2889
2890 /* -1 means everything between a CR and the following line end
2891 is invisible. >0 means lines indented more than this value are
2892 invisible. */
2893 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2894 ? (clip_to_bounds
2895 (-1, XINT (BVAR (current_buffer, selective_display)),
2896 PTRDIFF_MAX))
2897 : (!NILP (BVAR (current_buffer, selective_display))
2898 ? -1 : 0));
2899 it->selective_display_ellipsis_p
2900 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2901
2902 /* Display table to use. */
2903 it->dp = window_display_table (w);
2904
2905 /* Are multibyte characters enabled in current_buffer? */
2906 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2907
2908 /* Get the position at which the redisplay_end_trigger hook should
2909 be run, if it is to be run at all. */
2910 if (MARKERP (w->redisplay_end_trigger)
2911 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2912 it->redisplay_end_trigger_charpos
2913 = marker_position (w->redisplay_end_trigger);
2914 else if (INTEGERP (w->redisplay_end_trigger))
2915 it->redisplay_end_trigger_charpos
2916 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2917 PTRDIFF_MAX);
2918
2919 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2920
2921 /* Are lines in the display truncated? */
2922 if (base_face_id != DEFAULT_FACE_ID
2923 || it->w->hscroll
2924 || (! WINDOW_FULL_WIDTH_P (it->w)
2925 && ((!NILP (Vtruncate_partial_width_windows)
2926 && !INTEGERP (Vtruncate_partial_width_windows))
2927 || (INTEGERP (Vtruncate_partial_width_windows)
2928 /* PXW: Shall we do something about this? */
2929 && (WINDOW_TOTAL_COLS (it->w)
2930 < XINT (Vtruncate_partial_width_windows))))))
2931 it->line_wrap = TRUNCATE;
2932 else if (NILP (BVAR (current_buffer, truncate_lines)))
2933 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2934 ? WINDOW_WRAP : WORD_WRAP;
2935 else
2936 it->line_wrap = TRUNCATE;
2937
2938 /* Get dimensions of truncation and continuation glyphs. These are
2939 displayed as fringe bitmaps under X, but we need them for such
2940 frames when the fringes are turned off. But leave the dimensions
2941 zero for tooltip frames, as these glyphs look ugly there and also
2942 sabotage calculations of tooltip dimensions in x-show-tip. */
2943 #ifdef HAVE_WINDOW_SYSTEM
2944 if (!(FRAME_WINDOW_P (it->f)
2945 && FRAMEP (tip_frame)
2946 && it->f == XFRAME (tip_frame)))
2947 #endif
2948 {
2949 if (it->line_wrap == TRUNCATE)
2950 {
2951 /* We will need the truncation glyph. */
2952 eassert (it->glyph_row == NULL);
2953 produce_special_glyphs (it, IT_TRUNCATION);
2954 it->truncation_pixel_width = it->pixel_width;
2955 }
2956 else
2957 {
2958 /* We will need the continuation glyph. */
2959 eassert (it->glyph_row == NULL);
2960 produce_special_glyphs (it, IT_CONTINUATION);
2961 it->continuation_pixel_width = it->pixel_width;
2962 }
2963 }
2964
2965 /* Reset these values to zero because the produce_special_glyphs
2966 above has changed them. */
2967 it->pixel_width = it->ascent = it->descent = 0;
2968 it->phys_ascent = it->phys_descent = 0;
2969
2970 /* Set this after getting the dimensions of truncation and
2971 continuation glyphs, so that we don't produce glyphs when calling
2972 produce_special_glyphs, above. */
2973 it->glyph_row = row;
2974 it->area = TEXT_AREA;
2975
2976 /* Get the dimensions of the display area. The display area
2977 consists of the visible window area plus a horizontally scrolled
2978 part to the left of the window. All x-values are relative to the
2979 start of this total display area. */
2980 if (base_face_id != DEFAULT_FACE_ID)
2981 {
2982 /* Mode lines, menu bar in terminal frames. */
2983 it->first_visible_x = 0;
2984 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2985 }
2986 else
2987 {
2988 it->first_visible_x
2989 = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2990 it->last_visible_x = (it->first_visible_x
2991 + window_box_width (w, TEXT_AREA));
2992
2993 /* If we truncate lines, leave room for the truncation glyph(s) at
2994 the right margin. Otherwise, leave room for the continuation
2995 glyph(s). Done only if the window has no fringes. Since we
2996 don't know at this point whether there will be any R2L lines in
2997 the window, we reserve space for truncation/continuation glyphs
2998 even if only one of the fringes is absent. */
2999 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
3000 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
3001 {
3002 if (it->line_wrap == TRUNCATE)
3003 it->last_visible_x -= it->truncation_pixel_width;
3004 else
3005 it->last_visible_x -= it->continuation_pixel_width;
3006 }
3007
3008 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
3009 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
3010 }
3011
3012 /* Leave room for a border glyph. */
3013 if (!FRAME_WINDOW_P (it->f)
3014 && !WINDOW_RIGHTMOST_P (it->w))
3015 it->last_visible_x -= 1;
3016
3017 it->last_visible_y = window_text_bottom_y (w);
3018
3019 /* For mode lines and alike, arrange for the first glyph having a
3020 left box line if the face specifies a box. */
3021 if (base_face_id != DEFAULT_FACE_ID)
3022 {
3023 struct face *face;
3024
3025 it->face_id = remapped_base_face_id;
3026
3027 /* If we have a boxed mode line, make the first character appear
3028 with a left box line. */
3029 face = FACE_FROM_ID (it->f, remapped_base_face_id);
3030 if (face && face->box != FACE_NO_BOX)
3031 it->start_of_box_run_p = true;
3032 }
3033
3034 /* If a buffer position was specified, set the iterator there,
3035 getting overlays and face properties from that position. */
3036 if (charpos >= BUF_BEG (current_buffer))
3037 {
3038 it->stop_charpos = charpos;
3039 it->end_charpos = ZV;
3040 eassert (charpos == BYTE_TO_CHAR (bytepos));
3041 IT_CHARPOS (*it) = charpos;
3042 IT_BYTEPOS (*it) = bytepos;
3043
3044 /* We will rely on `reseat' to set this up properly, via
3045 handle_face_prop. */
3046 it->face_id = it->base_face_id;
3047
3048 it->start = it->current;
3049 /* Do we need to reorder bidirectional text? Not if this is a
3050 unibyte buffer: by definition, none of the single-byte
3051 characters are strong R2L, so no reordering is needed. And
3052 bidi.c doesn't support unibyte buffers anyway. Also, don't
3053 reorder while we are loading loadup.el, since the tables of
3054 character properties needed for reordering are not yet
3055 available. */
3056 it->bidi_p =
3057 NILP (Vpurify_flag)
3058 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3059 && it->multibyte_p;
3060
3061 /* If we are to reorder bidirectional text, init the bidi
3062 iterator. */
3063 if (it->bidi_p)
3064 {
3065 /* Note the paragraph direction that this buffer wants to
3066 use. */
3067 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3068 Qleft_to_right))
3069 it->paragraph_embedding = L2R;
3070 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3071 Qright_to_left))
3072 it->paragraph_embedding = R2L;
3073 else
3074 it->paragraph_embedding = NEUTRAL_DIR;
3075 bidi_unshelve_cache (NULL, 0);
3076 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3077 &it->bidi_it);
3078 }
3079
3080 /* Compute faces etc. */
3081 reseat (it, it->current.pos, 1);
3082 }
3083
3084 CHECK_IT (it);
3085 }
3086
3087
3088 /* Initialize IT for the display of window W with window start POS. */
3089
3090 void
3091 start_display (struct it *it, struct window *w, struct text_pos pos)
3092 {
3093 struct glyph_row *row;
3094 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
3095
3096 row = w->desired_matrix->rows + first_vpos;
3097 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3098 it->first_vpos = first_vpos;
3099
3100 /* Don't reseat to previous visible line start if current start
3101 position is in a string or image. */
3102 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3103 {
3104 int start_at_line_beg_p;
3105 int first_y = it->current_y;
3106
3107 /* If window start is not at a line start, skip forward to POS to
3108 get the correct continuation lines width. */
3109 start_at_line_beg_p = (CHARPOS (pos) == BEGV
3110 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3111 if (!start_at_line_beg_p)
3112 {
3113 int new_x;
3114
3115 reseat_at_previous_visible_line_start (it);
3116 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3117
3118 new_x = it->current_x + it->pixel_width;
3119
3120 /* If lines are continued, this line may end in the middle
3121 of a multi-glyph character (e.g. a control character
3122 displayed as \003, or in the middle of an overlay
3123 string). In this case move_it_to above will not have
3124 taken us to the start of the continuation line but to the
3125 end of the continued line. */
3126 if (it->current_x > 0
3127 && it->line_wrap != TRUNCATE /* Lines are continued. */
3128 && (/* And glyph doesn't fit on the line. */
3129 new_x > it->last_visible_x
3130 /* Or it fits exactly and we're on a window
3131 system frame. */
3132 || (new_x == it->last_visible_x
3133 && FRAME_WINDOW_P (it->f)
3134 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3135 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3136 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3137 {
3138 if ((it->current.dpvec_index >= 0
3139 || it->current.overlay_string_index >= 0)
3140 /* If we are on a newline from a display vector or
3141 overlay string, then we are already at the end of
3142 a screen line; no need to go to the next line in
3143 that case, as this line is not really continued.
3144 (If we do go to the next line, C-e will not DTRT.) */
3145 && it->c != '\n')
3146 {
3147 set_iterator_to_next (it, 1);
3148 move_it_in_display_line_to (it, -1, -1, 0);
3149 }
3150
3151 it->continuation_lines_width += it->current_x;
3152 }
3153 /* If the character at POS is displayed via a display
3154 vector, move_it_to above stops at the final glyph of
3155 IT->dpvec. To make the caller redisplay that character
3156 again (a.k.a. start at POS), we need to reset the
3157 dpvec_index to the beginning of IT->dpvec. */
3158 else if (it->current.dpvec_index >= 0)
3159 it->current.dpvec_index = 0;
3160
3161 /* We're starting a new display line, not affected by the
3162 height of the continued line, so clear the appropriate
3163 fields in the iterator structure. */
3164 it->max_ascent = it->max_descent = 0;
3165 it->max_phys_ascent = it->max_phys_descent = 0;
3166
3167 it->current_y = first_y;
3168 it->vpos = 0;
3169 it->current_x = it->hpos = 0;
3170 }
3171 }
3172 }
3173
3174
3175 /* Return 1 if POS is a position in ellipses displayed for invisible
3176 text. W is the window we display, for text property lookup. */
3177
3178 static int
3179 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3180 {
3181 Lisp_Object prop, window;
3182 int ellipses_p = 0;
3183 ptrdiff_t charpos = CHARPOS (pos->pos);
3184
3185 /* If POS specifies a position in a display vector, this might
3186 be for an ellipsis displayed for invisible text. We won't
3187 get the iterator set up for delivering that ellipsis unless
3188 we make sure that it gets aware of the invisible text. */
3189 if (pos->dpvec_index >= 0
3190 && pos->overlay_string_index < 0
3191 && CHARPOS (pos->string_pos) < 0
3192 && charpos > BEGV
3193 && (XSETWINDOW (window, w),
3194 prop = Fget_char_property (make_number (charpos),
3195 Qinvisible, window),
3196 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3197 {
3198 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3199 window);
3200 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3201 }
3202
3203 return ellipses_p;
3204 }
3205
3206
3207 /* Initialize IT for stepping through current_buffer in window W,
3208 starting at position POS that includes overlay string and display
3209 vector/ control character translation position information. Value
3210 is zero if there are overlay strings with newlines at POS. */
3211
3212 static int
3213 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3214 {
3215 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3216 int i, overlay_strings_with_newlines = 0;
3217
3218 /* If POS specifies a position in a display vector, this might
3219 be for an ellipsis displayed for invisible text. We won't
3220 get the iterator set up for delivering that ellipsis unless
3221 we make sure that it gets aware of the invisible text. */
3222 if (in_ellipses_for_invisible_text_p (pos, w))
3223 {
3224 --charpos;
3225 bytepos = 0;
3226 }
3227
3228 /* Keep in mind: the call to reseat in init_iterator skips invisible
3229 text, so we might end up at a position different from POS. This
3230 is only a problem when POS is a row start after a newline and an
3231 overlay starts there with an after-string, and the overlay has an
3232 invisible property. Since we don't skip invisible text in
3233 display_line and elsewhere immediately after consuming the
3234 newline before the row start, such a POS will not be in a string,
3235 but the call to init_iterator below will move us to the
3236 after-string. */
3237 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3238
3239 /* This only scans the current chunk -- it should scan all chunks.
3240 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3241 to 16 in 22.1 to make this a lesser problem. */
3242 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3243 {
3244 const char *s = SSDATA (it->overlay_strings[i]);
3245 const char *e = s + SBYTES (it->overlay_strings[i]);
3246
3247 while (s < e && *s != '\n')
3248 ++s;
3249
3250 if (s < e)
3251 {
3252 overlay_strings_with_newlines = 1;
3253 break;
3254 }
3255 }
3256
3257 /* If position is within an overlay string, set up IT to the right
3258 overlay string. */
3259 if (pos->overlay_string_index >= 0)
3260 {
3261 int relative_index;
3262
3263 /* If the first overlay string happens to have a `display'
3264 property for an image, the iterator will be set up for that
3265 image, and we have to undo that setup first before we can
3266 correct the overlay string index. */
3267 if (it->method == GET_FROM_IMAGE)
3268 pop_it (it);
3269
3270 /* We already have the first chunk of overlay strings in
3271 IT->overlay_strings. Load more until the one for
3272 pos->overlay_string_index is in IT->overlay_strings. */
3273 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3274 {
3275 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3276 it->current.overlay_string_index = 0;
3277 while (n--)
3278 {
3279 load_overlay_strings (it, 0);
3280 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3281 }
3282 }
3283
3284 it->current.overlay_string_index = pos->overlay_string_index;
3285 relative_index = (it->current.overlay_string_index
3286 % OVERLAY_STRING_CHUNK_SIZE);
3287 it->string = it->overlay_strings[relative_index];
3288 eassert (STRINGP (it->string));
3289 it->current.string_pos = pos->string_pos;
3290 it->method = GET_FROM_STRING;
3291 it->end_charpos = SCHARS (it->string);
3292 /* Set up the bidi iterator for this overlay string. */
3293 if (it->bidi_p)
3294 {
3295 it->bidi_it.string.lstring = it->string;
3296 it->bidi_it.string.s = NULL;
3297 it->bidi_it.string.schars = SCHARS (it->string);
3298 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3299 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3300 it->bidi_it.string.unibyte = !it->multibyte_p;
3301 it->bidi_it.w = it->w;
3302 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3303 FRAME_WINDOW_P (it->f), &it->bidi_it);
3304
3305 /* Synchronize the state of the bidi iterator with
3306 pos->string_pos. For any string position other than
3307 zero, this will be done automagically when we resume
3308 iteration over the string and get_visually_first_element
3309 is called. But if string_pos is zero, and the string is
3310 to be reordered for display, we need to resync manually,
3311 since it could be that the iteration state recorded in
3312 pos ended at string_pos of 0 moving backwards in string. */
3313 if (CHARPOS (pos->string_pos) == 0)
3314 {
3315 get_visually_first_element (it);
3316 if (IT_STRING_CHARPOS (*it) != 0)
3317 do {
3318 /* Paranoia. */
3319 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3320 bidi_move_to_visually_next (&it->bidi_it);
3321 } while (it->bidi_it.charpos != 0);
3322 }
3323 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3324 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3325 }
3326 }
3327
3328 if (CHARPOS (pos->string_pos) >= 0)
3329 {
3330 /* Recorded position is not in an overlay string, but in another
3331 string. This can only be a string from a `display' property.
3332 IT should already be filled with that string. */
3333 it->current.string_pos = pos->string_pos;
3334 eassert (STRINGP (it->string));
3335 if (it->bidi_p)
3336 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3337 FRAME_WINDOW_P (it->f), &it->bidi_it);
3338 }
3339
3340 /* Restore position in display vector translations, control
3341 character translations or ellipses. */
3342 if (pos->dpvec_index >= 0)
3343 {
3344 if (it->dpvec == NULL)
3345 get_next_display_element (it);
3346 eassert (it->dpvec && it->current.dpvec_index == 0);
3347 it->current.dpvec_index = pos->dpvec_index;
3348 }
3349
3350 CHECK_IT (it);
3351 return !overlay_strings_with_newlines;
3352 }
3353
3354
3355 /* Initialize IT for stepping through current_buffer in window W
3356 starting at ROW->start. */
3357
3358 static void
3359 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3360 {
3361 init_from_display_pos (it, w, &row->start);
3362 it->start = row->start;
3363 it->continuation_lines_width = row->continuation_lines_width;
3364 CHECK_IT (it);
3365 }
3366
3367
3368 /* Initialize IT for stepping through current_buffer in window W
3369 starting in the line following ROW, i.e. starting at ROW->end.
3370 Value is zero if there are overlay strings with newlines at ROW's
3371 end position. */
3372
3373 static int
3374 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3375 {
3376 int success = 0;
3377
3378 if (init_from_display_pos (it, w, &row->end))
3379 {
3380 if (row->continued_p)
3381 it->continuation_lines_width
3382 = row->continuation_lines_width + row->pixel_width;
3383 CHECK_IT (it);
3384 success = 1;
3385 }
3386
3387 return success;
3388 }
3389
3390
3391
3392 \f
3393 /***********************************************************************
3394 Text properties
3395 ***********************************************************************/
3396
3397 /* Called when IT reaches IT->stop_charpos. Handle text property and
3398 overlay changes. Set IT->stop_charpos to the next position where
3399 to stop. */
3400
3401 static void
3402 handle_stop (struct it *it)
3403 {
3404 enum prop_handled handled;
3405 int handle_overlay_change_p;
3406 struct props *p;
3407
3408 it->dpvec = NULL;
3409 it->current.dpvec_index = -1;
3410 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3411 it->ignore_overlay_strings_at_pos_p = 0;
3412 it->ellipsis_p = 0;
3413
3414 /* Use face of preceding text for ellipsis (if invisible) */
3415 if (it->selective_display_ellipsis_p)
3416 it->saved_face_id = it->face_id;
3417
3418 /* Here's the description of the semantics of, and the logic behind,
3419 the various HANDLED_* statuses:
3420
3421 HANDLED_NORMALLY means the handler did its job, and the loop
3422 should proceed to calling the next handler in order.
3423
3424 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3425 change in the properties and overlays at current position, so the
3426 loop should be restarted, to re-invoke the handlers that were
3427 already called. This happens when fontification-functions were
3428 called by handle_fontified_prop, and actually fontified
3429 something. Another case where HANDLED_RECOMPUTE_PROPS is
3430 returned is when we discover overlay strings that need to be
3431 displayed right away. The loop below will continue for as long
3432 as the status is HANDLED_RECOMPUTE_PROPS.
3433
3434 HANDLED_RETURN means return immediately to the caller, to
3435 continue iteration without calling any further handlers. This is
3436 used when we need to act on some property right away, for example
3437 when we need to display the ellipsis or a replacing display
3438 property, such as display string or image.
3439
3440 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3441 consumed, and the handler switched to the next overlay string.
3442 This signals the loop below to refrain from looking for more
3443 overlays before all the overlay strings of the current overlay
3444 are processed.
3445
3446 Some of the handlers called by the loop push the iterator state
3447 onto the stack (see 'push_it'), and arrange for the iteration to
3448 continue with another object, such as an image, a display string,
3449 or an overlay string. In most such cases, it->stop_charpos is
3450 set to the first character of the string, so that when the
3451 iteration resumes, this function will immediately be called
3452 again, to examine the properties at the beginning of the string.
3453
3454 When a display or overlay string is exhausted, the iterator state
3455 is popped (see 'pop_it'), and iteration continues with the
3456 previous object. Again, in many such cases this function is
3457 called again to find the next position where properties might
3458 change. */
3459
3460 do
3461 {
3462 handled = HANDLED_NORMALLY;
3463
3464 /* Call text property handlers. */
3465 for (p = it_props; p->handler; ++p)
3466 {
3467 handled = p->handler (it);
3468
3469 if (handled == HANDLED_RECOMPUTE_PROPS)
3470 break;
3471 else if (handled == HANDLED_RETURN)
3472 {
3473 /* We still want to show before and after strings from
3474 overlays even if the actual buffer text is replaced. */
3475 if (!handle_overlay_change_p
3476 || it->sp > 1
3477 /* Don't call get_overlay_strings_1 if we already
3478 have overlay strings loaded, because doing so
3479 will load them again and push the iterator state
3480 onto the stack one more time, which is not
3481 expected by the rest of the code that processes
3482 overlay strings. */
3483 || (it->current.overlay_string_index < 0
3484 ? !get_overlay_strings_1 (it, 0, 0)
3485 : 0))
3486 {
3487 if (it->ellipsis_p)
3488 setup_for_ellipsis (it, 0);
3489 /* When handling a display spec, we might load an
3490 empty string. In that case, discard it here. We
3491 used to discard it in handle_single_display_spec,
3492 but that causes get_overlay_strings_1, above, to
3493 ignore overlay strings that we must check. */
3494 if (STRINGP (it->string) && !SCHARS (it->string))
3495 pop_it (it);
3496 return;
3497 }
3498 else if (STRINGP (it->string) && !SCHARS (it->string))
3499 pop_it (it);
3500 else
3501 {
3502 it->ignore_overlay_strings_at_pos_p = true;
3503 it->string_from_display_prop_p = 0;
3504 it->from_disp_prop_p = 0;
3505 handle_overlay_change_p = 0;
3506 }
3507 handled = HANDLED_RECOMPUTE_PROPS;
3508 break;
3509 }
3510 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3511 handle_overlay_change_p = 0;
3512 }
3513
3514 if (handled != HANDLED_RECOMPUTE_PROPS)
3515 {
3516 /* Don't check for overlay strings below when set to deliver
3517 characters from a display vector. */
3518 if (it->method == GET_FROM_DISPLAY_VECTOR)
3519 handle_overlay_change_p = 0;
3520
3521 /* Handle overlay changes.
3522 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3523 if it finds overlays. */
3524 if (handle_overlay_change_p)
3525 handled = handle_overlay_change (it);
3526 }
3527
3528 if (it->ellipsis_p)
3529 {
3530 setup_for_ellipsis (it, 0);
3531 break;
3532 }
3533 }
3534 while (handled == HANDLED_RECOMPUTE_PROPS);
3535
3536 /* Determine where to stop next. */
3537 if (handled == HANDLED_NORMALLY)
3538 compute_stop_pos (it);
3539 }
3540
3541
3542 /* Compute IT->stop_charpos from text property and overlay change
3543 information for IT's current position. */
3544
3545 static void
3546 compute_stop_pos (struct it *it)
3547 {
3548 register INTERVAL iv, next_iv;
3549 Lisp_Object object, limit, position;
3550 ptrdiff_t charpos, bytepos;
3551
3552 if (STRINGP (it->string))
3553 {
3554 /* Strings are usually short, so don't limit the search for
3555 properties. */
3556 it->stop_charpos = it->end_charpos;
3557 object = it->string;
3558 limit = Qnil;
3559 charpos = IT_STRING_CHARPOS (*it);
3560 bytepos = IT_STRING_BYTEPOS (*it);
3561 }
3562 else
3563 {
3564 ptrdiff_t pos;
3565
3566 /* If end_charpos is out of range for some reason, such as a
3567 misbehaving display function, rationalize it (Bug#5984). */
3568 if (it->end_charpos > ZV)
3569 it->end_charpos = ZV;
3570 it->stop_charpos = it->end_charpos;
3571
3572 /* If next overlay change is in front of the current stop pos
3573 (which is IT->end_charpos), stop there. Note: value of
3574 next_overlay_change is point-max if no overlay change
3575 follows. */
3576 charpos = IT_CHARPOS (*it);
3577 bytepos = IT_BYTEPOS (*it);
3578 pos = next_overlay_change (charpos);
3579 if (pos < it->stop_charpos)
3580 it->stop_charpos = pos;
3581
3582 /* Set up variables for computing the stop position from text
3583 property changes. */
3584 XSETBUFFER (object, current_buffer);
3585 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3586 }
3587
3588 /* Get the interval containing IT's position. Value is a null
3589 interval if there isn't such an interval. */
3590 position = make_number (charpos);
3591 iv = validate_interval_range (object, &position, &position, 0);
3592 if (iv)
3593 {
3594 Lisp_Object values_here[LAST_PROP_IDX];
3595 struct props *p;
3596
3597 /* Get properties here. */
3598 for (p = it_props; p->handler; ++p)
3599 values_here[p->idx] = textget (iv->plist, *p->name);
3600
3601 /* Look for an interval following iv that has different
3602 properties. */
3603 for (next_iv = next_interval (iv);
3604 (next_iv
3605 && (NILP (limit)
3606 || XFASTINT (limit) > next_iv->position));
3607 next_iv = next_interval (next_iv))
3608 {
3609 for (p = it_props; p->handler; ++p)
3610 {
3611 Lisp_Object new_value;
3612
3613 new_value = textget (next_iv->plist, *p->name);
3614 if (!EQ (values_here[p->idx], new_value))
3615 break;
3616 }
3617
3618 if (p->handler)
3619 break;
3620 }
3621
3622 if (next_iv)
3623 {
3624 if (INTEGERP (limit)
3625 && next_iv->position >= XFASTINT (limit))
3626 /* No text property change up to limit. */
3627 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3628 else
3629 /* Text properties change in next_iv. */
3630 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3631 }
3632 }
3633
3634 if (it->cmp_it.id < 0)
3635 {
3636 ptrdiff_t stoppos = it->end_charpos;
3637
3638 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3639 stoppos = -1;
3640 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3641 stoppos, it->string);
3642 }
3643
3644 eassert (STRINGP (it->string)
3645 || (it->stop_charpos >= BEGV
3646 && it->stop_charpos >= IT_CHARPOS (*it)));
3647 }
3648
3649
3650 /* Return the position of the next overlay change after POS in
3651 current_buffer. Value is point-max if no overlay change
3652 follows. This is like `next-overlay-change' but doesn't use
3653 xmalloc. */
3654
3655 static ptrdiff_t
3656 next_overlay_change (ptrdiff_t pos)
3657 {
3658 ptrdiff_t i, noverlays;
3659 ptrdiff_t endpos;
3660 Lisp_Object *overlays;
3661 USE_SAFE_ALLOCA;
3662
3663 /* Get all overlays at the given position. */
3664 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3665
3666 /* If any of these overlays ends before endpos,
3667 use its ending point instead. */
3668 for (i = 0; i < noverlays; ++i)
3669 {
3670 Lisp_Object oend;
3671 ptrdiff_t oendpos;
3672
3673 oend = OVERLAY_END (overlays[i]);
3674 oendpos = OVERLAY_POSITION (oend);
3675 endpos = min (endpos, oendpos);
3676 }
3677
3678 SAFE_FREE ();
3679 return endpos;
3680 }
3681
3682 /* How many characters forward to search for a display property or
3683 display string. Searching too far forward makes the bidi display
3684 sluggish, especially in small windows. */
3685 #define MAX_DISP_SCAN 250
3686
3687 /* Return the character position of a display string at or after
3688 position specified by POSITION. If no display string exists at or
3689 after POSITION, return ZV. A display string is either an overlay
3690 with `display' property whose value is a string, or a `display'
3691 text property whose value is a string. STRING is data about the
3692 string to iterate; if STRING->lstring is nil, we are iterating a
3693 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3694 on a GUI frame. DISP_PROP is set to zero if we searched
3695 MAX_DISP_SCAN characters forward without finding any display
3696 strings, non-zero otherwise. It is set to 2 if the display string
3697 uses any kind of `(space ...)' spec that will produce a stretch of
3698 white space in the text area. */
3699 ptrdiff_t
3700 compute_display_string_pos (struct text_pos *position,
3701 struct bidi_string_data *string,
3702 struct window *w,
3703 int frame_window_p, int *disp_prop)
3704 {
3705 /* OBJECT = nil means current buffer. */
3706 Lisp_Object object, object1;
3707 Lisp_Object pos, spec, limpos;
3708 int string_p = (string && (STRINGP (string->lstring) || string->s));
3709 ptrdiff_t eob = string_p ? string->schars : ZV;
3710 ptrdiff_t begb = string_p ? 0 : BEGV;
3711 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3712 ptrdiff_t lim =
3713 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3714 struct text_pos tpos;
3715 int rv = 0;
3716
3717 if (string && STRINGP (string->lstring))
3718 object1 = object = string->lstring;
3719 else if (w && !string_p)
3720 {
3721 XSETWINDOW (object, w);
3722 object1 = Qnil;
3723 }
3724 else
3725 object1 = object = Qnil;
3726
3727 *disp_prop = 1;
3728
3729 if (charpos >= eob
3730 /* We don't support display properties whose values are strings
3731 that have display string properties. */
3732 || string->from_disp_str
3733 /* C strings cannot have display properties. */
3734 || (string->s && !STRINGP (object)))
3735 {
3736 *disp_prop = 0;
3737 return eob;
3738 }
3739
3740 /* If the character at CHARPOS is where the display string begins,
3741 return CHARPOS. */
3742 pos = make_number (charpos);
3743 if (STRINGP (object))
3744 bufpos = string->bufpos;
3745 else
3746 bufpos = charpos;
3747 tpos = *position;
3748 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3749 && (charpos <= begb
3750 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3751 object),
3752 spec))
3753 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3754 frame_window_p)))
3755 {
3756 if (rv == 2)
3757 *disp_prop = 2;
3758 return charpos;
3759 }
3760
3761 /* Look forward for the first character with a `display' property
3762 that will replace the underlying text when displayed. */
3763 limpos = make_number (lim);
3764 do {
3765 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3766 CHARPOS (tpos) = XFASTINT (pos);
3767 if (CHARPOS (tpos) >= lim)
3768 {
3769 *disp_prop = 0;
3770 break;
3771 }
3772 if (STRINGP (object))
3773 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3774 else
3775 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3776 spec = Fget_char_property (pos, Qdisplay, object);
3777 if (!STRINGP (object))
3778 bufpos = CHARPOS (tpos);
3779 } while (NILP (spec)
3780 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3781 bufpos, frame_window_p)));
3782 if (rv == 2)
3783 *disp_prop = 2;
3784
3785 return CHARPOS (tpos);
3786 }
3787
3788 /* Return the character position of the end of the display string that
3789 started at CHARPOS. If there's no display string at CHARPOS,
3790 return -1. A display string is either an overlay with `display'
3791 property whose value is a string or a `display' text property whose
3792 value is a string. */
3793 ptrdiff_t
3794 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3795 {
3796 /* OBJECT = nil means current buffer. */
3797 Lisp_Object object =
3798 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3799 Lisp_Object pos = make_number (charpos);
3800 ptrdiff_t eob =
3801 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3802
3803 if (charpos >= eob || (string->s && !STRINGP (object)))
3804 return eob;
3805
3806 /* It could happen that the display property or overlay was removed
3807 since we found it in compute_display_string_pos above. One way
3808 this can happen is if JIT font-lock was called (through
3809 handle_fontified_prop), and jit-lock-functions remove text
3810 properties or overlays from the portion of buffer that includes
3811 CHARPOS. Muse mode is known to do that, for example. In this
3812 case, we return -1 to the caller, to signal that no display
3813 string is actually present at CHARPOS. See bidi_fetch_char for
3814 how this is handled.
3815
3816 An alternative would be to never look for display properties past
3817 it->stop_charpos. But neither compute_display_string_pos nor
3818 bidi_fetch_char that calls it know or care where the next
3819 stop_charpos is. */
3820 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3821 return -1;
3822
3823 /* Look forward for the first character where the `display' property
3824 changes. */
3825 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3826
3827 return XFASTINT (pos);
3828 }
3829
3830
3831 \f
3832 /***********************************************************************
3833 Fontification
3834 ***********************************************************************/
3835
3836 /* Handle changes in the `fontified' property of the current buffer by
3837 calling hook functions from Qfontification_functions to fontify
3838 regions of text. */
3839
3840 static enum prop_handled
3841 handle_fontified_prop (struct it *it)
3842 {
3843 Lisp_Object prop, pos;
3844 enum prop_handled handled = HANDLED_NORMALLY;
3845
3846 if (!NILP (Vmemory_full))
3847 return handled;
3848
3849 /* Get the value of the `fontified' property at IT's current buffer
3850 position. (The `fontified' property doesn't have a special
3851 meaning in strings.) If the value is nil, call functions from
3852 Qfontification_functions. */
3853 if (!STRINGP (it->string)
3854 && it->s == NULL
3855 && !NILP (Vfontification_functions)
3856 && !NILP (Vrun_hooks)
3857 && (pos = make_number (IT_CHARPOS (*it)),
3858 prop = Fget_char_property (pos, Qfontified, Qnil),
3859 /* Ignore the special cased nil value always present at EOB since
3860 no amount of fontifying will be able to change it. */
3861 NILP (prop) && IT_CHARPOS (*it) < Z))
3862 {
3863 ptrdiff_t count = SPECPDL_INDEX ();
3864 Lisp_Object val;
3865 struct buffer *obuf = current_buffer;
3866 ptrdiff_t begv = BEGV, zv = ZV;
3867 bool old_clip_changed = current_buffer->clip_changed;
3868
3869 val = Vfontification_functions;
3870 specbind (Qfontification_functions, Qnil);
3871
3872 eassert (it->end_charpos == ZV);
3873
3874 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3875 safe_call1 (val, pos);
3876 else
3877 {
3878 Lisp_Object fns, fn;
3879 struct gcpro gcpro1, gcpro2;
3880
3881 fns = Qnil;
3882 GCPRO2 (val, fns);
3883
3884 for (; CONSP (val); val = XCDR (val))
3885 {
3886 fn = XCAR (val);
3887
3888 if (EQ (fn, Qt))
3889 {
3890 /* A value of t indicates this hook has a local
3891 binding; it means to run the global binding too.
3892 In a global value, t should not occur. If it
3893 does, we must ignore it to avoid an endless
3894 loop. */
3895 for (fns = Fdefault_value (Qfontification_functions);
3896 CONSP (fns);
3897 fns = XCDR (fns))
3898 {
3899 fn = XCAR (fns);
3900 if (!EQ (fn, Qt))
3901 safe_call1 (fn, pos);
3902 }
3903 }
3904 else
3905 safe_call1 (fn, pos);
3906 }
3907
3908 UNGCPRO;
3909 }
3910
3911 unbind_to (count, Qnil);
3912
3913 /* Fontification functions routinely call `save-restriction'.
3914 Normally, this tags clip_changed, which can confuse redisplay
3915 (see discussion in Bug#6671). Since we don't perform any
3916 special handling of fontification changes in the case where
3917 `save-restriction' isn't called, there's no point doing so in
3918 this case either. So, if the buffer's restrictions are
3919 actually left unchanged, reset clip_changed. */
3920 if (obuf == current_buffer)
3921 {
3922 if (begv == BEGV && zv == ZV)
3923 current_buffer->clip_changed = old_clip_changed;
3924 }
3925 /* There isn't much we can reasonably do to protect against
3926 misbehaving fontification, but here's a fig leaf. */
3927 else if (BUFFER_LIVE_P (obuf))
3928 set_buffer_internal_1 (obuf);
3929
3930 /* The fontification code may have added/removed text.
3931 It could do even a lot worse, but let's at least protect against
3932 the most obvious case where only the text past `pos' gets changed',
3933 as is/was done in grep.el where some escapes sequences are turned
3934 into face properties (bug#7876). */
3935 it->end_charpos = ZV;
3936
3937 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3938 something. This avoids an endless loop if they failed to
3939 fontify the text for which reason ever. */
3940 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3941 handled = HANDLED_RECOMPUTE_PROPS;
3942 }
3943
3944 return handled;
3945 }
3946
3947
3948 \f
3949 /***********************************************************************
3950 Faces
3951 ***********************************************************************/
3952
3953 /* Set up iterator IT from face properties at its current position.
3954 Called from handle_stop. */
3955
3956 static enum prop_handled
3957 handle_face_prop (struct it *it)
3958 {
3959 int new_face_id;
3960 ptrdiff_t next_stop;
3961
3962 if (!STRINGP (it->string))
3963 {
3964 new_face_id
3965 = face_at_buffer_position (it->w,
3966 IT_CHARPOS (*it),
3967 &next_stop,
3968 (IT_CHARPOS (*it)
3969 + TEXT_PROP_DISTANCE_LIMIT),
3970 0, it->base_face_id);
3971
3972 /* Is this a start of a run of characters with box face?
3973 Caveat: this can be called for a freshly initialized
3974 iterator; face_id is -1 in this case. We know that the new
3975 face will not change until limit, i.e. if the new face has a
3976 box, all characters up to limit will have one. But, as
3977 usual, we don't know whether limit is really the end. */
3978 if (new_face_id != it->face_id)
3979 {
3980 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3981 /* If it->face_id is -1, old_face below will be NULL, see
3982 the definition of FACE_FROM_ID. This will happen if this
3983 is the initial call that gets the face. */
3984 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3985
3986 /* If the value of face_id of the iterator is -1, we have to
3987 look in front of IT's position and see whether there is a
3988 face there that's different from new_face_id. */
3989 if (!old_face && IT_CHARPOS (*it) > BEG)
3990 {
3991 int prev_face_id = face_before_it_pos (it);
3992
3993 old_face = FACE_FROM_ID (it->f, prev_face_id);
3994 }
3995
3996 /* If the new face has a box, but the old face does not,
3997 this is the start of a run of characters with box face,
3998 i.e. this character has a shadow on the left side. */
3999 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
4000 && (old_face == NULL || !old_face->box));
4001 it->face_box_p = new_face->box != FACE_NO_BOX;
4002 }
4003 }
4004 else
4005 {
4006 int base_face_id;
4007 ptrdiff_t bufpos;
4008 int i;
4009 Lisp_Object from_overlay
4010 = (it->current.overlay_string_index >= 0
4011 ? it->string_overlays[it->current.overlay_string_index
4012 % OVERLAY_STRING_CHUNK_SIZE]
4013 : Qnil);
4014
4015 /* See if we got to this string directly or indirectly from
4016 an overlay property. That includes the before-string or
4017 after-string of an overlay, strings in display properties
4018 provided by an overlay, their text properties, etc.
4019
4020 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
4021 if (! NILP (from_overlay))
4022 for (i = it->sp - 1; i >= 0; i--)
4023 {
4024 if (it->stack[i].current.overlay_string_index >= 0)
4025 from_overlay
4026 = it->string_overlays[it->stack[i].current.overlay_string_index
4027 % OVERLAY_STRING_CHUNK_SIZE];
4028 else if (! NILP (it->stack[i].from_overlay))
4029 from_overlay = it->stack[i].from_overlay;
4030
4031 if (!NILP (from_overlay))
4032 break;
4033 }
4034
4035 if (! NILP (from_overlay))
4036 {
4037 bufpos = IT_CHARPOS (*it);
4038 /* For a string from an overlay, the base face depends
4039 only on text properties and ignores overlays. */
4040 base_face_id
4041 = face_for_overlay_string (it->w,
4042 IT_CHARPOS (*it),
4043 &next_stop,
4044 (IT_CHARPOS (*it)
4045 + TEXT_PROP_DISTANCE_LIMIT),
4046 0,
4047 from_overlay);
4048 }
4049 else
4050 {
4051 bufpos = 0;
4052
4053 /* For strings from a `display' property, use the face at
4054 IT's current buffer position as the base face to merge
4055 with, so that overlay strings appear in the same face as
4056 surrounding text, unless they specify their own faces.
4057 For strings from wrap-prefix and line-prefix properties,
4058 use the default face, possibly remapped via
4059 Vface_remapping_alist. */
4060 /* Note that the fact that we use the face at _buffer_
4061 position means that a 'display' property on an overlay
4062 string will not inherit the face of that overlay string,
4063 but will instead revert to the face of buffer text
4064 covered by the overlay. This is visible, e.g., when the
4065 overlay specifies a box face, but neither the buffer nor
4066 the display string do. This sounds like a design bug,
4067 but Emacs always did that since v21.1, so changing that
4068 might be a big deal. */
4069 base_face_id = it->string_from_prefix_prop_p
4070 ? (!NILP (Vface_remapping_alist)
4071 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
4072 : DEFAULT_FACE_ID)
4073 : underlying_face_id (it);
4074 }
4075
4076 new_face_id = face_at_string_position (it->w,
4077 it->string,
4078 IT_STRING_CHARPOS (*it),
4079 bufpos,
4080 &next_stop,
4081 base_face_id, 0);
4082
4083 /* Is this a start of a run of characters with box? Caveat:
4084 this can be called for a freshly allocated iterator; face_id
4085 is -1 is this case. We know that the new face will not
4086 change until the next check pos, i.e. if the new face has a
4087 box, all characters up to that position will have a
4088 box. But, as usual, we don't know whether that position
4089 is really the end. */
4090 if (new_face_id != it->face_id)
4091 {
4092 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4093 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
4094
4095 /* If new face has a box but old face hasn't, this is the
4096 start of a run of characters with box, i.e. it has a
4097 shadow on the left side. */
4098 it->start_of_box_run_p
4099 = new_face->box && (old_face == NULL || !old_face->box);
4100 it->face_box_p = new_face->box != FACE_NO_BOX;
4101 }
4102 }
4103
4104 it->face_id = new_face_id;
4105 return HANDLED_NORMALLY;
4106 }
4107
4108
4109 /* Return the ID of the face ``underlying'' IT's current position,
4110 which is in a string. If the iterator is associated with a
4111 buffer, return the face at IT's current buffer position.
4112 Otherwise, use the iterator's base_face_id. */
4113
4114 static int
4115 underlying_face_id (struct it *it)
4116 {
4117 int face_id = it->base_face_id, i;
4118
4119 eassert (STRINGP (it->string));
4120
4121 for (i = it->sp - 1; i >= 0; --i)
4122 if (NILP (it->stack[i].string))
4123 face_id = it->stack[i].face_id;
4124
4125 return face_id;
4126 }
4127
4128
4129 /* Compute the face one character before or after the current position
4130 of IT, in the visual order. BEFORE_P non-zero means get the face
4131 in front (to the left in L2R paragraphs, to the right in R2L
4132 paragraphs) of IT's screen position. Value is the ID of the face. */
4133
4134 static int
4135 face_before_or_after_it_pos (struct it *it, int before_p)
4136 {
4137 int face_id, limit;
4138 ptrdiff_t next_check_charpos;
4139 struct it it_copy;
4140 void *it_copy_data = NULL;
4141
4142 eassert (it->s == NULL);
4143
4144 if (STRINGP (it->string))
4145 {
4146 ptrdiff_t bufpos, charpos;
4147 int base_face_id;
4148
4149 /* No face change past the end of the string (for the case
4150 we are padding with spaces). No face change before the
4151 string start. */
4152 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4153 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4154 return it->face_id;
4155
4156 if (!it->bidi_p)
4157 {
4158 /* Set charpos to the position before or after IT's current
4159 position, in the logical order, which in the non-bidi
4160 case is the same as the visual order. */
4161 if (before_p)
4162 charpos = IT_STRING_CHARPOS (*it) - 1;
4163 else if (it->what == IT_COMPOSITION)
4164 /* For composition, we must check the character after the
4165 composition. */
4166 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4167 else
4168 charpos = IT_STRING_CHARPOS (*it) + 1;
4169 }
4170 else
4171 {
4172 if (before_p)
4173 {
4174 /* With bidi iteration, the character before the current
4175 in the visual order cannot be found by simple
4176 iteration, because "reverse" reordering is not
4177 supported. Instead, we need to use the move_it_*
4178 family of functions. */
4179 /* Ignore face changes before the first visible
4180 character on this display line. */
4181 if (it->current_x <= it->first_visible_x)
4182 return it->face_id;
4183 SAVE_IT (it_copy, *it, it_copy_data);
4184 /* Implementation note: Since move_it_in_display_line
4185 works in the iterator geometry, and thinks the first
4186 character is always the leftmost, even in R2L lines,
4187 we don't need to distinguish between the R2L and L2R
4188 cases here. */
4189 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4190 it_copy.current_x - 1, MOVE_TO_X);
4191 charpos = IT_STRING_CHARPOS (it_copy);
4192 RESTORE_IT (it, it, it_copy_data);
4193 }
4194 else
4195 {
4196 /* Set charpos to the string position of the character
4197 that comes after IT's current position in the visual
4198 order. */
4199 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4200
4201 it_copy = *it;
4202 while (n--)
4203 bidi_move_to_visually_next (&it_copy.bidi_it);
4204
4205 charpos = it_copy.bidi_it.charpos;
4206 }
4207 }
4208 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4209
4210 if (it->current.overlay_string_index >= 0)
4211 bufpos = IT_CHARPOS (*it);
4212 else
4213 bufpos = 0;
4214
4215 base_face_id = underlying_face_id (it);
4216
4217 /* Get the face for ASCII, or unibyte. */
4218 face_id = face_at_string_position (it->w,
4219 it->string,
4220 charpos,
4221 bufpos,
4222 &next_check_charpos,
4223 base_face_id, 0);
4224
4225 /* Correct the face for charsets different from ASCII. Do it
4226 for the multibyte case only. The face returned above is
4227 suitable for unibyte text if IT->string is unibyte. */
4228 if (STRING_MULTIBYTE (it->string))
4229 {
4230 struct text_pos pos1 = string_pos (charpos, it->string);
4231 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4232 int c, len;
4233 struct face *face = FACE_FROM_ID (it->f, face_id);
4234
4235 c = string_char_and_length (p, &len);
4236 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4237 }
4238 }
4239 else
4240 {
4241 struct text_pos pos;
4242
4243 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4244 || (IT_CHARPOS (*it) <= BEGV && before_p))
4245 return it->face_id;
4246
4247 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4248 pos = it->current.pos;
4249
4250 if (!it->bidi_p)
4251 {
4252 if (before_p)
4253 DEC_TEXT_POS (pos, it->multibyte_p);
4254 else
4255 {
4256 if (it->what == IT_COMPOSITION)
4257 {
4258 /* For composition, we must check the position after
4259 the composition. */
4260 pos.charpos += it->cmp_it.nchars;
4261 pos.bytepos += it->len;
4262 }
4263 else
4264 INC_TEXT_POS (pos, it->multibyte_p);
4265 }
4266 }
4267 else
4268 {
4269 if (before_p)
4270 {
4271 /* With bidi iteration, the character before the current
4272 in the visual order cannot be found by simple
4273 iteration, because "reverse" reordering is not
4274 supported. Instead, we need to use the move_it_*
4275 family of functions. */
4276 /* Ignore face changes before the first visible
4277 character on this display line. */
4278 if (it->current_x <= it->first_visible_x)
4279 return it->face_id;
4280 SAVE_IT (it_copy, *it, it_copy_data);
4281 /* Implementation note: Since move_it_in_display_line
4282 works in the iterator geometry, and thinks the first
4283 character is always the leftmost, even in R2L lines,
4284 we don't need to distinguish between the R2L and L2R
4285 cases here. */
4286 move_it_in_display_line (&it_copy, ZV,
4287 it_copy.current_x - 1, MOVE_TO_X);
4288 pos = it_copy.current.pos;
4289 RESTORE_IT (it, it, it_copy_data);
4290 }
4291 else
4292 {
4293 /* Set charpos to the buffer position of the character
4294 that comes after IT's current position in the visual
4295 order. */
4296 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4297
4298 it_copy = *it;
4299 while (n--)
4300 bidi_move_to_visually_next (&it_copy.bidi_it);
4301
4302 SET_TEXT_POS (pos,
4303 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4304 }
4305 }
4306 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4307
4308 /* Determine face for CHARSET_ASCII, or unibyte. */
4309 face_id = face_at_buffer_position (it->w,
4310 CHARPOS (pos),
4311 &next_check_charpos,
4312 limit, 0, -1);
4313
4314 /* Correct the face for charsets different from ASCII. Do it
4315 for the multibyte case only. The face returned above is
4316 suitable for unibyte text if current_buffer is unibyte. */
4317 if (it->multibyte_p)
4318 {
4319 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4320 struct face *face = FACE_FROM_ID (it->f, face_id);
4321 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4322 }
4323 }
4324
4325 return face_id;
4326 }
4327
4328
4329 \f
4330 /***********************************************************************
4331 Invisible text
4332 ***********************************************************************/
4333
4334 /* Set up iterator IT from invisible properties at its current
4335 position. Called from handle_stop. */
4336
4337 static enum prop_handled
4338 handle_invisible_prop (struct it *it)
4339 {
4340 enum prop_handled handled = HANDLED_NORMALLY;
4341 int invis_p;
4342 Lisp_Object prop;
4343
4344 if (STRINGP (it->string))
4345 {
4346 Lisp_Object end_charpos, limit, charpos;
4347
4348 /* Get the value of the invisible text property at the
4349 current position. Value will be nil if there is no such
4350 property. */
4351 charpos = make_number (IT_STRING_CHARPOS (*it));
4352 prop = Fget_text_property (charpos, Qinvisible, it->string);
4353 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4354
4355 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4356 {
4357 /* Record whether we have to display an ellipsis for the
4358 invisible text. */
4359 int display_ellipsis_p = (invis_p == 2);
4360 ptrdiff_t len, endpos;
4361
4362 handled = HANDLED_RECOMPUTE_PROPS;
4363
4364 /* Get the position at which the next visible text can be
4365 found in IT->string, if any. */
4366 endpos = len = SCHARS (it->string);
4367 XSETINT (limit, len);
4368 do
4369 {
4370 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4371 it->string, limit);
4372 if (INTEGERP (end_charpos))
4373 {
4374 endpos = XFASTINT (end_charpos);
4375 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4376 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4377 if (invis_p == 2)
4378 display_ellipsis_p = true;
4379 }
4380 }
4381 while (invis_p && endpos < len);
4382
4383 if (display_ellipsis_p)
4384 it->ellipsis_p = true;
4385
4386 if (endpos < len)
4387 {
4388 /* Text at END_CHARPOS is visible. Move IT there. */
4389 struct text_pos old;
4390 ptrdiff_t oldpos;
4391
4392 old = it->current.string_pos;
4393 oldpos = CHARPOS (old);
4394 if (it->bidi_p)
4395 {
4396 if (it->bidi_it.first_elt
4397 && it->bidi_it.charpos < SCHARS (it->string))
4398 bidi_paragraph_init (it->paragraph_embedding,
4399 &it->bidi_it, 1);
4400 /* Bidi-iterate out of the invisible text. */
4401 do
4402 {
4403 bidi_move_to_visually_next (&it->bidi_it);
4404 }
4405 while (oldpos <= it->bidi_it.charpos
4406 && it->bidi_it.charpos < endpos);
4407
4408 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4409 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4410 if (IT_CHARPOS (*it) >= endpos)
4411 it->prev_stop = endpos;
4412 }
4413 else
4414 {
4415 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4416 compute_string_pos (&it->current.string_pos, old, it->string);
4417 }
4418 }
4419 else
4420 {
4421 /* The rest of the string is invisible. If this is an
4422 overlay string, proceed with the next overlay string
4423 or whatever comes and return a character from there. */
4424 if (it->current.overlay_string_index >= 0
4425 && !display_ellipsis_p)
4426 {
4427 next_overlay_string (it);
4428 /* Don't check for overlay strings when we just
4429 finished processing them. */
4430 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4431 }
4432 else
4433 {
4434 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4435 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4436 }
4437 }
4438 }
4439 }
4440 else
4441 {
4442 ptrdiff_t newpos, next_stop, start_charpos, tem;
4443 Lisp_Object pos, overlay;
4444
4445 /* First of all, is there invisible text at this position? */
4446 tem = start_charpos = IT_CHARPOS (*it);
4447 pos = make_number (tem);
4448 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4449 &overlay);
4450 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4451
4452 /* If we are on invisible text, skip over it. */
4453 if (invis_p && start_charpos < it->end_charpos)
4454 {
4455 /* Record whether we have to display an ellipsis for the
4456 invisible text. */
4457 int display_ellipsis_p = invis_p == 2;
4458
4459 handled = HANDLED_RECOMPUTE_PROPS;
4460
4461 /* Loop skipping over invisible text. The loop is left at
4462 ZV or with IT on the first char being visible again. */
4463 do
4464 {
4465 /* Try to skip some invisible text. Return value is the
4466 position reached which can be equal to where we start
4467 if there is nothing invisible there. This skips both
4468 over invisible text properties and overlays with
4469 invisible property. */
4470 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4471
4472 /* If we skipped nothing at all we weren't at invisible
4473 text in the first place. If everything to the end of
4474 the buffer was skipped, end the loop. */
4475 if (newpos == tem || newpos >= ZV)
4476 invis_p = 0;
4477 else
4478 {
4479 /* We skipped some characters but not necessarily
4480 all there are. Check if we ended up on visible
4481 text. Fget_char_property returns the property of
4482 the char before the given position, i.e. if we
4483 get invis_p = 0, this means that the char at
4484 newpos is visible. */
4485 pos = make_number (newpos);
4486 prop = Fget_char_property (pos, Qinvisible, it->window);
4487 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4488 }
4489
4490 /* If we ended up on invisible text, proceed to
4491 skip starting with next_stop. */
4492 if (invis_p)
4493 tem = next_stop;
4494
4495 /* If there are adjacent invisible texts, don't lose the
4496 second one's ellipsis. */
4497 if (invis_p == 2)
4498 display_ellipsis_p = true;
4499 }
4500 while (invis_p);
4501
4502 /* The position newpos is now either ZV or on visible text. */
4503 if (it->bidi_p)
4504 {
4505 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4506 int on_newline
4507 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4508 int after_newline
4509 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4510
4511 /* If the invisible text ends on a newline or on a
4512 character after a newline, we can avoid the costly,
4513 character by character, bidi iteration to NEWPOS, and
4514 instead simply reseat the iterator there. That's
4515 because all bidi reordering information is tossed at
4516 the newline. This is a big win for modes that hide
4517 complete lines, like Outline, Org, etc. */
4518 if (on_newline || after_newline)
4519 {
4520 struct text_pos tpos;
4521 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4522
4523 SET_TEXT_POS (tpos, newpos, bpos);
4524 reseat_1 (it, tpos, 0);
4525 /* If we reseat on a newline/ZV, we need to prep the
4526 bidi iterator for advancing to the next character
4527 after the newline/EOB, keeping the current paragraph
4528 direction (so that PRODUCE_GLYPHS does TRT wrt
4529 prepending/appending glyphs to a glyph row). */
4530 if (on_newline)
4531 {
4532 it->bidi_it.first_elt = 0;
4533 it->bidi_it.paragraph_dir = pdir;
4534 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4535 it->bidi_it.nchars = 1;
4536 it->bidi_it.ch_len = 1;
4537 }
4538 }
4539 else /* Must use the slow method. */
4540 {
4541 /* With bidi iteration, the region of invisible text
4542 could start and/or end in the middle of a
4543 non-base embedding level. Therefore, we need to
4544 skip invisible text using the bidi iterator,
4545 starting at IT's current position, until we find
4546 ourselves outside of the invisible text.
4547 Skipping invisible text _after_ bidi iteration
4548 avoids affecting the visual order of the
4549 displayed text when invisible properties are
4550 added or removed. */
4551 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4552 {
4553 /* If we were `reseat'ed to a new paragraph,
4554 determine the paragraph base direction. We
4555 need to do it now because
4556 next_element_from_buffer may not have a
4557 chance to do it, if we are going to skip any
4558 text at the beginning, which resets the
4559 FIRST_ELT flag. */
4560 bidi_paragraph_init (it->paragraph_embedding,
4561 &it->bidi_it, 1);
4562 }
4563 do
4564 {
4565 bidi_move_to_visually_next (&it->bidi_it);
4566 }
4567 while (it->stop_charpos <= it->bidi_it.charpos
4568 && it->bidi_it.charpos < newpos);
4569 IT_CHARPOS (*it) = it->bidi_it.charpos;
4570 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4571 /* If we overstepped NEWPOS, record its position in
4572 the iterator, so that we skip invisible text if
4573 later the bidi iteration lands us in the
4574 invisible region again. */
4575 if (IT_CHARPOS (*it) >= newpos)
4576 it->prev_stop = newpos;
4577 }
4578 }
4579 else
4580 {
4581 IT_CHARPOS (*it) = newpos;
4582 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4583 }
4584
4585 /* If there are before-strings at the start of invisible
4586 text, and the text is invisible because of a text
4587 property, arrange to show before-strings because 20.x did
4588 it that way. (If the text is invisible because of an
4589 overlay property instead of a text property, this is
4590 already handled in the overlay code.) */
4591 if (NILP (overlay)
4592 && get_overlay_strings (it, it->stop_charpos))
4593 {
4594 handled = HANDLED_RECOMPUTE_PROPS;
4595 if (it->sp > 0)
4596 {
4597 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4598 /* The call to get_overlay_strings above recomputes
4599 it->stop_charpos, but it only considers changes
4600 in properties and overlays beyond iterator's
4601 current position. This causes us to miss changes
4602 that happen exactly where the invisible property
4603 ended. So we play it safe here and force the
4604 iterator to check for potential stop positions
4605 immediately after the invisible text. Note that
4606 if get_overlay_strings returns non-zero, it
4607 normally also pushed the iterator stack, so we
4608 need to update the stop position in the slot
4609 below the current one. */
4610 it->stack[it->sp - 1].stop_charpos
4611 = CHARPOS (it->stack[it->sp - 1].current.pos);
4612 }
4613 }
4614 else if (display_ellipsis_p)
4615 {
4616 /* Make sure that the glyphs of the ellipsis will get
4617 correct `charpos' values. If we would not update
4618 it->position here, the glyphs would belong to the
4619 last visible character _before_ the invisible
4620 text, which confuses `set_cursor_from_row'.
4621
4622 We use the last invisible position instead of the
4623 first because this way the cursor is always drawn on
4624 the first "." of the ellipsis, whenever PT is inside
4625 the invisible text. Otherwise the cursor would be
4626 placed _after_ the ellipsis when the point is after the
4627 first invisible character. */
4628 if (!STRINGP (it->object))
4629 {
4630 it->position.charpos = newpos - 1;
4631 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4632 }
4633 it->ellipsis_p = true;
4634 /* Let the ellipsis display before
4635 considering any properties of the following char.
4636 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4637 handled = HANDLED_RETURN;
4638 }
4639 }
4640 }
4641
4642 return handled;
4643 }
4644
4645
4646 /* Make iterator IT return `...' next.
4647 Replaces LEN characters from buffer. */
4648
4649 static void
4650 setup_for_ellipsis (struct it *it, int len)
4651 {
4652 /* Use the display table definition for `...'. Invalid glyphs
4653 will be handled by the method returning elements from dpvec. */
4654 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4655 {
4656 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4657 it->dpvec = v->contents;
4658 it->dpend = v->contents + v->header.size;
4659 }
4660 else
4661 {
4662 /* Default `...'. */
4663 it->dpvec = default_invis_vector;
4664 it->dpend = default_invis_vector + 3;
4665 }
4666
4667 it->dpvec_char_len = len;
4668 it->current.dpvec_index = 0;
4669 it->dpvec_face_id = -1;
4670
4671 /* Remember the current face id in case glyphs specify faces.
4672 IT's face is restored in set_iterator_to_next.
4673 saved_face_id was set to preceding char's face in handle_stop. */
4674 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4675 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4676
4677 it->method = GET_FROM_DISPLAY_VECTOR;
4678 it->ellipsis_p = true;
4679 }
4680
4681
4682 \f
4683 /***********************************************************************
4684 'display' property
4685 ***********************************************************************/
4686
4687 /* Set up iterator IT from `display' property at its current position.
4688 Called from handle_stop.
4689 We return HANDLED_RETURN if some part of the display property
4690 overrides the display of the buffer text itself.
4691 Otherwise we return HANDLED_NORMALLY. */
4692
4693 static enum prop_handled
4694 handle_display_prop (struct it *it)
4695 {
4696 Lisp_Object propval, object, overlay;
4697 struct text_pos *position;
4698 ptrdiff_t bufpos;
4699 /* Nonzero if some property replaces the display of the text itself. */
4700 int display_replaced_p = 0;
4701
4702 if (STRINGP (it->string))
4703 {
4704 object = it->string;
4705 position = &it->current.string_pos;
4706 bufpos = CHARPOS (it->current.pos);
4707 }
4708 else
4709 {
4710 XSETWINDOW (object, it->w);
4711 position = &it->current.pos;
4712 bufpos = CHARPOS (*position);
4713 }
4714
4715 /* Reset those iterator values set from display property values. */
4716 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4717 it->space_width = Qnil;
4718 it->font_height = Qnil;
4719 it->voffset = 0;
4720
4721 /* We don't support recursive `display' properties, i.e. string
4722 values that have a string `display' property, that have a string
4723 `display' property etc. */
4724 if (!it->string_from_display_prop_p)
4725 it->area = TEXT_AREA;
4726
4727 propval = get_char_property_and_overlay (make_number (position->charpos),
4728 Qdisplay, object, &overlay);
4729 if (NILP (propval))
4730 return HANDLED_NORMALLY;
4731 /* Now OVERLAY is the overlay that gave us this property, or nil
4732 if it was a text property. */
4733
4734 if (!STRINGP (it->string))
4735 object = it->w->contents;
4736
4737 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4738 position, bufpos,
4739 FRAME_WINDOW_P (it->f));
4740
4741 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4742 }
4743
4744 /* Subroutine of handle_display_prop. Returns non-zero if the display
4745 specification in SPEC is a replacing specification, i.e. it would
4746 replace the text covered by `display' property with something else,
4747 such as an image or a display string. If SPEC includes any kind or
4748 `(space ...) specification, the value is 2; this is used by
4749 compute_display_string_pos, which see.
4750
4751 See handle_single_display_spec for documentation of arguments.
4752 frame_window_p is non-zero if the window being redisplayed is on a
4753 GUI frame; this argument is used only if IT is NULL, see below.
4754
4755 IT can be NULL, if this is called by the bidi reordering code
4756 through compute_display_string_pos, which see. In that case, this
4757 function only examines SPEC, but does not otherwise "handle" it, in
4758 the sense that it doesn't set up members of IT from the display
4759 spec. */
4760 static int
4761 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4762 Lisp_Object overlay, struct text_pos *position,
4763 ptrdiff_t bufpos, int frame_window_p)
4764 {
4765 int replacing_p = 0;
4766 int rv;
4767
4768 if (CONSP (spec)
4769 /* Simple specifications. */
4770 && !EQ (XCAR (spec), Qimage)
4771 && !EQ (XCAR (spec), Qspace)
4772 && !EQ (XCAR (spec), Qwhen)
4773 && !EQ (XCAR (spec), Qslice)
4774 && !EQ (XCAR (spec), Qspace_width)
4775 && !EQ (XCAR (spec), Qheight)
4776 && !EQ (XCAR (spec), Qraise)
4777 /* Marginal area specifications. */
4778 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4779 && !EQ (XCAR (spec), Qleft_fringe)
4780 && !EQ (XCAR (spec), Qright_fringe)
4781 && !NILP (XCAR (spec)))
4782 {
4783 for (; CONSP (spec); spec = XCDR (spec))
4784 {
4785 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4786 overlay, position, bufpos,
4787 replacing_p, frame_window_p)))
4788 {
4789 replacing_p = rv;
4790 /* If some text in a string is replaced, `position' no
4791 longer points to the position of `object'. */
4792 if (!it || STRINGP (object))
4793 break;
4794 }
4795 }
4796 }
4797 else if (VECTORP (spec))
4798 {
4799 ptrdiff_t i;
4800 for (i = 0; i < ASIZE (spec); ++i)
4801 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4802 overlay, position, bufpos,
4803 replacing_p, frame_window_p)))
4804 {
4805 replacing_p = rv;
4806 /* If some text in a string is replaced, `position' no
4807 longer points to the position of `object'. */
4808 if (!it || STRINGP (object))
4809 break;
4810 }
4811 }
4812 else
4813 {
4814 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4815 position, bufpos, 0,
4816 frame_window_p)))
4817 replacing_p = rv;
4818 }
4819
4820 return replacing_p;
4821 }
4822
4823 /* Value is the position of the end of the `display' property starting
4824 at START_POS in OBJECT. */
4825
4826 static struct text_pos
4827 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4828 {
4829 Lisp_Object end;
4830 struct text_pos end_pos;
4831
4832 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4833 Qdisplay, object, Qnil);
4834 CHARPOS (end_pos) = XFASTINT (end);
4835 if (STRINGP (object))
4836 compute_string_pos (&end_pos, start_pos, it->string);
4837 else
4838 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4839
4840 return end_pos;
4841 }
4842
4843
4844 /* Set up IT from a single `display' property specification SPEC. OBJECT
4845 is the object in which the `display' property was found. *POSITION
4846 is the position in OBJECT at which the `display' property was found.
4847 BUFPOS is the buffer position of OBJECT (different from POSITION if
4848 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4849 previously saw a display specification which already replaced text
4850 display with something else, for example an image; we ignore such
4851 properties after the first one has been processed.
4852
4853 OVERLAY is the overlay this `display' property came from,
4854 or nil if it was a text property.
4855
4856 If SPEC is a `space' or `image' specification, and in some other
4857 cases too, set *POSITION to the position where the `display'
4858 property ends.
4859
4860 If IT is NULL, only examine the property specification in SPEC, but
4861 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4862 is intended to be displayed in a window on a GUI frame.
4863
4864 Value is non-zero if something was found which replaces the display
4865 of buffer or string text. */
4866
4867 static int
4868 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4869 Lisp_Object overlay, struct text_pos *position,
4870 ptrdiff_t bufpos, int display_replaced_p,
4871 int frame_window_p)
4872 {
4873 Lisp_Object form;
4874 Lisp_Object location, value;
4875 struct text_pos start_pos = *position;
4876 int valid_p;
4877
4878 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4879 If the result is non-nil, use VALUE instead of SPEC. */
4880 form = Qt;
4881 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4882 {
4883 spec = XCDR (spec);
4884 if (!CONSP (spec))
4885 return 0;
4886 form = XCAR (spec);
4887 spec = XCDR (spec);
4888 }
4889
4890 if (!NILP (form) && !EQ (form, Qt))
4891 {
4892 ptrdiff_t count = SPECPDL_INDEX ();
4893 struct gcpro gcpro1;
4894
4895 /* Bind `object' to the object having the `display' property, a
4896 buffer or string. Bind `position' to the position in the
4897 object where the property was found, and `buffer-position'
4898 to the current position in the buffer. */
4899
4900 if (NILP (object))
4901 XSETBUFFER (object, current_buffer);
4902 specbind (Qobject, object);
4903 specbind (Qposition, make_number (CHARPOS (*position)));
4904 specbind (Qbuffer_position, make_number (bufpos));
4905 GCPRO1 (form);
4906 form = safe_eval (form);
4907 UNGCPRO;
4908 unbind_to (count, Qnil);
4909 }
4910
4911 if (NILP (form))
4912 return 0;
4913
4914 /* Handle `(height HEIGHT)' specifications. */
4915 if (CONSP (spec)
4916 && EQ (XCAR (spec), Qheight)
4917 && CONSP (XCDR (spec)))
4918 {
4919 if (it)
4920 {
4921 if (!FRAME_WINDOW_P (it->f))
4922 return 0;
4923
4924 it->font_height = XCAR (XCDR (spec));
4925 if (!NILP (it->font_height))
4926 {
4927 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4928 int new_height = -1;
4929
4930 if (CONSP (it->font_height)
4931 && (EQ (XCAR (it->font_height), Qplus)
4932 || EQ (XCAR (it->font_height), Qminus))
4933 && CONSP (XCDR (it->font_height))
4934 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4935 {
4936 /* `(+ N)' or `(- N)' where N is an integer. */
4937 int steps = XINT (XCAR (XCDR (it->font_height)));
4938 if (EQ (XCAR (it->font_height), Qplus))
4939 steps = - steps;
4940 it->face_id = smaller_face (it->f, it->face_id, steps);
4941 }
4942 else if (FUNCTIONP (it->font_height))
4943 {
4944 /* Call function with current height as argument.
4945 Value is the new height. */
4946 Lisp_Object height;
4947 height = safe_call1 (it->font_height,
4948 face->lface[LFACE_HEIGHT_INDEX]);
4949 if (NUMBERP (height))
4950 new_height = XFLOATINT (height);
4951 }
4952 else if (NUMBERP (it->font_height))
4953 {
4954 /* Value is a multiple of the canonical char height. */
4955 struct face *f;
4956
4957 f = FACE_FROM_ID (it->f,
4958 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4959 new_height = (XFLOATINT (it->font_height)
4960 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4961 }
4962 else
4963 {
4964 /* Evaluate IT->font_height with `height' bound to the
4965 current specified height to get the new height. */
4966 ptrdiff_t count = SPECPDL_INDEX ();
4967
4968 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4969 value = safe_eval (it->font_height);
4970 unbind_to (count, Qnil);
4971
4972 if (NUMBERP (value))
4973 new_height = XFLOATINT (value);
4974 }
4975
4976 if (new_height > 0)
4977 it->face_id = face_with_height (it->f, it->face_id, new_height);
4978 }
4979 }
4980
4981 return 0;
4982 }
4983
4984 /* Handle `(space-width WIDTH)'. */
4985 if (CONSP (spec)
4986 && EQ (XCAR (spec), Qspace_width)
4987 && CONSP (XCDR (spec)))
4988 {
4989 if (it)
4990 {
4991 if (!FRAME_WINDOW_P (it->f))
4992 return 0;
4993
4994 value = XCAR (XCDR (spec));
4995 if (NUMBERP (value) && XFLOATINT (value) > 0)
4996 it->space_width = value;
4997 }
4998
4999 return 0;
5000 }
5001
5002 /* Handle `(slice X Y WIDTH HEIGHT)'. */
5003 if (CONSP (spec)
5004 && EQ (XCAR (spec), Qslice))
5005 {
5006 Lisp_Object tem;
5007
5008 if (it)
5009 {
5010 if (!FRAME_WINDOW_P (it->f))
5011 return 0;
5012
5013 if (tem = XCDR (spec), CONSP (tem))
5014 {
5015 it->slice.x = XCAR (tem);
5016 if (tem = XCDR (tem), CONSP (tem))
5017 {
5018 it->slice.y = XCAR (tem);
5019 if (tem = XCDR (tem), CONSP (tem))
5020 {
5021 it->slice.width = XCAR (tem);
5022 if (tem = XCDR (tem), CONSP (tem))
5023 it->slice.height = XCAR (tem);
5024 }
5025 }
5026 }
5027 }
5028
5029 return 0;
5030 }
5031
5032 /* Handle `(raise FACTOR)'. */
5033 if (CONSP (spec)
5034 && EQ (XCAR (spec), Qraise)
5035 && CONSP (XCDR (spec)))
5036 {
5037 if (it)
5038 {
5039 if (!FRAME_WINDOW_P (it->f))
5040 return 0;
5041
5042 #ifdef HAVE_WINDOW_SYSTEM
5043 value = XCAR (XCDR (spec));
5044 if (NUMBERP (value))
5045 {
5046 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5047 it->voffset = - (XFLOATINT (value)
5048 * (FONT_HEIGHT (face->font)));
5049 }
5050 #endif /* HAVE_WINDOW_SYSTEM */
5051 }
5052
5053 return 0;
5054 }
5055
5056 /* Don't handle the other kinds of display specifications
5057 inside a string that we got from a `display' property. */
5058 if (it && it->string_from_display_prop_p)
5059 return 0;
5060
5061 /* Characters having this form of property are not displayed, so
5062 we have to find the end of the property. */
5063 if (it)
5064 {
5065 start_pos = *position;
5066 *position = display_prop_end (it, object, start_pos);
5067 }
5068 value = Qnil;
5069
5070 /* Stop the scan at that end position--we assume that all
5071 text properties change there. */
5072 if (it)
5073 it->stop_charpos = position->charpos;
5074
5075 /* Handle `(left-fringe BITMAP [FACE])'
5076 and `(right-fringe BITMAP [FACE])'. */
5077 if (CONSP (spec)
5078 && (EQ (XCAR (spec), Qleft_fringe)
5079 || EQ (XCAR (spec), Qright_fringe))
5080 && CONSP (XCDR (spec)))
5081 {
5082 int fringe_bitmap;
5083
5084 if (it)
5085 {
5086 if (!FRAME_WINDOW_P (it->f))
5087 /* If we return here, POSITION has been advanced
5088 across the text with this property. */
5089 {
5090 /* Synchronize the bidi iterator with POSITION. This is
5091 needed because we are not going to push the iterator
5092 on behalf of this display property, so there will be
5093 no pop_it call to do this synchronization for us. */
5094 if (it->bidi_p)
5095 {
5096 it->position = *position;
5097 iterate_out_of_display_property (it);
5098 *position = it->position;
5099 }
5100 return 1;
5101 }
5102 }
5103 else if (!frame_window_p)
5104 return 1;
5105
5106 #ifdef HAVE_WINDOW_SYSTEM
5107 value = XCAR (XCDR (spec));
5108 if (!SYMBOLP (value)
5109 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
5110 /* If we return here, POSITION has been advanced
5111 across the text with this property. */
5112 {
5113 if (it && it->bidi_p)
5114 {
5115 it->position = *position;
5116 iterate_out_of_display_property (it);
5117 *position = it->position;
5118 }
5119 return 1;
5120 }
5121
5122 if (it)
5123 {
5124 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
5125
5126 if (CONSP (XCDR (XCDR (spec))))
5127 {
5128 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5129 int face_id2 = lookup_derived_face (it->f, face_name,
5130 FRINGE_FACE_ID, 0);
5131 if (face_id2 >= 0)
5132 face_id = face_id2;
5133 }
5134
5135 /* Save current settings of IT so that we can restore them
5136 when we are finished with the glyph property value. */
5137 push_it (it, position);
5138
5139 it->area = TEXT_AREA;
5140 it->what = IT_IMAGE;
5141 it->image_id = -1; /* no image */
5142 it->position = start_pos;
5143 it->object = NILP (object) ? it->w->contents : object;
5144 it->method = GET_FROM_IMAGE;
5145 it->from_overlay = Qnil;
5146 it->face_id = face_id;
5147 it->from_disp_prop_p = true;
5148
5149 /* Say that we haven't consumed the characters with
5150 `display' property yet. The call to pop_it in
5151 set_iterator_to_next will clean this up. */
5152 *position = start_pos;
5153
5154 if (EQ (XCAR (spec), Qleft_fringe))
5155 {
5156 it->left_user_fringe_bitmap = fringe_bitmap;
5157 it->left_user_fringe_face_id = face_id;
5158 }
5159 else
5160 {
5161 it->right_user_fringe_bitmap = fringe_bitmap;
5162 it->right_user_fringe_face_id = face_id;
5163 }
5164 }
5165 #endif /* HAVE_WINDOW_SYSTEM */
5166 return 1;
5167 }
5168
5169 /* Prepare to handle `((margin left-margin) ...)',
5170 `((margin right-margin) ...)' and `((margin nil) ...)'
5171 prefixes for display specifications. */
5172 location = Qunbound;
5173 if (CONSP (spec) && CONSP (XCAR (spec)))
5174 {
5175 Lisp_Object tem;
5176
5177 value = XCDR (spec);
5178 if (CONSP (value))
5179 value = XCAR (value);
5180
5181 tem = XCAR (spec);
5182 if (EQ (XCAR (tem), Qmargin)
5183 && (tem = XCDR (tem),
5184 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5185 (NILP (tem)
5186 || EQ (tem, Qleft_margin)
5187 || EQ (tem, Qright_margin))))
5188 location = tem;
5189 }
5190
5191 if (EQ (location, Qunbound))
5192 {
5193 location = Qnil;
5194 value = spec;
5195 }
5196
5197 /* After this point, VALUE is the property after any
5198 margin prefix has been stripped. It must be a string,
5199 an image specification, or `(space ...)'.
5200
5201 LOCATION specifies where to display: `left-margin',
5202 `right-margin' or nil. */
5203
5204 valid_p = (STRINGP (value)
5205 #ifdef HAVE_WINDOW_SYSTEM
5206 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5207 && valid_image_p (value))
5208 #endif /* not HAVE_WINDOW_SYSTEM */
5209 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5210
5211 if (valid_p && !display_replaced_p)
5212 {
5213 int retval = 1;
5214
5215 if (!it)
5216 {
5217 /* Callers need to know whether the display spec is any kind
5218 of `(space ...)' spec that is about to affect text-area
5219 display. */
5220 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5221 retval = 2;
5222 return retval;
5223 }
5224
5225 /* Save current settings of IT so that we can restore them
5226 when we are finished with the glyph property value. */
5227 push_it (it, position);
5228 it->from_overlay = overlay;
5229 it->from_disp_prop_p = true;
5230
5231 if (NILP (location))
5232 it->area = TEXT_AREA;
5233 else if (EQ (location, Qleft_margin))
5234 it->area = LEFT_MARGIN_AREA;
5235 else
5236 it->area = RIGHT_MARGIN_AREA;
5237
5238 if (STRINGP (value))
5239 {
5240 it->string = value;
5241 it->multibyte_p = STRING_MULTIBYTE (it->string);
5242 it->current.overlay_string_index = -1;
5243 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5244 it->end_charpos = it->string_nchars = SCHARS (it->string);
5245 it->method = GET_FROM_STRING;
5246 it->stop_charpos = 0;
5247 it->prev_stop = 0;
5248 it->base_level_stop = 0;
5249 it->string_from_display_prop_p = true;
5250 /* Say that we haven't consumed the characters with
5251 `display' property yet. The call to pop_it in
5252 set_iterator_to_next will clean this up. */
5253 if (BUFFERP (object))
5254 *position = start_pos;
5255
5256 /* Force paragraph direction to be that of the parent
5257 object. If the parent object's paragraph direction is
5258 not yet determined, default to L2R. */
5259 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5260 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5261 else
5262 it->paragraph_embedding = L2R;
5263
5264 /* Set up the bidi iterator for this display string. */
5265 if (it->bidi_p)
5266 {
5267 it->bidi_it.string.lstring = it->string;
5268 it->bidi_it.string.s = NULL;
5269 it->bidi_it.string.schars = it->end_charpos;
5270 it->bidi_it.string.bufpos = bufpos;
5271 it->bidi_it.string.from_disp_str = 1;
5272 it->bidi_it.string.unibyte = !it->multibyte_p;
5273 it->bidi_it.w = it->w;
5274 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5275 }
5276 }
5277 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5278 {
5279 it->method = GET_FROM_STRETCH;
5280 it->object = value;
5281 *position = it->position = start_pos;
5282 retval = 1 + (it->area == TEXT_AREA);
5283 }
5284 #ifdef HAVE_WINDOW_SYSTEM
5285 else
5286 {
5287 it->what = IT_IMAGE;
5288 it->image_id = lookup_image (it->f, value);
5289 it->position = start_pos;
5290 it->object = NILP (object) ? it->w->contents : object;
5291 it->method = GET_FROM_IMAGE;
5292
5293 /* Say that we haven't consumed the characters with
5294 `display' property yet. The call to pop_it in
5295 set_iterator_to_next will clean this up. */
5296 *position = start_pos;
5297 }
5298 #endif /* HAVE_WINDOW_SYSTEM */
5299
5300 return retval;
5301 }
5302
5303 /* Invalid property or property not supported. Restore
5304 POSITION to what it was before. */
5305 *position = start_pos;
5306 return 0;
5307 }
5308
5309 /* Check if PROP is a display property value whose text should be
5310 treated as intangible. OVERLAY is the overlay from which PROP
5311 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5312 specify the buffer position covered by PROP. */
5313
5314 int
5315 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5316 ptrdiff_t charpos, ptrdiff_t bytepos)
5317 {
5318 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5319 struct text_pos position;
5320
5321 SET_TEXT_POS (position, charpos, bytepos);
5322 return handle_display_spec (NULL, prop, Qnil, overlay,
5323 &position, charpos, frame_window_p);
5324 }
5325
5326
5327 /* Return 1 if PROP is a display sub-property value containing STRING.
5328
5329 Implementation note: this and the following function are really
5330 special cases of handle_display_spec and
5331 handle_single_display_spec, and should ideally use the same code.
5332 Until they do, these two pairs must be consistent and must be
5333 modified in sync. */
5334
5335 static int
5336 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5337 {
5338 if (EQ (string, prop))
5339 return 1;
5340
5341 /* Skip over `when FORM'. */
5342 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5343 {
5344 prop = XCDR (prop);
5345 if (!CONSP (prop))
5346 return 0;
5347 /* Actually, the condition following `when' should be eval'ed,
5348 like handle_single_display_spec does, and we should return
5349 zero if it evaluates to nil. However, this function is
5350 called only when the buffer was already displayed and some
5351 glyph in the glyph matrix was found to come from a display
5352 string. Therefore, the condition was already evaluated, and
5353 the result was non-nil, otherwise the display string wouldn't
5354 have been displayed and we would have never been called for
5355 this property. Thus, we can skip the evaluation and assume
5356 its result is non-nil. */
5357 prop = XCDR (prop);
5358 }
5359
5360 if (CONSP (prop))
5361 /* Skip over `margin LOCATION'. */
5362 if (EQ (XCAR (prop), Qmargin))
5363 {
5364 prop = XCDR (prop);
5365 if (!CONSP (prop))
5366 return 0;
5367
5368 prop = XCDR (prop);
5369 if (!CONSP (prop))
5370 return 0;
5371 }
5372
5373 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5374 }
5375
5376
5377 /* Return 1 if STRING appears in the `display' property PROP. */
5378
5379 static int
5380 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5381 {
5382 if (CONSP (prop)
5383 && !EQ (XCAR (prop), Qwhen)
5384 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5385 {
5386 /* A list of sub-properties. */
5387 while (CONSP (prop))
5388 {
5389 if (single_display_spec_string_p (XCAR (prop), string))
5390 return 1;
5391 prop = XCDR (prop);
5392 }
5393 }
5394 else if (VECTORP (prop))
5395 {
5396 /* A vector of sub-properties. */
5397 ptrdiff_t i;
5398 for (i = 0; i < ASIZE (prop); ++i)
5399 if (single_display_spec_string_p (AREF (prop, i), string))
5400 return 1;
5401 }
5402 else
5403 return single_display_spec_string_p (prop, string);
5404
5405 return 0;
5406 }
5407
5408 /* Look for STRING in overlays and text properties in the current
5409 buffer, between character positions FROM and TO (excluding TO).
5410 BACK_P non-zero means look back (in this case, TO is supposed to be
5411 less than FROM).
5412 Value is the first character position where STRING was found, or
5413 zero if it wasn't found before hitting TO.
5414
5415 This function may only use code that doesn't eval because it is
5416 called asynchronously from note_mouse_highlight. */
5417
5418 static ptrdiff_t
5419 string_buffer_position_lim (Lisp_Object string,
5420 ptrdiff_t from, ptrdiff_t to, int back_p)
5421 {
5422 Lisp_Object limit, prop, pos;
5423 int found = 0;
5424
5425 pos = make_number (max (from, BEGV));
5426
5427 if (!back_p) /* looking forward */
5428 {
5429 limit = make_number (min (to, ZV));
5430 while (!found && !EQ (pos, limit))
5431 {
5432 prop = Fget_char_property (pos, Qdisplay, Qnil);
5433 if (!NILP (prop) && display_prop_string_p (prop, string))
5434 found = 1;
5435 else
5436 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5437 limit);
5438 }
5439 }
5440 else /* looking back */
5441 {
5442 limit = make_number (max (to, BEGV));
5443 while (!found && !EQ (pos, limit))
5444 {
5445 prop = Fget_char_property (pos, Qdisplay, Qnil);
5446 if (!NILP (prop) && display_prop_string_p (prop, string))
5447 found = 1;
5448 else
5449 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5450 limit);
5451 }
5452 }
5453
5454 return found ? XINT (pos) : 0;
5455 }
5456
5457 /* Determine which buffer position in current buffer STRING comes from.
5458 AROUND_CHARPOS is an approximate position where it could come from.
5459 Value is the buffer position or 0 if it couldn't be determined.
5460
5461 This function is necessary because we don't record buffer positions
5462 in glyphs generated from strings (to keep struct glyph small).
5463 This function may only use code that doesn't eval because it is
5464 called asynchronously from note_mouse_highlight. */
5465
5466 static ptrdiff_t
5467 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5468 {
5469 const int MAX_DISTANCE = 1000;
5470 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5471 around_charpos + MAX_DISTANCE,
5472 0);
5473
5474 if (!found)
5475 found = string_buffer_position_lim (string, around_charpos,
5476 around_charpos - MAX_DISTANCE, 1);
5477 return found;
5478 }
5479
5480
5481 \f
5482 /***********************************************************************
5483 `composition' property
5484 ***********************************************************************/
5485
5486 /* Set up iterator IT from `composition' property at its current
5487 position. Called from handle_stop. */
5488
5489 static enum prop_handled
5490 handle_composition_prop (struct it *it)
5491 {
5492 Lisp_Object prop, string;
5493 ptrdiff_t pos, pos_byte, start, end;
5494
5495 if (STRINGP (it->string))
5496 {
5497 unsigned char *s;
5498
5499 pos = IT_STRING_CHARPOS (*it);
5500 pos_byte = IT_STRING_BYTEPOS (*it);
5501 string = it->string;
5502 s = SDATA (string) + pos_byte;
5503 it->c = STRING_CHAR (s);
5504 }
5505 else
5506 {
5507 pos = IT_CHARPOS (*it);
5508 pos_byte = IT_BYTEPOS (*it);
5509 string = Qnil;
5510 it->c = FETCH_CHAR (pos_byte);
5511 }
5512
5513 /* If there's a valid composition and point is not inside of the
5514 composition (in the case that the composition is from the current
5515 buffer), draw a glyph composed from the composition components. */
5516 if (find_composition (pos, -1, &start, &end, &prop, string)
5517 && composition_valid_p (start, end, prop)
5518 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5519 {
5520 if (start < pos)
5521 /* As we can't handle this situation (perhaps font-lock added
5522 a new composition), we just return here hoping that next
5523 redisplay will detect this composition much earlier. */
5524 return HANDLED_NORMALLY;
5525 if (start != pos)
5526 {
5527 if (STRINGP (it->string))
5528 pos_byte = string_char_to_byte (it->string, start);
5529 else
5530 pos_byte = CHAR_TO_BYTE (start);
5531 }
5532 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5533 prop, string);
5534
5535 if (it->cmp_it.id >= 0)
5536 {
5537 it->cmp_it.ch = -1;
5538 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5539 it->cmp_it.nglyphs = -1;
5540 }
5541 }
5542
5543 return HANDLED_NORMALLY;
5544 }
5545
5546
5547 \f
5548 /***********************************************************************
5549 Overlay strings
5550 ***********************************************************************/
5551
5552 /* The following structure is used to record overlay strings for
5553 later sorting in load_overlay_strings. */
5554
5555 struct overlay_entry
5556 {
5557 Lisp_Object overlay;
5558 Lisp_Object string;
5559 EMACS_INT priority;
5560 int after_string_p;
5561 };
5562
5563
5564 /* Set up iterator IT from overlay strings at its current position.
5565 Called from handle_stop. */
5566
5567 static enum prop_handled
5568 handle_overlay_change (struct it *it)
5569 {
5570 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5571 return HANDLED_RECOMPUTE_PROPS;
5572 else
5573 return HANDLED_NORMALLY;
5574 }
5575
5576
5577 /* Set up the next overlay string for delivery by IT, if there is an
5578 overlay string to deliver. Called by set_iterator_to_next when the
5579 end of the current overlay string is reached. If there are more
5580 overlay strings to display, IT->string and
5581 IT->current.overlay_string_index are set appropriately here.
5582 Otherwise IT->string is set to nil. */
5583
5584 static void
5585 next_overlay_string (struct it *it)
5586 {
5587 ++it->current.overlay_string_index;
5588 if (it->current.overlay_string_index == it->n_overlay_strings)
5589 {
5590 /* No more overlay strings. Restore IT's settings to what
5591 they were before overlay strings were processed, and
5592 continue to deliver from current_buffer. */
5593
5594 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5595 pop_it (it);
5596 eassert (it->sp > 0
5597 || (NILP (it->string)
5598 && it->method == GET_FROM_BUFFER
5599 && it->stop_charpos >= BEGV
5600 && it->stop_charpos <= it->end_charpos));
5601 it->current.overlay_string_index = -1;
5602 it->n_overlay_strings = 0;
5603 it->overlay_strings_charpos = -1;
5604 /* If there's an empty display string on the stack, pop the
5605 stack, to resync the bidi iterator with IT's position. Such
5606 empty strings are pushed onto the stack in
5607 get_overlay_strings_1. */
5608 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5609 pop_it (it);
5610
5611 /* If we're at the end of the buffer, record that we have
5612 processed the overlay strings there already, so that
5613 next_element_from_buffer doesn't try it again. */
5614 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5615 it->overlay_strings_at_end_processed_p = true;
5616 }
5617 else
5618 {
5619 /* There are more overlay strings to process. If
5620 IT->current.overlay_string_index has advanced to a position
5621 where we must load IT->overlay_strings with more strings, do
5622 it. We must load at the IT->overlay_strings_charpos where
5623 IT->n_overlay_strings was originally computed; when invisible
5624 text is present, this might not be IT_CHARPOS (Bug#7016). */
5625 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5626
5627 if (it->current.overlay_string_index && i == 0)
5628 load_overlay_strings (it, it->overlay_strings_charpos);
5629
5630 /* Initialize IT to deliver display elements from the overlay
5631 string. */
5632 it->string = it->overlay_strings[i];
5633 it->multibyte_p = STRING_MULTIBYTE (it->string);
5634 SET_TEXT_POS (it->current.string_pos, 0, 0);
5635 it->method = GET_FROM_STRING;
5636 it->stop_charpos = 0;
5637 it->end_charpos = SCHARS (it->string);
5638 if (it->cmp_it.stop_pos >= 0)
5639 it->cmp_it.stop_pos = 0;
5640 it->prev_stop = 0;
5641 it->base_level_stop = 0;
5642
5643 /* Set up the bidi iterator for this overlay string. */
5644 if (it->bidi_p)
5645 {
5646 it->bidi_it.string.lstring = it->string;
5647 it->bidi_it.string.s = NULL;
5648 it->bidi_it.string.schars = SCHARS (it->string);
5649 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5650 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5651 it->bidi_it.string.unibyte = !it->multibyte_p;
5652 it->bidi_it.w = it->w;
5653 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5654 }
5655 }
5656
5657 CHECK_IT (it);
5658 }
5659
5660
5661 /* Compare two overlay_entry structures E1 and E2. Used as a
5662 comparison function for qsort in load_overlay_strings. Overlay
5663 strings for the same position are sorted so that
5664
5665 1. All after-strings come in front of before-strings, except
5666 when they come from the same overlay.
5667
5668 2. Within after-strings, strings are sorted so that overlay strings
5669 from overlays with higher priorities come first.
5670
5671 2. Within before-strings, strings are sorted so that overlay
5672 strings from overlays with higher priorities come last.
5673
5674 Value is analogous to strcmp. */
5675
5676
5677 static int
5678 compare_overlay_entries (const void *e1, const void *e2)
5679 {
5680 struct overlay_entry const *entry1 = e1;
5681 struct overlay_entry const *entry2 = e2;
5682 int result;
5683
5684 if (entry1->after_string_p != entry2->after_string_p)
5685 {
5686 /* Let after-strings appear in front of before-strings if
5687 they come from different overlays. */
5688 if (EQ (entry1->overlay, entry2->overlay))
5689 result = entry1->after_string_p ? 1 : -1;
5690 else
5691 result = entry1->after_string_p ? -1 : 1;
5692 }
5693 else if (entry1->priority != entry2->priority)
5694 {
5695 if (entry1->after_string_p)
5696 /* After-strings sorted in order of decreasing priority. */
5697 result = entry2->priority < entry1->priority ? -1 : 1;
5698 else
5699 /* Before-strings sorted in order of increasing priority. */
5700 result = entry1->priority < entry2->priority ? -1 : 1;
5701 }
5702 else
5703 result = 0;
5704
5705 return result;
5706 }
5707
5708
5709 /* Load the vector IT->overlay_strings with overlay strings from IT's
5710 current buffer position, or from CHARPOS if that is > 0. Set
5711 IT->n_overlays to the total number of overlay strings found.
5712
5713 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5714 a time. On entry into load_overlay_strings,
5715 IT->current.overlay_string_index gives the number of overlay
5716 strings that have already been loaded by previous calls to this
5717 function.
5718
5719 IT->add_overlay_start contains an additional overlay start
5720 position to consider for taking overlay strings from, if non-zero.
5721 This position comes into play when the overlay has an `invisible'
5722 property, and both before and after-strings. When we've skipped to
5723 the end of the overlay, because of its `invisible' property, we
5724 nevertheless want its before-string to appear.
5725 IT->add_overlay_start will contain the overlay start position
5726 in this case.
5727
5728 Overlay strings are sorted so that after-string strings come in
5729 front of before-string strings. Within before and after-strings,
5730 strings are sorted by overlay priority. See also function
5731 compare_overlay_entries. */
5732
5733 static void
5734 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5735 {
5736 Lisp_Object overlay, window, str, invisible;
5737 struct Lisp_Overlay *ov;
5738 ptrdiff_t start, end;
5739 ptrdiff_t n = 0, i, j;
5740 int invis_p;
5741 struct overlay_entry entriesbuf[20];
5742 ptrdiff_t size = ARRAYELTS (entriesbuf);
5743 struct overlay_entry *entries = entriesbuf;
5744 USE_SAFE_ALLOCA;
5745
5746 if (charpos <= 0)
5747 charpos = IT_CHARPOS (*it);
5748
5749 /* Append the overlay string STRING of overlay OVERLAY to vector
5750 `entries' which has size `size' and currently contains `n'
5751 elements. AFTER_P non-zero means STRING is an after-string of
5752 OVERLAY. */
5753 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5754 do \
5755 { \
5756 Lisp_Object priority; \
5757 \
5758 if (n == size) \
5759 { \
5760 struct overlay_entry *old = entries; \
5761 SAFE_NALLOCA (entries, 2, size); \
5762 memcpy (entries, old, size * sizeof *entries); \
5763 size *= 2; \
5764 } \
5765 \
5766 entries[n].string = (STRING); \
5767 entries[n].overlay = (OVERLAY); \
5768 priority = Foverlay_get ((OVERLAY), Qpriority); \
5769 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5770 entries[n].after_string_p = (AFTER_P); \
5771 ++n; \
5772 } \
5773 while (0)
5774
5775 /* Process overlay before the overlay center. */
5776 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5777 {
5778 XSETMISC (overlay, ov);
5779 eassert (OVERLAYP (overlay));
5780 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5781 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5782
5783 if (end < charpos)
5784 break;
5785
5786 /* Skip this overlay if it doesn't start or end at IT's current
5787 position. */
5788 if (end != charpos && start != charpos)
5789 continue;
5790
5791 /* Skip this overlay if it doesn't apply to IT->w. */
5792 window = Foverlay_get (overlay, Qwindow);
5793 if (WINDOWP (window) && XWINDOW (window) != it->w)
5794 continue;
5795
5796 /* If the text ``under'' the overlay is invisible, both before-
5797 and after-strings from this overlay are visible; start and
5798 end position are indistinguishable. */
5799 invisible = Foverlay_get (overlay, Qinvisible);
5800 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5801
5802 /* If overlay has a non-empty before-string, record it. */
5803 if ((start == charpos || (end == charpos && invis_p))
5804 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5805 && SCHARS (str))
5806 RECORD_OVERLAY_STRING (overlay, str, 0);
5807
5808 /* If overlay has a non-empty after-string, record it. */
5809 if ((end == charpos || (start == charpos && invis_p))
5810 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5811 && SCHARS (str))
5812 RECORD_OVERLAY_STRING (overlay, str, 1);
5813 }
5814
5815 /* Process overlays after the overlay center. */
5816 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5817 {
5818 XSETMISC (overlay, ov);
5819 eassert (OVERLAYP (overlay));
5820 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5821 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5822
5823 if (start > charpos)
5824 break;
5825
5826 /* Skip this overlay if it doesn't start or end at IT's current
5827 position. */
5828 if (end != charpos && start != charpos)
5829 continue;
5830
5831 /* Skip this overlay if it doesn't apply to IT->w. */
5832 window = Foverlay_get (overlay, Qwindow);
5833 if (WINDOWP (window) && XWINDOW (window) != it->w)
5834 continue;
5835
5836 /* If the text ``under'' the overlay is invisible, it has a zero
5837 dimension, and both before- and after-strings apply. */
5838 invisible = Foverlay_get (overlay, Qinvisible);
5839 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5840
5841 /* If overlay has a non-empty before-string, record it. */
5842 if ((start == charpos || (end == charpos && invis_p))
5843 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5844 && SCHARS (str))
5845 RECORD_OVERLAY_STRING (overlay, str, 0);
5846
5847 /* If overlay has a non-empty after-string, record it. */
5848 if ((end == charpos || (start == charpos && invis_p))
5849 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5850 && SCHARS (str))
5851 RECORD_OVERLAY_STRING (overlay, str, 1);
5852 }
5853
5854 #undef RECORD_OVERLAY_STRING
5855
5856 /* Sort entries. */
5857 if (n > 1)
5858 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5859
5860 /* Record number of overlay strings, and where we computed it. */
5861 it->n_overlay_strings = n;
5862 it->overlay_strings_charpos = charpos;
5863
5864 /* IT->current.overlay_string_index is the number of overlay strings
5865 that have already been consumed by IT. Copy some of the
5866 remaining overlay strings to IT->overlay_strings. */
5867 i = 0;
5868 j = it->current.overlay_string_index;
5869 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5870 {
5871 it->overlay_strings[i] = entries[j].string;
5872 it->string_overlays[i++] = entries[j++].overlay;
5873 }
5874
5875 CHECK_IT (it);
5876 SAFE_FREE ();
5877 }
5878
5879
5880 /* Get the first chunk of overlay strings at IT's current buffer
5881 position, or at CHARPOS if that is > 0. Value is non-zero if at
5882 least one overlay string was found. */
5883
5884 static int
5885 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5886 {
5887 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5888 process. This fills IT->overlay_strings with strings, and sets
5889 IT->n_overlay_strings to the total number of strings to process.
5890 IT->pos.overlay_string_index has to be set temporarily to zero
5891 because load_overlay_strings needs this; it must be set to -1
5892 when no overlay strings are found because a zero value would
5893 indicate a position in the first overlay string. */
5894 it->current.overlay_string_index = 0;
5895 load_overlay_strings (it, charpos);
5896
5897 /* If we found overlay strings, set up IT to deliver display
5898 elements from the first one. Otherwise set up IT to deliver
5899 from current_buffer. */
5900 if (it->n_overlay_strings)
5901 {
5902 /* Make sure we know settings in current_buffer, so that we can
5903 restore meaningful values when we're done with the overlay
5904 strings. */
5905 if (compute_stop_p)
5906 compute_stop_pos (it);
5907 eassert (it->face_id >= 0);
5908
5909 /* Save IT's settings. They are restored after all overlay
5910 strings have been processed. */
5911 eassert (!compute_stop_p || it->sp == 0);
5912
5913 /* When called from handle_stop, there might be an empty display
5914 string loaded. In that case, don't bother saving it. But
5915 don't use this optimization with the bidi iterator, since we
5916 need the corresponding pop_it call to resync the bidi
5917 iterator's position with IT's position, after we are done
5918 with the overlay strings. (The corresponding call to pop_it
5919 in case of an empty display string is in
5920 next_overlay_string.) */
5921 if (!(!it->bidi_p
5922 && STRINGP (it->string) && !SCHARS (it->string)))
5923 push_it (it, NULL);
5924
5925 /* Set up IT to deliver display elements from the first overlay
5926 string. */
5927 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5928 it->string = it->overlay_strings[0];
5929 it->from_overlay = Qnil;
5930 it->stop_charpos = 0;
5931 eassert (STRINGP (it->string));
5932 it->end_charpos = SCHARS (it->string);
5933 it->prev_stop = 0;
5934 it->base_level_stop = 0;
5935 it->multibyte_p = STRING_MULTIBYTE (it->string);
5936 it->method = GET_FROM_STRING;
5937 it->from_disp_prop_p = 0;
5938
5939 /* Force paragraph direction to be that of the parent
5940 buffer. */
5941 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5942 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5943 else
5944 it->paragraph_embedding = L2R;
5945
5946 /* Set up the bidi iterator for this overlay string. */
5947 if (it->bidi_p)
5948 {
5949 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5950
5951 it->bidi_it.string.lstring = it->string;
5952 it->bidi_it.string.s = NULL;
5953 it->bidi_it.string.schars = SCHARS (it->string);
5954 it->bidi_it.string.bufpos = pos;
5955 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5956 it->bidi_it.string.unibyte = !it->multibyte_p;
5957 it->bidi_it.w = it->w;
5958 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5959 }
5960 return 1;
5961 }
5962
5963 it->current.overlay_string_index = -1;
5964 return 0;
5965 }
5966
5967 static int
5968 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5969 {
5970 it->string = Qnil;
5971 it->method = GET_FROM_BUFFER;
5972
5973 (void) get_overlay_strings_1 (it, charpos, 1);
5974
5975 CHECK_IT (it);
5976
5977 /* Value is non-zero if we found at least one overlay string. */
5978 return STRINGP (it->string);
5979 }
5980
5981
5982 \f
5983 /***********************************************************************
5984 Saving and restoring state
5985 ***********************************************************************/
5986
5987 /* Save current settings of IT on IT->stack. Called, for example,
5988 before setting up IT for an overlay string, to be able to restore
5989 IT's settings to what they were after the overlay string has been
5990 processed. If POSITION is non-NULL, it is the position to save on
5991 the stack instead of IT->position. */
5992
5993 static void
5994 push_it (struct it *it, struct text_pos *position)
5995 {
5996 struct iterator_stack_entry *p;
5997
5998 eassert (it->sp < IT_STACK_SIZE);
5999 p = it->stack + it->sp;
6000
6001 p->stop_charpos = it->stop_charpos;
6002 p->prev_stop = it->prev_stop;
6003 p->base_level_stop = it->base_level_stop;
6004 p->cmp_it = it->cmp_it;
6005 eassert (it->face_id >= 0);
6006 p->face_id = it->face_id;
6007 p->string = it->string;
6008 p->method = it->method;
6009 p->from_overlay = it->from_overlay;
6010 switch (p->method)
6011 {
6012 case GET_FROM_IMAGE:
6013 p->u.image.object = it->object;
6014 p->u.image.image_id = it->image_id;
6015 p->u.image.slice = it->slice;
6016 break;
6017 case GET_FROM_STRETCH:
6018 p->u.stretch.object = it->object;
6019 break;
6020 }
6021 p->position = position ? *position : it->position;
6022 p->current = it->current;
6023 p->end_charpos = it->end_charpos;
6024 p->string_nchars = it->string_nchars;
6025 p->area = it->area;
6026 p->multibyte_p = it->multibyte_p;
6027 p->avoid_cursor_p = it->avoid_cursor_p;
6028 p->space_width = it->space_width;
6029 p->font_height = it->font_height;
6030 p->voffset = it->voffset;
6031 p->string_from_display_prop_p = it->string_from_display_prop_p;
6032 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
6033 p->display_ellipsis_p = 0;
6034 p->line_wrap = it->line_wrap;
6035 p->bidi_p = it->bidi_p;
6036 p->paragraph_embedding = it->paragraph_embedding;
6037 p->from_disp_prop_p = it->from_disp_prop_p;
6038 ++it->sp;
6039
6040 /* Save the state of the bidi iterator as well. */
6041 if (it->bidi_p)
6042 bidi_push_it (&it->bidi_it);
6043 }
6044
6045 static void
6046 iterate_out_of_display_property (struct it *it)
6047 {
6048 int buffer_p = !STRINGP (it->string);
6049 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6050 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6051
6052 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6053
6054 /* Maybe initialize paragraph direction. If we are at the beginning
6055 of a new paragraph, next_element_from_buffer may not have a
6056 chance to do that. */
6057 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6058 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6059 /* prev_stop can be zero, so check against BEGV as well. */
6060 while (it->bidi_it.charpos >= bob
6061 && it->prev_stop <= it->bidi_it.charpos
6062 && it->bidi_it.charpos < CHARPOS (it->position)
6063 && it->bidi_it.charpos < eob)
6064 bidi_move_to_visually_next (&it->bidi_it);
6065 /* Record the stop_pos we just crossed, for when we cross it
6066 back, maybe. */
6067 if (it->bidi_it.charpos > CHARPOS (it->position))
6068 it->prev_stop = CHARPOS (it->position);
6069 /* If we ended up not where pop_it put us, resync IT's
6070 positional members with the bidi iterator. */
6071 if (it->bidi_it.charpos != CHARPOS (it->position))
6072 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6073 if (buffer_p)
6074 it->current.pos = it->position;
6075 else
6076 it->current.string_pos = it->position;
6077 }
6078
6079 /* Restore IT's settings from IT->stack. Called, for example, when no
6080 more overlay strings must be processed, and we return to delivering
6081 display elements from a buffer, or when the end of a string from a
6082 `display' property is reached and we return to delivering display
6083 elements from an overlay string, or from a buffer. */
6084
6085 static void
6086 pop_it (struct it *it)
6087 {
6088 struct iterator_stack_entry *p;
6089 int from_display_prop = it->from_disp_prop_p;
6090
6091 eassert (it->sp > 0);
6092 --it->sp;
6093 p = it->stack + it->sp;
6094 it->stop_charpos = p->stop_charpos;
6095 it->prev_stop = p->prev_stop;
6096 it->base_level_stop = p->base_level_stop;
6097 it->cmp_it = p->cmp_it;
6098 it->face_id = p->face_id;
6099 it->current = p->current;
6100 it->position = p->position;
6101 it->string = p->string;
6102 it->from_overlay = p->from_overlay;
6103 if (NILP (it->string))
6104 SET_TEXT_POS (it->current.string_pos, -1, -1);
6105 it->method = p->method;
6106 switch (it->method)
6107 {
6108 case GET_FROM_IMAGE:
6109 it->image_id = p->u.image.image_id;
6110 it->object = p->u.image.object;
6111 it->slice = p->u.image.slice;
6112 break;
6113 case GET_FROM_STRETCH:
6114 it->object = p->u.stretch.object;
6115 break;
6116 case GET_FROM_BUFFER:
6117 it->object = it->w->contents;
6118 break;
6119 case GET_FROM_STRING:
6120 {
6121 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6122
6123 /* Restore the face_box_p flag, since it could have been
6124 overwritten by the face of the object that we just finished
6125 displaying. */
6126 if (face)
6127 it->face_box_p = face->box != FACE_NO_BOX;
6128 it->object = it->string;
6129 }
6130 break;
6131 case GET_FROM_DISPLAY_VECTOR:
6132 if (it->s)
6133 it->method = GET_FROM_C_STRING;
6134 else if (STRINGP (it->string))
6135 it->method = GET_FROM_STRING;
6136 else
6137 {
6138 it->method = GET_FROM_BUFFER;
6139 it->object = it->w->contents;
6140 }
6141 }
6142 it->end_charpos = p->end_charpos;
6143 it->string_nchars = p->string_nchars;
6144 it->area = p->area;
6145 it->multibyte_p = p->multibyte_p;
6146 it->avoid_cursor_p = p->avoid_cursor_p;
6147 it->space_width = p->space_width;
6148 it->font_height = p->font_height;
6149 it->voffset = p->voffset;
6150 it->string_from_display_prop_p = p->string_from_display_prop_p;
6151 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6152 it->line_wrap = p->line_wrap;
6153 it->bidi_p = p->bidi_p;
6154 it->paragraph_embedding = p->paragraph_embedding;
6155 it->from_disp_prop_p = p->from_disp_prop_p;
6156 if (it->bidi_p)
6157 {
6158 bidi_pop_it (&it->bidi_it);
6159 /* Bidi-iterate until we get out of the portion of text, if any,
6160 covered by a `display' text property or by an overlay with
6161 `display' property. (We cannot just jump there, because the
6162 internal coherency of the bidi iterator state can not be
6163 preserved across such jumps.) We also must determine the
6164 paragraph base direction if the overlay we just processed is
6165 at the beginning of a new paragraph. */
6166 if (from_display_prop
6167 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6168 iterate_out_of_display_property (it);
6169
6170 eassert ((BUFFERP (it->object)
6171 && IT_CHARPOS (*it) == it->bidi_it.charpos
6172 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6173 || (STRINGP (it->object)
6174 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6175 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6176 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6177 }
6178 }
6179
6180
6181 \f
6182 /***********************************************************************
6183 Moving over lines
6184 ***********************************************************************/
6185
6186 /* Set IT's current position to the previous line start. */
6187
6188 static void
6189 back_to_previous_line_start (struct it *it)
6190 {
6191 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6192
6193 DEC_BOTH (cp, bp);
6194 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6195 }
6196
6197
6198 /* Move IT to the next line start.
6199
6200 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6201 we skipped over part of the text (as opposed to moving the iterator
6202 continuously over the text). Otherwise, don't change the value
6203 of *SKIPPED_P.
6204
6205 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6206 iterator on the newline, if it was found.
6207
6208 Newlines may come from buffer text, overlay strings, or strings
6209 displayed via the `display' property. That's the reason we can't
6210 simply use find_newline_no_quit.
6211
6212 Note that this function may not skip over invisible text that is so
6213 because of text properties and immediately follows a newline. If
6214 it would, function reseat_at_next_visible_line_start, when called
6215 from set_iterator_to_next, would effectively make invisible
6216 characters following a newline part of the wrong glyph row, which
6217 leads to wrong cursor motion. */
6218
6219 static int
6220 forward_to_next_line_start (struct it *it, int *skipped_p,
6221 struct bidi_it *bidi_it_prev)
6222 {
6223 ptrdiff_t old_selective;
6224 int newline_found_p, n;
6225 const int MAX_NEWLINE_DISTANCE = 500;
6226
6227 /* If already on a newline, just consume it to avoid unintended
6228 skipping over invisible text below. */
6229 if (it->what == IT_CHARACTER
6230 && it->c == '\n'
6231 && CHARPOS (it->position) == IT_CHARPOS (*it))
6232 {
6233 if (it->bidi_p && bidi_it_prev)
6234 *bidi_it_prev = it->bidi_it;
6235 set_iterator_to_next (it, 0);
6236 it->c = 0;
6237 return 1;
6238 }
6239
6240 /* Don't handle selective display in the following. It's (a)
6241 unnecessary because it's done by the caller, and (b) leads to an
6242 infinite recursion because next_element_from_ellipsis indirectly
6243 calls this function. */
6244 old_selective = it->selective;
6245 it->selective = 0;
6246
6247 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6248 from buffer text. */
6249 for (n = newline_found_p = 0;
6250 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6251 n += STRINGP (it->string) ? 0 : 1)
6252 {
6253 if (!get_next_display_element (it))
6254 return 0;
6255 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6256 if (newline_found_p && it->bidi_p && bidi_it_prev)
6257 *bidi_it_prev = it->bidi_it;
6258 set_iterator_to_next (it, 0);
6259 }
6260
6261 /* If we didn't find a newline near enough, see if we can use a
6262 short-cut. */
6263 if (!newline_found_p)
6264 {
6265 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6266 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6267 1, &bytepos);
6268 Lisp_Object pos;
6269
6270 eassert (!STRINGP (it->string));
6271
6272 /* If there isn't any `display' property in sight, and no
6273 overlays, we can just use the position of the newline in
6274 buffer text. */
6275 if (it->stop_charpos >= limit
6276 || ((pos = Fnext_single_property_change (make_number (start),
6277 Qdisplay, Qnil,
6278 make_number (limit)),
6279 NILP (pos))
6280 && next_overlay_change (start) == ZV))
6281 {
6282 if (!it->bidi_p)
6283 {
6284 IT_CHARPOS (*it) = limit;
6285 IT_BYTEPOS (*it) = bytepos;
6286 }
6287 else
6288 {
6289 struct bidi_it bprev;
6290
6291 /* Help bidi.c avoid expensive searches for display
6292 properties and overlays, by telling it that there are
6293 none up to `limit'. */
6294 if (it->bidi_it.disp_pos < limit)
6295 {
6296 it->bidi_it.disp_pos = limit;
6297 it->bidi_it.disp_prop = 0;
6298 }
6299 do {
6300 bprev = it->bidi_it;
6301 bidi_move_to_visually_next (&it->bidi_it);
6302 } while (it->bidi_it.charpos != limit);
6303 IT_CHARPOS (*it) = limit;
6304 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6305 if (bidi_it_prev)
6306 *bidi_it_prev = bprev;
6307 }
6308 *skipped_p = newline_found_p = true;
6309 }
6310 else
6311 {
6312 while (get_next_display_element (it)
6313 && !newline_found_p)
6314 {
6315 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6316 if (newline_found_p && it->bidi_p && bidi_it_prev)
6317 *bidi_it_prev = it->bidi_it;
6318 set_iterator_to_next (it, 0);
6319 }
6320 }
6321 }
6322
6323 it->selective = old_selective;
6324 return newline_found_p;
6325 }
6326
6327
6328 /* Set IT's current position to the previous visible line start. Skip
6329 invisible text that is so either due to text properties or due to
6330 selective display. Caution: this does not change IT->current_x and
6331 IT->hpos. */
6332
6333 static void
6334 back_to_previous_visible_line_start (struct it *it)
6335 {
6336 while (IT_CHARPOS (*it) > BEGV)
6337 {
6338 back_to_previous_line_start (it);
6339
6340 if (IT_CHARPOS (*it) <= BEGV)
6341 break;
6342
6343 /* If selective > 0, then lines indented more than its value are
6344 invisible. */
6345 if (it->selective > 0
6346 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6347 it->selective))
6348 continue;
6349
6350 /* Check the newline before point for invisibility. */
6351 {
6352 Lisp_Object prop;
6353 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6354 Qinvisible, it->window);
6355 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6356 continue;
6357 }
6358
6359 if (IT_CHARPOS (*it) <= BEGV)
6360 break;
6361
6362 {
6363 struct it it2;
6364 void *it2data = NULL;
6365 ptrdiff_t pos;
6366 ptrdiff_t beg, end;
6367 Lisp_Object val, overlay;
6368
6369 SAVE_IT (it2, *it, it2data);
6370
6371 /* If newline is part of a composition, continue from start of composition */
6372 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6373 && beg < IT_CHARPOS (*it))
6374 goto replaced;
6375
6376 /* If newline is replaced by a display property, find start of overlay
6377 or interval and continue search from that point. */
6378 pos = --IT_CHARPOS (it2);
6379 --IT_BYTEPOS (it2);
6380 it2.sp = 0;
6381 bidi_unshelve_cache (NULL, 0);
6382 it2.string_from_display_prop_p = 0;
6383 it2.from_disp_prop_p = 0;
6384 if (handle_display_prop (&it2) == HANDLED_RETURN
6385 && !NILP (val = get_char_property_and_overlay
6386 (make_number (pos), Qdisplay, Qnil, &overlay))
6387 && (OVERLAYP (overlay)
6388 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6389 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6390 {
6391 RESTORE_IT (it, it, it2data);
6392 goto replaced;
6393 }
6394
6395 /* Newline is not replaced by anything -- so we are done. */
6396 RESTORE_IT (it, it, it2data);
6397 break;
6398
6399 replaced:
6400 if (beg < BEGV)
6401 beg = BEGV;
6402 IT_CHARPOS (*it) = beg;
6403 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6404 }
6405 }
6406
6407 it->continuation_lines_width = 0;
6408
6409 eassert (IT_CHARPOS (*it) >= BEGV);
6410 eassert (IT_CHARPOS (*it) == BEGV
6411 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6412 CHECK_IT (it);
6413 }
6414
6415
6416 /* Reseat iterator IT at the previous visible line start. Skip
6417 invisible text that is so either due to text properties or due to
6418 selective display. At the end, update IT's overlay information,
6419 face information etc. */
6420
6421 void
6422 reseat_at_previous_visible_line_start (struct it *it)
6423 {
6424 back_to_previous_visible_line_start (it);
6425 reseat (it, it->current.pos, 1);
6426 CHECK_IT (it);
6427 }
6428
6429
6430 /* Reseat iterator IT on the next visible line start in the current
6431 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6432 preceding the line start. Skip over invisible text that is so
6433 because of selective display. Compute faces, overlays etc at the
6434 new position. Note that this function does not skip over text that
6435 is invisible because of text properties. */
6436
6437 static void
6438 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6439 {
6440 int newline_found_p, skipped_p = 0;
6441 struct bidi_it bidi_it_prev;
6442
6443 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6444
6445 /* Skip over lines that are invisible because they are indented
6446 more than the value of IT->selective. */
6447 if (it->selective > 0)
6448 while (IT_CHARPOS (*it) < ZV
6449 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6450 it->selective))
6451 {
6452 eassert (IT_BYTEPOS (*it) == BEGV
6453 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6454 newline_found_p =
6455 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6456 }
6457
6458 /* Position on the newline if that's what's requested. */
6459 if (on_newline_p && newline_found_p)
6460 {
6461 if (STRINGP (it->string))
6462 {
6463 if (IT_STRING_CHARPOS (*it) > 0)
6464 {
6465 if (!it->bidi_p)
6466 {
6467 --IT_STRING_CHARPOS (*it);
6468 --IT_STRING_BYTEPOS (*it);
6469 }
6470 else
6471 {
6472 /* We need to restore the bidi iterator to the state
6473 it had on the newline, and resync the IT's
6474 position with that. */
6475 it->bidi_it = bidi_it_prev;
6476 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6477 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6478 }
6479 }
6480 }
6481 else if (IT_CHARPOS (*it) > BEGV)
6482 {
6483 if (!it->bidi_p)
6484 {
6485 --IT_CHARPOS (*it);
6486 --IT_BYTEPOS (*it);
6487 }
6488 else
6489 {
6490 /* We need to restore the bidi iterator to the state it
6491 had on the newline and resync IT with that. */
6492 it->bidi_it = bidi_it_prev;
6493 IT_CHARPOS (*it) = it->bidi_it.charpos;
6494 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6495 }
6496 reseat (it, it->current.pos, 0);
6497 }
6498 }
6499 else if (skipped_p)
6500 reseat (it, it->current.pos, 0);
6501
6502 CHECK_IT (it);
6503 }
6504
6505
6506 \f
6507 /***********************************************************************
6508 Changing an iterator's position
6509 ***********************************************************************/
6510
6511 /* Change IT's current position to POS in current_buffer. If FORCE_P
6512 is non-zero, always check for text properties at the new position.
6513 Otherwise, text properties are only looked up if POS >=
6514 IT->check_charpos of a property. */
6515
6516 static void
6517 reseat (struct it *it, struct text_pos pos, int force_p)
6518 {
6519 ptrdiff_t original_pos = IT_CHARPOS (*it);
6520
6521 reseat_1 (it, pos, 0);
6522
6523 /* Determine where to check text properties. Avoid doing it
6524 where possible because text property lookup is very expensive. */
6525 if (force_p
6526 || CHARPOS (pos) > it->stop_charpos
6527 || CHARPOS (pos) < original_pos)
6528 {
6529 if (it->bidi_p)
6530 {
6531 /* For bidi iteration, we need to prime prev_stop and
6532 base_level_stop with our best estimations. */
6533 /* Implementation note: Of course, POS is not necessarily a
6534 stop position, so assigning prev_pos to it is a lie; we
6535 should have called compute_stop_backwards. However, if
6536 the current buffer does not include any R2L characters,
6537 that call would be a waste of cycles, because the
6538 iterator will never move back, and thus never cross this
6539 "fake" stop position. So we delay that backward search
6540 until the time we really need it, in next_element_from_buffer. */
6541 if (CHARPOS (pos) != it->prev_stop)
6542 it->prev_stop = CHARPOS (pos);
6543 if (CHARPOS (pos) < it->base_level_stop)
6544 it->base_level_stop = 0; /* meaning it's unknown */
6545 handle_stop (it);
6546 }
6547 else
6548 {
6549 handle_stop (it);
6550 it->prev_stop = it->base_level_stop = 0;
6551 }
6552
6553 }
6554
6555 CHECK_IT (it);
6556 }
6557
6558
6559 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6560 IT->stop_pos to POS, also. */
6561
6562 static void
6563 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6564 {
6565 /* Don't call this function when scanning a C string. */
6566 eassert (it->s == NULL);
6567
6568 /* POS must be a reasonable value. */
6569 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6570
6571 it->current.pos = it->position = pos;
6572 it->end_charpos = ZV;
6573 it->dpvec = NULL;
6574 it->current.dpvec_index = -1;
6575 it->current.overlay_string_index = -1;
6576 IT_STRING_CHARPOS (*it) = -1;
6577 IT_STRING_BYTEPOS (*it) = -1;
6578 it->string = Qnil;
6579 it->method = GET_FROM_BUFFER;
6580 it->object = it->w->contents;
6581 it->area = TEXT_AREA;
6582 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6583 it->sp = 0;
6584 it->string_from_display_prop_p = 0;
6585 it->string_from_prefix_prop_p = 0;
6586
6587 it->from_disp_prop_p = 0;
6588 it->face_before_selective_p = 0;
6589 if (it->bidi_p)
6590 {
6591 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6592 &it->bidi_it);
6593 bidi_unshelve_cache (NULL, 0);
6594 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6595 it->bidi_it.string.s = NULL;
6596 it->bidi_it.string.lstring = Qnil;
6597 it->bidi_it.string.bufpos = 0;
6598 it->bidi_it.string.from_disp_str = 0;
6599 it->bidi_it.string.unibyte = 0;
6600 it->bidi_it.w = it->w;
6601 }
6602
6603 if (set_stop_p)
6604 {
6605 it->stop_charpos = CHARPOS (pos);
6606 it->base_level_stop = CHARPOS (pos);
6607 }
6608 /* This make the information stored in it->cmp_it invalidate. */
6609 it->cmp_it.id = -1;
6610 }
6611
6612
6613 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6614 If S is non-null, it is a C string to iterate over. Otherwise,
6615 STRING gives a Lisp string to iterate over.
6616
6617 If PRECISION > 0, don't return more then PRECISION number of
6618 characters from the string.
6619
6620 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6621 characters have been returned. FIELD_WIDTH < 0 means an infinite
6622 field width.
6623
6624 MULTIBYTE = 0 means disable processing of multibyte characters,
6625 MULTIBYTE > 0 means enable it,
6626 MULTIBYTE < 0 means use IT->multibyte_p.
6627
6628 IT must be initialized via a prior call to init_iterator before
6629 calling this function. */
6630
6631 static void
6632 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6633 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6634 int multibyte)
6635 {
6636 /* No text property checks performed by default, but see below. */
6637 it->stop_charpos = -1;
6638
6639 /* Set iterator position and end position. */
6640 memset (&it->current, 0, sizeof it->current);
6641 it->current.overlay_string_index = -1;
6642 it->current.dpvec_index = -1;
6643 eassert (charpos >= 0);
6644
6645 /* If STRING is specified, use its multibyteness, otherwise use the
6646 setting of MULTIBYTE, if specified. */
6647 if (multibyte >= 0)
6648 it->multibyte_p = multibyte > 0;
6649
6650 /* Bidirectional reordering of strings is controlled by the default
6651 value of bidi-display-reordering. Don't try to reorder while
6652 loading loadup.el, as the necessary character property tables are
6653 not yet available. */
6654 it->bidi_p =
6655 NILP (Vpurify_flag)
6656 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6657
6658 if (s == NULL)
6659 {
6660 eassert (STRINGP (string));
6661 it->string = string;
6662 it->s = NULL;
6663 it->end_charpos = it->string_nchars = SCHARS (string);
6664 it->method = GET_FROM_STRING;
6665 it->current.string_pos = string_pos (charpos, string);
6666
6667 if (it->bidi_p)
6668 {
6669 it->bidi_it.string.lstring = string;
6670 it->bidi_it.string.s = NULL;
6671 it->bidi_it.string.schars = it->end_charpos;
6672 it->bidi_it.string.bufpos = 0;
6673 it->bidi_it.string.from_disp_str = 0;
6674 it->bidi_it.string.unibyte = !it->multibyte_p;
6675 it->bidi_it.w = it->w;
6676 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6677 FRAME_WINDOW_P (it->f), &it->bidi_it);
6678 }
6679 }
6680 else
6681 {
6682 it->s = (const unsigned char *) s;
6683 it->string = Qnil;
6684
6685 /* Note that we use IT->current.pos, not it->current.string_pos,
6686 for displaying C strings. */
6687 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6688 if (it->multibyte_p)
6689 {
6690 it->current.pos = c_string_pos (charpos, s, 1);
6691 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6692 }
6693 else
6694 {
6695 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6696 it->end_charpos = it->string_nchars = strlen (s);
6697 }
6698
6699 if (it->bidi_p)
6700 {
6701 it->bidi_it.string.lstring = Qnil;
6702 it->bidi_it.string.s = (const unsigned char *) s;
6703 it->bidi_it.string.schars = it->end_charpos;
6704 it->bidi_it.string.bufpos = 0;
6705 it->bidi_it.string.from_disp_str = 0;
6706 it->bidi_it.string.unibyte = !it->multibyte_p;
6707 it->bidi_it.w = it->w;
6708 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6709 &it->bidi_it);
6710 }
6711 it->method = GET_FROM_C_STRING;
6712 }
6713
6714 /* PRECISION > 0 means don't return more than PRECISION characters
6715 from the string. */
6716 if (precision > 0 && it->end_charpos - charpos > precision)
6717 {
6718 it->end_charpos = it->string_nchars = charpos + precision;
6719 if (it->bidi_p)
6720 it->bidi_it.string.schars = it->end_charpos;
6721 }
6722
6723 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6724 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6725 FIELD_WIDTH < 0 means infinite field width. This is useful for
6726 padding with `-' at the end of a mode line. */
6727 if (field_width < 0)
6728 field_width = INFINITY;
6729 /* Implementation note: We deliberately don't enlarge
6730 it->bidi_it.string.schars here to fit it->end_charpos, because
6731 the bidi iterator cannot produce characters out of thin air. */
6732 if (field_width > it->end_charpos - charpos)
6733 it->end_charpos = charpos + field_width;
6734
6735 /* Use the standard display table for displaying strings. */
6736 if (DISP_TABLE_P (Vstandard_display_table))
6737 it->dp = XCHAR_TABLE (Vstandard_display_table);
6738
6739 it->stop_charpos = charpos;
6740 it->prev_stop = charpos;
6741 it->base_level_stop = 0;
6742 if (it->bidi_p)
6743 {
6744 it->bidi_it.first_elt = 1;
6745 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6746 it->bidi_it.disp_pos = -1;
6747 }
6748 if (s == NULL && it->multibyte_p)
6749 {
6750 ptrdiff_t endpos = SCHARS (it->string);
6751 if (endpos > it->end_charpos)
6752 endpos = it->end_charpos;
6753 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6754 it->string);
6755 }
6756 CHECK_IT (it);
6757 }
6758
6759
6760 \f
6761 /***********************************************************************
6762 Iteration
6763 ***********************************************************************/
6764
6765 /* Map enum it_method value to corresponding next_element_from_* function. */
6766
6767 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6768 {
6769 next_element_from_buffer,
6770 next_element_from_display_vector,
6771 next_element_from_string,
6772 next_element_from_c_string,
6773 next_element_from_image,
6774 next_element_from_stretch
6775 };
6776
6777 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6778
6779
6780 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6781 (possibly with the following characters). */
6782
6783 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6784 ((IT)->cmp_it.id >= 0 \
6785 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6786 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6787 END_CHARPOS, (IT)->w, \
6788 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6789 (IT)->string)))
6790
6791
6792 /* Lookup the char-table Vglyphless_char_display for character C (-1
6793 if we want information for no-font case), and return the display
6794 method symbol. By side-effect, update it->what and
6795 it->glyphless_method. This function is called from
6796 get_next_display_element for each character element, and from
6797 x_produce_glyphs when no suitable font was found. */
6798
6799 Lisp_Object
6800 lookup_glyphless_char_display (int c, struct it *it)
6801 {
6802 Lisp_Object glyphless_method = Qnil;
6803
6804 if (CHAR_TABLE_P (Vglyphless_char_display)
6805 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6806 {
6807 if (c >= 0)
6808 {
6809 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6810 if (CONSP (glyphless_method))
6811 glyphless_method = FRAME_WINDOW_P (it->f)
6812 ? XCAR (glyphless_method)
6813 : XCDR (glyphless_method);
6814 }
6815 else
6816 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6817 }
6818
6819 retry:
6820 if (NILP (glyphless_method))
6821 {
6822 if (c >= 0)
6823 /* The default is to display the character by a proper font. */
6824 return Qnil;
6825 /* The default for the no-font case is to display an empty box. */
6826 glyphless_method = Qempty_box;
6827 }
6828 if (EQ (glyphless_method, Qzero_width))
6829 {
6830 if (c >= 0)
6831 return glyphless_method;
6832 /* This method can't be used for the no-font case. */
6833 glyphless_method = Qempty_box;
6834 }
6835 if (EQ (glyphless_method, Qthin_space))
6836 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6837 else if (EQ (glyphless_method, Qempty_box))
6838 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6839 else if (EQ (glyphless_method, Qhex_code))
6840 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6841 else if (STRINGP (glyphless_method))
6842 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6843 else
6844 {
6845 /* Invalid value. We use the default method. */
6846 glyphless_method = Qnil;
6847 goto retry;
6848 }
6849 it->what = IT_GLYPHLESS;
6850 return glyphless_method;
6851 }
6852
6853 /* Merge escape glyph face and cache the result. */
6854
6855 static struct frame *last_escape_glyph_frame = NULL;
6856 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6857 static int last_escape_glyph_merged_face_id = 0;
6858
6859 static int
6860 merge_escape_glyph_face (struct it *it)
6861 {
6862 int face_id;
6863
6864 if (it->f == last_escape_glyph_frame
6865 && it->face_id == last_escape_glyph_face_id)
6866 face_id = last_escape_glyph_merged_face_id;
6867 else
6868 {
6869 /* Merge the `escape-glyph' face into the current face. */
6870 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6871 last_escape_glyph_frame = it->f;
6872 last_escape_glyph_face_id = it->face_id;
6873 last_escape_glyph_merged_face_id = face_id;
6874 }
6875 return face_id;
6876 }
6877
6878 /* Likewise for glyphless glyph face. */
6879
6880 static struct frame *last_glyphless_glyph_frame = NULL;
6881 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6882 static int last_glyphless_glyph_merged_face_id = 0;
6883
6884 int
6885 merge_glyphless_glyph_face (struct it *it)
6886 {
6887 int face_id;
6888
6889 if (it->f == last_glyphless_glyph_frame
6890 && it->face_id == last_glyphless_glyph_face_id)
6891 face_id = last_glyphless_glyph_merged_face_id;
6892 else
6893 {
6894 /* Merge the `glyphless-char' face into the current face. */
6895 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6896 last_glyphless_glyph_frame = it->f;
6897 last_glyphless_glyph_face_id = it->face_id;
6898 last_glyphless_glyph_merged_face_id = face_id;
6899 }
6900 return face_id;
6901 }
6902
6903 /* Load IT's display element fields with information about the next
6904 display element from the current position of IT. Value is zero if
6905 end of buffer (or C string) is reached. */
6906
6907 static int
6908 get_next_display_element (struct it *it)
6909 {
6910 /* Non-zero means that we found a display element. Zero means that
6911 we hit the end of what we iterate over. Performance note: the
6912 function pointer `method' used here turns out to be faster than
6913 using a sequence of if-statements. */
6914 int success_p;
6915
6916 get_next:
6917 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6918
6919 if (it->what == IT_CHARACTER)
6920 {
6921 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6922 and only if (a) the resolved directionality of that character
6923 is R..." */
6924 /* FIXME: Do we need an exception for characters from display
6925 tables? */
6926 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6927 it->c = bidi_mirror_char (it->c);
6928 /* Map via display table or translate control characters.
6929 IT->c, IT->len etc. have been set to the next character by
6930 the function call above. If we have a display table, and it
6931 contains an entry for IT->c, translate it. Don't do this if
6932 IT->c itself comes from a display table, otherwise we could
6933 end up in an infinite recursion. (An alternative could be to
6934 count the recursion depth of this function and signal an
6935 error when a certain maximum depth is reached.) Is it worth
6936 it? */
6937 if (success_p && it->dpvec == NULL)
6938 {
6939 Lisp_Object dv;
6940 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6941 int nonascii_space_p = 0;
6942 int nonascii_hyphen_p = 0;
6943 int c = it->c; /* This is the character to display. */
6944
6945 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6946 {
6947 eassert (SINGLE_BYTE_CHAR_P (c));
6948 if (unibyte_display_via_language_environment)
6949 {
6950 c = DECODE_CHAR (unibyte, c);
6951 if (c < 0)
6952 c = BYTE8_TO_CHAR (it->c);
6953 }
6954 else
6955 c = BYTE8_TO_CHAR (it->c);
6956 }
6957
6958 if (it->dp
6959 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6960 VECTORP (dv)))
6961 {
6962 struct Lisp_Vector *v = XVECTOR (dv);
6963
6964 /* Return the first character from the display table
6965 entry, if not empty. If empty, don't display the
6966 current character. */
6967 if (v->header.size)
6968 {
6969 it->dpvec_char_len = it->len;
6970 it->dpvec = v->contents;
6971 it->dpend = v->contents + v->header.size;
6972 it->current.dpvec_index = 0;
6973 it->dpvec_face_id = -1;
6974 it->saved_face_id = it->face_id;
6975 it->method = GET_FROM_DISPLAY_VECTOR;
6976 it->ellipsis_p = 0;
6977 }
6978 else
6979 {
6980 set_iterator_to_next (it, 0);
6981 }
6982 goto get_next;
6983 }
6984
6985 if (! NILP (lookup_glyphless_char_display (c, it)))
6986 {
6987 if (it->what == IT_GLYPHLESS)
6988 goto done;
6989 /* Don't display this character. */
6990 set_iterator_to_next (it, 0);
6991 goto get_next;
6992 }
6993
6994 /* If `nobreak-char-display' is non-nil, we display
6995 non-ASCII spaces and hyphens specially. */
6996 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6997 {
6998 if (c == 0xA0)
6999 nonascii_space_p = true;
7000 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
7001 nonascii_hyphen_p = true;
7002 }
7003
7004 /* Translate control characters into `\003' or `^C' form.
7005 Control characters coming from a display table entry are
7006 currently not translated because we use IT->dpvec to hold
7007 the translation. This could easily be changed but I
7008 don't believe that it is worth doing.
7009
7010 The characters handled by `nobreak-char-display' must be
7011 translated too.
7012
7013 Non-printable characters and raw-byte characters are also
7014 translated to octal form. */
7015 if (((c < ' ' || c == 127) /* ASCII control chars. */
7016 ? (it->area != TEXT_AREA
7017 /* In mode line, treat \n, \t like other crl chars. */
7018 || (c != '\t'
7019 && it->glyph_row
7020 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
7021 || (c != '\n' && c != '\t'))
7022 : (nonascii_space_p
7023 || nonascii_hyphen_p
7024 || CHAR_BYTE8_P (c)
7025 || ! CHAR_PRINTABLE_P (c))))
7026 {
7027 /* C is a control character, non-ASCII space/hyphen,
7028 raw-byte, or a non-printable character which must be
7029 displayed either as '\003' or as `^C' where the '\\'
7030 and '^' can be defined in the display table. Fill
7031 IT->ctl_chars with glyphs for what we have to
7032 display. Then, set IT->dpvec to these glyphs. */
7033 Lisp_Object gc;
7034 int ctl_len;
7035 int face_id;
7036 int lface_id = 0;
7037 int escape_glyph;
7038
7039 /* Handle control characters with ^. */
7040
7041 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7042 {
7043 int g;
7044
7045 g = '^'; /* default glyph for Control */
7046 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7047 if (it->dp
7048 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7049 {
7050 g = GLYPH_CODE_CHAR (gc);
7051 lface_id = GLYPH_CODE_FACE (gc);
7052 }
7053
7054 face_id = (lface_id
7055 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7056 : merge_escape_glyph_face (it));
7057
7058 XSETINT (it->ctl_chars[0], g);
7059 XSETINT (it->ctl_chars[1], c ^ 0100);
7060 ctl_len = 2;
7061 goto display_control;
7062 }
7063
7064 /* Handle non-ascii space in the mode where it only gets
7065 highlighting. */
7066
7067 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7068 {
7069 /* Merge `nobreak-space' into the current face. */
7070 face_id = merge_faces (it->f, Qnobreak_space, 0,
7071 it->face_id);
7072 XSETINT (it->ctl_chars[0], ' ');
7073 ctl_len = 1;
7074 goto display_control;
7075 }
7076
7077 /* Handle sequences that start with the "escape glyph". */
7078
7079 /* the default escape glyph is \. */
7080 escape_glyph = '\\';
7081
7082 if (it->dp
7083 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7084 {
7085 escape_glyph = GLYPH_CODE_CHAR (gc);
7086 lface_id = GLYPH_CODE_FACE (gc);
7087 }
7088
7089 face_id = (lface_id
7090 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7091 : merge_escape_glyph_face (it));
7092
7093 /* Draw non-ASCII hyphen with just highlighting: */
7094
7095 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7096 {
7097 XSETINT (it->ctl_chars[0], '-');
7098 ctl_len = 1;
7099 goto display_control;
7100 }
7101
7102 /* Draw non-ASCII space/hyphen with escape glyph: */
7103
7104 if (nonascii_space_p || nonascii_hyphen_p)
7105 {
7106 XSETINT (it->ctl_chars[0], escape_glyph);
7107 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7108 ctl_len = 2;
7109 goto display_control;
7110 }
7111
7112 {
7113 char str[10];
7114 int len, i;
7115
7116 if (CHAR_BYTE8_P (c))
7117 /* Display \200 instead of \17777600. */
7118 c = CHAR_TO_BYTE8 (c);
7119 len = sprintf (str, "%03o", c);
7120
7121 XSETINT (it->ctl_chars[0], escape_glyph);
7122 for (i = 0; i < len; i++)
7123 XSETINT (it->ctl_chars[i + 1], str[i]);
7124 ctl_len = len + 1;
7125 }
7126
7127 display_control:
7128 /* Set up IT->dpvec and return first character from it. */
7129 it->dpvec_char_len = it->len;
7130 it->dpvec = it->ctl_chars;
7131 it->dpend = it->dpvec + ctl_len;
7132 it->current.dpvec_index = 0;
7133 it->dpvec_face_id = face_id;
7134 it->saved_face_id = it->face_id;
7135 it->method = GET_FROM_DISPLAY_VECTOR;
7136 it->ellipsis_p = 0;
7137 goto get_next;
7138 }
7139 it->char_to_display = c;
7140 }
7141 else if (success_p)
7142 {
7143 it->char_to_display = it->c;
7144 }
7145 }
7146
7147 #ifdef HAVE_WINDOW_SYSTEM
7148 /* Adjust face id for a multibyte character. There are no multibyte
7149 character in unibyte text. */
7150 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7151 && it->multibyte_p
7152 && success_p
7153 && FRAME_WINDOW_P (it->f))
7154 {
7155 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7156
7157 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7158 {
7159 /* Automatic composition with glyph-string. */
7160 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7161
7162 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7163 }
7164 else
7165 {
7166 ptrdiff_t pos = (it->s ? -1
7167 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7168 : IT_CHARPOS (*it));
7169 int c;
7170
7171 if (it->what == IT_CHARACTER)
7172 c = it->char_to_display;
7173 else
7174 {
7175 struct composition *cmp = composition_table[it->cmp_it.id];
7176 int i;
7177
7178 c = ' ';
7179 for (i = 0; i < cmp->glyph_len; i++)
7180 /* TAB in a composition means display glyphs with
7181 padding space on the left or right. */
7182 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7183 break;
7184 }
7185 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7186 }
7187 }
7188 #endif /* HAVE_WINDOW_SYSTEM */
7189
7190 done:
7191 /* Is this character the last one of a run of characters with
7192 box? If yes, set IT->end_of_box_run_p to 1. */
7193 if (it->face_box_p
7194 && it->s == NULL)
7195 {
7196 if (it->method == GET_FROM_STRING && it->sp)
7197 {
7198 int face_id = underlying_face_id (it);
7199 struct face *face = FACE_FROM_ID (it->f, face_id);
7200
7201 if (face)
7202 {
7203 if (face->box == FACE_NO_BOX)
7204 {
7205 /* If the box comes from face properties in a
7206 display string, check faces in that string. */
7207 int string_face_id = face_after_it_pos (it);
7208 it->end_of_box_run_p
7209 = (FACE_FROM_ID (it->f, string_face_id)->box
7210 == FACE_NO_BOX);
7211 }
7212 /* Otherwise, the box comes from the underlying face.
7213 If this is the last string character displayed, check
7214 the next buffer location. */
7215 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7216 /* n_overlay_strings is unreliable unless
7217 overlay_string_index is non-negative. */
7218 && ((it->current.overlay_string_index >= 0
7219 && (it->current.overlay_string_index
7220 == it->n_overlay_strings - 1))
7221 /* A string from display property. */
7222 || it->from_disp_prop_p))
7223 {
7224 ptrdiff_t ignore;
7225 int next_face_id;
7226 struct text_pos pos = it->current.pos;
7227
7228 /* For a string from a display property, the next
7229 buffer position is stored in the 'position'
7230 member of the iteration stack slot below the
7231 current one, see handle_single_display_spec. By
7232 contrast, it->current.pos was is not yet updated
7233 to point to that buffer position; that will
7234 happen in pop_it, after we finish displaying the
7235 current string. Note that we already checked
7236 above that it->sp is positive, so subtracting one
7237 from it is safe. */
7238 if (it->from_disp_prop_p)
7239 pos = (it->stack + it->sp - 1)->position;
7240 else
7241 INC_TEXT_POS (pos, it->multibyte_p);
7242
7243 if (CHARPOS (pos) >= ZV)
7244 it->end_of_box_run_p = true;
7245 else
7246 {
7247 next_face_id = face_at_buffer_position
7248 (it->w, CHARPOS (pos), &ignore,
7249 CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, 0, -1);
7250 it->end_of_box_run_p
7251 = (FACE_FROM_ID (it->f, next_face_id)->box
7252 == FACE_NO_BOX);
7253 }
7254 }
7255 }
7256 }
7257 /* next_element_from_display_vector sets this flag according to
7258 faces of the display vector glyphs, see there. */
7259 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7260 {
7261 int face_id = face_after_it_pos (it);
7262 it->end_of_box_run_p
7263 = (face_id != it->face_id
7264 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7265 }
7266 }
7267 /* If we reached the end of the object we've been iterating (e.g., a
7268 display string or an overlay string), and there's something on
7269 IT->stack, proceed with what's on the stack. It doesn't make
7270 sense to return zero if there's unprocessed stuff on the stack,
7271 because otherwise that stuff will never be displayed. */
7272 if (!success_p && it->sp > 0)
7273 {
7274 set_iterator_to_next (it, 0);
7275 success_p = get_next_display_element (it);
7276 }
7277
7278 /* Value is 0 if end of buffer or string reached. */
7279 return success_p;
7280 }
7281
7282
7283 /* Move IT to the next display element.
7284
7285 RESEAT_P non-zero means if called on a newline in buffer text,
7286 skip to the next visible line start.
7287
7288 Functions get_next_display_element and set_iterator_to_next are
7289 separate because I find this arrangement easier to handle than a
7290 get_next_display_element function that also increments IT's
7291 position. The way it is we can first look at an iterator's current
7292 display element, decide whether it fits on a line, and if it does,
7293 increment the iterator position. The other way around we probably
7294 would either need a flag indicating whether the iterator has to be
7295 incremented the next time, or we would have to implement a
7296 decrement position function which would not be easy to write. */
7297
7298 void
7299 set_iterator_to_next (struct it *it, int reseat_p)
7300 {
7301 /* Reset flags indicating start and end of a sequence of characters
7302 with box. Reset them at the start of this function because
7303 moving the iterator to a new position might set them. */
7304 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7305
7306 switch (it->method)
7307 {
7308 case GET_FROM_BUFFER:
7309 /* The current display element of IT is a character from
7310 current_buffer. Advance in the buffer, and maybe skip over
7311 invisible lines that are so because of selective display. */
7312 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7313 reseat_at_next_visible_line_start (it, 0);
7314 else if (it->cmp_it.id >= 0)
7315 {
7316 /* We are currently getting glyphs from a composition. */
7317 int i;
7318
7319 if (! it->bidi_p)
7320 {
7321 IT_CHARPOS (*it) += it->cmp_it.nchars;
7322 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7323 if (it->cmp_it.to < it->cmp_it.nglyphs)
7324 {
7325 it->cmp_it.from = it->cmp_it.to;
7326 }
7327 else
7328 {
7329 it->cmp_it.id = -1;
7330 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7331 IT_BYTEPOS (*it),
7332 it->end_charpos, Qnil);
7333 }
7334 }
7335 else if (! it->cmp_it.reversed_p)
7336 {
7337 /* Composition created while scanning forward. */
7338 /* Update IT's char/byte positions to point to the first
7339 character of the next grapheme cluster, or to the
7340 character visually after the current composition. */
7341 for (i = 0; i < it->cmp_it.nchars; i++)
7342 bidi_move_to_visually_next (&it->bidi_it);
7343 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7344 IT_CHARPOS (*it) = it->bidi_it.charpos;
7345
7346 if (it->cmp_it.to < it->cmp_it.nglyphs)
7347 {
7348 /* Proceed to the next grapheme cluster. */
7349 it->cmp_it.from = it->cmp_it.to;
7350 }
7351 else
7352 {
7353 /* No more grapheme clusters in this composition.
7354 Find the next stop position. */
7355 ptrdiff_t stop = it->end_charpos;
7356 if (it->bidi_it.scan_dir < 0)
7357 /* Now we are scanning backward and don't know
7358 where to stop. */
7359 stop = -1;
7360 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7361 IT_BYTEPOS (*it), stop, Qnil);
7362 }
7363 }
7364 else
7365 {
7366 /* Composition created while scanning backward. */
7367 /* Update IT's char/byte positions to point to the last
7368 character of the previous grapheme cluster, or the
7369 character visually after the current composition. */
7370 for (i = 0; i < it->cmp_it.nchars; i++)
7371 bidi_move_to_visually_next (&it->bidi_it);
7372 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7373 IT_CHARPOS (*it) = it->bidi_it.charpos;
7374 if (it->cmp_it.from > 0)
7375 {
7376 /* Proceed to the previous grapheme cluster. */
7377 it->cmp_it.to = it->cmp_it.from;
7378 }
7379 else
7380 {
7381 /* No more grapheme clusters in this composition.
7382 Find the next stop position. */
7383 ptrdiff_t stop = it->end_charpos;
7384 if (it->bidi_it.scan_dir < 0)
7385 /* Now we are scanning backward and don't know
7386 where to stop. */
7387 stop = -1;
7388 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7389 IT_BYTEPOS (*it), stop, Qnil);
7390 }
7391 }
7392 }
7393 else
7394 {
7395 eassert (it->len != 0);
7396
7397 if (!it->bidi_p)
7398 {
7399 IT_BYTEPOS (*it) += it->len;
7400 IT_CHARPOS (*it) += 1;
7401 }
7402 else
7403 {
7404 int prev_scan_dir = it->bidi_it.scan_dir;
7405 /* If this is a new paragraph, determine its base
7406 direction (a.k.a. its base embedding level). */
7407 if (it->bidi_it.new_paragraph)
7408 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7409 bidi_move_to_visually_next (&it->bidi_it);
7410 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7411 IT_CHARPOS (*it) = it->bidi_it.charpos;
7412 if (prev_scan_dir != it->bidi_it.scan_dir)
7413 {
7414 /* As the scan direction was changed, we must
7415 re-compute the stop position for composition. */
7416 ptrdiff_t stop = it->end_charpos;
7417 if (it->bidi_it.scan_dir < 0)
7418 stop = -1;
7419 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7420 IT_BYTEPOS (*it), stop, Qnil);
7421 }
7422 }
7423 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7424 }
7425 break;
7426
7427 case GET_FROM_C_STRING:
7428 /* Current display element of IT is from a C string. */
7429 if (!it->bidi_p
7430 /* If the string position is beyond string's end, it means
7431 next_element_from_c_string is padding the string with
7432 blanks, in which case we bypass the bidi iterator,
7433 because it cannot deal with such virtual characters. */
7434 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7435 {
7436 IT_BYTEPOS (*it) += it->len;
7437 IT_CHARPOS (*it) += 1;
7438 }
7439 else
7440 {
7441 bidi_move_to_visually_next (&it->bidi_it);
7442 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7443 IT_CHARPOS (*it) = it->bidi_it.charpos;
7444 }
7445 break;
7446
7447 case GET_FROM_DISPLAY_VECTOR:
7448 /* Current display element of IT is from a display table entry.
7449 Advance in the display table definition. Reset it to null if
7450 end reached, and continue with characters from buffers/
7451 strings. */
7452 ++it->current.dpvec_index;
7453
7454 /* Restore face of the iterator to what they were before the
7455 display vector entry (these entries may contain faces). */
7456 it->face_id = it->saved_face_id;
7457
7458 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7459 {
7460 int recheck_faces = it->ellipsis_p;
7461
7462 if (it->s)
7463 it->method = GET_FROM_C_STRING;
7464 else if (STRINGP (it->string))
7465 it->method = GET_FROM_STRING;
7466 else
7467 {
7468 it->method = GET_FROM_BUFFER;
7469 it->object = it->w->contents;
7470 }
7471
7472 it->dpvec = NULL;
7473 it->current.dpvec_index = -1;
7474
7475 /* Skip over characters which were displayed via IT->dpvec. */
7476 if (it->dpvec_char_len < 0)
7477 reseat_at_next_visible_line_start (it, 1);
7478 else if (it->dpvec_char_len > 0)
7479 {
7480 if (it->method == GET_FROM_STRING
7481 && it->current.overlay_string_index >= 0
7482 && it->n_overlay_strings > 0)
7483 it->ignore_overlay_strings_at_pos_p = true;
7484 it->len = it->dpvec_char_len;
7485 set_iterator_to_next (it, reseat_p);
7486 }
7487
7488 /* Maybe recheck faces after display vector. */
7489 if (recheck_faces)
7490 it->stop_charpos = IT_CHARPOS (*it);
7491 }
7492 break;
7493
7494 case GET_FROM_STRING:
7495 /* Current display element is a character from a Lisp string. */
7496 eassert (it->s == NULL && STRINGP (it->string));
7497 /* Don't advance past string end. These conditions are true
7498 when set_iterator_to_next is called at the end of
7499 get_next_display_element, in which case the Lisp string is
7500 already exhausted, and all we want is pop the iterator
7501 stack. */
7502 if (it->current.overlay_string_index >= 0)
7503 {
7504 /* This is an overlay string, so there's no padding with
7505 spaces, and the number of characters in the string is
7506 where the string ends. */
7507 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7508 goto consider_string_end;
7509 }
7510 else
7511 {
7512 /* Not an overlay string. There could be padding, so test
7513 against it->end_charpos. */
7514 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7515 goto consider_string_end;
7516 }
7517 if (it->cmp_it.id >= 0)
7518 {
7519 int i;
7520
7521 if (! it->bidi_p)
7522 {
7523 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7524 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7525 if (it->cmp_it.to < it->cmp_it.nglyphs)
7526 it->cmp_it.from = it->cmp_it.to;
7527 else
7528 {
7529 it->cmp_it.id = -1;
7530 composition_compute_stop_pos (&it->cmp_it,
7531 IT_STRING_CHARPOS (*it),
7532 IT_STRING_BYTEPOS (*it),
7533 it->end_charpos, it->string);
7534 }
7535 }
7536 else if (! it->cmp_it.reversed_p)
7537 {
7538 for (i = 0; i < it->cmp_it.nchars; i++)
7539 bidi_move_to_visually_next (&it->bidi_it);
7540 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7541 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7542
7543 if (it->cmp_it.to < it->cmp_it.nglyphs)
7544 it->cmp_it.from = it->cmp_it.to;
7545 else
7546 {
7547 ptrdiff_t stop = it->end_charpos;
7548 if (it->bidi_it.scan_dir < 0)
7549 stop = -1;
7550 composition_compute_stop_pos (&it->cmp_it,
7551 IT_STRING_CHARPOS (*it),
7552 IT_STRING_BYTEPOS (*it), stop,
7553 it->string);
7554 }
7555 }
7556 else
7557 {
7558 for (i = 0; i < it->cmp_it.nchars; i++)
7559 bidi_move_to_visually_next (&it->bidi_it);
7560 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7561 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7562 if (it->cmp_it.from > 0)
7563 it->cmp_it.to = it->cmp_it.from;
7564 else
7565 {
7566 ptrdiff_t stop = it->end_charpos;
7567 if (it->bidi_it.scan_dir < 0)
7568 stop = -1;
7569 composition_compute_stop_pos (&it->cmp_it,
7570 IT_STRING_CHARPOS (*it),
7571 IT_STRING_BYTEPOS (*it), stop,
7572 it->string);
7573 }
7574 }
7575 }
7576 else
7577 {
7578 if (!it->bidi_p
7579 /* If the string position is beyond string's end, it
7580 means next_element_from_string is padding the string
7581 with blanks, in which case we bypass the bidi
7582 iterator, because it cannot deal with such virtual
7583 characters. */
7584 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7585 {
7586 IT_STRING_BYTEPOS (*it) += it->len;
7587 IT_STRING_CHARPOS (*it) += 1;
7588 }
7589 else
7590 {
7591 int prev_scan_dir = it->bidi_it.scan_dir;
7592
7593 bidi_move_to_visually_next (&it->bidi_it);
7594 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7595 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7596 if (prev_scan_dir != it->bidi_it.scan_dir)
7597 {
7598 ptrdiff_t stop = it->end_charpos;
7599
7600 if (it->bidi_it.scan_dir < 0)
7601 stop = -1;
7602 composition_compute_stop_pos (&it->cmp_it,
7603 IT_STRING_CHARPOS (*it),
7604 IT_STRING_BYTEPOS (*it), stop,
7605 it->string);
7606 }
7607 }
7608 }
7609
7610 consider_string_end:
7611
7612 if (it->current.overlay_string_index >= 0)
7613 {
7614 /* IT->string is an overlay string. Advance to the
7615 next, if there is one. */
7616 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7617 {
7618 it->ellipsis_p = 0;
7619 next_overlay_string (it);
7620 if (it->ellipsis_p)
7621 setup_for_ellipsis (it, 0);
7622 }
7623 }
7624 else
7625 {
7626 /* IT->string is not an overlay string. If we reached
7627 its end, and there is something on IT->stack, proceed
7628 with what is on the stack. This can be either another
7629 string, this time an overlay string, or a buffer. */
7630 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7631 && it->sp > 0)
7632 {
7633 pop_it (it);
7634 if (it->method == GET_FROM_STRING)
7635 goto consider_string_end;
7636 }
7637 }
7638 break;
7639
7640 case GET_FROM_IMAGE:
7641 case GET_FROM_STRETCH:
7642 /* The position etc with which we have to proceed are on
7643 the stack. The position may be at the end of a string,
7644 if the `display' property takes up the whole string. */
7645 eassert (it->sp > 0);
7646 pop_it (it);
7647 if (it->method == GET_FROM_STRING)
7648 goto consider_string_end;
7649 break;
7650
7651 default:
7652 /* There are no other methods defined, so this should be a bug. */
7653 emacs_abort ();
7654 }
7655
7656 eassert (it->method != GET_FROM_STRING
7657 || (STRINGP (it->string)
7658 && IT_STRING_CHARPOS (*it) >= 0));
7659 }
7660
7661 /* Load IT's display element fields with information about the next
7662 display element which comes from a display table entry or from the
7663 result of translating a control character to one of the forms `^C'
7664 or `\003'.
7665
7666 IT->dpvec holds the glyphs to return as characters.
7667 IT->saved_face_id holds the face id before the display vector--it
7668 is restored into IT->face_id in set_iterator_to_next. */
7669
7670 static int
7671 next_element_from_display_vector (struct it *it)
7672 {
7673 Lisp_Object gc;
7674 int prev_face_id = it->face_id;
7675 int next_face_id;
7676
7677 /* Precondition. */
7678 eassert (it->dpvec && it->current.dpvec_index >= 0);
7679
7680 it->face_id = it->saved_face_id;
7681
7682 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7683 That seemed totally bogus - so I changed it... */
7684 gc = it->dpvec[it->current.dpvec_index];
7685
7686 if (GLYPH_CODE_P (gc))
7687 {
7688 struct face *this_face, *prev_face, *next_face;
7689
7690 it->c = GLYPH_CODE_CHAR (gc);
7691 it->len = CHAR_BYTES (it->c);
7692
7693 /* The entry may contain a face id to use. Such a face id is
7694 the id of a Lisp face, not a realized face. A face id of
7695 zero means no face is specified. */
7696 if (it->dpvec_face_id >= 0)
7697 it->face_id = it->dpvec_face_id;
7698 else
7699 {
7700 int lface_id = GLYPH_CODE_FACE (gc);
7701 if (lface_id > 0)
7702 it->face_id = merge_faces (it->f, Qt, lface_id,
7703 it->saved_face_id);
7704 }
7705
7706 /* Glyphs in the display vector could have the box face, so we
7707 need to set the related flags in the iterator, as
7708 appropriate. */
7709 this_face = FACE_FROM_ID (it->f, it->face_id);
7710 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7711
7712 /* Is this character the first character of a box-face run? */
7713 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7714 && (!prev_face
7715 || prev_face->box == FACE_NO_BOX));
7716
7717 /* For the last character of the box-face run, we need to look
7718 either at the next glyph from the display vector, or at the
7719 face we saw before the display vector. */
7720 next_face_id = it->saved_face_id;
7721 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7722 {
7723 if (it->dpvec_face_id >= 0)
7724 next_face_id = it->dpvec_face_id;
7725 else
7726 {
7727 int lface_id =
7728 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7729
7730 if (lface_id > 0)
7731 next_face_id = merge_faces (it->f, Qt, lface_id,
7732 it->saved_face_id);
7733 }
7734 }
7735 next_face = FACE_FROM_ID (it->f, next_face_id);
7736 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7737 && (!next_face
7738 || next_face->box == FACE_NO_BOX));
7739 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7740 }
7741 else
7742 /* Display table entry is invalid. Return a space. */
7743 it->c = ' ', it->len = 1;
7744
7745 /* Don't change position and object of the iterator here. They are
7746 still the values of the character that had this display table
7747 entry or was translated, and that's what we want. */
7748 it->what = IT_CHARACTER;
7749 return 1;
7750 }
7751
7752 /* Get the first element of string/buffer in the visual order, after
7753 being reseated to a new position in a string or a buffer. */
7754 static void
7755 get_visually_first_element (struct it *it)
7756 {
7757 int string_p = STRINGP (it->string) || it->s;
7758 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7759 ptrdiff_t bob = (string_p ? 0 : BEGV);
7760
7761 if (STRINGP (it->string))
7762 {
7763 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7764 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7765 }
7766 else
7767 {
7768 it->bidi_it.charpos = IT_CHARPOS (*it);
7769 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7770 }
7771
7772 if (it->bidi_it.charpos == eob)
7773 {
7774 /* Nothing to do, but reset the FIRST_ELT flag, like
7775 bidi_paragraph_init does, because we are not going to
7776 call it. */
7777 it->bidi_it.first_elt = 0;
7778 }
7779 else if (it->bidi_it.charpos == bob
7780 || (!string_p
7781 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7782 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7783 {
7784 /* If we are at the beginning of a line/string, we can produce
7785 the next element right away. */
7786 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7787 bidi_move_to_visually_next (&it->bidi_it);
7788 }
7789 else
7790 {
7791 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7792
7793 /* We need to prime the bidi iterator starting at the line's or
7794 string's beginning, before we will be able to produce the
7795 next element. */
7796 if (string_p)
7797 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7798 else
7799 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7800 IT_BYTEPOS (*it), -1,
7801 &it->bidi_it.bytepos);
7802 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7803 do
7804 {
7805 /* Now return to buffer/string position where we were asked
7806 to get the next display element, and produce that. */
7807 bidi_move_to_visually_next (&it->bidi_it);
7808 }
7809 while (it->bidi_it.bytepos != orig_bytepos
7810 && it->bidi_it.charpos < eob);
7811 }
7812
7813 /* Adjust IT's position information to where we ended up. */
7814 if (STRINGP (it->string))
7815 {
7816 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7817 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7818 }
7819 else
7820 {
7821 IT_CHARPOS (*it) = it->bidi_it.charpos;
7822 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7823 }
7824
7825 if (STRINGP (it->string) || !it->s)
7826 {
7827 ptrdiff_t stop, charpos, bytepos;
7828
7829 if (STRINGP (it->string))
7830 {
7831 eassert (!it->s);
7832 stop = SCHARS (it->string);
7833 if (stop > it->end_charpos)
7834 stop = it->end_charpos;
7835 charpos = IT_STRING_CHARPOS (*it);
7836 bytepos = IT_STRING_BYTEPOS (*it);
7837 }
7838 else
7839 {
7840 stop = it->end_charpos;
7841 charpos = IT_CHARPOS (*it);
7842 bytepos = IT_BYTEPOS (*it);
7843 }
7844 if (it->bidi_it.scan_dir < 0)
7845 stop = -1;
7846 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7847 it->string);
7848 }
7849 }
7850
7851 /* Load IT with the next display element from Lisp string IT->string.
7852 IT->current.string_pos is the current position within the string.
7853 If IT->current.overlay_string_index >= 0, the Lisp string is an
7854 overlay string. */
7855
7856 static int
7857 next_element_from_string (struct it *it)
7858 {
7859 struct text_pos position;
7860
7861 eassert (STRINGP (it->string));
7862 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7863 eassert (IT_STRING_CHARPOS (*it) >= 0);
7864 position = it->current.string_pos;
7865
7866 /* With bidi reordering, the character to display might not be the
7867 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7868 that we were reseat()ed to a new string, whose paragraph
7869 direction is not known. */
7870 if (it->bidi_p && it->bidi_it.first_elt)
7871 {
7872 get_visually_first_element (it);
7873 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7874 }
7875
7876 /* Time to check for invisible text? */
7877 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7878 {
7879 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7880 {
7881 if (!(!it->bidi_p
7882 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7883 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7884 {
7885 /* With bidi non-linear iteration, we could find
7886 ourselves far beyond the last computed stop_charpos,
7887 with several other stop positions in between that we
7888 missed. Scan them all now, in buffer's logical
7889 order, until we find and handle the last stop_charpos
7890 that precedes our current position. */
7891 handle_stop_backwards (it, it->stop_charpos);
7892 return GET_NEXT_DISPLAY_ELEMENT (it);
7893 }
7894 else
7895 {
7896 if (it->bidi_p)
7897 {
7898 /* Take note of the stop position we just moved
7899 across, for when we will move back across it. */
7900 it->prev_stop = it->stop_charpos;
7901 /* If we are at base paragraph embedding level, take
7902 note of the last stop position seen at this
7903 level. */
7904 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7905 it->base_level_stop = it->stop_charpos;
7906 }
7907 handle_stop (it);
7908
7909 /* Since a handler may have changed IT->method, we must
7910 recurse here. */
7911 return GET_NEXT_DISPLAY_ELEMENT (it);
7912 }
7913 }
7914 else if (it->bidi_p
7915 /* If we are before prev_stop, we may have overstepped
7916 on our way backwards a stop_pos, and if so, we need
7917 to handle that stop_pos. */
7918 && IT_STRING_CHARPOS (*it) < it->prev_stop
7919 /* We can sometimes back up for reasons that have nothing
7920 to do with bidi reordering. E.g., compositions. The
7921 code below is only needed when we are above the base
7922 embedding level, so test for that explicitly. */
7923 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7924 {
7925 /* If we lost track of base_level_stop, we have no better
7926 place for handle_stop_backwards to start from than string
7927 beginning. This happens, e.g., when we were reseated to
7928 the previous screenful of text by vertical-motion. */
7929 if (it->base_level_stop <= 0
7930 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7931 it->base_level_stop = 0;
7932 handle_stop_backwards (it, it->base_level_stop);
7933 return GET_NEXT_DISPLAY_ELEMENT (it);
7934 }
7935 }
7936
7937 if (it->current.overlay_string_index >= 0)
7938 {
7939 /* Get the next character from an overlay string. In overlay
7940 strings, there is no field width or padding with spaces to
7941 do. */
7942 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7943 {
7944 it->what = IT_EOB;
7945 return 0;
7946 }
7947 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7948 IT_STRING_BYTEPOS (*it),
7949 it->bidi_it.scan_dir < 0
7950 ? -1
7951 : SCHARS (it->string))
7952 && next_element_from_composition (it))
7953 {
7954 return 1;
7955 }
7956 else if (STRING_MULTIBYTE (it->string))
7957 {
7958 const unsigned char *s = (SDATA (it->string)
7959 + IT_STRING_BYTEPOS (*it));
7960 it->c = string_char_and_length (s, &it->len);
7961 }
7962 else
7963 {
7964 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7965 it->len = 1;
7966 }
7967 }
7968 else
7969 {
7970 /* Get the next character from a Lisp string that is not an
7971 overlay string. Such strings come from the mode line, for
7972 example. We may have to pad with spaces, or truncate the
7973 string. See also next_element_from_c_string. */
7974 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7975 {
7976 it->what = IT_EOB;
7977 return 0;
7978 }
7979 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7980 {
7981 /* Pad with spaces. */
7982 it->c = ' ', it->len = 1;
7983 CHARPOS (position) = BYTEPOS (position) = -1;
7984 }
7985 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7986 IT_STRING_BYTEPOS (*it),
7987 it->bidi_it.scan_dir < 0
7988 ? -1
7989 : it->string_nchars)
7990 && next_element_from_composition (it))
7991 {
7992 return 1;
7993 }
7994 else if (STRING_MULTIBYTE (it->string))
7995 {
7996 const unsigned char *s = (SDATA (it->string)
7997 + IT_STRING_BYTEPOS (*it));
7998 it->c = string_char_and_length (s, &it->len);
7999 }
8000 else
8001 {
8002 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8003 it->len = 1;
8004 }
8005 }
8006
8007 /* Record what we have and where it came from. */
8008 it->what = IT_CHARACTER;
8009 it->object = it->string;
8010 it->position = position;
8011 return 1;
8012 }
8013
8014
8015 /* Load IT with next display element from C string IT->s.
8016 IT->string_nchars is the maximum number of characters to return
8017 from the string. IT->end_charpos may be greater than
8018 IT->string_nchars when this function is called, in which case we
8019 may have to return padding spaces. Value is zero if end of string
8020 reached, including padding spaces. */
8021
8022 static int
8023 next_element_from_c_string (struct it *it)
8024 {
8025 bool success_p = true;
8026
8027 eassert (it->s);
8028 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
8029 it->what = IT_CHARACTER;
8030 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
8031 it->object = Qnil;
8032
8033 /* With bidi reordering, the character to display might not be the
8034 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8035 we were reseated to a new string, whose paragraph direction is
8036 not known. */
8037 if (it->bidi_p && it->bidi_it.first_elt)
8038 get_visually_first_element (it);
8039
8040 /* IT's position can be greater than IT->string_nchars in case a
8041 field width or precision has been specified when the iterator was
8042 initialized. */
8043 if (IT_CHARPOS (*it) >= it->end_charpos)
8044 {
8045 /* End of the game. */
8046 it->what = IT_EOB;
8047 success_p = 0;
8048 }
8049 else if (IT_CHARPOS (*it) >= it->string_nchars)
8050 {
8051 /* Pad with spaces. */
8052 it->c = ' ', it->len = 1;
8053 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8054 }
8055 else if (it->multibyte_p)
8056 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8057 else
8058 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8059
8060 return success_p;
8061 }
8062
8063
8064 /* Set up IT to return characters from an ellipsis, if appropriate.
8065 The definition of the ellipsis glyphs may come from a display table
8066 entry. This function fills IT with the first glyph from the
8067 ellipsis if an ellipsis is to be displayed. */
8068
8069 static int
8070 next_element_from_ellipsis (struct it *it)
8071 {
8072 if (it->selective_display_ellipsis_p)
8073 setup_for_ellipsis (it, it->len);
8074 else
8075 {
8076 /* The face at the current position may be different from the
8077 face we find after the invisible text. Remember what it
8078 was in IT->saved_face_id, and signal that it's there by
8079 setting face_before_selective_p. */
8080 it->saved_face_id = it->face_id;
8081 it->method = GET_FROM_BUFFER;
8082 it->object = it->w->contents;
8083 reseat_at_next_visible_line_start (it, 1);
8084 it->face_before_selective_p = true;
8085 }
8086
8087 return GET_NEXT_DISPLAY_ELEMENT (it);
8088 }
8089
8090
8091 /* Deliver an image display element. The iterator IT is already
8092 filled with image information (done in handle_display_prop). Value
8093 is always 1. */
8094
8095
8096 static int
8097 next_element_from_image (struct it *it)
8098 {
8099 it->what = IT_IMAGE;
8100 it->ignore_overlay_strings_at_pos_p = 0;
8101 return 1;
8102 }
8103
8104
8105 /* Fill iterator IT with next display element from a stretch glyph
8106 property. IT->object is the value of the text property. Value is
8107 always 1. */
8108
8109 static int
8110 next_element_from_stretch (struct it *it)
8111 {
8112 it->what = IT_STRETCH;
8113 return 1;
8114 }
8115
8116 /* Scan backwards from IT's current position until we find a stop
8117 position, or until BEGV. This is called when we find ourself
8118 before both the last known prev_stop and base_level_stop while
8119 reordering bidirectional text. */
8120
8121 static void
8122 compute_stop_pos_backwards (struct it *it)
8123 {
8124 const int SCAN_BACK_LIMIT = 1000;
8125 struct text_pos pos;
8126 struct display_pos save_current = it->current;
8127 struct text_pos save_position = it->position;
8128 ptrdiff_t charpos = IT_CHARPOS (*it);
8129 ptrdiff_t where_we_are = charpos;
8130 ptrdiff_t save_stop_pos = it->stop_charpos;
8131 ptrdiff_t save_end_pos = it->end_charpos;
8132
8133 eassert (NILP (it->string) && !it->s);
8134 eassert (it->bidi_p);
8135 it->bidi_p = 0;
8136 do
8137 {
8138 it->end_charpos = min (charpos + 1, ZV);
8139 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8140 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8141 reseat_1 (it, pos, 0);
8142 compute_stop_pos (it);
8143 /* We must advance forward, right? */
8144 if (it->stop_charpos <= charpos)
8145 emacs_abort ();
8146 }
8147 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8148
8149 if (it->stop_charpos <= where_we_are)
8150 it->prev_stop = it->stop_charpos;
8151 else
8152 it->prev_stop = BEGV;
8153 it->bidi_p = true;
8154 it->current = save_current;
8155 it->position = save_position;
8156 it->stop_charpos = save_stop_pos;
8157 it->end_charpos = save_end_pos;
8158 }
8159
8160 /* Scan forward from CHARPOS in the current buffer/string, until we
8161 find a stop position > current IT's position. Then handle the stop
8162 position before that. This is called when we bump into a stop
8163 position while reordering bidirectional text. CHARPOS should be
8164 the last previously processed stop_pos (or BEGV/0, if none were
8165 processed yet) whose position is less that IT's current
8166 position. */
8167
8168 static void
8169 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8170 {
8171 int bufp = !STRINGP (it->string);
8172 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8173 struct display_pos save_current = it->current;
8174 struct text_pos save_position = it->position;
8175 struct text_pos pos1;
8176 ptrdiff_t next_stop;
8177
8178 /* Scan in strict logical order. */
8179 eassert (it->bidi_p);
8180 it->bidi_p = 0;
8181 do
8182 {
8183 it->prev_stop = charpos;
8184 if (bufp)
8185 {
8186 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8187 reseat_1 (it, pos1, 0);
8188 }
8189 else
8190 it->current.string_pos = string_pos (charpos, it->string);
8191 compute_stop_pos (it);
8192 /* We must advance forward, right? */
8193 if (it->stop_charpos <= it->prev_stop)
8194 emacs_abort ();
8195 charpos = it->stop_charpos;
8196 }
8197 while (charpos <= where_we_are);
8198
8199 it->bidi_p = true;
8200 it->current = save_current;
8201 it->position = save_position;
8202 next_stop = it->stop_charpos;
8203 it->stop_charpos = it->prev_stop;
8204 handle_stop (it);
8205 it->stop_charpos = next_stop;
8206 }
8207
8208 /* Load IT with the next display element from current_buffer. Value
8209 is zero if end of buffer reached. IT->stop_charpos is the next
8210 position at which to stop and check for text properties or buffer
8211 end. */
8212
8213 static int
8214 next_element_from_buffer (struct it *it)
8215 {
8216 bool success_p = true;
8217
8218 eassert (IT_CHARPOS (*it) >= BEGV);
8219 eassert (NILP (it->string) && !it->s);
8220 eassert (!it->bidi_p
8221 || (EQ (it->bidi_it.string.lstring, Qnil)
8222 && it->bidi_it.string.s == NULL));
8223
8224 /* With bidi reordering, the character to display might not be the
8225 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8226 we were reseat()ed to a new buffer position, which is potentially
8227 a different paragraph. */
8228 if (it->bidi_p && it->bidi_it.first_elt)
8229 {
8230 get_visually_first_element (it);
8231 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8232 }
8233
8234 if (IT_CHARPOS (*it) >= it->stop_charpos)
8235 {
8236 if (IT_CHARPOS (*it) >= it->end_charpos)
8237 {
8238 int overlay_strings_follow_p;
8239
8240 /* End of the game, except when overlay strings follow that
8241 haven't been returned yet. */
8242 if (it->overlay_strings_at_end_processed_p)
8243 overlay_strings_follow_p = 0;
8244 else
8245 {
8246 it->overlay_strings_at_end_processed_p = true;
8247 overlay_strings_follow_p = get_overlay_strings (it, 0);
8248 }
8249
8250 if (overlay_strings_follow_p)
8251 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8252 else
8253 {
8254 it->what = IT_EOB;
8255 it->position = it->current.pos;
8256 success_p = 0;
8257 }
8258 }
8259 else if (!(!it->bidi_p
8260 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8261 || IT_CHARPOS (*it) == it->stop_charpos))
8262 {
8263 /* With bidi non-linear iteration, we could find ourselves
8264 far beyond the last computed stop_charpos, with several
8265 other stop positions in between that we missed. Scan
8266 them all now, in buffer's logical order, until we find
8267 and handle the last stop_charpos that precedes our
8268 current position. */
8269 handle_stop_backwards (it, it->stop_charpos);
8270 return GET_NEXT_DISPLAY_ELEMENT (it);
8271 }
8272 else
8273 {
8274 if (it->bidi_p)
8275 {
8276 /* Take note of the stop position we just moved across,
8277 for when we will move back across it. */
8278 it->prev_stop = it->stop_charpos;
8279 /* If we are at base paragraph embedding level, take
8280 note of the last stop position seen at this
8281 level. */
8282 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8283 it->base_level_stop = it->stop_charpos;
8284 }
8285 handle_stop (it);
8286 return GET_NEXT_DISPLAY_ELEMENT (it);
8287 }
8288 }
8289 else if (it->bidi_p
8290 /* If we are before prev_stop, we may have overstepped on
8291 our way backwards a stop_pos, and if so, we need to
8292 handle that stop_pos. */
8293 && IT_CHARPOS (*it) < it->prev_stop
8294 /* We can sometimes back up for reasons that have nothing
8295 to do with bidi reordering. E.g., compositions. The
8296 code below is only needed when we are above the base
8297 embedding level, so test for that explicitly. */
8298 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8299 {
8300 if (it->base_level_stop <= 0
8301 || IT_CHARPOS (*it) < it->base_level_stop)
8302 {
8303 /* If we lost track of base_level_stop, we need to find
8304 prev_stop by looking backwards. This happens, e.g., when
8305 we were reseated to the previous screenful of text by
8306 vertical-motion. */
8307 it->base_level_stop = BEGV;
8308 compute_stop_pos_backwards (it);
8309 handle_stop_backwards (it, it->prev_stop);
8310 }
8311 else
8312 handle_stop_backwards (it, it->base_level_stop);
8313 return GET_NEXT_DISPLAY_ELEMENT (it);
8314 }
8315 else
8316 {
8317 /* No face changes, overlays etc. in sight, so just return a
8318 character from current_buffer. */
8319 unsigned char *p;
8320 ptrdiff_t stop;
8321
8322 /* Maybe run the redisplay end trigger hook. Performance note:
8323 This doesn't seem to cost measurable time. */
8324 if (it->redisplay_end_trigger_charpos
8325 && it->glyph_row
8326 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8327 run_redisplay_end_trigger_hook (it);
8328
8329 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8330 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8331 stop)
8332 && next_element_from_composition (it))
8333 {
8334 return 1;
8335 }
8336
8337 /* Get the next character, maybe multibyte. */
8338 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8339 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8340 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8341 else
8342 it->c = *p, it->len = 1;
8343
8344 /* Record what we have and where it came from. */
8345 it->what = IT_CHARACTER;
8346 it->object = it->w->contents;
8347 it->position = it->current.pos;
8348
8349 /* Normally we return the character found above, except when we
8350 really want to return an ellipsis for selective display. */
8351 if (it->selective)
8352 {
8353 if (it->c == '\n')
8354 {
8355 /* A value of selective > 0 means hide lines indented more
8356 than that number of columns. */
8357 if (it->selective > 0
8358 && IT_CHARPOS (*it) + 1 < ZV
8359 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8360 IT_BYTEPOS (*it) + 1,
8361 it->selective))
8362 {
8363 success_p = next_element_from_ellipsis (it);
8364 it->dpvec_char_len = -1;
8365 }
8366 }
8367 else if (it->c == '\r' && it->selective == -1)
8368 {
8369 /* A value of selective == -1 means that everything from the
8370 CR to the end of the line is invisible, with maybe an
8371 ellipsis displayed for it. */
8372 success_p = next_element_from_ellipsis (it);
8373 it->dpvec_char_len = -1;
8374 }
8375 }
8376 }
8377
8378 /* Value is zero if end of buffer reached. */
8379 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8380 return success_p;
8381 }
8382
8383
8384 /* Run the redisplay end trigger hook for IT. */
8385
8386 static void
8387 run_redisplay_end_trigger_hook (struct it *it)
8388 {
8389 Lisp_Object args[3];
8390
8391 /* IT->glyph_row should be non-null, i.e. we should be actually
8392 displaying something, or otherwise we should not run the hook. */
8393 eassert (it->glyph_row);
8394
8395 /* Set up hook arguments. */
8396 args[0] = Qredisplay_end_trigger_functions;
8397 args[1] = it->window;
8398 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8399 it->redisplay_end_trigger_charpos = 0;
8400
8401 /* Since we are *trying* to run these functions, don't try to run
8402 them again, even if they get an error. */
8403 wset_redisplay_end_trigger (it->w, Qnil);
8404 Frun_hook_with_args (3, args);
8405
8406 /* Notice if it changed the face of the character we are on. */
8407 handle_face_prop (it);
8408 }
8409
8410
8411 /* Deliver a composition display element. Unlike the other
8412 next_element_from_XXX, this function is not registered in the array
8413 get_next_element[]. It is called from next_element_from_buffer and
8414 next_element_from_string when necessary. */
8415
8416 static int
8417 next_element_from_composition (struct it *it)
8418 {
8419 it->what = IT_COMPOSITION;
8420 it->len = it->cmp_it.nbytes;
8421 if (STRINGP (it->string))
8422 {
8423 if (it->c < 0)
8424 {
8425 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8426 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8427 return 0;
8428 }
8429 it->position = it->current.string_pos;
8430 it->object = it->string;
8431 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8432 IT_STRING_BYTEPOS (*it), it->string);
8433 }
8434 else
8435 {
8436 if (it->c < 0)
8437 {
8438 IT_CHARPOS (*it) += it->cmp_it.nchars;
8439 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8440 if (it->bidi_p)
8441 {
8442 if (it->bidi_it.new_paragraph)
8443 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8444 /* Resync the bidi iterator with IT's new position.
8445 FIXME: this doesn't support bidirectional text. */
8446 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8447 bidi_move_to_visually_next (&it->bidi_it);
8448 }
8449 return 0;
8450 }
8451 it->position = it->current.pos;
8452 it->object = it->w->contents;
8453 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8454 IT_BYTEPOS (*it), Qnil);
8455 }
8456 return 1;
8457 }
8458
8459
8460 \f
8461 /***********************************************************************
8462 Moving an iterator without producing glyphs
8463 ***********************************************************************/
8464
8465 /* Check if iterator is at a position corresponding to a valid buffer
8466 position after some move_it_ call. */
8467
8468 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8469 ((it)->method == GET_FROM_STRING \
8470 ? IT_STRING_CHARPOS (*it) == 0 \
8471 : 1)
8472
8473
8474 /* Move iterator IT to a specified buffer or X position within one
8475 line on the display without producing glyphs.
8476
8477 OP should be a bit mask including some or all of these bits:
8478 MOVE_TO_X: Stop upon reaching x-position TO_X.
8479 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8480 Regardless of OP's value, stop upon reaching the end of the display line.
8481
8482 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8483 This means, in particular, that TO_X includes window's horizontal
8484 scroll amount.
8485
8486 The return value has several possible values that
8487 say what condition caused the scan to stop:
8488
8489 MOVE_POS_MATCH_OR_ZV
8490 - when TO_POS or ZV was reached.
8491
8492 MOVE_X_REACHED
8493 -when TO_X was reached before TO_POS or ZV were reached.
8494
8495 MOVE_LINE_CONTINUED
8496 - when we reached the end of the display area and the line must
8497 be continued.
8498
8499 MOVE_LINE_TRUNCATED
8500 - when we reached the end of the display area and the line is
8501 truncated.
8502
8503 MOVE_NEWLINE_OR_CR
8504 - when we stopped at a line end, i.e. a newline or a CR and selective
8505 display is on. */
8506
8507 static enum move_it_result
8508 move_it_in_display_line_to (struct it *it,
8509 ptrdiff_t to_charpos, int to_x,
8510 enum move_operation_enum op)
8511 {
8512 enum move_it_result result = MOVE_UNDEFINED;
8513 struct glyph_row *saved_glyph_row;
8514 struct it wrap_it, atpos_it, atx_it, ppos_it;
8515 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8516 void *ppos_data = NULL;
8517 int may_wrap = 0;
8518 enum it_method prev_method = it->method;
8519 ptrdiff_t closest_pos IF_LINT (= 0), prev_pos = IT_CHARPOS (*it);
8520 int saw_smaller_pos = prev_pos < to_charpos;
8521
8522 /* Don't produce glyphs in produce_glyphs. */
8523 saved_glyph_row = it->glyph_row;
8524 it->glyph_row = NULL;
8525
8526 /* Use wrap_it to save a copy of IT wherever a word wrap could
8527 occur. Use atpos_it to save a copy of IT at the desired buffer
8528 position, if found, so that we can scan ahead and check if the
8529 word later overshoots the window edge. Use atx_it similarly, for
8530 pixel positions. */
8531 wrap_it.sp = -1;
8532 atpos_it.sp = -1;
8533 atx_it.sp = -1;
8534
8535 /* Use ppos_it under bidi reordering to save a copy of IT for the
8536 initial position. We restore that position in IT when we have
8537 scanned the entire display line without finding a match for
8538 TO_CHARPOS and all the character positions are greater than
8539 TO_CHARPOS. We then restart the scan from the initial position,
8540 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8541 the closest to TO_CHARPOS. */
8542 if (it->bidi_p)
8543 {
8544 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8545 {
8546 SAVE_IT (ppos_it, *it, ppos_data);
8547 closest_pos = IT_CHARPOS (*it);
8548 }
8549 else
8550 closest_pos = ZV;
8551 }
8552
8553 #define BUFFER_POS_REACHED_P() \
8554 ((op & MOVE_TO_POS) != 0 \
8555 && BUFFERP (it->object) \
8556 && (IT_CHARPOS (*it) == to_charpos \
8557 || ((!it->bidi_p \
8558 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8559 && IT_CHARPOS (*it) > to_charpos) \
8560 || (it->what == IT_COMPOSITION \
8561 && ((IT_CHARPOS (*it) > to_charpos \
8562 && to_charpos >= it->cmp_it.charpos) \
8563 || (IT_CHARPOS (*it) < to_charpos \
8564 && to_charpos <= it->cmp_it.charpos)))) \
8565 && (it->method == GET_FROM_BUFFER \
8566 || (it->method == GET_FROM_DISPLAY_VECTOR \
8567 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8568
8569 /* If there's a line-/wrap-prefix, handle it. */
8570 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8571 && it->current_y < it->last_visible_y)
8572 handle_line_prefix (it);
8573
8574 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8575 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8576
8577 while (1)
8578 {
8579 int x, i, ascent = 0, descent = 0;
8580
8581 /* Utility macro to reset an iterator with x, ascent, and descent. */
8582 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8583 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8584 (IT)->max_descent = descent)
8585
8586 /* Stop if we move beyond TO_CHARPOS (after an image or a
8587 display string or stretch glyph). */
8588 if ((op & MOVE_TO_POS) != 0
8589 && BUFFERP (it->object)
8590 && it->method == GET_FROM_BUFFER
8591 && (((!it->bidi_p
8592 /* When the iterator is at base embedding level, we
8593 are guaranteed that characters are delivered for
8594 display in strictly increasing order of their
8595 buffer positions. */
8596 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8597 && IT_CHARPOS (*it) > to_charpos)
8598 || (it->bidi_p
8599 && (prev_method == GET_FROM_IMAGE
8600 || prev_method == GET_FROM_STRETCH
8601 || prev_method == GET_FROM_STRING)
8602 /* Passed TO_CHARPOS from left to right. */
8603 && ((prev_pos < to_charpos
8604 && IT_CHARPOS (*it) > to_charpos)
8605 /* Passed TO_CHARPOS from right to left. */
8606 || (prev_pos > to_charpos
8607 && IT_CHARPOS (*it) < to_charpos)))))
8608 {
8609 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8610 {
8611 result = MOVE_POS_MATCH_OR_ZV;
8612 break;
8613 }
8614 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8615 /* If wrap_it is valid, the current position might be in a
8616 word that is wrapped. So, save the iterator in
8617 atpos_it and continue to see if wrapping happens. */
8618 SAVE_IT (atpos_it, *it, atpos_data);
8619 }
8620
8621 /* Stop when ZV reached.
8622 We used to stop here when TO_CHARPOS reached as well, but that is
8623 too soon if this glyph does not fit on this line. So we handle it
8624 explicitly below. */
8625 if (!get_next_display_element (it))
8626 {
8627 result = MOVE_POS_MATCH_OR_ZV;
8628 break;
8629 }
8630
8631 if (it->line_wrap == TRUNCATE)
8632 {
8633 if (BUFFER_POS_REACHED_P ())
8634 {
8635 result = MOVE_POS_MATCH_OR_ZV;
8636 break;
8637 }
8638 }
8639 else
8640 {
8641 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8642 {
8643 if (IT_DISPLAYING_WHITESPACE (it))
8644 may_wrap = 1;
8645 else if (may_wrap)
8646 {
8647 /* We have reached a glyph that follows one or more
8648 whitespace characters. If the position is
8649 already found, we are done. */
8650 if (atpos_it.sp >= 0)
8651 {
8652 RESTORE_IT (it, &atpos_it, atpos_data);
8653 result = MOVE_POS_MATCH_OR_ZV;
8654 goto done;
8655 }
8656 if (atx_it.sp >= 0)
8657 {
8658 RESTORE_IT (it, &atx_it, atx_data);
8659 result = MOVE_X_REACHED;
8660 goto done;
8661 }
8662 /* Otherwise, we can wrap here. */
8663 SAVE_IT (wrap_it, *it, wrap_data);
8664 may_wrap = 0;
8665 }
8666 }
8667 }
8668
8669 /* Remember the line height for the current line, in case
8670 the next element doesn't fit on the line. */
8671 ascent = it->max_ascent;
8672 descent = it->max_descent;
8673
8674 /* The call to produce_glyphs will get the metrics of the
8675 display element IT is loaded with. Record the x-position
8676 before this display element, in case it doesn't fit on the
8677 line. */
8678 x = it->current_x;
8679
8680 PRODUCE_GLYPHS (it);
8681
8682 if (it->area != TEXT_AREA)
8683 {
8684 prev_method = it->method;
8685 if (it->method == GET_FROM_BUFFER)
8686 prev_pos = IT_CHARPOS (*it);
8687 set_iterator_to_next (it, 1);
8688 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8689 SET_TEXT_POS (this_line_min_pos,
8690 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8691 if (it->bidi_p
8692 && (op & MOVE_TO_POS)
8693 && IT_CHARPOS (*it) > to_charpos
8694 && IT_CHARPOS (*it) < closest_pos)
8695 closest_pos = IT_CHARPOS (*it);
8696 continue;
8697 }
8698
8699 /* The number of glyphs we get back in IT->nglyphs will normally
8700 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8701 character on a terminal frame, or (iii) a line end. For the
8702 second case, IT->nglyphs - 1 padding glyphs will be present.
8703 (On X frames, there is only one glyph produced for a
8704 composite character.)
8705
8706 The behavior implemented below means, for continuation lines,
8707 that as many spaces of a TAB as fit on the current line are
8708 displayed there. For terminal frames, as many glyphs of a
8709 multi-glyph character are displayed in the current line, too.
8710 This is what the old redisplay code did, and we keep it that
8711 way. Under X, the whole shape of a complex character must
8712 fit on the line or it will be completely displayed in the
8713 next line.
8714
8715 Note that both for tabs and padding glyphs, all glyphs have
8716 the same width. */
8717 if (it->nglyphs)
8718 {
8719 /* More than one glyph or glyph doesn't fit on line. All
8720 glyphs have the same width. */
8721 int single_glyph_width = it->pixel_width / it->nglyphs;
8722 int new_x;
8723 int x_before_this_char = x;
8724 int hpos_before_this_char = it->hpos;
8725
8726 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8727 {
8728 new_x = x + single_glyph_width;
8729
8730 /* We want to leave anything reaching TO_X to the caller. */
8731 if ((op & MOVE_TO_X) && new_x > to_x)
8732 {
8733 if (BUFFER_POS_REACHED_P ())
8734 {
8735 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8736 goto buffer_pos_reached;
8737 if (atpos_it.sp < 0)
8738 {
8739 SAVE_IT (atpos_it, *it, atpos_data);
8740 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8741 }
8742 }
8743 else
8744 {
8745 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8746 {
8747 it->current_x = x;
8748 result = MOVE_X_REACHED;
8749 break;
8750 }
8751 if (atx_it.sp < 0)
8752 {
8753 SAVE_IT (atx_it, *it, atx_data);
8754 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8755 }
8756 }
8757 }
8758
8759 if (/* Lines are continued. */
8760 it->line_wrap != TRUNCATE
8761 && (/* And glyph doesn't fit on the line. */
8762 new_x > it->last_visible_x
8763 /* Or it fits exactly and we're on a window
8764 system frame. */
8765 || (new_x == it->last_visible_x
8766 && FRAME_WINDOW_P (it->f)
8767 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8768 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8769 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8770 {
8771 if (/* IT->hpos == 0 means the very first glyph
8772 doesn't fit on the line, e.g. a wide image. */
8773 it->hpos == 0
8774 || (new_x == it->last_visible_x
8775 && FRAME_WINDOW_P (it->f)
8776 /* When word-wrap is ON and we have a valid
8777 wrap point, we don't allow the last glyph
8778 to "just barely fit" on the line. */
8779 && (it->line_wrap != WORD_WRAP
8780 || wrap_it.sp < 0)))
8781 {
8782 ++it->hpos;
8783 it->current_x = new_x;
8784
8785 /* The character's last glyph just barely fits
8786 in this row. */
8787 if (i == it->nglyphs - 1)
8788 {
8789 /* If this is the destination position,
8790 return a position *before* it in this row,
8791 now that we know it fits in this row. */
8792 if (BUFFER_POS_REACHED_P ())
8793 {
8794 if (it->line_wrap != WORD_WRAP
8795 || wrap_it.sp < 0)
8796 {
8797 it->hpos = hpos_before_this_char;
8798 it->current_x = x_before_this_char;
8799 result = MOVE_POS_MATCH_OR_ZV;
8800 break;
8801 }
8802 if (it->line_wrap == WORD_WRAP
8803 && atpos_it.sp < 0)
8804 {
8805 SAVE_IT (atpos_it, *it, atpos_data);
8806 atpos_it.current_x = x_before_this_char;
8807 atpos_it.hpos = hpos_before_this_char;
8808 }
8809 }
8810
8811 prev_method = it->method;
8812 if (it->method == GET_FROM_BUFFER)
8813 prev_pos = IT_CHARPOS (*it);
8814 set_iterator_to_next (it, 1);
8815 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8816 SET_TEXT_POS (this_line_min_pos,
8817 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8818 /* On graphical terminals, newlines may
8819 "overflow" into the fringe if
8820 overflow-newline-into-fringe is non-nil.
8821 On text terminals, and on graphical
8822 terminals with no right margin, newlines
8823 may overflow into the last glyph on the
8824 display line.*/
8825 if (!FRAME_WINDOW_P (it->f)
8826 || ((it->bidi_p
8827 && it->bidi_it.paragraph_dir == R2L)
8828 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8829 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8830 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8831 {
8832 if (!get_next_display_element (it))
8833 {
8834 result = MOVE_POS_MATCH_OR_ZV;
8835 break;
8836 }
8837 if (BUFFER_POS_REACHED_P ())
8838 {
8839 if (ITERATOR_AT_END_OF_LINE_P (it))
8840 result = MOVE_POS_MATCH_OR_ZV;
8841 else
8842 result = MOVE_LINE_CONTINUED;
8843 break;
8844 }
8845 if (ITERATOR_AT_END_OF_LINE_P (it)
8846 && (it->line_wrap != WORD_WRAP
8847 || wrap_it.sp < 0))
8848 {
8849 result = MOVE_NEWLINE_OR_CR;
8850 break;
8851 }
8852 }
8853 }
8854 }
8855 else
8856 IT_RESET_X_ASCENT_DESCENT (it);
8857
8858 if (wrap_it.sp >= 0)
8859 {
8860 RESTORE_IT (it, &wrap_it, wrap_data);
8861 atpos_it.sp = -1;
8862 atx_it.sp = -1;
8863 }
8864
8865 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8866 IT_CHARPOS (*it)));
8867 result = MOVE_LINE_CONTINUED;
8868 break;
8869 }
8870
8871 if (BUFFER_POS_REACHED_P ())
8872 {
8873 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8874 goto buffer_pos_reached;
8875 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8876 {
8877 SAVE_IT (atpos_it, *it, atpos_data);
8878 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8879 }
8880 }
8881
8882 if (new_x > it->first_visible_x)
8883 {
8884 /* Glyph is visible. Increment number of glyphs that
8885 would be displayed. */
8886 ++it->hpos;
8887 }
8888 }
8889
8890 if (result != MOVE_UNDEFINED)
8891 break;
8892 }
8893 else if (BUFFER_POS_REACHED_P ())
8894 {
8895 buffer_pos_reached:
8896 IT_RESET_X_ASCENT_DESCENT (it);
8897 result = MOVE_POS_MATCH_OR_ZV;
8898 break;
8899 }
8900 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8901 {
8902 /* Stop when TO_X specified and reached. This check is
8903 necessary here because of lines consisting of a line end,
8904 only. The line end will not produce any glyphs and we
8905 would never get MOVE_X_REACHED. */
8906 eassert (it->nglyphs == 0);
8907 result = MOVE_X_REACHED;
8908 break;
8909 }
8910
8911 /* Is this a line end? If yes, we're done. */
8912 if (ITERATOR_AT_END_OF_LINE_P (it))
8913 {
8914 /* If we are past TO_CHARPOS, but never saw any character
8915 positions smaller than TO_CHARPOS, return
8916 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8917 did. */
8918 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8919 {
8920 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8921 {
8922 if (closest_pos < ZV)
8923 {
8924 RESTORE_IT (it, &ppos_it, ppos_data);
8925 /* Don't recurse if closest_pos is equal to
8926 to_charpos, since we have just tried that. */
8927 if (closest_pos != to_charpos)
8928 move_it_in_display_line_to (it, closest_pos, -1,
8929 MOVE_TO_POS);
8930 result = MOVE_POS_MATCH_OR_ZV;
8931 }
8932 else
8933 goto buffer_pos_reached;
8934 }
8935 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8936 && IT_CHARPOS (*it) > to_charpos)
8937 goto buffer_pos_reached;
8938 else
8939 result = MOVE_NEWLINE_OR_CR;
8940 }
8941 else
8942 result = MOVE_NEWLINE_OR_CR;
8943 break;
8944 }
8945
8946 prev_method = it->method;
8947 if (it->method == GET_FROM_BUFFER)
8948 prev_pos = IT_CHARPOS (*it);
8949 /* The current display element has been consumed. Advance
8950 to the next. */
8951 set_iterator_to_next (it, 1);
8952 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8953 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8954 if (IT_CHARPOS (*it) < to_charpos)
8955 saw_smaller_pos = 1;
8956 if (it->bidi_p
8957 && (op & MOVE_TO_POS)
8958 && IT_CHARPOS (*it) >= to_charpos
8959 && IT_CHARPOS (*it) < closest_pos)
8960 closest_pos = IT_CHARPOS (*it);
8961
8962 /* Stop if lines are truncated and IT's current x-position is
8963 past the right edge of the window now. */
8964 if (it->line_wrap == TRUNCATE
8965 && it->current_x >= it->last_visible_x)
8966 {
8967 if (!FRAME_WINDOW_P (it->f)
8968 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8969 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8970 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8971 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8972 {
8973 int at_eob_p = 0;
8974
8975 if ((at_eob_p = !get_next_display_element (it))
8976 || BUFFER_POS_REACHED_P ()
8977 /* If we are past TO_CHARPOS, but never saw any
8978 character positions smaller than TO_CHARPOS,
8979 return MOVE_POS_MATCH_OR_ZV, like the
8980 unidirectional display did. */
8981 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8982 && !saw_smaller_pos
8983 && IT_CHARPOS (*it) > to_charpos))
8984 {
8985 if (it->bidi_p
8986 && !BUFFER_POS_REACHED_P ()
8987 && !at_eob_p && closest_pos < ZV)
8988 {
8989 RESTORE_IT (it, &ppos_it, ppos_data);
8990 if (closest_pos != to_charpos)
8991 move_it_in_display_line_to (it, closest_pos, -1,
8992 MOVE_TO_POS);
8993 }
8994 result = MOVE_POS_MATCH_OR_ZV;
8995 break;
8996 }
8997 if (ITERATOR_AT_END_OF_LINE_P (it))
8998 {
8999 result = MOVE_NEWLINE_OR_CR;
9000 break;
9001 }
9002 }
9003 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
9004 && !saw_smaller_pos
9005 && IT_CHARPOS (*it) > to_charpos)
9006 {
9007 if (closest_pos < ZV)
9008 {
9009 RESTORE_IT (it, &ppos_it, ppos_data);
9010 if (closest_pos != to_charpos)
9011 move_it_in_display_line_to (it, closest_pos, -1,
9012 MOVE_TO_POS);
9013 }
9014 result = MOVE_POS_MATCH_OR_ZV;
9015 break;
9016 }
9017 result = MOVE_LINE_TRUNCATED;
9018 break;
9019 }
9020 #undef IT_RESET_X_ASCENT_DESCENT
9021 }
9022
9023 #undef BUFFER_POS_REACHED_P
9024
9025 /* If we scanned beyond to_pos and didn't find a point to wrap at,
9026 restore the saved iterator. */
9027 if (atpos_it.sp >= 0)
9028 RESTORE_IT (it, &atpos_it, atpos_data);
9029 else if (atx_it.sp >= 0)
9030 RESTORE_IT (it, &atx_it, atx_data);
9031
9032 done:
9033
9034 if (atpos_data)
9035 bidi_unshelve_cache (atpos_data, 1);
9036 if (atx_data)
9037 bidi_unshelve_cache (atx_data, 1);
9038 if (wrap_data)
9039 bidi_unshelve_cache (wrap_data, 1);
9040 if (ppos_data)
9041 bidi_unshelve_cache (ppos_data, 1);
9042
9043 /* Restore the iterator settings altered at the beginning of this
9044 function. */
9045 it->glyph_row = saved_glyph_row;
9046 return result;
9047 }
9048
9049 /* For external use. */
9050 void
9051 move_it_in_display_line (struct it *it,
9052 ptrdiff_t to_charpos, int to_x,
9053 enum move_operation_enum op)
9054 {
9055 if (it->line_wrap == WORD_WRAP
9056 && (op & MOVE_TO_X))
9057 {
9058 struct it save_it;
9059 void *save_data = NULL;
9060 int skip;
9061
9062 SAVE_IT (save_it, *it, save_data);
9063 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9064 /* When word-wrap is on, TO_X may lie past the end
9065 of a wrapped line. Then it->current is the
9066 character on the next line, so backtrack to the
9067 space before the wrap point. */
9068 if (skip == MOVE_LINE_CONTINUED)
9069 {
9070 int prev_x = max (it->current_x - 1, 0);
9071 RESTORE_IT (it, &save_it, save_data);
9072 move_it_in_display_line_to
9073 (it, -1, prev_x, MOVE_TO_X);
9074 }
9075 else
9076 bidi_unshelve_cache (save_data, 1);
9077 }
9078 else
9079 move_it_in_display_line_to (it, to_charpos, to_x, op);
9080 }
9081
9082
9083 /* Move IT forward until it satisfies one or more of the criteria in
9084 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9085
9086 OP is a bit-mask that specifies where to stop, and in particular,
9087 which of those four position arguments makes a difference. See the
9088 description of enum move_operation_enum.
9089
9090 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9091 screen line, this function will set IT to the next position that is
9092 displayed to the right of TO_CHARPOS on the screen.
9093
9094 Return the maximum pixel length of any line scanned but never more
9095 than it.last_visible_x. */
9096
9097 int
9098 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9099 {
9100 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9101 int line_height, line_start_x = 0, reached = 0;
9102 int max_current_x = 0;
9103 void *backup_data = NULL;
9104
9105 for (;;)
9106 {
9107 if (op & MOVE_TO_VPOS)
9108 {
9109 /* If no TO_CHARPOS and no TO_X specified, stop at the
9110 start of the line TO_VPOS. */
9111 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9112 {
9113 if (it->vpos == to_vpos)
9114 {
9115 reached = 1;
9116 break;
9117 }
9118 else
9119 skip = move_it_in_display_line_to (it, -1, -1, 0);
9120 }
9121 else
9122 {
9123 /* TO_VPOS >= 0 means stop at TO_X in the line at
9124 TO_VPOS, or at TO_POS, whichever comes first. */
9125 if (it->vpos == to_vpos)
9126 {
9127 reached = 2;
9128 break;
9129 }
9130
9131 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9132
9133 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9134 {
9135 reached = 3;
9136 break;
9137 }
9138 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9139 {
9140 /* We have reached TO_X but not in the line we want. */
9141 skip = move_it_in_display_line_to (it, to_charpos,
9142 -1, MOVE_TO_POS);
9143 if (skip == MOVE_POS_MATCH_OR_ZV)
9144 {
9145 reached = 4;
9146 break;
9147 }
9148 }
9149 }
9150 }
9151 else if (op & MOVE_TO_Y)
9152 {
9153 struct it it_backup;
9154
9155 if (it->line_wrap == WORD_WRAP)
9156 SAVE_IT (it_backup, *it, backup_data);
9157
9158 /* TO_Y specified means stop at TO_X in the line containing
9159 TO_Y---or at TO_CHARPOS if this is reached first. The
9160 problem is that we can't really tell whether the line
9161 contains TO_Y before we have completely scanned it, and
9162 this may skip past TO_X. What we do is to first scan to
9163 TO_X.
9164
9165 If TO_X is not specified, use a TO_X of zero. The reason
9166 is to make the outcome of this function more predictable.
9167 If we didn't use TO_X == 0, we would stop at the end of
9168 the line which is probably not what a caller would expect
9169 to happen. */
9170 skip = move_it_in_display_line_to
9171 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9172 (MOVE_TO_X | (op & MOVE_TO_POS)));
9173
9174 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9175 if (skip == MOVE_POS_MATCH_OR_ZV)
9176 reached = 5;
9177 else if (skip == MOVE_X_REACHED)
9178 {
9179 /* If TO_X was reached, we want to know whether TO_Y is
9180 in the line. We know this is the case if the already
9181 scanned glyphs make the line tall enough. Otherwise,
9182 we must check by scanning the rest of the line. */
9183 line_height = it->max_ascent + it->max_descent;
9184 if (to_y >= it->current_y
9185 && to_y < it->current_y + line_height)
9186 {
9187 reached = 6;
9188 break;
9189 }
9190 SAVE_IT (it_backup, *it, backup_data);
9191 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9192 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9193 op & MOVE_TO_POS);
9194 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9195 line_height = it->max_ascent + it->max_descent;
9196 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9197
9198 if (to_y >= it->current_y
9199 && to_y < it->current_y + line_height)
9200 {
9201 /* If TO_Y is in this line and TO_X was reached
9202 above, we scanned too far. We have to restore
9203 IT's settings to the ones before skipping. But
9204 keep the more accurate values of max_ascent and
9205 max_descent we've found while skipping the rest
9206 of the line, for the sake of callers, such as
9207 pos_visible_p, that need to know the line
9208 height. */
9209 int max_ascent = it->max_ascent;
9210 int max_descent = it->max_descent;
9211
9212 RESTORE_IT (it, &it_backup, backup_data);
9213 it->max_ascent = max_ascent;
9214 it->max_descent = max_descent;
9215 reached = 6;
9216 }
9217 else
9218 {
9219 skip = skip2;
9220 if (skip == MOVE_POS_MATCH_OR_ZV)
9221 reached = 7;
9222 }
9223 }
9224 else
9225 {
9226 /* Check whether TO_Y is in this line. */
9227 line_height = it->max_ascent + it->max_descent;
9228 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9229
9230 if (to_y >= it->current_y
9231 && to_y < it->current_y + line_height)
9232 {
9233 if (to_y > it->current_y)
9234 max_current_x = max (it->current_x, max_current_x);
9235
9236 /* When word-wrap is on, TO_X may lie past the end
9237 of a wrapped line. Then it->current is the
9238 character on the next line, so backtrack to the
9239 space before the wrap point. */
9240 if (skip == MOVE_LINE_CONTINUED
9241 && it->line_wrap == WORD_WRAP)
9242 {
9243 int prev_x = max (it->current_x - 1, 0);
9244 RESTORE_IT (it, &it_backup, backup_data);
9245 skip = move_it_in_display_line_to
9246 (it, -1, prev_x, MOVE_TO_X);
9247 }
9248
9249 reached = 6;
9250 }
9251 }
9252
9253 if (reached)
9254 {
9255 max_current_x = max (it->current_x, max_current_x);
9256 break;
9257 }
9258 }
9259 else if (BUFFERP (it->object)
9260 && (it->method == GET_FROM_BUFFER
9261 || it->method == GET_FROM_STRETCH)
9262 && IT_CHARPOS (*it) >= to_charpos
9263 /* Under bidi iteration, a call to set_iterator_to_next
9264 can scan far beyond to_charpos if the initial
9265 portion of the next line needs to be reordered. In
9266 that case, give move_it_in_display_line_to another
9267 chance below. */
9268 && !(it->bidi_p
9269 && it->bidi_it.scan_dir == -1))
9270 skip = MOVE_POS_MATCH_OR_ZV;
9271 else
9272 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9273
9274 switch (skip)
9275 {
9276 case MOVE_POS_MATCH_OR_ZV:
9277 max_current_x = max (it->current_x, max_current_x);
9278 reached = 8;
9279 goto out;
9280
9281 case MOVE_NEWLINE_OR_CR:
9282 max_current_x = max (it->current_x, max_current_x);
9283 set_iterator_to_next (it, 1);
9284 it->continuation_lines_width = 0;
9285 break;
9286
9287 case MOVE_LINE_TRUNCATED:
9288 max_current_x = it->last_visible_x;
9289 it->continuation_lines_width = 0;
9290 reseat_at_next_visible_line_start (it, 0);
9291 if ((op & MOVE_TO_POS) != 0
9292 && IT_CHARPOS (*it) > to_charpos)
9293 {
9294 reached = 9;
9295 goto out;
9296 }
9297 break;
9298
9299 case MOVE_LINE_CONTINUED:
9300 max_current_x = it->last_visible_x;
9301 /* For continued lines ending in a tab, some of the glyphs
9302 associated with the tab are displayed on the current
9303 line. Since it->current_x does not include these glyphs,
9304 we use it->last_visible_x instead. */
9305 if (it->c == '\t')
9306 {
9307 it->continuation_lines_width += it->last_visible_x;
9308 /* When moving by vpos, ensure that the iterator really
9309 advances to the next line (bug#847, bug#969). Fixme:
9310 do we need to do this in other circumstances? */
9311 if (it->current_x != it->last_visible_x
9312 && (op & MOVE_TO_VPOS)
9313 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9314 {
9315 line_start_x = it->current_x + it->pixel_width
9316 - it->last_visible_x;
9317 if (FRAME_WINDOW_P (it->f))
9318 {
9319 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9320 struct font *face_font = face->font;
9321
9322 /* When display_line produces a continued line
9323 that ends in a TAB, it skips a tab stop that
9324 is closer than the font's space character
9325 width (see x_produce_glyphs where it produces
9326 the stretch glyph which represents a TAB).
9327 We need to reproduce the same logic here. */
9328 eassert (face_font);
9329 if (face_font)
9330 {
9331 if (line_start_x < face_font->space_width)
9332 line_start_x
9333 += it->tab_width * face_font->space_width;
9334 }
9335 }
9336 set_iterator_to_next (it, 0);
9337 }
9338 }
9339 else
9340 it->continuation_lines_width += it->current_x;
9341 break;
9342
9343 default:
9344 emacs_abort ();
9345 }
9346
9347 /* Reset/increment for the next run. */
9348 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9349 it->current_x = line_start_x;
9350 line_start_x = 0;
9351 it->hpos = 0;
9352 it->current_y += it->max_ascent + it->max_descent;
9353 ++it->vpos;
9354 last_height = it->max_ascent + it->max_descent;
9355 it->max_ascent = it->max_descent = 0;
9356 }
9357
9358 out:
9359
9360 /* On text terminals, we may stop at the end of a line in the middle
9361 of a multi-character glyph. If the glyph itself is continued,
9362 i.e. it is actually displayed on the next line, don't treat this
9363 stopping point as valid; move to the next line instead (unless
9364 that brings us offscreen). */
9365 if (!FRAME_WINDOW_P (it->f)
9366 && op & MOVE_TO_POS
9367 && IT_CHARPOS (*it) == to_charpos
9368 && it->what == IT_CHARACTER
9369 && it->nglyphs > 1
9370 && it->line_wrap == WINDOW_WRAP
9371 && it->current_x == it->last_visible_x - 1
9372 && it->c != '\n'
9373 && it->c != '\t'
9374 && it->vpos < it->w->window_end_vpos)
9375 {
9376 it->continuation_lines_width += it->current_x;
9377 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9378 it->current_y += it->max_ascent + it->max_descent;
9379 ++it->vpos;
9380 last_height = it->max_ascent + it->max_descent;
9381 }
9382
9383 if (backup_data)
9384 bidi_unshelve_cache (backup_data, 1);
9385
9386 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9387
9388 return max_current_x;
9389 }
9390
9391
9392 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9393
9394 If DY > 0, move IT backward at least that many pixels. DY = 0
9395 means move IT backward to the preceding line start or BEGV. This
9396 function may move over more than DY pixels if IT->current_y - DY
9397 ends up in the middle of a line; in this case IT->current_y will be
9398 set to the top of the line moved to. */
9399
9400 void
9401 move_it_vertically_backward (struct it *it, int dy)
9402 {
9403 int nlines, h;
9404 struct it it2, it3;
9405 void *it2data = NULL, *it3data = NULL;
9406 ptrdiff_t start_pos;
9407 int nchars_per_row
9408 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9409 ptrdiff_t pos_limit;
9410
9411 move_further_back:
9412 eassert (dy >= 0);
9413
9414 start_pos = IT_CHARPOS (*it);
9415
9416 /* Estimate how many newlines we must move back. */
9417 nlines = max (1, dy / default_line_pixel_height (it->w));
9418 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9419 pos_limit = BEGV;
9420 else
9421 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9422
9423 /* Set the iterator's position that many lines back. But don't go
9424 back more than NLINES full screen lines -- this wins a day with
9425 buffers which have very long lines. */
9426 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9427 back_to_previous_visible_line_start (it);
9428
9429 /* Reseat the iterator here. When moving backward, we don't want
9430 reseat to skip forward over invisible text, set up the iterator
9431 to deliver from overlay strings at the new position etc. So,
9432 use reseat_1 here. */
9433 reseat_1 (it, it->current.pos, 1);
9434
9435 /* We are now surely at a line start. */
9436 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9437 reordering is in effect. */
9438 it->continuation_lines_width = 0;
9439
9440 /* Move forward and see what y-distance we moved. First move to the
9441 start of the next line so that we get its height. We need this
9442 height to be able to tell whether we reached the specified
9443 y-distance. */
9444 SAVE_IT (it2, *it, it2data);
9445 it2.max_ascent = it2.max_descent = 0;
9446 do
9447 {
9448 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9449 MOVE_TO_POS | MOVE_TO_VPOS);
9450 }
9451 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9452 /* If we are in a display string which starts at START_POS,
9453 and that display string includes a newline, and we are
9454 right after that newline (i.e. at the beginning of a
9455 display line), exit the loop, because otherwise we will
9456 infloop, since move_it_to will see that it is already at
9457 START_POS and will not move. */
9458 || (it2.method == GET_FROM_STRING
9459 && IT_CHARPOS (it2) == start_pos
9460 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9461 eassert (IT_CHARPOS (*it) >= BEGV);
9462 SAVE_IT (it3, it2, it3data);
9463
9464 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9465 eassert (IT_CHARPOS (*it) >= BEGV);
9466 /* H is the actual vertical distance from the position in *IT
9467 and the starting position. */
9468 h = it2.current_y - it->current_y;
9469 /* NLINES is the distance in number of lines. */
9470 nlines = it2.vpos - it->vpos;
9471
9472 /* Correct IT's y and vpos position
9473 so that they are relative to the starting point. */
9474 it->vpos -= nlines;
9475 it->current_y -= h;
9476
9477 if (dy == 0)
9478 {
9479 /* DY == 0 means move to the start of the screen line. The
9480 value of nlines is > 0 if continuation lines were involved,
9481 or if the original IT position was at start of a line. */
9482 RESTORE_IT (it, it, it2data);
9483 if (nlines > 0)
9484 move_it_by_lines (it, nlines);
9485 /* The above code moves us to some position NLINES down,
9486 usually to its first glyph (leftmost in an L2R line), but
9487 that's not necessarily the start of the line, under bidi
9488 reordering. We want to get to the character position
9489 that is immediately after the newline of the previous
9490 line. */
9491 if (it->bidi_p
9492 && !it->continuation_lines_width
9493 && !STRINGP (it->string)
9494 && IT_CHARPOS (*it) > BEGV
9495 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9496 {
9497 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9498
9499 DEC_BOTH (cp, bp);
9500 cp = find_newline_no_quit (cp, bp, -1, NULL);
9501 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9502 }
9503 bidi_unshelve_cache (it3data, 1);
9504 }
9505 else
9506 {
9507 /* The y-position we try to reach, relative to *IT.
9508 Note that H has been subtracted in front of the if-statement. */
9509 int target_y = it->current_y + h - dy;
9510 int y0 = it3.current_y;
9511 int y1;
9512 int line_height;
9513
9514 RESTORE_IT (&it3, &it3, it3data);
9515 y1 = line_bottom_y (&it3);
9516 line_height = y1 - y0;
9517 RESTORE_IT (it, it, it2data);
9518 /* If we did not reach target_y, try to move further backward if
9519 we can. If we moved too far backward, try to move forward. */
9520 if (target_y < it->current_y
9521 /* This is heuristic. In a window that's 3 lines high, with
9522 a line height of 13 pixels each, recentering with point
9523 on the bottom line will try to move -39/2 = 19 pixels
9524 backward. Try to avoid moving into the first line. */
9525 && (it->current_y - target_y
9526 > min (window_box_height (it->w), line_height * 2 / 3))
9527 && IT_CHARPOS (*it) > BEGV)
9528 {
9529 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9530 target_y - it->current_y));
9531 dy = it->current_y - target_y;
9532 goto move_further_back;
9533 }
9534 else if (target_y >= it->current_y + line_height
9535 && IT_CHARPOS (*it) < ZV)
9536 {
9537 /* Should move forward by at least one line, maybe more.
9538
9539 Note: Calling move_it_by_lines can be expensive on
9540 terminal frames, where compute_motion is used (via
9541 vmotion) to do the job, when there are very long lines
9542 and truncate-lines is nil. That's the reason for
9543 treating terminal frames specially here. */
9544
9545 if (!FRAME_WINDOW_P (it->f))
9546 move_it_vertically (it, target_y - (it->current_y + line_height));
9547 else
9548 {
9549 do
9550 {
9551 move_it_by_lines (it, 1);
9552 }
9553 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9554 }
9555 }
9556 }
9557 }
9558
9559
9560 /* Move IT by a specified amount of pixel lines DY. DY negative means
9561 move backwards. DY = 0 means move to start of screen line. At the
9562 end, IT will be on the start of a screen line. */
9563
9564 void
9565 move_it_vertically (struct it *it, int dy)
9566 {
9567 if (dy <= 0)
9568 move_it_vertically_backward (it, -dy);
9569 else
9570 {
9571 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9572 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9573 MOVE_TO_POS | MOVE_TO_Y);
9574 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9575
9576 /* If buffer ends in ZV without a newline, move to the start of
9577 the line to satisfy the post-condition. */
9578 if (IT_CHARPOS (*it) == ZV
9579 && ZV > BEGV
9580 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9581 move_it_by_lines (it, 0);
9582 }
9583 }
9584
9585
9586 /* Move iterator IT past the end of the text line it is in. */
9587
9588 void
9589 move_it_past_eol (struct it *it)
9590 {
9591 enum move_it_result rc;
9592
9593 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9594 if (rc == MOVE_NEWLINE_OR_CR)
9595 set_iterator_to_next (it, 0);
9596 }
9597
9598
9599 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9600 negative means move up. DVPOS == 0 means move to the start of the
9601 screen line.
9602
9603 Optimization idea: If we would know that IT->f doesn't use
9604 a face with proportional font, we could be faster for
9605 truncate-lines nil. */
9606
9607 void
9608 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9609 {
9610
9611 /* The commented-out optimization uses vmotion on terminals. This
9612 gives bad results, because elements like it->what, on which
9613 callers such as pos_visible_p rely, aren't updated. */
9614 /* struct position pos;
9615 if (!FRAME_WINDOW_P (it->f))
9616 {
9617 struct text_pos textpos;
9618
9619 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9620 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9621 reseat (it, textpos, 1);
9622 it->vpos += pos.vpos;
9623 it->current_y += pos.vpos;
9624 }
9625 else */
9626
9627 if (dvpos == 0)
9628 {
9629 /* DVPOS == 0 means move to the start of the screen line. */
9630 move_it_vertically_backward (it, 0);
9631 /* Let next call to line_bottom_y calculate real line height. */
9632 last_height = 0;
9633 }
9634 else if (dvpos > 0)
9635 {
9636 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9637 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9638 {
9639 /* Only move to the next buffer position if we ended up in a
9640 string from display property, not in an overlay string
9641 (before-string or after-string). That is because the
9642 latter don't conceal the underlying buffer position, so
9643 we can ask to move the iterator to the exact position we
9644 are interested in. Note that, even if we are already at
9645 IT_CHARPOS (*it), the call below is not a no-op, as it
9646 will detect that we are at the end of the string, pop the
9647 iterator, and compute it->current_x and it->hpos
9648 correctly. */
9649 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9650 -1, -1, -1, MOVE_TO_POS);
9651 }
9652 }
9653 else
9654 {
9655 struct it it2;
9656 void *it2data = NULL;
9657 ptrdiff_t start_charpos, i;
9658 int nchars_per_row
9659 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9660 bool hit_pos_limit = false;
9661 ptrdiff_t pos_limit;
9662
9663 /* Start at the beginning of the screen line containing IT's
9664 position. This may actually move vertically backwards,
9665 in case of overlays, so adjust dvpos accordingly. */
9666 dvpos += it->vpos;
9667 move_it_vertically_backward (it, 0);
9668 dvpos -= it->vpos;
9669
9670 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9671 screen lines, and reseat the iterator there. */
9672 start_charpos = IT_CHARPOS (*it);
9673 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9674 pos_limit = BEGV;
9675 else
9676 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9677
9678 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9679 back_to_previous_visible_line_start (it);
9680 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9681 hit_pos_limit = true;
9682 reseat (it, it->current.pos, 1);
9683
9684 /* Move further back if we end up in a string or an image. */
9685 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9686 {
9687 /* First try to move to start of display line. */
9688 dvpos += it->vpos;
9689 move_it_vertically_backward (it, 0);
9690 dvpos -= it->vpos;
9691 if (IT_POS_VALID_AFTER_MOVE_P (it))
9692 break;
9693 /* If start of line is still in string or image,
9694 move further back. */
9695 back_to_previous_visible_line_start (it);
9696 reseat (it, it->current.pos, 1);
9697 dvpos--;
9698 }
9699
9700 it->current_x = it->hpos = 0;
9701
9702 /* Above call may have moved too far if continuation lines
9703 are involved. Scan forward and see if it did. */
9704 SAVE_IT (it2, *it, it2data);
9705 it2.vpos = it2.current_y = 0;
9706 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9707 it->vpos -= it2.vpos;
9708 it->current_y -= it2.current_y;
9709 it->current_x = it->hpos = 0;
9710
9711 /* If we moved too far back, move IT some lines forward. */
9712 if (it2.vpos > -dvpos)
9713 {
9714 int delta = it2.vpos + dvpos;
9715
9716 RESTORE_IT (&it2, &it2, it2data);
9717 SAVE_IT (it2, *it, it2data);
9718 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9719 /* Move back again if we got too far ahead. */
9720 if (IT_CHARPOS (*it) >= start_charpos)
9721 RESTORE_IT (it, &it2, it2data);
9722 else
9723 bidi_unshelve_cache (it2data, 1);
9724 }
9725 else if (hit_pos_limit && pos_limit > BEGV
9726 && dvpos < 0 && it2.vpos < -dvpos)
9727 {
9728 /* If we hit the limit, but still didn't make it far enough
9729 back, that means there's a display string with a newline
9730 covering a large chunk of text, and that caused
9731 back_to_previous_visible_line_start try to go too far.
9732 Punish those who commit such atrocities by going back
9733 until we've reached DVPOS, after lifting the limit, which
9734 could make it slow for very long lines. "If it hurts,
9735 don't do that!" */
9736 dvpos += it2.vpos;
9737 RESTORE_IT (it, it, it2data);
9738 for (i = -dvpos; i > 0; --i)
9739 {
9740 back_to_previous_visible_line_start (it);
9741 it->vpos--;
9742 }
9743 }
9744 else
9745 RESTORE_IT (it, it, it2data);
9746 }
9747 }
9748
9749 /* Return true if IT points into the middle of a display vector. */
9750
9751 bool
9752 in_display_vector_p (struct it *it)
9753 {
9754 return (it->method == GET_FROM_DISPLAY_VECTOR
9755 && it->current.dpvec_index > 0
9756 && it->dpvec + it->current.dpvec_index != it->dpend);
9757 }
9758
9759 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9760 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9761 WINDOW must be a live window and defaults to the selected one. The
9762 return value is a cons of the maximum pixel-width of any text line and
9763 the maximum pixel-height of all text lines.
9764
9765 The optional argument FROM, if non-nil, specifies the first text
9766 position and defaults to the minimum accessible position of the buffer.
9767 If FROM is t, use the minimum accessible position that is not a newline
9768 character. TO, if non-nil, specifies the last text position and
9769 defaults to the maximum accessible position of the buffer. If TO is t,
9770 use the maximum accessible position that is not a newline character.
9771
9772 The optional argument X-LIMIT, if non-nil, specifies the maximum text
9773 width that can be returned. X-LIMIT nil or omitted, means to use the
9774 pixel-width of WINDOW's body; use this if you do not intend to change
9775 the width of WINDOW. Use the maximum width WINDOW may assume if you
9776 intend to change WINDOW's width. In any case, text whose x-coordinate
9777 is beyond X-LIMIT is ignored. Since calculating the width of long lines
9778 can take some time, it's always a good idea to make this argument as
9779 small as possible; in particular, if the buffer contains long lines that
9780 shall be truncated anyway.
9781
9782 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
9783 height that can be returned. Text lines whose y-coordinate is beyond
9784 Y-LIMIT are ignored. Since calculating the text height of a large
9785 buffer can take some time, it makes sense to specify this argument if
9786 the size of the buffer is unknown.
9787
9788 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
9789 include the height of the mode- or header-line of WINDOW in the return
9790 value. If it is either the symbol `mode-line' or `header-line', include
9791 only the height of that line, if present, in the return value. If t,
9792 include the height of both, if present, in the return value. */)
9793 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, Lisp_Object y_limit,
9794 Lisp_Object mode_and_header_line)
9795 {
9796 struct window *w = decode_live_window (window);
9797 Lisp_Object buf;
9798 struct buffer *b;
9799 struct it it;
9800 struct buffer *old_buffer = NULL;
9801 ptrdiff_t start, end, pos;
9802 struct text_pos startp;
9803 void *itdata = NULL;
9804 int c, max_y = -1, x = 0, y = 0;
9805
9806 buf = w->contents;
9807 CHECK_BUFFER (buf);
9808 b = XBUFFER (buf);
9809
9810 if (b != current_buffer)
9811 {
9812 old_buffer = current_buffer;
9813 set_buffer_internal (b);
9814 }
9815
9816 if (NILP (from))
9817 start = BEGV;
9818 else if (EQ (from, Qt))
9819 {
9820 start = pos = BEGV;
9821 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
9822 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9823 start = pos;
9824 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9825 start = pos;
9826 }
9827 else
9828 {
9829 CHECK_NUMBER_COERCE_MARKER (from);
9830 start = min (max (XINT (from), BEGV), ZV);
9831 }
9832
9833 if (NILP (to))
9834 end = ZV;
9835 else if (EQ (to, Qt))
9836 {
9837 end = pos = ZV;
9838 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
9839 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9840 end = pos;
9841 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9842 end = pos;
9843 }
9844 else
9845 {
9846 CHECK_NUMBER_COERCE_MARKER (to);
9847 end = max (start, min (XINT (to), ZV));
9848 }
9849
9850 if (!NILP (y_limit))
9851 {
9852 CHECK_NUMBER (y_limit);
9853 max_y = min (XINT (y_limit), INT_MAX);
9854 }
9855
9856 itdata = bidi_shelve_cache ();
9857 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
9858 start_display (&it, w, startp);
9859
9860 if (NILP (x_limit))
9861 x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
9862 else
9863 {
9864 CHECK_NUMBER (x_limit);
9865 it.last_visible_x = min (XINT (x_limit), INFINITY);
9866 /* Actually, we never want move_it_to stop at to_x. But to make
9867 sure that move_it_in_display_line_to always moves far enough,
9868 we set it to INT_MAX and specify MOVE_TO_X. */
9869 x = move_it_to (&it, end, INT_MAX, max_y, -1,
9870 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9871 }
9872
9873 y = it.current_y + it.max_ascent + it.max_descent;
9874
9875 if (!EQ (mode_and_header_line, Qheader_line)
9876 && !EQ (mode_and_header_line, Qt))
9877 /* Do not count the header-line which was counted automatically by
9878 start_display. */
9879 y = y - WINDOW_HEADER_LINE_HEIGHT (w);
9880
9881 if (EQ (mode_and_header_line, Qmode_line)
9882 || EQ (mode_and_header_line, Qt))
9883 /* Do count the mode-line which is not included automatically by
9884 start_display. */
9885 y = y + WINDOW_MODE_LINE_HEIGHT (w);
9886
9887 bidi_unshelve_cache (itdata, 0);
9888
9889 if (old_buffer)
9890 set_buffer_internal (old_buffer);
9891
9892 return Fcons (make_number (x), make_number (y));
9893 }
9894 \f
9895 /***********************************************************************
9896 Messages
9897 ***********************************************************************/
9898
9899
9900 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9901 to *Messages*. */
9902
9903 void
9904 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9905 {
9906 Lisp_Object args[3];
9907 Lisp_Object msg, fmt;
9908 char *buffer;
9909 ptrdiff_t len;
9910 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9911 USE_SAFE_ALLOCA;
9912
9913 fmt = msg = Qnil;
9914 GCPRO4 (fmt, msg, arg1, arg2);
9915
9916 args[0] = fmt = build_string (format);
9917 args[1] = arg1;
9918 args[2] = arg2;
9919 msg = Fformat (3, args);
9920
9921 len = SBYTES (msg) + 1;
9922 buffer = SAFE_ALLOCA (len);
9923 memcpy (buffer, SDATA (msg), len);
9924
9925 message_dolog (buffer, len - 1, 1, 0);
9926 SAFE_FREE ();
9927
9928 UNGCPRO;
9929 }
9930
9931
9932 /* Output a newline in the *Messages* buffer if "needs" one. */
9933
9934 void
9935 message_log_maybe_newline (void)
9936 {
9937 if (message_log_need_newline)
9938 message_dolog ("", 0, 1, 0);
9939 }
9940
9941
9942 /* Add a string M of length NBYTES to the message log, optionally
9943 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9944 true, means interpret the contents of M as multibyte. This
9945 function calls low-level routines in order to bypass text property
9946 hooks, etc. which might not be safe to run.
9947
9948 This may GC (insert may run before/after change hooks),
9949 so the buffer M must NOT point to a Lisp string. */
9950
9951 void
9952 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9953 {
9954 const unsigned char *msg = (const unsigned char *) m;
9955
9956 if (!NILP (Vmemory_full))
9957 return;
9958
9959 if (!NILP (Vmessage_log_max))
9960 {
9961 struct buffer *oldbuf;
9962 Lisp_Object oldpoint, oldbegv, oldzv;
9963 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9964 ptrdiff_t point_at_end = 0;
9965 ptrdiff_t zv_at_end = 0;
9966 Lisp_Object old_deactivate_mark;
9967 struct gcpro gcpro1;
9968
9969 old_deactivate_mark = Vdeactivate_mark;
9970 oldbuf = current_buffer;
9971
9972 /* Ensure the Messages buffer exists, and switch to it.
9973 If we created it, set the major-mode. */
9974 {
9975 int newbuffer = 0;
9976 if (NILP (Fget_buffer (Vmessages_buffer_name))) newbuffer = 1;
9977
9978 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9979
9980 if (newbuffer
9981 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
9982 call0 (intern ("messages-buffer-mode"));
9983 }
9984
9985 bset_undo_list (current_buffer, Qt);
9986 bset_cache_long_scans (current_buffer, Qnil);
9987
9988 oldpoint = message_dolog_marker1;
9989 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9990 oldbegv = message_dolog_marker2;
9991 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9992 oldzv = message_dolog_marker3;
9993 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9994 GCPRO1 (old_deactivate_mark);
9995
9996 if (PT == Z)
9997 point_at_end = 1;
9998 if (ZV == Z)
9999 zv_at_end = 1;
10000
10001 BEGV = BEG;
10002 BEGV_BYTE = BEG_BYTE;
10003 ZV = Z;
10004 ZV_BYTE = Z_BYTE;
10005 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10006
10007 /* Insert the string--maybe converting multibyte to single byte
10008 or vice versa, so that all the text fits the buffer. */
10009 if (multibyte
10010 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10011 {
10012 ptrdiff_t i;
10013 int c, char_bytes;
10014 char work[1];
10015
10016 /* Convert a multibyte string to single-byte
10017 for the *Message* buffer. */
10018 for (i = 0; i < nbytes; i += char_bytes)
10019 {
10020 c = string_char_and_length (msg + i, &char_bytes);
10021 work[0] = CHAR_TO_BYTE8 (c);
10022 insert_1_both (work, 1, 1, 1, 0, 0);
10023 }
10024 }
10025 else if (! multibyte
10026 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10027 {
10028 ptrdiff_t i;
10029 int c, char_bytes;
10030 unsigned char str[MAX_MULTIBYTE_LENGTH];
10031 /* Convert a single-byte string to multibyte
10032 for the *Message* buffer. */
10033 for (i = 0; i < nbytes; i++)
10034 {
10035 c = msg[i];
10036 MAKE_CHAR_MULTIBYTE (c);
10037 char_bytes = CHAR_STRING (c, str);
10038 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
10039 }
10040 }
10041 else if (nbytes)
10042 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
10043
10044 if (nlflag)
10045 {
10046 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10047 printmax_t dups;
10048
10049 insert_1_both ("\n", 1, 1, 1, 0, 0);
10050
10051 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
10052 this_bol = PT;
10053 this_bol_byte = PT_BYTE;
10054
10055 /* See if this line duplicates the previous one.
10056 If so, combine duplicates. */
10057 if (this_bol > BEG)
10058 {
10059 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
10060 prev_bol = PT;
10061 prev_bol_byte = PT_BYTE;
10062
10063 dups = message_log_check_duplicate (prev_bol_byte,
10064 this_bol_byte);
10065 if (dups)
10066 {
10067 del_range_both (prev_bol, prev_bol_byte,
10068 this_bol, this_bol_byte, 0);
10069 if (dups > 1)
10070 {
10071 char dupstr[sizeof " [ times]"
10072 + INT_STRLEN_BOUND (printmax_t)];
10073
10074 /* If you change this format, don't forget to also
10075 change message_log_check_duplicate. */
10076 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10077 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10078 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
10079 }
10080 }
10081 }
10082
10083 /* If we have more than the desired maximum number of lines
10084 in the *Messages* buffer now, delete the oldest ones.
10085 This is safe because we don't have undo in this buffer. */
10086
10087 if (NATNUMP (Vmessage_log_max))
10088 {
10089 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10090 -XFASTINT (Vmessage_log_max) - 1, 0);
10091 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
10092 }
10093 }
10094 BEGV = marker_position (oldbegv);
10095 BEGV_BYTE = marker_byte_position (oldbegv);
10096
10097 if (zv_at_end)
10098 {
10099 ZV = Z;
10100 ZV_BYTE = Z_BYTE;
10101 }
10102 else
10103 {
10104 ZV = marker_position (oldzv);
10105 ZV_BYTE = marker_byte_position (oldzv);
10106 }
10107
10108 if (point_at_end)
10109 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10110 else
10111 /* We can't do Fgoto_char (oldpoint) because it will run some
10112 Lisp code. */
10113 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10114 marker_byte_position (oldpoint));
10115
10116 UNGCPRO;
10117 unchain_marker (XMARKER (oldpoint));
10118 unchain_marker (XMARKER (oldbegv));
10119 unchain_marker (XMARKER (oldzv));
10120
10121 /* We called insert_1_both above with its 5th argument (PREPARE)
10122 zero, which prevents insert_1_both from calling
10123 prepare_to_modify_buffer, which in turns prevents us from
10124 incrementing windows_or_buffers_changed even if *Messages* is
10125 shown in some window. So we must manually set
10126 windows_or_buffers_changed here to make up for that. */
10127 windows_or_buffers_changed = old_windows_or_buffers_changed;
10128 bset_redisplay (current_buffer);
10129
10130 set_buffer_internal (oldbuf);
10131
10132 message_log_need_newline = !nlflag;
10133 Vdeactivate_mark = old_deactivate_mark;
10134 }
10135 }
10136
10137
10138 /* We are at the end of the buffer after just having inserted a newline.
10139 (Note: We depend on the fact we won't be crossing the gap.)
10140 Check to see if the most recent message looks a lot like the previous one.
10141 Return 0 if different, 1 if the new one should just replace it, or a
10142 value N > 1 if we should also append " [N times]". */
10143
10144 static intmax_t
10145 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10146 {
10147 ptrdiff_t i;
10148 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10149 int seen_dots = 0;
10150 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10151 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10152
10153 for (i = 0; i < len; i++)
10154 {
10155 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10156 seen_dots = 1;
10157 if (p1[i] != p2[i])
10158 return seen_dots;
10159 }
10160 p1 += len;
10161 if (*p1 == '\n')
10162 return 2;
10163 if (*p1++ == ' ' && *p1++ == '[')
10164 {
10165 char *pend;
10166 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10167 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10168 return n + 1;
10169 }
10170 return 0;
10171 }
10172 \f
10173
10174 /* Display an echo area message M with a specified length of NBYTES
10175 bytes. The string may include null characters. If M is not a
10176 string, clear out any existing message, and let the mini-buffer
10177 text show through.
10178
10179 This function cancels echoing. */
10180
10181 void
10182 message3 (Lisp_Object m)
10183 {
10184 struct gcpro gcpro1;
10185
10186 GCPRO1 (m);
10187 clear_message (true, true);
10188 cancel_echoing ();
10189
10190 /* First flush out any partial line written with print. */
10191 message_log_maybe_newline ();
10192 if (STRINGP (m))
10193 {
10194 ptrdiff_t nbytes = SBYTES (m);
10195 bool multibyte = STRING_MULTIBYTE (m);
10196 char *buffer;
10197 USE_SAFE_ALLOCA;
10198 SAFE_ALLOCA_STRING (buffer, m);
10199 message_dolog (buffer, nbytes, 1, multibyte);
10200 SAFE_FREE ();
10201 }
10202 message3_nolog (m);
10203
10204 UNGCPRO;
10205 }
10206
10207
10208 /* The non-logging version of message3.
10209 This does not cancel echoing, because it is used for echoing.
10210 Perhaps we need to make a separate function for echoing
10211 and make this cancel echoing. */
10212
10213 void
10214 message3_nolog (Lisp_Object m)
10215 {
10216 struct frame *sf = SELECTED_FRAME ();
10217
10218 if (FRAME_INITIAL_P (sf))
10219 {
10220 if (noninteractive_need_newline)
10221 putc ('\n', stderr);
10222 noninteractive_need_newline = 0;
10223 if (STRINGP (m))
10224 {
10225 Lisp_Object s = ENCODE_SYSTEM (m);
10226
10227 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10228 }
10229 if (cursor_in_echo_area == 0)
10230 fprintf (stderr, "\n");
10231 fflush (stderr);
10232 }
10233 /* Error messages get reported properly by cmd_error, so this must be just an
10234 informative message; if the frame hasn't really been initialized yet, just
10235 toss it. */
10236 else if (INTERACTIVE && sf->glyphs_initialized_p)
10237 {
10238 /* Get the frame containing the mini-buffer
10239 that the selected frame is using. */
10240 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10241 Lisp_Object frame = XWINDOW (mini_window)->frame;
10242 struct frame *f = XFRAME (frame);
10243
10244 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10245 Fmake_frame_visible (frame);
10246
10247 if (STRINGP (m) && SCHARS (m) > 0)
10248 {
10249 set_message (m);
10250 if (minibuffer_auto_raise)
10251 Fraise_frame (frame);
10252 /* Assume we are not echoing.
10253 (If we are, echo_now will override this.) */
10254 echo_message_buffer = Qnil;
10255 }
10256 else
10257 clear_message (true, true);
10258
10259 do_pending_window_change (0);
10260 echo_area_display (1);
10261 do_pending_window_change (0);
10262 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10263 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10264 }
10265 }
10266
10267
10268 /* Display a null-terminated echo area message M. If M is 0, clear
10269 out any existing message, and let the mini-buffer text show through.
10270
10271 The buffer M must continue to exist until after the echo area gets
10272 cleared or some other message gets displayed there. Do not pass
10273 text that is stored in a Lisp string. Do not pass text in a buffer
10274 that was alloca'd. */
10275
10276 void
10277 message1 (const char *m)
10278 {
10279 message3 (m ? build_unibyte_string (m) : Qnil);
10280 }
10281
10282
10283 /* The non-logging counterpart of message1. */
10284
10285 void
10286 message1_nolog (const char *m)
10287 {
10288 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10289 }
10290
10291 /* Display a message M which contains a single %s
10292 which gets replaced with STRING. */
10293
10294 void
10295 message_with_string (const char *m, Lisp_Object string, int log)
10296 {
10297 CHECK_STRING (string);
10298
10299 if (noninteractive)
10300 {
10301 if (m)
10302 {
10303 /* ENCODE_SYSTEM below can GC and/or relocate the
10304 Lisp data, so make sure we don't use it here. */
10305 eassert (relocatable_string_data_p (m) != 1);
10306
10307 if (noninteractive_need_newline)
10308 putc ('\n', stderr);
10309 noninteractive_need_newline = 0;
10310 fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string)));
10311 if (!cursor_in_echo_area)
10312 fprintf (stderr, "\n");
10313 fflush (stderr);
10314 }
10315 }
10316 else if (INTERACTIVE)
10317 {
10318 /* The frame whose minibuffer we're going to display the message on.
10319 It may be larger than the selected frame, so we need
10320 to use its buffer, not the selected frame's buffer. */
10321 Lisp_Object mini_window;
10322 struct frame *f, *sf = SELECTED_FRAME ();
10323
10324 /* Get the frame containing the minibuffer
10325 that the selected frame is using. */
10326 mini_window = FRAME_MINIBUF_WINDOW (sf);
10327 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10328
10329 /* Error messages get reported properly by cmd_error, so this must be
10330 just an informative message; if the frame hasn't really been
10331 initialized yet, just toss it. */
10332 if (f->glyphs_initialized_p)
10333 {
10334 Lisp_Object args[2], msg;
10335 struct gcpro gcpro1, gcpro2;
10336
10337 args[0] = build_string (m);
10338 args[1] = msg = string;
10339 GCPRO2 (args[0], msg);
10340 gcpro1.nvars = 2;
10341
10342 msg = Fformat (2, args);
10343
10344 if (log)
10345 message3 (msg);
10346 else
10347 message3_nolog (msg);
10348
10349 UNGCPRO;
10350
10351 /* Print should start at the beginning of the message
10352 buffer next time. */
10353 message_buf_print = 0;
10354 }
10355 }
10356 }
10357
10358
10359 /* Dump an informative message to the minibuf. If M is 0, clear out
10360 any existing message, and let the mini-buffer text show through. */
10361
10362 static void
10363 vmessage (const char *m, va_list ap)
10364 {
10365 if (noninteractive)
10366 {
10367 if (m)
10368 {
10369 if (noninteractive_need_newline)
10370 putc ('\n', stderr);
10371 noninteractive_need_newline = 0;
10372 vfprintf (stderr, m, ap);
10373 if (cursor_in_echo_area == 0)
10374 fprintf (stderr, "\n");
10375 fflush (stderr);
10376 }
10377 }
10378 else if (INTERACTIVE)
10379 {
10380 /* The frame whose mini-buffer we're going to display the message
10381 on. It may be larger than the selected frame, so we need to
10382 use its buffer, not the selected frame's buffer. */
10383 Lisp_Object mini_window;
10384 struct frame *f, *sf = SELECTED_FRAME ();
10385
10386 /* Get the frame containing the mini-buffer
10387 that the selected frame is using. */
10388 mini_window = FRAME_MINIBUF_WINDOW (sf);
10389 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10390
10391 /* Error messages get reported properly by cmd_error, so this must be
10392 just an informative message; if the frame hasn't really been
10393 initialized yet, just toss it. */
10394 if (f->glyphs_initialized_p)
10395 {
10396 if (m)
10397 {
10398 ptrdiff_t len;
10399 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10400 USE_SAFE_ALLOCA;
10401 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10402
10403 len = doprnt (message_buf, maxsize, m, 0, ap);
10404
10405 message3 (make_string (message_buf, len));
10406 SAFE_FREE ();
10407 }
10408 else
10409 message1 (0);
10410
10411 /* Print should start at the beginning of the message
10412 buffer next time. */
10413 message_buf_print = 0;
10414 }
10415 }
10416 }
10417
10418 void
10419 message (const char *m, ...)
10420 {
10421 va_list ap;
10422 va_start (ap, m);
10423 vmessage (m, ap);
10424 va_end (ap);
10425 }
10426
10427
10428 #if 0
10429 /* The non-logging version of message. */
10430
10431 void
10432 message_nolog (const char *m, ...)
10433 {
10434 Lisp_Object old_log_max;
10435 va_list ap;
10436 va_start (ap, m);
10437 old_log_max = Vmessage_log_max;
10438 Vmessage_log_max = Qnil;
10439 vmessage (m, ap);
10440 Vmessage_log_max = old_log_max;
10441 va_end (ap);
10442 }
10443 #endif
10444
10445
10446 /* Display the current message in the current mini-buffer. This is
10447 only called from error handlers in process.c, and is not time
10448 critical. */
10449
10450 void
10451 update_echo_area (void)
10452 {
10453 if (!NILP (echo_area_buffer[0]))
10454 {
10455 Lisp_Object string;
10456 string = Fcurrent_message ();
10457 message3 (string);
10458 }
10459 }
10460
10461
10462 /* Make sure echo area buffers in `echo_buffers' are live.
10463 If they aren't, make new ones. */
10464
10465 static void
10466 ensure_echo_area_buffers (void)
10467 {
10468 int i;
10469
10470 for (i = 0; i < 2; ++i)
10471 if (!BUFFERP (echo_buffer[i])
10472 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10473 {
10474 char name[30];
10475 Lisp_Object old_buffer;
10476 int j;
10477
10478 old_buffer = echo_buffer[i];
10479 echo_buffer[i] = Fget_buffer_create
10480 (make_formatted_string (name, " *Echo Area %d*", i));
10481 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10482 /* to force word wrap in echo area -
10483 it was decided to postpone this*/
10484 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10485
10486 for (j = 0; j < 2; ++j)
10487 if (EQ (old_buffer, echo_area_buffer[j]))
10488 echo_area_buffer[j] = echo_buffer[i];
10489 }
10490 }
10491
10492
10493 /* Call FN with args A1..A2 with either the current or last displayed
10494 echo_area_buffer as current buffer.
10495
10496 WHICH zero means use the current message buffer
10497 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10498 from echo_buffer[] and clear it.
10499
10500 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10501 suitable buffer from echo_buffer[] and clear it.
10502
10503 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10504 that the current message becomes the last displayed one, make
10505 choose a suitable buffer for echo_area_buffer[0], and clear it.
10506
10507 Value is what FN returns. */
10508
10509 static int
10510 with_echo_area_buffer (struct window *w, int which,
10511 int (*fn) (ptrdiff_t, Lisp_Object),
10512 ptrdiff_t a1, Lisp_Object a2)
10513 {
10514 Lisp_Object buffer;
10515 int this_one, the_other, clear_buffer_p, rc;
10516 ptrdiff_t count = SPECPDL_INDEX ();
10517
10518 /* If buffers aren't live, make new ones. */
10519 ensure_echo_area_buffers ();
10520
10521 clear_buffer_p = 0;
10522
10523 if (which == 0)
10524 this_one = 0, the_other = 1;
10525 else if (which > 0)
10526 this_one = 1, the_other = 0;
10527 else
10528 {
10529 this_one = 0, the_other = 1;
10530 clear_buffer_p = true;
10531
10532 /* We need a fresh one in case the current echo buffer equals
10533 the one containing the last displayed echo area message. */
10534 if (!NILP (echo_area_buffer[this_one])
10535 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10536 echo_area_buffer[this_one] = Qnil;
10537 }
10538
10539 /* Choose a suitable buffer from echo_buffer[] is we don't
10540 have one. */
10541 if (NILP (echo_area_buffer[this_one]))
10542 {
10543 echo_area_buffer[this_one]
10544 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10545 ? echo_buffer[the_other]
10546 : echo_buffer[this_one]);
10547 clear_buffer_p = true;
10548 }
10549
10550 buffer = echo_area_buffer[this_one];
10551
10552 /* Don't get confused by reusing the buffer used for echoing
10553 for a different purpose. */
10554 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10555 cancel_echoing ();
10556
10557 record_unwind_protect (unwind_with_echo_area_buffer,
10558 with_echo_area_buffer_unwind_data (w));
10559
10560 /* Make the echo area buffer current. Note that for display
10561 purposes, it is not necessary that the displayed window's buffer
10562 == current_buffer, except for text property lookup. So, let's
10563 only set that buffer temporarily here without doing a full
10564 Fset_window_buffer. We must also change w->pointm, though,
10565 because otherwise an assertions in unshow_buffer fails, and Emacs
10566 aborts. */
10567 set_buffer_internal_1 (XBUFFER (buffer));
10568 if (w)
10569 {
10570 wset_buffer (w, buffer);
10571 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10572 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10573 }
10574
10575 bset_undo_list (current_buffer, Qt);
10576 bset_read_only (current_buffer, Qnil);
10577 specbind (Qinhibit_read_only, Qt);
10578 specbind (Qinhibit_modification_hooks, Qt);
10579
10580 if (clear_buffer_p && Z > BEG)
10581 del_range (BEG, Z);
10582
10583 eassert (BEGV >= BEG);
10584 eassert (ZV <= Z && ZV >= BEGV);
10585
10586 rc = fn (a1, a2);
10587
10588 eassert (BEGV >= BEG);
10589 eassert (ZV <= Z && ZV >= BEGV);
10590
10591 unbind_to (count, Qnil);
10592 return rc;
10593 }
10594
10595
10596 /* Save state that should be preserved around the call to the function
10597 FN called in with_echo_area_buffer. */
10598
10599 static Lisp_Object
10600 with_echo_area_buffer_unwind_data (struct window *w)
10601 {
10602 int i = 0;
10603 Lisp_Object vector, tmp;
10604
10605 /* Reduce consing by keeping one vector in
10606 Vwith_echo_area_save_vector. */
10607 vector = Vwith_echo_area_save_vector;
10608 Vwith_echo_area_save_vector = Qnil;
10609
10610 if (NILP (vector))
10611 vector = Fmake_vector (make_number (11), Qnil);
10612
10613 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10614 ASET (vector, i, Vdeactivate_mark); ++i;
10615 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10616
10617 if (w)
10618 {
10619 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10620 ASET (vector, i, w->contents); ++i;
10621 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10622 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10623 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10624 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10625 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10626 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10627 }
10628 else
10629 {
10630 int end = i + 8;
10631 for (; i < end; ++i)
10632 ASET (vector, i, Qnil);
10633 }
10634
10635 eassert (i == ASIZE (vector));
10636 return vector;
10637 }
10638
10639
10640 /* Restore global state from VECTOR which was created by
10641 with_echo_area_buffer_unwind_data. */
10642
10643 static void
10644 unwind_with_echo_area_buffer (Lisp_Object vector)
10645 {
10646 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10647 Vdeactivate_mark = AREF (vector, 1);
10648 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10649
10650 if (WINDOWP (AREF (vector, 3)))
10651 {
10652 struct window *w;
10653 Lisp_Object buffer;
10654
10655 w = XWINDOW (AREF (vector, 3));
10656 buffer = AREF (vector, 4);
10657
10658 wset_buffer (w, buffer);
10659 set_marker_both (w->pointm, buffer,
10660 XFASTINT (AREF (vector, 5)),
10661 XFASTINT (AREF (vector, 6)));
10662 set_marker_both (w->old_pointm, buffer,
10663 XFASTINT (AREF (vector, 7)),
10664 XFASTINT (AREF (vector, 8)));
10665 set_marker_both (w->start, buffer,
10666 XFASTINT (AREF (vector, 9)),
10667 XFASTINT (AREF (vector, 10)));
10668 }
10669
10670 Vwith_echo_area_save_vector = vector;
10671 }
10672
10673
10674 /* Set up the echo area for use by print functions. MULTIBYTE_P
10675 non-zero means we will print multibyte. */
10676
10677 void
10678 setup_echo_area_for_printing (int multibyte_p)
10679 {
10680 /* If we can't find an echo area any more, exit. */
10681 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10682 Fkill_emacs (Qnil);
10683
10684 ensure_echo_area_buffers ();
10685
10686 if (!message_buf_print)
10687 {
10688 /* A message has been output since the last time we printed.
10689 Choose a fresh echo area buffer. */
10690 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10691 echo_area_buffer[0] = echo_buffer[1];
10692 else
10693 echo_area_buffer[0] = echo_buffer[0];
10694
10695 /* Switch to that buffer and clear it. */
10696 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10697 bset_truncate_lines (current_buffer, Qnil);
10698
10699 if (Z > BEG)
10700 {
10701 ptrdiff_t count = SPECPDL_INDEX ();
10702 specbind (Qinhibit_read_only, Qt);
10703 /* Note that undo recording is always disabled. */
10704 del_range (BEG, Z);
10705 unbind_to (count, Qnil);
10706 }
10707 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10708
10709 /* Set up the buffer for the multibyteness we need. */
10710 if (multibyte_p
10711 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10712 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10713
10714 /* Raise the frame containing the echo area. */
10715 if (minibuffer_auto_raise)
10716 {
10717 struct frame *sf = SELECTED_FRAME ();
10718 Lisp_Object mini_window;
10719 mini_window = FRAME_MINIBUF_WINDOW (sf);
10720 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10721 }
10722
10723 message_log_maybe_newline ();
10724 message_buf_print = 1;
10725 }
10726 else
10727 {
10728 if (NILP (echo_area_buffer[0]))
10729 {
10730 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10731 echo_area_buffer[0] = echo_buffer[1];
10732 else
10733 echo_area_buffer[0] = echo_buffer[0];
10734 }
10735
10736 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10737 {
10738 /* Someone switched buffers between print requests. */
10739 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10740 bset_truncate_lines (current_buffer, Qnil);
10741 }
10742 }
10743 }
10744
10745
10746 /* Display an echo area message in window W. Value is non-zero if W's
10747 height is changed. If display_last_displayed_message_p is
10748 non-zero, display the message that was last displayed, otherwise
10749 display the current message. */
10750
10751 static int
10752 display_echo_area (struct window *w)
10753 {
10754 int i, no_message_p, window_height_changed_p;
10755
10756 /* Temporarily disable garbage collections while displaying the echo
10757 area. This is done because a GC can print a message itself.
10758 That message would modify the echo area buffer's contents while a
10759 redisplay of the buffer is going on, and seriously confuse
10760 redisplay. */
10761 ptrdiff_t count = inhibit_garbage_collection ();
10762
10763 /* If there is no message, we must call display_echo_area_1
10764 nevertheless because it resizes the window. But we will have to
10765 reset the echo_area_buffer in question to nil at the end because
10766 with_echo_area_buffer will sets it to an empty buffer. */
10767 i = display_last_displayed_message_p ? 1 : 0;
10768 no_message_p = NILP (echo_area_buffer[i]);
10769
10770 window_height_changed_p
10771 = with_echo_area_buffer (w, display_last_displayed_message_p,
10772 display_echo_area_1,
10773 (intptr_t) w, Qnil);
10774
10775 if (no_message_p)
10776 echo_area_buffer[i] = Qnil;
10777
10778 unbind_to (count, Qnil);
10779 return window_height_changed_p;
10780 }
10781
10782
10783 /* Helper for display_echo_area. Display the current buffer which
10784 contains the current echo area message in window W, a mini-window,
10785 a pointer to which is passed in A1. A2..A4 are currently not used.
10786 Change the height of W so that all of the message is displayed.
10787 Value is non-zero if height of W was changed. */
10788
10789 static int
10790 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10791 {
10792 intptr_t i1 = a1;
10793 struct window *w = (struct window *) i1;
10794 Lisp_Object window;
10795 struct text_pos start;
10796 int window_height_changed_p = 0;
10797
10798 /* Do this before displaying, so that we have a large enough glyph
10799 matrix for the display. If we can't get enough space for the
10800 whole text, display the last N lines. That works by setting w->start. */
10801 window_height_changed_p = resize_mini_window (w, 0);
10802
10803 /* Use the starting position chosen by resize_mini_window. */
10804 SET_TEXT_POS_FROM_MARKER (start, w->start);
10805
10806 /* Display. */
10807 clear_glyph_matrix (w->desired_matrix);
10808 XSETWINDOW (window, w);
10809 try_window (window, start, 0);
10810
10811 return window_height_changed_p;
10812 }
10813
10814
10815 /* Resize the echo area window to exactly the size needed for the
10816 currently displayed message, if there is one. If a mini-buffer
10817 is active, don't shrink it. */
10818
10819 void
10820 resize_echo_area_exactly (void)
10821 {
10822 if (BUFFERP (echo_area_buffer[0])
10823 && WINDOWP (echo_area_window))
10824 {
10825 struct window *w = XWINDOW (echo_area_window);
10826 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
10827 int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10828 (intptr_t) w, resize_exactly);
10829 if (resized_p)
10830 {
10831 windows_or_buffers_changed = 42;
10832 update_mode_lines = 30;
10833 redisplay_internal ();
10834 }
10835 }
10836 }
10837
10838
10839 /* Callback function for with_echo_area_buffer, when used from
10840 resize_echo_area_exactly. A1 contains a pointer to the window to
10841 resize, EXACTLY non-nil means resize the mini-window exactly to the
10842 size of the text displayed. A3 and A4 are not used. Value is what
10843 resize_mini_window returns. */
10844
10845 static int
10846 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10847 {
10848 intptr_t i1 = a1;
10849 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10850 }
10851
10852
10853 /* Resize mini-window W to fit the size of its contents. EXACT_P
10854 means size the window exactly to the size needed. Otherwise, it's
10855 only enlarged until W's buffer is empty.
10856
10857 Set W->start to the right place to begin display. If the whole
10858 contents fit, start at the beginning. Otherwise, start so as
10859 to make the end of the contents appear. This is particularly
10860 important for y-or-n-p, but seems desirable generally.
10861
10862 Value is non-zero if the window height has been changed. */
10863
10864 int
10865 resize_mini_window (struct window *w, int exact_p)
10866 {
10867 struct frame *f = XFRAME (w->frame);
10868 int window_height_changed_p = 0;
10869
10870 eassert (MINI_WINDOW_P (w));
10871
10872 /* By default, start display at the beginning. */
10873 set_marker_both (w->start, w->contents,
10874 BUF_BEGV (XBUFFER (w->contents)),
10875 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10876
10877 /* Don't resize windows while redisplaying a window; it would
10878 confuse redisplay functions when the size of the window they are
10879 displaying changes from under them. Such a resizing can happen,
10880 for instance, when which-func prints a long message while
10881 we are running fontification-functions. We're running these
10882 functions with safe_call which binds inhibit-redisplay to t. */
10883 if (!NILP (Vinhibit_redisplay))
10884 return 0;
10885
10886 /* Nil means don't try to resize. */
10887 if (NILP (Vresize_mini_windows)
10888 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10889 return 0;
10890
10891 if (!FRAME_MINIBUF_ONLY_P (f))
10892 {
10893 struct it it;
10894 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
10895 + WINDOW_PIXEL_HEIGHT (w));
10896 int unit = FRAME_LINE_HEIGHT (f);
10897 int height, max_height;
10898 struct text_pos start;
10899 struct buffer *old_current_buffer = NULL;
10900
10901 if (current_buffer != XBUFFER (w->contents))
10902 {
10903 old_current_buffer = current_buffer;
10904 set_buffer_internal (XBUFFER (w->contents));
10905 }
10906
10907 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10908
10909 /* Compute the max. number of lines specified by the user. */
10910 if (FLOATP (Vmax_mini_window_height))
10911 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
10912 else if (INTEGERP (Vmax_mini_window_height))
10913 max_height = XINT (Vmax_mini_window_height) * unit;
10914 else
10915 max_height = total_height / 4;
10916
10917 /* Correct that max. height if it's bogus. */
10918 max_height = clip_to_bounds (unit, max_height, total_height);
10919
10920 /* Find out the height of the text in the window. */
10921 if (it.line_wrap == TRUNCATE)
10922 height = unit;
10923 else
10924 {
10925 last_height = 0;
10926 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10927 if (it.max_ascent == 0 && it.max_descent == 0)
10928 height = it.current_y + last_height;
10929 else
10930 height = it.current_y + it.max_ascent + it.max_descent;
10931 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10932 }
10933
10934 /* Compute a suitable window start. */
10935 if (height > max_height)
10936 {
10937 height = (max_height / unit) * unit;
10938 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10939 move_it_vertically_backward (&it, height - unit);
10940 start = it.current.pos;
10941 }
10942 else
10943 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10944 SET_MARKER_FROM_TEXT_POS (w->start, start);
10945
10946 if (EQ (Vresize_mini_windows, Qgrow_only))
10947 {
10948 /* Let it grow only, until we display an empty message, in which
10949 case the window shrinks again. */
10950 if (height > WINDOW_PIXEL_HEIGHT (w))
10951 {
10952 int old_height = WINDOW_PIXEL_HEIGHT (w);
10953
10954 FRAME_WINDOWS_FROZEN (f) = 1;
10955 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10956 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10957 }
10958 else if (height < WINDOW_PIXEL_HEIGHT (w)
10959 && (exact_p || BEGV == ZV))
10960 {
10961 int old_height = WINDOW_PIXEL_HEIGHT (w);
10962
10963 FRAME_WINDOWS_FROZEN (f) = 0;
10964 shrink_mini_window (w, 1);
10965 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10966 }
10967 }
10968 else
10969 {
10970 /* Always resize to exact size needed. */
10971 if (height > WINDOW_PIXEL_HEIGHT (w))
10972 {
10973 int old_height = WINDOW_PIXEL_HEIGHT (w);
10974
10975 FRAME_WINDOWS_FROZEN (f) = 1;
10976 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10977 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10978 }
10979 else if (height < WINDOW_PIXEL_HEIGHT (w))
10980 {
10981 int old_height = WINDOW_PIXEL_HEIGHT (w);
10982
10983 FRAME_WINDOWS_FROZEN (f) = 0;
10984 shrink_mini_window (w, 1);
10985
10986 if (height)
10987 {
10988 FRAME_WINDOWS_FROZEN (f) = 1;
10989 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10990 }
10991
10992 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10993 }
10994 }
10995
10996 if (old_current_buffer)
10997 set_buffer_internal (old_current_buffer);
10998 }
10999
11000 return window_height_changed_p;
11001 }
11002
11003
11004 /* Value is the current message, a string, or nil if there is no
11005 current message. */
11006
11007 Lisp_Object
11008 current_message (void)
11009 {
11010 Lisp_Object msg;
11011
11012 if (!BUFFERP (echo_area_buffer[0]))
11013 msg = Qnil;
11014 else
11015 {
11016 with_echo_area_buffer (0, 0, current_message_1,
11017 (intptr_t) &msg, Qnil);
11018 if (NILP (msg))
11019 echo_area_buffer[0] = Qnil;
11020 }
11021
11022 return msg;
11023 }
11024
11025
11026 static int
11027 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
11028 {
11029 intptr_t i1 = a1;
11030 Lisp_Object *msg = (Lisp_Object *) i1;
11031
11032 if (Z > BEG)
11033 *msg = make_buffer_string (BEG, Z, 1);
11034 else
11035 *msg = Qnil;
11036 return 0;
11037 }
11038
11039
11040 /* Push the current message on Vmessage_stack for later restoration
11041 by restore_message. Value is non-zero if the current message isn't
11042 empty. This is a relatively infrequent operation, so it's not
11043 worth optimizing. */
11044
11045 bool
11046 push_message (void)
11047 {
11048 Lisp_Object msg = current_message ();
11049 Vmessage_stack = Fcons (msg, Vmessage_stack);
11050 return STRINGP (msg);
11051 }
11052
11053
11054 /* Restore message display from the top of Vmessage_stack. */
11055
11056 void
11057 restore_message (void)
11058 {
11059 eassert (CONSP (Vmessage_stack));
11060 message3_nolog (XCAR (Vmessage_stack));
11061 }
11062
11063
11064 /* Handler for unwind-protect calling pop_message. */
11065
11066 void
11067 pop_message_unwind (void)
11068 {
11069 /* Pop the top-most entry off Vmessage_stack. */
11070 eassert (CONSP (Vmessage_stack));
11071 Vmessage_stack = XCDR (Vmessage_stack);
11072 }
11073
11074
11075 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11076 exits. If the stack is not empty, we have a missing pop_message
11077 somewhere. */
11078
11079 void
11080 check_message_stack (void)
11081 {
11082 if (!NILP (Vmessage_stack))
11083 emacs_abort ();
11084 }
11085
11086
11087 /* Truncate to NCHARS what will be displayed in the echo area the next
11088 time we display it---but don't redisplay it now. */
11089
11090 void
11091 truncate_echo_area (ptrdiff_t nchars)
11092 {
11093 if (nchars == 0)
11094 echo_area_buffer[0] = Qnil;
11095 else if (!noninteractive
11096 && INTERACTIVE
11097 && !NILP (echo_area_buffer[0]))
11098 {
11099 struct frame *sf = SELECTED_FRAME ();
11100 /* Error messages get reported properly by cmd_error, so this must be
11101 just an informative message; if the frame hasn't really been
11102 initialized yet, just toss it. */
11103 if (sf->glyphs_initialized_p)
11104 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11105 }
11106 }
11107
11108
11109 /* Helper function for truncate_echo_area. Truncate the current
11110 message to at most NCHARS characters. */
11111
11112 static int
11113 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11114 {
11115 if (BEG + nchars < Z)
11116 del_range (BEG + nchars, Z);
11117 if (Z == BEG)
11118 echo_area_buffer[0] = Qnil;
11119 return 0;
11120 }
11121
11122 /* Set the current message to STRING. */
11123
11124 static void
11125 set_message (Lisp_Object string)
11126 {
11127 eassert (STRINGP (string));
11128
11129 message_enable_multibyte = STRING_MULTIBYTE (string);
11130
11131 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11132 message_buf_print = 0;
11133 help_echo_showing_p = 0;
11134
11135 if (STRINGP (Vdebug_on_message)
11136 && STRINGP (string)
11137 && fast_string_match (Vdebug_on_message, string) >= 0)
11138 call_debugger (list2 (Qerror, string));
11139 }
11140
11141
11142 /* Helper function for set_message. First argument is ignored and second
11143 argument has the same meaning as for set_message.
11144 This function is called with the echo area buffer being current. */
11145
11146 static int
11147 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11148 {
11149 eassert (STRINGP (string));
11150
11151 /* Change multibyteness of the echo buffer appropriately. */
11152 if (message_enable_multibyte
11153 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11154 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
11155
11156 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11157 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11158 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11159
11160 /* Insert new message at BEG. */
11161 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11162
11163 /* This function takes care of single/multibyte conversion.
11164 We just have to ensure that the echo area buffer has the right
11165 setting of enable_multibyte_characters. */
11166 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
11167
11168 return 0;
11169 }
11170
11171
11172 /* Clear messages. CURRENT_P non-zero means clear the current
11173 message. LAST_DISPLAYED_P non-zero means clear the message
11174 last displayed. */
11175
11176 void
11177 clear_message (bool current_p, bool last_displayed_p)
11178 {
11179 if (current_p)
11180 {
11181 echo_area_buffer[0] = Qnil;
11182 message_cleared_p = true;
11183 }
11184
11185 if (last_displayed_p)
11186 echo_area_buffer[1] = Qnil;
11187
11188 message_buf_print = 0;
11189 }
11190
11191 /* Clear garbaged frames.
11192
11193 This function is used where the old redisplay called
11194 redraw_garbaged_frames which in turn called redraw_frame which in
11195 turn called clear_frame. The call to clear_frame was a source of
11196 flickering. I believe a clear_frame is not necessary. It should
11197 suffice in the new redisplay to invalidate all current matrices,
11198 and ensure a complete redisplay of all windows. */
11199
11200 static void
11201 clear_garbaged_frames (void)
11202 {
11203 if (frame_garbaged)
11204 {
11205 Lisp_Object tail, frame;
11206
11207 FOR_EACH_FRAME (tail, frame)
11208 {
11209 struct frame *f = XFRAME (frame);
11210
11211 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11212 {
11213 if (f->resized_p)
11214 redraw_frame (f);
11215 else
11216 clear_current_matrices (f);
11217 fset_redisplay (f);
11218 f->garbaged = false;
11219 f->resized_p = false;
11220 }
11221 }
11222
11223 frame_garbaged = false;
11224 }
11225 }
11226
11227
11228 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
11229 is non-zero update selected_frame. Value is non-zero if the
11230 mini-windows height has been changed. */
11231
11232 static int
11233 echo_area_display (int update_frame_p)
11234 {
11235 Lisp_Object mini_window;
11236 struct window *w;
11237 struct frame *f;
11238 int window_height_changed_p = 0;
11239 struct frame *sf = SELECTED_FRAME ();
11240
11241 mini_window = FRAME_MINIBUF_WINDOW (sf);
11242 w = XWINDOW (mini_window);
11243 f = XFRAME (WINDOW_FRAME (w));
11244
11245 /* Don't display if frame is invisible or not yet initialized. */
11246 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11247 return 0;
11248
11249 #ifdef HAVE_WINDOW_SYSTEM
11250 /* When Emacs starts, selected_frame may be the initial terminal
11251 frame. If we let this through, a message would be displayed on
11252 the terminal. */
11253 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11254 return 0;
11255 #endif /* HAVE_WINDOW_SYSTEM */
11256
11257 /* Redraw garbaged frames. */
11258 clear_garbaged_frames ();
11259
11260 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11261 {
11262 echo_area_window = mini_window;
11263 window_height_changed_p = display_echo_area (w);
11264 w->must_be_updated_p = true;
11265
11266 /* Update the display, unless called from redisplay_internal.
11267 Also don't update the screen during redisplay itself. The
11268 update will happen at the end of redisplay, and an update
11269 here could cause confusion. */
11270 if (update_frame_p && !redisplaying_p)
11271 {
11272 int n = 0;
11273
11274 /* If the display update has been interrupted by pending
11275 input, update mode lines in the frame. Due to the
11276 pending input, it might have been that redisplay hasn't
11277 been called, so that mode lines above the echo area are
11278 garbaged. This looks odd, so we prevent it here. */
11279 if (!display_completed)
11280 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11281
11282 if (window_height_changed_p
11283 /* Don't do this if Emacs is shutting down. Redisplay
11284 needs to run hooks. */
11285 && !NILP (Vrun_hooks))
11286 {
11287 /* Must update other windows. Likewise as in other
11288 cases, don't let this update be interrupted by
11289 pending input. */
11290 ptrdiff_t count = SPECPDL_INDEX ();
11291 specbind (Qredisplay_dont_pause, Qt);
11292 windows_or_buffers_changed = 44;
11293 redisplay_internal ();
11294 unbind_to (count, Qnil);
11295 }
11296 else if (FRAME_WINDOW_P (f) && n == 0)
11297 {
11298 /* Window configuration is the same as before.
11299 Can do with a display update of the echo area,
11300 unless we displayed some mode lines. */
11301 update_single_window (w, 1);
11302 flush_frame (f);
11303 }
11304 else
11305 update_frame (f, 1, 1);
11306
11307 /* If cursor is in the echo area, make sure that the next
11308 redisplay displays the minibuffer, so that the cursor will
11309 be replaced with what the minibuffer wants. */
11310 if (cursor_in_echo_area)
11311 wset_redisplay (XWINDOW (mini_window));
11312 }
11313 }
11314 else if (!EQ (mini_window, selected_window))
11315 wset_redisplay (XWINDOW (mini_window));
11316
11317 /* Last displayed message is now the current message. */
11318 echo_area_buffer[1] = echo_area_buffer[0];
11319 /* Inform read_char that we're not echoing. */
11320 echo_message_buffer = Qnil;
11321
11322 /* Prevent redisplay optimization in redisplay_internal by resetting
11323 this_line_start_pos. This is done because the mini-buffer now
11324 displays the message instead of its buffer text. */
11325 if (EQ (mini_window, selected_window))
11326 CHARPOS (this_line_start_pos) = 0;
11327
11328 return window_height_changed_p;
11329 }
11330
11331 /* Nonzero if W's buffer was changed but not saved. */
11332
11333 static int
11334 window_buffer_changed (struct window *w)
11335 {
11336 struct buffer *b = XBUFFER (w->contents);
11337
11338 eassert (BUFFER_LIVE_P (b));
11339
11340 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
11341 }
11342
11343 /* Nonzero if W has %c in its mode line and mode line should be updated. */
11344
11345 static int
11346 mode_line_update_needed (struct window *w)
11347 {
11348 return (w->column_number_displayed != -1
11349 && !(PT == w->last_point && !window_outdated (w))
11350 && (w->column_number_displayed != current_column ()));
11351 }
11352
11353 /* Nonzero if window start of W is frozen and may not be changed during
11354 redisplay. */
11355
11356 static bool
11357 window_frozen_p (struct window *w)
11358 {
11359 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11360 {
11361 Lisp_Object window;
11362
11363 XSETWINDOW (window, w);
11364 if (MINI_WINDOW_P (w))
11365 return 0;
11366 else if (EQ (window, selected_window))
11367 return 0;
11368 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11369 && EQ (window, Vminibuf_scroll_window))
11370 /* This special window can't be frozen too. */
11371 return 0;
11372 else
11373 return 1;
11374 }
11375 return 0;
11376 }
11377
11378 /***********************************************************************
11379 Mode Lines and Frame Titles
11380 ***********************************************************************/
11381
11382 /* A buffer for constructing non-propertized mode-line strings and
11383 frame titles in it; allocated from the heap in init_xdisp and
11384 resized as needed in store_mode_line_noprop_char. */
11385
11386 static char *mode_line_noprop_buf;
11387
11388 /* The buffer's end, and a current output position in it. */
11389
11390 static char *mode_line_noprop_buf_end;
11391 static char *mode_line_noprop_ptr;
11392
11393 #define MODE_LINE_NOPROP_LEN(start) \
11394 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11395
11396 static enum {
11397 MODE_LINE_DISPLAY = 0,
11398 MODE_LINE_TITLE,
11399 MODE_LINE_NOPROP,
11400 MODE_LINE_STRING
11401 } mode_line_target;
11402
11403 /* Alist that caches the results of :propertize.
11404 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11405 static Lisp_Object mode_line_proptrans_alist;
11406
11407 /* List of strings making up the mode-line. */
11408 static Lisp_Object mode_line_string_list;
11409
11410 /* Base face property when building propertized mode line string. */
11411 static Lisp_Object mode_line_string_face;
11412 static Lisp_Object mode_line_string_face_prop;
11413
11414
11415 /* Unwind data for mode line strings */
11416
11417 static Lisp_Object Vmode_line_unwind_vector;
11418
11419 static Lisp_Object
11420 format_mode_line_unwind_data (struct frame *target_frame,
11421 struct buffer *obuf,
11422 Lisp_Object owin,
11423 int save_proptrans)
11424 {
11425 Lisp_Object vector, tmp;
11426
11427 /* Reduce consing by keeping one vector in
11428 Vwith_echo_area_save_vector. */
11429 vector = Vmode_line_unwind_vector;
11430 Vmode_line_unwind_vector = Qnil;
11431
11432 if (NILP (vector))
11433 vector = Fmake_vector (make_number (10), Qnil);
11434
11435 ASET (vector, 0, make_number (mode_line_target));
11436 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11437 ASET (vector, 2, mode_line_string_list);
11438 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11439 ASET (vector, 4, mode_line_string_face);
11440 ASET (vector, 5, mode_line_string_face_prop);
11441
11442 if (obuf)
11443 XSETBUFFER (tmp, obuf);
11444 else
11445 tmp = Qnil;
11446 ASET (vector, 6, tmp);
11447 ASET (vector, 7, owin);
11448 if (target_frame)
11449 {
11450 /* Similarly to `with-selected-window', if the operation selects
11451 a window on another frame, we must restore that frame's
11452 selected window, and (for a tty) the top-frame. */
11453 ASET (vector, 8, target_frame->selected_window);
11454 if (FRAME_TERMCAP_P (target_frame))
11455 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11456 }
11457
11458 return vector;
11459 }
11460
11461 static void
11462 unwind_format_mode_line (Lisp_Object vector)
11463 {
11464 Lisp_Object old_window = AREF (vector, 7);
11465 Lisp_Object target_frame_window = AREF (vector, 8);
11466 Lisp_Object old_top_frame = AREF (vector, 9);
11467
11468 mode_line_target = XINT (AREF (vector, 0));
11469 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11470 mode_line_string_list = AREF (vector, 2);
11471 if (! EQ (AREF (vector, 3), Qt))
11472 mode_line_proptrans_alist = AREF (vector, 3);
11473 mode_line_string_face = AREF (vector, 4);
11474 mode_line_string_face_prop = AREF (vector, 5);
11475
11476 /* Select window before buffer, since it may change the buffer. */
11477 if (!NILP (old_window))
11478 {
11479 /* If the operation that we are unwinding had selected a window
11480 on a different frame, reset its frame-selected-window. For a
11481 text terminal, reset its top-frame if necessary. */
11482 if (!NILP (target_frame_window))
11483 {
11484 Lisp_Object frame
11485 = WINDOW_FRAME (XWINDOW (target_frame_window));
11486
11487 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11488 Fselect_window (target_frame_window, Qt);
11489
11490 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11491 Fselect_frame (old_top_frame, Qt);
11492 }
11493
11494 Fselect_window (old_window, Qt);
11495 }
11496
11497 if (!NILP (AREF (vector, 6)))
11498 {
11499 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11500 ASET (vector, 6, Qnil);
11501 }
11502
11503 Vmode_line_unwind_vector = vector;
11504 }
11505
11506
11507 /* Store a single character C for the frame title in mode_line_noprop_buf.
11508 Re-allocate mode_line_noprop_buf if necessary. */
11509
11510 static void
11511 store_mode_line_noprop_char (char c)
11512 {
11513 /* If output position has reached the end of the allocated buffer,
11514 increase the buffer's size. */
11515 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11516 {
11517 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11518 ptrdiff_t size = len;
11519 mode_line_noprop_buf =
11520 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11521 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11522 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11523 }
11524
11525 *mode_line_noprop_ptr++ = c;
11526 }
11527
11528
11529 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11530 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11531 characters that yield more columns than PRECISION; PRECISION <= 0
11532 means copy the whole string. Pad with spaces until FIELD_WIDTH
11533 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11534 pad. Called from display_mode_element when it is used to build a
11535 frame title. */
11536
11537 static int
11538 store_mode_line_noprop (const char *string, int field_width, int precision)
11539 {
11540 const unsigned char *str = (const unsigned char *) string;
11541 int n = 0;
11542 ptrdiff_t dummy, nbytes;
11543
11544 /* Copy at most PRECISION chars from STR. */
11545 nbytes = strlen (string);
11546 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11547 while (nbytes--)
11548 store_mode_line_noprop_char (*str++);
11549
11550 /* Fill up with spaces until FIELD_WIDTH reached. */
11551 while (field_width > 0
11552 && n < field_width)
11553 {
11554 store_mode_line_noprop_char (' ');
11555 ++n;
11556 }
11557
11558 return n;
11559 }
11560
11561 /***********************************************************************
11562 Frame Titles
11563 ***********************************************************************/
11564
11565 #ifdef HAVE_WINDOW_SYSTEM
11566
11567 /* Set the title of FRAME, if it has changed. The title format is
11568 Vicon_title_format if FRAME is iconified, otherwise it is
11569 frame_title_format. */
11570
11571 static void
11572 x_consider_frame_title (Lisp_Object frame)
11573 {
11574 struct frame *f = XFRAME (frame);
11575
11576 if (FRAME_WINDOW_P (f)
11577 || FRAME_MINIBUF_ONLY_P (f)
11578 || f->explicit_name)
11579 {
11580 /* Do we have more than one visible frame on this X display? */
11581 Lisp_Object tail, other_frame, fmt;
11582 ptrdiff_t title_start;
11583 char *title;
11584 ptrdiff_t len;
11585 struct it it;
11586 ptrdiff_t count = SPECPDL_INDEX ();
11587
11588 FOR_EACH_FRAME (tail, other_frame)
11589 {
11590 struct frame *tf = XFRAME (other_frame);
11591
11592 if (tf != f
11593 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11594 && !FRAME_MINIBUF_ONLY_P (tf)
11595 && !EQ (other_frame, tip_frame)
11596 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11597 break;
11598 }
11599
11600 /* Set global variable indicating that multiple frames exist. */
11601 multiple_frames = CONSP (tail);
11602
11603 /* Switch to the buffer of selected window of the frame. Set up
11604 mode_line_target so that display_mode_element will output into
11605 mode_line_noprop_buf; then display the title. */
11606 record_unwind_protect (unwind_format_mode_line,
11607 format_mode_line_unwind_data
11608 (f, current_buffer, selected_window, 0));
11609
11610 Fselect_window (f->selected_window, Qt);
11611 set_buffer_internal_1
11612 (XBUFFER (XWINDOW (f->selected_window)->contents));
11613 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11614
11615 mode_line_target = MODE_LINE_TITLE;
11616 title_start = MODE_LINE_NOPROP_LEN (0);
11617 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11618 NULL, DEFAULT_FACE_ID);
11619 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11620 len = MODE_LINE_NOPROP_LEN (title_start);
11621 title = mode_line_noprop_buf + title_start;
11622 unbind_to (count, Qnil);
11623
11624 /* Set the title only if it's changed. This avoids consing in
11625 the common case where it hasn't. (If it turns out that we've
11626 already wasted too much time by walking through the list with
11627 display_mode_element, then we might need to optimize at a
11628 higher level than this.) */
11629 if (! STRINGP (f->name)
11630 || SBYTES (f->name) != len
11631 || memcmp (title, SDATA (f->name), len) != 0)
11632 x_implicitly_set_name (f, make_string (title, len), Qnil);
11633 }
11634 }
11635
11636 #endif /* not HAVE_WINDOW_SYSTEM */
11637
11638 \f
11639 /***********************************************************************
11640 Menu Bars
11641 ***********************************************************************/
11642
11643 /* Non-zero if we will not redisplay all visible windows. */
11644 #define REDISPLAY_SOME_P() \
11645 ((windows_or_buffers_changed == 0 \
11646 || windows_or_buffers_changed == REDISPLAY_SOME) \
11647 && (update_mode_lines == 0 \
11648 || update_mode_lines == REDISPLAY_SOME))
11649
11650 /* Prepare for redisplay by updating menu-bar item lists when
11651 appropriate. This can call eval. */
11652
11653 static void
11654 prepare_menu_bars (void)
11655 {
11656 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11657 bool some_windows = REDISPLAY_SOME_P ();
11658 struct gcpro gcpro1, gcpro2;
11659 Lisp_Object tooltip_frame;
11660
11661 #ifdef HAVE_WINDOW_SYSTEM
11662 tooltip_frame = tip_frame;
11663 #else
11664 tooltip_frame = Qnil;
11665 #endif
11666
11667 if (FUNCTIONP (Vpre_redisplay_function))
11668 {
11669 Lisp_Object windows = all_windows ? Qt : Qnil;
11670 if (all_windows && some_windows)
11671 {
11672 Lisp_Object ws = window_list ();
11673 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
11674 {
11675 Lisp_Object this = XCAR (ws);
11676 struct window *w = XWINDOW (this);
11677 if (w->redisplay
11678 || XFRAME (w->frame)->redisplay
11679 || XBUFFER (w->contents)->text->redisplay)
11680 {
11681 windows = Fcons (this, windows);
11682 }
11683 }
11684 }
11685 safe__call1 (true, Vpre_redisplay_function, windows);
11686 }
11687
11688 /* Update all frame titles based on their buffer names, etc. We do
11689 this before the menu bars so that the buffer-menu will show the
11690 up-to-date frame titles. */
11691 #ifdef HAVE_WINDOW_SYSTEM
11692 if (all_windows)
11693 {
11694 Lisp_Object tail, frame;
11695
11696 FOR_EACH_FRAME (tail, frame)
11697 {
11698 struct frame *f = XFRAME (frame);
11699 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11700 if (some_windows
11701 && !f->redisplay
11702 && !w->redisplay
11703 && !XBUFFER (w->contents)->text->redisplay)
11704 continue;
11705
11706 if (!EQ (frame, tooltip_frame)
11707 && (FRAME_ICONIFIED_P (f)
11708 || FRAME_VISIBLE_P (f) == 1
11709 /* Exclude TTY frames that are obscured because they
11710 are not the top frame on their console. This is
11711 because x_consider_frame_title actually switches
11712 to the frame, which for TTY frames means it is
11713 marked as garbaged, and will be completely
11714 redrawn on the next redisplay cycle. This causes
11715 TTY frames to be completely redrawn, when there
11716 are more than one of them, even though nothing
11717 should be changed on display. */
11718 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11719 x_consider_frame_title (frame);
11720 }
11721 }
11722 #endif /* HAVE_WINDOW_SYSTEM */
11723
11724 /* Update the menu bar item lists, if appropriate. This has to be
11725 done before any actual redisplay or generation of display lines. */
11726
11727 if (all_windows)
11728 {
11729 Lisp_Object tail, frame;
11730 ptrdiff_t count = SPECPDL_INDEX ();
11731 /* 1 means that update_menu_bar has run its hooks
11732 so any further calls to update_menu_bar shouldn't do so again. */
11733 int menu_bar_hooks_run = 0;
11734
11735 record_unwind_save_match_data ();
11736
11737 FOR_EACH_FRAME (tail, frame)
11738 {
11739 struct frame *f = XFRAME (frame);
11740 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11741
11742 /* Ignore tooltip frame. */
11743 if (EQ (frame, tooltip_frame))
11744 continue;
11745
11746 if (some_windows
11747 && !f->redisplay
11748 && !w->redisplay
11749 && !XBUFFER (w->contents)->text->redisplay)
11750 continue;
11751
11752 /* If a window on this frame changed size, report that to
11753 the user and clear the size-change flag. */
11754 if (FRAME_WINDOW_SIZES_CHANGED (f))
11755 {
11756 Lisp_Object functions;
11757
11758 /* Clear flag first in case we get an error below. */
11759 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11760 functions = Vwindow_size_change_functions;
11761 GCPRO2 (tail, functions);
11762
11763 while (CONSP (functions))
11764 {
11765 if (!EQ (XCAR (functions), Qt))
11766 call1 (XCAR (functions), frame);
11767 functions = XCDR (functions);
11768 }
11769 UNGCPRO;
11770 }
11771
11772 GCPRO1 (tail);
11773 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11774 #ifdef HAVE_WINDOW_SYSTEM
11775 update_tool_bar (f, 0);
11776 #endif
11777 #ifdef HAVE_NS
11778 if (windows_or_buffers_changed
11779 && FRAME_NS_P (f))
11780 ns_set_doc_edited
11781 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11782 #endif
11783 UNGCPRO;
11784 }
11785
11786 unbind_to (count, Qnil);
11787 }
11788 else
11789 {
11790 struct frame *sf = SELECTED_FRAME ();
11791 update_menu_bar (sf, 1, 0);
11792 #ifdef HAVE_WINDOW_SYSTEM
11793 update_tool_bar (sf, 1);
11794 #endif
11795 }
11796 }
11797
11798
11799 /* Update the menu bar item list for frame F. This has to be done
11800 before we start to fill in any display lines, because it can call
11801 eval.
11802
11803 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11804
11805 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11806 already ran the menu bar hooks for this redisplay, so there
11807 is no need to run them again. The return value is the
11808 updated value of this flag, to pass to the next call. */
11809
11810 static int
11811 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11812 {
11813 Lisp_Object window;
11814 register struct window *w;
11815
11816 /* If called recursively during a menu update, do nothing. This can
11817 happen when, for instance, an activate-menubar-hook causes a
11818 redisplay. */
11819 if (inhibit_menubar_update)
11820 return hooks_run;
11821
11822 window = FRAME_SELECTED_WINDOW (f);
11823 w = XWINDOW (window);
11824
11825 if (FRAME_WINDOW_P (f)
11826 ?
11827 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11828 || defined (HAVE_NS) || defined (USE_GTK)
11829 FRAME_EXTERNAL_MENU_BAR (f)
11830 #else
11831 FRAME_MENU_BAR_LINES (f) > 0
11832 #endif
11833 : FRAME_MENU_BAR_LINES (f) > 0)
11834 {
11835 /* If the user has switched buffers or windows, we need to
11836 recompute to reflect the new bindings. But we'll
11837 recompute when update_mode_lines is set too; that means
11838 that people can use force-mode-line-update to request
11839 that the menu bar be recomputed. The adverse effect on
11840 the rest of the redisplay algorithm is about the same as
11841 windows_or_buffers_changed anyway. */
11842 if (windows_or_buffers_changed
11843 /* This used to test w->update_mode_line, but we believe
11844 there is no need to recompute the menu in that case. */
11845 || update_mode_lines
11846 || window_buffer_changed (w))
11847 {
11848 struct buffer *prev = current_buffer;
11849 ptrdiff_t count = SPECPDL_INDEX ();
11850
11851 specbind (Qinhibit_menubar_update, Qt);
11852
11853 set_buffer_internal_1 (XBUFFER (w->contents));
11854 if (save_match_data)
11855 record_unwind_save_match_data ();
11856 if (NILP (Voverriding_local_map_menu_flag))
11857 {
11858 specbind (Qoverriding_terminal_local_map, Qnil);
11859 specbind (Qoverriding_local_map, Qnil);
11860 }
11861
11862 if (!hooks_run)
11863 {
11864 /* Run the Lucid hook. */
11865 safe_run_hooks (Qactivate_menubar_hook);
11866
11867 /* If it has changed current-menubar from previous value,
11868 really recompute the menu-bar from the value. */
11869 if (! NILP (Vlucid_menu_bar_dirty_flag))
11870 call0 (Qrecompute_lucid_menubar);
11871
11872 safe_run_hooks (Qmenu_bar_update_hook);
11873
11874 hooks_run = 1;
11875 }
11876
11877 XSETFRAME (Vmenu_updating_frame, f);
11878 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11879
11880 /* Redisplay the menu bar in case we changed it. */
11881 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11882 || defined (HAVE_NS) || defined (USE_GTK)
11883 if (FRAME_WINDOW_P (f))
11884 {
11885 #if defined (HAVE_NS)
11886 /* All frames on Mac OS share the same menubar. So only
11887 the selected frame should be allowed to set it. */
11888 if (f == SELECTED_FRAME ())
11889 #endif
11890 set_frame_menubar (f, 0, 0);
11891 }
11892 else
11893 /* On a terminal screen, the menu bar is an ordinary screen
11894 line, and this makes it get updated. */
11895 w->update_mode_line = 1;
11896 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11897 /* In the non-toolkit version, the menu bar is an ordinary screen
11898 line, and this makes it get updated. */
11899 w->update_mode_line = 1;
11900 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11901
11902 unbind_to (count, Qnil);
11903 set_buffer_internal_1 (prev);
11904 }
11905 }
11906
11907 return hooks_run;
11908 }
11909
11910 /***********************************************************************
11911 Tool-bars
11912 ***********************************************************************/
11913
11914 #ifdef HAVE_WINDOW_SYSTEM
11915
11916 /* Select `frame' temporarily without running all the code in
11917 do_switch_frame.
11918 FIXME: Maybe do_switch_frame should be trimmed down similarly
11919 when `norecord' is set. */
11920 static void
11921 fast_set_selected_frame (Lisp_Object frame)
11922 {
11923 if (!EQ (selected_frame, frame))
11924 {
11925 selected_frame = frame;
11926 selected_window = XFRAME (frame)->selected_window;
11927 }
11928 }
11929
11930 /* Update the tool-bar item list for frame F. This has to be done
11931 before we start to fill in any display lines. Called from
11932 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11933 and restore it here. */
11934
11935 static void
11936 update_tool_bar (struct frame *f, int save_match_data)
11937 {
11938 #if defined (USE_GTK) || defined (HAVE_NS)
11939 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11940 #else
11941 int do_update = (WINDOWP (f->tool_bar_window)
11942 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
11943 #endif
11944
11945 if (do_update)
11946 {
11947 Lisp_Object window;
11948 struct window *w;
11949
11950 window = FRAME_SELECTED_WINDOW (f);
11951 w = XWINDOW (window);
11952
11953 /* If the user has switched buffers or windows, we need to
11954 recompute to reflect the new bindings. But we'll
11955 recompute when update_mode_lines is set too; that means
11956 that people can use force-mode-line-update to request
11957 that the menu bar be recomputed. The adverse effect on
11958 the rest of the redisplay algorithm is about the same as
11959 windows_or_buffers_changed anyway. */
11960 if (windows_or_buffers_changed
11961 || w->update_mode_line
11962 || update_mode_lines
11963 || window_buffer_changed (w))
11964 {
11965 struct buffer *prev = current_buffer;
11966 ptrdiff_t count = SPECPDL_INDEX ();
11967 Lisp_Object frame, new_tool_bar;
11968 int new_n_tool_bar;
11969 struct gcpro gcpro1;
11970
11971 /* Set current_buffer to the buffer of the selected
11972 window of the frame, so that we get the right local
11973 keymaps. */
11974 set_buffer_internal_1 (XBUFFER (w->contents));
11975
11976 /* Save match data, if we must. */
11977 if (save_match_data)
11978 record_unwind_save_match_data ();
11979
11980 /* Make sure that we don't accidentally use bogus keymaps. */
11981 if (NILP (Voverriding_local_map_menu_flag))
11982 {
11983 specbind (Qoverriding_terminal_local_map, Qnil);
11984 specbind (Qoverriding_local_map, Qnil);
11985 }
11986
11987 GCPRO1 (new_tool_bar);
11988
11989 /* We must temporarily set the selected frame to this frame
11990 before calling tool_bar_items, because the calculation of
11991 the tool-bar keymap uses the selected frame (see
11992 `tool-bar-make-keymap' in tool-bar.el). */
11993 eassert (EQ (selected_window,
11994 /* Since we only explicitly preserve selected_frame,
11995 check that selected_window would be redundant. */
11996 XFRAME (selected_frame)->selected_window));
11997 record_unwind_protect (fast_set_selected_frame, selected_frame);
11998 XSETFRAME (frame, f);
11999 fast_set_selected_frame (frame);
12000
12001 /* Build desired tool-bar items from keymaps. */
12002 new_tool_bar
12003 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
12004 &new_n_tool_bar);
12005
12006 /* Redisplay the tool-bar if we changed it. */
12007 if (new_n_tool_bar != f->n_tool_bar_items
12008 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
12009 {
12010 /* Redisplay that happens asynchronously due to an expose event
12011 may access f->tool_bar_items. Make sure we update both
12012 variables within BLOCK_INPUT so no such event interrupts. */
12013 block_input ();
12014 fset_tool_bar_items (f, new_tool_bar);
12015 f->n_tool_bar_items = new_n_tool_bar;
12016 w->update_mode_line = 1;
12017 unblock_input ();
12018 }
12019
12020 UNGCPRO;
12021
12022 unbind_to (count, Qnil);
12023 set_buffer_internal_1 (prev);
12024 }
12025 }
12026 }
12027
12028 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12029
12030 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12031 F's desired tool-bar contents. F->tool_bar_items must have
12032 been set up previously by calling prepare_menu_bars. */
12033
12034 static void
12035 build_desired_tool_bar_string (struct frame *f)
12036 {
12037 int i, size, size_needed;
12038 struct gcpro gcpro1, gcpro2, gcpro3;
12039 Lisp_Object image, plist, props;
12040
12041 image = plist = props = Qnil;
12042 GCPRO3 (image, plist, props);
12043
12044 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12045 Otherwise, make a new string. */
12046
12047 /* The size of the string we might be able to reuse. */
12048 size = (STRINGP (f->desired_tool_bar_string)
12049 ? SCHARS (f->desired_tool_bar_string)
12050 : 0);
12051
12052 /* We need one space in the string for each image. */
12053 size_needed = f->n_tool_bar_items;
12054
12055 /* Reuse f->desired_tool_bar_string, if possible. */
12056 if (size < size_needed || NILP (f->desired_tool_bar_string))
12057 fset_desired_tool_bar_string
12058 (f, Fmake_string (make_number (size_needed), make_number (' ')));
12059 else
12060 {
12061 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
12062 Fremove_text_properties (make_number (0), make_number (size),
12063 props, f->desired_tool_bar_string);
12064 }
12065
12066 /* Put a `display' property on the string for the images to display,
12067 put a `menu_item' property on tool-bar items with a value that
12068 is the index of the item in F's tool-bar item vector. */
12069 for (i = 0; i < f->n_tool_bar_items; ++i)
12070 {
12071 #define PROP(IDX) \
12072 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12073
12074 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12075 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12076 int hmargin, vmargin, relief, idx, end;
12077
12078 /* If image is a vector, choose the image according to the
12079 button state. */
12080 image = PROP (TOOL_BAR_ITEM_IMAGES);
12081 if (VECTORP (image))
12082 {
12083 if (enabled_p)
12084 idx = (selected_p
12085 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12086 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12087 else
12088 idx = (selected_p
12089 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12090 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12091
12092 eassert (ASIZE (image) >= idx);
12093 image = AREF (image, idx);
12094 }
12095 else
12096 idx = -1;
12097
12098 /* Ignore invalid image specifications. */
12099 if (!valid_image_p (image))
12100 continue;
12101
12102 /* Display the tool-bar button pressed, or depressed. */
12103 plist = Fcopy_sequence (XCDR (image));
12104
12105 /* Compute margin and relief to draw. */
12106 relief = (tool_bar_button_relief >= 0
12107 ? tool_bar_button_relief
12108 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12109 hmargin = vmargin = relief;
12110
12111 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12112 INT_MAX - max (hmargin, vmargin)))
12113 {
12114 hmargin += XFASTINT (Vtool_bar_button_margin);
12115 vmargin += XFASTINT (Vtool_bar_button_margin);
12116 }
12117 else if (CONSP (Vtool_bar_button_margin))
12118 {
12119 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12120 INT_MAX - hmargin))
12121 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12122
12123 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12124 INT_MAX - vmargin))
12125 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12126 }
12127
12128 if (auto_raise_tool_bar_buttons_p)
12129 {
12130 /* Add a `:relief' property to the image spec if the item is
12131 selected. */
12132 if (selected_p)
12133 {
12134 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12135 hmargin -= relief;
12136 vmargin -= relief;
12137 }
12138 }
12139 else
12140 {
12141 /* If image is selected, display it pressed, i.e. with a
12142 negative relief. If it's not selected, display it with a
12143 raised relief. */
12144 plist = Fplist_put (plist, QCrelief,
12145 (selected_p
12146 ? make_number (-relief)
12147 : make_number (relief)));
12148 hmargin -= relief;
12149 vmargin -= relief;
12150 }
12151
12152 /* Put a margin around the image. */
12153 if (hmargin || vmargin)
12154 {
12155 if (hmargin == vmargin)
12156 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12157 else
12158 plist = Fplist_put (plist, QCmargin,
12159 Fcons (make_number (hmargin),
12160 make_number (vmargin)));
12161 }
12162
12163 /* If button is not enabled, and we don't have special images
12164 for the disabled state, make the image appear disabled by
12165 applying an appropriate algorithm to it. */
12166 if (!enabled_p && idx < 0)
12167 plist = Fplist_put (plist, QCconversion, Qdisabled);
12168
12169 /* Put a `display' text property on the string for the image to
12170 display. Put a `menu-item' property on the string that gives
12171 the start of this item's properties in the tool-bar items
12172 vector. */
12173 image = Fcons (Qimage, plist);
12174 props = list4 (Qdisplay, image,
12175 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
12176
12177 /* Let the last image hide all remaining spaces in the tool bar
12178 string. The string can be longer than needed when we reuse a
12179 previous string. */
12180 if (i + 1 == f->n_tool_bar_items)
12181 end = SCHARS (f->desired_tool_bar_string);
12182 else
12183 end = i + 1;
12184 Fadd_text_properties (make_number (i), make_number (end),
12185 props, f->desired_tool_bar_string);
12186 #undef PROP
12187 }
12188
12189 UNGCPRO;
12190 }
12191
12192
12193 /* Display one line of the tool-bar of frame IT->f.
12194
12195 HEIGHT specifies the desired height of the tool-bar line.
12196 If the actual height of the glyph row is less than HEIGHT, the
12197 row's height is increased to HEIGHT, and the icons are centered
12198 vertically in the new height.
12199
12200 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12201 count a final empty row in case the tool-bar width exactly matches
12202 the window width.
12203 */
12204
12205 static void
12206 display_tool_bar_line (struct it *it, int height)
12207 {
12208 struct glyph_row *row = it->glyph_row;
12209 int max_x = it->last_visible_x;
12210 struct glyph *last;
12211
12212 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12213 clear_glyph_row (row);
12214 row->enabled_p = true;
12215 row->y = it->current_y;
12216
12217 /* Note that this isn't made use of if the face hasn't a box,
12218 so there's no need to check the face here. */
12219 it->start_of_box_run_p = 1;
12220
12221 while (it->current_x < max_x)
12222 {
12223 int x, n_glyphs_before, i, nglyphs;
12224 struct it it_before;
12225
12226 /* Get the next display element. */
12227 if (!get_next_display_element (it))
12228 {
12229 /* Don't count empty row if we are counting needed tool-bar lines. */
12230 if (height < 0 && !it->hpos)
12231 return;
12232 break;
12233 }
12234
12235 /* Produce glyphs. */
12236 n_glyphs_before = row->used[TEXT_AREA];
12237 it_before = *it;
12238
12239 PRODUCE_GLYPHS (it);
12240
12241 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12242 i = 0;
12243 x = it_before.current_x;
12244 while (i < nglyphs)
12245 {
12246 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12247
12248 if (x + glyph->pixel_width > max_x)
12249 {
12250 /* Glyph doesn't fit on line. Backtrack. */
12251 row->used[TEXT_AREA] = n_glyphs_before;
12252 *it = it_before;
12253 /* If this is the only glyph on this line, it will never fit on the
12254 tool-bar, so skip it. But ensure there is at least one glyph,
12255 so we don't accidentally disable the tool-bar. */
12256 if (n_glyphs_before == 0
12257 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12258 break;
12259 goto out;
12260 }
12261
12262 ++it->hpos;
12263 x += glyph->pixel_width;
12264 ++i;
12265 }
12266
12267 /* Stop at line end. */
12268 if (ITERATOR_AT_END_OF_LINE_P (it))
12269 break;
12270
12271 set_iterator_to_next (it, 1);
12272 }
12273
12274 out:;
12275
12276 row->displays_text_p = row->used[TEXT_AREA] != 0;
12277
12278 /* Use default face for the border below the tool bar.
12279
12280 FIXME: When auto-resize-tool-bars is grow-only, there is
12281 no additional border below the possibly empty tool-bar lines.
12282 So to make the extra empty lines look "normal", we have to
12283 use the tool-bar face for the border too. */
12284 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12285 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12286 it->face_id = DEFAULT_FACE_ID;
12287
12288 extend_face_to_end_of_line (it);
12289 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12290 last->right_box_line_p = 1;
12291 if (last == row->glyphs[TEXT_AREA])
12292 last->left_box_line_p = 1;
12293
12294 /* Make line the desired height and center it vertically. */
12295 if ((height -= it->max_ascent + it->max_descent) > 0)
12296 {
12297 /* Don't add more than one line height. */
12298 height %= FRAME_LINE_HEIGHT (it->f);
12299 it->max_ascent += height / 2;
12300 it->max_descent += (height + 1) / 2;
12301 }
12302
12303 compute_line_metrics (it);
12304
12305 /* If line is empty, make it occupy the rest of the tool-bar. */
12306 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12307 {
12308 row->height = row->phys_height = it->last_visible_y - row->y;
12309 row->visible_height = row->height;
12310 row->ascent = row->phys_ascent = 0;
12311 row->extra_line_spacing = 0;
12312 }
12313
12314 row->full_width_p = 1;
12315 row->continued_p = 0;
12316 row->truncated_on_left_p = 0;
12317 row->truncated_on_right_p = 0;
12318
12319 it->current_x = it->hpos = 0;
12320 it->current_y += row->height;
12321 ++it->vpos;
12322 ++it->glyph_row;
12323 }
12324
12325
12326 /* Value is the number of pixels needed to make all tool-bar items of
12327 frame F visible. The actual number of glyph rows needed is
12328 returned in *N_ROWS if non-NULL. */
12329 static int
12330 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12331 {
12332 struct window *w = XWINDOW (f->tool_bar_window);
12333 struct it it;
12334 /* tool_bar_height is called from redisplay_tool_bar after building
12335 the desired matrix, so use (unused) mode-line row as temporary row to
12336 avoid destroying the first tool-bar row. */
12337 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12338
12339 /* Initialize an iterator for iteration over
12340 F->desired_tool_bar_string in the tool-bar window of frame F. */
12341 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12342 temp_row->reversed_p = false;
12343 it.first_visible_x = 0;
12344 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12345 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12346 it.paragraph_embedding = L2R;
12347
12348 while (!ITERATOR_AT_END_P (&it))
12349 {
12350 clear_glyph_row (temp_row);
12351 it.glyph_row = temp_row;
12352 display_tool_bar_line (&it, -1);
12353 }
12354 clear_glyph_row (temp_row);
12355
12356 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12357 if (n_rows)
12358 *n_rows = it.vpos > 0 ? it.vpos : -1;
12359
12360 if (pixelwise)
12361 return it.current_y;
12362 else
12363 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12364 }
12365
12366 #endif /* !USE_GTK && !HAVE_NS */
12367
12368 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12369 0, 2, 0,
12370 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12371 If FRAME is nil or omitted, use the selected frame. Optional argument
12372 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12373 (Lisp_Object frame, Lisp_Object pixelwise)
12374 {
12375 int height = 0;
12376
12377 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12378 struct frame *f = decode_any_frame (frame);
12379
12380 if (WINDOWP (f->tool_bar_window)
12381 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12382 {
12383 update_tool_bar (f, 1);
12384 if (f->n_tool_bar_items)
12385 {
12386 build_desired_tool_bar_string (f);
12387 height = tool_bar_height (f, NULL, NILP (pixelwise) ? 0 : 1);
12388 }
12389 }
12390 #endif
12391
12392 return make_number (height);
12393 }
12394
12395
12396 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
12397 height should be changed. */
12398 static int
12399 redisplay_tool_bar (struct frame *f)
12400 {
12401 #if defined (USE_GTK) || defined (HAVE_NS)
12402
12403 if (FRAME_EXTERNAL_TOOL_BAR (f))
12404 update_frame_tool_bar (f);
12405 return 0;
12406
12407 #else /* !USE_GTK && !HAVE_NS */
12408
12409 struct window *w;
12410 struct it it;
12411 struct glyph_row *row;
12412
12413 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12414 do anything. This means you must start with tool-bar-lines
12415 non-zero to get the auto-sizing effect. Or in other words, you
12416 can turn off tool-bars by specifying tool-bar-lines zero. */
12417 if (!WINDOWP (f->tool_bar_window)
12418 || (w = XWINDOW (f->tool_bar_window),
12419 WINDOW_TOTAL_LINES (w) == 0))
12420 return 0;
12421
12422 /* Set up an iterator for the tool-bar window. */
12423 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12424 it.first_visible_x = 0;
12425 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12426 row = it.glyph_row;
12427 row->reversed_p = false;
12428
12429 /* Build a string that represents the contents of the tool-bar. */
12430 build_desired_tool_bar_string (f);
12431 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12432 /* FIXME: This should be controlled by a user option. But it
12433 doesn't make sense to have an R2L tool bar if the menu bar cannot
12434 be drawn also R2L, and making the menu bar R2L is tricky due
12435 toolkit-specific code that implements it. If an R2L tool bar is
12436 ever supported, display_tool_bar_line should also be augmented to
12437 call unproduce_glyphs like display_line and display_string
12438 do. */
12439 it.paragraph_embedding = L2R;
12440
12441 if (f->n_tool_bar_rows == 0)
12442 {
12443 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, 1);
12444
12445 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12446 {
12447 x_change_tool_bar_height (f, new_height);
12448 /* Always do that now. */
12449 clear_glyph_matrix (w->desired_matrix);
12450 f->fonts_changed = 1;
12451 return 1;
12452 }
12453 }
12454
12455 /* Display as many lines as needed to display all tool-bar items. */
12456
12457 if (f->n_tool_bar_rows > 0)
12458 {
12459 int border, rows, height, extra;
12460
12461 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12462 border = XINT (Vtool_bar_border);
12463 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12464 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12465 else if (EQ (Vtool_bar_border, Qborder_width))
12466 border = f->border_width;
12467 else
12468 border = 0;
12469 if (border < 0)
12470 border = 0;
12471
12472 rows = f->n_tool_bar_rows;
12473 height = max (1, (it.last_visible_y - border) / rows);
12474 extra = it.last_visible_y - border - height * rows;
12475
12476 while (it.current_y < it.last_visible_y)
12477 {
12478 int h = 0;
12479 if (extra > 0 && rows-- > 0)
12480 {
12481 h = (extra + rows - 1) / rows;
12482 extra -= h;
12483 }
12484 display_tool_bar_line (&it, height + h);
12485 }
12486 }
12487 else
12488 {
12489 while (it.current_y < it.last_visible_y)
12490 display_tool_bar_line (&it, 0);
12491 }
12492
12493 /* It doesn't make much sense to try scrolling in the tool-bar
12494 window, so don't do it. */
12495 w->desired_matrix->no_scrolling_p = 1;
12496 w->must_be_updated_p = 1;
12497
12498 if (!NILP (Vauto_resize_tool_bars))
12499 {
12500 int change_height_p = 0;
12501
12502 /* If we couldn't display everything, change the tool-bar's
12503 height if there is room for more. */
12504 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12505 change_height_p = 1;
12506
12507 /* We subtract 1 because display_tool_bar_line advances the
12508 glyph_row pointer before returning to its caller. We want to
12509 examine the last glyph row produced by
12510 display_tool_bar_line. */
12511 row = it.glyph_row - 1;
12512
12513 /* If there are blank lines at the end, except for a partially
12514 visible blank line at the end that is smaller than
12515 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12516 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12517 && row->height >= FRAME_LINE_HEIGHT (f))
12518 change_height_p = 1;
12519
12520 /* If row displays tool-bar items, but is partially visible,
12521 change the tool-bar's height. */
12522 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12523 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12524 change_height_p = 1;
12525
12526 /* Resize windows as needed by changing the `tool-bar-lines'
12527 frame parameter. */
12528 if (change_height_p)
12529 {
12530 int nrows;
12531 int new_height = tool_bar_height (f, &nrows, 1);
12532
12533 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12534 && !f->minimize_tool_bar_window_p)
12535 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12536 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12537 f->minimize_tool_bar_window_p = 0;
12538
12539 if (change_height_p)
12540 {
12541 x_change_tool_bar_height (f, new_height);
12542 clear_glyph_matrix (w->desired_matrix);
12543 f->n_tool_bar_rows = nrows;
12544 f->fonts_changed = 1;
12545
12546 return 1;
12547 }
12548 }
12549 }
12550
12551 f->minimize_tool_bar_window_p = 0;
12552 return 0;
12553
12554 #endif /* USE_GTK || HAVE_NS */
12555 }
12556
12557 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12558
12559 /* Get information about the tool-bar item which is displayed in GLYPH
12560 on frame F. Return in *PROP_IDX the index where tool-bar item
12561 properties start in F->tool_bar_items. Value is zero if
12562 GLYPH doesn't display a tool-bar item. */
12563
12564 static int
12565 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12566 {
12567 Lisp_Object prop;
12568 int success_p;
12569 int charpos;
12570
12571 /* This function can be called asynchronously, which means we must
12572 exclude any possibility that Fget_text_property signals an
12573 error. */
12574 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12575 charpos = max (0, charpos);
12576
12577 /* Get the text property `menu-item' at pos. The value of that
12578 property is the start index of this item's properties in
12579 F->tool_bar_items. */
12580 prop = Fget_text_property (make_number (charpos),
12581 Qmenu_item, f->current_tool_bar_string);
12582 if (INTEGERP (prop))
12583 {
12584 *prop_idx = XINT (prop);
12585 success_p = 1;
12586 }
12587 else
12588 success_p = 0;
12589
12590 return success_p;
12591 }
12592
12593 \f
12594 /* Get information about the tool-bar item at position X/Y on frame F.
12595 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12596 the current matrix of the tool-bar window of F, or NULL if not
12597 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12598 item in F->tool_bar_items. Value is
12599
12600 -1 if X/Y is not on a tool-bar item
12601 0 if X/Y is on the same item that was highlighted before.
12602 1 otherwise. */
12603
12604 static int
12605 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12606 int *hpos, int *vpos, int *prop_idx)
12607 {
12608 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12609 struct window *w = XWINDOW (f->tool_bar_window);
12610 int area;
12611
12612 /* Find the glyph under X/Y. */
12613 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12614 if (*glyph == NULL)
12615 return -1;
12616
12617 /* Get the start of this tool-bar item's properties in
12618 f->tool_bar_items. */
12619 if (!tool_bar_item_info (f, *glyph, prop_idx))
12620 return -1;
12621
12622 /* Is mouse on the highlighted item? */
12623 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12624 && *vpos >= hlinfo->mouse_face_beg_row
12625 && *vpos <= hlinfo->mouse_face_end_row
12626 && (*vpos > hlinfo->mouse_face_beg_row
12627 || *hpos >= hlinfo->mouse_face_beg_col)
12628 && (*vpos < hlinfo->mouse_face_end_row
12629 || *hpos < hlinfo->mouse_face_end_col
12630 || hlinfo->mouse_face_past_end))
12631 return 0;
12632
12633 return 1;
12634 }
12635
12636
12637 /* EXPORT:
12638 Handle mouse button event on the tool-bar of frame F, at
12639 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12640 0 for button release. MODIFIERS is event modifiers for button
12641 release. */
12642
12643 void
12644 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12645 int modifiers)
12646 {
12647 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12648 struct window *w = XWINDOW (f->tool_bar_window);
12649 int hpos, vpos, prop_idx;
12650 struct glyph *glyph;
12651 Lisp_Object enabled_p;
12652 int ts;
12653
12654 /* If not on the highlighted tool-bar item, and mouse-highlight is
12655 non-nil, return. This is so we generate the tool-bar button
12656 click only when the mouse button is released on the same item as
12657 where it was pressed. However, when mouse-highlight is disabled,
12658 generate the click when the button is released regardless of the
12659 highlight, since tool-bar items are not highlighted in that
12660 case. */
12661 frame_to_window_pixel_xy (w, &x, &y);
12662 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12663 if (ts == -1
12664 || (ts != 0 && !NILP (Vmouse_highlight)))
12665 return;
12666
12667 /* When mouse-highlight is off, generate the click for the item
12668 where the button was pressed, disregarding where it was
12669 released. */
12670 if (NILP (Vmouse_highlight) && !down_p)
12671 prop_idx = f->last_tool_bar_item;
12672
12673 /* If item is disabled, do nothing. */
12674 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12675 if (NILP (enabled_p))
12676 return;
12677
12678 if (down_p)
12679 {
12680 /* Show item in pressed state. */
12681 if (!NILP (Vmouse_highlight))
12682 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12683 f->last_tool_bar_item = prop_idx;
12684 }
12685 else
12686 {
12687 Lisp_Object key, frame;
12688 struct input_event event;
12689 EVENT_INIT (event);
12690
12691 /* Show item in released state. */
12692 if (!NILP (Vmouse_highlight))
12693 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12694
12695 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12696
12697 XSETFRAME (frame, f);
12698 event.kind = TOOL_BAR_EVENT;
12699 event.frame_or_window = frame;
12700 event.arg = frame;
12701 kbd_buffer_store_event (&event);
12702
12703 event.kind = TOOL_BAR_EVENT;
12704 event.frame_or_window = frame;
12705 event.arg = key;
12706 event.modifiers = modifiers;
12707 kbd_buffer_store_event (&event);
12708 f->last_tool_bar_item = -1;
12709 }
12710 }
12711
12712
12713 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12714 tool-bar window-relative coordinates X/Y. Called from
12715 note_mouse_highlight. */
12716
12717 static void
12718 note_tool_bar_highlight (struct frame *f, int x, int y)
12719 {
12720 Lisp_Object window = f->tool_bar_window;
12721 struct window *w = XWINDOW (window);
12722 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
12723 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12724 int hpos, vpos;
12725 struct glyph *glyph;
12726 struct glyph_row *row;
12727 int i;
12728 Lisp_Object enabled_p;
12729 int prop_idx;
12730 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12731 int mouse_down_p, rc;
12732
12733 /* Function note_mouse_highlight is called with negative X/Y
12734 values when mouse moves outside of the frame. */
12735 if (x <= 0 || y <= 0)
12736 {
12737 clear_mouse_face (hlinfo);
12738 return;
12739 }
12740
12741 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12742 if (rc < 0)
12743 {
12744 /* Not on tool-bar item. */
12745 clear_mouse_face (hlinfo);
12746 return;
12747 }
12748 else if (rc == 0)
12749 /* On same tool-bar item as before. */
12750 goto set_help_echo;
12751
12752 clear_mouse_face (hlinfo);
12753
12754 /* Mouse is down, but on different tool-bar item? */
12755 mouse_down_p = (x_mouse_grabbed (dpyinfo)
12756 && f == dpyinfo->last_mouse_frame);
12757
12758 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
12759 return;
12760
12761 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12762
12763 /* If tool-bar item is not enabled, don't highlight it. */
12764 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12765 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12766 {
12767 /* Compute the x-position of the glyph. In front and past the
12768 image is a space. We include this in the highlighted area. */
12769 row = MATRIX_ROW (w->current_matrix, vpos);
12770 for (i = x = 0; i < hpos; ++i)
12771 x += row->glyphs[TEXT_AREA][i].pixel_width;
12772
12773 /* Record this as the current active region. */
12774 hlinfo->mouse_face_beg_col = hpos;
12775 hlinfo->mouse_face_beg_row = vpos;
12776 hlinfo->mouse_face_beg_x = x;
12777 hlinfo->mouse_face_past_end = 0;
12778
12779 hlinfo->mouse_face_end_col = hpos + 1;
12780 hlinfo->mouse_face_end_row = vpos;
12781 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12782 hlinfo->mouse_face_window = window;
12783 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12784
12785 /* Display it as active. */
12786 show_mouse_face (hlinfo, draw);
12787 }
12788
12789 set_help_echo:
12790
12791 /* Set help_echo_string to a help string to display for this tool-bar item.
12792 XTread_socket does the rest. */
12793 help_echo_object = help_echo_window = Qnil;
12794 help_echo_pos = -1;
12795 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12796 if (NILP (help_echo_string))
12797 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12798 }
12799
12800 #endif /* !USE_GTK && !HAVE_NS */
12801
12802 #endif /* HAVE_WINDOW_SYSTEM */
12803
12804
12805 \f
12806 /************************************************************************
12807 Horizontal scrolling
12808 ************************************************************************/
12809
12810 static int hscroll_window_tree (Lisp_Object);
12811 static int hscroll_windows (Lisp_Object);
12812
12813 /* For all leaf windows in the window tree rooted at WINDOW, set their
12814 hscroll value so that PT is (i) visible in the window, and (ii) so
12815 that it is not within a certain margin at the window's left and
12816 right border. Value is non-zero if any window's hscroll has been
12817 changed. */
12818
12819 static int
12820 hscroll_window_tree (Lisp_Object window)
12821 {
12822 int hscrolled_p = 0;
12823 int hscroll_relative_p = FLOATP (Vhscroll_step);
12824 int hscroll_step_abs = 0;
12825 double hscroll_step_rel = 0;
12826
12827 if (hscroll_relative_p)
12828 {
12829 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12830 if (hscroll_step_rel < 0)
12831 {
12832 hscroll_relative_p = 0;
12833 hscroll_step_abs = 0;
12834 }
12835 }
12836 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12837 {
12838 hscroll_step_abs = XINT (Vhscroll_step);
12839 if (hscroll_step_abs < 0)
12840 hscroll_step_abs = 0;
12841 }
12842 else
12843 hscroll_step_abs = 0;
12844
12845 while (WINDOWP (window))
12846 {
12847 struct window *w = XWINDOW (window);
12848
12849 if (WINDOWP (w->contents))
12850 hscrolled_p |= hscroll_window_tree (w->contents);
12851 else if (w->cursor.vpos >= 0)
12852 {
12853 int h_margin;
12854 int text_area_width;
12855 struct glyph_row *cursor_row;
12856 struct glyph_row *bottom_row;
12857 int row_r2l_p;
12858
12859 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
12860 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
12861 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12862 else
12863 cursor_row = bottom_row - 1;
12864
12865 if (!cursor_row->enabled_p)
12866 {
12867 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12868 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
12869 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12870 else
12871 cursor_row = bottom_row - 1;
12872 }
12873 row_r2l_p = cursor_row->reversed_p;
12874
12875 text_area_width = window_box_width (w, TEXT_AREA);
12876
12877 /* Scroll when cursor is inside this scroll margin. */
12878 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12879
12880 /* If the position of this window's point has explicitly
12881 changed, no more suspend auto hscrolling. */
12882 if (NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))))
12883 w->suspend_auto_hscroll = 0;
12884
12885 /* Remember window point. */
12886 Fset_marker (w->old_pointm,
12887 ((w == XWINDOW (selected_window))
12888 ? make_number (BUF_PT (XBUFFER (w->contents)))
12889 : Fmarker_position (w->pointm)),
12890 w->contents);
12891
12892 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12893 && w->suspend_auto_hscroll == 0
12894 /* In some pathological cases, like restoring a window
12895 configuration into a frame that is much smaller than
12896 the one from which the configuration was saved, we
12897 get glyph rows whose start and end have zero buffer
12898 positions, which we cannot handle below. Just skip
12899 such windows. */
12900 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
12901 /* For left-to-right rows, hscroll when cursor is either
12902 (i) inside the right hscroll margin, or (ii) if it is
12903 inside the left margin and the window is already
12904 hscrolled. */
12905 && ((!row_r2l_p
12906 && ((w->hscroll && w->cursor.x <= h_margin)
12907 || (cursor_row->enabled_p
12908 && cursor_row->truncated_on_right_p
12909 && (w->cursor.x >= text_area_width - h_margin))))
12910 /* For right-to-left rows, the logic is similar,
12911 except that rules for scrolling to left and right
12912 are reversed. E.g., if cursor.x <= h_margin, we
12913 need to hscroll "to the right" unconditionally,
12914 and that will scroll the screen to the left so as
12915 to reveal the next portion of the row. */
12916 || (row_r2l_p
12917 && ((cursor_row->enabled_p
12918 /* FIXME: It is confusing to set the
12919 truncated_on_right_p flag when R2L rows
12920 are actually truncated on the left. */
12921 && cursor_row->truncated_on_right_p
12922 && w->cursor.x <= h_margin)
12923 || (w->hscroll
12924 && (w->cursor.x >= text_area_width - h_margin))))))
12925 {
12926 struct it it;
12927 ptrdiff_t hscroll;
12928 struct buffer *saved_current_buffer;
12929 ptrdiff_t pt;
12930 int wanted_x;
12931
12932 /* Find point in a display of infinite width. */
12933 saved_current_buffer = current_buffer;
12934 current_buffer = XBUFFER (w->contents);
12935
12936 if (w == XWINDOW (selected_window))
12937 pt = PT;
12938 else
12939 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12940
12941 /* Move iterator to pt starting at cursor_row->start in
12942 a line with infinite width. */
12943 init_to_row_start (&it, w, cursor_row);
12944 it.last_visible_x = INFINITY;
12945 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12946 current_buffer = saved_current_buffer;
12947
12948 /* Position cursor in window. */
12949 if (!hscroll_relative_p && hscroll_step_abs == 0)
12950 hscroll = max (0, (it.current_x
12951 - (ITERATOR_AT_END_OF_LINE_P (&it)
12952 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12953 : (text_area_width / 2))))
12954 / FRAME_COLUMN_WIDTH (it.f);
12955 else if ((!row_r2l_p
12956 && w->cursor.x >= text_area_width - h_margin)
12957 || (row_r2l_p && w->cursor.x <= h_margin))
12958 {
12959 if (hscroll_relative_p)
12960 wanted_x = text_area_width * (1 - hscroll_step_rel)
12961 - h_margin;
12962 else
12963 wanted_x = text_area_width
12964 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12965 - h_margin;
12966 hscroll
12967 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12968 }
12969 else
12970 {
12971 if (hscroll_relative_p)
12972 wanted_x = text_area_width * hscroll_step_rel
12973 + h_margin;
12974 else
12975 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12976 + h_margin;
12977 hscroll
12978 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12979 }
12980 hscroll = max (hscroll, w->min_hscroll);
12981
12982 /* Don't prevent redisplay optimizations if hscroll
12983 hasn't changed, as it will unnecessarily slow down
12984 redisplay. */
12985 if (w->hscroll != hscroll)
12986 {
12987 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12988 w->hscroll = hscroll;
12989 hscrolled_p = 1;
12990 }
12991 }
12992 }
12993
12994 window = w->next;
12995 }
12996
12997 /* Value is non-zero if hscroll of any leaf window has been changed. */
12998 return hscrolled_p;
12999 }
13000
13001
13002 /* Set hscroll so that cursor is visible and not inside horizontal
13003 scroll margins for all windows in the tree rooted at WINDOW. See
13004 also hscroll_window_tree above. Value is non-zero if any window's
13005 hscroll has been changed. If it has, desired matrices on the frame
13006 of WINDOW are cleared. */
13007
13008 static int
13009 hscroll_windows (Lisp_Object window)
13010 {
13011 int hscrolled_p = hscroll_window_tree (window);
13012 if (hscrolled_p)
13013 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
13014 return hscrolled_p;
13015 }
13016
13017
13018 \f
13019 /************************************************************************
13020 Redisplay
13021 ************************************************************************/
13022
13023 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
13024 to a non-zero value. This is sometimes handy to have in a debugger
13025 session. */
13026
13027 #ifdef GLYPH_DEBUG
13028
13029 /* First and last unchanged row for try_window_id. */
13030
13031 static int debug_first_unchanged_at_end_vpos;
13032 static int debug_last_unchanged_at_beg_vpos;
13033
13034 /* Delta vpos and y. */
13035
13036 static int debug_dvpos, debug_dy;
13037
13038 /* Delta in characters and bytes for try_window_id. */
13039
13040 static ptrdiff_t debug_delta, debug_delta_bytes;
13041
13042 /* Values of window_end_pos and window_end_vpos at the end of
13043 try_window_id. */
13044
13045 static ptrdiff_t debug_end_vpos;
13046
13047 /* Append a string to W->desired_matrix->method. FMT is a printf
13048 format string. If trace_redisplay_p is true also printf the
13049 resulting string to stderr. */
13050
13051 static void debug_method_add (struct window *, char const *, ...)
13052 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13053
13054 static void
13055 debug_method_add (struct window *w, char const *fmt, ...)
13056 {
13057 void *ptr = w;
13058 char *method = w->desired_matrix->method;
13059 int len = strlen (method);
13060 int size = sizeof w->desired_matrix->method;
13061 int remaining = size - len - 1;
13062 va_list ap;
13063
13064 if (len && remaining)
13065 {
13066 method[len] = '|';
13067 --remaining, ++len;
13068 }
13069
13070 va_start (ap, fmt);
13071 vsnprintf (method + len, remaining + 1, fmt, ap);
13072 va_end (ap);
13073
13074 if (trace_redisplay_p)
13075 fprintf (stderr, "%p (%s): %s\n",
13076 ptr,
13077 ((BUFFERP (w->contents)
13078 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13079 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13080 : "no buffer"),
13081 method + len);
13082 }
13083
13084 #endif /* GLYPH_DEBUG */
13085
13086
13087 /* Value is non-zero if all changes in window W, which displays
13088 current_buffer, are in the text between START and END. START is a
13089 buffer position, END is given as a distance from Z. Used in
13090 redisplay_internal for display optimization. */
13091
13092 static int
13093 text_outside_line_unchanged_p (struct window *w,
13094 ptrdiff_t start, ptrdiff_t end)
13095 {
13096 int unchanged_p = 1;
13097
13098 /* If text or overlays have changed, see where. */
13099 if (window_outdated (w))
13100 {
13101 /* Gap in the line? */
13102 if (GPT < start || Z - GPT < end)
13103 unchanged_p = 0;
13104
13105 /* Changes start in front of the line, or end after it? */
13106 if (unchanged_p
13107 && (BEG_UNCHANGED < start - 1
13108 || END_UNCHANGED < end))
13109 unchanged_p = 0;
13110
13111 /* If selective display, can't optimize if changes start at the
13112 beginning of the line. */
13113 if (unchanged_p
13114 && INTEGERP (BVAR (current_buffer, selective_display))
13115 && XINT (BVAR (current_buffer, selective_display)) > 0
13116 && (BEG_UNCHANGED < start || GPT <= start))
13117 unchanged_p = 0;
13118
13119 /* If there are overlays at the start or end of the line, these
13120 may have overlay strings with newlines in them. A change at
13121 START, for instance, may actually concern the display of such
13122 overlay strings as well, and they are displayed on different
13123 lines. So, quickly rule out this case. (For the future, it
13124 might be desirable to implement something more telling than
13125 just BEG/END_UNCHANGED.) */
13126 if (unchanged_p)
13127 {
13128 if (BEG + BEG_UNCHANGED == start
13129 && overlay_touches_p (start))
13130 unchanged_p = 0;
13131 if (END_UNCHANGED == end
13132 && overlay_touches_p (Z - end))
13133 unchanged_p = 0;
13134 }
13135
13136 /* Under bidi reordering, adding or deleting a character in the
13137 beginning of a paragraph, before the first strong directional
13138 character, can change the base direction of the paragraph (unless
13139 the buffer specifies a fixed paragraph direction), which will
13140 require to redisplay the whole paragraph. It might be worthwhile
13141 to find the paragraph limits and widen the range of redisplayed
13142 lines to that, but for now just give up this optimization. */
13143 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13144 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13145 unchanged_p = 0;
13146 }
13147
13148 return unchanged_p;
13149 }
13150
13151
13152 /* Do a frame update, taking possible shortcuts into account. This is
13153 the main external entry point for redisplay.
13154
13155 If the last redisplay displayed an echo area message and that message
13156 is no longer requested, we clear the echo area or bring back the
13157 mini-buffer if that is in use. */
13158
13159 void
13160 redisplay (void)
13161 {
13162 redisplay_internal ();
13163 }
13164
13165
13166 static Lisp_Object
13167 overlay_arrow_string_or_property (Lisp_Object var)
13168 {
13169 Lisp_Object val;
13170
13171 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13172 return val;
13173
13174 return Voverlay_arrow_string;
13175 }
13176
13177 /* Return 1 if there are any overlay-arrows in current_buffer. */
13178 static int
13179 overlay_arrow_in_current_buffer_p (void)
13180 {
13181 Lisp_Object vlist;
13182
13183 for (vlist = Voverlay_arrow_variable_list;
13184 CONSP (vlist);
13185 vlist = XCDR (vlist))
13186 {
13187 Lisp_Object var = XCAR (vlist);
13188 Lisp_Object val;
13189
13190 if (!SYMBOLP (var))
13191 continue;
13192 val = find_symbol_value (var);
13193 if (MARKERP (val)
13194 && current_buffer == XMARKER (val)->buffer)
13195 return 1;
13196 }
13197 return 0;
13198 }
13199
13200
13201 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
13202 has changed. */
13203
13204 static int
13205 overlay_arrows_changed_p (void)
13206 {
13207 Lisp_Object vlist;
13208
13209 for (vlist = Voverlay_arrow_variable_list;
13210 CONSP (vlist);
13211 vlist = XCDR (vlist))
13212 {
13213 Lisp_Object var = XCAR (vlist);
13214 Lisp_Object val, pstr;
13215
13216 if (!SYMBOLP (var))
13217 continue;
13218 val = find_symbol_value (var);
13219 if (!MARKERP (val))
13220 continue;
13221 if (! EQ (COERCE_MARKER (val),
13222 Fget (var, Qlast_arrow_position))
13223 || ! (pstr = overlay_arrow_string_or_property (var),
13224 EQ (pstr, Fget (var, Qlast_arrow_string))))
13225 return 1;
13226 }
13227 return 0;
13228 }
13229
13230 /* Mark overlay arrows to be updated on next redisplay. */
13231
13232 static void
13233 update_overlay_arrows (int up_to_date)
13234 {
13235 Lisp_Object vlist;
13236
13237 for (vlist = Voverlay_arrow_variable_list;
13238 CONSP (vlist);
13239 vlist = XCDR (vlist))
13240 {
13241 Lisp_Object var = XCAR (vlist);
13242
13243 if (!SYMBOLP (var))
13244 continue;
13245
13246 if (up_to_date > 0)
13247 {
13248 Lisp_Object val = find_symbol_value (var);
13249 Fput (var, Qlast_arrow_position,
13250 COERCE_MARKER (val));
13251 Fput (var, Qlast_arrow_string,
13252 overlay_arrow_string_or_property (var));
13253 }
13254 else if (up_to_date < 0
13255 || !NILP (Fget (var, Qlast_arrow_position)))
13256 {
13257 Fput (var, Qlast_arrow_position, Qt);
13258 Fput (var, Qlast_arrow_string, Qt);
13259 }
13260 }
13261 }
13262
13263
13264 /* Return overlay arrow string to display at row.
13265 Return integer (bitmap number) for arrow bitmap in left fringe.
13266 Return nil if no overlay arrow. */
13267
13268 static Lisp_Object
13269 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13270 {
13271 Lisp_Object vlist;
13272
13273 for (vlist = Voverlay_arrow_variable_list;
13274 CONSP (vlist);
13275 vlist = XCDR (vlist))
13276 {
13277 Lisp_Object var = XCAR (vlist);
13278 Lisp_Object val;
13279
13280 if (!SYMBOLP (var))
13281 continue;
13282
13283 val = find_symbol_value (var);
13284
13285 if (MARKERP (val)
13286 && current_buffer == XMARKER (val)->buffer
13287 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13288 {
13289 if (FRAME_WINDOW_P (it->f)
13290 /* FIXME: if ROW->reversed_p is set, this should test
13291 the right fringe, not the left one. */
13292 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13293 {
13294 #ifdef HAVE_WINDOW_SYSTEM
13295 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13296 {
13297 int fringe_bitmap;
13298 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
13299 return make_number (fringe_bitmap);
13300 }
13301 #endif
13302 return make_number (-1); /* Use default arrow bitmap. */
13303 }
13304 return overlay_arrow_string_or_property (var);
13305 }
13306 }
13307
13308 return Qnil;
13309 }
13310
13311 /* Return 1 if point moved out of or into a composition. Otherwise
13312 return 0. PREV_BUF and PREV_PT are the last point buffer and
13313 position. BUF and PT are the current point buffer and position. */
13314
13315 static int
13316 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13317 struct buffer *buf, ptrdiff_t pt)
13318 {
13319 ptrdiff_t start, end;
13320 Lisp_Object prop;
13321 Lisp_Object buffer;
13322
13323 XSETBUFFER (buffer, buf);
13324 /* Check a composition at the last point if point moved within the
13325 same buffer. */
13326 if (prev_buf == buf)
13327 {
13328 if (prev_pt == pt)
13329 /* Point didn't move. */
13330 return 0;
13331
13332 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13333 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13334 && composition_valid_p (start, end, prop)
13335 && start < prev_pt && end > prev_pt)
13336 /* The last point was within the composition. Return 1 iff
13337 point moved out of the composition. */
13338 return (pt <= start || pt >= end);
13339 }
13340
13341 /* Check a composition at the current point. */
13342 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13343 && find_composition (pt, -1, &start, &end, &prop, buffer)
13344 && composition_valid_p (start, end, prop)
13345 && start < pt && end > pt);
13346 }
13347
13348 /* Reconsider the clip changes of buffer which is displayed in W. */
13349
13350 static void
13351 reconsider_clip_changes (struct window *w)
13352 {
13353 struct buffer *b = XBUFFER (w->contents);
13354
13355 if (b->clip_changed
13356 && w->window_end_valid
13357 && w->current_matrix->buffer == b
13358 && w->current_matrix->zv == BUF_ZV (b)
13359 && w->current_matrix->begv == BUF_BEGV (b))
13360 b->clip_changed = 0;
13361
13362 /* If display wasn't paused, and W is not a tool bar window, see if
13363 point has been moved into or out of a composition. In that case,
13364 we set b->clip_changed to 1 to force updating the screen. If
13365 b->clip_changed has already been set to 1, we can skip this
13366 check. */
13367 if (!b->clip_changed && w->window_end_valid)
13368 {
13369 ptrdiff_t pt = (w == XWINDOW (selected_window)
13370 ? PT : marker_position (w->pointm));
13371
13372 if ((w->current_matrix->buffer != b || pt != w->last_point)
13373 && check_point_in_composition (w->current_matrix->buffer,
13374 w->last_point, b, pt))
13375 b->clip_changed = 1;
13376 }
13377 }
13378
13379 static void
13380 propagate_buffer_redisplay (void)
13381 { /* Resetting b->text->redisplay is problematic!
13382 We can't just reset it in the case that some window that displays
13383 it has not been redisplayed; and such a window can stay
13384 unredisplayed for a long time if it's currently invisible.
13385 But we do want to reset it at the end of redisplay otherwise
13386 its displayed windows will keep being redisplayed over and over
13387 again.
13388 So we copy all b->text->redisplay flags up to their windows here,
13389 such that mark_window_display_accurate can safely reset
13390 b->text->redisplay. */
13391 Lisp_Object ws = window_list ();
13392 for (; CONSP (ws); ws = XCDR (ws))
13393 {
13394 struct window *thisw = XWINDOW (XCAR (ws));
13395 struct buffer *thisb = XBUFFER (thisw->contents);
13396 if (thisb->text->redisplay)
13397 thisw->redisplay = true;
13398 }
13399 }
13400
13401 #define STOP_POLLING \
13402 do { if (! polling_stopped_here) stop_polling (); \
13403 polling_stopped_here = 1; } while (0)
13404
13405 #define RESUME_POLLING \
13406 do { if (polling_stopped_here) start_polling (); \
13407 polling_stopped_here = 0; } while (0)
13408
13409
13410 /* Perhaps in the future avoid recentering windows if it
13411 is not necessary; currently that causes some problems. */
13412
13413 static void
13414 redisplay_internal (void)
13415 {
13416 struct window *w = XWINDOW (selected_window);
13417 struct window *sw;
13418 struct frame *fr;
13419 int pending;
13420 bool must_finish = 0, match_p;
13421 struct text_pos tlbufpos, tlendpos;
13422 int number_of_visible_frames;
13423 ptrdiff_t count;
13424 struct frame *sf;
13425 int polling_stopped_here = 0;
13426 Lisp_Object tail, frame;
13427
13428 /* True means redisplay has to consider all windows on all
13429 frames. False, only selected_window is considered. */
13430 bool consider_all_windows_p;
13431
13432 /* True means redisplay has to redisplay the miniwindow. */
13433 bool update_miniwindow_p = false;
13434
13435 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13436
13437 /* No redisplay if running in batch mode or frame is not yet fully
13438 initialized, or redisplay is explicitly turned off by setting
13439 Vinhibit_redisplay. */
13440 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13441 || !NILP (Vinhibit_redisplay))
13442 return;
13443
13444 /* Don't examine these until after testing Vinhibit_redisplay.
13445 When Emacs is shutting down, perhaps because its connection to
13446 X has dropped, we should not look at them at all. */
13447 fr = XFRAME (w->frame);
13448 sf = SELECTED_FRAME ();
13449
13450 if (!fr->glyphs_initialized_p)
13451 return;
13452
13453 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13454 if (popup_activated ())
13455 return;
13456 #endif
13457
13458 /* I don't think this happens but let's be paranoid. */
13459 if (redisplaying_p)
13460 return;
13461
13462 /* Record a function that clears redisplaying_p
13463 when we leave this function. */
13464 count = SPECPDL_INDEX ();
13465 record_unwind_protect_void (unwind_redisplay);
13466 redisplaying_p = 1;
13467 specbind (Qinhibit_free_realized_faces, Qnil);
13468
13469 /* Record this function, so it appears on the profiler's backtraces. */
13470 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
13471
13472 FOR_EACH_FRAME (tail, frame)
13473 XFRAME (frame)->already_hscrolled_p = 0;
13474
13475 retry:
13476 /* Remember the currently selected window. */
13477 sw = w;
13478
13479 pending = 0;
13480 last_escape_glyph_frame = NULL;
13481 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13482 last_glyphless_glyph_frame = NULL;
13483 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13484
13485 /* If face_change_count is non-zero, init_iterator will free all
13486 realized faces, which includes the faces referenced from current
13487 matrices. So, we can't reuse current matrices in this case. */
13488 if (face_change_count)
13489 windows_or_buffers_changed = 47;
13490
13491 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13492 && FRAME_TTY (sf)->previous_frame != sf)
13493 {
13494 /* Since frames on a single ASCII terminal share the same
13495 display area, displaying a different frame means redisplay
13496 the whole thing. */
13497 SET_FRAME_GARBAGED (sf);
13498 #ifndef DOS_NT
13499 set_tty_color_mode (FRAME_TTY (sf), sf);
13500 #endif
13501 FRAME_TTY (sf)->previous_frame = sf;
13502 }
13503
13504 /* Set the visible flags for all frames. Do this before checking for
13505 resized or garbaged frames; they want to know if their frames are
13506 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13507 number_of_visible_frames = 0;
13508
13509 FOR_EACH_FRAME (tail, frame)
13510 {
13511 struct frame *f = XFRAME (frame);
13512
13513 if (FRAME_VISIBLE_P (f))
13514 {
13515 ++number_of_visible_frames;
13516 /* Adjust matrices for visible frames only. */
13517 if (f->fonts_changed)
13518 {
13519 adjust_frame_glyphs (f);
13520 f->fonts_changed = 0;
13521 }
13522 /* If cursor type has been changed on the frame
13523 other than selected, consider all frames. */
13524 if (f != sf && f->cursor_type_changed)
13525 update_mode_lines = 31;
13526 }
13527 clear_desired_matrices (f);
13528 }
13529
13530 /* Notice any pending interrupt request to change frame size. */
13531 do_pending_window_change (1);
13532
13533 /* do_pending_window_change could change the selected_window due to
13534 frame resizing which makes the selected window too small. */
13535 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13536 sw = w;
13537
13538 /* Clear frames marked as garbaged. */
13539 clear_garbaged_frames ();
13540
13541 /* Build menubar and tool-bar items. */
13542 if (NILP (Vmemory_full))
13543 prepare_menu_bars ();
13544
13545 reconsider_clip_changes (w);
13546
13547 /* In most cases selected window displays current buffer. */
13548 match_p = XBUFFER (w->contents) == current_buffer;
13549 if (match_p)
13550 {
13551 /* Detect case that we need to write or remove a star in the mode line. */
13552 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13553 w->update_mode_line = 1;
13554
13555 if (mode_line_update_needed (w))
13556 w->update_mode_line = 1;
13557 }
13558
13559 /* Normally the message* functions will have already displayed and
13560 updated the echo area, but the frame may have been trashed, or
13561 the update may have been preempted, so display the echo area
13562 again here. Checking message_cleared_p captures the case that
13563 the echo area should be cleared. */
13564 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13565 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13566 || (message_cleared_p
13567 && minibuf_level == 0
13568 /* If the mini-window is currently selected, this means the
13569 echo-area doesn't show through. */
13570 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13571 {
13572 int window_height_changed_p = echo_area_display (0);
13573
13574 if (message_cleared_p)
13575 update_miniwindow_p = true;
13576
13577 must_finish = 1;
13578
13579 /* If we don't display the current message, don't clear the
13580 message_cleared_p flag, because, if we did, we wouldn't clear
13581 the echo area in the next redisplay which doesn't preserve
13582 the echo area. */
13583 if (!display_last_displayed_message_p)
13584 message_cleared_p = 0;
13585
13586 if (window_height_changed_p)
13587 {
13588 windows_or_buffers_changed = 50;
13589
13590 /* If window configuration was changed, frames may have been
13591 marked garbaged. Clear them or we will experience
13592 surprises wrt scrolling. */
13593 clear_garbaged_frames ();
13594 }
13595 }
13596 else if (EQ (selected_window, minibuf_window)
13597 && (current_buffer->clip_changed || window_outdated (w))
13598 && resize_mini_window (w, 0))
13599 {
13600 /* Resized active mini-window to fit the size of what it is
13601 showing if its contents might have changed. */
13602 must_finish = 1;
13603
13604 /* If window configuration was changed, frames may have been
13605 marked garbaged. Clear them or we will experience
13606 surprises wrt scrolling. */
13607 clear_garbaged_frames ();
13608 }
13609
13610 if (windows_or_buffers_changed && !update_mode_lines)
13611 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13612 only the windows's contents needs to be refreshed, or whether the
13613 mode-lines also need a refresh. */
13614 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
13615 ? REDISPLAY_SOME : 32);
13616
13617 /* If specs for an arrow have changed, do thorough redisplay
13618 to ensure we remove any arrow that should no longer exist. */
13619 if (overlay_arrows_changed_p ())
13620 /* Apparently, this is the only case where we update other windows,
13621 without updating other mode-lines. */
13622 windows_or_buffers_changed = 49;
13623
13624 consider_all_windows_p = (update_mode_lines
13625 || windows_or_buffers_changed);
13626
13627 #define AINC(a,i) \
13628 if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
13629 ASET (a, i, make_number (1 + XINT (AREF (a, i))))
13630
13631 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
13632 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
13633
13634 /* Optimize the case that only the line containing the cursor in the
13635 selected window has changed. Variables starting with this_ are
13636 set in display_line and record information about the line
13637 containing the cursor. */
13638 tlbufpos = this_line_start_pos;
13639 tlendpos = this_line_end_pos;
13640 if (!consider_all_windows_p
13641 && CHARPOS (tlbufpos) > 0
13642 && !w->update_mode_line
13643 && !current_buffer->clip_changed
13644 && !current_buffer->prevent_redisplay_optimizations_p
13645 && FRAME_VISIBLE_P (XFRAME (w->frame))
13646 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13647 && !XFRAME (w->frame)->cursor_type_changed
13648 /* Make sure recorded data applies to current buffer, etc. */
13649 && this_line_buffer == current_buffer
13650 && match_p
13651 && !w->force_start
13652 && !w->optional_new_start
13653 /* Point must be on the line that we have info recorded about. */
13654 && PT >= CHARPOS (tlbufpos)
13655 && PT <= Z - CHARPOS (tlendpos)
13656 /* All text outside that line, including its final newline,
13657 must be unchanged. */
13658 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13659 CHARPOS (tlendpos)))
13660 {
13661 if (CHARPOS (tlbufpos) > BEGV
13662 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13663 && (CHARPOS (tlbufpos) == ZV
13664 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13665 /* Former continuation line has disappeared by becoming empty. */
13666 goto cancel;
13667 else if (window_outdated (w) || MINI_WINDOW_P (w))
13668 {
13669 /* We have to handle the case of continuation around a
13670 wide-column character (see the comment in indent.c around
13671 line 1340).
13672
13673 For instance, in the following case:
13674
13675 -------- Insert --------
13676 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13677 J_I_ ==> J_I_ `^^' are cursors.
13678 ^^ ^^
13679 -------- --------
13680
13681 As we have to redraw the line above, we cannot use this
13682 optimization. */
13683
13684 struct it it;
13685 int line_height_before = this_line_pixel_height;
13686
13687 /* Note that start_display will handle the case that the
13688 line starting at tlbufpos is a continuation line. */
13689 start_display (&it, w, tlbufpos);
13690
13691 /* Implementation note: It this still necessary? */
13692 if (it.current_x != this_line_start_x)
13693 goto cancel;
13694
13695 TRACE ((stderr, "trying display optimization 1\n"));
13696 w->cursor.vpos = -1;
13697 overlay_arrow_seen = 0;
13698 it.vpos = this_line_vpos;
13699 it.current_y = this_line_y;
13700 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13701 display_line (&it);
13702
13703 /* If line contains point, is not continued,
13704 and ends at same distance from eob as before, we win. */
13705 if (w->cursor.vpos >= 0
13706 /* Line is not continued, otherwise this_line_start_pos
13707 would have been set to 0 in display_line. */
13708 && CHARPOS (this_line_start_pos)
13709 /* Line ends as before. */
13710 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13711 /* Line has same height as before. Otherwise other lines
13712 would have to be shifted up or down. */
13713 && this_line_pixel_height == line_height_before)
13714 {
13715 /* If this is not the window's last line, we must adjust
13716 the charstarts of the lines below. */
13717 if (it.current_y < it.last_visible_y)
13718 {
13719 struct glyph_row *row
13720 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13721 ptrdiff_t delta, delta_bytes;
13722
13723 /* We used to distinguish between two cases here,
13724 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13725 when the line ends in a newline or the end of the
13726 buffer's accessible portion. But both cases did
13727 the same, so they were collapsed. */
13728 delta = (Z
13729 - CHARPOS (tlendpos)
13730 - MATRIX_ROW_START_CHARPOS (row));
13731 delta_bytes = (Z_BYTE
13732 - BYTEPOS (tlendpos)
13733 - MATRIX_ROW_START_BYTEPOS (row));
13734
13735 increment_matrix_positions (w->current_matrix,
13736 this_line_vpos + 1,
13737 w->current_matrix->nrows,
13738 delta, delta_bytes);
13739 }
13740
13741 /* If this row displays text now but previously didn't,
13742 or vice versa, w->window_end_vpos may have to be
13743 adjusted. */
13744 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13745 {
13746 if (w->window_end_vpos < this_line_vpos)
13747 w->window_end_vpos = this_line_vpos;
13748 }
13749 else if (w->window_end_vpos == this_line_vpos
13750 && this_line_vpos > 0)
13751 w->window_end_vpos = this_line_vpos - 1;
13752 w->window_end_valid = 0;
13753
13754 /* Update hint: No need to try to scroll in update_window. */
13755 w->desired_matrix->no_scrolling_p = 1;
13756
13757 #ifdef GLYPH_DEBUG
13758 *w->desired_matrix->method = 0;
13759 debug_method_add (w, "optimization 1");
13760 #endif
13761 #ifdef HAVE_WINDOW_SYSTEM
13762 update_window_fringes (w, 0);
13763 #endif
13764 goto update;
13765 }
13766 else
13767 goto cancel;
13768 }
13769 else if (/* Cursor position hasn't changed. */
13770 PT == w->last_point
13771 /* Make sure the cursor was last displayed
13772 in this window. Otherwise we have to reposition it. */
13773
13774 /* PXW: Must be converted to pixels, probably. */
13775 && 0 <= w->cursor.vpos
13776 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13777 {
13778 if (!must_finish)
13779 {
13780 do_pending_window_change (1);
13781 /* If selected_window changed, redisplay again. */
13782 if (WINDOWP (selected_window)
13783 && (w = XWINDOW (selected_window)) != sw)
13784 goto retry;
13785
13786 /* We used to always goto end_of_redisplay here, but this
13787 isn't enough if we have a blinking cursor. */
13788 if (w->cursor_off_p == w->last_cursor_off_p)
13789 goto end_of_redisplay;
13790 }
13791 goto update;
13792 }
13793 /* If highlighting the region, or if the cursor is in the echo area,
13794 then we can't just move the cursor. */
13795 else if (NILP (Vshow_trailing_whitespace)
13796 && !cursor_in_echo_area)
13797 {
13798 struct it it;
13799 struct glyph_row *row;
13800
13801 /* Skip from tlbufpos to PT and see where it is. Note that
13802 PT may be in invisible text. If so, we will end at the
13803 next visible position. */
13804 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13805 NULL, DEFAULT_FACE_ID);
13806 it.current_x = this_line_start_x;
13807 it.current_y = this_line_y;
13808 it.vpos = this_line_vpos;
13809
13810 /* The call to move_it_to stops in front of PT, but
13811 moves over before-strings. */
13812 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13813
13814 if (it.vpos == this_line_vpos
13815 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13816 row->enabled_p))
13817 {
13818 eassert (this_line_vpos == it.vpos);
13819 eassert (this_line_y == it.current_y);
13820 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13821 #ifdef GLYPH_DEBUG
13822 *w->desired_matrix->method = 0;
13823 debug_method_add (w, "optimization 3");
13824 #endif
13825 goto update;
13826 }
13827 else
13828 goto cancel;
13829 }
13830
13831 cancel:
13832 /* Text changed drastically or point moved off of line. */
13833 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
13834 }
13835
13836 CHARPOS (this_line_start_pos) = 0;
13837 ++clear_face_cache_count;
13838 #ifdef HAVE_WINDOW_SYSTEM
13839 ++clear_image_cache_count;
13840 #endif
13841
13842 /* Build desired matrices, and update the display. If
13843 consider_all_windows_p is non-zero, do it for all windows on all
13844 frames. Otherwise do it for selected_window, only. */
13845
13846 if (consider_all_windows_p)
13847 {
13848 FOR_EACH_FRAME (tail, frame)
13849 XFRAME (frame)->updated_p = 0;
13850
13851 propagate_buffer_redisplay ();
13852
13853 FOR_EACH_FRAME (tail, frame)
13854 {
13855 struct frame *f = XFRAME (frame);
13856
13857 /* We don't have to do anything for unselected terminal
13858 frames. */
13859 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13860 && !EQ (FRAME_TTY (f)->top_frame, frame))
13861 continue;
13862
13863 retry_frame:
13864
13865 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13866 {
13867 bool gcscrollbars
13868 /* Only GC scrollbars when we redisplay the whole frame. */
13869 = f->redisplay || !REDISPLAY_SOME_P ();
13870 /* Mark all the scroll bars to be removed; we'll redeem
13871 the ones we want when we redisplay their windows. */
13872 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13873 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13874
13875 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13876 redisplay_windows (FRAME_ROOT_WINDOW (f));
13877 /* Remember that the invisible frames need to be redisplayed next
13878 time they're visible. */
13879 else if (!REDISPLAY_SOME_P ())
13880 f->redisplay = true;
13881
13882 /* The X error handler may have deleted that frame. */
13883 if (!FRAME_LIVE_P (f))
13884 continue;
13885
13886 /* Any scroll bars which redisplay_windows should have
13887 nuked should now go away. */
13888 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13889 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13890
13891 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13892 {
13893 /* If fonts changed on visible frame, display again. */
13894 if (f->fonts_changed)
13895 {
13896 adjust_frame_glyphs (f);
13897 f->fonts_changed = 0;
13898 goto retry_frame;
13899 }
13900
13901 /* See if we have to hscroll. */
13902 if (!f->already_hscrolled_p)
13903 {
13904 f->already_hscrolled_p = 1;
13905 if (hscroll_windows (f->root_window))
13906 goto retry_frame;
13907 }
13908
13909 /* Prevent various kinds of signals during display
13910 update. stdio is not robust about handling
13911 signals, which can cause an apparent I/O error. */
13912 if (interrupt_input)
13913 unrequest_sigio ();
13914 STOP_POLLING;
13915
13916 pending |= update_frame (f, 0, 0);
13917 f->cursor_type_changed = 0;
13918 f->updated_p = 1;
13919 }
13920 }
13921 }
13922
13923 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13924
13925 if (!pending)
13926 {
13927 /* Do the mark_window_display_accurate after all windows have
13928 been redisplayed because this call resets flags in buffers
13929 which are needed for proper redisplay. */
13930 FOR_EACH_FRAME (tail, frame)
13931 {
13932 struct frame *f = XFRAME (frame);
13933 if (f->updated_p)
13934 {
13935 f->redisplay = false;
13936 mark_window_display_accurate (f->root_window, 1);
13937 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13938 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13939 }
13940 }
13941 }
13942 }
13943 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13944 {
13945 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13946 struct frame *mini_frame;
13947
13948 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13949 /* Use list_of_error, not Qerror, so that
13950 we catch only errors and don't run the debugger. */
13951 internal_condition_case_1 (redisplay_window_1, selected_window,
13952 list_of_error,
13953 redisplay_window_error);
13954 if (update_miniwindow_p)
13955 internal_condition_case_1 (redisplay_window_1, mini_window,
13956 list_of_error,
13957 redisplay_window_error);
13958
13959 /* Compare desired and current matrices, perform output. */
13960
13961 update:
13962 /* If fonts changed, display again. */
13963 if (sf->fonts_changed)
13964 goto retry;
13965
13966 /* Prevent various kinds of signals during display update.
13967 stdio is not robust about handling signals,
13968 which can cause an apparent I/O error. */
13969 if (interrupt_input)
13970 unrequest_sigio ();
13971 STOP_POLLING;
13972
13973 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13974 {
13975 if (hscroll_windows (selected_window))
13976 goto retry;
13977
13978 XWINDOW (selected_window)->must_be_updated_p = true;
13979 pending = update_frame (sf, 0, 0);
13980 sf->cursor_type_changed = 0;
13981 }
13982
13983 /* We may have called echo_area_display at the top of this
13984 function. If the echo area is on another frame, that may
13985 have put text on a frame other than the selected one, so the
13986 above call to update_frame would not have caught it. Catch
13987 it here. */
13988 mini_window = FRAME_MINIBUF_WINDOW (sf);
13989 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13990
13991 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13992 {
13993 XWINDOW (mini_window)->must_be_updated_p = true;
13994 pending |= update_frame (mini_frame, 0, 0);
13995 mini_frame->cursor_type_changed = 0;
13996 if (!pending && hscroll_windows (mini_window))
13997 goto retry;
13998 }
13999 }
14000
14001 /* If display was paused because of pending input, make sure we do a
14002 thorough update the next time. */
14003 if (pending)
14004 {
14005 /* Prevent the optimization at the beginning of
14006 redisplay_internal that tries a single-line update of the
14007 line containing the cursor in the selected window. */
14008 CHARPOS (this_line_start_pos) = 0;
14009
14010 /* Let the overlay arrow be updated the next time. */
14011 update_overlay_arrows (0);
14012
14013 /* If we pause after scrolling, some rows in the current
14014 matrices of some windows are not valid. */
14015 if (!WINDOW_FULL_WIDTH_P (w)
14016 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14017 update_mode_lines = 36;
14018 }
14019 else
14020 {
14021 if (!consider_all_windows_p)
14022 {
14023 /* This has already been done above if
14024 consider_all_windows_p is set. */
14025 if (XBUFFER (w->contents)->text->redisplay
14026 && buffer_window_count (XBUFFER (w->contents)) > 1)
14027 /* This can happen if b->text->redisplay was set during
14028 jit-lock. */
14029 propagate_buffer_redisplay ();
14030 mark_window_display_accurate_1 (w, 1);
14031
14032 /* Say overlay arrows are up to date. */
14033 update_overlay_arrows (1);
14034
14035 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14036 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14037 }
14038
14039 update_mode_lines = 0;
14040 windows_or_buffers_changed = 0;
14041 }
14042
14043 /* Start SIGIO interrupts coming again. Having them off during the
14044 code above makes it less likely one will discard output, but not
14045 impossible, since there might be stuff in the system buffer here.
14046 But it is much hairier to try to do anything about that. */
14047 if (interrupt_input)
14048 request_sigio ();
14049 RESUME_POLLING;
14050
14051 /* If a frame has become visible which was not before, redisplay
14052 again, so that we display it. Expose events for such a frame
14053 (which it gets when becoming visible) don't call the parts of
14054 redisplay constructing glyphs, so simply exposing a frame won't
14055 display anything in this case. So, we have to display these
14056 frames here explicitly. */
14057 if (!pending)
14058 {
14059 int new_count = 0;
14060
14061 FOR_EACH_FRAME (tail, frame)
14062 {
14063 if (XFRAME (frame)->visible)
14064 new_count++;
14065 }
14066
14067 if (new_count != number_of_visible_frames)
14068 windows_or_buffers_changed = 52;
14069 }
14070
14071 /* Change frame size now if a change is pending. */
14072 do_pending_window_change (1);
14073
14074 /* If we just did a pending size change, or have additional
14075 visible frames, or selected_window changed, redisplay again. */
14076 if ((windows_or_buffers_changed && !pending)
14077 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14078 goto retry;
14079
14080 /* Clear the face and image caches.
14081
14082 We used to do this only if consider_all_windows_p. But the cache
14083 needs to be cleared if a timer creates images in the current
14084 buffer (e.g. the test case in Bug#6230). */
14085
14086 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14087 {
14088 clear_face_cache (0);
14089 clear_face_cache_count = 0;
14090 }
14091
14092 #ifdef HAVE_WINDOW_SYSTEM
14093 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14094 {
14095 clear_image_caches (Qnil);
14096 clear_image_cache_count = 0;
14097 }
14098 #endif /* HAVE_WINDOW_SYSTEM */
14099
14100 end_of_redisplay:
14101 if (interrupt_input && interrupts_deferred)
14102 request_sigio ();
14103
14104 unbind_to (count, Qnil);
14105 RESUME_POLLING;
14106 }
14107
14108
14109 /* Redisplay, but leave alone any recent echo area message unless
14110 another message has been requested in its place.
14111
14112 This is useful in situations where you need to redisplay but no
14113 user action has occurred, making it inappropriate for the message
14114 area to be cleared. See tracking_off and
14115 wait_reading_process_output for examples of these situations.
14116
14117 FROM_WHERE is an integer saying from where this function was
14118 called. This is useful for debugging. */
14119
14120 void
14121 redisplay_preserve_echo_area (int from_where)
14122 {
14123 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14124
14125 if (!NILP (echo_area_buffer[1]))
14126 {
14127 /* We have a previously displayed message, but no current
14128 message. Redisplay the previous message. */
14129 display_last_displayed_message_p = 1;
14130 redisplay_internal ();
14131 display_last_displayed_message_p = 0;
14132 }
14133 else
14134 redisplay_internal ();
14135
14136 flush_frame (SELECTED_FRAME ());
14137 }
14138
14139
14140 /* Function registered with record_unwind_protect in redisplay_internal. */
14141
14142 static void
14143 unwind_redisplay (void)
14144 {
14145 redisplaying_p = 0;
14146 }
14147
14148
14149 /* Mark the display of leaf window W as accurate or inaccurate.
14150 If ACCURATE_P is non-zero mark display of W as accurate. If
14151 ACCURATE_P is zero, arrange for W to be redisplayed the next
14152 time redisplay_internal is called. */
14153
14154 static void
14155 mark_window_display_accurate_1 (struct window *w, int accurate_p)
14156 {
14157 struct buffer *b = XBUFFER (w->contents);
14158
14159 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14160 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14161 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14162
14163 if (accurate_p)
14164 {
14165 b->clip_changed = false;
14166 b->prevent_redisplay_optimizations_p = false;
14167 eassert (buffer_window_count (b) > 0);
14168 /* Resetting b->text->redisplay is problematic!
14169 In order to make it safer to do it here, redisplay_internal must
14170 have copied all b->text->redisplay to their respective windows. */
14171 b->text->redisplay = false;
14172
14173 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14174 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14175 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14176 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14177
14178 w->current_matrix->buffer = b;
14179 w->current_matrix->begv = BUF_BEGV (b);
14180 w->current_matrix->zv = BUF_ZV (b);
14181
14182 w->last_cursor_vpos = w->cursor.vpos;
14183 w->last_cursor_off_p = w->cursor_off_p;
14184
14185 if (w == XWINDOW (selected_window))
14186 w->last_point = BUF_PT (b);
14187 else
14188 w->last_point = marker_position (w->pointm);
14189
14190 w->window_end_valid = true;
14191 w->update_mode_line = false;
14192 }
14193
14194 w->redisplay = !accurate_p;
14195 }
14196
14197
14198 /* Mark the display of windows in the window tree rooted at WINDOW as
14199 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
14200 windows as accurate. If ACCURATE_P is zero, arrange for windows to
14201 be redisplayed the next time redisplay_internal is called. */
14202
14203 void
14204 mark_window_display_accurate (Lisp_Object window, int accurate_p)
14205 {
14206 struct window *w;
14207
14208 for (; !NILP (window); window = w->next)
14209 {
14210 w = XWINDOW (window);
14211 if (WINDOWP (w->contents))
14212 mark_window_display_accurate (w->contents, accurate_p);
14213 else
14214 mark_window_display_accurate_1 (w, accurate_p);
14215 }
14216
14217 if (accurate_p)
14218 update_overlay_arrows (1);
14219 else
14220 /* Force a thorough redisplay the next time by setting
14221 last_arrow_position and last_arrow_string to t, which is
14222 unequal to any useful value of Voverlay_arrow_... */
14223 update_overlay_arrows (-1);
14224 }
14225
14226
14227 /* Return value in display table DP (Lisp_Char_Table *) for character
14228 C. Since a display table doesn't have any parent, we don't have to
14229 follow parent. Do not call this function directly but use the
14230 macro DISP_CHAR_VECTOR. */
14231
14232 Lisp_Object
14233 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14234 {
14235 Lisp_Object val;
14236
14237 if (ASCII_CHAR_P (c))
14238 {
14239 val = dp->ascii;
14240 if (SUB_CHAR_TABLE_P (val))
14241 val = XSUB_CHAR_TABLE (val)->contents[c];
14242 }
14243 else
14244 {
14245 Lisp_Object table;
14246
14247 XSETCHAR_TABLE (table, dp);
14248 val = char_table_ref (table, c);
14249 }
14250 if (NILP (val))
14251 val = dp->defalt;
14252 return val;
14253 }
14254
14255
14256 \f
14257 /***********************************************************************
14258 Window Redisplay
14259 ***********************************************************************/
14260
14261 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14262
14263 static void
14264 redisplay_windows (Lisp_Object window)
14265 {
14266 while (!NILP (window))
14267 {
14268 struct window *w = XWINDOW (window);
14269
14270 if (WINDOWP (w->contents))
14271 redisplay_windows (w->contents);
14272 else if (BUFFERP (w->contents))
14273 {
14274 displayed_buffer = XBUFFER (w->contents);
14275 /* Use list_of_error, not Qerror, so that
14276 we catch only errors and don't run the debugger. */
14277 internal_condition_case_1 (redisplay_window_0, window,
14278 list_of_error,
14279 redisplay_window_error);
14280 }
14281
14282 window = w->next;
14283 }
14284 }
14285
14286 static Lisp_Object
14287 redisplay_window_error (Lisp_Object ignore)
14288 {
14289 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14290 return Qnil;
14291 }
14292
14293 static Lisp_Object
14294 redisplay_window_0 (Lisp_Object window)
14295 {
14296 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14297 redisplay_window (window, false);
14298 return Qnil;
14299 }
14300
14301 static Lisp_Object
14302 redisplay_window_1 (Lisp_Object window)
14303 {
14304 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14305 redisplay_window (window, true);
14306 return Qnil;
14307 }
14308 \f
14309
14310 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14311 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14312 which positions recorded in ROW differ from current buffer
14313 positions.
14314
14315 Return 0 if cursor is not on this row, 1 otherwise. */
14316
14317 static int
14318 set_cursor_from_row (struct window *w, struct glyph_row *row,
14319 struct glyph_matrix *matrix,
14320 ptrdiff_t delta, ptrdiff_t delta_bytes,
14321 int dy, int dvpos)
14322 {
14323 struct glyph *glyph = row->glyphs[TEXT_AREA];
14324 struct glyph *end = glyph + row->used[TEXT_AREA];
14325 struct glyph *cursor = NULL;
14326 /* The last known character position in row. */
14327 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14328 int x = row->x;
14329 ptrdiff_t pt_old = PT - delta;
14330 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14331 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14332 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14333 /* A glyph beyond the edge of TEXT_AREA which we should never
14334 touch. */
14335 struct glyph *glyphs_end = end;
14336 /* Non-zero means we've found a match for cursor position, but that
14337 glyph has the avoid_cursor_p flag set. */
14338 int match_with_avoid_cursor = 0;
14339 /* Non-zero means we've seen at least one glyph that came from a
14340 display string. */
14341 int string_seen = 0;
14342 /* Largest and smallest buffer positions seen so far during scan of
14343 glyph row. */
14344 ptrdiff_t bpos_max = pos_before;
14345 ptrdiff_t bpos_min = pos_after;
14346 /* Last buffer position covered by an overlay string with an integer
14347 `cursor' property. */
14348 ptrdiff_t bpos_covered = 0;
14349 /* Non-zero means the display string on which to display the cursor
14350 comes from a text property, not from an overlay. */
14351 int string_from_text_prop = 0;
14352
14353 /* Don't even try doing anything if called for a mode-line or
14354 header-line row, since the rest of the code isn't prepared to
14355 deal with such calamities. */
14356 eassert (!row->mode_line_p);
14357 if (row->mode_line_p)
14358 return 0;
14359
14360 /* Skip over glyphs not having an object at the start and the end of
14361 the row. These are special glyphs like truncation marks on
14362 terminal frames. */
14363 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14364 {
14365 if (!row->reversed_p)
14366 {
14367 while (glyph < end
14368 && INTEGERP (glyph->object)
14369 && glyph->charpos < 0)
14370 {
14371 x += glyph->pixel_width;
14372 ++glyph;
14373 }
14374 while (end > glyph
14375 && INTEGERP ((end - 1)->object)
14376 /* CHARPOS is zero for blanks and stretch glyphs
14377 inserted by extend_face_to_end_of_line. */
14378 && (end - 1)->charpos <= 0)
14379 --end;
14380 glyph_before = glyph - 1;
14381 glyph_after = end;
14382 }
14383 else
14384 {
14385 struct glyph *g;
14386
14387 /* If the glyph row is reversed, we need to process it from back
14388 to front, so swap the edge pointers. */
14389 glyphs_end = end = glyph - 1;
14390 glyph += row->used[TEXT_AREA] - 1;
14391
14392 while (glyph > end + 1
14393 && INTEGERP (glyph->object)
14394 && glyph->charpos < 0)
14395 {
14396 --glyph;
14397 x -= glyph->pixel_width;
14398 }
14399 if (INTEGERP (glyph->object) && glyph->charpos < 0)
14400 --glyph;
14401 /* By default, in reversed rows we put the cursor on the
14402 rightmost (first in the reading order) glyph. */
14403 for (g = end + 1; g < glyph; g++)
14404 x += g->pixel_width;
14405 while (end < glyph
14406 && INTEGERP ((end + 1)->object)
14407 && (end + 1)->charpos <= 0)
14408 ++end;
14409 glyph_before = glyph + 1;
14410 glyph_after = end;
14411 }
14412 }
14413 else if (row->reversed_p)
14414 {
14415 /* In R2L rows that don't display text, put the cursor on the
14416 rightmost glyph. Case in point: an empty last line that is
14417 part of an R2L paragraph. */
14418 cursor = end - 1;
14419 /* Avoid placing the cursor on the last glyph of the row, where
14420 on terminal frames we hold the vertical border between
14421 adjacent windows. */
14422 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
14423 && !WINDOW_RIGHTMOST_P (w)
14424 && cursor == row->glyphs[LAST_AREA] - 1)
14425 cursor--;
14426 x = -1; /* will be computed below, at label compute_x */
14427 }
14428
14429 /* Step 1: Try to find the glyph whose character position
14430 corresponds to point. If that's not possible, find 2 glyphs
14431 whose character positions are the closest to point, one before
14432 point, the other after it. */
14433 if (!row->reversed_p)
14434 while (/* not marched to end of glyph row */
14435 glyph < end
14436 /* glyph was not inserted by redisplay for internal purposes */
14437 && !INTEGERP (glyph->object))
14438 {
14439 if (BUFFERP (glyph->object))
14440 {
14441 ptrdiff_t dpos = glyph->charpos - pt_old;
14442
14443 if (glyph->charpos > bpos_max)
14444 bpos_max = glyph->charpos;
14445 if (glyph->charpos < bpos_min)
14446 bpos_min = glyph->charpos;
14447 if (!glyph->avoid_cursor_p)
14448 {
14449 /* If we hit point, we've found the glyph on which to
14450 display the cursor. */
14451 if (dpos == 0)
14452 {
14453 match_with_avoid_cursor = 0;
14454 break;
14455 }
14456 /* See if we've found a better approximation to
14457 POS_BEFORE or to POS_AFTER. */
14458 if (0 > dpos && dpos > pos_before - pt_old)
14459 {
14460 pos_before = glyph->charpos;
14461 glyph_before = glyph;
14462 }
14463 else if (0 < dpos && dpos < pos_after - pt_old)
14464 {
14465 pos_after = glyph->charpos;
14466 glyph_after = glyph;
14467 }
14468 }
14469 else if (dpos == 0)
14470 match_with_avoid_cursor = 1;
14471 }
14472 else if (STRINGP (glyph->object))
14473 {
14474 Lisp_Object chprop;
14475 ptrdiff_t glyph_pos = glyph->charpos;
14476
14477 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14478 glyph->object);
14479 if (!NILP (chprop))
14480 {
14481 /* If the string came from a `display' text property,
14482 look up the buffer position of that property and
14483 use that position to update bpos_max, as if we
14484 actually saw such a position in one of the row's
14485 glyphs. This helps with supporting integer values
14486 of `cursor' property on the display string in
14487 situations where most or all of the row's buffer
14488 text is completely covered by display properties,
14489 so that no glyph with valid buffer positions is
14490 ever seen in the row. */
14491 ptrdiff_t prop_pos =
14492 string_buffer_position_lim (glyph->object, pos_before,
14493 pos_after, 0);
14494
14495 if (prop_pos >= pos_before)
14496 bpos_max = prop_pos;
14497 }
14498 if (INTEGERP (chprop))
14499 {
14500 bpos_covered = bpos_max + XINT (chprop);
14501 /* If the `cursor' property covers buffer positions up
14502 to and including point, we should display cursor on
14503 this glyph. Note that, if a `cursor' property on one
14504 of the string's characters has an integer value, we
14505 will break out of the loop below _before_ we get to
14506 the position match above. IOW, integer values of
14507 the `cursor' property override the "exact match for
14508 point" strategy of positioning the cursor. */
14509 /* Implementation note: bpos_max == pt_old when, e.g.,
14510 we are in an empty line, where bpos_max is set to
14511 MATRIX_ROW_START_CHARPOS, see above. */
14512 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14513 {
14514 cursor = glyph;
14515 break;
14516 }
14517 }
14518
14519 string_seen = 1;
14520 }
14521 x += glyph->pixel_width;
14522 ++glyph;
14523 }
14524 else if (glyph > end) /* row is reversed */
14525 while (!INTEGERP (glyph->object))
14526 {
14527 if (BUFFERP (glyph->object))
14528 {
14529 ptrdiff_t dpos = glyph->charpos - pt_old;
14530
14531 if (glyph->charpos > bpos_max)
14532 bpos_max = glyph->charpos;
14533 if (glyph->charpos < bpos_min)
14534 bpos_min = glyph->charpos;
14535 if (!glyph->avoid_cursor_p)
14536 {
14537 if (dpos == 0)
14538 {
14539 match_with_avoid_cursor = 0;
14540 break;
14541 }
14542 if (0 > dpos && dpos > pos_before - pt_old)
14543 {
14544 pos_before = glyph->charpos;
14545 glyph_before = glyph;
14546 }
14547 else if (0 < dpos && dpos < pos_after - pt_old)
14548 {
14549 pos_after = glyph->charpos;
14550 glyph_after = glyph;
14551 }
14552 }
14553 else if (dpos == 0)
14554 match_with_avoid_cursor = 1;
14555 }
14556 else if (STRINGP (glyph->object))
14557 {
14558 Lisp_Object chprop;
14559 ptrdiff_t glyph_pos = glyph->charpos;
14560
14561 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14562 glyph->object);
14563 if (!NILP (chprop))
14564 {
14565 ptrdiff_t prop_pos =
14566 string_buffer_position_lim (glyph->object, pos_before,
14567 pos_after, 0);
14568
14569 if (prop_pos >= pos_before)
14570 bpos_max = prop_pos;
14571 }
14572 if (INTEGERP (chprop))
14573 {
14574 bpos_covered = bpos_max + XINT (chprop);
14575 /* If the `cursor' property covers buffer positions up
14576 to and including point, we should display cursor on
14577 this glyph. */
14578 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14579 {
14580 cursor = glyph;
14581 break;
14582 }
14583 }
14584 string_seen = 1;
14585 }
14586 --glyph;
14587 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14588 {
14589 x--; /* can't use any pixel_width */
14590 break;
14591 }
14592 x -= glyph->pixel_width;
14593 }
14594
14595 /* Step 2: If we didn't find an exact match for point, we need to
14596 look for a proper place to put the cursor among glyphs between
14597 GLYPH_BEFORE and GLYPH_AFTER. */
14598 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14599 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14600 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
14601 {
14602 /* An empty line has a single glyph whose OBJECT is zero and
14603 whose CHARPOS is the position of a newline on that line.
14604 Note that on a TTY, there are more glyphs after that, which
14605 were produced by extend_face_to_end_of_line, but their
14606 CHARPOS is zero or negative. */
14607 int empty_line_p =
14608 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14609 && INTEGERP (glyph->object) && glyph->charpos > 0
14610 /* On a TTY, continued and truncated rows also have a glyph at
14611 their end whose OBJECT is zero and whose CHARPOS is
14612 positive (the continuation and truncation glyphs), but such
14613 rows are obviously not "empty". */
14614 && !(row->continued_p || row->truncated_on_right_p);
14615
14616 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14617 {
14618 ptrdiff_t ellipsis_pos;
14619
14620 /* Scan back over the ellipsis glyphs. */
14621 if (!row->reversed_p)
14622 {
14623 ellipsis_pos = (glyph - 1)->charpos;
14624 while (glyph > row->glyphs[TEXT_AREA]
14625 && (glyph - 1)->charpos == ellipsis_pos)
14626 glyph--, x -= glyph->pixel_width;
14627 /* That loop always goes one position too far, including
14628 the glyph before the ellipsis. So scan forward over
14629 that one. */
14630 x += glyph->pixel_width;
14631 glyph++;
14632 }
14633 else /* row is reversed */
14634 {
14635 ellipsis_pos = (glyph + 1)->charpos;
14636 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14637 && (glyph + 1)->charpos == ellipsis_pos)
14638 glyph++, x += glyph->pixel_width;
14639 x -= glyph->pixel_width;
14640 glyph--;
14641 }
14642 }
14643 else if (match_with_avoid_cursor)
14644 {
14645 cursor = glyph_after;
14646 x = -1;
14647 }
14648 else if (string_seen)
14649 {
14650 int incr = row->reversed_p ? -1 : +1;
14651
14652 /* Need to find the glyph that came out of a string which is
14653 present at point. That glyph is somewhere between
14654 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14655 positioned between POS_BEFORE and POS_AFTER in the
14656 buffer. */
14657 struct glyph *start, *stop;
14658 ptrdiff_t pos = pos_before;
14659
14660 x = -1;
14661
14662 /* If the row ends in a newline from a display string,
14663 reordering could have moved the glyphs belonging to the
14664 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14665 in this case we extend the search to the last glyph in
14666 the row that was not inserted by redisplay. */
14667 if (row->ends_in_newline_from_string_p)
14668 {
14669 glyph_after = end;
14670 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14671 }
14672
14673 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14674 correspond to POS_BEFORE and POS_AFTER, respectively. We
14675 need START and STOP in the order that corresponds to the
14676 row's direction as given by its reversed_p flag. If the
14677 directionality of characters between POS_BEFORE and
14678 POS_AFTER is the opposite of the row's base direction,
14679 these characters will have been reordered for display,
14680 and we need to reverse START and STOP. */
14681 if (!row->reversed_p)
14682 {
14683 start = min (glyph_before, glyph_after);
14684 stop = max (glyph_before, glyph_after);
14685 }
14686 else
14687 {
14688 start = max (glyph_before, glyph_after);
14689 stop = min (glyph_before, glyph_after);
14690 }
14691 for (glyph = start + incr;
14692 row->reversed_p ? glyph > stop : glyph < stop; )
14693 {
14694
14695 /* Any glyphs that come from the buffer are here because
14696 of bidi reordering. Skip them, and only pay
14697 attention to glyphs that came from some string. */
14698 if (STRINGP (glyph->object))
14699 {
14700 Lisp_Object str;
14701 ptrdiff_t tem;
14702 /* If the display property covers the newline, we
14703 need to search for it one position farther. */
14704 ptrdiff_t lim = pos_after
14705 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14706
14707 string_from_text_prop = 0;
14708 str = glyph->object;
14709 tem = string_buffer_position_lim (str, pos, lim, 0);
14710 if (tem == 0 /* from overlay */
14711 || pos <= tem)
14712 {
14713 /* If the string from which this glyph came is
14714 found in the buffer at point, or at position
14715 that is closer to point than pos_after, then
14716 we've found the glyph we've been looking for.
14717 If it comes from an overlay (tem == 0), and
14718 it has the `cursor' property on one of its
14719 glyphs, record that glyph as a candidate for
14720 displaying the cursor. (As in the
14721 unidirectional version, we will display the
14722 cursor on the last candidate we find.) */
14723 if (tem == 0
14724 || tem == pt_old
14725 || (tem - pt_old > 0 && tem < pos_after))
14726 {
14727 /* The glyphs from this string could have
14728 been reordered. Find the one with the
14729 smallest string position. Or there could
14730 be a character in the string with the
14731 `cursor' property, which means display
14732 cursor on that character's glyph. */
14733 ptrdiff_t strpos = glyph->charpos;
14734
14735 if (tem)
14736 {
14737 cursor = glyph;
14738 string_from_text_prop = 1;
14739 }
14740 for ( ;
14741 (row->reversed_p ? glyph > stop : glyph < stop)
14742 && EQ (glyph->object, str);
14743 glyph += incr)
14744 {
14745 Lisp_Object cprop;
14746 ptrdiff_t gpos = glyph->charpos;
14747
14748 cprop = Fget_char_property (make_number (gpos),
14749 Qcursor,
14750 glyph->object);
14751 if (!NILP (cprop))
14752 {
14753 cursor = glyph;
14754 break;
14755 }
14756 if (tem && glyph->charpos < strpos)
14757 {
14758 strpos = glyph->charpos;
14759 cursor = glyph;
14760 }
14761 }
14762
14763 if (tem == pt_old
14764 || (tem - pt_old > 0 && tem < pos_after))
14765 goto compute_x;
14766 }
14767 if (tem)
14768 pos = tem + 1; /* don't find previous instances */
14769 }
14770 /* This string is not what we want; skip all of the
14771 glyphs that came from it. */
14772 while ((row->reversed_p ? glyph > stop : glyph < stop)
14773 && EQ (glyph->object, str))
14774 glyph += incr;
14775 }
14776 else
14777 glyph += incr;
14778 }
14779
14780 /* If we reached the end of the line, and END was from a string,
14781 the cursor is not on this line. */
14782 if (cursor == NULL
14783 && (row->reversed_p ? glyph <= end : glyph >= end)
14784 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14785 && STRINGP (end->object)
14786 && row->continued_p)
14787 return 0;
14788 }
14789 /* A truncated row may not include PT among its character positions.
14790 Setting the cursor inside the scroll margin will trigger
14791 recalculation of hscroll in hscroll_window_tree. But if a
14792 display string covers point, defer to the string-handling
14793 code below to figure this out. */
14794 else if (row->truncated_on_left_p && pt_old < bpos_min)
14795 {
14796 cursor = glyph_before;
14797 x = -1;
14798 }
14799 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14800 /* Zero-width characters produce no glyphs. */
14801 || (!empty_line_p
14802 && (row->reversed_p
14803 ? glyph_after > glyphs_end
14804 : glyph_after < glyphs_end)))
14805 {
14806 cursor = glyph_after;
14807 x = -1;
14808 }
14809 }
14810
14811 compute_x:
14812 if (cursor != NULL)
14813 glyph = cursor;
14814 else if (glyph == glyphs_end
14815 && pos_before == pos_after
14816 && STRINGP ((row->reversed_p
14817 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14818 : row->glyphs[TEXT_AREA])->object))
14819 {
14820 /* If all the glyphs of this row came from strings, put the
14821 cursor on the first glyph of the row. This avoids having the
14822 cursor outside of the text area in this very rare and hard
14823 use case. */
14824 glyph =
14825 row->reversed_p
14826 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14827 : row->glyphs[TEXT_AREA];
14828 }
14829 if (x < 0)
14830 {
14831 struct glyph *g;
14832
14833 /* Need to compute x that corresponds to GLYPH. */
14834 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14835 {
14836 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14837 emacs_abort ();
14838 x += g->pixel_width;
14839 }
14840 }
14841
14842 /* ROW could be part of a continued line, which, under bidi
14843 reordering, might have other rows whose start and end charpos
14844 occlude point. Only set w->cursor if we found a better
14845 approximation to the cursor position than we have from previously
14846 examined candidate rows belonging to the same continued line. */
14847 if (/* We already have a candidate row. */
14848 w->cursor.vpos >= 0
14849 /* That candidate is not the row we are processing. */
14850 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14851 /* Make sure cursor.vpos specifies a row whose start and end
14852 charpos occlude point, and it is valid candidate for being a
14853 cursor-row. This is because some callers of this function
14854 leave cursor.vpos at the row where the cursor was displayed
14855 during the last redisplay cycle. */
14856 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14857 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14858 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14859 {
14860 struct glyph *g1
14861 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14862
14863 /* Don't consider glyphs that are outside TEXT_AREA. */
14864 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14865 return 0;
14866 /* Keep the candidate whose buffer position is the closest to
14867 point or has the `cursor' property. */
14868 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
14869 w->cursor.hpos >= 0
14870 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14871 && ((BUFFERP (g1->object)
14872 && (g1->charpos == pt_old /* An exact match always wins. */
14873 || (BUFFERP (glyph->object)
14874 && eabs (g1->charpos - pt_old)
14875 < eabs (glyph->charpos - pt_old))))
14876 /* Previous candidate is a glyph from a string that has
14877 a non-nil `cursor' property. */
14878 || (STRINGP (g1->object)
14879 && (!NILP (Fget_char_property (make_number (g1->charpos),
14880 Qcursor, g1->object))
14881 /* Previous candidate is from the same display
14882 string as this one, and the display string
14883 came from a text property. */
14884 || (EQ (g1->object, glyph->object)
14885 && string_from_text_prop)
14886 /* this candidate is from newline and its
14887 position is not an exact match */
14888 || (INTEGERP (glyph->object)
14889 && glyph->charpos != pt_old)))))
14890 return 0;
14891 /* If this candidate gives an exact match, use that. */
14892 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14893 /* If this candidate is a glyph created for the
14894 terminating newline of a line, and point is on that
14895 newline, it wins because it's an exact match. */
14896 || (!row->continued_p
14897 && INTEGERP (glyph->object)
14898 && glyph->charpos == 0
14899 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14900 /* Otherwise, keep the candidate that comes from a row
14901 spanning less buffer positions. This may win when one or
14902 both candidate positions are on glyphs that came from
14903 display strings, for which we cannot compare buffer
14904 positions. */
14905 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14906 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14907 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14908 return 0;
14909 }
14910 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14911 w->cursor.x = x;
14912 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14913 w->cursor.y = row->y + dy;
14914
14915 if (w == XWINDOW (selected_window))
14916 {
14917 if (!row->continued_p
14918 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14919 && row->x == 0)
14920 {
14921 this_line_buffer = XBUFFER (w->contents);
14922
14923 CHARPOS (this_line_start_pos)
14924 = MATRIX_ROW_START_CHARPOS (row) + delta;
14925 BYTEPOS (this_line_start_pos)
14926 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14927
14928 CHARPOS (this_line_end_pos)
14929 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14930 BYTEPOS (this_line_end_pos)
14931 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14932
14933 this_line_y = w->cursor.y;
14934 this_line_pixel_height = row->height;
14935 this_line_vpos = w->cursor.vpos;
14936 this_line_start_x = row->x;
14937 }
14938 else
14939 CHARPOS (this_line_start_pos) = 0;
14940 }
14941
14942 return 1;
14943 }
14944
14945
14946 /* Run window scroll functions, if any, for WINDOW with new window
14947 start STARTP. Sets the window start of WINDOW to that position.
14948
14949 We assume that the window's buffer is really current. */
14950
14951 static struct text_pos
14952 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14953 {
14954 struct window *w = XWINDOW (window);
14955 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14956
14957 eassert (current_buffer == XBUFFER (w->contents));
14958
14959 if (!NILP (Vwindow_scroll_functions))
14960 {
14961 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14962 make_number (CHARPOS (startp)));
14963 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14964 /* In case the hook functions switch buffers. */
14965 set_buffer_internal (XBUFFER (w->contents));
14966 }
14967
14968 return startp;
14969 }
14970
14971
14972 /* Make sure the line containing the cursor is fully visible.
14973 A value of 1 means there is nothing to be done.
14974 (Either the line is fully visible, or it cannot be made so,
14975 or we cannot tell.)
14976
14977 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14978 is higher than window.
14979
14980 A value of 0 means the caller should do scrolling
14981 as if point had gone off the screen. */
14982
14983 static int
14984 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14985 {
14986 struct glyph_matrix *matrix;
14987 struct glyph_row *row;
14988 int window_height;
14989
14990 if (!make_cursor_line_fully_visible_p)
14991 return 1;
14992
14993 /* It's not always possible to find the cursor, e.g, when a window
14994 is full of overlay strings. Don't do anything in that case. */
14995 if (w->cursor.vpos < 0)
14996 return 1;
14997
14998 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14999 row = MATRIX_ROW (matrix, w->cursor.vpos);
15000
15001 /* If the cursor row is not partially visible, there's nothing to do. */
15002 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15003 return 1;
15004
15005 /* If the row the cursor is in is taller than the window's height,
15006 it's not clear what to do, so do nothing. */
15007 window_height = window_box_height (w);
15008 if (row->height >= window_height)
15009 {
15010 if (!force_p || MINI_WINDOW_P (w)
15011 || w->vscroll || w->cursor.vpos == 0)
15012 return 1;
15013 }
15014 return 0;
15015 }
15016
15017
15018 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15019 non-zero means only WINDOW is redisplayed in redisplay_internal.
15020 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15021 in redisplay_window to bring a partially visible line into view in
15022 the case that only the cursor has moved.
15023
15024 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
15025 last screen line's vertical height extends past the end of the screen.
15026
15027 Value is
15028
15029 1 if scrolling succeeded
15030
15031 0 if scrolling didn't find point.
15032
15033 -1 if new fonts have been loaded so that we must interrupt
15034 redisplay, adjust glyph matrices, and try again. */
15035
15036 enum
15037 {
15038 SCROLLING_SUCCESS,
15039 SCROLLING_FAILED,
15040 SCROLLING_NEED_LARGER_MATRICES
15041 };
15042
15043 /* If scroll-conservatively is more than this, never recenter.
15044
15045 If you change this, don't forget to update the doc string of
15046 `scroll-conservatively' and the Emacs manual. */
15047 #define SCROLL_LIMIT 100
15048
15049 static int
15050 try_scrolling (Lisp_Object window, int just_this_one_p,
15051 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15052 int temp_scroll_step, int last_line_misfit)
15053 {
15054 struct window *w = XWINDOW (window);
15055 struct frame *f = XFRAME (w->frame);
15056 struct text_pos pos, startp;
15057 struct it it;
15058 int this_scroll_margin, scroll_max, rc, height;
15059 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
15060 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
15061 Lisp_Object aggressive;
15062 /* We will never try scrolling more than this number of lines. */
15063 int scroll_limit = SCROLL_LIMIT;
15064 int frame_line_height = default_line_pixel_height (w);
15065 int window_total_lines
15066 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15067
15068 #ifdef GLYPH_DEBUG
15069 debug_method_add (w, "try_scrolling");
15070 #endif
15071
15072 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15073
15074 /* Compute scroll margin height in pixels. We scroll when point is
15075 within this distance from the top or bottom of the window. */
15076 if (scroll_margin > 0)
15077 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
15078 * frame_line_height;
15079 else
15080 this_scroll_margin = 0;
15081
15082 /* Force arg_scroll_conservatively to have a reasonable value, to
15083 avoid scrolling too far away with slow move_it_* functions. Note
15084 that the user can supply scroll-conservatively equal to
15085 `most-positive-fixnum', which can be larger than INT_MAX. */
15086 if (arg_scroll_conservatively > scroll_limit)
15087 {
15088 arg_scroll_conservatively = scroll_limit + 1;
15089 scroll_max = scroll_limit * frame_line_height;
15090 }
15091 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15092 /* Compute how much we should try to scroll maximally to bring
15093 point into view. */
15094 scroll_max = (max (scroll_step,
15095 max (arg_scroll_conservatively, temp_scroll_step))
15096 * frame_line_height);
15097 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15098 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15099 /* We're trying to scroll because of aggressive scrolling but no
15100 scroll_step is set. Choose an arbitrary one. */
15101 scroll_max = 10 * frame_line_height;
15102 else
15103 scroll_max = 0;
15104
15105 too_near_end:
15106
15107 /* Decide whether to scroll down. */
15108 if (PT > CHARPOS (startp))
15109 {
15110 int scroll_margin_y;
15111
15112 /* Compute the pixel ypos of the scroll margin, then move IT to
15113 either that ypos or PT, whichever comes first. */
15114 start_display (&it, w, startp);
15115 scroll_margin_y = it.last_visible_y - this_scroll_margin
15116 - frame_line_height * extra_scroll_margin_lines;
15117 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15118 (MOVE_TO_POS | MOVE_TO_Y));
15119
15120 if (PT > CHARPOS (it.current.pos))
15121 {
15122 int y0 = line_bottom_y (&it);
15123 /* Compute how many pixels below window bottom to stop searching
15124 for PT. This avoids costly search for PT that is far away if
15125 the user limited scrolling by a small number of lines, but
15126 always finds PT if scroll_conservatively is set to a large
15127 number, such as most-positive-fixnum. */
15128 int slack = max (scroll_max, 10 * frame_line_height);
15129 int y_to_move = it.last_visible_y + slack;
15130
15131 /* Compute the distance from the scroll margin to PT or to
15132 the scroll limit, whichever comes first. This should
15133 include the height of the cursor line, to make that line
15134 fully visible. */
15135 move_it_to (&it, PT, -1, y_to_move,
15136 -1, MOVE_TO_POS | MOVE_TO_Y);
15137 dy = line_bottom_y (&it) - y0;
15138
15139 if (dy > scroll_max)
15140 return SCROLLING_FAILED;
15141
15142 if (dy > 0)
15143 scroll_down_p = 1;
15144 }
15145 }
15146
15147 if (scroll_down_p)
15148 {
15149 /* Point is in or below the bottom scroll margin, so move the
15150 window start down. If scrolling conservatively, move it just
15151 enough down to make point visible. If scroll_step is set,
15152 move it down by scroll_step. */
15153 if (arg_scroll_conservatively)
15154 amount_to_scroll
15155 = min (max (dy, frame_line_height),
15156 frame_line_height * arg_scroll_conservatively);
15157 else if (scroll_step || temp_scroll_step)
15158 amount_to_scroll = scroll_max;
15159 else
15160 {
15161 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15162 height = WINDOW_BOX_TEXT_HEIGHT (w);
15163 if (NUMBERP (aggressive))
15164 {
15165 double float_amount = XFLOATINT (aggressive) * height;
15166 int aggressive_scroll = float_amount;
15167 if (aggressive_scroll == 0 && float_amount > 0)
15168 aggressive_scroll = 1;
15169 /* Don't let point enter the scroll margin near top of
15170 the window. This could happen if the value of
15171 scroll_up_aggressively is too large and there are
15172 non-zero margins, because scroll_up_aggressively
15173 means put point that fraction of window height
15174 _from_the_bottom_margin_. */
15175 if (aggressive_scroll + 2*this_scroll_margin > height)
15176 aggressive_scroll = height - 2*this_scroll_margin;
15177 amount_to_scroll = dy + aggressive_scroll;
15178 }
15179 }
15180
15181 if (amount_to_scroll <= 0)
15182 return SCROLLING_FAILED;
15183
15184 start_display (&it, w, startp);
15185 if (arg_scroll_conservatively <= scroll_limit)
15186 move_it_vertically (&it, amount_to_scroll);
15187 else
15188 {
15189 /* Extra precision for users who set scroll-conservatively
15190 to a large number: make sure the amount we scroll
15191 the window start is never less than amount_to_scroll,
15192 which was computed as distance from window bottom to
15193 point. This matters when lines at window top and lines
15194 below window bottom have different height. */
15195 struct it it1;
15196 void *it1data = NULL;
15197 /* We use a temporary it1 because line_bottom_y can modify
15198 its argument, if it moves one line down; see there. */
15199 int start_y;
15200
15201 SAVE_IT (it1, it, it1data);
15202 start_y = line_bottom_y (&it1);
15203 do {
15204 RESTORE_IT (&it, &it, it1data);
15205 move_it_by_lines (&it, 1);
15206 SAVE_IT (it1, it, it1data);
15207 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
15208 }
15209
15210 /* If STARTP is unchanged, move it down another screen line. */
15211 if (CHARPOS (it.current.pos) == CHARPOS (startp))
15212 move_it_by_lines (&it, 1);
15213 startp = it.current.pos;
15214 }
15215 else
15216 {
15217 struct text_pos scroll_margin_pos = startp;
15218 int y_offset = 0;
15219
15220 /* See if point is inside the scroll margin at the top of the
15221 window. */
15222 if (this_scroll_margin)
15223 {
15224 int y_start;
15225
15226 start_display (&it, w, startp);
15227 y_start = it.current_y;
15228 move_it_vertically (&it, this_scroll_margin);
15229 scroll_margin_pos = it.current.pos;
15230 /* If we didn't move enough before hitting ZV, request
15231 additional amount of scroll, to move point out of the
15232 scroll margin. */
15233 if (IT_CHARPOS (it) == ZV
15234 && it.current_y - y_start < this_scroll_margin)
15235 y_offset = this_scroll_margin - (it.current_y - y_start);
15236 }
15237
15238 if (PT < CHARPOS (scroll_margin_pos))
15239 {
15240 /* Point is in the scroll margin at the top of the window or
15241 above what is displayed in the window. */
15242 int y0, y_to_move;
15243
15244 /* Compute the vertical distance from PT to the scroll
15245 margin position. Move as far as scroll_max allows, or
15246 one screenful, or 10 screen lines, whichever is largest.
15247 Give up if distance is greater than scroll_max or if we
15248 didn't reach the scroll margin position. */
15249 SET_TEXT_POS (pos, PT, PT_BYTE);
15250 start_display (&it, w, pos);
15251 y0 = it.current_y;
15252 y_to_move = max (it.last_visible_y,
15253 max (scroll_max, 10 * frame_line_height));
15254 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15255 y_to_move, -1,
15256 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15257 dy = it.current_y - y0;
15258 if (dy > scroll_max
15259 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15260 return SCROLLING_FAILED;
15261
15262 /* Additional scroll for when ZV was too close to point. */
15263 dy += y_offset;
15264
15265 /* Compute new window start. */
15266 start_display (&it, w, startp);
15267
15268 if (arg_scroll_conservatively)
15269 amount_to_scroll = max (dy, frame_line_height *
15270 max (scroll_step, temp_scroll_step));
15271 else if (scroll_step || temp_scroll_step)
15272 amount_to_scroll = scroll_max;
15273 else
15274 {
15275 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15276 height = WINDOW_BOX_TEXT_HEIGHT (w);
15277 if (NUMBERP (aggressive))
15278 {
15279 double float_amount = XFLOATINT (aggressive) * height;
15280 int aggressive_scroll = float_amount;
15281 if (aggressive_scroll == 0 && float_amount > 0)
15282 aggressive_scroll = 1;
15283 /* Don't let point enter the scroll margin near
15284 bottom of the window, if the value of
15285 scroll_down_aggressively happens to be too
15286 large. */
15287 if (aggressive_scroll + 2*this_scroll_margin > height)
15288 aggressive_scroll = height - 2*this_scroll_margin;
15289 amount_to_scroll = dy + aggressive_scroll;
15290 }
15291 }
15292
15293 if (amount_to_scroll <= 0)
15294 return SCROLLING_FAILED;
15295
15296 move_it_vertically_backward (&it, amount_to_scroll);
15297 startp = it.current.pos;
15298 }
15299 }
15300
15301 /* Run window scroll functions. */
15302 startp = run_window_scroll_functions (window, startp);
15303
15304 /* Display the window. Give up if new fonts are loaded, or if point
15305 doesn't appear. */
15306 if (!try_window (window, startp, 0))
15307 rc = SCROLLING_NEED_LARGER_MATRICES;
15308 else if (w->cursor.vpos < 0)
15309 {
15310 clear_glyph_matrix (w->desired_matrix);
15311 rc = SCROLLING_FAILED;
15312 }
15313 else
15314 {
15315 /* Maybe forget recorded base line for line number display. */
15316 if (!just_this_one_p
15317 || current_buffer->clip_changed
15318 || BEG_UNCHANGED < CHARPOS (startp))
15319 w->base_line_number = 0;
15320
15321 /* If cursor ends up on a partially visible line,
15322 treat that as being off the bottom of the screen. */
15323 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
15324 /* It's possible that the cursor is on the first line of the
15325 buffer, which is partially obscured due to a vscroll
15326 (Bug#7537). In that case, avoid looping forever. */
15327 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15328 {
15329 clear_glyph_matrix (w->desired_matrix);
15330 ++extra_scroll_margin_lines;
15331 goto too_near_end;
15332 }
15333 rc = SCROLLING_SUCCESS;
15334 }
15335
15336 return rc;
15337 }
15338
15339
15340 /* Compute a suitable window start for window W if display of W starts
15341 on a continuation line. Value is non-zero if a new window start
15342 was computed.
15343
15344 The new window start will be computed, based on W's width, starting
15345 from the start of the continued line. It is the start of the
15346 screen line with the minimum distance from the old start W->start. */
15347
15348 static int
15349 compute_window_start_on_continuation_line (struct window *w)
15350 {
15351 struct text_pos pos, start_pos;
15352 int window_start_changed_p = 0;
15353
15354 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
15355
15356 /* If window start is on a continuation line... Window start may be
15357 < BEGV in case there's invisible text at the start of the
15358 buffer (M-x rmail, for example). */
15359 if (CHARPOS (start_pos) > BEGV
15360 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
15361 {
15362 struct it it;
15363 struct glyph_row *row;
15364
15365 /* Handle the case that the window start is out of range. */
15366 if (CHARPOS (start_pos) < BEGV)
15367 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
15368 else if (CHARPOS (start_pos) > ZV)
15369 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
15370
15371 /* Find the start of the continued line. This should be fast
15372 because find_newline is fast (newline cache). */
15373 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
15374 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
15375 row, DEFAULT_FACE_ID);
15376 reseat_at_previous_visible_line_start (&it);
15377
15378 /* If the line start is "too far" away from the window start,
15379 say it takes too much time to compute a new window start. */
15380 if (CHARPOS (start_pos) - IT_CHARPOS (it)
15381 /* PXW: Do we need upper bounds here? */
15382 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
15383 {
15384 int min_distance, distance;
15385
15386 /* Move forward by display lines to find the new window
15387 start. If window width was enlarged, the new start can
15388 be expected to be > the old start. If window width was
15389 decreased, the new window start will be < the old start.
15390 So, we're looking for the display line start with the
15391 minimum distance from the old window start. */
15392 pos = it.current.pos;
15393 min_distance = INFINITY;
15394 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15395 distance < min_distance)
15396 {
15397 min_distance = distance;
15398 pos = it.current.pos;
15399 if (it.line_wrap == WORD_WRAP)
15400 {
15401 /* Under WORD_WRAP, move_it_by_lines is likely to
15402 overshoot and stop not at the first, but the
15403 second character from the left margin. So in
15404 that case, we need a more tight control on the X
15405 coordinate of the iterator than move_it_by_lines
15406 promises in its contract. The method is to first
15407 go to the last (rightmost) visible character of a
15408 line, then move to the leftmost character on the
15409 next line in a separate call. */
15410 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
15411 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15412 move_it_to (&it, ZV, 0,
15413 it.current_y + it.max_ascent + it.max_descent, -1,
15414 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15415 }
15416 else
15417 move_it_by_lines (&it, 1);
15418 }
15419
15420 /* Set the window start there. */
15421 SET_MARKER_FROM_TEXT_POS (w->start, pos);
15422 window_start_changed_p = 1;
15423 }
15424 }
15425
15426 return window_start_changed_p;
15427 }
15428
15429
15430 /* Try cursor movement in case text has not changed in window WINDOW,
15431 with window start STARTP. Value is
15432
15433 CURSOR_MOVEMENT_SUCCESS if successful
15434
15435 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
15436
15437 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
15438 display. *SCROLL_STEP is set to 1, under certain circumstances, if
15439 we want to scroll as if scroll-step were set to 1. See the code.
15440
15441 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
15442 which case we have to abort this redisplay, and adjust matrices
15443 first. */
15444
15445 enum
15446 {
15447 CURSOR_MOVEMENT_SUCCESS,
15448 CURSOR_MOVEMENT_CANNOT_BE_USED,
15449 CURSOR_MOVEMENT_MUST_SCROLL,
15450 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
15451 };
15452
15453 static int
15454 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
15455 {
15456 struct window *w = XWINDOW (window);
15457 struct frame *f = XFRAME (w->frame);
15458 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15459
15460 #ifdef GLYPH_DEBUG
15461 if (inhibit_try_cursor_movement)
15462 return rc;
15463 #endif
15464
15465 /* Previously, there was a check for Lisp integer in the
15466 if-statement below. Now, this field is converted to
15467 ptrdiff_t, thus zero means invalid position in a buffer. */
15468 eassert (w->last_point > 0);
15469 /* Likewise there was a check whether window_end_vpos is nil or larger
15470 than the window. Now window_end_vpos is int and so never nil, but
15471 let's leave eassert to check whether it fits in the window. */
15472 eassert (w->window_end_vpos < w->current_matrix->nrows);
15473
15474 /* Handle case where text has not changed, only point, and it has
15475 not moved off the frame. */
15476 if (/* Point may be in this window. */
15477 PT >= CHARPOS (startp)
15478 /* Selective display hasn't changed. */
15479 && !current_buffer->clip_changed
15480 /* Function force-mode-line-update is used to force a thorough
15481 redisplay. It sets either windows_or_buffers_changed or
15482 update_mode_lines. So don't take a shortcut here for these
15483 cases. */
15484 && !update_mode_lines
15485 && !windows_or_buffers_changed
15486 && !f->cursor_type_changed
15487 && NILP (Vshow_trailing_whitespace)
15488 /* This code is not used for mini-buffer for the sake of the case
15489 of redisplaying to replace an echo area message; since in
15490 that case the mini-buffer contents per se are usually
15491 unchanged. This code is of no real use in the mini-buffer
15492 since the handling of this_line_start_pos, etc., in redisplay
15493 handles the same cases. */
15494 && !EQ (window, minibuf_window)
15495 && (FRAME_WINDOW_P (f)
15496 || !overlay_arrow_in_current_buffer_p ()))
15497 {
15498 int this_scroll_margin, top_scroll_margin;
15499 struct glyph_row *row = NULL;
15500 int frame_line_height = default_line_pixel_height (w);
15501 int window_total_lines
15502 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15503
15504 #ifdef GLYPH_DEBUG
15505 debug_method_add (w, "cursor movement");
15506 #endif
15507
15508 /* Scroll if point within this distance from the top or bottom
15509 of the window. This is a pixel value. */
15510 if (scroll_margin > 0)
15511 {
15512 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15513 this_scroll_margin *= frame_line_height;
15514 }
15515 else
15516 this_scroll_margin = 0;
15517
15518 top_scroll_margin = this_scroll_margin;
15519 if (WINDOW_WANTS_HEADER_LINE_P (w))
15520 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15521
15522 /* Start with the row the cursor was displayed during the last
15523 not paused redisplay. Give up if that row is not valid. */
15524 if (w->last_cursor_vpos < 0
15525 || w->last_cursor_vpos >= w->current_matrix->nrows)
15526 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15527 else
15528 {
15529 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15530 if (row->mode_line_p)
15531 ++row;
15532 if (!row->enabled_p)
15533 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15534 }
15535
15536 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15537 {
15538 int scroll_p = 0, must_scroll = 0;
15539 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15540
15541 if (PT > w->last_point)
15542 {
15543 /* Point has moved forward. */
15544 while (MATRIX_ROW_END_CHARPOS (row) < PT
15545 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15546 {
15547 eassert (row->enabled_p);
15548 ++row;
15549 }
15550
15551 /* If the end position of a row equals the start
15552 position of the next row, and PT is at that position,
15553 we would rather display cursor in the next line. */
15554 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15555 && MATRIX_ROW_END_CHARPOS (row) == PT
15556 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15557 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15558 && !cursor_row_p (row))
15559 ++row;
15560
15561 /* If within the scroll margin, scroll. Note that
15562 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15563 the next line would be drawn, and that
15564 this_scroll_margin can be zero. */
15565 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15566 || PT > MATRIX_ROW_END_CHARPOS (row)
15567 /* Line is completely visible last line in window
15568 and PT is to be set in the next line. */
15569 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15570 && PT == MATRIX_ROW_END_CHARPOS (row)
15571 && !row->ends_at_zv_p
15572 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15573 scroll_p = 1;
15574 }
15575 else if (PT < w->last_point)
15576 {
15577 /* Cursor has to be moved backward. Note that PT >=
15578 CHARPOS (startp) because of the outer if-statement. */
15579 while (!row->mode_line_p
15580 && (MATRIX_ROW_START_CHARPOS (row) > PT
15581 || (MATRIX_ROW_START_CHARPOS (row) == PT
15582 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15583 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15584 row > w->current_matrix->rows
15585 && (row-1)->ends_in_newline_from_string_p))))
15586 && (row->y > top_scroll_margin
15587 || CHARPOS (startp) == BEGV))
15588 {
15589 eassert (row->enabled_p);
15590 --row;
15591 }
15592
15593 /* Consider the following case: Window starts at BEGV,
15594 there is invisible, intangible text at BEGV, so that
15595 display starts at some point START > BEGV. It can
15596 happen that we are called with PT somewhere between
15597 BEGV and START. Try to handle that case. */
15598 if (row < w->current_matrix->rows
15599 || row->mode_line_p)
15600 {
15601 row = w->current_matrix->rows;
15602 if (row->mode_line_p)
15603 ++row;
15604 }
15605
15606 /* Due to newlines in overlay strings, we may have to
15607 skip forward over overlay strings. */
15608 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15609 && MATRIX_ROW_END_CHARPOS (row) == PT
15610 && !cursor_row_p (row))
15611 ++row;
15612
15613 /* If within the scroll margin, scroll. */
15614 if (row->y < top_scroll_margin
15615 && CHARPOS (startp) != BEGV)
15616 scroll_p = 1;
15617 }
15618 else
15619 {
15620 /* Cursor did not move. So don't scroll even if cursor line
15621 is partially visible, as it was so before. */
15622 rc = CURSOR_MOVEMENT_SUCCESS;
15623 }
15624
15625 if (PT < MATRIX_ROW_START_CHARPOS (row)
15626 || PT > MATRIX_ROW_END_CHARPOS (row))
15627 {
15628 /* if PT is not in the glyph row, give up. */
15629 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15630 must_scroll = 1;
15631 }
15632 else if (rc != CURSOR_MOVEMENT_SUCCESS
15633 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15634 {
15635 struct glyph_row *row1;
15636
15637 /* If rows are bidi-reordered and point moved, back up
15638 until we find a row that does not belong to a
15639 continuation line. This is because we must consider
15640 all rows of a continued line as candidates for the
15641 new cursor positioning, since row start and end
15642 positions change non-linearly with vertical position
15643 in such rows. */
15644 /* FIXME: Revisit this when glyph ``spilling'' in
15645 continuation lines' rows is implemented for
15646 bidi-reordered rows. */
15647 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15648 MATRIX_ROW_CONTINUATION_LINE_P (row);
15649 --row)
15650 {
15651 /* If we hit the beginning of the displayed portion
15652 without finding the first row of a continued
15653 line, give up. */
15654 if (row <= row1)
15655 {
15656 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15657 break;
15658 }
15659 eassert (row->enabled_p);
15660 }
15661 }
15662 if (must_scroll)
15663 ;
15664 else if (rc != CURSOR_MOVEMENT_SUCCESS
15665 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15666 /* Make sure this isn't a header line by any chance, since
15667 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15668 && !row->mode_line_p
15669 && make_cursor_line_fully_visible_p)
15670 {
15671 if (PT == MATRIX_ROW_END_CHARPOS (row)
15672 && !row->ends_at_zv_p
15673 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15674 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15675 else if (row->height > window_box_height (w))
15676 {
15677 /* If we end up in a partially visible line, let's
15678 make it fully visible, except when it's taller
15679 than the window, in which case we can't do much
15680 about it. */
15681 *scroll_step = 1;
15682 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15683 }
15684 else
15685 {
15686 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15687 if (!cursor_row_fully_visible_p (w, 0, 1))
15688 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15689 else
15690 rc = CURSOR_MOVEMENT_SUCCESS;
15691 }
15692 }
15693 else if (scroll_p)
15694 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15695 else if (rc != CURSOR_MOVEMENT_SUCCESS
15696 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15697 {
15698 /* With bidi-reordered rows, there could be more than
15699 one candidate row whose start and end positions
15700 occlude point. We need to let set_cursor_from_row
15701 find the best candidate. */
15702 /* FIXME: Revisit this when glyph ``spilling'' in
15703 continuation lines' rows is implemented for
15704 bidi-reordered rows. */
15705 int rv = 0;
15706
15707 do
15708 {
15709 int at_zv_p = 0, exact_match_p = 0;
15710
15711 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15712 && PT <= MATRIX_ROW_END_CHARPOS (row)
15713 && cursor_row_p (row))
15714 rv |= set_cursor_from_row (w, row, w->current_matrix,
15715 0, 0, 0, 0);
15716 /* As soon as we've found the exact match for point,
15717 or the first suitable row whose ends_at_zv_p flag
15718 is set, we are done. */
15719 if (rv)
15720 {
15721 at_zv_p = MATRIX_ROW (w->current_matrix,
15722 w->cursor.vpos)->ends_at_zv_p;
15723 if (!at_zv_p
15724 && w->cursor.hpos >= 0
15725 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15726 w->cursor.vpos))
15727 {
15728 struct glyph_row *candidate =
15729 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15730 struct glyph *g =
15731 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15732 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15733
15734 exact_match_p =
15735 (BUFFERP (g->object) && g->charpos == PT)
15736 || (INTEGERP (g->object)
15737 && (g->charpos == PT
15738 || (g->charpos == 0 && endpos - 1 == PT)));
15739 }
15740 if (at_zv_p || exact_match_p)
15741 {
15742 rc = CURSOR_MOVEMENT_SUCCESS;
15743 break;
15744 }
15745 }
15746 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15747 break;
15748 ++row;
15749 }
15750 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15751 || row->continued_p)
15752 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15753 || (MATRIX_ROW_START_CHARPOS (row) == PT
15754 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15755 /* If we didn't find any candidate rows, or exited the
15756 loop before all the candidates were examined, signal
15757 to the caller that this method failed. */
15758 if (rc != CURSOR_MOVEMENT_SUCCESS
15759 && !(rv
15760 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15761 && !row->continued_p))
15762 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15763 else if (rv)
15764 rc = CURSOR_MOVEMENT_SUCCESS;
15765 }
15766 else
15767 {
15768 do
15769 {
15770 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15771 {
15772 rc = CURSOR_MOVEMENT_SUCCESS;
15773 break;
15774 }
15775 ++row;
15776 }
15777 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15778 && MATRIX_ROW_START_CHARPOS (row) == PT
15779 && cursor_row_p (row));
15780 }
15781 }
15782 }
15783
15784 return rc;
15785 }
15786
15787
15788 void
15789 set_vertical_scroll_bar (struct window *w)
15790 {
15791 ptrdiff_t start, end, whole;
15792
15793 /* Calculate the start and end positions for the current window.
15794 At some point, it would be nice to choose between scrollbars
15795 which reflect the whole buffer size, with special markers
15796 indicating narrowing, and scrollbars which reflect only the
15797 visible region.
15798
15799 Note that mini-buffers sometimes aren't displaying any text. */
15800 if (!MINI_WINDOW_P (w)
15801 || (w == XWINDOW (minibuf_window)
15802 && NILP (echo_area_buffer[0])))
15803 {
15804 struct buffer *buf = XBUFFER (w->contents);
15805 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15806 start = marker_position (w->start) - BUF_BEGV (buf);
15807 /* I don't think this is guaranteed to be right. For the
15808 moment, we'll pretend it is. */
15809 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15810
15811 if (end < start)
15812 end = start;
15813 if (whole < (end - start))
15814 whole = end - start;
15815 }
15816 else
15817 start = end = whole = 0;
15818
15819 /* Indicate what this scroll bar ought to be displaying now. */
15820 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15821 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15822 (w, end - start, whole, start);
15823 }
15824
15825
15826 void
15827 set_horizontal_scroll_bar (struct window *w)
15828 {
15829 int start, end, whole, portion;
15830
15831 if (!MINI_WINDOW_P (w)
15832 || (w == XWINDOW (minibuf_window)
15833 && NILP (echo_area_buffer[0])))
15834 {
15835 struct buffer *b = XBUFFER (w->contents);
15836 struct buffer *old_buffer = NULL;
15837 struct it it;
15838 struct text_pos startp;
15839
15840 if (b != current_buffer)
15841 {
15842 old_buffer = current_buffer;
15843 set_buffer_internal (b);
15844 }
15845
15846 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15847 start_display (&it, w, startp);
15848 it.last_visible_x = INT_MAX;
15849 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
15850 MOVE_TO_X | MOVE_TO_Y);
15851 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
15852 window_box_height (w), -1,
15853 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
15854
15855 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
15856 end = start + window_box_width (w, TEXT_AREA);
15857 portion = end - start;
15858 /* After enlarging a horizontally scrolled window such that it
15859 gets at least as wide as the text it contains, make sure that
15860 the thumb doesn't fill the entire scroll bar so we can still
15861 drag it back to see the entire text. */
15862 whole = max (whole, end);
15863
15864 if (it.bidi_p)
15865 {
15866 Lisp_Object pdir;
15867
15868 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
15869 if (EQ (pdir, Qright_to_left))
15870 {
15871 start = whole - end;
15872 end = start + portion;
15873 }
15874 }
15875
15876 if (old_buffer)
15877 set_buffer_internal (old_buffer);
15878 }
15879 else
15880 start = end = whole = portion = 0;
15881
15882 w->hscroll_whole = whole;
15883
15884 /* Indicate what this scroll bar ought to be displaying now. */
15885 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15886 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15887 (w, portion, whole, start);
15888 }
15889
15890
15891 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15892 selected_window is redisplayed.
15893
15894 We can return without actually redisplaying the window if fonts has been
15895 changed on window's frame. In that case, redisplay_internal will retry.
15896
15897 As one of the important parts of redisplaying a window, we need to
15898 decide whether the previous window-start position (stored in the
15899 window's w->start marker position) is still valid, and if it isn't,
15900 recompute it. Some details about that:
15901
15902 . The previous window-start could be in a continuation line, in
15903 which case we need to recompute it when the window width
15904 changes. See compute_window_start_on_continuation_line and its
15905 call below.
15906
15907 . The text that changed since last redisplay could include the
15908 previous window-start position. In that case, we try to salvage
15909 what we can from the current glyph matrix by calling
15910 try_scrolling, which see.
15911
15912 . Some Emacs command could force us to use a specific window-start
15913 position by setting the window's force_start flag, or gently
15914 propose doing that by setting the window's optional_new_start
15915 flag. In these cases, we try using the specified start point if
15916 that succeeds (i.e. the window desired matrix is successfully
15917 recomputed, and point location is within the window). In case
15918 of optional_new_start, we first check if the specified start
15919 position is feasible, i.e. if it will allow point to be
15920 displayed in the window. If using the specified start point
15921 fails, e.g., if new fonts are needed to be loaded, we abort the
15922 redisplay cycle and leave it up to the next cycle to figure out
15923 things.
15924
15925 . Note that the window's force_start flag is sometimes set by
15926 redisplay itself, when it decides that the previous window start
15927 point is fine and should be kept. Search for "goto force_start"
15928 below to see the details. Like the values of window-start
15929 specified outside of redisplay, these internally-deduced values
15930 are tested for feasibility, and ignored if found to be
15931 unfeasible.
15932
15933 . Note that the function try_window, used to completely redisplay
15934 a window, accepts the window's start point as its argument.
15935 This is used several times in the redisplay code to control
15936 where the window start will be, according to user options such
15937 as scroll-conservatively, and also to ensure the screen line
15938 showing point will be fully (as opposed to partially) visible on
15939 display. */
15940
15941 static void
15942 redisplay_window (Lisp_Object window, bool just_this_one_p)
15943 {
15944 struct window *w = XWINDOW (window);
15945 struct frame *f = XFRAME (w->frame);
15946 struct buffer *buffer = XBUFFER (w->contents);
15947 struct buffer *old = current_buffer;
15948 struct text_pos lpoint, opoint, startp;
15949 int update_mode_line;
15950 int tem;
15951 struct it it;
15952 /* Record it now because it's overwritten. */
15953 bool current_matrix_up_to_date_p = false;
15954 bool used_current_matrix_p = false;
15955 /* This is less strict than current_matrix_up_to_date_p.
15956 It indicates that the buffer contents and narrowing are unchanged. */
15957 bool buffer_unchanged_p = false;
15958 int temp_scroll_step = 0;
15959 ptrdiff_t count = SPECPDL_INDEX ();
15960 int rc;
15961 int centering_position = -1;
15962 int last_line_misfit = 0;
15963 ptrdiff_t beg_unchanged, end_unchanged;
15964 int frame_line_height;
15965
15966 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15967 opoint = lpoint;
15968
15969 #ifdef GLYPH_DEBUG
15970 *w->desired_matrix->method = 0;
15971 #endif
15972
15973 if (!just_this_one_p
15974 && REDISPLAY_SOME_P ()
15975 && !w->redisplay
15976 && !f->redisplay
15977 && !buffer->text->redisplay
15978 && BUF_PT (buffer) == w->last_point)
15979 return;
15980
15981 /* Make sure that both W's markers are valid. */
15982 eassert (XMARKER (w->start)->buffer == buffer);
15983 eassert (XMARKER (w->pointm)->buffer == buffer);
15984
15985 /* We come here again if we need to run window-text-change-functions
15986 below. */
15987 restart:
15988 reconsider_clip_changes (w);
15989 frame_line_height = default_line_pixel_height (w);
15990
15991 /* Has the mode line to be updated? */
15992 update_mode_line = (w->update_mode_line
15993 || update_mode_lines
15994 || buffer->clip_changed
15995 || buffer->prevent_redisplay_optimizations_p);
15996
15997 if (!just_this_one_p)
15998 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
15999 cleverly elsewhere. */
16000 w->must_be_updated_p = true;
16001
16002 if (MINI_WINDOW_P (w))
16003 {
16004 if (w == XWINDOW (echo_area_window)
16005 && !NILP (echo_area_buffer[0]))
16006 {
16007 if (update_mode_line)
16008 /* We may have to update a tty frame's menu bar or a
16009 tool-bar. Example `M-x C-h C-h C-g'. */
16010 goto finish_menu_bars;
16011 else
16012 /* We've already displayed the echo area glyphs in this window. */
16013 goto finish_scroll_bars;
16014 }
16015 else if ((w != XWINDOW (minibuf_window)
16016 || minibuf_level == 0)
16017 /* When buffer is nonempty, redisplay window normally. */
16018 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16019 /* Quail displays non-mini buffers in minibuffer window.
16020 In that case, redisplay the window normally. */
16021 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16022 {
16023 /* W is a mini-buffer window, but it's not active, so clear
16024 it. */
16025 int yb = window_text_bottom_y (w);
16026 struct glyph_row *row;
16027 int y;
16028
16029 for (y = 0, row = w->desired_matrix->rows;
16030 y < yb;
16031 y += row->height, ++row)
16032 blank_row (w, row, y);
16033 goto finish_scroll_bars;
16034 }
16035
16036 clear_glyph_matrix (w->desired_matrix);
16037 }
16038
16039 /* Otherwise set up data on this window; select its buffer and point
16040 value. */
16041 /* Really select the buffer, for the sake of buffer-local
16042 variables. */
16043 set_buffer_internal_1 (XBUFFER (w->contents));
16044
16045 current_matrix_up_to_date_p
16046 = (w->window_end_valid
16047 && !current_buffer->clip_changed
16048 && !current_buffer->prevent_redisplay_optimizations_p
16049 && !window_outdated (w));
16050
16051 /* Run the window-text-change-functions
16052 if it is possible that the text on the screen has changed
16053 (either due to modification of the text, or any other reason). */
16054 if (!current_matrix_up_to_date_p
16055 && !NILP (Vwindow_text_change_functions))
16056 {
16057 safe_run_hooks (Qwindow_text_change_functions);
16058 goto restart;
16059 }
16060
16061 beg_unchanged = BEG_UNCHANGED;
16062 end_unchanged = END_UNCHANGED;
16063
16064 SET_TEXT_POS (opoint, PT, PT_BYTE);
16065
16066 specbind (Qinhibit_point_motion_hooks, Qt);
16067
16068 buffer_unchanged_p
16069 = (w->window_end_valid
16070 && !current_buffer->clip_changed
16071 && !window_outdated (w));
16072
16073 /* When windows_or_buffers_changed is non-zero, we can't rely
16074 on the window end being valid, so set it to zero there. */
16075 if (windows_or_buffers_changed)
16076 {
16077 /* If window starts on a continuation line, maybe adjust the
16078 window start in case the window's width changed. */
16079 if (XMARKER (w->start)->buffer == current_buffer)
16080 compute_window_start_on_continuation_line (w);
16081
16082 w->window_end_valid = false;
16083 /* If so, we also can't rely on current matrix
16084 and should not fool try_cursor_movement below. */
16085 current_matrix_up_to_date_p = false;
16086 }
16087
16088 /* Some sanity checks. */
16089 CHECK_WINDOW_END (w);
16090 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16091 emacs_abort ();
16092 if (BYTEPOS (opoint) < CHARPOS (opoint))
16093 emacs_abort ();
16094
16095 if (mode_line_update_needed (w))
16096 update_mode_line = 1;
16097
16098 /* Point refers normally to the selected window. For any other
16099 window, set up appropriate value. */
16100 if (!EQ (window, selected_window))
16101 {
16102 ptrdiff_t new_pt = marker_position (w->pointm);
16103 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16104
16105 if (new_pt < BEGV)
16106 {
16107 new_pt = BEGV;
16108 new_pt_byte = BEGV_BYTE;
16109 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16110 }
16111 else if (new_pt > (ZV - 1))
16112 {
16113 new_pt = ZV;
16114 new_pt_byte = ZV_BYTE;
16115 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16116 }
16117
16118 /* We don't use SET_PT so that the point-motion hooks don't run. */
16119 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16120 }
16121
16122 /* If any of the character widths specified in the display table
16123 have changed, invalidate the width run cache. It's true that
16124 this may be a bit late to catch such changes, but the rest of
16125 redisplay goes (non-fatally) haywire when the display table is
16126 changed, so why should we worry about doing any better? */
16127 if (current_buffer->width_run_cache
16128 || (current_buffer->base_buffer
16129 && current_buffer->base_buffer->width_run_cache))
16130 {
16131 struct Lisp_Char_Table *disptab = buffer_display_table ();
16132
16133 if (! disptab_matches_widthtab
16134 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16135 {
16136 struct buffer *buf = current_buffer;
16137
16138 if (buf->base_buffer)
16139 buf = buf->base_buffer;
16140 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16141 recompute_width_table (current_buffer, disptab);
16142 }
16143 }
16144
16145 /* If window-start is screwed up, choose a new one. */
16146 if (XMARKER (w->start)->buffer != current_buffer)
16147 goto recenter;
16148
16149 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16150
16151 /* If someone specified a new starting point but did not insist,
16152 check whether it can be used. */
16153 if (w->optional_new_start
16154 && CHARPOS (startp) >= BEGV
16155 && CHARPOS (startp) <= ZV)
16156 {
16157 w->optional_new_start = 0;
16158 start_display (&it, w, startp);
16159 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16160 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16161 if (IT_CHARPOS (it) == PT)
16162 w->force_start = 1;
16163 /* IT may overshoot PT if text at PT is invisible. */
16164 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
16165 w->force_start = 1;
16166 }
16167
16168 force_start:
16169
16170 /* Handle case where place to start displaying has been specified,
16171 unless the specified location is outside the accessible range. */
16172 if (w->force_start || window_frozen_p (w))
16173 {
16174 /* We set this later on if we have to adjust point. */
16175 int new_vpos = -1;
16176
16177 w->force_start = 0;
16178 w->vscroll = 0;
16179 w->window_end_valid = 0;
16180
16181 /* Forget any recorded base line for line number display. */
16182 if (!buffer_unchanged_p)
16183 w->base_line_number = 0;
16184
16185 /* Redisplay the mode line. Select the buffer properly for that.
16186 Also, run the hook window-scroll-functions
16187 because we have scrolled. */
16188 /* Note, we do this after clearing force_start because
16189 if there's an error, it is better to forget about force_start
16190 than to get into an infinite loop calling the hook functions
16191 and having them get more errors. */
16192 if (!update_mode_line
16193 || ! NILP (Vwindow_scroll_functions))
16194 {
16195 update_mode_line = 1;
16196 w->update_mode_line = 1;
16197 startp = run_window_scroll_functions (window, startp);
16198 }
16199
16200 if (CHARPOS (startp) < BEGV)
16201 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16202 else if (CHARPOS (startp) > ZV)
16203 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16204
16205 /* Redisplay, then check if cursor has been set during the
16206 redisplay. Give up if new fonts were loaded. */
16207 /* We used to issue a CHECK_MARGINS argument to try_window here,
16208 but this causes scrolling to fail when point begins inside
16209 the scroll margin (bug#148) -- cyd */
16210 if (!try_window (window, startp, 0))
16211 {
16212 w->force_start = 1;
16213 clear_glyph_matrix (w->desired_matrix);
16214 goto need_larger_matrices;
16215 }
16216
16217 if (w->cursor.vpos < 0 && !window_frozen_p (w))
16218 {
16219 /* If point does not appear, try to move point so it does
16220 appear. The desired matrix has been built above, so we
16221 can use it here. */
16222 new_vpos = window_box_height (w) / 2;
16223 }
16224
16225 if (!cursor_row_fully_visible_p (w, 0, 0))
16226 {
16227 /* Point does appear, but on a line partly visible at end of window.
16228 Move it back to a fully-visible line. */
16229 new_vpos = window_box_height (w);
16230 /* But if window_box_height suggests a Y coordinate that is
16231 not less than we already have, that line will clearly not
16232 be fully visible, so give up and scroll the display.
16233 This can happen when the default face uses a font whose
16234 dimensions are different from the frame's default
16235 font. */
16236 if (new_vpos >= w->cursor.y)
16237 {
16238 w->cursor.vpos = -1;
16239 clear_glyph_matrix (w->desired_matrix);
16240 goto try_to_scroll;
16241 }
16242 }
16243 else if (w->cursor.vpos >= 0)
16244 {
16245 /* Some people insist on not letting point enter the scroll
16246 margin, even though this part handles windows that didn't
16247 scroll at all. */
16248 int window_total_lines
16249 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16250 int margin = min (scroll_margin, window_total_lines / 4);
16251 int pixel_margin = margin * frame_line_height;
16252 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
16253
16254 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16255 below, which finds the row to move point to, advances by
16256 the Y coordinate of the _next_ row, see the definition of
16257 MATRIX_ROW_BOTTOM_Y. */
16258 if (w->cursor.vpos < margin + header_line)
16259 {
16260 w->cursor.vpos = -1;
16261 clear_glyph_matrix (w->desired_matrix);
16262 goto try_to_scroll;
16263 }
16264 else
16265 {
16266 int window_height = window_box_height (w);
16267
16268 if (header_line)
16269 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16270 if (w->cursor.y >= window_height - pixel_margin)
16271 {
16272 w->cursor.vpos = -1;
16273 clear_glyph_matrix (w->desired_matrix);
16274 goto try_to_scroll;
16275 }
16276 }
16277 }
16278
16279 /* If we need to move point for either of the above reasons,
16280 now actually do it. */
16281 if (new_vpos >= 0)
16282 {
16283 struct glyph_row *row;
16284
16285 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16286 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16287 ++row;
16288
16289 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
16290 MATRIX_ROW_START_BYTEPOS (row));
16291
16292 if (w != XWINDOW (selected_window))
16293 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
16294 else if (current_buffer == old)
16295 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16296
16297 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
16298
16299 /* If we are highlighting the region, then we just changed
16300 the region, so redisplay to show it. */
16301 /* FIXME: We need to (re)run pre-redisplay-function! */
16302 /* if (markpos_of_region () >= 0)
16303 {
16304 clear_glyph_matrix (w->desired_matrix);
16305 if (!try_window (window, startp, 0))
16306 goto need_larger_matrices;
16307 }
16308 */
16309 }
16310
16311 #ifdef GLYPH_DEBUG
16312 debug_method_add (w, "forced window start");
16313 #endif
16314 goto done;
16315 }
16316
16317 /* Handle case where text has not changed, only point, and it has
16318 not moved off the frame, and we are not retrying after hscroll.
16319 (current_matrix_up_to_date_p is nonzero when retrying.) */
16320 if (current_matrix_up_to_date_p
16321 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
16322 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
16323 {
16324 switch (rc)
16325 {
16326 case CURSOR_MOVEMENT_SUCCESS:
16327 used_current_matrix_p = 1;
16328 goto done;
16329
16330 case CURSOR_MOVEMENT_MUST_SCROLL:
16331 goto try_to_scroll;
16332
16333 default:
16334 emacs_abort ();
16335 }
16336 }
16337 /* If current starting point was originally the beginning of a line
16338 but no longer is, find a new starting point. */
16339 else if (w->start_at_line_beg
16340 && !(CHARPOS (startp) <= BEGV
16341 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
16342 {
16343 #ifdef GLYPH_DEBUG
16344 debug_method_add (w, "recenter 1");
16345 #endif
16346 goto recenter;
16347 }
16348
16349 /* Try scrolling with try_window_id. Value is > 0 if update has
16350 been done, it is -1 if we know that the same window start will
16351 not work. It is 0 if unsuccessful for some other reason. */
16352 else if ((tem = try_window_id (w)) != 0)
16353 {
16354 #ifdef GLYPH_DEBUG
16355 debug_method_add (w, "try_window_id %d", tem);
16356 #endif
16357
16358 if (f->fonts_changed)
16359 goto need_larger_matrices;
16360 if (tem > 0)
16361 goto done;
16362
16363 /* Otherwise try_window_id has returned -1 which means that we
16364 don't want the alternative below this comment to execute. */
16365 }
16366 else if (CHARPOS (startp) >= BEGV
16367 && CHARPOS (startp) <= ZV
16368 && PT >= CHARPOS (startp)
16369 && (CHARPOS (startp) < ZV
16370 /* Avoid starting at end of buffer. */
16371 || CHARPOS (startp) == BEGV
16372 || !window_outdated (w)))
16373 {
16374 int d1, d2, d3, d4, d5, d6;
16375
16376 /* If first window line is a continuation line, and window start
16377 is inside the modified region, but the first change is before
16378 current window start, we must select a new window start.
16379
16380 However, if this is the result of a down-mouse event (e.g. by
16381 extending the mouse-drag-overlay), we don't want to select a
16382 new window start, since that would change the position under
16383 the mouse, resulting in an unwanted mouse-movement rather
16384 than a simple mouse-click. */
16385 if (!w->start_at_line_beg
16386 && NILP (do_mouse_tracking)
16387 && CHARPOS (startp) > BEGV
16388 && CHARPOS (startp) > BEG + beg_unchanged
16389 && CHARPOS (startp) <= Z - end_unchanged
16390 /* Even if w->start_at_line_beg is nil, a new window may
16391 start at a line_beg, since that's how set_buffer_window
16392 sets it. So, we need to check the return value of
16393 compute_window_start_on_continuation_line. (See also
16394 bug#197). */
16395 && XMARKER (w->start)->buffer == current_buffer
16396 && compute_window_start_on_continuation_line (w)
16397 /* It doesn't make sense to force the window start like we
16398 do at label force_start if it is already known that point
16399 will not be visible in the resulting window, because
16400 doing so will move point from its correct position
16401 instead of scrolling the window to bring point into view.
16402 See bug#9324. */
16403 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
16404 {
16405 w->force_start = 1;
16406 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16407 goto force_start;
16408 }
16409
16410 #ifdef GLYPH_DEBUG
16411 debug_method_add (w, "same window start");
16412 #endif
16413
16414 /* Try to redisplay starting at same place as before.
16415 If point has not moved off frame, accept the results. */
16416 if (!current_matrix_up_to_date_p
16417 /* Don't use try_window_reusing_current_matrix in this case
16418 because a window scroll function can have changed the
16419 buffer. */
16420 || !NILP (Vwindow_scroll_functions)
16421 || MINI_WINDOW_P (w)
16422 || !(used_current_matrix_p
16423 = try_window_reusing_current_matrix (w)))
16424 {
16425 IF_DEBUG (debug_method_add (w, "1"));
16426 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
16427 /* -1 means we need to scroll.
16428 0 means we need new matrices, but fonts_changed
16429 is set in that case, so we will detect it below. */
16430 goto try_to_scroll;
16431 }
16432
16433 if (f->fonts_changed)
16434 goto need_larger_matrices;
16435
16436 if (w->cursor.vpos >= 0)
16437 {
16438 if (!just_this_one_p
16439 || current_buffer->clip_changed
16440 || BEG_UNCHANGED < CHARPOS (startp))
16441 /* Forget any recorded base line for line number display. */
16442 w->base_line_number = 0;
16443
16444 if (!cursor_row_fully_visible_p (w, 1, 0))
16445 {
16446 clear_glyph_matrix (w->desired_matrix);
16447 last_line_misfit = 1;
16448 }
16449 /* Drop through and scroll. */
16450 else
16451 goto done;
16452 }
16453 else
16454 clear_glyph_matrix (w->desired_matrix);
16455 }
16456
16457 try_to_scroll:
16458
16459 /* Redisplay the mode line. Select the buffer properly for that. */
16460 if (!update_mode_line)
16461 {
16462 update_mode_line = 1;
16463 w->update_mode_line = 1;
16464 }
16465
16466 /* Try to scroll by specified few lines. */
16467 if ((scroll_conservatively
16468 || emacs_scroll_step
16469 || temp_scroll_step
16470 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
16471 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
16472 && CHARPOS (startp) >= BEGV
16473 && CHARPOS (startp) <= ZV)
16474 {
16475 /* The function returns -1 if new fonts were loaded, 1 if
16476 successful, 0 if not successful. */
16477 int ss = try_scrolling (window, just_this_one_p,
16478 scroll_conservatively,
16479 emacs_scroll_step,
16480 temp_scroll_step, last_line_misfit);
16481 switch (ss)
16482 {
16483 case SCROLLING_SUCCESS:
16484 goto done;
16485
16486 case SCROLLING_NEED_LARGER_MATRICES:
16487 goto need_larger_matrices;
16488
16489 case SCROLLING_FAILED:
16490 break;
16491
16492 default:
16493 emacs_abort ();
16494 }
16495 }
16496
16497 /* Finally, just choose a place to start which positions point
16498 according to user preferences. */
16499
16500 recenter:
16501
16502 #ifdef GLYPH_DEBUG
16503 debug_method_add (w, "recenter");
16504 #endif
16505
16506 /* Forget any previously recorded base line for line number display. */
16507 if (!buffer_unchanged_p)
16508 w->base_line_number = 0;
16509
16510 /* Determine the window start relative to point. */
16511 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16512 it.current_y = it.last_visible_y;
16513 if (centering_position < 0)
16514 {
16515 int window_total_lines
16516 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16517 int margin =
16518 scroll_margin > 0
16519 ? min (scroll_margin, window_total_lines / 4)
16520 : 0;
16521 ptrdiff_t margin_pos = CHARPOS (startp);
16522 Lisp_Object aggressive;
16523 int scrolling_up;
16524
16525 /* If there is a scroll margin at the top of the window, find
16526 its character position. */
16527 if (margin
16528 /* Cannot call start_display if startp is not in the
16529 accessible region of the buffer. This can happen when we
16530 have just switched to a different buffer and/or changed
16531 its restriction. In that case, startp is initialized to
16532 the character position 1 (BEGV) because we did not yet
16533 have chance to display the buffer even once. */
16534 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
16535 {
16536 struct it it1;
16537 void *it1data = NULL;
16538
16539 SAVE_IT (it1, it, it1data);
16540 start_display (&it1, w, startp);
16541 move_it_vertically (&it1, margin * frame_line_height);
16542 margin_pos = IT_CHARPOS (it1);
16543 RESTORE_IT (&it, &it, it1data);
16544 }
16545 scrolling_up = PT > margin_pos;
16546 aggressive =
16547 scrolling_up
16548 ? BVAR (current_buffer, scroll_up_aggressively)
16549 : BVAR (current_buffer, scroll_down_aggressively);
16550
16551 if (!MINI_WINDOW_P (w)
16552 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
16553 {
16554 int pt_offset = 0;
16555
16556 /* Setting scroll-conservatively overrides
16557 scroll-*-aggressively. */
16558 if (!scroll_conservatively && NUMBERP (aggressive))
16559 {
16560 double float_amount = XFLOATINT (aggressive);
16561
16562 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
16563 if (pt_offset == 0 && float_amount > 0)
16564 pt_offset = 1;
16565 if (pt_offset && margin > 0)
16566 margin -= 1;
16567 }
16568 /* Compute how much to move the window start backward from
16569 point so that point will be displayed where the user
16570 wants it. */
16571 if (scrolling_up)
16572 {
16573 centering_position = it.last_visible_y;
16574 if (pt_offset)
16575 centering_position -= pt_offset;
16576 centering_position -=
16577 frame_line_height * (1 + margin + (last_line_misfit != 0))
16578 + WINDOW_HEADER_LINE_HEIGHT (w);
16579 /* Don't let point enter the scroll margin near top of
16580 the window. */
16581 if (centering_position < margin * frame_line_height)
16582 centering_position = margin * frame_line_height;
16583 }
16584 else
16585 centering_position = margin * frame_line_height + pt_offset;
16586 }
16587 else
16588 /* Set the window start half the height of the window backward
16589 from point. */
16590 centering_position = window_box_height (w) / 2;
16591 }
16592 move_it_vertically_backward (&it, centering_position);
16593
16594 eassert (IT_CHARPOS (it) >= BEGV);
16595
16596 /* The function move_it_vertically_backward may move over more
16597 than the specified y-distance. If it->w is small, e.g. a
16598 mini-buffer window, we may end up in front of the window's
16599 display area. Start displaying at the start of the line
16600 containing PT in this case. */
16601 if (it.current_y <= 0)
16602 {
16603 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16604 move_it_vertically_backward (&it, 0);
16605 it.current_y = 0;
16606 }
16607
16608 it.current_x = it.hpos = 0;
16609
16610 /* Set the window start position here explicitly, to avoid an
16611 infinite loop in case the functions in window-scroll-functions
16612 get errors. */
16613 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16614
16615 /* Run scroll hooks. */
16616 startp = run_window_scroll_functions (window, it.current.pos);
16617
16618 /* Redisplay the window. */
16619 if (!current_matrix_up_to_date_p
16620 || windows_or_buffers_changed
16621 || f->cursor_type_changed
16622 /* Don't use try_window_reusing_current_matrix in this case
16623 because it can have changed the buffer. */
16624 || !NILP (Vwindow_scroll_functions)
16625 || !just_this_one_p
16626 || MINI_WINDOW_P (w)
16627 || !(used_current_matrix_p
16628 = try_window_reusing_current_matrix (w)))
16629 try_window (window, startp, 0);
16630
16631 /* If new fonts have been loaded (due to fontsets), give up. We
16632 have to start a new redisplay since we need to re-adjust glyph
16633 matrices. */
16634 if (f->fonts_changed)
16635 goto need_larger_matrices;
16636
16637 /* If cursor did not appear assume that the middle of the window is
16638 in the first line of the window. Do it again with the next line.
16639 (Imagine a window of height 100, displaying two lines of height
16640 60. Moving back 50 from it->last_visible_y will end in the first
16641 line.) */
16642 if (w->cursor.vpos < 0)
16643 {
16644 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16645 {
16646 clear_glyph_matrix (w->desired_matrix);
16647 move_it_by_lines (&it, 1);
16648 try_window (window, it.current.pos, 0);
16649 }
16650 else if (PT < IT_CHARPOS (it))
16651 {
16652 clear_glyph_matrix (w->desired_matrix);
16653 move_it_by_lines (&it, -1);
16654 try_window (window, it.current.pos, 0);
16655 }
16656 else
16657 {
16658 /* Not much we can do about it. */
16659 }
16660 }
16661
16662 /* Consider the following case: Window starts at BEGV, there is
16663 invisible, intangible text at BEGV, so that display starts at
16664 some point START > BEGV. It can happen that we are called with
16665 PT somewhere between BEGV and START. Try to handle that case,
16666 and similar ones. */
16667 if (w->cursor.vpos < 0)
16668 {
16669 /* First, try locating the proper glyph row for PT. */
16670 struct glyph_row *row =
16671 row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0);
16672
16673 /* Sometimes point is at the beginning of invisible text that is
16674 before the 1st character displayed in the row. In that case,
16675 row_containing_pos fails to find the row, because no glyphs
16676 with appropriate buffer positions are present in the row.
16677 Therefore, we next try to find the row which shows the 1st
16678 position after the invisible text. */
16679 if (!row)
16680 {
16681 Lisp_Object val =
16682 get_char_property_and_overlay (make_number (PT), Qinvisible,
16683 Qnil, NULL);
16684
16685 if (TEXT_PROP_MEANS_INVISIBLE (val))
16686 {
16687 ptrdiff_t alt_pos;
16688 Lisp_Object invis_end =
16689 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16690 Qnil, Qnil);
16691
16692 if (NATNUMP (invis_end))
16693 alt_pos = XFASTINT (invis_end);
16694 else
16695 alt_pos = ZV;
16696 row = row_containing_pos (w, alt_pos, w->current_matrix->rows,
16697 NULL, 0);
16698 }
16699 }
16700 /* Finally, fall back on the first row of the window after the
16701 header line (if any). This is slightly better than not
16702 displaying the cursor at all. */
16703 if (!row)
16704 {
16705 row = w->current_matrix->rows;
16706 if (row->mode_line_p)
16707 ++row;
16708 }
16709 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16710 }
16711
16712 if (!cursor_row_fully_visible_p (w, 0, 0))
16713 {
16714 /* If vscroll is enabled, disable it and try again. */
16715 if (w->vscroll)
16716 {
16717 w->vscroll = 0;
16718 clear_glyph_matrix (w->desired_matrix);
16719 goto recenter;
16720 }
16721
16722 /* Users who set scroll-conservatively to a large number want
16723 point just above/below the scroll margin. If we ended up
16724 with point's row partially visible, move the window start to
16725 make that row fully visible and out of the margin. */
16726 if (scroll_conservatively > SCROLL_LIMIT)
16727 {
16728 int window_total_lines
16729 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16730 int margin =
16731 scroll_margin > 0
16732 ? min (scroll_margin, window_total_lines / 4)
16733 : 0;
16734 int move_down = w->cursor.vpos >= window_total_lines / 2;
16735
16736 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16737 clear_glyph_matrix (w->desired_matrix);
16738 if (1 == try_window (window, it.current.pos,
16739 TRY_WINDOW_CHECK_MARGINS))
16740 goto done;
16741 }
16742
16743 /* If centering point failed to make the whole line visible,
16744 put point at the top instead. That has to make the whole line
16745 visible, if it can be done. */
16746 if (centering_position == 0)
16747 goto done;
16748
16749 clear_glyph_matrix (w->desired_matrix);
16750 centering_position = 0;
16751 goto recenter;
16752 }
16753
16754 done:
16755
16756 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16757 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16758 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16759
16760 /* Display the mode line, if we must. */
16761 if ((update_mode_line
16762 /* If window not full width, must redo its mode line
16763 if (a) the window to its side is being redone and
16764 (b) we do a frame-based redisplay. This is a consequence
16765 of how inverted lines are drawn in frame-based redisplay. */
16766 || (!just_this_one_p
16767 && !FRAME_WINDOW_P (f)
16768 && !WINDOW_FULL_WIDTH_P (w))
16769 /* Line number to display. */
16770 || w->base_line_pos > 0
16771 /* Column number is displayed and different from the one displayed. */
16772 || (w->column_number_displayed != -1
16773 && (w->column_number_displayed != current_column ())))
16774 /* This means that the window has a mode line. */
16775 && (WINDOW_WANTS_MODELINE_P (w)
16776 || WINDOW_WANTS_HEADER_LINE_P (w)))
16777 {
16778
16779 display_mode_lines (w);
16780
16781 /* If mode line height has changed, arrange for a thorough
16782 immediate redisplay using the correct mode line height. */
16783 if (WINDOW_WANTS_MODELINE_P (w)
16784 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16785 {
16786 f->fonts_changed = 1;
16787 w->mode_line_height = -1;
16788 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16789 = DESIRED_MODE_LINE_HEIGHT (w);
16790 }
16791
16792 /* If header line height has changed, arrange for a thorough
16793 immediate redisplay using the correct header line height. */
16794 if (WINDOW_WANTS_HEADER_LINE_P (w)
16795 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16796 {
16797 f->fonts_changed = 1;
16798 w->header_line_height = -1;
16799 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16800 = DESIRED_HEADER_LINE_HEIGHT (w);
16801 }
16802
16803 if (f->fonts_changed)
16804 goto need_larger_matrices;
16805 }
16806
16807 if (!line_number_displayed && w->base_line_pos != -1)
16808 {
16809 w->base_line_pos = 0;
16810 w->base_line_number = 0;
16811 }
16812
16813 finish_menu_bars:
16814
16815 /* When we reach a frame's selected window, redo the frame's menu bar. */
16816 if (update_mode_line
16817 && EQ (FRAME_SELECTED_WINDOW (f), window))
16818 {
16819 int redisplay_menu_p = 0;
16820
16821 if (FRAME_WINDOW_P (f))
16822 {
16823 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16824 || defined (HAVE_NS) || defined (USE_GTK)
16825 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16826 #else
16827 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16828 #endif
16829 }
16830 else
16831 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16832
16833 if (redisplay_menu_p)
16834 display_menu_bar (w);
16835
16836 #ifdef HAVE_WINDOW_SYSTEM
16837 if (FRAME_WINDOW_P (f))
16838 {
16839 #if defined (USE_GTK) || defined (HAVE_NS)
16840 if (FRAME_EXTERNAL_TOOL_BAR (f))
16841 redisplay_tool_bar (f);
16842 #else
16843 if (WINDOWP (f->tool_bar_window)
16844 && (FRAME_TOOL_BAR_LINES (f) > 0
16845 || !NILP (Vauto_resize_tool_bars))
16846 && redisplay_tool_bar (f))
16847 ignore_mouse_drag_p = 1;
16848 #endif
16849 }
16850 #endif
16851 }
16852
16853 #ifdef HAVE_WINDOW_SYSTEM
16854 if (FRAME_WINDOW_P (f)
16855 && update_window_fringes (w, (just_this_one_p
16856 || (!used_current_matrix_p && !overlay_arrow_seen)
16857 || w->pseudo_window_p)))
16858 {
16859 update_begin (f);
16860 block_input ();
16861 if (draw_window_fringes (w, 1))
16862 {
16863 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
16864 x_draw_right_divider (w);
16865 else
16866 x_draw_vertical_border (w);
16867 }
16868 unblock_input ();
16869 update_end (f);
16870 }
16871
16872 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
16873 x_draw_bottom_divider (w);
16874 #endif /* HAVE_WINDOW_SYSTEM */
16875
16876 /* We go to this label, with fonts_changed set, if it is
16877 necessary to try again using larger glyph matrices.
16878 We have to redeem the scroll bar even in this case,
16879 because the loop in redisplay_internal expects that. */
16880 need_larger_matrices:
16881 ;
16882 finish_scroll_bars:
16883
16884 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16885 {
16886 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16887 /* Set the thumb's position and size. */
16888 set_vertical_scroll_bar (w);
16889
16890 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16891 /* Set the thumb's position and size. */
16892 set_horizontal_scroll_bar (w);
16893
16894 /* Note that we actually used the scroll bar attached to this
16895 window, so it shouldn't be deleted at the end of redisplay. */
16896 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16897 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16898 }
16899
16900 /* Restore current_buffer and value of point in it. The window
16901 update may have changed the buffer, so first make sure `opoint'
16902 is still valid (Bug#6177). */
16903 if (CHARPOS (opoint) < BEGV)
16904 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16905 else if (CHARPOS (opoint) > ZV)
16906 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16907 else
16908 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16909
16910 set_buffer_internal_1 (old);
16911 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16912 shorter. This can be caused by log truncation in *Messages*. */
16913 if (CHARPOS (lpoint) <= ZV)
16914 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16915
16916 unbind_to (count, Qnil);
16917 }
16918
16919
16920 /* Build the complete desired matrix of WINDOW with a window start
16921 buffer position POS.
16922
16923 Value is 1 if successful. It is zero if fonts were loaded during
16924 redisplay which makes re-adjusting glyph matrices necessary, and -1
16925 if point would appear in the scroll margins.
16926 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16927 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16928 set in FLAGS.) */
16929
16930 int
16931 try_window (Lisp_Object window, struct text_pos pos, int flags)
16932 {
16933 struct window *w = XWINDOW (window);
16934 struct it it;
16935 struct glyph_row *last_text_row = NULL;
16936 struct frame *f = XFRAME (w->frame);
16937 int frame_line_height = default_line_pixel_height (w);
16938
16939 /* Make POS the new window start. */
16940 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16941
16942 /* Mark cursor position as unknown. No overlay arrow seen. */
16943 w->cursor.vpos = -1;
16944 overlay_arrow_seen = 0;
16945
16946 /* Initialize iterator and info to start at POS. */
16947 start_display (&it, w, pos);
16948 it.glyph_row->reversed_p = false;
16949
16950 /* Display all lines of W. */
16951 while (it.current_y < it.last_visible_y)
16952 {
16953 if (display_line (&it))
16954 last_text_row = it.glyph_row - 1;
16955 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16956 return 0;
16957 }
16958
16959 /* Don't let the cursor end in the scroll margins. */
16960 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16961 && !MINI_WINDOW_P (w))
16962 {
16963 int this_scroll_margin;
16964 int window_total_lines
16965 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16966
16967 if (scroll_margin > 0)
16968 {
16969 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16970 this_scroll_margin *= frame_line_height;
16971 }
16972 else
16973 this_scroll_margin = 0;
16974
16975 if ((w->cursor.y >= 0 /* not vscrolled */
16976 && w->cursor.y < this_scroll_margin
16977 && CHARPOS (pos) > BEGV
16978 && IT_CHARPOS (it) < ZV)
16979 /* rms: considering make_cursor_line_fully_visible_p here
16980 seems to give wrong results. We don't want to recenter
16981 when the last line is partly visible, we want to allow
16982 that case to be handled in the usual way. */
16983 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16984 {
16985 w->cursor.vpos = -1;
16986 clear_glyph_matrix (w->desired_matrix);
16987 return -1;
16988 }
16989 }
16990
16991 /* If bottom moved off end of frame, change mode line percentage. */
16992 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
16993 w->update_mode_line = 1;
16994
16995 /* Set window_end_pos to the offset of the last character displayed
16996 on the window from the end of current_buffer. Set
16997 window_end_vpos to its row number. */
16998 if (last_text_row)
16999 {
17000 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17001 adjust_window_ends (w, last_text_row, 0);
17002 eassert
17003 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17004 w->window_end_vpos)));
17005 }
17006 else
17007 {
17008 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17009 w->window_end_pos = Z - ZV;
17010 w->window_end_vpos = 0;
17011 }
17012
17013 /* But that is not valid info until redisplay finishes. */
17014 w->window_end_valid = 0;
17015 return 1;
17016 }
17017
17018
17019 \f
17020 /************************************************************************
17021 Window redisplay reusing current matrix when buffer has not changed
17022 ************************************************************************/
17023
17024 /* Try redisplay of window W showing an unchanged buffer with a
17025 different window start than the last time it was displayed by
17026 reusing its current matrix. Value is non-zero if successful.
17027 W->start is the new window start. */
17028
17029 static int
17030 try_window_reusing_current_matrix (struct window *w)
17031 {
17032 struct frame *f = XFRAME (w->frame);
17033 struct glyph_row *bottom_row;
17034 struct it it;
17035 struct run run;
17036 struct text_pos start, new_start;
17037 int nrows_scrolled, i;
17038 struct glyph_row *last_text_row;
17039 struct glyph_row *last_reused_text_row;
17040 struct glyph_row *start_row;
17041 int start_vpos, min_y, max_y;
17042
17043 #ifdef GLYPH_DEBUG
17044 if (inhibit_try_window_reusing)
17045 return 0;
17046 #endif
17047
17048 if (/* This function doesn't handle terminal frames. */
17049 !FRAME_WINDOW_P (f)
17050 /* Don't try to reuse the display if windows have been split
17051 or such. */
17052 || windows_or_buffers_changed
17053 || f->cursor_type_changed)
17054 return 0;
17055
17056 /* Can't do this if showing trailing whitespace. */
17057 if (!NILP (Vshow_trailing_whitespace))
17058 return 0;
17059
17060 /* If top-line visibility has changed, give up. */
17061 if (WINDOW_WANTS_HEADER_LINE_P (w)
17062 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17063 return 0;
17064
17065 /* Give up if old or new display is scrolled vertically. We could
17066 make this function handle this, but right now it doesn't. */
17067 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17068 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17069 return 0;
17070
17071 /* The variable new_start now holds the new window start. The old
17072 start `start' can be determined from the current matrix. */
17073 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17074 start = start_row->minpos;
17075 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17076
17077 /* Clear the desired matrix for the display below. */
17078 clear_glyph_matrix (w->desired_matrix);
17079
17080 if (CHARPOS (new_start) <= CHARPOS (start))
17081 {
17082 /* Don't use this method if the display starts with an ellipsis
17083 displayed for invisible text. It's not easy to handle that case
17084 below, and it's certainly not worth the effort since this is
17085 not a frequent case. */
17086 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17087 return 0;
17088
17089 IF_DEBUG (debug_method_add (w, "twu1"));
17090
17091 /* Display up to a row that can be reused. The variable
17092 last_text_row is set to the last row displayed that displays
17093 text. Note that it.vpos == 0 if or if not there is a
17094 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17095 start_display (&it, w, new_start);
17096 w->cursor.vpos = -1;
17097 last_text_row = last_reused_text_row = NULL;
17098
17099 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17100 {
17101 /* If we have reached into the characters in the START row,
17102 that means the line boundaries have changed. So we
17103 can't start copying with the row START. Maybe it will
17104 work to start copying with the following row. */
17105 while (IT_CHARPOS (it) > CHARPOS (start))
17106 {
17107 /* Advance to the next row as the "start". */
17108 start_row++;
17109 start = start_row->minpos;
17110 /* If there are no more rows to try, or just one, give up. */
17111 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17112 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17113 || CHARPOS (start) == ZV)
17114 {
17115 clear_glyph_matrix (w->desired_matrix);
17116 return 0;
17117 }
17118
17119 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17120 }
17121 /* If we have reached alignment, we can copy the rest of the
17122 rows. */
17123 if (IT_CHARPOS (it) == CHARPOS (start)
17124 /* Don't accept "alignment" inside a display vector,
17125 since start_row could have started in the middle of
17126 that same display vector (thus their character
17127 positions match), and we have no way of telling if
17128 that is the case. */
17129 && it.current.dpvec_index < 0)
17130 break;
17131
17132 it.glyph_row->reversed_p = false;
17133 if (display_line (&it))
17134 last_text_row = it.glyph_row - 1;
17135
17136 }
17137
17138 /* A value of current_y < last_visible_y means that we stopped
17139 at the previous window start, which in turn means that we
17140 have at least one reusable row. */
17141 if (it.current_y < it.last_visible_y)
17142 {
17143 struct glyph_row *row;
17144
17145 /* IT.vpos always starts from 0; it counts text lines. */
17146 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17147
17148 /* Find PT if not already found in the lines displayed. */
17149 if (w->cursor.vpos < 0)
17150 {
17151 int dy = it.current_y - start_row->y;
17152
17153 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17154 row = row_containing_pos (w, PT, row, NULL, dy);
17155 if (row)
17156 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17157 dy, nrows_scrolled);
17158 else
17159 {
17160 clear_glyph_matrix (w->desired_matrix);
17161 return 0;
17162 }
17163 }
17164
17165 /* Scroll the display. Do it before the current matrix is
17166 changed. The problem here is that update has not yet
17167 run, i.e. part of the current matrix is not up to date.
17168 scroll_run_hook will clear the cursor, and use the
17169 current matrix to get the height of the row the cursor is
17170 in. */
17171 run.current_y = start_row->y;
17172 run.desired_y = it.current_y;
17173 run.height = it.last_visible_y - it.current_y;
17174
17175 if (run.height > 0 && run.current_y != run.desired_y)
17176 {
17177 update_begin (f);
17178 FRAME_RIF (f)->update_window_begin_hook (w);
17179 FRAME_RIF (f)->clear_window_mouse_face (w);
17180 FRAME_RIF (f)->scroll_run_hook (w, &run);
17181 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17182 update_end (f);
17183 }
17184
17185 /* Shift current matrix down by nrows_scrolled lines. */
17186 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17187 rotate_matrix (w->current_matrix,
17188 start_vpos,
17189 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17190 nrows_scrolled);
17191
17192 /* Disable lines that must be updated. */
17193 for (i = 0; i < nrows_scrolled; ++i)
17194 (start_row + i)->enabled_p = false;
17195
17196 /* Re-compute Y positions. */
17197 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17198 max_y = it.last_visible_y;
17199 for (row = start_row + nrows_scrolled;
17200 row < bottom_row;
17201 ++row)
17202 {
17203 row->y = it.current_y;
17204 row->visible_height = row->height;
17205
17206 if (row->y < min_y)
17207 row->visible_height -= min_y - row->y;
17208 if (row->y + row->height > max_y)
17209 row->visible_height -= row->y + row->height - max_y;
17210 if (row->fringe_bitmap_periodic_p)
17211 row->redraw_fringe_bitmaps_p = 1;
17212
17213 it.current_y += row->height;
17214
17215 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17216 last_reused_text_row = row;
17217 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17218 break;
17219 }
17220
17221 /* Disable lines in the current matrix which are now
17222 below the window. */
17223 for (++row; row < bottom_row; ++row)
17224 row->enabled_p = row->mode_line_p = 0;
17225 }
17226
17227 /* Update window_end_pos etc.; last_reused_text_row is the last
17228 reused row from the current matrix containing text, if any.
17229 The value of last_text_row is the last displayed line
17230 containing text. */
17231 if (last_reused_text_row)
17232 adjust_window_ends (w, last_reused_text_row, 1);
17233 else if (last_text_row)
17234 adjust_window_ends (w, last_text_row, 0);
17235 else
17236 {
17237 /* This window must be completely empty. */
17238 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17239 w->window_end_pos = Z - ZV;
17240 w->window_end_vpos = 0;
17241 }
17242 w->window_end_valid = 0;
17243
17244 /* Update hint: don't try scrolling again in update_window. */
17245 w->desired_matrix->no_scrolling_p = 1;
17246
17247 #ifdef GLYPH_DEBUG
17248 debug_method_add (w, "try_window_reusing_current_matrix 1");
17249 #endif
17250 return 1;
17251 }
17252 else if (CHARPOS (new_start) > CHARPOS (start))
17253 {
17254 struct glyph_row *pt_row, *row;
17255 struct glyph_row *first_reusable_row;
17256 struct glyph_row *first_row_to_display;
17257 int dy;
17258 int yb = window_text_bottom_y (w);
17259
17260 /* Find the row starting at new_start, if there is one. Don't
17261 reuse a partially visible line at the end. */
17262 first_reusable_row = start_row;
17263 while (first_reusable_row->enabled_p
17264 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
17265 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17266 < CHARPOS (new_start)))
17267 ++first_reusable_row;
17268
17269 /* Give up if there is no row to reuse. */
17270 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
17271 || !first_reusable_row->enabled_p
17272 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17273 != CHARPOS (new_start)))
17274 return 0;
17275
17276 /* We can reuse fully visible rows beginning with
17277 first_reusable_row to the end of the window. Set
17278 first_row_to_display to the first row that cannot be reused.
17279 Set pt_row to the row containing point, if there is any. */
17280 pt_row = NULL;
17281 for (first_row_to_display = first_reusable_row;
17282 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
17283 ++first_row_to_display)
17284 {
17285 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
17286 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
17287 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
17288 && first_row_to_display->ends_at_zv_p
17289 && pt_row == NULL)))
17290 pt_row = first_row_to_display;
17291 }
17292
17293 /* Start displaying at the start of first_row_to_display. */
17294 eassert (first_row_to_display->y < yb);
17295 init_to_row_start (&it, w, first_row_to_display);
17296
17297 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
17298 - start_vpos);
17299 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
17300 - nrows_scrolled);
17301 it.current_y = (first_row_to_display->y - first_reusable_row->y
17302 + WINDOW_HEADER_LINE_HEIGHT (w));
17303
17304 /* Display lines beginning with first_row_to_display in the
17305 desired matrix. Set last_text_row to the last row displayed
17306 that displays text. */
17307 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
17308 if (pt_row == NULL)
17309 w->cursor.vpos = -1;
17310 last_text_row = NULL;
17311 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17312 if (display_line (&it))
17313 last_text_row = it.glyph_row - 1;
17314
17315 /* If point is in a reused row, adjust y and vpos of the cursor
17316 position. */
17317 if (pt_row)
17318 {
17319 w->cursor.vpos -= nrows_scrolled;
17320 w->cursor.y -= first_reusable_row->y - start_row->y;
17321 }
17322
17323 /* Give up if point isn't in a row displayed or reused. (This
17324 also handles the case where w->cursor.vpos < nrows_scrolled
17325 after the calls to display_line, which can happen with scroll
17326 margins. See bug#1295.) */
17327 if (w->cursor.vpos < 0)
17328 {
17329 clear_glyph_matrix (w->desired_matrix);
17330 return 0;
17331 }
17332
17333 /* Scroll the display. */
17334 run.current_y = first_reusable_row->y;
17335 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
17336 run.height = it.last_visible_y - run.current_y;
17337 dy = run.current_y - run.desired_y;
17338
17339 if (run.height)
17340 {
17341 update_begin (f);
17342 FRAME_RIF (f)->update_window_begin_hook (w);
17343 FRAME_RIF (f)->clear_window_mouse_face (w);
17344 FRAME_RIF (f)->scroll_run_hook (w, &run);
17345 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17346 update_end (f);
17347 }
17348
17349 /* Adjust Y positions of reused rows. */
17350 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17351 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17352 max_y = it.last_visible_y;
17353 for (row = first_reusable_row; row < first_row_to_display; ++row)
17354 {
17355 row->y -= dy;
17356 row->visible_height = row->height;
17357 if (row->y < min_y)
17358 row->visible_height -= min_y - row->y;
17359 if (row->y + row->height > max_y)
17360 row->visible_height -= row->y + row->height - max_y;
17361 if (row->fringe_bitmap_periodic_p)
17362 row->redraw_fringe_bitmaps_p = 1;
17363 }
17364
17365 /* Scroll the current matrix. */
17366 eassert (nrows_scrolled > 0);
17367 rotate_matrix (w->current_matrix,
17368 start_vpos,
17369 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17370 -nrows_scrolled);
17371
17372 /* Disable rows not reused. */
17373 for (row -= nrows_scrolled; row < bottom_row; ++row)
17374 row->enabled_p = false;
17375
17376 /* Point may have moved to a different line, so we cannot assume that
17377 the previous cursor position is valid; locate the correct row. */
17378 if (pt_row)
17379 {
17380 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
17381 row < bottom_row
17382 && PT >= MATRIX_ROW_END_CHARPOS (row)
17383 && !row->ends_at_zv_p;
17384 row++)
17385 {
17386 w->cursor.vpos++;
17387 w->cursor.y = row->y;
17388 }
17389 if (row < bottom_row)
17390 {
17391 /* Can't simply scan the row for point with
17392 bidi-reordered glyph rows. Let set_cursor_from_row
17393 figure out where to put the cursor, and if it fails,
17394 give up. */
17395 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
17396 {
17397 if (!set_cursor_from_row (w, row, w->current_matrix,
17398 0, 0, 0, 0))
17399 {
17400 clear_glyph_matrix (w->desired_matrix);
17401 return 0;
17402 }
17403 }
17404 else
17405 {
17406 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
17407 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17408
17409 for (; glyph < end
17410 && (!BUFFERP (glyph->object)
17411 || glyph->charpos < PT);
17412 glyph++)
17413 {
17414 w->cursor.hpos++;
17415 w->cursor.x += glyph->pixel_width;
17416 }
17417 }
17418 }
17419 }
17420
17421 /* Adjust window end. A null value of last_text_row means that
17422 the window end is in reused rows which in turn means that
17423 only its vpos can have changed. */
17424 if (last_text_row)
17425 adjust_window_ends (w, last_text_row, 0);
17426 else
17427 w->window_end_vpos -= nrows_scrolled;
17428
17429 w->window_end_valid = 0;
17430 w->desired_matrix->no_scrolling_p = 1;
17431
17432 #ifdef GLYPH_DEBUG
17433 debug_method_add (w, "try_window_reusing_current_matrix 2");
17434 #endif
17435 return 1;
17436 }
17437
17438 return 0;
17439 }
17440
17441
17442 \f
17443 /************************************************************************
17444 Window redisplay reusing current matrix when buffer has changed
17445 ************************************************************************/
17446
17447 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
17448 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
17449 ptrdiff_t *, ptrdiff_t *);
17450 static struct glyph_row *
17451 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
17452 struct glyph_row *);
17453
17454
17455 /* Return the last row in MATRIX displaying text. If row START is
17456 non-null, start searching with that row. IT gives the dimensions
17457 of the display. Value is null if matrix is empty; otherwise it is
17458 a pointer to the row found. */
17459
17460 static struct glyph_row *
17461 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
17462 struct glyph_row *start)
17463 {
17464 struct glyph_row *row, *row_found;
17465
17466 /* Set row_found to the last row in IT->w's current matrix
17467 displaying text. The loop looks funny but think of partially
17468 visible lines. */
17469 row_found = NULL;
17470 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
17471 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17472 {
17473 eassert (row->enabled_p);
17474 row_found = row;
17475 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
17476 break;
17477 ++row;
17478 }
17479
17480 return row_found;
17481 }
17482
17483
17484 /* Return the last row in the current matrix of W that is not affected
17485 by changes at the start of current_buffer that occurred since W's
17486 current matrix was built. Value is null if no such row exists.
17487
17488 BEG_UNCHANGED us the number of characters unchanged at the start of
17489 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
17490 first changed character in current_buffer. Characters at positions <
17491 BEG + BEG_UNCHANGED are at the same buffer positions as they were
17492 when the current matrix was built. */
17493
17494 static struct glyph_row *
17495 find_last_unchanged_at_beg_row (struct window *w)
17496 {
17497 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
17498 struct glyph_row *row;
17499 struct glyph_row *row_found = NULL;
17500 int yb = window_text_bottom_y (w);
17501
17502 /* Find the last row displaying unchanged text. */
17503 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17504 MATRIX_ROW_DISPLAYS_TEXT_P (row)
17505 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
17506 ++row)
17507 {
17508 if (/* If row ends before first_changed_pos, it is unchanged,
17509 except in some case. */
17510 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
17511 /* When row ends in ZV and we write at ZV it is not
17512 unchanged. */
17513 && !row->ends_at_zv_p
17514 /* When first_changed_pos is the end of a continued line,
17515 row is not unchanged because it may be no longer
17516 continued. */
17517 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
17518 && (row->continued_p
17519 || row->exact_window_width_line_p))
17520 /* If ROW->end is beyond ZV, then ROW->end is outdated and
17521 needs to be recomputed, so don't consider this row as
17522 unchanged. This happens when the last line was
17523 bidi-reordered and was killed immediately before this
17524 redisplay cycle. In that case, ROW->end stores the
17525 buffer position of the first visual-order character of
17526 the killed text, which is now beyond ZV. */
17527 && CHARPOS (row->end.pos) <= ZV)
17528 row_found = row;
17529
17530 /* Stop if last visible row. */
17531 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
17532 break;
17533 }
17534
17535 return row_found;
17536 }
17537
17538
17539 /* Find the first glyph row in the current matrix of W that is not
17540 affected by changes at the end of current_buffer since the
17541 time W's current matrix was built.
17542
17543 Return in *DELTA the number of chars by which buffer positions in
17544 unchanged text at the end of current_buffer must be adjusted.
17545
17546 Return in *DELTA_BYTES the corresponding number of bytes.
17547
17548 Value is null if no such row exists, i.e. all rows are affected by
17549 changes. */
17550
17551 static struct glyph_row *
17552 find_first_unchanged_at_end_row (struct window *w,
17553 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
17554 {
17555 struct glyph_row *row;
17556 struct glyph_row *row_found = NULL;
17557
17558 *delta = *delta_bytes = 0;
17559
17560 /* Display must not have been paused, otherwise the current matrix
17561 is not up to date. */
17562 eassert (w->window_end_valid);
17563
17564 /* A value of window_end_pos >= END_UNCHANGED means that the window
17565 end is in the range of changed text. If so, there is no
17566 unchanged row at the end of W's current matrix. */
17567 if (w->window_end_pos >= END_UNCHANGED)
17568 return NULL;
17569
17570 /* Set row to the last row in W's current matrix displaying text. */
17571 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17572
17573 /* If matrix is entirely empty, no unchanged row exists. */
17574 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17575 {
17576 /* The value of row is the last glyph row in the matrix having a
17577 meaningful buffer position in it. The end position of row
17578 corresponds to window_end_pos. This allows us to translate
17579 buffer positions in the current matrix to current buffer
17580 positions for characters not in changed text. */
17581 ptrdiff_t Z_old =
17582 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17583 ptrdiff_t Z_BYTE_old =
17584 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17585 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
17586 struct glyph_row *first_text_row
17587 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17588
17589 *delta = Z - Z_old;
17590 *delta_bytes = Z_BYTE - Z_BYTE_old;
17591
17592 /* Set last_unchanged_pos to the buffer position of the last
17593 character in the buffer that has not been changed. Z is the
17594 index + 1 of the last character in current_buffer, i.e. by
17595 subtracting END_UNCHANGED we get the index of the last
17596 unchanged character, and we have to add BEG to get its buffer
17597 position. */
17598 last_unchanged_pos = Z - END_UNCHANGED + BEG;
17599 last_unchanged_pos_old = last_unchanged_pos - *delta;
17600
17601 /* Search backward from ROW for a row displaying a line that
17602 starts at a minimum position >= last_unchanged_pos_old. */
17603 for (; row > first_text_row; --row)
17604 {
17605 /* This used to abort, but it can happen.
17606 It is ok to just stop the search instead here. KFS. */
17607 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
17608 break;
17609
17610 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
17611 row_found = row;
17612 }
17613 }
17614
17615 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
17616
17617 return row_found;
17618 }
17619
17620
17621 /* Make sure that glyph rows in the current matrix of window W
17622 reference the same glyph memory as corresponding rows in the
17623 frame's frame matrix. This function is called after scrolling W's
17624 current matrix on a terminal frame in try_window_id and
17625 try_window_reusing_current_matrix. */
17626
17627 static void
17628 sync_frame_with_window_matrix_rows (struct window *w)
17629 {
17630 struct frame *f = XFRAME (w->frame);
17631 struct glyph_row *window_row, *window_row_end, *frame_row;
17632
17633 /* Preconditions: W must be a leaf window and full-width. Its frame
17634 must have a frame matrix. */
17635 eassert (BUFFERP (w->contents));
17636 eassert (WINDOW_FULL_WIDTH_P (w));
17637 eassert (!FRAME_WINDOW_P (f));
17638
17639 /* If W is a full-width window, glyph pointers in W's current matrix
17640 have, by definition, to be the same as glyph pointers in the
17641 corresponding frame matrix. Note that frame matrices have no
17642 marginal areas (see build_frame_matrix). */
17643 window_row = w->current_matrix->rows;
17644 window_row_end = window_row + w->current_matrix->nrows;
17645 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17646 while (window_row < window_row_end)
17647 {
17648 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17649 struct glyph *end = window_row->glyphs[LAST_AREA];
17650
17651 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17652 frame_row->glyphs[TEXT_AREA] = start;
17653 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17654 frame_row->glyphs[LAST_AREA] = end;
17655
17656 /* Disable frame rows whose corresponding window rows have
17657 been disabled in try_window_id. */
17658 if (!window_row->enabled_p)
17659 frame_row->enabled_p = false;
17660
17661 ++window_row, ++frame_row;
17662 }
17663 }
17664
17665
17666 /* Find the glyph row in window W containing CHARPOS. Consider all
17667 rows between START and END (not inclusive). END null means search
17668 all rows to the end of the display area of W. Value is the row
17669 containing CHARPOS or null. */
17670
17671 struct glyph_row *
17672 row_containing_pos (struct window *w, ptrdiff_t charpos,
17673 struct glyph_row *start, struct glyph_row *end, int dy)
17674 {
17675 struct glyph_row *row = start;
17676 struct glyph_row *best_row = NULL;
17677 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17678 int last_y;
17679
17680 /* If we happen to start on a header-line, skip that. */
17681 if (row->mode_line_p)
17682 ++row;
17683
17684 if ((end && row >= end) || !row->enabled_p)
17685 return NULL;
17686
17687 last_y = window_text_bottom_y (w) - dy;
17688
17689 while (1)
17690 {
17691 /* Give up if we have gone too far. */
17692 if (end && row >= end)
17693 return NULL;
17694 /* This formerly returned if they were equal.
17695 I think that both quantities are of a "last plus one" type;
17696 if so, when they are equal, the row is within the screen. -- rms. */
17697 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17698 return NULL;
17699
17700 /* If it is in this row, return this row. */
17701 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17702 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17703 /* The end position of a row equals the start
17704 position of the next row. If CHARPOS is there, we
17705 would rather consider it displayed in the next
17706 line, except when this line ends in ZV. */
17707 && !row_for_charpos_p (row, charpos)))
17708 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17709 {
17710 struct glyph *g;
17711
17712 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17713 || (!best_row && !row->continued_p))
17714 return row;
17715 /* In bidi-reordered rows, there could be several rows whose
17716 edges surround CHARPOS, all of these rows belonging to
17717 the same continued line. We need to find the row which
17718 fits CHARPOS the best. */
17719 for (g = row->glyphs[TEXT_AREA];
17720 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17721 g++)
17722 {
17723 if (!STRINGP (g->object))
17724 {
17725 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17726 {
17727 mindif = eabs (g->charpos - charpos);
17728 best_row = row;
17729 /* Exact match always wins. */
17730 if (mindif == 0)
17731 return best_row;
17732 }
17733 }
17734 }
17735 }
17736 else if (best_row && !row->continued_p)
17737 return best_row;
17738 ++row;
17739 }
17740 }
17741
17742
17743 /* Try to redisplay window W by reusing its existing display. W's
17744 current matrix must be up to date when this function is called,
17745 i.e. window_end_valid must be nonzero.
17746
17747 Value is
17748
17749 >= 1 if successful, i.e. display has been updated
17750 specifically:
17751 1 means the changes were in front of a newline that precedes
17752 the window start, and the whole current matrix was reused
17753 2 means the changes were after the last position displayed
17754 in the window, and the whole current matrix was reused
17755 3 means portions of the current matrix were reused, while
17756 some of the screen lines were redrawn
17757 -1 if redisplay with same window start is known not to succeed
17758 0 if otherwise unsuccessful
17759
17760 The following steps are performed:
17761
17762 1. Find the last row in the current matrix of W that is not
17763 affected by changes at the start of current_buffer. If no such row
17764 is found, give up.
17765
17766 2. Find the first row in W's current matrix that is not affected by
17767 changes at the end of current_buffer. Maybe there is no such row.
17768
17769 3. Display lines beginning with the row + 1 found in step 1 to the
17770 row found in step 2 or, if step 2 didn't find a row, to the end of
17771 the window.
17772
17773 4. If cursor is not known to appear on the window, give up.
17774
17775 5. If display stopped at the row found in step 2, scroll the
17776 display and current matrix as needed.
17777
17778 6. Maybe display some lines at the end of W, if we must. This can
17779 happen under various circumstances, like a partially visible line
17780 becoming fully visible, or because newly displayed lines are displayed
17781 in smaller font sizes.
17782
17783 7. Update W's window end information. */
17784
17785 static int
17786 try_window_id (struct window *w)
17787 {
17788 struct frame *f = XFRAME (w->frame);
17789 struct glyph_matrix *current_matrix = w->current_matrix;
17790 struct glyph_matrix *desired_matrix = w->desired_matrix;
17791 struct glyph_row *last_unchanged_at_beg_row;
17792 struct glyph_row *first_unchanged_at_end_row;
17793 struct glyph_row *row;
17794 struct glyph_row *bottom_row;
17795 int bottom_vpos;
17796 struct it it;
17797 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17798 int dvpos, dy;
17799 struct text_pos start_pos;
17800 struct run run;
17801 int first_unchanged_at_end_vpos = 0;
17802 struct glyph_row *last_text_row, *last_text_row_at_end;
17803 struct text_pos start;
17804 ptrdiff_t first_changed_charpos, last_changed_charpos;
17805
17806 #ifdef GLYPH_DEBUG
17807 if (inhibit_try_window_id)
17808 return 0;
17809 #endif
17810
17811 /* This is handy for debugging. */
17812 #if 0
17813 #define GIVE_UP(X) \
17814 do { \
17815 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17816 return 0; \
17817 } while (0)
17818 #else
17819 #define GIVE_UP(X) return 0
17820 #endif
17821
17822 SET_TEXT_POS_FROM_MARKER (start, w->start);
17823
17824 /* Don't use this for mini-windows because these can show
17825 messages and mini-buffers, and we don't handle that here. */
17826 if (MINI_WINDOW_P (w))
17827 GIVE_UP (1);
17828
17829 /* This flag is used to prevent redisplay optimizations. */
17830 if (windows_or_buffers_changed || f->cursor_type_changed)
17831 GIVE_UP (2);
17832
17833 /* This function's optimizations cannot be used if overlays have
17834 changed in the buffer displayed by the window, so give up if they
17835 have. */
17836 if (w->last_overlay_modified != OVERLAY_MODIFF)
17837 GIVE_UP (21);
17838
17839 /* Verify that narrowing has not changed.
17840 Also verify that we were not told to prevent redisplay optimizations.
17841 It would be nice to further
17842 reduce the number of cases where this prevents try_window_id. */
17843 if (current_buffer->clip_changed
17844 || current_buffer->prevent_redisplay_optimizations_p)
17845 GIVE_UP (3);
17846
17847 /* Window must either use window-based redisplay or be full width. */
17848 if (!FRAME_WINDOW_P (f)
17849 && (!FRAME_LINE_INS_DEL_OK (f)
17850 || !WINDOW_FULL_WIDTH_P (w)))
17851 GIVE_UP (4);
17852
17853 /* Give up if point is known NOT to appear in W. */
17854 if (PT < CHARPOS (start))
17855 GIVE_UP (5);
17856
17857 /* Another way to prevent redisplay optimizations. */
17858 if (w->last_modified == 0)
17859 GIVE_UP (6);
17860
17861 /* Verify that window is not hscrolled. */
17862 if (w->hscroll != 0)
17863 GIVE_UP (7);
17864
17865 /* Verify that display wasn't paused. */
17866 if (!w->window_end_valid)
17867 GIVE_UP (8);
17868
17869 /* Likewise if highlighting trailing whitespace. */
17870 if (!NILP (Vshow_trailing_whitespace))
17871 GIVE_UP (11);
17872
17873 /* Can't use this if overlay arrow position and/or string have
17874 changed. */
17875 if (overlay_arrows_changed_p ())
17876 GIVE_UP (12);
17877
17878 /* When word-wrap is on, adding a space to the first word of a
17879 wrapped line can change the wrap position, altering the line
17880 above it. It might be worthwhile to handle this more
17881 intelligently, but for now just redisplay from scratch. */
17882 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17883 GIVE_UP (21);
17884
17885 /* Under bidi reordering, adding or deleting a character in the
17886 beginning of a paragraph, before the first strong directional
17887 character, can change the base direction of the paragraph (unless
17888 the buffer specifies a fixed paragraph direction), which will
17889 require to redisplay the whole paragraph. It might be worthwhile
17890 to find the paragraph limits and widen the range of redisplayed
17891 lines to that, but for now just give up this optimization and
17892 redisplay from scratch. */
17893 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17894 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17895 GIVE_UP (22);
17896
17897 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17898 only if buffer has really changed. The reason is that the gap is
17899 initially at Z for freshly visited files. The code below would
17900 set end_unchanged to 0 in that case. */
17901 if (MODIFF > SAVE_MODIFF
17902 /* This seems to happen sometimes after saving a buffer. */
17903 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17904 {
17905 if (GPT - BEG < BEG_UNCHANGED)
17906 BEG_UNCHANGED = GPT - BEG;
17907 if (Z - GPT < END_UNCHANGED)
17908 END_UNCHANGED = Z - GPT;
17909 }
17910
17911 /* The position of the first and last character that has been changed. */
17912 first_changed_charpos = BEG + BEG_UNCHANGED;
17913 last_changed_charpos = Z - END_UNCHANGED;
17914
17915 /* If window starts after a line end, and the last change is in
17916 front of that newline, then changes don't affect the display.
17917 This case happens with stealth-fontification. Note that although
17918 the display is unchanged, glyph positions in the matrix have to
17919 be adjusted, of course. */
17920 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17921 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17922 && ((last_changed_charpos < CHARPOS (start)
17923 && CHARPOS (start) == BEGV)
17924 || (last_changed_charpos < CHARPOS (start) - 1
17925 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17926 {
17927 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17928 struct glyph_row *r0;
17929
17930 /* Compute how many chars/bytes have been added to or removed
17931 from the buffer. */
17932 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17933 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17934 Z_delta = Z - Z_old;
17935 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17936
17937 /* Give up if PT is not in the window. Note that it already has
17938 been checked at the start of try_window_id that PT is not in
17939 front of the window start. */
17940 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17941 GIVE_UP (13);
17942
17943 /* If window start is unchanged, we can reuse the whole matrix
17944 as is, after adjusting glyph positions. No need to compute
17945 the window end again, since its offset from Z hasn't changed. */
17946 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17947 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17948 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17949 /* PT must not be in a partially visible line. */
17950 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17951 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17952 {
17953 /* Adjust positions in the glyph matrix. */
17954 if (Z_delta || Z_delta_bytes)
17955 {
17956 struct glyph_row *r1
17957 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17958 increment_matrix_positions (w->current_matrix,
17959 MATRIX_ROW_VPOS (r0, current_matrix),
17960 MATRIX_ROW_VPOS (r1, current_matrix),
17961 Z_delta, Z_delta_bytes);
17962 }
17963
17964 /* Set the cursor. */
17965 row = row_containing_pos (w, PT, r0, NULL, 0);
17966 if (row)
17967 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17968 return 1;
17969 }
17970 }
17971
17972 /* Handle the case that changes are all below what is displayed in
17973 the window, and that PT is in the window. This shortcut cannot
17974 be taken if ZV is visible in the window, and text has been added
17975 there that is visible in the window. */
17976 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17977 /* ZV is not visible in the window, or there are no
17978 changes at ZV, actually. */
17979 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17980 || first_changed_charpos == last_changed_charpos))
17981 {
17982 struct glyph_row *r0;
17983
17984 /* Give up if PT is not in the window. Note that it already has
17985 been checked at the start of try_window_id that PT is not in
17986 front of the window start. */
17987 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17988 GIVE_UP (14);
17989
17990 /* If window start is unchanged, we can reuse the whole matrix
17991 as is, without changing glyph positions since no text has
17992 been added/removed in front of the window end. */
17993 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17994 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17995 /* PT must not be in a partially visible line. */
17996 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17997 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17998 {
17999 /* We have to compute the window end anew since text
18000 could have been added/removed after it. */
18001 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18002 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18003
18004 /* Set the cursor. */
18005 row = row_containing_pos (w, PT, r0, NULL, 0);
18006 if (row)
18007 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18008 return 2;
18009 }
18010 }
18011
18012 /* Give up if window start is in the changed area.
18013
18014 The condition used to read
18015
18016 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18017
18018 but why that was tested escapes me at the moment. */
18019 if (CHARPOS (start) >= first_changed_charpos
18020 && CHARPOS (start) <= last_changed_charpos)
18021 GIVE_UP (15);
18022
18023 /* Check that window start agrees with the start of the first glyph
18024 row in its current matrix. Check this after we know the window
18025 start is not in changed text, otherwise positions would not be
18026 comparable. */
18027 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18028 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18029 GIVE_UP (16);
18030
18031 /* Give up if the window ends in strings. Overlay strings
18032 at the end are difficult to handle, so don't try. */
18033 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18034 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18035 GIVE_UP (20);
18036
18037 /* Compute the position at which we have to start displaying new
18038 lines. Some of the lines at the top of the window might be
18039 reusable because they are not displaying changed text. Find the
18040 last row in W's current matrix not affected by changes at the
18041 start of current_buffer. Value is null if changes start in the
18042 first line of window. */
18043 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18044 if (last_unchanged_at_beg_row)
18045 {
18046 /* Avoid starting to display in the middle of a character, a TAB
18047 for instance. This is easier than to set up the iterator
18048 exactly, and it's not a frequent case, so the additional
18049 effort wouldn't really pay off. */
18050 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18051 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18052 && last_unchanged_at_beg_row > w->current_matrix->rows)
18053 --last_unchanged_at_beg_row;
18054
18055 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18056 GIVE_UP (17);
18057
18058 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
18059 GIVE_UP (18);
18060 start_pos = it.current.pos;
18061
18062 /* Start displaying new lines in the desired matrix at the same
18063 vpos we would use in the current matrix, i.e. below
18064 last_unchanged_at_beg_row. */
18065 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18066 current_matrix);
18067 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18068 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18069
18070 eassert (it.hpos == 0 && it.current_x == 0);
18071 }
18072 else
18073 {
18074 /* There are no reusable lines at the start of the window.
18075 Start displaying in the first text line. */
18076 start_display (&it, w, start);
18077 it.vpos = it.first_vpos;
18078 start_pos = it.current.pos;
18079 }
18080
18081 /* Find the first row that is not affected by changes at the end of
18082 the buffer. Value will be null if there is no unchanged row, in
18083 which case we must redisplay to the end of the window. delta
18084 will be set to the value by which buffer positions beginning with
18085 first_unchanged_at_end_row have to be adjusted due to text
18086 changes. */
18087 first_unchanged_at_end_row
18088 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18089 IF_DEBUG (debug_delta = delta);
18090 IF_DEBUG (debug_delta_bytes = delta_bytes);
18091
18092 /* Set stop_pos to the buffer position up to which we will have to
18093 display new lines. If first_unchanged_at_end_row != NULL, this
18094 is the buffer position of the start of the line displayed in that
18095 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18096 that we don't stop at a buffer position. */
18097 stop_pos = 0;
18098 if (first_unchanged_at_end_row)
18099 {
18100 eassert (last_unchanged_at_beg_row == NULL
18101 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18102
18103 /* If this is a continuation line, move forward to the next one
18104 that isn't. Changes in lines above affect this line.
18105 Caution: this may move first_unchanged_at_end_row to a row
18106 not displaying text. */
18107 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18108 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18109 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18110 < it.last_visible_y))
18111 ++first_unchanged_at_end_row;
18112
18113 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18114 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18115 >= it.last_visible_y))
18116 first_unchanged_at_end_row = NULL;
18117 else
18118 {
18119 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18120 + delta);
18121 first_unchanged_at_end_vpos
18122 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18123 eassert (stop_pos >= Z - END_UNCHANGED);
18124 }
18125 }
18126 else if (last_unchanged_at_beg_row == NULL)
18127 GIVE_UP (19);
18128
18129
18130 #ifdef GLYPH_DEBUG
18131
18132 /* Either there is no unchanged row at the end, or the one we have
18133 now displays text. This is a necessary condition for the window
18134 end pos calculation at the end of this function. */
18135 eassert (first_unchanged_at_end_row == NULL
18136 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18137
18138 debug_last_unchanged_at_beg_vpos
18139 = (last_unchanged_at_beg_row
18140 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18141 : -1);
18142 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18143
18144 #endif /* GLYPH_DEBUG */
18145
18146
18147 /* Display new lines. Set last_text_row to the last new line
18148 displayed which has text on it, i.e. might end up as being the
18149 line where the window_end_vpos is. */
18150 w->cursor.vpos = -1;
18151 last_text_row = NULL;
18152 overlay_arrow_seen = 0;
18153 if (it.current_y < it.last_visible_y
18154 && !f->fonts_changed
18155 && (first_unchanged_at_end_row == NULL
18156 || IT_CHARPOS (it) < stop_pos))
18157 it.glyph_row->reversed_p = false;
18158 while (it.current_y < it.last_visible_y
18159 && !f->fonts_changed
18160 && (first_unchanged_at_end_row == NULL
18161 || IT_CHARPOS (it) < stop_pos))
18162 {
18163 if (display_line (&it))
18164 last_text_row = it.glyph_row - 1;
18165 }
18166
18167 if (f->fonts_changed)
18168 return -1;
18169
18170
18171 /* Compute differences in buffer positions, y-positions etc. for
18172 lines reused at the bottom of the window. Compute what we can
18173 scroll. */
18174 if (first_unchanged_at_end_row
18175 /* No lines reused because we displayed everything up to the
18176 bottom of the window. */
18177 && it.current_y < it.last_visible_y)
18178 {
18179 dvpos = (it.vpos
18180 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18181 current_matrix));
18182 dy = it.current_y - first_unchanged_at_end_row->y;
18183 run.current_y = first_unchanged_at_end_row->y;
18184 run.desired_y = run.current_y + dy;
18185 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18186 }
18187 else
18188 {
18189 delta = delta_bytes = dvpos = dy
18190 = run.current_y = run.desired_y = run.height = 0;
18191 first_unchanged_at_end_row = NULL;
18192 }
18193 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18194
18195
18196 /* Find the cursor if not already found. We have to decide whether
18197 PT will appear on this window (it sometimes doesn't, but this is
18198 not a very frequent case.) This decision has to be made before
18199 the current matrix is altered. A value of cursor.vpos < 0 means
18200 that PT is either in one of the lines beginning at
18201 first_unchanged_at_end_row or below the window. Don't care for
18202 lines that might be displayed later at the window end; as
18203 mentioned, this is not a frequent case. */
18204 if (w->cursor.vpos < 0)
18205 {
18206 /* Cursor in unchanged rows at the top? */
18207 if (PT < CHARPOS (start_pos)
18208 && last_unchanged_at_beg_row)
18209 {
18210 row = row_containing_pos (w, PT,
18211 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
18212 last_unchanged_at_beg_row + 1, 0);
18213 if (row)
18214 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
18215 }
18216
18217 /* Start from first_unchanged_at_end_row looking for PT. */
18218 else if (first_unchanged_at_end_row)
18219 {
18220 row = row_containing_pos (w, PT - delta,
18221 first_unchanged_at_end_row, NULL, 0);
18222 if (row)
18223 set_cursor_from_row (w, row, w->current_matrix, delta,
18224 delta_bytes, dy, dvpos);
18225 }
18226
18227 /* Give up if cursor was not found. */
18228 if (w->cursor.vpos < 0)
18229 {
18230 clear_glyph_matrix (w->desired_matrix);
18231 return -1;
18232 }
18233 }
18234
18235 /* Don't let the cursor end in the scroll margins. */
18236 {
18237 int this_scroll_margin, cursor_height;
18238 int frame_line_height = default_line_pixel_height (w);
18239 int window_total_lines
18240 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
18241
18242 this_scroll_margin =
18243 max (0, min (scroll_margin, window_total_lines / 4));
18244 this_scroll_margin *= frame_line_height;
18245 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
18246
18247 if ((w->cursor.y < this_scroll_margin
18248 && CHARPOS (start) > BEGV)
18249 /* Old redisplay didn't take scroll margin into account at the bottom,
18250 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
18251 || (w->cursor.y + (make_cursor_line_fully_visible_p
18252 ? cursor_height + this_scroll_margin
18253 : 1)) > it.last_visible_y)
18254 {
18255 w->cursor.vpos = -1;
18256 clear_glyph_matrix (w->desired_matrix);
18257 return -1;
18258 }
18259 }
18260
18261 /* Scroll the display. Do it before changing the current matrix so
18262 that xterm.c doesn't get confused about where the cursor glyph is
18263 found. */
18264 if (dy && run.height)
18265 {
18266 update_begin (f);
18267
18268 if (FRAME_WINDOW_P (f))
18269 {
18270 FRAME_RIF (f)->update_window_begin_hook (w);
18271 FRAME_RIF (f)->clear_window_mouse_face (w);
18272 FRAME_RIF (f)->scroll_run_hook (w, &run);
18273 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
18274 }
18275 else
18276 {
18277 /* Terminal frame. In this case, dvpos gives the number of
18278 lines to scroll by; dvpos < 0 means scroll up. */
18279 int from_vpos
18280 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
18281 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
18282 int end = (WINDOW_TOP_EDGE_LINE (w)
18283 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
18284 + window_internal_height (w));
18285
18286 #if defined (HAVE_GPM) || defined (MSDOS)
18287 x_clear_window_mouse_face (w);
18288 #endif
18289 /* Perform the operation on the screen. */
18290 if (dvpos > 0)
18291 {
18292 /* Scroll last_unchanged_at_beg_row to the end of the
18293 window down dvpos lines. */
18294 set_terminal_window (f, end);
18295
18296 /* On dumb terminals delete dvpos lines at the end
18297 before inserting dvpos empty lines. */
18298 if (!FRAME_SCROLL_REGION_OK (f))
18299 ins_del_lines (f, end - dvpos, -dvpos);
18300
18301 /* Insert dvpos empty lines in front of
18302 last_unchanged_at_beg_row. */
18303 ins_del_lines (f, from, dvpos);
18304 }
18305 else if (dvpos < 0)
18306 {
18307 /* Scroll up last_unchanged_at_beg_vpos to the end of
18308 the window to last_unchanged_at_beg_vpos - |dvpos|. */
18309 set_terminal_window (f, end);
18310
18311 /* Delete dvpos lines in front of
18312 last_unchanged_at_beg_vpos. ins_del_lines will set
18313 the cursor to the given vpos and emit |dvpos| delete
18314 line sequences. */
18315 ins_del_lines (f, from + dvpos, dvpos);
18316
18317 /* On a dumb terminal insert dvpos empty lines at the
18318 end. */
18319 if (!FRAME_SCROLL_REGION_OK (f))
18320 ins_del_lines (f, end + dvpos, -dvpos);
18321 }
18322
18323 set_terminal_window (f, 0);
18324 }
18325
18326 update_end (f);
18327 }
18328
18329 /* Shift reused rows of the current matrix to the right position.
18330 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
18331 text. */
18332 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18333 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
18334 if (dvpos < 0)
18335 {
18336 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
18337 bottom_vpos, dvpos);
18338 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
18339 bottom_vpos);
18340 }
18341 else if (dvpos > 0)
18342 {
18343 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
18344 bottom_vpos, dvpos);
18345 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
18346 first_unchanged_at_end_vpos + dvpos);
18347 }
18348
18349 /* For frame-based redisplay, make sure that current frame and window
18350 matrix are in sync with respect to glyph memory. */
18351 if (!FRAME_WINDOW_P (f))
18352 sync_frame_with_window_matrix_rows (w);
18353
18354 /* Adjust buffer positions in reused rows. */
18355 if (delta || delta_bytes)
18356 increment_matrix_positions (current_matrix,
18357 first_unchanged_at_end_vpos + dvpos,
18358 bottom_vpos, delta, delta_bytes);
18359
18360 /* Adjust Y positions. */
18361 if (dy)
18362 shift_glyph_matrix (w, current_matrix,
18363 first_unchanged_at_end_vpos + dvpos,
18364 bottom_vpos, dy);
18365
18366 if (first_unchanged_at_end_row)
18367 {
18368 first_unchanged_at_end_row += dvpos;
18369 if (first_unchanged_at_end_row->y >= it.last_visible_y
18370 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
18371 first_unchanged_at_end_row = NULL;
18372 }
18373
18374 /* If scrolling up, there may be some lines to display at the end of
18375 the window. */
18376 last_text_row_at_end = NULL;
18377 if (dy < 0)
18378 {
18379 /* Scrolling up can leave for example a partially visible line
18380 at the end of the window to be redisplayed. */
18381 /* Set last_row to the glyph row in the current matrix where the
18382 window end line is found. It has been moved up or down in
18383 the matrix by dvpos. */
18384 int last_vpos = w->window_end_vpos + dvpos;
18385 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
18386
18387 /* If last_row is the window end line, it should display text. */
18388 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
18389
18390 /* If window end line was partially visible before, begin
18391 displaying at that line. Otherwise begin displaying with the
18392 line following it. */
18393 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
18394 {
18395 init_to_row_start (&it, w, last_row);
18396 it.vpos = last_vpos;
18397 it.current_y = last_row->y;
18398 }
18399 else
18400 {
18401 init_to_row_end (&it, w, last_row);
18402 it.vpos = 1 + last_vpos;
18403 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
18404 ++last_row;
18405 }
18406
18407 /* We may start in a continuation line. If so, we have to
18408 get the right continuation_lines_width and current_x. */
18409 it.continuation_lines_width = last_row->continuation_lines_width;
18410 it.hpos = it.current_x = 0;
18411
18412 /* Display the rest of the lines at the window end. */
18413 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18414 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18415 {
18416 /* Is it always sure that the display agrees with lines in
18417 the current matrix? I don't think so, so we mark rows
18418 displayed invalid in the current matrix by setting their
18419 enabled_p flag to zero. */
18420 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
18421 if (display_line (&it))
18422 last_text_row_at_end = it.glyph_row - 1;
18423 }
18424 }
18425
18426 /* Update window_end_pos and window_end_vpos. */
18427 if (first_unchanged_at_end_row && !last_text_row_at_end)
18428 {
18429 /* Window end line if one of the preserved rows from the current
18430 matrix. Set row to the last row displaying text in current
18431 matrix starting at first_unchanged_at_end_row, after
18432 scrolling. */
18433 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18434 row = find_last_row_displaying_text (w->current_matrix, &it,
18435 first_unchanged_at_end_row);
18436 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
18437 adjust_window_ends (w, row, 1);
18438 eassert (w->window_end_bytepos >= 0);
18439 IF_DEBUG (debug_method_add (w, "A"));
18440 }
18441 else if (last_text_row_at_end)
18442 {
18443 adjust_window_ends (w, last_text_row_at_end, 0);
18444 eassert (w->window_end_bytepos >= 0);
18445 IF_DEBUG (debug_method_add (w, "B"));
18446 }
18447 else if (last_text_row)
18448 {
18449 /* We have displayed either to the end of the window or at the
18450 end of the window, i.e. the last row with text is to be found
18451 in the desired matrix. */
18452 adjust_window_ends (w, last_text_row, 0);
18453 eassert (w->window_end_bytepos >= 0);
18454 }
18455 else if (first_unchanged_at_end_row == NULL
18456 && last_text_row == NULL
18457 && last_text_row_at_end == NULL)
18458 {
18459 /* Displayed to end of window, but no line containing text was
18460 displayed. Lines were deleted at the end of the window. */
18461 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
18462 int vpos = w->window_end_vpos;
18463 struct glyph_row *current_row = current_matrix->rows + vpos;
18464 struct glyph_row *desired_row = desired_matrix->rows + vpos;
18465
18466 for (row = NULL;
18467 row == NULL && vpos >= first_vpos;
18468 --vpos, --current_row, --desired_row)
18469 {
18470 if (desired_row->enabled_p)
18471 {
18472 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
18473 row = desired_row;
18474 }
18475 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
18476 row = current_row;
18477 }
18478
18479 eassert (row != NULL);
18480 w->window_end_vpos = vpos + 1;
18481 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18482 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18483 eassert (w->window_end_bytepos >= 0);
18484 IF_DEBUG (debug_method_add (w, "C"));
18485 }
18486 else
18487 emacs_abort ();
18488
18489 IF_DEBUG ((debug_end_pos = w->window_end_pos,
18490 debug_end_vpos = w->window_end_vpos));
18491
18492 /* Record that display has not been completed. */
18493 w->window_end_valid = 0;
18494 w->desired_matrix->no_scrolling_p = 1;
18495 return 3;
18496
18497 #undef GIVE_UP
18498 }
18499
18500
18501 \f
18502 /***********************************************************************
18503 More debugging support
18504 ***********************************************************************/
18505
18506 #ifdef GLYPH_DEBUG
18507
18508 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
18509 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
18510 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
18511
18512
18513 /* Dump the contents of glyph matrix MATRIX on stderr.
18514
18515 GLYPHS 0 means don't show glyph contents.
18516 GLYPHS 1 means show glyphs in short form
18517 GLYPHS > 1 means show glyphs in long form. */
18518
18519 void
18520 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
18521 {
18522 int i;
18523 for (i = 0; i < matrix->nrows; ++i)
18524 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
18525 }
18526
18527
18528 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
18529 the glyph row and area where the glyph comes from. */
18530
18531 void
18532 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18533 {
18534 if (glyph->type == CHAR_GLYPH
18535 || glyph->type == GLYPHLESS_GLYPH)
18536 {
18537 fprintf (stderr,
18538 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18539 glyph - row->glyphs[TEXT_AREA],
18540 (glyph->type == CHAR_GLYPH
18541 ? 'C'
18542 : 'G'),
18543 glyph->charpos,
18544 (BUFFERP (glyph->object)
18545 ? 'B'
18546 : (STRINGP (glyph->object)
18547 ? 'S'
18548 : (INTEGERP (glyph->object)
18549 ? '0'
18550 : '-'))),
18551 glyph->pixel_width,
18552 glyph->u.ch,
18553 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
18554 ? glyph->u.ch
18555 : '.'),
18556 glyph->face_id,
18557 glyph->left_box_line_p,
18558 glyph->right_box_line_p);
18559 }
18560 else if (glyph->type == STRETCH_GLYPH)
18561 {
18562 fprintf (stderr,
18563 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18564 glyph - row->glyphs[TEXT_AREA],
18565 'S',
18566 glyph->charpos,
18567 (BUFFERP (glyph->object)
18568 ? 'B'
18569 : (STRINGP (glyph->object)
18570 ? 'S'
18571 : (INTEGERP (glyph->object)
18572 ? '0'
18573 : '-'))),
18574 glyph->pixel_width,
18575 0,
18576 ' ',
18577 glyph->face_id,
18578 glyph->left_box_line_p,
18579 glyph->right_box_line_p);
18580 }
18581 else if (glyph->type == IMAGE_GLYPH)
18582 {
18583 fprintf (stderr,
18584 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18585 glyph - row->glyphs[TEXT_AREA],
18586 'I',
18587 glyph->charpos,
18588 (BUFFERP (glyph->object)
18589 ? 'B'
18590 : (STRINGP (glyph->object)
18591 ? 'S'
18592 : (INTEGERP (glyph->object)
18593 ? '0'
18594 : '-'))),
18595 glyph->pixel_width,
18596 glyph->u.img_id,
18597 '.',
18598 glyph->face_id,
18599 glyph->left_box_line_p,
18600 glyph->right_box_line_p);
18601 }
18602 else if (glyph->type == COMPOSITE_GLYPH)
18603 {
18604 fprintf (stderr,
18605 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
18606 glyph - row->glyphs[TEXT_AREA],
18607 '+',
18608 glyph->charpos,
18609 (BUFFERP (glyph->object)
18610 ? 'B'
18611 : (STRINGP (glyph->object)
18612 ? 'S'
18613 : (INTEGERP (glyph->object)
18614 ? '0'
18615 : '-'))),
18616 glyph->pixel_width,
18617 glyph->u.cmp.id);
18618 if (glyph->u.cmp.automatic)
18619 fprintf (stderr,
18620 "[%d-%d]",
18621 glyph->slice.cmp.from, glyph->slice.cmp.to);
18622 fprintf (stderr, " . %4d %1.1d%1.1d\n",
18623 glyph->face_id,
18624 glyph->left_box_line_p,
18625 glyph->right_box_line_p);
18626 }
18627 }
18628
18629
18630 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
18631 GLYPHS 0 means don't show glyph contents.
18632 GLYPHS 1 means show glyphs in short form
18633 GLYPHS > 1 means show glyphs in long form. */
18634
18635 void
18636 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
18637 {
18638 if (glyphs != 1)
18639 {
18640 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
18641 fprintf (stderr, "==============================================================================\n");
18642
18643 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
18644 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
18645 vpos,
18646 MATRIX_ROW_START_CHARPOS (row),
18647 MATRIX_ROW_END_CHARPOS (row),
18648 row->used[TEXT_AREA],
18649 row->contains_overlapping_glyphs_p,
18650 row->enabled_p,
18651 row->truncated_on_left_p,
18652 row->truncated_on_right_p,
18653 row->continued_p,
18654 MATRIX_ROW_CONTINUATION_LINE_P (row),
18655 MATRIX_ROW_DISPLAYS_TEXT_P (row),
18656 row->ends_at_zv_p,
18657 row->fill_line_p,
18658 row->ends_in_middle_of_char_p,
18659 row->starts_in_middle_of_char_p,
18660 row->mouse_face_p,
18661 row->x,
18662 row->y,
18663 row->pixel_width,
18664 row->height,
18665 row->visible_height,
18666 row->ascent,
18667 row->phys_ascent);
18668 /* The next 3 lines should align to "Start" in the header. */
18669 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18670 row->end.overlay_string_index,
18671 row->continuation_lines_width);
18672 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18673 CHARPOS (row->start.string_pos),
18674 CHARPOS (row->end.string_pos));
18675 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18676 row->end.dpvec_index);
18677 }
18678
18679 if (glyphs > 1)
18680 {
18681 int area;
18682
18683 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18684 {
18685 struct glyph *glyph = row->glyphs[area];
18686 struct glyph *glyph_end = glyph + row->used[area];
18687
18688 /* Glyph for a line end in text. */
18689 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18690 ++glyph_end;
18691
18692 if (glyph < glyph_end)
18693 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18694
18695 for (; glyph < glyph_end; ++glyph)
18696 dump_glyph (row, glyph, area);
18697 }
18698 }
18699 else if (glyphs == 1)
18700 {
18701 int area;
18702 char s[SHRT_MAX + 4];
18703
18704 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18705 {
18706 int i;
18707
18708 for (i = 0; i < row->used[area]; ++i)
18709 {
18710 struct glyph *glyph = row->glyphs[area] + i;
18711 if (i == row->used[area] - 1
18712 && area == TEXT_AREA
18713 && INTEGERP (glyph->object)
18714 && glyph->type == CHAR_GLYPH
18715 && glyph->u.ch == ' ')
18716 {
18717 strcpy (&s[i], "[\\n]");
18718 i += 4;
18719 }
18720 else if (glyph->type == CHAR_GLYPH
18721 && glyph->u.ch < 0x80
18722 && glyph->u.ch >= ' ')
18723 s[i] = glyph->u.ch;
18724 else
18725 s[i] = '.';
18726 }
18727
18728 s[i] = '\0';
18729 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18730 }
18731 }
18732 }
18733
18734
18735 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18736 Sdump_glyph_matrix, 0, 1, "p",
18737 doc: /* Dump the current matrix of the selected window to stderr.
18738 Shows contents of glyph row structures. With non-nil
18739 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18740 glyphs in short form, otherwise show glyphs in long form. */)
18741 (Lisp_Object glyphs)
18742 {
18743 struct window *w = XWINDOW (selected_window);
18744 struct buffer *buffer = XBUFFER (w->contents);
18745
18746 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18747 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18748 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18749 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18750 fprintf (stderr, "=============================================\n");
18751 dump_glyph_matrix (w->current_matrix,
18752 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18753 return Qnil;
18754 }
18755
18756
18757 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18758 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18759 (void)
18760 {
18761 struct frame *f = XFRAME (selected_frame);
18762 dump_glyph_matrix (f->current_matrix, 1);
18763 return Qnil;
18764 }
18765
18766
18767 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18768 doc: /* Dump glyph row ROW to stderr.
18769 GLYPH 0 means don't dump glyphs.
18770 GLYPH 1 means dump glyphs in short form.
18771 GLYPH > 1 or omitted means dump glyphs in long form. */)
18772 (Lisp_Object row, Lisp_Object glyphs)
18773 {
18774 struct glyph_matrix *matrix;
18775 EMACS_INT vpos;
18776
18777 CHECK_NUMBER (row);
18778 matrix = XWINDOW (selected_window)->current_matrix;
18779 vpos = XINT (row);
18780 if (vpos >= 0 && vpos < matrix->nrows)
18781 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18782 vpos,
18783 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18784 return Qnil;
18785 }
18786
18787
18788 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18789 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18790 GLYPH 0 means don't dump glyphs.
18791 GLYPH 1 means dump glyphs in short form.
18792 GLYPH > 1 or omitted means dump glyphs in long form.
18793
18794 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
18795 do nothing. */)
18796 (Lisp_Object row, Lisp_Object glyphs)
18797 {
18798 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
18799 struct frame *sf = SELECTED_FRAME ();
18800 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18801 EMACS_INT vpos;
18802
18803 CHECK_NUMBER (row);
18804 vpos = XINT (row);
18805 if (vpos >= 0 && vpos < m->nrows)
18806 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18807 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18808 #endif
18809 return Qnil;
18810 }
18811
18812
18813 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18814 doc: /* Toggle tracing of redisplay.
18815 With ARG, turn tracing on if and only if ARG is positive. */)
18816 (Lisp_Object arg)
18817 {
18818 if (NILP (arg))
18819 trace_redisplay_p = !trace_redisplay_p;
18820 else
18821 {
18822 arg = Fprefix_numeric_value (arg);
18823 trace_redisplay_p = XINT (arg) > 0;
18824 }
18825
18826 return Qnil;
18827 }
18828
18829
18830 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18831 doc: /* Like `format', but print result to stderr.
18832 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18833 (ptrdiff_t nargs, Lisp_Object *args)
18834 {
18835 Lisp_Object s = Fformat (nargs, args);
18836 fprintf (stderr, "%s", SDATA (s));
18837 return Qnil;
18838 }
18839
18840 #endif /* GLYPH_DEBUG */
18841
18842
18843 \f
18844 /***********************************************************************
18845 Building Desired Matrix Rows
18846 ***********************************************************************/
18847
18848 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18849 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18850
18851 static struct glyph_row *
18852 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18853 {
18854 struct frame *f = XFRAME (WINDOW_FRAME (w));
18855 struct buffer *buffer = XBUFFER (w->contents);
18856 struct buffer *old = current_buffer;
18857 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18858 int arrow_len = SCHARS (overlay_arrow_string);
18859 const unsigned char *arrow_end = arrow_string + arrow_len;
18860 const unsigned char *p;
18861 struct it it;
18862 bool multibyte_p;
18863 int n_glyphs_before;
18864
18865 set_buffer_temp (buffer);
18866 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18867 scratch_glyph_row.reversed_p = false;
18868 it.glyph_row->used[TEXT_AREA] = 0;
18869 SET_TEXT_POS (it.position, 0, 0);
18870
18871 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18872 p = arrow_string;
18873 while (p < arrow_end)
18874 {
18875 Lisp_Object face, ilisp;
18876
18877 /* Get the next character. */
18878 if (multibyte_p)
18879 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18880 else
18881 {
18882 it.c = it.char_to_display = *p, it.len = 1;
18883 if (! ASCII_CHAR_P (it.c))
18884 it.char_to_display = BYTE8_TO_CHAR (it.c);
18885 }
18886 p += it.len;
18887
18888 /* Get its face. */
18889 ilisp = make_number (p - arrow_string);
18890 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18891 it.face_id = compute_char_face (f, it.char_to_display, face);
18892
18893 /* Compute its width, get its glyphs. */
18894 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18895 SET_TEXT_POS (it.position, -1, -1);
18896 PRODUCE_GLYPHS (&it);
18897
18898 /* If this character doesn't fit any more in the line, we have
18899 to remove some glyphs. */
18900 if (it.current_x > it.last_visible_x)
18901 {
18902 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18903 break;
18904 }
18905 }
18906
18907 set_buffer_temp (old);
18908 return it.glyph_row;
18909 }
18910
18911
18912 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18913 glyphs to insert is determined by produce_special_glyphs. */
18914
18915 static void
18916 insert_left_trunc_glyphs (struct it *it)
18917 {
18918 struct it truncate_it;
18919 struct glyph *from, *end, *to, *toend;
18920
18921 eassert (!FRAME_WINDOW_P (it->f)
18922 || (!it->glyph_row->reversed_p
18923 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18924 || (it->glyph_row->reversed_p
18925 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18926
18927 /* Get the truncation glyphs. */
18928 truncate_it = *it;
18929 truncate_it.current_x = 0;
18930 truncate_it.face_id = DEFAULT_FACE_ID;
18931 truncate_it.glyph_row = &scratch_glyph_row;
18932 truncate_it.area = TEXT_AREA;
18933 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18934 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18935 truncate_it.object = make_number (0);
18936 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18937
18938 /* Overwrite glyphs from IT with truncation glyphs. */
18939 if (!it->glyph_row->reversed_p)
18940 {
18941 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18942
18943 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18944 end = from + tused;
18945 to = it->glyph_row->glyphs[TEXT_AREA];
18946 toend = to + it->glyph_row->used[TEXT_AREA];
18947 if (FRAME_WINDOW_P (it->f))
18948 {
18949 /* On GUI frames, when variable-size fonts are displayed,
18950 the truncation glyphs may need more pixels than the row's
18951 glyphs they overwrite. We overwrite more glyphs to free
18952 enough screen real estate, and enlarge the stretch glyph
18953 on the right (see display_line), if there is one, to
18954 preserve the screen position of the truncation glyphs on
18955 the right. */
18956 int w = 0;
18957 struct glyph *g = to;
18958 short used;
18959
18960 /* The first glyph could be partially visible, in which case
18961 it->glyph_row->x will be negative. But we want the left
18962 truncation glyphs to be aligned at the left margin of the
18963 window, so we override the x coordinate at which the row
18964 will begin. */
18965 it->glyph_row->x = 0;
18966 while (g < toend && w < it->truncation_pixel_width)
18967 {
18968 w += g->pixel_width;
18969 ++g;
18970 }
18971 if (g - to - tused > 0)
18972 {
18973 memmove (to + tused, g, (toend - g) * sizeof(*g));
18974 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18975 }
18976 used = it->glyph_row->used[TEXT_AREA];
18977 if (it->glyph_row->truncated_on_right_p
18978 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18979 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18980 == STRETCH_GLYPH)
18981 {
18982 int extra = w - it->truncation_pixel_width;
18983
18984 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18985 }
18986 }
18987
18988 while (from < end)
18989 *to++ = *from++;
18990
18991 /* There may be padding glyphs left over. Overwrite them too. */
18992 if (!FRAME_WINDOW_P (it->f))
18993 {
18994 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18995 {
18996 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18997 while (from < end)
18998 *to++ = *from++;
18999 }
19000 }
19001
19002 if (to > toend)
19003 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19004 }
19005 else
19006 {
19007 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19008
19009 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19010 that back to front. */
19011 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19012 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19013 toend = it->glyph_row->glyphs[TEXT_AREA];
19014 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19015 if (FRAME_WINDOW_P (it->f))
19016 {
19017 int w = 0;
19018 struct glyph *g = to;
19019
19020 while (g >= toend && w < it->truncation_pixel_width)
19021 {
19022 w += g->pixel_width;
19023 --g;
19024 }
19025 if (to - g - tused > 0)
19026 to = g + tused;
19027 if (it->glyph_row->truncated_on_right_p
19028 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19029 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19030 {
19031 int extra = w - it->truncation_pixel_width;
19032
19033 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19034 }
19035 }
19036
19037 while (from >= end && to >= toend)
19038 *to-- = *from--;
19039 if (!FRAME_WINDOW_P (it->f))
19040 {
19041 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19042 {
19043 from =
19044 truncate_it.glyph_row->glyphs[TEXT_AREA]
19045 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19046 while (from >= end && to >= toend)
19047 *to-- = *from--;
19048 }
19049 }
19050 if (from >= end)
19051 {
19052 /* Need to free some room before prepending additional
19053 glyphs. */
19054 int move_by = from - end + 1;
19055 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19056 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19057
19058 for ( ; g >= g0; g--)
19059 g[move_by] = *g;
19060 while (from >= end)
19061 *to-- = *from--;
19062 it->glyph_row->used[TEXT_AREA] += move_by;
19063 }
19064 }
19065 }
19066
19067 /* Compute the hash code for ROW. */
19068 unsigned
19069 row_hash (struct glyph_row *row)
19070 {
19071 int area, k;
19072 unsigned hashval = 0;
19073
19074 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19075 for (k = 0; k < row->used[area]; ++k)
19076 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19077 + row->glyphs[area][k].u.val
19078 + row->glyphs[area][k].face_id
19079 + row->glyphs[area][k].padding_p
19080 + (row->glyphs[area][k].type << 2));
19081
19082 return hashval;
19083 }
19084
19085 /* Compute the pixel height and width of IT->glyph_row.
19086
19087 Most of the time, ascent and height of a display line will be equal
19088 to the max_ascent and max_height values of the display iterator
19089 structure. This is not the case if
19090
19091 1. We hit ZV without displaying anything. In this case, max_ascent
19092 and max_height will be zero.
19093
19094 2. We have some glyphs that don't contribute to the line height.
19095 (The glyph row flag contributes_to_line_height_p is for future
19096 pixmap extensions).
19097
19098 The first case is easily covered by using default values because in
19099 these cases, the line height does not really matter, except that it
19100 must not be zero. */
19101
19102 static void
19103 compute_line_metrics (struct it *it)
19104 {
19105 struct glyph_row *row = it->glyph_row;
19106
19107 if (FRAME_WINDOW_P (it->f))
19108 {
19109 int i, min_y, max_y;
19110
19111 /* The line may consist of one space only, that was added to
19112 place the cursor on it. If so, the row's height hasn't been
19113 computed yet. */
19114 if (row->height == 0)
19115 {
19116 if (it->max_ascent + it->max_descent == 0)
19117 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19118 row->ascent = it->max_ascent;
19119 row->height = it->max_ascent + it->max_descent;
19120 row->phys_ascent = it->max_phys_ascent;
19121 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19122 row->extra_line_spacing = it->max_extra_line_spacing;
19123 }
19124
19125 /* Compute the width of this line. */
19126 row->pixel_width = row->x;
19127 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19128 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19129
19130 eassert (row->pixel_width >= 0);
19131 eassert (row->ascent >= 0 && row->height > 0);
19132
19133 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19134 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19135
19136 /* If first line's physical ascent is larger than its logical
19137 ascent, use the physical ascent, and make the row taller.
19138 This makes accented characters fully visible. */
19139 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19140 && row->phys_ascent > row->ascent)
19141 {
19142 row->height += row->phys_ascent - row->ascent;
19143 row->ascent = row->phys_ascent;
19144 }
19145
19146 /* Compute how much of the line is visible. */
19147 row->visible_height = row->height;
19148
19149 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19150 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19151
19152 if (row->y < min_y)
19153 row->visible_height -= min_y - row->y;
19154 if (row->y + row->height > max_y)
19155 row->visible_height -= row->y + row->height - max_y;
19156 }
19157 else
19158 {
19159 row->pixel_width = row->used[TEXT_AREA];
19160 if (row->continued_p)
19161 row->pixel_width -= it->continuation_pixel_width;
19162 else if (row->truncated_on_right_p)
19163 row->pixel_width -= it->truncation_pixel_width;
19164 row->ascent = row->phys_ascent = 0;
19165 row->height = row->phys_height = row->visible_height = 1;
19166 row->extra_line_spacing = 0;
19167 }
19168
19169 /* Compute a hash code for this row. */
19170 row->hash = row_hash (row);
19171
19172 it->max_ascent = it->max_descent = 0;
19173 it->max_phys_ascent = it->max_phys_descent = 0;
19174 }
19175
19176
19177 /* Append one space to the glyph row of iterator IT if doing a
19178 window-based redisplay. The space has the same face as
19179 IT->face_id. Value is non-zero if a space was added.
19180
19181 This function is called to make sure that there is always one glyph
19182 at the end of a glyph row that the cursor can be set on under
19183 window-systems. (If there weren't such a glyph we would not know
19184 how wide and tall a box cursor should be displayed).
19185
19186 At the same time this space let's a nicely handle clearing to the
19187 end of the line if the row ends in italic text. */
19188
19189 static int
19190 append_space_for_newline (struct it *it, int default_face_p)
19191 {
19192 if (FRAME_WINDOW_P (it->f))
19193 {
19194 int n = it->glyph_row->used[TEXT_AREA];
19195
19196 if (it->glyph_row->glyphs[TEXT_AREA] + n
19197 < it->glyph_row->glyphs[1 + TEXT_AREA])
19198 {
19199 /* Save some values that must not be changed.
19200 Must save IT->c and IT->len because otherwise
19201 ITERATOR_AT_END_P wouldn't work anymore after
19202 append_space_for_newline has been called. */
19203 enum display_element_type saved_what = it->what;
19204 int saved_c = it->c, saved_len = it->len;
19205 int saved_char_to_display = it->char_to_display;
19206 int saved_x = it->current_x;
19207 int saved_face_id = it->face_id;
19208 int saved_box_end = it->end_of_box_run_p;
19209 struct text_pos saved_pos;
19210 Lisp_Object saved_object;
19211 struct face *face;
19212
19213 saved_object = it->object;
19214 saved_pos = it->position;
19215
19216 it->what = IT_CHARACTER;
19217 memset (&it->position, 0, sizeof it->position);
19218 it->object = make_number (0);
19219 it->c = it->char_to_display = ' ';
19220 it->len = 1;
19221
19222 /* If the default face was remapped, be sure to use the
19223 remapped face for the appended newline. */
19224 if (default_face_p)
19225 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
19226 else if (it->face_before_selective_p)
19227 it->face_id = it->saved_face_id;
19228 face = FACE_FROM_ID (it->f, it->face_id);
19229 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
19230 /* In R2L rows, we will prepend a stretch glyph that will
19231 have the end_of_box_run_p flag set for it, so there's no
19232 need for the appended newline glyph to have that flag
19233 set. */
19234 if (it->glyph_row->reversed_p
19235 /* But if the appended newline glyph goes all the way to
19236 the end of the row, there will be no stretch glyph,
19237 so leave the box flag set. */
19238 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
19239 it->end_of_box_run_p = 0;
19240
19241 PRODUCE_GLYPHS (it);
19242
19243 it->override_ascent = -1;
19244 it->constrain_row_ascent_descent_p = 0;
19245 it->current_x = saved_x;
19246 it->object = saved_object;
19247 it->position = saved_pos;
19248 it->what = saved_what;
19249 it->face_id = saved_face_id;
19250 it->len = saved_len;
19251 it->c = saved_c;
19252 it->char_to_display = saved_char_to_display;
19253 it->end_of_box_run_p = saved_box_end;
19254 return 1;
19255 }
19256 }
19257
19258 return 0;
19259 }
19260
19261
19262 /* Extend the face of the last glyph in the text area of IT->glyph_row
19263 to the end of the display line. Called from display_line. If the
19264 glyph row is empty, add a space glyph to it so that we know the
19265 face to draw. Set the glyph row flag fill_line_p. If the glyph
19266 row is R2L, prepend a stretch glyph to cover the empty space to the
19267 left of the leftmost glyph. */
19268
19269 static void
19270 extend_face_to_end_of_line (struct it *it)
19271 {
19272 struct face *face, *default_face;
19273 struct frame *f = it->f;
19274
19275 /* If line is already filled, do nothing. Non window-system frames
19276 get a grace of one more ``pixel'' because their characters are
19277 1-``pixel'' wide, so they hit the equality too early. This grace
19278 is needed only for R2L rows that are not continued, to produce
19279 one extra blank where we could display the cursor. */
19280 if ((it->current_x >= it->last_visible_x
19281 + (!FRAME_WINDOW_P (f)
19282 && it->glyph_row->reversed_p
19283 && !it->glyph_row->continued_p))
19284 /* If the window has display margins, we will need to extend
19285 their face even if the text area is filled. */
19286 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19287 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
19288 return;
19289
19290 /* The default face, possibly remapped. */
19291 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
19292
19293 /* Face extension extends the background and box of IT->face_id
19294 to the end of the line. If the background equals the background
19295 of the frame, we don't have to do anything. */
19296 if (it->face_before_selective_p)
19297 face = FACE_FROM_ID (f, it->saved_face_id);
19298 else
19299 face = FACE_FROM_ID (f, it->face_id);
19300
19301 if (FRAME_WINDOW_P (f)
19302 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
19303 && face->box == FACE_NO_BOX
19304 && face->background == FRAME_BACKGROUND_PIXEL (f)
19305 #ifdef HAVE_WINDOW_SYSTEM
19306 && !face->stipple
19307 #endif
19308 && !it->glyph_row->reversed_p)
19309 return;
19310
19311 /* Set the glyph row flag indicating that the face of the last glyph
19312 in the text area has to be drawn to the end of the text area. */
19313 it->glyph_row->fill_line_p = 1;
19314
19315 /* If current character of IT is not ASCII, make sure we have the
19316 ASCII face. This will be automatically undone the next time
19317 get_next_display_element returns a multibyte character. Note
19318 that the character will always be single byte in unibyte
19319 text. */
19320 if (!ASCII_CHAR_P (it->c))
19321 {
19322 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
19323 }
19324
19325 if (FRAME_WINDOW_P (f))
19326 {
19327 /* If the row is empty, add a space with the current face of IT,
19328 so that we know which face to draw. */
19329 if (it->glyph_row->used[TEXT_AREA] == 0)
19330 {
19331 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
19332 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
19333 it->glyph_row->used[TEXT_AREA] = 1;
19334 }
19335 /* Mode line and the header line don't have margins, and
19336 likewise the frame's tool-bar window, if there is any. */
19337 if (!(it->glyph_row->mode_line_p
19338 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19339 || (WINDOWP (f->tool_bar_window)
19340 && it->w == XWINDOW (f->tool_bar_window))
19341 #endif
19342 ))
19343 {
19344 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19345 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
19346 {
19347 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
19348 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
19349 default_face->id;
19350 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
19351 }
19352 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19353 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
19354 {
19355 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
19356 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
19357 default_face->id;
19358 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
19359 }
19360 }
19361 #ifdef HAVE_WINDOW_SYSTEM
19362 if (it->glyph_row->reversed_p)
19363 {
19364 /* Prepend a stretch glyph to the row, such that the
19365 rightmost glyph will be drawn flushed all the way to the
19366 right margin of the window. The stretch glyph that will
19367 occupy the empty space, if any, to the left of the
19368 glyphs. */
19369 struct font *font = face->font ? face->font : FRAME_FONT (f);
19370 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
19371 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
19372 struct glyph *g;
19373 int row_width, stretch_ascent, stretch_width;
19374 struct text_pos saved_pos;
19375 int saved_face_id, saved_avoid_cursor, saved_box_start;
19376
19377 for (row_width = 0, g = row_start; g < row_end; g++)
19378 row_width += g->pixel_width;
19379 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
19380 if (stretch_width > 0)
19381 {
19382 stretch_ascent =
19383 (((it->ascent + it->descent)
19384 * FONT_BASE (font)) / FONT_HEIGHT (font));
19385 saved_pos = it->position;
19386 memset (&it->position, 0, sizeof it->position);
19387 saved_avoid_cursor = it->avoid_cursor_p;
19388 it->avoid_cursor_p = 1;
19389 saved_face_id = it->face_id;
19390 saved_box_start = it->start_of_box_run_p;
19391 /* The last row's stretch glyph should get the default
19392 face, to avoid painting the rest of the window with
19393 the region face, if the region ends at ZV. */
19394 if (it->glyph_row->ends_at_zv_p)
19395 it->face_id = default_face->id;
19396 else
19397 it->face_id = face->id;
19398 it->start_of_box_run_p = 0;
19399 append_stretch_glyph (it, make_number (0), stretch_width,
19400 it->ascent + it->descent, stretch_ascent);
19401 it->position = saved_pos;
19402 it->avoid_cursor_p = saved_avoid_cursor;
19403 it->face_id = saved_face_id;
19404 it->start_of_box_run_p = saved_box_start;
19405 }
19406 /* If stretch_width comes out negative, it means that the
19407 last glyph is only partially visible. In R2L rows, we
19408 want the leftmost glyph to be partially visible, so we
19409 need to give the row the corresponding left offset. */
19410 if (stretch_width < 0)
19411 it->glyph_row->x = stretch_width;
19412 }
19413 #endif /* HAVE_WINDOW_SYSTEM */
19414 }
19415 else
19416 {
19417 /* Save some values that must not be changed. */
19418 int saved_x = it->current_x;
19419 struct text_pos saved_pos;
19420 Lisp_Object saved_object;
19421 enum display_element_type saved_what = it->what;
19422 int saved_face_id = it->face_id;
19423
19424 saved_object = it->object;
19425 saved_pos = it->position;
19426
19427 it->what = IT_CHARACTER;
19428 memset (&it->position, 0, sizeof it->position);
19429 it->object = make_number (0);
19430 it->c = it->char_to_display = ' ';
19431 it->len = 1;
19432
19433 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19434 && (it->glyph_row->used[LEFT_MARGIN_AREA]
19435 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19436 && !it->glyph_row->mode_line_p
19437 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19438 {
19439 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
19440 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
19441
19442 for (it->current_x = 0; g < e; g++)
19443 it->current_x += g->pixel_width;
19444
19445 it->area = LEFT_MARGIN_AREA;
19446 it->face_id = default_face->id;
19447 while (it->glyph_row->used[LEFT_MARGIN_AREA]
19448 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19449 {
19450 PRODUCE_GLYPHS (it);
19451 /* term.c:produce_glyphs advances it->current_x only for
19452 TEXT_AREA. */
19453 it->current_x += it->pixel_width;
19454 }
19455
19456 it->current_x = saved_x;
19457 it->area = TEXT_AREA;
19458 }
19459
19460 /* The last row's blank glyphs should get the default face, to
19461 avoid painting the rest of the window with the region face,
19462 if the region ends at ZV. */
19463 if (it->glyph_row->ends_at_zv_p)
19464 it->face_id = default_face->id;
19465 else
19466 it->face_id = face->id;
19467 PRODUCE_GLYPHS (it);
19468
19469 while (it->current_x <= it->last_visible_x)
19470 PRODUCE_GLYPHS (it);
19471
19472 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19473 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
19474 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19475 && !it->glyph_row->mode_line_p
19476 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19477 {
19478 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
19479 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
19480
19481 for ( ; g < e; g++)
19482 it->current_x += g->pixel_width;
19483
19484 it->area = RIGHT_MARGIN_AREA;
19485 it->face_id = default_face->id;
19486 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
19487 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19488 {
19489 PRODUCE_GLYPHS (it);
19490 it->current_x += it->pixel_width;
19491 }
19492
19493 it->area = TEXT_AREA;
19494 }
19495
19496 /* Don't count these blanks really. It would let us insert a left
19497 truncation glyph below and make us set the cursor on them, maybe. */
19498 it->current_x = saved_x;
19499 it->object = saved_object;
19500 it->position = saved_pos;
19501 it->what = saved_what;
19502 it->face_id = saved_face_id;
19503 }
19504 }
19505
19506
19507 /* Value is non-zero if text starting at CHARPOS in current_buffer is
19508 trailing whitespace. */
19509
19510 static int
19511 trailing_whitespace_p (ptrdiff_t charpos)
19512 {
19513 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
19514 int c = 0;
19515
19516 while (bytepos < ZV_BYTE
19517 && (c = FETCH_CHAR (bytepos),
19518 c == ' ' || c == '\t'))
19519 ++bytepos;
19520
19521 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
19522 {
19523 if (bytepos != PT_BYTE)
19524 return 1;
19525 }
19526 return 0;
19527 }
19528
19529
19530 /* Highlight trailing whitespace, if any, in ROW. */
19531
19532 static void
19533 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
19534 {
19535 int used = row->used[TEXT_AREA];
19536
19537 if (used)
19538 {
19539 struct glyph *start = row->glyphs[TEXT_AREA];
19540 struct glyph *glyph = start + used - 1;
19541
19542 if (row->reversed_p)
19543 {
19544 /* Right-to-left rows need to be processed in the opposite
19545 direction, so swap the edge pointers. */
19546 glyph = start;
19547 start = row->glyphs[TEXT_AREA] + used - 1;
19548 }
19549
19550 /* Skip over glyphs inserted to display the cursor at the
19551 end of a line, for extending the face of the last glyph
19552 to the end of the line on terminals, and for truncation
19553 and continuation glyphs. */
19554 if (!row->reversed_p)
19555 {
19556 while (glyph >= start
19557 && glyph->type == CHAR_GLYPH
19558 && INTEGERP (glyph->object))
19559 --glyph;
19560 }
19561 else
19562 {
19563 while (glyph <= start
19564 && glyph->type == CHAR_GLYPH
19565 && INTEGERP (glyph->object))
19566 ++glyph;
19567 }
19568
19569 /* If last glyph is a space or stretch, and it's trailing
19570 whitespace, set the face of all trailing whitespace glyphs in
19571 IT->glyph_row to `trailing-whitespace'. */
19572 if ((row->reversed_p ? glyph <= start : glyph >= start)
19573 && BUFFERP (glyph->object)
19574 && (glyph->type == STRETCH_GLYPH
19575 || (glyph->type == CHAR_GLYPH
19576 && glyph->u.ch == ' '))
19577 && trailing_whitespace_p (glyph->charpos))
19578 {
19579 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
19580 if (face_id < 0)
19581 return;
19582
19583 if (!row->reversed_p)
19584 {
19585 while (glyph >= start
19586 && BUFFERP (glyph->object)
19587 && (glyph->type == STRETCH_GLYPH
19588 || (glyph->type == CHAR_GLYPH
19589 && glyph->u.ch == ' ')))
19590 (glyph--)->face_id = face_id;
19591 }
19592 else
19593 {
19594 while (glyph <= start
19595 && BUFFERP (glyph->object)
19596 && (glyph->type == STRETCH_GLYPH
19597 || (glyph->type == CHAR_GLYPH
19598 && glyph->u.ch == ' ')))
19599 (glyph++)->face_id = face_id;
19600 }
19601 }
19602 }
19603 }
19604
19605
19606 /* Value is non-zero if glyph row ROW should be
19607 considered to hold the buffer position CHARPOS. */
19608
19609 static int
19610 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
19611 {
19612 int result = 1;
19613
19614 if (charpos == CHARPOS (row->end.pos)
19615 || charpos == MATRIX_ROW_END_CHARPOS (row))
19616 {
19617 /* Suppose the row ends on a string.
19618 Unless the row is continued, that means it ends on a newline
19619 in the string. If it's anything other than a display string
19620 (e.g., a before-string from an overlay), we don't want the
19621 cursor there. (This heuristic seems to give the optimal
19622 behavior for the various types of multi-line strings.)
19623 One exception: if the string has `cursor' property on one of
19624 its characters, we _do_ want the cursor there. */
19625 if (CHARPOS (row->end.string_pos) >= 0)
19626 {
19627 if (row->continued_p)
19628 result = 1;
19629 else
19630 {
19631 /* Check for `display' property. */
19632 struct glyph *beg = row->glyphs[TEXT_AREA];
19633 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
19634 struct glyph *glyph;
19635
19636 result = 0;
19637 for (glyph = end; glyph >= beg; --glyph)
19638 if (STRINGP (glyph->object))
19639 {
19640 Lisp_Object prop
19641 = Fget_char_property (make_number (charpos),
19642 Qdisplay, Qnil);
19643 result =
19644 (!NILP (prop)
19645 && display_prop_string_p (prop, glyph->object));
19646 /* If there's a `cursor' property on one of the
19647 string's characters, this row is a cursor row,
19648 even though this is not a display string. */
19649 if (!result)
19650 {
19651 Lisp_Object s = glyph->object;
19652
19653 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
19654 {
19655 ptrdiff_t gpos = glyph->charpos;
19656
19657 if (!NILP (Fget_char_property (make_number (gpos),
19658 Qcursor, s)))
19659 {
19660 result = 1;
19661 break;
19662 }
19663 }
19664 }
19665 break;
19666 }
19667 }
19668 }
19669 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
19670 {
19671 /* If the row ends in middle of a real character,
19672 and the line is continued, we want the cursor here.
19673 That's because CHARPOS (ROW->end.pos) would equal
19674 PT if PT is before the character. */
19675 if (!row->ends_in_ellipsis_p)
19676 result = row->continued_p;
19677 else
19678 /* If the row ends in an ellipsis, then
19679 CHARPOS (ROW->end.pos) will equal point after the
19680 invisible text. We want that position to be displayed
19681 after the ellipsis. */
19682 result = 0;
19683 }
19684 /* If the row ends at ZV, display the cursor at the end of that
19685 row instead of at the start of the row below. */
19686 else if (row->ends_at_zv_p)
19687 result = 1;
19688 else
19689 result = 0;
19690 }
19691
19692 return result;
19693 }
19694
19695 /* Value is non-zero if glyph row ROW should be
19696 used to hold the cursor. */
19697
19698 static int
19699 cursor_row_p (struct glyph_row *row)
19700 {
19701 return row_for_charpos_p (row, PT);
19702 }
19703
19704 \f
19705
19706 /* Push the property PROP so that it will be rendered at the current
19707 position in IT. Return 1 if PROP was successfully pushed, 0
19708 otherwise. Called from handle_line_prefix to handle the
19709 `line-prefix' and `wrap-prefix' properties. */
19710
19711 static int
19712 push_prefix_prop (struct it *it, Lisp_Object prop)
19713 {
19714 struct text_pos pos =
19715 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
19716
19717 eassert (it->method == GET_FROM_BUFFER
19718 || it->method == GET_FROM_DISPLAY_VECTOR
19719 || it->method == GET_FROM_STRING);
19720
19721 /* We need to save the current buffer/string position, so it will be
19722 restored by pop_it, because iterate_out_of_display_property
19723 depends on that being set correctly, but some situations leave
19724 it->position not yet set when this function is called. */
19725 push_it (it, &pos);
19726
19727 if (STRINGP (prop))
19728 {
19729 if (SCHARS (prop) == 0)
19730 {
19731 pop_it (it);
19732 return 0;
19733 }
19734
19735 it->string = prop;
19736 it->string_from_prefix_prop_p = 1;
19737 it->multibyte_p = STRING_MULTIBYTE (it->string);
19738 it->current.overlay_string_index = -1;
19739 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
19740 it->end_charpos = it->string_nchars = SCHARS (it->string);
19741 it->method = GET_FROM_STRING;
19742 it->stop_charpos = 0;
19743 it->prev_stop = 0;
19744 it->base_level_stop = 0;
19745
19746 /* Force paragraph direction to be that of the parent
19747 buffer/string. */
19748 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19749 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19750 else
19751 it->paragraph_embedding = L2R;
19752
19753 /* Set up the bidi iterator for this display string. */
19754 if (it->bidi_p)
19755 {
19756 it->bidi_it.string.lstring = it->string;
19757 it->bidi_it.string.s = NULL;
19758 it->bidi_it.string.schars = it->end_charpos;
19759 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19760 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19761 it->bidi_it.string.unibyte = !it->multibyte_p;
19762 it->bidi_it.w = it->w;
19763 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19764 }
19765 }
19766 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19767 {
19768 it->method = GET_FROM_STRETCH;
19769 it->object = prop;
19770 }
19771 #ifdef HAVE_WINDOW_SYSTEM
19772 else if (IMAGEP (prop))
19773 {
19774 it->what = IT_IMAGE;
19775 it->image_id = lookup_image (it->f, prop);
19776 it->method = GET_FROM_IMAGE;
19777 }
19778 #endif /* HAVE_WINDOW_SYSTEM */
19779 else
19780 {
19781 pop_it (it); /* bogus display property, give up */
19782 return 0;
19783 }
19784
19785 return 1;
19786 }
19787
19788 /* Return the character-property PROP at the current position in IT. */
19789
19790 static Lisp_Object
19791 get_it_property (struct it *it, Lisp_Object prop)
19792 {
19793 Lisp_Object position, object = it->object;
19794
19795 if (STRINGP (object))
19796 position = make_number (IT_STRING_CHARPOS (*it));
19797 else if (BUFFERP (object))
19798 {
19799 position = make_number (IT_CHARPOS (*it));
19800 object = it->window;
19801 }
19802 else
19803 return Qnil;
19804
19805 return Fget_char_property (position, prop, object);
19806 }
19807
19808 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19809
19810 static void
19811 handle_line_prefix (struct it *it)
19812 {
19813 Lisp_Object prefix;
19814
19815 if (it->continuation_lines_width > 0)
19816 {
19817 prefix = get_it_property (it, Qwrap_prefix);
19818 if (NILP (prefix))
19819 prefix = Vwrap_prefix;
19820 }
19821 else
19822 {
19823 prefix = get_it_property (it, Qline_prefix);
19824 if (NILP (prefix))
19825 prefix = Vline_prefix;
19826 }
19827 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19828 {
19829 /* If the prefix is wider than the window, and we try to wrap
19830 it, it would acquire its own wrap prefix, and so on till the
19831 iterator stack overflows. So, don't wrap the prefix. */
19832 it->line_wrap = TRUNCATE;
19833 it->avoid_cursor_p = 1;
19834 }
19835 }
19836
19837 \f
19838
19839 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19840 only for R2L lines from display_line and display_string, when they
19841 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19842 the line/string needs to be continued on the next glyph row. */
19843 static void
19844 unproduce_glyphs (struct it *it, int n)
19845 {
19846 struct glyph *glyph, *end;
19847
19848 eassert (it->glyph_row);
19849 eassert (it->glyph_row->reversed_p);
19850 eassert (it->area == TEXT_AREA);
19851 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19852
19853 if (n > it->glyph_row->used[TEXT_AREA])
19854 n = it->glyph_row->used[TEXT_AREA];
19855 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19856 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19857 for ( ; glyph < end; glyph++)
19858 glyph[-n] = *glyph;
19859 }
19860
19861 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19862 and ROW->maxpos. */
19863 static void
19864 find_row_edges (struct it *it, struct glyph_row *row,
19865 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19866 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19867 {
19868 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19869 lines' rows is implemented for bidi-reordered rows. */
19870
19871 /* ROW->minpos is the value of min_pos, the minimal buffer position
19872 we have in ROW, or ROW->start.pos if that is smaller. */
19873 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19874 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19875 else
19876 /* We didn't find buffer positions smaller than ROW->start, or
19877 didn't find _any_ valid buffer positions in any of the glyphs,
19878 so we must trust the iterator's computed positions. */
19879 row->minpos = row->start.pos;
19880 if (max_pos <= 0)
19881 {
19882 max_pos = CHARPOS (it->current.pos);
19883 max_bpos = BYTEPOS (it->current.pos);
19884 }
19885
19886 /* Here are the various use-cases for ending the row, and the
19887 corresponding values for ROW->maxpos:
19888
19889 Line ends in a newline from buffer eol_pos + 1
19890 Line is continued from buffer max_pos + 1
19891 Line is truncated on right it->current.pos
19892 Line ends in a newline from string max_pos + 1(*)
19893 (*) + 1 only when line ends in a forward scan
19894 Line is continued from string max_pos
19895 Line is continued from display vector max_pos
19896 Line is entirely from a string min_pos == max_pos
19897 Line is entirely from a display vector min_pos == max_pos
19898 Line that ends at ZV ZV
19899
19900 If you discover other use-cases, please add them here as
19901 appropriate. */
19902 if (row->ends_at_zv_p)
19903 row->maxpos = it->current.pos;
19904 else if (row->used[TEXT_AREA])
19905 {
19906 int seen_this_string = 0;
19907 struct glyph_row *r1 = row - 1;
19908
19909 /* Did we see the same display string on the previous row? */
19910 if (STRINGP (it->object)
19911 /* this is not the first row */
19912 && row > it->w->desired_matrix->rows
19913 /* previous row is not the header line */
19914 && !r1->mode_line_p
19915 /* previous row also ends in a newline from a string */
19916 && r1->ends_in_newline_from_string_p)
19917 {
19918 struct glyph *start, *end;
19919
19920 /* Search for the last glyph of the previous row that came
19921 from buffer or string. Depending on whether the row is
19922 L2R or R2L, we need to process it front to back or the
19923 other way round. */
19924 if (!r1->reversed_p)
19925 {
19926 start = r1->glyphs[TEXT_AREA];
19927 end = start + r1->used[TEXT_AREA];
19928 /* Glyphs inserted by redisplay have an integer (zero)
19929 as their object. */
19930 while (end > start
19931 && INTEGERP ((end - 1)->object)
19932 && (end - 1)->charpos <= 0)
19933 --end;
19934 if (end > start)
19935 {
19936 if (EQ ((end - 1)->object, it->object))
19937 seen_this_string = 1;
19938 }
19939 else
19940 /* If all the glyphs of the previous row were inserted
19941 by redisplay, it means the previous row was
19942 produced from a single newline, which is only
19943 possible if that newline came from the same string
19944 as the one which produced this ROW. */
19945 seen_this_string = 1;
19946 }
19947 else
19948 {
19949 end = r1->glyphs[TEXT_AREA] - 1;
19950 start = end + r1->used[TEXT_AREA];
19951 while (end < start
19952 && INTEGERP ((end + 1)->object)
19953 && (end + 1)->charpos <= 0)
19954 ++end;
19955 if (end < start)
19956 {
19957 if (EQ ((end + 1)->object, it->object))
19958 seen_this_string = 1;
19959 }
19960 else
19961 seen_this_string = 1;
19962 }
19963 }
19964 /* Take note of each display string that covers a newline only
19965 once, the first time we see it. This is for when a display
19966 string includes more than one newline in it. */
19967 if (row->ends_in_newline_from_string_p && !seen_this_string)
19968 {
19969 /* If we were scanning the buffer forward when we displayed
19970 the string, we want to account for at least one buffer
19971 position that belongs to this row (position covered by
19972 the display string), so that cursor positioning will
19973 consider this row as a candidate when point is at the end
19974 of the visual line represented by this row. This is not
19975 required when scanning back, because max_pos will already
19976 have a much larger value. */
19977 if (CHARPOS (row->end.pos) > max_pos)
19978 INC_BOTH (max_pos, max_bpos);
19979 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19980 }
19981 else if (CHARPOS (it->eol_pos) > 0)
19982 SET_TEXT_POS (row->maxpos,
19983 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19984 else if (row->continued_p)
19985 {
19986 /* If max_pos is different from IT's current position, it
19987 means IT->method does not belong to the display element
19988 at max_pos. However, it also means that the display
19989 element at max_pos was displayed in its entirety on this
19990 line, which is equivalent to saying that the next line
19991 starts at the next buffer position. */
19992 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19993 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19994 else
19995 {
19996 INC_BOTH (max_pos, max_bpos);
19997 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19998 }
19999 }
20000 else if (row->truncated_on_right_p)
20001 /* display_line already called reseat_at_next_visible_line_start,
20002 which puts the iterator at the beginning of the next line, in
20003 the logical order. */
20004 row->maxpos = it->current.pos;
20005 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20006 /* A line that is entirely from a string/image/stretch... */
20007 row->maxpos = row->minpos;
20008 else
20009 emacs_abort ();
20010 }
20011 else
20012 row->maxpos = it->current.pos;
20013 }
20014
20015 /* Construct the glyph row IT->glyph_row in the desired matrix of
20016 IT->w from text at the current position of IT. See dispextern.h
20017 for an overview of struct it. Value is non-zero if
20018 IT->glyph_row displays text, as opposed to a line displaying ZV
20019 only. */
20020
20021 static int
20022 display_line (struct it *it)
20023 {
20024 struct glyph_row *row = it->glyph_row;
20025 Lisp_Object overlay_arrow_string;
20026 struct it wrap_it;
20027 void *wrap_data = NULL;
20028 int may_wrap = 0, wrap_x IF_LINT (= 0);
20029 int wrap_row_used = -1;
20030 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
20031 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
20032 int wrap_row_extra_line_spacing IF_LINT (= 0);
20033 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
20034 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
20035 int cvpos;
20036 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
20037 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
20038 bool pending_handle_line_prefix = false;
20039
20040 /* We always start displaying at hpos zero even if hscrolled. */
20041 eassert (it->hpos == 0 && it->current_x == 0);
20042
20043 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
20044 >= it->w->desired_matrix->nrows)
20045 {
20046 it->w->nrows_scale_factor++;
20047 it->f->fonts_changed = 1;
20048 return 0;
20049 }
20050
20051 /* Clear the result glyph row and enable it. */
20052 prepare_desired_row (it->w, row, false);
20053
20054 row->y = it->current_y;
20055 row->start = it->start;
20056 row->continuation_lines_width = it->continuation_lines_width;
20057 row->displays_text_p = 1;
20058 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
20059 it->starts_in_middle_of_char_p = 0;
20060
20061 /* Arrange the overlays nicely for our purposes. Usually, we call
20062 display_line on only one line at a time, in which case this
20063 can't really hurt too much, or we call it on lines which appear
20064 one after another in the buffer, in which case all calls to
20065 recenter_overlay_lists but the first will be pretty cheap. */
20066 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
20067
20068 /* Move over display elements that are not visible because we are
20069 hscrolled. This may stop at an x-position < IT->first_visible_x
20070 if the first glyph is partially visible or if we hit a line end. */
20071 if (it->current_x < it->first_visible_x)
20072 {
20073 enum move_it_result move_result;
20074
20075 this_line_min_pos = row->start.pos;
20076 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
20077 MOVE_TO_POS | MOVE_TO_X);
20078 /* If we are under a large hscroll, move_it_in_display_line_to
20079 could hit the end of the line without reaching
20080 it->first_visible_x. Pretend that we did reach it. This is
20081 especially important on a TTY, where we will call
20082 extend_face_to_end_of_line, which needs to know how many
20083 blank glyphs to produce. */
20084 if (it->current_x < it->first_visible_x
20085 && (move_result == MOVE_NEWLINE_OR_CR
20086 || move_result == MOVE_POS_MATCH_OR_ZV))
20087 it->current_x = it->first_visible_x;
20088
20089 /* Record the smallest positions seen while we moved over
20090 display elements that are not visible. This is needed by
20091 redisplay_internal for optimizing the case where the cursor
20092 stays inside the same line. The rest of this function only
20093 considers positions that are actually displayed, so
20094 RECORD_MAX_MIN_POS will not otherwise record positions that
20095 are hscrolled to the left of the left edge of the window. */
20096 min_pos = CHARPOS (this_line_min_pos);
20097 min_bpos = BYTEPOS (this_line_min_pos);
20098 }
20099 else if (it->area == TEXT_AREA)
20100 {
20101 /* We only do this when not calling move_it_in_display_line_to
20102 above, because that function calls itself handle_line_prefix. */
20103 handle_line_prefix (it);
20104 }
20105 else
20106 {
20107 /* Line-prefix and wrap-prefix are always displayed in the text
20108 area. But if this is the first call to display_line after
20109 init_iterator, the iterator might have been set up to write
20110 into a marginal area, e.g. if the line begins with some
20111 display property that writes to the margins. So we need to
20112 wait with the call to handle_line_prefix until whatever
20113 writes to the margin has done its job. */
20114 pending_handle_line_prefix = true;
20115 }
20116
20117 /* Get the initial row height. This is either the height of the
20118 text hscrolled, if there is any, or zero. */
20119 row->ascent = it->max_ascent;
20120 row->height = it->max_ascent + it->max_descent;
20121 row->phys_ascent = it->max_phys_ascent;
20122 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20123 row->extra_line_spacing = it->max_extra_line_spacing;
20124
20125 /* Utility macro to record max and min buffer positions seen until now. */
20126 #define RECORD_MAX_MIN_POS(IT) \
20127 do \
20128 { \
20129 int composition_p = !STRINGP ((IT)->string) \
20130 && ((IT)->what == IT_COMPOSITION); \
20131 ptrdiff_t current_pos = \
20132 composition_p ? (IT)->cmp_it.charpos \
20133 : IT_CHARPOS (*(IT)); \
20134 ptrdiff_t current_bpos = \
20135 composition_p ? CHAR_TO_BYTE (current_pos) \
20136 : IT_BYTEPOS (*(IT)); \
20137 if (current_pos < min_pos) \
20138 { \
20139 min_pos = current_pos; \
20140 min_bpos = current_bpos; \
20141 } \
20142 if (IT_CHARPOS (*it) > max_pos) \
20143 { \
20144 max_pos = IT_CHARPOS (*it); \
20145 max_bpos = IT_BYTEPOS (*it); \
20146 } \
20147 } \
20148 while (0)
20149
20150 /* Loop generating characters. The loop is left with IT on the next
20151 character to display. */
20152 while (1)
20153 {
20154 int n_glyphs_before, hpos_before, x_before;
20155 int x, nglyphs;
20156 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
20157
20158 /* Retrieve the next thing to display. Value is zero if end of
20159 buffer reached. */
20160 if (!get_next_display_element (it))
20161 {
20162 /* Maybe add a space at the end of this line that is used to
20163 display the cursor there under X. Set the charpos of the
20164 first glyph of blank lines not corresponding to any text
20165 to -1. */
20166 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20167 row->exact_window_width_line_p = 1;
20168 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
20169 || row->used[TEXT_AREA] == 0)
20170 {
20171 row->glyphs[TEXT_AREA]->charpos = -1;
20172 row->displays_text_p = 0;
20173
20174 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
20175 && (!MINI_WINDOW_P (it->w)
20176 || (minibuf_level && EQ (it->window, minibuf_window))))
20177 row->indicate_empty_line_p = 1;
20178 }
20179
20180 it->continuation_lines_width = 0;
20181 row->ends_at_zv_p = 1;
20182 /* A row that displays right-to-left text must always have
20183 its last face extended all the way to the end of line,
20184 even if this row ends in ZV, because we still write to
20185 the screen left to right. We also need to extend the
20186 last face if the default face is remapped to some
20187 different face, otherwise the functions that clear
20188 portions of the screen will clear with the default face's
20189 background color. */
20190 if (row->reversed_p
20191 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
20192 extend_face_to_end_of_line (it);
20193 break;
20194 }
20195
20196 /* Now, get the metrics of what we want to display. This also
20197 generates glyphs in `row' (which is IT->glyph_row). */
20198 n_glyphs_before = row->used[TEXT_AREA];
20199 x = it->current_x;
20200
20201 /* Remember the line height so far in case the next element doesn't
20202 fit on the line. */
20203 if (it->line_wrap != TRUNCATE)
20204 {
20205 ascent = it->max_ascent;
20206 descent = it->max_descent;
20207 phys_ascent = it->max_phys_ascent;
20208 phys_descent = it->max_phys_descent;
20209
20210 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
20211 {
20212 if (IT_DISPLAYING_WHITESPACE (it))
20213 may_wrap = 1;
20214 else if (may_wrap)
20215 {
20216 SAVE_IT (wrap_it, *it, wrap_data);
20217 wrap_x = x;
20218 wrap_row_used = row->used[TEXT_AREA];
20219 wrap_row_ascent = row->ascent;
20220 wrap_row_height = row->height;
20221 wrap_row_phys_ascent = row->phys_ascent;
20222 wrap_row_phys_height = row->phys_height;
20223 wrap_row_extra_line_spacing = row->extra_line_spacing;
20224 wrap_row_min_pos = min_pos;
20225 wrap_row_min_bpos = min_bpos;
20226 wrap_row_max_pos = max_pos;
20227 wrap_row_max_bpos = max_bpos;
20228 may_wrap = 0;
20229 }
20230 }
20231 }
20232
20233 PRODUCE_GLYPHS (it);
20234
20235 /* If this display element was in marginal areas, continue with
20236 the next one. */
20237 if (it->area != TEXT_AREA)
20238 {
20239 row->ascent = max (row->ascent, it->max_ascent);
20240 row->height = max (row->height, it->max_ascent + it->max_descent);
20241 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20242 row->phys_height = max (row->phys_height,
20243 it->max_phys_ascent + it->max_phys_descent);
20244 row->extra_line_spacing = max (row->extra_line_spacing,
20245 it->max_extra_line_spacing);
20246 set_iterator_to_next (it, 1);
20247 /* If we didn't handle the line/wrap prefix above, and the
20248 call to set_iterator_to_next just switched to TEXT_AREA,
20249 process the prefix now. */
20250 if (it->area == TEXT_AREA && pending_handle_line_prefix)
20251 {
20252 pending_handle_line_prefix = false;
20253 handle_line_prefix (it);
20254 }
20255 continue;
20256 }
20257
20258 /* Does the display element fit on the line? If we truncate
20259 lines, we should draw past the right edge of the window. If
20260 we don't truncate, we want to stop so that we can display the
20261 continuation glyph before the right margin. If lines are
20262 continued, there are two possible strategies for characters
20263 resulting in more than 1 glyph (e.g. tabs): Display as many
20264 glyphs as possible in this line and leave the rest for the
20265 continuation line, or display the whole element in the next
20266 line. Original redisplay did the former, so we do it also. */
20267 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
20268 hpos_before = it->hpos;
20269 x_before = x;
20270
20271 if (/* Not a newline. */
20272 nglyphs > 0
20273 /* Glyphs produced fit entirely in the line. */
20274 && it->current_x < it->last_visible_x)
20275 {
20276 it->hpos += nglyphs;
20277 row->ascent = max (row->ascent, it->max_ascent);
20278 row->height = max (row->height, it->max_ascent + it->max_descent);
20279 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20280 row->phys_height = max (row->phys_height,
20281 it->max_phys_ascent + it->max_phys_descent);
20282 row->extra_line_spacing = max (row->extra_line_spacing,
20283 it->max_extra_line_spacing);
20284 if (it->current_x - it->pixel_width < it->first_visible_x
20285 /* In R2L rows, we arrange in extend_face_to_end_of_line
20286 to add a right offset to the line, by a suitable
20287 change to the stretch glyph that is the leftmost
20288 glyph of the line. */
20289 && !row->reversed_p)
20290 row->x = x - it->first_visible_x;
20291 /* Record the maximum and minimum buffer positions seen so
20292 far in glyphs that will be displayed by this row. */
20293 if (it->bidi_p)
20294 RECORD_MAX_MIN_POS (it);
20295 }
20296 else
20297 {
20298 int i, new_x;
20299 struct glyph *glyph;
20300
20301 for (i = 0; i < nglyphs; ++i, x = new_x)
20302 {
20303 /* Identify the glyphs added by the last call to
20304 PRODUCE_GLYPHS. In R2L rows, they are prepended to
20305 the previous glyphs. */
20306 if (!row->reversed_p)
20307 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20308 else
20309 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
20310 new_x = x + glyph->pixel_width;
20311
20312 if (/* Lines are continued. */
20313 it->line_wrap != TRUNCATE
20314 && (/* Glyph doesn't fit on the line. */
20315 new_x > it->last_visible_x
20316 /* Or it fits exactly on a window system frame. */
20317 || (new_x == it->last_visible_x
20318 && FRAME_WINDOW_P (it->f)
20319 && (row->reversed_p
20320 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20321 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
20322 {
20323 /* End of a continued line. */
20324
20325 if (it->hpos == 0
20326 || (new_x == it->last_visible_x
20327 && FRAME_WINDOW_P (it->f)
20328 && (row->reversed_p
20329 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20330 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
20331 {
20332 /* Current glyph is the only one on the line or
20333 fits exactly on the line. We must continue
20334 the line because we can't draw the cursor
20335 after the glyph. */
20336 row->continued_p = 1;
20337 it->current_x = new_x;
20338 it->continuation_lines_width += new_x;
20339 ++it->hpos;
20340 if (i == nglyphs - 1)
20341 {
20342 /* If line-wrap is on, check if a previous
20343 wrap point was found. */
20344 if (wrap_row_used > 0
20345 /* Even if there is a previous wrap
20346 point, continue the line here as
20347 usual, if (i) the previous character
20348 was a space or tab AND (ii) the
20349 current character is not. */
20350 && (!may_wrap
20351 || IT_DISPLAYING_WHITESPACE (it)))
20352 goto back_to_wrap;
20353
20354 /* Record the maximum and minimum buffer
20355 positions seen so far in glyphs that will be
20356 displayed by this row. */
20357 if (it->bidi_p)
20358 RECORD_MAX_MIN_POS (it);
20359 set_iterator_to_next (it, 1);
20360 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20361 {
20362 if (!get_next_display_element (it))
20363 {
20364 row->exact_window_width_line_p = 1;
20365 it->continuation_lines_width = 0;
20366 row->continued_p = 0;
20367 row->ends_at_zv_p = 1;
20368 }
20369 else if (ITERATOR_AT_END_OF_LINE_P (it))
20370 {
20371 row->continued_p = 0;
20372 row->exact_window_width_line_p = 1;
20373 }
20374 }
20375 }
20376 else if (it->bidi_p)
20377 RECORD_MAX_MIN_POS (it);
20378 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20379 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20380 extend_face_to_end_of_line (it);
20381 }
20382 else if (CHAR_GLYPH_PADDING_P (*glyph)
20383 && !FRAME_WINDOW_P (it->f))
20384 {
20385 /* A padding glyph that doesn't fit on this line.
20386 This means the whole character doesn't fit
20387 on the line. */
20388 if (row->reversed_p)
20389 unproduce_glyphs (it, row->used[TEXT_AREA]
20390 - n_glyphs_before);
20391 row->used[TEXT_AREA] = n_glyphs_before;
20392
20393 /* Fill the rest of the row with continuation
20394 glyphs like in 20.x. */
20395 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
20396 < row->glyphs[1 + TEXT_AREA])
20397 produce_special_glyphs (it, IT_CONTINUATION);
20398
20399 row->continued_p = 1;
20400 it->current_x = x_before;
20401 it->continuation_lines_width += x_before;
20402
20403 /* Restore the height to what it was before the
20404 element not fitting on the line. */
20405 it->max_ascent = ascent;
20406 it->max_descent = descent;
20407 it->max_phys_ascent = phys_ascent;
20408 it->max_phys_descent = phys_descent;
20409 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20410 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20411 extend_face_to_end_of_line (it);
20412 }
20413 else if (wrap_row_used > 0)
20414 {
20415 back_to_wrap:
20416 if (row->reversed_p)
20417 unproduce_glyphs (it,
20418 row->used[TEXT_AREA] - wrap_row_used);
20419 RESTORE_IT (it, &wrap_it, wrap_data);
20420 it->continuation_lines_width += wrap_x;
20421 row->used[TEXT_AREA] = wrap_row_used;
20422 row->ascent = wrap_row_ascent;
20423 row->height = wrap_row_height;
20424 row->phys_ascent = wrap_row_phys_ascent;
20425 row->phys_height = wrap_row_phys_height;
20426 row->extra_line_spacing = wrap_row_extra_line_spacing;
20427 min_pos = wrap_row_min_pos;
20428 min_bpos = wrap_row_min_bpos;
20429 max_pos = wrap_row_max_pos;
20430 max_bpos = wrap_row_max_bpos;
20431 row->continued_p = 1;
20432 row->ends_at_zv_p = 0;
20433 row->exact_window_width_line_p = 0;
20434 it->continuation_lines_width += x;
20435
20436 /* Make sure that a non-default face is extended
20437 up to the right margin of the window. */
20438 extend_face_to_end_of_line (it);
20439 }
20440 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
20441 {
20442 /* A TAB that extends past the right edge of the
20443 window. This produces a single glyph on
20444 window system frames. We leave the glyph in
20445 this row and let it fill the row, but don't
20446 consume the TAB. */
20447 if ((row->reversed_p
20448 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20449 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20450 produce_special_glyphs (it, IT_CONTINUATION);
20451 it->continuation_lines_width += it->last_visible_x;
20452 row->ends_in_middle_of_char_p = 1;
20453 row->continued_p = 1;
20454 glyph->pixel_width = it->last_visible_x - x;
20455 it->starts_in_middle_of_char_p = 1;
20456 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20457 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20458 extend_face_to_end_of_line (it);
20459 }
20460 else
20461 {
20462 /* Something other than a TAB that draws past
20463 the right edge of the window. Restore
20464 positions to values before the element. */
20465 if (row->reversed_p)
20466 unproduce_glyphs (it, row->used[TEXT_AREA]
20467 - (n_glyphs_before + i));
20468 row->used[TEXT_AREA] = n_glyphs_before + i;
20469
20470 /* Display continuation glyphs. */
20471 it->current_x = x_before;
20472 it->continuation_lines_width += x;
20473 if (!FRAME_WINDOW_P (it->f)
20474 || (row->reversed_p
20475 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20476 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20477 produce_special_glyphs (it, IT_CONTINUATION);
20478 row->continued_p = 1;
20479
20480 extend_face_to_end_of_line (it);
20481
20482 if (nglyphs > 1 && i > 0)
20483 {
20484 row->ends_in_middle_of_char_p = 1;
20485 it->starts_in_middle_of_char_p = 1;
20486 }
20487
20488 /* Restore the height to what it was before the
20489 element not fitting on the line. */
20490 it->max_ascent = ascent;
20491 it->max_descent = descent;
20492 it->max_phys_ascent = phys_ascent;
20493 it->max_phys_descent = phys_descent;
20494 }
20495
20496 break;
20497 }
20498 else if (new_x > it->first_visible_x)
20499 {
20500 /* Increment number of glyphs actually displayed. */
20501 ++it->hpos;
20502
20503 /* Record the maximum and minimum buffer positions
20504 seen so far in glyphs that will be displayed by
20505 this row. */
20506 if (it->bidi_p)
20507 RECORD_MAX_MIN_POS (it);
20508
20509 if (x < it->first_visible_x && !row->reversed_p)
20510 /* Glyph is partially visible, i.e. row starts at
20511 negative X position. Don't do that in R2L
20512 rows, where we arrange to add a right offset to
20513 the line in extend_face_to_end_of_line, by a
20514 suitable change to the stretch glyph that is
20515 the leftmost glyph of the line. */
20516 row->x = x - it->first_visible_x;
20517 /* When the last glyph of an R2L row only fits
20518 partially on the line, we need to set row->x to a
20519 negative offset, so that the leftmost glyph is
20520 the one that is partially visible. */
20521 if (row->reversed_p && new_x > it->last_visible_x)
20522 row->x = it->last_visible_x - new_x;
20523 }
20524 else
20525 {
20526 /* Glyph is completely off the left margin of the
20527 window. This should not happen because of the
20528 move_it_in_display_line at the start of this
20529 function, unless the text display area of the
20530 window is empty. */
20531 eassert (it->first_visible_x <= it->last_visible_x);
20532 }
20533 }
20534 /* Even if this display element produced no glyphs at all,
20535 we want to record its position. */
20536 if (it->bidi_p && nglyphs == 0)
20537 RECORD_MAX_MIN_POS (it);
20538
20539 row->ascent = max (row->ascent, it->max_ascent);
20540 row->height = max (row->height, it->max_ascent + it->max_descent);
20541 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20542 row->phys_height = max (row->phys_height,
20543 it->max_phys_ascent + it->max_phys_descent);
20544 row->extra_line_spacing = max (row->extra_line_spacing,
20545 it->max_extra_line_spacing);
20546
20547 /* End of this display line if row is continued. */
20548 if (row->continued_p || row->ends_at_zv_p)
20549 break;
20550 }
20551
20552 at_end_of_line:
20553 /* Is this a line end? If yes, we're also done, after making
20554 sure that a non-default face is extended up to the right
20555 margin of the window. */
20556 if (ITERATOR_AT_END_OF_LINE_P (it))
20557 {
20558 int used_before = row->used[TEXT_AREA];
20559
20560 row->ends_in_newline_from_string_p = STRINGP (it->object);
20561
20562 /* Add a space at the end of the line that is used to
20563 display the cursor there. */
20564 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20565 append_space_for_newline (it, 0);
20566
20567 /* Extend the face to the end of the line. */
20568 extend_face_to_end_of_line (it);
20569
20570 /* Make sure we have the position. */
20571 if (used_before == 0)
20572 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
20573
20574 /* Record the position of the newline, for use in
20575 find_row_edges. */
20576 it->eol_pos = it->current.pos;
20577
20578 /* Consume the line end. This skips over invisible lines. */
20579 set_iterator_to_next (it, 1);
20580 it->continuation_lines_width = 0;
20581 break;
20582 }
20583
20584 /* Proceed with next display element. Note that this skips
20585 over lines invisible because of selective display. */
20586 set_iterator_to_next (it, 1);
20587
20588 /* If we truncate lines, we are done when the last displayed
20589 glyphs reach past the right margin of the window. */
20590 if (it->line_wrap == TRUNCATE
20591 && ((FRAME_WINDOW_P (it->f)
20592 /* Images are preprocessed in produce_image_glyph such
20593 that they are cropped at the right edge of the
20594 window, so an image glyph will always end exactly at
20595 last_visible_x, even if there's no right fringe. */
20596 && (WINDOW_RIGHT_FRINGE_WIDTH (it->w) || it->what == IT_IMAGE))
20597 ? (it->current_x >= it->last_visible_x)
20598 : (it->current_x > it->last_visible_x)))
20599 {
20600 /* Maybe add truncation glyphs. */
20601 if (!FRAME_WINDOW_P (it->f)
20602 || (row->reversed_p
20603 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20604 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20605 {
20606 int i, n;
20607
20608 if (!row->reversed_p)
20609 {
20610 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
20611 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20612 break;
20613 }
20614 else
20615 {
20616 for (i = 0; i < row->used[TEXT_AREA]; i++)
20617 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20618 break;
20619 /* Remove any padding glyphs at the front of ROW, to
20620 make room for the truncation glyphs we will be
20621 adding below. The loop below always inserts at
20622 least one truncation glyph, so also remove the
20623 last glyph added to ROW. */
20624 unproduce_glyphs (it, i + 1);
20625 /* Adjust i for the loop below. */
20626 i = row->used[TEXT_AREA] - (i + 1);
20627 }
20628
20629 /* produce_special_glyphs overwrites the last glyph, so
20630 we don't want that if we want to keep that last
20631 glyph, which means it's an image. */
20632 if (it->current_x > it->last_visible_x)
20633 {
20634 it->current_x = x_before;
20635 if (!FRAME_WINDOW_P (it->f))
20636 {
20637 for (n = row->used[TEXT_AREA]; i < n; ++i)
20638 {
20639 row->used[TEXT_AREA] = i;
20640 produce_special_glyphs (it, IT_TRUNCATION);
20641 }
20642 }
20643 else
20644 {
20645 row->used[TEXT_AREA] = i;
20646 produce_special_glyphs (it, IT_TRUNCATION);
20647 }
20648 it->hpos = hpos_before;
20649 }
20650 }
20651 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20652 {
20653 /* Don't truncate if we can overflow newline into fringe. */
20654 if (!get_next_display_element (it))
20655 {
20656 it->continuation_lines_width = 0;
20657 row->ends_at_zv_p = 1;
20658 row->exact_window_width_line_p = 1;
20659 break;
20660 }
20661 if (ITERATOR_AT_END_OF_LINE_P (it))
20662 {
20663 row->exact_window_width_line_p = 1;
20664 goto at_end_of_line;
20665 }
20666 it->current_x = x_before;
20667 it->hpos = hpos_before;
20668 }
20669
20670 row->truncated_on_right_p = 1;
20671 it->continuation_lines_width = 0;
20672 reseat_at_next_visible_line_start (it, 0);
20673 /* We insist below that IT's position be at ZV because in
20674 bidi-reordered lines the character at visible line start
20675 might not be the character that follows the newline in
20676 the logical order. */
20677 if (IT_BYTEPOS (*it) > BEG_BYTE)
20678 row->ends_at_zv_p =
20679 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
20680 else
20681 row->ends_at_zv_p = false;
20682 break;
20683 }
20684 }
20685
20686 if (wrap_data)
20687 bidi_unshelve_cache (wrap_data, 1);
20688
20689 /* If line is not empty and hscrolled, maybe insert truncation glyphs
20690 at the left window margin. */
20691 if (it->first_visible_x
20692 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
20693 {
20694 if (!FRAME_WINDOW_P (it->f)
20695 || (((row->reversed_p
20696 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20697 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
20698 /* Don't let insert_left_trunc_glyphs overwrite the
20699 first glyph of the row if it is an image. */
20700 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
20701 insert_left_trunc_glyphs (it);
20702 row->truncated_on_left_p = 1;
20703 }
20704
20705 /* Remember the position at which this line ends.
20706
20707 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
20708 cannot be before the call to find_row_edges below, since that is
20709 where these positions are determined. */
20710 row->end = it->current;
20711 if (!it->bidi_p)
20712 {
20713 row->minpos = row->start.pos;
20714 row->maxpos = row->end.pos;
20715 }
20716 else
20717 {
20718 /* ROW->minpos and ROW->maxpos must be the smallest and
20719 `1 + the largest' buffer positions in ROW. But if ROW was
20720 bidi-reordered, these two positions can be anywhere in the
20721 row, so we must determine them now. */
20722 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
20723 }
20724
20725 /* If the start of this line is the overlay arrow-position, then
20726 mark this glyph row as the one containing the overlay arrow.
20727 This is clearly a mess with variable size fonts. It would be
20728 better to let it be displayed like cursors under X. */
20729 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
20730 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
20731 !NILP (overlay_arrow_string)))
20732 {
20733 /* Overlay arrow in window redisplay is a fringe bitmap. */
20734 if (STRINGP (overlay_arrow_string))
20735 {
20736 struct glyph_row *arrow_row
20737 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
20738 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
20739 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
20740 struct glyph *p = row->glyphs[TEXT_AREA];
20741 struct glyph *p2, *end;
20742
20743 /* Copy the arrow glyphs. */
20744 while (glyph < arrow_end)
20745 *p++ = *glyph++;
20746
20747 /* Throw away padding glyphs. */
20748 p2 = p;
20749 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
20750 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
20751 ++p2;
20752 if (p2 > p)
20753 {
20754 while (p2 < end)
20755 *p++ = *p2++;
20756 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
20757 }
20758 }
20759 else
20760 {
20761 eassert (INTEGERP (overlay_arrow_string));
20762 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
20763 }
20764 overlay_arrow_seen = 1;
20765 }
20766
20767 /* Highlight trailing whitespace. */
20768 if (!NILP (Vshow_trailing_whitespace))
20769 highlight_trailing_whitespace (it->f, it->glyph_row);
20770
20771 /* Compute pixel dimensions of this line. */
20772 compute_line_metrics (it);
20773
20774 /* Implementation note: No changes in the glyphs of ROW or in their
20775 faces can be done past this point, because compute_line_metrics
20776 computes ROW's hash value and stores it within the glyph_row
20777 structure. */
20778
20779 /* Record whether this row ends inside an ellipsis. */
20780 row->ends_in_ellipsis_p
20781 = (it->method == GET_FROM_DISPLAY_VECTOR
20782 && it->ellipsis_p);
20783
20784 /* Save fringe bitmaps in this row. */
20785 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
20786 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
20787 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
20788 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
20789
20790 it->left_user_fringe_bitmap = 0;
20791 it->left_user_fringe_face_id = 0;
20792 it->right_user_fringe_bitmap = 0;
20793 it->right_user_fringe_face_id = 0;
20794
20795 /* Maybe set the cursor. */
20796 cvpos = it->w->cursor.vpos;
20797 if ((cvpos < 0
20798 /* In bidi-reordered rows, keep checking for proper cursor
20799 position even if one has been found already, because buffer
20800 positions in such rows change non-linearly with ROW->VPOS,
20801 when a line is continued. One exception: when we are at ZV,
20802 display cursor on the first suitable glyph row, since all
20803 the empty rows after that also have their position set to ZV. */
20804 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20805 lines' rows is implemented for bidi-reordered rows. */
20806 || (it->bidi_p
20807 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
20808 && PT >= MATRIX_ROW_START_CHARPOS (row)
20809 && PT <= MATRIX_ROW_END_CHARPOS (row)
20810 && cursor_row_p (row))
20811 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
20812
20813 /* Prepare for the next line. This line starts horizontally at (X
20814 HPOS) = (0 0). Vertical positions are incremented. As a
20815 convenience for the caller, IT->glyph_row is set to the next
20816 row to be used. */
20817 it->current_x = it->hpos = 0;
20818 it->current_y += row->height;
20819 SET_TEXT_POS (it->eol_pos, 0, 0);
20820 ++it->vpos;
20821 ++it->glyph_row;
20822 /* The next row should by default use the same value of the
20823 reversed_p flag as this one. set_iterator_to_next decides when
20824 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20825 the flag accordingly. */
20826 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20827 it->glyph_row->reversed_p = row->reversed_p;
20828 it->start = row->end;
20829 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
20830
20831 #undef RECORD_MAX_MIN_POS
20832 }
20833
20834 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20835 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20836 doc: /* Return paragraph direction at point in BUFFER.
20837 Value is either `left-to-right' or `right-to-left'.
20838 If BUFFER is omitted or nil, it defaults to the current buffer.
20839
20840 Paragraph direction determines how the text in the paragraph is displayed.
20841 In left-to-right paragraphs, text begins at the left margin of the window
20842 and the reading direction is generally left to right. In right-to-left
20843 paragraphs, text begins at the right margin and is read from right to left.
20844
20845 See also `bidi-paragraph-direction'. */)
20846 (Lisp_Object buffer)
20847 {
20848 struct buffer *buf = current_buffer;
20849 struct buffer *old = buf;
20850
20851 if (! NILP (buffer))
20852 {
20853 CHECK_BUFFER (buffer);
20854 buf = XBUFFER (buffer);
20855 }
20856
20857 if (NILP (BVAR (buf, bidi_display_reordering))
20858 || NILP (BVAR (buf, enable_multibyte_characters))
20859 /* When we are loading loadup.el, the character property tables
20860 needed for bidi iteration are not yet available. */
20861 || !NILP (Vpurify_flag))
20862 return Qleft_to_right;
20863 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20864 return BVAR (buf, bidi_paragraph_direction);
20865 else
20866 {
20867 /* Determine the direction from buffer text. We could try to
20868 use current_matrix if it is up to date, but this seems fast
20869 enough as it is. */
20870 struct bidi_it itb;
20871 ptrdiff_t pos = BUF_PT (buf);
20872 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20873 int c;
20874 void *itb_data = bidi_shelve_cache ();
20875
20876 set_buffer_temp (buf);
20877 /* bidi_paragraph_init finds the base direction of the paragraph
20878 by searching forward from paragraph start. We need the base
20879 direction of the current or _previous_ paragraph, so we need
20880 to make sure we are within that paragraph. To that end, find
20881 the previous non-empty line. */
20882 if (pos >= ZV && pos > BEGV)
20883 DEC_BOTH (pos, bytepos);
20884 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20885 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20886 {
20887 while ((c = FETCH_BYTE (bytepos)) == '\n'
20888 || c == ' ' || c == '\t' || c == '\f')
20889 {
20890 if (bytepos <= BEGV_BYTE)
20891 break;
20892 bytepos--;
20893 pos--;
20894 }
20895 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20896 bytepos--;
20897 }
20898 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20899 itb.paragraph_dir = NEUTRAL_DIR;
20900 itb.string.s = NULL;
20901 itb.string.lstring = Qnil;
20902 itb.string.bufpos = 0;
20903 itb.string.from_disp_str = 0;
20904 itb.string.unibyte = 0;
20905 /* We have no window to use here for ignoring window-specific
20906 overlays. Using NULL for window pointer will cause
20907 compute_display_string_pos to use the current buffer. */
20908 itb.w = NULL;
20909 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20910 bidi_unshelve_cache (itb_data, 0);
20911 set_buffer_temp (old);
20912 switch (itb.paragraph_dir)
20913 {
20914 case L2R:
20915 return Qleft_to_right;
20916 break;
20917 case R2L:
20918 return Qright_to_left;
20919 break;
20920 default:
20921 emacs_abort ();
20922 }
20923 }
20924 }
20925
20926 DEFUN ("move-point-visually", Fmove_point_visually,
20927 Smove_point_visually, 1, 1, 0,
20928 doc: /* Move point in the visual order in the specified DIRECTION.
20929 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20930 left.
20931
20932 Value is the new character position of point. */)
20933 (Lisp_Object direction)
20934 {
20935 struct window *w = XWINDOW (selected_window);
20936 struct buffer *b = XBUFFER (w->contents);
20937 struct glyph_row *row;
20938 int dir;
20939 Lisp_Object paragraph_dir;
20940
20941 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20942 (!(ROW)->continued_p \
20943 && INTEGERP ((GLYPH)->object) \
20944 && (GLYPH)->type == CHAR_GLYPH \
20945 && (GLYPH)->u.ch == ' ' \
20946 && (GLYPH)->charpos >= 0 \
20947 && !(GLYPH)->avoid_cursor_p)
20948
20949 CHECK_NUMBER (direction);
20950 dir = XINT (direction);
20951 if (dir > 0)
20952 dir = 1;
20953 else
20954 dir = -1;
20955
20956 /* If current matrix is up-to-date, we can use the information
20957 recorded in the glyphs, at least as long as the goal is on the
20958 screen. */
20959 if (w->window_end_valid
20960 && !windows_or_buffers_changed
20961 && b
20962 && !b->clip_changed
20963 && !b->prevent_redisplay_optimizations_p
20964 && !window_outdated (w)
20965 /* We rely below on the cursor coordinates to be up to date, but
20966 we cannot trust them if some command moved point since the
20967 last complete redisplay. */
20968 && w->last_point == BUF_PT (b)
20969 && w->cursor.vpos >= 0
20970 && w->cursor.vpos < w->current_matrix->nrows
20971 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20972 {
20973 struct glyph *g = row->glyphs[TEXT_AREA];
20974 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20975 struct glyph *gpt = g + w->cursor.hpos;
20976
20977 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20978 {
20979 if (BUFFERP (g->object) && g->charpos != PT)
20980 {
20981 SET_PT (g->charpos);
20982 w->cursor.vpos = -1;
20983 return make_number (PT);
20984 }
20985 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20986 {
20987 ptrdiff_t new_pos;
20988
20989 if (BUFFERP (gpt->object))
20990 {
20991 new_pos = PT;
20992 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20993 new_pos += (row->reversed_p ? -dir : dir);
20994 else
20995 new_pos -= (row->reversed_p ? -dir : dir);
20996 }
20997 else if (BUFFERP (g->object))
20998 new_pos = g->charpos;
20999 else
21000 break;
21001 SET_PT (new_pos);
21002 w->cursor.vpos = -1;
21003 return make_number (PT);
21004 }
21005 else if (ROW_GLYPH_NEWLINE_P (row, g))
21006 {
21007 /* Glyphs inserted at the end of a non-empty line for
21008 positioning the cursor have zero charpos, so we must
21009 deduce the value of point by other means. */
21010 if (g->charpos > 0)
21011 SET_PT (g->charpos);
21012 else if (row->ends_at_zv_p && PT != ZV)
21013 SET_PT (ZV);
21014 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
21015 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21016 else
21017 break;
21018 w->cursor.vpos = -1;
21019 return make_number (PT);
21020 }
21021 }
21022 if (g == e || INTEGERP (g->object))
21023 {
21024 if (row->truncated_on_left_p || row->truncated_on_right_p)
21025 goto simulate_display;
21026 if (!row->reversed_p)
21027 row += dir;
21028 else
21029 row -= dir;
21030 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
21031 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
21032 goto simulate_display;
21033
21034 if (dir > 0)
21035 {
21036 if (row->reversed_p && !row->continued_p)
21037 {
21038 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21039 w->cursor.vpos = -1;
21040 return make_number (PT);
21041 }
21042 g = row->glyphs[TEXT_AREA];
21043 e = g + row->used[TEXT_AREA];
21044 for ( ; g < e; g++)
21045 {
21046 if (BUFFERP (g->object)
21047 /* Empty lines have only one glyph, which stands
21048 for the newline, and whose charpos is the
21049 buffer position of the newline. */
21050 || ROW_GLYPH_NEWLINE_P (row, g)
21051 /* When the buffer ends in a newline, the line at
21052 EOB also has one glyph, but its charpos is -1. */
21053 || (row->ends_at_zv_p
21054 && !row->reversed_p
21055 && INTEGERP (g->object)
21056 && g->type == CHAR_GLYPH
21057 && g->u.ch == ' '))
21058 {
21059 if (g->charpos > 0)
21060 SET_PT (g->charpos);
21061 else if (!row->reversed_p
21062 && row->ends_at_zv_p
21063 && PT != ZV)
21064 SET_PT (ZV);
21065 else
21066 continue;
21067 w->cursor.vpos = -1;
21068 return make_number (PT);
21069 }
21070 }
21071 }
21072 else
21073 {
21074 if (!row->reversed_p && !row->continued_p)
21075 {
21076 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21077 w->cursor.vpos = -1;
21078 return make_number (PT);
21079 }
21080 e = row->glyphs[TEXT_AREA];
21081 g = e + row->used[TEXT_AREA] - 1;
21082 for ( ; g >= e; g--)
21083 {
21084 if (BUFFERP (g->object)
21085 || (ROW_GLYPH_NEWLINE_P (row, g)
21086 && g->charpos > 0)
21087 /* Empty R2L lines on GUI frames have the buffer
21088 position of the newline stored in the stretch
21089 glyph. */
21090 || g->type == STRETCH_GLYPH
21091 || (row->ends_at_zv_p
21092 && row->reversed_p
21093 && INTEGERP (g->object)
21094 && g->type == CHAR_GLYPH
21095 && g->u.ch == ' '))
21096 {
21097 if (g->charpos > 0)
21098 SET_PT (g->charpos);
21099 else if (row->reversed_p
21100 && row->ends_at_zv_p
21101 && PT != ZV)
21102 SET_PT (ZV);
21103 else
21104 continue;
21105 w->cursor.vpos = -1;
21106 return make_number (PT);
21107 }
21108 }
21109 }
21110 }
21111 }
21112
21113 simulate_display:
21114
21115 /* If we wind up here, we failed to move by using the glyphs, so we
21116 need to simulate display instead. */
21117
21118 if (b)
21119 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
21120 else
21121 paragraph_dir = Qleft_to_right;
21122 if (EQ (paragraph_dir, Qright_to_left))
21123 dir = -dir;
21124 if (PT <= BEGV && dir < 0)
21125 xsignal0 (Qbeginning_of_buffer);
21126 else if (PT >= ZV && dir > 0)
21127 xsignal0 (Qend_of_buffer);
21128 else
21129 {
21130 struct text_pos pt;
21131 struct it it;
21132 int pt_x, target_x, pixel_width, pt_vpos;
21133 bool at_eol_p;
21134 bool overshoot_expected = false;
21135 bool target_is_eol_p = false;
21136
21137 /* Setup the arena. */
21138 SET_TEXT_POS (pt, PT, PT_BYTE);
21139 start_display (&it, w, pt);
21140
21141 if (it.cmp_it.id < 0
21142 && it.method == GET_FROM_STRING
21143 && it.area == TEXT_AREA
21144 && it.string_from_display_prop_p
21145 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
21146 overshoot_expected = true;
21147
21148 /* Find the X coordinate of point. We start from the beginning
21149 of this or previous line to make sure we are before point in
21150 the logical order (since the move_it_* functions can only
21151 move forward). */
21152 reseat:
21153 reseat_at_previous_visible_line_start (&it);
21154 it.current_x = it.hpos = it.current_y = it.vpos = 0;
21155 if (IT_CHARPOS (it) != PT)
21156 {
21157 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
21158 -1, -1, -1, MOVE_TO_POS);
21159 /* If we missed point because the character there is
21160 displayed out of a display vector that has more than one
21161 glyph, retry expecting overshoot. */
21162 if (it.method == GET_FROM_DISPLAY_VECTOR
21163 && it.current.dpvec_index > 0
21164 && !overshoot_expected)
21165 {
21166 overshoot_expected = true;
21167 goto reseat;
21168 }
21169 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
21170 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
21171 }
21172 pt_x = it.current_x;
21173 pt_vpos = it.vpos;
21174 if (dir > 0 || overshoot_expected)
21175 {
21176 struct glyph_row *row = it.glyph_row;
21177
21178 /* When point is at beginning of line, we don't have
21179 information about the glyph there loaded into struct
21180 it. Calling get_next_display_element fixes that. */
21181 if (pt_x == 0)
21182 get_next_display_element (&it);
21183 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21184 it.glyph_row = NULL;
21185 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
21186 it.glyph_row = row;
21187 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
21188 it, lest it will become out of sync with it's buffer
21189 position. */
21190 it.current_x = pt_x;
21191 }
21192 else
21193 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21194 pixel_width = it.pixel_width;
21195 if (overshoot_expected && at_eol_p)
21196 pixel_width = 0;
21197 else if (pixel_width <= 0)
21198 pixel_width = 1;
21199
21200 /* If there's a display string (or something similar) at point,
21201 we are actually at the glyph to the left of point, so we need
21202 to correct the X coordinate. */
21203 if (overshoot_expected)
21204 {
21205 if (it.bidi_p)
21206 pt_x += pixel_width * it.bidi_it.scan_dir;
21207 else
21208 pt_x += pixel_width;
21209 }
21210
21211 /* Compute target X coordinate, either to the left or to the
21212 right of point. On TTY frames, all characters have the same
21213 pixel width of 1, so we can use that. On GUI frames we don't
21214 have an easy way of getting at the pixel width of the
21215 character to the left of point, so we use a different method
21216 of getting to that place. */
21217 if (dir > 0)
21218 target_x = pt_x + pixel_width;
21219 else
21220 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
21221
21222 /* Target X coordinate could be one line above or below the line
21223 of point, in which case we need to adjust the target X
21224 coordinate. Also, if moving to the left, we need to begin at
21225 the left edge of the point's screen line. */
21226 if (dir < 0)
21227 {
21228 if (pt_x > 0)
21229 {
21230 start_display (&it, w, pt);
21231 reseat_at_previous_visible_line_start (&it);
21232 it.current_x = it.current_y = it.hpos = 0;
21233 if (pt_vpos != 0)
21234 move_it_by_lines (&it, pt_vpos);
21235 }
21236 else
21237 {
21238 move_it_by_lines (&it, -1);
21239 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
21240 target_is_eol_p = true;
21241 /* Under word-wrap, we don't know the x coordinate of
21242 the last character displayed on the previous line,
21243 which immediately precedes the wrap point. To find
21244 out its x coordinate, we try moving to the right
21245 margin of the window, which will stop at the wrap
21246 point, and then reset target_x to point at the
21247 character that precedes the wrap point. This is not
21248 needed on GUI frames, because (see below) there we
21249 move from the left margin one grapheme cluster at a
21250 time, and stop when we hit the wrap point. */
21251 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
21252 {
21253 void *it_data = NULL;
21254 struct it it2;
21255
21256 SAVE_IT (it2, it, it_data);
21257 move_it_in_display_line_to (&it, ZV, target_x,
21258 MOVE_TO_POS | MOVE_TO_X);
21259 /* If we arrived at target_x, that _is_ the last
21260 character on the previous line. */
21261 if (it.current_x != target_x)
21262 target_x = it.current_x - 1;
21263 RESTORE_IT (&it, &it2, it_data);
21264 }
21265 }
21266 }
21267 else
21268 {
21269 if (at_eol_p
21270 || (target_x >= it.last_visible_x
21271 && it.line_wrap != TRUNCATE))
21272 {
21273 if (pt_x > 0)
21274 move_it_by_lines (&it, 0);
21275 move_it_by_lines (&it, 1);
21276 target_x = 0;
21277 }
21278 }
21279
21280 /* Move to the target X coordinate. */
21281 #ifdef HAVE_WINDOW_SYSTEM
21282 /* On GUI frames, as we don't know the X coordinate of the
21283 character to the left of point, moving point to the left
21284 requires walking, one grapheme cluster at a time, until we
21285 find ourself at a place immediately to the left of the
21286 character at point. */
21287 if (FRAME_WINDOW_P (it.f) && dir < 0)
21288 {
21289 struct text_pos new_pos;
21290 enum move_it_result rc = MOVE_X_REACHED;
21291
21292 if (it.current_x == 0)
21293 get_next_display_element (&it);
21294 if (it.what == IT_COMPOSITION)
21295 {
21296 new_pos.charpos = it.cmp_it.charpos;
21297 new_pos.bytepos = -1;
21298 }
21299 else
21300 new_pos = it.current.pos;
21301
21302 while (it.current_x + it.pixel_width <= target_x
21303 && (rc == MOVE_X_REACHED
21304 /* Under word-wrap, move_it_in_display_line_to
21305 stops at correct coordinates, but sometimes
21306 returns MOVE_POS_MATCH_OR_ZV. */
21307 || (it.line_wrap == WORD_WRAP
21308 && rc == MOVE_POS_MATCH_OR_ZV)))
21309 {
21310 int new_x = it.current_x + it.pixel_width;
21311
21312 /* For composed characters, we want the position of the
21313 first character in the grapheme cluster (usually, the
21314 composition's base character), whereas it.current
21315 might give us the position of the _last_ one, e.g. if
21316 the composition is rendered in reverse due to bidi
21317 reordering. */
21318 if (it.what == IT_COMPOSITION)
21319 {
21320 new_pos.charpos = it.cmp_it.charpos;
21321 new_pos.bytepos = -1;
21322 }
21323 else
21324 new_pos = it.current.pos;
21325 if (new_x == it.current_x)
21326 new_x++;
21327 rc = move_it_in_display_line_to (&it, ZV, new_x,
21328 MOVE_TO_POS | MOVE_TO_X);
21329 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
21330 break;
21331 }
21332 /* The previous position we saw in the loop is the one we
21333 want. */
21334 if (new_pos.bytepos == -1)
21335 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
21336 it.current.pos = new_pos;
21337 }
21338 else
21339 #endif
21340 if (it.current_x != target_x)
21341 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
21342
21343 /* When lines are truncated, the above loop will stop at the
21344 window edge. But we want to get to the end of line, even if
21345 it is beyond the window edge; automatic hscroll will then
21346 scroll the window to show point as appropriate. */
21347 if (target_is_eol_p && it.line_wrap == TRUNCATE
21348 && get_next_display_element (&it))
21349 {
21350 struct text_pos new_pos = it.current.pos;
21351
21352 while (!ITERATOR_AT_END_OF_LINE_P (&it))
21353 {
21354 set_iterator_to_next (&it, 0);
21355 if (it.method == GET_FROM_BUFFER)
21356 new_pos = it.current.pos;
21357 if (!get_next_display_element (&it))
21358 break;
21359 }
21360
21361 it.current.pos = new_pos;
21362 }
21363
21364 /* If we ended up in a display string that covers point, move to
21365 buffer position to the right in the visual order. */
21366 if (dir > 0)
21367 {
21368 while (IT_CHARPOS (it) == PT)
21369 {
21370 set_iterator_to_next (&it, 0);
21371 if (!get_next_display_element (&it))
21372 break;
21373 }
21374 }
21375
21376 /* Move point to that position. */
21377 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
21378 }
21379
21380 return make_number (PT);
21381
21382 #undef ROW_GLYPH_NEWLINE_P
21383 }
21384
21385 \f
21386 /***********************************************************************
21387 Menu Bar
21388 ***********************************************************************/
21389
21390 /* Redisplay the menu bar in the frame for window W.
21391
21392 The menu bar of X frames that don't have X toolkit support is
21393 displayed in a special window W->frame->menu_bar_window.
21394
21395 The menu bar of terminal frames is treated specially as far as
21396 glyph matrices are concerned. Menu bar lines are not part of
21397 windows, so the update is done directly on the frame matrix rows
21398 for the menu bar. */
21399
21400 static void
21401 display_menu_bar (struct window *w)
21402 {
21403 struct frame *f = XFRAME (WINDOW_FRAME (w));
21404 struct it it;
21405 Lisp_Object items;
21406 int i;
21407
21408 /* Don't do all this for graphical frames. */
21409 #ifdef HAVE_NTGUI
21410 if (FRAME_W32_P (f))
21411 return;
21412 #endif
21413 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21414 if (FRAME_X_P (f))
21415 return;
21416 #endif
21417
21418 #ifdef HAVE_NS
21419 if (FRAME_NS_P (f))
21420 return;
21421 #endif /* HAVE_NS */
21422
21423 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21424 eassert (!FRAME_WINDOW_P (f));
21425 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
21426 it.first_visible_x = 0;
21427 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21428 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
21429 if (FRAME_WINDOW_P (f))
21430 {
21431 /* Menu bar lines are displayed in the desired matrix of the
21432 dummy window menu_bar_window. */
21433 struct window *menu_w;
21434 menu_w = XWINDOW (f->menu_bar_window);
21435 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
21436 MENU_FACE_ID);
21437 it.first_visible_x = 0;
21438 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21439 }
21440 else
21441 #endif /* not USE_X_TOOLKIT and not USE_GTK */
21442 {
21443 /* This is a TTY frame, i.e. character hpos/vpos are used as
21444 pixel x/y. */
21445 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
21446 MENU_FACE_ID);
21447 it.first_visible_x = 0;
21448 it.last_visible_x = FRAME_COLS (f);
21449 }
21450
21451 /* FIXME: This should be controlled by a user option. See the
21452 comments in redisplay_tool_bar and display_mode_line about
21453 this. */
21454 it.paragraph_embedding = L2R;
21455
21456 /* Clear all rows of the menu bar. */
21457 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
21458 {
21459 struct glyph_row *row = it.glyph_row + i;
21460 clear_glyph_row (row);
21461 row->enabled_p = true;
21462 row->full_width_p = 1;
21463 row->reversed_p = false;
21464 }
21465
21466 /* Display all items of the menu bar. */
21467 items = FRAME_MENU_BAR_ITEMS (it.f);
21468 for (i = 0; i < ASIZE (items); i += 4)
21469 {
21470 Lisp_Object string;
21471
21472 /* Stop at nil string. */
21473 string = AREF (items, i + 1);
21474 if (NILP (string))
21475 break;
21476
21477 /* Remember where item was displayed. */
21478 ASET (items, i + 3, make_number (it.hpos));
21479
21480 /* Display the item, pad with one space. */
21481 if (it.current_x < it.last_visible_x)
21482 display_string (NULL, string, Qnil, 0, 0, &it,
21483 SCHARS (string) + 1, 0, 0, -1);
21484 }
21485
21486 /* Fill out the line with spaces. */
21487 if (it.current_x < it.last_visible_x)
21488 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
21489
21490 /* Compute the total height of the lines. */
21491 compute_line_metrics (&it);
21492 }
21493
21494 /* Deep copy of a glyph row, including the glyphs. */
21495 static void
21496 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
21497 {
21498 struct glyph *pointers[1 + LAST_AREA];
21499 int to_used = to->used[TEXT_AREA];
21500
21501 /* Save glyph pointers of TO. */
21502 memcpy (pointers, to->glyphs, sizeof to->glyphs);
21503
21504 /* Do a structure assignment. */
21505 *to = *from;
21506
21507 /* Restore original glyph pointers of TO. */
21508 memcpy (to->glyphs, pointers, sizeof to->glyphs);
21509
21510 /* Copy the glyphs. */
21511 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
21512 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
21513
21514 /* If we filled only part of the TO row, fill the rest with
21515 space_glyph (which will display as empty space). */
21516 if (to_used > from->used[TEXT_AREA])
21517 fill_up_frame_row_with_spaces (to, to_used);
21518 }
21519
21520 /* Display one menu item on a TTY, by overwriting the glyphs in the
21521 frame F's desired glyph matrix with glyphs produced from the menu
21522 item text. Called from term.c to display TTY drop-down menus one
21523 item at a time.
21524
21525 ITEM_TEXT is the menu item text as a C string.
21526
21527 FACE_ID is the face ID to be used for this menu item. FACE_ID
21528 could specify one of 3 faces: a face for an enabled item, a face
21529 for a disabled item, or a face for a selected item.
21530
21531 X and Y are coordinates of the first glyph in the frame's desired
21532 matrix to be overwritten by the menu item. Since this is a TTY, Y
21533 is the zero-based number of the glyph row and X is the zero-based
21534 glyph number in the row, starting from left, where to start
21535 displaying the item.
21536
21537 SUBMENU non-zero means this menu item drops down a submenu, which
21538 should be indicated by displaying a proper visual cue after the
21539 item text. */
21540
21541 void
21542 display_tty_menu_item (const char *item_text, int width, int face_id,
21543 int x, int y, int submenu)
21544 {
21545 struct it it;
21546 struct frame *f = SELECTED_FRAME ();
21547 struct window *w = XWINDOW (f->selected_window);
21548 int saved_used, saved_truncated, saved_width, saved_reversed;
21549 struct glyph_row *row;
21550 size_t item_len = strlen (item_text);
21551
21552 eassert (FRAME_TERMCAP_P (f));
21553
21554 /* Don't write beyond the matrix's last row. This can happen for
21555 TTY screens that are not high enough to show the entire menu.
21556 (This is actually a bit of defensive programming, as
21557 tty_menu_display already limits the number of menu items to one
21558 less than the number of screen lines.) */
21559 if (y >= f->desired_matrix->nrows)
21560 return;
21561
21562 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
21563 it.first_visible_x = 0;
21564 it.last_visible_x = FRAME_COLS (f) - 1;
21565 row = it.glyph_row;
21566 /* Start with the row contents from the current matrix. */
21567 deep_copy_glyph_row (row, f->current_matrix->rows + y);
21568 saved_width = row->full_width_p;
21569 row->full_width_p = 1;
21570 saved_reversed = row->reversed_p;
21571 row->reversed_p = 0;
21572 row->enabled_p = true;
21573
21574 /* Arrange for the menu item glyphs to start at (X,Y) and have the
21575 desired face. */
21576 eassert (x < f->desired_matrix->matrix_w);
21577 it.current_x = it.hpos = x;
21578 it.current_y = it.vpos = y;
21579 saved_used = row->used[TEXT_AREA];
21580 saved_truncated = row->truncated_on_right_p;
21581 row->used[TEXT_AREA] = x;
21582 it.face_id = face_id;
21583 it.line_wrap = TRUNCATE;
21584
21585 /* FIXME: This should be controlled by a user option. See the
21586 comments in redisplay_tool_bar and display_mode_line about this.
21587 Also, if paragraph_embedding could ever be R2L, changes will be
21588 needed to avoid shifting to the right the row characters in
21589 term.c:append_glyph. */
21590 it.paragraph_embedding = L2R;
21591
21592 /* Pad with a space on the left. */
21593 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
21594 width--;
21595 /* Display the menu item, pad with spaces to WIDTH. */
21596 if (submenu)
21597 {
21598 display_string (item_text, Qnil, Qnil, 0, 0, &it,
21599 item_len, 0, FRAME_COLS (f) - 1, -1);
21600 width -= item_len;
21601 /* Indicate with " >" that there's a submenu. */
21602 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
21603 FRAME_COLS (f) - 1, -1);
21604 }
21605 else
21606 display_string (item_text, Qnil, Qnil, 0, 0, &it,
21607 width, 0, FRAME_COLS (f) - 1, -1);
21608
21609 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
21610 row->truncated_on_right_p = saved_truncated;
21611 row->hash = row_hash (row);
21612 row->full_width_p = saved_width;
21613 row->reversed_p = saved_reversed;
21614 }
21615 \f
21616 /***********************************************************************
21617 Mode Line
21618 ***********************************************************************/
21619
21620 /* Redisplay mode lines in the window tree whose root is WINDOW. If
21621 FORCE is non-zero, redisplay mode lines unconditionally.
21622 Otherwise, redisplay only mode lines that are garbaged. Value is
21623 the number of windows whose mode lines were redisplayed. */
21624
21625 static int
21626 redisplay_mode_lines (Lisp_Object window, bool force)
21627 {
21628 int nwindows = 0;
21629
21630 while (!NILP (window))
21631 {
21632 struct window *w = XWINDOW (window);
21633
21634 if (WINDOWP (w->contents))
21635 nwindows += redisplay_mode_lines (w->contents, force);
21636 else if (force
21637 || FRAME_GARBAGED_P (XFRAME (w->frame))
21638 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
21639 {
21640 struct text_pos lpoint;
21641 struct buffer *old = current_buffer;
21642
21643 /* Set the window's buffer for the mode line display. */
21644 SET_TEXT_POS (lpoint, PT, PT_BYTE);
21645 set_buffer_internal_1 (XBUFFER (w->contents));
21646
21647 /* Point refers normally to the selected window. For any
21648 other window, set up appropriate value. */
21649 if (!EQ (window, selected_window))
21650 {
21651 struct text_pos pt;
21652
21653 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
21654 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
21655 }
21656
21657 /* Display mode lines. */
21658 clear_glyph_matrix (w->desired_matrix);
21659 if (display_mode_lines (w))
21660 ++nwindows;
21661
21662 /* Restore old settings. */
21663 set_buffer_internal_1 (old);
21664 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
21665 }
21666
21667 window = w->next;
21668 }
21669
21670 return nwindows;
21671 }
21672
21673
21674 /* Display the mode and/or header line of window W. Value is the
21675 sum number of mode lines and header lines displayed. */
21676
21677 static int
21678 display_mode_lines (struct window *w)
21679 {
21680 Lisp_Object old_selected_window = selected_window;
21681 Lisp_Object old_selected_frame = selected_frame;
21682 Lisp_Object new_frame = w->frame;
21683 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
21684 int n = 0;
21685
21686 selected_frame = new_frame;
21687 /* FIXME: If we were to allow the mode-line's computation changing the buffer
21688 or window's point, then we'd need select_window_1 here as well. */
21689 XSETWINDOW (selected_window, w);
21690 XFRAME (new_frame)->selected_window = selected_window;
21691
21692 /* These will be set while the mode line specs are processed. */
21693 line_number_displayed = 0;
21694 w->column_number_displayed = -1;
21695
21696 if (WINDOW_WANTS_MODELINE_P (w))
21697 {
21698 struct window *sel_w = XWINDOW (old_selected_window);
21699
21700 /* Select mode line face based on the real selected window. */
21701 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
21702 BVAR (current_buffer, mode_line_format));
21703 ++n;
21704 }
21705
21706 if (WINDOW_WANTS_HEADER_LINE_P (w))
21707 {
21708 display_mode_line (w, HEADER_LINE_FACE_ID,
21709 BVAR (current_buffer, header_line_format));
21710 ++n;
21711 }
21712
21713 XFRAME (new_frame)->selected_window = old_frame_selected_window;
21714 selected_frame = old_selected_frame;
21715 selected_window = old_selected_window;
21716 if (n > 0)
21717 w->must_be_updated_p = true;
21718 return n;
21719 }
21720
21721
21722 /* Display mode or header line of window W. FACE_ID specifies which
21723 line to display; it is either MODE_LINE_FACE_ID or
21724 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
21725 display. Value is the pixel height of the mode/header line
21726 displayed. */
21727
21728 static int
21729 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
21730 {
21731 struct it it;
21732 struct face *face;
21733 ptrdiff_t count = SPECPDL_INDEX ();
21734
21735 init_iterator (&it, w, -1, -1, NULL, face_id);
21736 /* Don't extend on a previously drawn mode-line.
21737 This may happen if called from pos_visible_p. */
21738 it.glyph_row->enabled_p = false;
21739 prepare_desired_row (w, it.glyph_row, true);
21740
21741 it.glyph_row->mode_line_p = 1;
21742
21743 /* FIXME: This should be controlled by a user option. But
21744 supporting such an option is not trivial, since the mode line is
21745 made up of many separate strings. */
21746 it.paragraph_embedding = L2R;
21747
21748 record_unwind_protect (unwind_format_mode_line,
21749 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
21750
21751 mode_line_target = MODE_LINE_DISPLAY;
21752
21753 /* Temporarily make frame's keyboard the current kboard so that
21754 kboard-local variables in the mode_line_format will get the right
21755 values. */
21756 push_kboard (FRAME_KBOARD (it.f));
21757 record_unwind_save_match_data ();
21758 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21759 pop_kboard ();
21760
21761 unbind_to (count, Qnil);
21762
21763 /* Fill up with spaces. */
21764 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
21765
21766 compute_line_metrics (&it);
21767 it.glyph_row->full_width_p = 1;
21768 it.glyph_row->continued_p = 0;
21769 it.glyph_row->truncated_on_left_p = 0;
21770 it.glyph_row->truncated_on_right_p = 0;
21771
21772 /* Make a 3D mode-line have a shadow at its right end. */
21773 face = FACE_FROM_ID (it.f, face_id);
21774 extend_face_to_end_of_line (&it);
21775 if (face->box != FACE_NO_BOX)
21776 {
21777 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
21778 + it.glyph_row->used[TEXT_AREA] - 1);
21779 last->right_box_line_p = 1;
21780 }
21781
21782 return it.glyph_row->height;
21783 }
21784
21785 /* Move element ELT in LIST to the front of LIST.
21786 Return the updated list. */
21787
21788 static Lisp_Object
21789 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
21790 {
21791 register Lisp_Object tail, prev;
21792 register Lisp_Object tem;
21793
21794 tail = list;
21795 prev = Qnil;
21796 while (CONSP (tail))
21797 {
21798 tem = XCAR (tail);
21799
21800 if (EQ (elt, tem))
21801 {
21802 /* Splice out the link TAIL. */
21803 if (NILP (prev))
21804 list = XCDR (tail);
21805 else
21806 Fsetcdr (prev, XCDR (tail));
21807
21808 /* Now make it the first. */
21809 Fsetcdr (tail, list);
21810 return tail;
21811 }
21812 else
21813 prev = tail;
21814 tail = XCDR (tail);
21815 QUIT;
21816 }
21817
21818 /* Not found--return unchanged LIST. */
21819 return list;
21820 }
21821
21822 /* Contribute ELT to the mode line for window IT->w. How it
21823 translates into text depends on its data type.
21824
21825 IT describes the display environment in which we display, as usual.
21826
21827 DEPTH is the depth in recursion. It is used to prevent
21828 infinite recursion here.
21829
21830 FIELD_WIDTH is the number of characters the display of ELT should
21831 occupy in the mode line, and PRECISION is the maximum number of
21832 characters to display from ELT's representation. See
21833 display_string for details.
21834
21835 Returns the hpos of the end of the text generated by ELT.
21836
21837 PROPS is a property list to add to any string we encounter.
21838
21839 If RISKY is nonzero, remove (disregard) any properties in any string
21840 we encounter, and ignore :eval and :propertize.
21841
21842 The global variable `mode_line_target' determines whether the
21843 output is passed to `store_mode_line_noprop',
21844 `store_mode_line_string', or `display_string'. */
21845
21846 static int
21847 display_mode_element (struct it *it, int depth, int field_width, int precision,
21848 Lisp_Object elt, Lisp_Object props, int risky)
21849 {
21850 int n = 0, field, prec;
21851 int literal = 0;
21852
21853 tail_recurse:
21854 if (depth > 100)
21855 elt = build_string ("*too-deep*");
21856
21857 depth++;
21858
21859 switch (XTYPE (elt))
21860 {
21861 case Lisp_String:
21862 {
21863 /* A string: output it and check for %-constructs within it. */
21864 unsigned char c;
21865 ptrdiff_t offset = 0;
21866
21867 if (SCHARS (elt) > 0
21868 && (!NILP (props) || risky))
21869 {
21870 Lisp_Object oprops, aelt;
21871 oprops = Ftext_properties_at (make_number (0), elt);
21872
21873 /* If the starting string's properties are not what
21874 we want, translate the string. Also, if the string
21875 is risky, do that anyway. */
21876
21877 if (NILP (Fequal (props, oprops)) || risky)
21878 {
21879 /* If the starting string has properties,
21880 merge the specified ones onto the existing ones. */
21881 if (! NILP (oprops) && !risky)
21882 {
21883 Lisp_Object tem;
21884
21885 oprops = Fcopy_sequence (oprops);
21886 tem = props;
21887 while (CONSP (tem))
21888 {
21889 oprops = Fplist_put (oprops, XCAR (tem),
21890 XCAR (XCDR (tem)));
21891 tem = XCDR (XCDR (tem));
21892 }
21893 props = oprops;
21894 }
21895
21896 aelt = Fassoc (elt, mode_line_proptrans_alist);
21897 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
21898 {
21899 /* AELT is what we want. Move it to the front
21900 without consing. */
21901 elt = XCAR (aelt);
21902 mode_line_proptrans_alist
21903 = move_elt_to_front (aelt, mode_line_proptrans_alist);
21904 }
21905 else
21906 {
21907 Lisp_Object tem;
21908
21909 /* If AELT has the wrong props, it is useless.
21910 so get rid of it. */
21911 if (! NILP (aelt))
21912 mode_line_proptrans_alist
21913 = Fdelq (aelt, mode_line_proptrans_alist);
21914
21915 elt = Fcopy_sequence (elt);
21916 Fset_text_properties (make_number (0), Flength (elt),
21917 props, elt);
21918 /* Add this item to mode_line_proptrans_alist. */
21919 mode_line_proptrans_alist
21920 = Fcons (Fcons (elt, props),
21921 mode_line_proptrans_alist);
21922 /* Truncate mode_line_proptrans_alist
21923 to at most 50 elements. */
21924 tem = Fnthcdr (make_number (50),
21925 mode_line_proptrans_alist);
21926 if (! NILP (tem))
21927 XSETCDR (tem, Qnil);
21928 }
21929 }
21930 }
21931
21932 offset = 0;
21933
21934 if (literal)
21935 {
21936 prec = precision - n;
21937 switch (mode_line_target)
21938 {
21939 case MODE_LINE_NOPROP:
21940 case MODE_LINE_TITLE:
21941 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
21942 break;
21943 case MODE_LINE_STRING:
21944 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
21945 break;
21946 case MODE_LINE_DISPLAY:
21947 n += display_string (NULL, elt, Qnil, 0, 0, it,
21948 0, prec, 0, STRING_MULTIBYTE (elt));
21949 break;
21950 }
21951
21952 break;
21953 }
21954
21955 /* Handle the non-literal case. */
21956
21957 while ((precision <= 0 || n < precision)
21958 && SREF (elt, offset) != 0
21959 && (mode_line_target != MODE_LINE_DISPLAY
21960 || it->current_x < it->last_visible_x))
21961 {
21962 ptrdiff_t last_offset = offset;
21963
21964 /* Advance to end of string or next format specifier. */
21965 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
21966 ;
21967
21968 if (offset - 1 != last_offset)
21969 {
21970 ptrdiff_t nchars, nbytes;
21971
21972 /* Output to end of string or up to '%'. Field width
21973 is length of string. Don't output more than
21974 PRECISION allows us. */
21975 offset--;
21976
21977 prec = c_string_width (SDATA (elt) + last_offset,
21978 offset - last_offset, precision - n,
21979 &nchars, &nbytes);
21980
21981 switch (mode_line_target)
21982 {
21983 case MODE_LINE_NOPROP:
21984 case MODE_LINE_TITLE:
21985 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
21986 break;
21987 case MODE_LINE_STRING:
21988 {
21989 ptrdiff_t bytepos = last_offset;
21990 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21991 ptrdiff_t endpos = (precision <= 0
21992 ? string_byte_to_char (elt, offset)
21993 : charpos + nchars);
21994
21995 n += store_mode_line_string (NULL,
21996 Fsubstring (elt, make_number (charpos),
21997 make_number (endpos)),
21998 0, 0, 0, Qnil);
21999 }
22000 break;
22001 case MODE_LINE_DISPLAY:
22002 {
22003 ptrdiff_t bytepos = last_offset;
22004 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22005
22006 if (precision <= 0)
22007 nchars = string_byte_to_char (elt, offset) - charpos;
22008 n += display_string (NULL, elt, Qnil, 0, charpos,
22009 it, 0, nchars, 0,
22010 STRING_MULTIBYTE (elt));
22011 }
22012 break;
22013 }
22014 }
22015 else /* c == '%' */
22016 {
22017 ptrdiff_t percent_position = offset;
22018
22019 /* Get the specified minimum width. Zero means
22020 don't pad. */
22021 field = 0;
22022 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
22023 field = field * 10 + c - '0';
22024
22025 /* Don't pad beyond the total padding allowed. */
22026 if (field_width - n > 0 && field > field_width - n)
22027 field = field_width - n;
22028
22029 /* Note that either PRECISION <= 0 or N < PRECISION. */
22030 prec = precision - n;
22031
22032 if (c == 'M')
22033 n += display_mode_element (it, depth, field, prec,
22034 Vglobal_mode_string, props,
22035 risky);
22036 else if (c != 0)
22037 {
22038 bool multibyte;
22039 ptrdiff_t bytepos, charpos;
22040 const char *spec;
22041 Lisp_Object string;
22042
22043 bytepos = percent_position;
22044 charpos = (STRING_MULTIBYTE (elt)
22045 ? string_byte_to_char (elt, bytepos)
22046 : bytepos);
22047 spec = decode_mode_spec (it->w, c, field, &string);
22048 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
22049
22050 switch (mode_line_target)
22051 {
22052 case MODE_LINE_NOPROP:
22053 case MODE_LINE_TITLE:
22054 n += store_mode_line_noprop (spec, field, prec);
22055 break;
22056 case MODE_LINE_STRING:
22057 {
22058 Lisp_Object tem = build_string (spec);
22059 props = Ftext_properties_at (make_number (charpos), elt);
22060 /* Should only keep face property in props */
22061 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
22062 }
22063 break;
22064 case MODE_LINE_DISPLAY:
22065 {
22066 int nglyphs_before, nwritten;
22067
22068 nglyphs_before = it->glyph_row->used[TEXT_AREA];
22069 nwritten = display_string (spec, string, elt,
22070 charpos, 0, it,
22071 field, prec, 0,
22072 multibyte);
22073
22074 /* Assign to the glyphs written above the
22075 string where the `%x' came from, position
22076 of the `%'. */
22077 if (nwritten > 0)
22078 {
22079 struct glyph *glyph
22080 = (it->glyph_row->glyphs[TEXT_AREA]
22081 + nglyphs_before);
22082 int i;
22083
22084 for (i = 0; i < nwritten; ++i)
22085 {
22086 glyph[i].object = elt;
22087 glyph[i].charpos = charpos;
22088 }
22089
22090 n += nwritten;
22091 }
22092 }
22093 break;
22094 }
22095 }
22096 else /* c == 0 */
22097 break;
22098 }
22099 }
22100 }
22101 break;
22102
22103 case Lisp_Symbol:
22104 /* A symbol: process the value of the symbol recursively
22105 as if it appeared here directly. Avoid error if symbol void.
22106 Special case: if value of symbol is a string, output the string
22107 literally. */
22108 {
22109 register Lisp_Object tem;
22110
22111 /* If the variable is not marked as risky to set
22112 then its contents are risky to use. */
22113 if (NILP (Fget (elt, Qrisky_local_variable)))
22114 risky = 1;
22115
22116 tem = Fboundp (elt);
22117 if (!NILP (tem))
22118 {
22119 tem = Fsymbol_value (elt);
22120 /* If value is a string, output that string literally:
22121 don't check for % within it. */
22122 if (STRINGP (tem))
22123 literal = 1;
22124
22125 if (!EQ (tem, elt))
22126 {
22127 /* Give up right away for nil or t. */
22128 elt = tem;
22129 goto tail_recurse;
22130 }
22131 }
22132 }
22133 break;
22134
22135 case Lisp_Cons:
22136 {
22137 register Lisp_Object car, tem;
22138
22139 /* A cons cell: five distinct cases.
22140 If first element is :eval or :propertize, do something special.
22141 If first element is a string or a cons, process all the elements
22142 and effectively concatenate them.
22143 If first element is a negative number, truncate displaying cdr to
22144 at most that many characters. If positive, pad (with spaces)
22145 to at least that many characters.
22146 If first element is a symbol, process the cadr or caddr recursively
22147 according to whether the symbol's value is non-nil or nil. */
22148 car = XCAR (elt);
22149 if (EQ (car, QCeval))
22150 {
22151 /* An element of the form (:eval FORM) means evaluate FORM
22152 and use the result as mode line elements. */
22153
22154 if (risky)
22155 break;
22156
22157 if (CONSP (XCDR (elt)))
22158 {
22159 Lisp_Object spec;
22160 spec = safe__eval (true, XCAR (XCDR (elt)));
22161 n += display_mode_element (it, depth, field_width - n,
22162 precision - n, spec, props,
22163 risky);
22164 }
22165 }
22166 else if (EQ (car, QCpropertize))
22167 {
22168 /* An element of the form (:propertize ELT PROPS...)
22169 means display ELT but applying properties PROPS. */
22170
22171 if (risky)
22172 break;
22173
22174 if (CONSP (XCDR (elt)))
22175 n += display_mode_element (it, depth, field_width - n,
22176 precision - n, XCAR (XCDR (elt)),
22177 XCDR (XCDR (elt)), risky);
22178 }
22179 else if (SYMBOLP (car))
22180 {
22181 tem = Fboundp (car);
22182 elt = XCDR (elt);
22183 if (!CONSP (elt))
22184 goto invalid;
22185 /* elt is now the cdr, and we know it is a cons cell.
22186 Use its car if CAR has a non-nil value. */
22187 if (!NILP (tem))
22188 {
22189 tem = Fsymbol_value (car);
22190 if (!NILP (tem))
22191 {
22192 elt = XCAR (elt);
22193 goto tail_recurse;
22194 }
22195 }
22196 /* Symbol's value is nil (or symbol is unbound)
22197 Get the cddr of the original list
22198 and if possible find the caddr and use that. */
22199 elt = XCDR (elt);
22200 if (NILP (elt))
22201 break;
22202 else if (!CONSP (elt))
22203 goto invalid;
22204 elt = XCAR (elt);
22205 goto tail_recurse;
22206 }
22207 else if (INTEGERP (car))
22208 {
22209 register int lim = XINT (car);
22210 elt = XCDR (elt);
22211 if (lim < 0)
22212 {
22213 /* Negative int means reduce maximum width. */
22214 if (precision <= 0)
22215 precision = -lim;
22216 else
22217 precision = min (precision, -lim);
22218 }
22219 else if (lim > 0)
22220 {
22221 /* Padding specified. Don't let it be more than
22222 current maximum. */
22223 if (precision > 0)
22224 lim = min (precision, lim);
22225
22226 /* If that's more padding than already wanted, queue it.
22227 But don't reduce padding already specified even if
22228 that is beyond the current truncation point. */
22229 field_width = max (lim, field_width);
22230 }
22231 goto tail_recurse;
22232 }
22233 else if (STRINGP (car) || CONSP (car))
22234 {
22235 Lisp_Object halftail = elt;
22236 int len = 0;
22237
22238 while (CONSP (elt)
22239 && (precision <= 0 || n < precision))
22240 {
22241 n += display_mode_element (it, depth,
22242 /* Do padding only after the last
22243 element in the list. */
22244 (! CONSP (XCDR (elt))
22245 ? field_width - n
22246 : 0),
22247 precision - n, XCAR (elt),
22248 props, risky);
22249 elt = XCDR (elt);
22250 len++;
22251 if ((len & 1) == 0)
22252 halftail = XCDR (halftail);
22253 /* Check for cycle. */
22254 if (EQ (halftail, elt))
22255 break;
22256 }
22257 }
22258 }
22259 break;
22260
22261 default:
22262 invalid:
22263 elt = build_string ("*invalid*");
22264 goto tail_recurse;
22265 }
22266
22267 /* Pad to FIELD_WIDTH. */
22268 if (field_width > 0 && n < field_width)
22269 {
22270 switch (mode_line_target)
22271 {
22272 case MODE_LINE_NOPROP:
22273 case MODE_LINE_TITLE:
22274 n += store_mode_line_noprop ("", field_width - n, 0);
22275 break;
22276 case MODE_LINE_STRING:
22277 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
22278 break;
22279 case MODE_LINE_DISPLAY:
22280 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
22281 0, 0, 0);
22282 break;
22283 }
22284 }
22285
22286 return n;
22287 }
22288
22289 /* Store a mode-line string element in mode_line_string_list.
22290
22291 If STRING is non-null, display that C string. Otherwise, the Lisp
22292 string LISP_STRING is displayed.
22293
22294 FIELD_WIDTH is the minimum number of output glyphs to produce.
22295 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22296 with spaces. FIELD_WIDTH <= 0 means don't pad.
22297
22298 PRECISION is the maximum number of characters to output from
22299 STRING. PRECISION <= 0 means don't truncate the string.
22300
22301 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
22302 properties to the string.
22303
22304 PROPS are the properties to add to the string.
22305 The mode_line_string_face face property is always added to the string.
22306 */
22307
22308 static int
22309 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
22310 int field_width, int precision, Lisp_Object props)
22311 {
22312 ptrdiff_t len;
22313 int n = 0;
22314
22315 if (string != NULL)
22316 {
22317 len = strlen (string);
22318 if (precision > 0 && len > precision)
22319 len = precision;
22320 lisp_string = make_string (string, len);
22321 if (NILP (props))
22322 props = mode_line_string_face_prop;
22323 else if (!NILP (mode_line_string_face))
22324 {
22325 Lisp_Object face = Fplist_get (props, Qface);
22326 props = Fcopy_sequence (props);
22327 if (NILP (face))
22328 face = mode_line_string_face;
22329 else
22330 face = list2 (face, mode_line_string_face);
22331 props = Fplist_put (props, Qface, face);
22332 }
22333 Fadd_text_properties (make_number (0), make_number (len),
22334 props, lisp_string);
22335 }
22336 else
22337 {
22338 len = XFASTINT (Flength (lisp_string));
22339 if (precision > 0 && len > precision)
22340 {
22341 len = precision;
22342 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
22343 precision = -1;
22344 }
22345 if (!NILP (mode_line_string_face))
22346 {
22347 Lisp_Object face;
22348 if (NILP (props))
22349 props = Ftext_properties_at (make_number (0), lisp_string);
22350 face = Fplist_get (props, Qface);
22351 if (NILP (face))
22352 face = mode_line_string_face;
22353 else
22354 face = list2 (face, mode_line_string_face);
22355 props = list2 (Qface, face);
22356 if (copy_string)
22357 lisp_string = Fcopy_sequence (lisp_string);
22358 }
22359 if (!NILP (props))
22360 Fadd_text_properties (make_number (0), make_number (len),
22361 props, lisp_string);
22362 }
22363
22364 if (len > 0)
22365 {
22366 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22367 n += len;
22368 }
22369
22370 if (field_width > len)
22371 {
22372 field_width -= len;
22373 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
22374 if (!NILP (props))
22375 Fadd_text_properties (make_number (0), make_number (field_width),
22376 props, lisp_string);
22377 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22378 n += field_width;
22379 }
22380
22381 return n;
22382 }
22383
22384
22385 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
22386 1, 4, 0,
22387 doc: /* Format a string out of a mode line format specification.
22388 First arg FORMAT specifies the mode line format (see `mode-line-format'
22389 for details) to use.
22390
22391 By default, the format is evaluated for the currently selected window.
22392
22393 Optional second arg FACE specifies the face property to put on all
22394 characters for which no face is specified. The value nil means the
22395 default face. The value t means whatever face the window's mode line
22396 currently uses (either `mode-line' or `mode-line-inactive',
22397 depending on whether the window is the selected window or not).
22398 An integer value means the value string has no text
22399 properties.
22400
22401 Optional third and fourth args WINDOW and BUFFER specify the window
22402 and buffer to use as the context for the formatting (defaults
22403 are the selected window and the WINDOW's buffer). */)
22404 (Lisp_Object format, Lisp_Object face,
22405 Lisp_Object window, Lisp_Object buffer)
22406 {
22407 struct it it;
22408 int len;
22409 struct window *w;
22410 struct buffer *old_buffer = NULL;
22411 int face_id;
22412 int no_props = INTEGERP (face);
22413 ptrdiff_t count = SPECPDL_INDEX ();
22414 Lisp_Object str;
22415 int string_start = 0;
22416
22417 w = decode_any_window (window);
22418 XSETWINDOW (window, w);
22419
22420 if (NILP (buffer))
22421 buffer = w->contents;
22422 CHECK_BUFFER (buffer);
22423
22424 /* Make formatting the modeline a non-op when noninteractive, otherwise
22425 there will be problems later caused by a partially initialized frame. */
22426 if (NILP (format) || noninteractive)
22427 return empty_unibyte_string;
22428
22429 if (no_props)
22430 face = Qnil;
22431
22432 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
22433 : EQ (face, Qt) ? (EQ (window, selected_window)
22434 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
22435 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
22436 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
22437 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
22438 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
22439 : DEFAULT_FACE_ID;
22440
22441 old_buffer = current_buffer;
22442
22443 /* Save things including mode_line_proptrans_alist,
22444 and set that to nil so that we don't alter the outer value. */
22445 record_unwind_protect (unwind_format_mode_line,
22446 format_mode_line_unwind_data
22447 (XFRAME (WINDOW_FRAME (w)),
22448 old_buffer, selected_window, 1));
22449 mode_line_proptrans_alist = Qnil;
22450
22451 Fselect_window (window, Qt);
22452 set_buffer_internal_1 (XBUFFER (buffer));
22453
22454 init_iterator (&it, w, -1, -1, NULL, face_id);
22455
22456 if (no_props)
22457 {
22458 mode_line_target = MODE_LINE_NOPROP;
22459 mode_line_string_face_prop = Qnil;
22460 mode_line_string_list = Qnil;
22461 string_start = MODE_LINE_NOPROP_LEN (0);
22462 }
22463 else
22464 {
22465 mode_line_target = MODE_LINE_STRING;
22466 mode_line_string_list = Qnil;
22467 mode_line_string_face = face;
22468 mode_line_string_face_prop
22469 = NILP (face) ? Qnil : list2 (Qface, face);
22470 }
22471
22472 push_kboard (FRAME_KBOARD (it.f));
22473 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
22474 pop_kboard ();
22475
22476 if (no_props)
22477 {
22478 len = MODE_LINE_NOPROP_LEN (string_start);
22479 str = make_string (mode_line_noprop_buf + string_start, len);
22480 }
22481 else
22482 {
22483 mode_line_string_list = Fnreverse (mode_line_string_list);
22484 str = Fmapconcat (intern ("identity"), mode_line_string_list,
22485 empty_unibyte_string);
22486 }
22487
22488 unbind_to (count, Qnil);
22489 return str;
22490 }
22491
22492 /* Write a null-terminated, right justified decimal representation of
22493 the positive integer D to BUF using a minimal field width WIDTH. */
22494
22495 static void
22496 pint2str (register char *buf, register int width, register ptrdiff_t d)
22497 {
22498 register char *p = buf;
22499
22500 if (d <= 0)
22501 *p++ = '0';
22502 else
22503 {
22504 while (d > 0)
22505 {
22506 *p++ = d % 10 + '0';
22507 d /= 10;
22508 }
22509 }
22510
22511 for (width -= (int) (p - buf); width > 0; --width)
22512 *p++ = ' ';
22513 *p-- = '\0';
22514 while (p > buf)
22515 {
22516 d = *buf;
22517 *buf++ = *p;
22518 *p-- = d;
22519 }
22520 }
22521
22522 /* Write a null-terminated, right justified decimal and "human
22523 readable" representation of the nonnegative integer D to BUF using
22524 a minimal field width WIDTH. D should be smaller than 999.5e24. */
22525
22526 static const char power_letter[] =
22527 {
22528 0, /* no letter */
22529 'k', /* kilo */
22530 'M', /* mega */
22531 'G', /* giga */
22532 'T', /* tera */
22533 'P', /* peta */
22534 'E', /* exa */
22535 'Z', /* zetta */
22536 'Y' /* yotta */
22537 };
22538
22539 static void
22540 pint2hrstr (char *buf, int width, ptrdiff_t d)
22541 {
22542 /* We aim to represent the nonnegative integer D as
22543 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
22544 ptrdiff_t quotient = d;
22545 int remainder = 0;
22546 /* -1 means: do not use TENTHS. */
22547 int tenths = -1;
22548 int exponent = 0;
22549
22550 /* Length of QUOTIENT.TENTHS as a string. */
22551 int length;
22552
22553 char * psuffix;
22554 char * p;
22555
22556 if (quotient >= 1000)
22557 {
22558 /* Scale to the appropriate EXPONENT. */
22559 do
22560 {
22561 remainder = quotient % 1000;
22562 quotient /= 1000;
22563 exponent++;
22564 }
22565 while (quotient >= 1000);
22566
22567 /* Round to nearest and decide whether to use TENTHS or not. */
22568 if (quotient <= 9)
22569 {
22570 tenths = remainder / 100;
22571 if (remainder % 100 >= 50)
22572 {
22573 if (tenths < 9)
22574 tenths++;
22575 else
22576 {
22577 quotient++;
22578 if (quotient == 10)
22579 tenths = -1;
22580 else
22581 tenths = 0;
22582 }
22583 }
22584 }
22585 else
22586 if (remainder >= 500)
22587 {
22588 if (quotient < 999)
22589 quotient++;
22590 else
22591 {
22592 quotient = 1;
22593 exponent++;
22594 tenths = 0;
22595 }
22596 }
22597 }
22598
22599 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
22600 if (tenths == -1 && quotient <= 99)
22601 if (quotient <= 9)
22602 length = 1;
22603 else
22604 length = 2;
22605 else
22606 length = 3;
22607 p = psuffix = buf + max (width, length);
22608
22609 /* Print EXPONENT. */
22610 *psuffix++ = power_letter[exponent];
22611 *psuffix = '\0';
22612
22613 /* Print TENTHS. */
22614 if (tenths >= 0)
22615 {
22616 *--p = '0' + tenths;
22617 *--p = '.';
22618 }
22619
22620 /* Print QUOTIENT. */
22621 do
22622 {
22623 int digit = quotient % 10;
22624 *--p = '0' + digit;
22625 }
22626 while ((quotient /= 10) != 0);
22627
22628 /* Print leading spaces. */
22629 while (buf < p)
22630 *--p = ' ';
22631 }
22632
22633 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
22634 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
22635 type of CODING_SYSTEM. Return updated pointer into BUF. */
22636
22637 static unsigned char invalid_eol_type[] = "(*invalid*)";
22638
22639 static char *
22640 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
22641 {
22642 Lisp_Object val;
22643 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
22644 const unsigned char *eol_str;
22645 int eol_str_len;
22646 /* The EOL conversion we are using. */
22647 Lisp_Object eoltype;
22648
22649 val = CODING_SYSTEM_SPEC (coding_system);
22650 eoltype = Qnil;
22651
22652 if (!VECTORP (val)) /* Not yet decided. */
22653 {
22654 *buf++ = multibyte ? '-' : ' ';
22655 if (eol_flag)
22656 eoltype = eol_mnemonic_undecided;
22657 /* Don't mention EOL conversion if it isn't decided. */
22658 }
22659 else
22660 {
22661 Lisp_Object attrs;
22662 Lisp_Object eolvalue;
22663
22664 attrs = AREF (val, 0);
22665 eolvalue = AREF (val, 2);
22666
22667 *buf++ = multibyte
22668 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
22669 : ' ';
22670
22671 if (eol_flag)
22672 {
22673 /* The EOL conversion that is normal on this system. */
22674
22675 if (NILP (eolvalue)) /* Not yet decided. */
22676 eoltype = eol_mnemonic_undecided;
22677 else if (VECTORP (eolvalue)) /* Not yet decided. */
22678 eoltype = eol_mnemonic_undecided;
22679 else /* eolvalue is Qunix, Qdos, or Qmac. */
22680 eoltype = (EQ (eolvalue, Qunix)
22681 ? eol_mnemonic_unix
22682 : (EQ (eolvalue, Qdos) == 1
22683 ? eol_mnemonic_dos : eol_mnemonic_mac));
22684 }
22685 }
22686
22687 if (eol_flag)
22688 {
22689 /* Mention the EOL conversion if it is not the usual one. */
22690 if (STRINGP (eoltype))
22691 {
22692 eol_str = SDATA (eoltype);
22693 eol_str_len = SBYTES (eoltype);
22694 }
22695 else if (CHARACTERP (eoltype))
22696 {
22697 int c = XFASTINT (eoltype);
22698 return buf + CHAR_STRING (c, (unsigned char *) buf);
22699 }
22700 else
22701 {
22702 eol_str = invalid_eol_type;
22703 eol_str_len = sizeof (invalid_eol_type) - 1;
22704 }
22705 memcpy (buf, eol_str, eol_str_len);
22706 buf += eol_str_len;
22707 }
22708
22709 return buf;
22710 }
22711
22712 /* Return a string for the output of a mode line %-spec for window W,
22713 generated by character C. FIELD_WIDTH > 0 means pad the string
22714 returned with spaces to that value. Return a Lisp string in
22715 *STRING if the resulting string is taken from that Lisp string.
22716
22717 Note we operate on the current buffer for most purposes. */
22718
22719 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
22720
22721 static const char *
22722 decode_mode_spec (struct window *w, register int c, int field_width,
22723 Lisp_Object *string)
22724 {
22725 Lisp_Object obj;
22726 struct frame *f = XFRAME (WINDOW_FRAME (w));
22727 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
22728 /* We are going to use f->decode_mode_spec_buffer as the buffer to
22729 produce strings from numerical values, so limit preposterously
22730 large values of FIELD_WIDTH to avoid overrunning the buffer's
22731 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
22732 bytes plus the terminating null. */
22733 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
22734 struct buffer *b = current_buffer;
22735
22736 obj = Qnil;
22737 *string = Qnil;
22738
22739 switch (c)
22740 {
22741 case '*':
22742 if (!NILP (BVAR (b, read_only)))
22743 return "%";
22744 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22745 return "*";
22746 return "-";
22747
22748 case '+':
22749 /* This differs from %* only for a modified read-only buffer. */
22750 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22751 return "*";
22752 if (!NILP (BVAR (b, read_only)))
22753 return "%";
22754 return "-";
22755
22756 case '&':
22757 /* This differs from %* in ignoring read-only-ness. */
22758 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22759 return "*";
22760 return "-";
22761
22762 case '%':
22763 return "%";
22764
22765 case '[':
22766 {
22767 int i;
22768 char *p;
22769
22770 if (command_loop_level > 5)
22771 return "[[[... ";
22772 p = decode_mode_spec_buf;
22773 for (i = 0; i < command_loop_level; i++)
22774 *p++ = '[';
22775 *p = 0;
22776 return decode_mode_spec_buf;
22777 }
22778
22779 case ']':
22780 {
22781 int i;
22782 char *p;
22783
22784 if (command_loop_level > 5)
22785 return " ...]]]";
22786 p = decode_mode_spec_buf;
22787 for (i = 0; i < command_loop_level; i++)
22788 *p++ = ']';
22789 *p = 0;
22790 return decode_mode_spec_buf;
22791 }
22792
22793 case '-':
22794 {
22795 register int i;
22796
22797 /* Let lots_of_dashes be a string of infinite length. */
22798 if (mode_line_target == MODE_LINE_NOPROP
22799 || mode_line_target == MODE_LINE_STRING)
22800 return "--";
22801 if (field_width <= 0
22802 || field_width > sizeof (lots_of_dashes))
22803 {
22804 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
22805 decode_mode_spec_buf[i] = '-';
22806 decode_mode_spec_buf[i] = '\0';
22807 return decode_mode_spec_buf;
22808 }
22809 else
22810 return lots_of_dashes;
22811 }
22812
22813 case 'b':
22814 obj = BVAR (b, name);
22815 break;
22816
22817 case 'c':
22818 /* %c and %l are ignored in `frame-title-format'.
22819 (In redisplay_internal, the frame title is drawn _before_ the
22820 windows are updated, so the stuff which depends on actual
22821 window contents (such as %l) may fail to render properly, or
22822 even crash emacs.) */
22823 if (mode_line_target == MODE_LINE_TITLE)
22824 return "";
22825 else
22826 {
22827 ptrdiff_t col = current_column ();
22828 w->column_number_displayed = col;
22829 pint2str (decode_mode_spec_buf, width, col);
22830 return decode_mode_spec_buf;
22831 }
22832
22833 case 'e':
22834 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
22835 {
22836 if (NILP (Vmemory_full))
22837 return "";
22838 else
22839 return "!MEM FULL! ";
22840 }
22841 #else
22842 return "";
22843 #endif
22844
22845 case 'F':
22846 /* %F displays the frame name. */
22847 if (!NILP (f->title))
22848 return SSDATA (f->title);
22849 if (f->explicit_name || ! FRAME_WINDOW_P (f))
22850 return SSDATA (f->name);
22851 return "Emacs";
22852
22853 case 'f':
22854 obj = BVAR (b, filename);
22855 break;
22856
22857 case 'i':
22858 {
22859 ptrdiff_t size = ZV - BEGV;
22860 pint2str (decode_mode_spec_buf, width, size);
22861 return decode_mode_spec_buf;
22862 }
22863
22864 case 'I':
22865 {
22866 ptrdiff_t size = ZV - BEGV;
22867 pint2hrstr (decode_mode_spec_buf, width, size);
22868 return decode_mode_spec_buf;
22869 }
22870
22871 case 'l':
22872 {
22873 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
22874 ptrdiff_t topline, nlines, height;
22875 ptrdiff_t junk;
22876
22877 /* %c and %l are ignored in `frame-title-format'. */
22878 if (mode_line_target == MODE_LINE_TITLE)
22879 return "";
22880
22881 startpos = marker_position (w->start);
22882 startpos_byte = marker_byte_position (w->start);
22883 height = WINDOW_TOTAL_LINES (w);
22884
22885 /* If we decided that this buffer isn't suitable for line numbers,
22886 don't forget that too fast. */
22887 if (w->base_line_pos == -1)
22888 goto no_value;
22889
22890 /* If the buffer is very big, don't waste time. */
22891 if (INTEGERP (Vline_number_display_limit)
22892 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
22893 {
22894 w->base_line_pos = 0;
22895 w->base_line_number = 0;
22896 goto no_value;
22897 }
22898
22899 if (w->base_line_number > 0
22900 && w->base_line_pos > 0
22901 && w->base_line_pos <= startpos)
22902 {
22903 line = w->base_line_number;
22904 linepos = w->base_line_pos;
22905 linepos_byte = buf_charpos_to_bytepos (b, linepos);
22906 }
22907 else
22908 {
22909 line = 1;
22910 linepos = BUF_BEGV (b);
22911 linepos_byte = BUF_BEGV_BYTE (b);
22912 }
22913
22914 /* Count lines from base line to window start position. */
22915 nlines = display_count_lines (linepos_byte,
22916 startpos_byte,
22917 startpos, &junk);
22918
22919 topline = nlines + line;
22920
22921 /* Determine a new base line, if the old one is too close
22922 or too far away, or if we did not have one.
22923 "Too close" means it's plausible a scroll-down would
22924 go back past it. */
22925 if (startpos == BUF_BEGV (b))
22926 {
22927 w->base_line_number = topline;
22928 w->base_line_pos = BUF_BEGV (b);
22929 }
22930 else if (nlines < height + 25 || nlines > height * 3 + 50
22931 || linepos == BUF_BEGV (b))
22932 {
22933 ptrdiff_t limit = BUF_BEGV (b);
22934 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
22935 ptrdiff_t position;
22936 ptrdiff_t distance =
22937 (height * 2 + 30) * line_number_display_limit_width;
22938
22939 if (startpos - distance > limit)
22940 {
22941 limit = startpos - distance;
22942 limit_byte = CHAR_TO_BYTE (limit);
22943 }
22944
22945 nlines = display_count_lines (startpos_byte,
22946 limit_byte,
22947 - (height * 2 + 30),
22948 &position);
22949 /* If we couldn't find the lines we wanted within
22950 line_number_display_limit_width chars per line,
22951 give up on line numbers for this window. */
22952 if (position == limit_byte && limit == startpos - distance)
22953 {
22954 w->base_line_pos = -1;
22955 w->base_line_number = 0;
22956 goto no_value;
22957 }
22958
22959 w->base_line_number = topline - nlines;
22960 w->base_line_pos = BYTE_TO_CHAR (position);
22961 }
22962
22963 /* Now count lines from the start pos to point. */
22964 nlines = display_count_lines (startpos_byte,
22965 PT_BYTE, PT, &junk);
22966
22967 /* Record that we did display the line number. */
22968 line_number_displayed = 1;
22969
22970 /* Make the string to show. */
22971 pint2str (decode_mode_spec_buf, width, topline + nlines);
22972 return decode_mode_spec_buf;
22973 no_value:
22974 {
22975 char *p = decode_mode_spec_buf;
22976 int pad = width - 2;
22977 while (pad-- > 0)
22978 *p++ = ' ';
22979 *p++ = '?';
22980 *p++ = '?';
22981 *p = '\0';
22982 return decode_mode_spec_buf;
22983 }
22984 }
22985 break;
22986
22987 case 'm':
22988 obj = BVAR (b, mode_name);
22989 break;
22990
22991 case 'n':
22992 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
22993 return " Narrow";
22994 break;
22995
22996 case 'p':
22997 {
22998 ptrdiff_t pos = marker_position (w->start);
22999 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23000
23001 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
23002 {
23003 if (pos <= BUF_BEGV (b))
23004 return "All";
23005 else
23006 return "Bottom";
23007 }
23008 else if (pos <= BUF_BEGV (b))
23009 return "Top";
23010 else
23011 {
23012 if (total > 1000000)
23013 /* Do it differently for a large value, to avoid overflow. */
23014 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23015 else
23016 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
23017 /* We can't normally display a 3-digit number,
23018 so get us a 2-digit number that is close. */
23019 if (total == 100)
23020 total = 99;
23021 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23022 return decode_mode_spec_buf;
23023 }
23024 }
23025
23026 /* Display percentage of size above the bottom of the screen. */
23027 case 'P':
23028 {
23029 ptrdiff_t toppos = marker_position (w->start);
23030 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
23031 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23032
23033 if (botpos >= BUF_ZV (b))
23034 {
23035 if (toppos <= BUF_BEGV (b))
23036 return "All";
23037 else
23038 return "Bottom";
23039 }
23040 else
23041 {
23042 if (total > 1000000)
23043 /* Do it differently for a large value, to avoid overflow. */
23044 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23045 else
23046 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
23047 /* We can't normally display a 3-digit number,
23048 so get us a 2-digit number that is close. */
23049 if (total == 100)
23050 total = 99;
23051 if (toppos <= BUF_BEGV (b))
23052 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
23053 else
23054 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23055 return decode_mode_spec_buf;
23056 }
23057 }
23058
23059 case 's':
23060 /* status of process */
23061 obj = Fget_buffer_process (Fcurrent_buffer ());
23062 if (NILP (obj))
23063 return "no process";
23064 #ifndef MSDOS
23065 obj = Fsymbol_name (Fprocess_status (obj));
23066 #endif
23067 break;
23068
23069 case '@':
23070 {
23071 ptrdiff_t count = inhibit_garbage_collection ();
23072 Lisp_Object curdir = BVAR (current_buffer, directory);
23073 Lisp_Object val = Qnil;
23074
23075 if (STRINGP (curdir))
23076 val = call1 (intern ("file-remote-p"), curdir);
23077
23078 unbind_to (count, Qnil);
23079
23080 if (NILP (val))
23081 return "-";
23082 else
23083 return "@";
23084 }
23085
23086 case 'z':
23087 /* coding-system (not including end-of-line format) */
23088 case 'Z':
23089 /* coding-system (including end-of-line type) */
23090 {
23091 int eol_flag = (c == 'Z');
23092 char *p = decode_mode_spec_buf;
23093
23094 if (! FRAME_WINDOW_P (f))
23095 {
23096 /* No need to mention EOL here--the terminal never needs
23097 to do EOL conversion. */
23098 p = decode_mode_spec_coding (CODING_ID_NAME
23099 (FRAME_KEYBOARD_CODING (f)->id),
23100 p, 0);
23101 p = decode_mode_spec_coding (CODING_ID_NAME
23102 (FRAME_TERMINAL_CODING (f)->id),
23103 p, 0);
23104 }
23105 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
23106 p, eol_flag);
23107
23108 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
23109 #ifdef subprocesses
23110 obj = Fget_buffer_process (Fcurrent_buffer ());
23111 if (PROCESSP (obj))
23112 {
23113 p = decode_mode_spec_coding
23114 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
23115 p = decode_mode_spec_coding
23116 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
23117 }
23118 #endif /* subprocesses */
23119 #endif /* 0 */
23120 *p = 0;
23121 return decode_mode_spec_buf;
23122 }
23123 }
23124
23125 if (STRINGP (obj))
23126 {
23127 *string = obj;
23128 return SSDATA (obj);
23129 }
23130 else
23131 return "";
23132 }
23133
23134
23135 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
23136 means count lines back from START_BYTE. But don't go beyond
23137 LIMIT_BYTE. Return the number of lines thus found (always
23138 nonnegative).
23139
23140 Set *BYTE_POS_PTR to the byte position where we stopped. This is
23141 either the position COUNT lines after/before START_BYTE, if we
23142 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
23143 COUNT lines. */
23144
23145 static ptrdiff_t
23146 display_count_lines (ptrdiff_t start_byte,
23147 ptrdiff_t limit_byte, ptrdiff_t count,
23148 ptrdiff_t *byte_pos_ptr)
23149 {
23150 register unsigned char *cursor;
23151 unsigned char *base;
23152
23153 register ptrdiff_t ceiling;
23154 register unsigned char *ceiling_addr;
23155 ptrdiff_t orig_count = count;
23156
23157 /* If we are not in selective display mode,
23158 check only for newlines. */
23159 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
23160 && !INTEGERP (BVAR (current_buffer, selective_display)));
23161
23162 if (count > 0)
23163 {
23164 while (start_byte < limit_byte)
23165 {
23166 ceiling = BUFFER_CEILING_OF (start_byte);
23167 ceiling = min (limit_byte - 1, ceiling);
23168 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
23169 base = (cursor = BYTE_POS_ADDR (start_byte));
23170
23171 do
23172 {
23173 if (selective_display)
23174 {
23175 while (*cursor != '\n' && *cursor != 015
23176 && ++cursor != ceiling_addr)
23177 continue;
23178 if (cursor == ceiling_addr)
23179 break;
23180 }
23181 else
23182 {
23183 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
23184 if (! cursor)
23185 break;
23186 }
23187
23188 cursor++;
23189
23190 if (--count == 0)
23191 {
23192 start_byte += cursor - base;
23193 *byte_pos_ptr = start_byte;
23194 return orig_count;
23195 }
23196 }
23197 while (cursor < ceiling_addr);
23198
23199 start_byte += ceiling_addr - base;
23200 }
23201 }
23202 else
23203 {
23204 while (start_byte > limit_byte)
23205 {
23206 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
23207 ceiling = max (limit_byte, ceiling);
23208 ceiling_addr = BYTE_POS_ADDR (ceiling);
23209 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
23210 while (1)
23211 {
23212 if (selective_display)
23213 {
23214 while (--cursor >= ceiling_addr
23215 && *cursor != '\n' && *cursor != 015)
23216 continue;
23217 if (cursor < ceiling_addr)
23218 break;
23219 }
23220 else
23221 {
23222 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
23223 if (! cursor)
23224 break;
23225 }
23226
23227 if (++count == 0)
23228 {
23229 start_byte += cursor - base + 1;
23230 *byte_pos_ptr = start_byte;
23231 /* When scanning backwards, we should
23232 not count the newline posterior to which we stop. */
23233 return - orig_count - 1;
23234 }
23235 }
23236 start_byte += ceiling_addr - base;
23237 }
23238 }
23239
23240 *byte_pos_ptr = limit_byte;
23241
23242 if (count < 0)
23243 return - orig_count + count;
23244 return orig_count - count;
23245
23246 }
23247
23248
23249 \f
23250 /***********************************************************************
23251 Displaying strings
23252 ***********************************************************************/
23253
23254 /* Display a NUL-terminated string, starting with index START.
23255
23256 If STRING is non-null, display that C string. Otherwise, the Lisp
23257 string LISP_STRING is displayed. There's a case that STRING is
23258 non-null and LISP_STRING is not nil. It means STRING is a string
23259 data of LISP_STRING. In that case, we display LISP_STRING while
23260 ignoring its text properties.
23261
23262 If FACE_STRING is not nil, FACE_STRING_POS is a position in
23263 FACE_STRING. Display STRING or LISP_STRING with the face at
23264 FACE_STRING_POS in FACE_STRING:
23265
23266 Display the string in the environment given by IT, but use the
23267 standard display table, temporarily.
23268
23269 FIELD_WIDTH is the minimum number of output glyphs to produce.
23270 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23271 with spaces. If STRING has more characters, more than FIELD_WIDTH
23272 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
23273
23274 PRECISION is the maximum number of characters to output from
23275 STRING. PRECISION < 0 means don't truncate the string.
23276
23277 This is roughly equivalent to printf format specifiers:
23278
23279 FIELD_WIDTH PRECISION PRINTF
23280 ----------------------------------------
23281 -1 -1 %s
23282 -1 10 %.10s
23283 10 -1 %10s
23284 20 10 %20.10s
23285
23286 MULTIBYTE zero means do not display multibyte chars, > 0 means do
23287 display them, and < 0 means obey the current buffer's value of
23288 enable_multibyte_characters.
23289
23290 Value is the number of columns displayed. */
23291
23292 static int
23293 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
23294 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
23295 int field_width, int precision, int max_x, int multibyte)
23296 {
23297 int hpos_at_start = it->hpos;
23298 int saved_face_id = it->face_id;
23299 struct glyph_row *row = it->glyph_row;
23300 ptrdiff_t it_charpos;
23301
23302 /* Initialize the iterator IT for iteration over STRING beginning
23303 with index START. */
23304 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
23305 precision, field_width, multibyte);
23306 if (string && STRINGP (lisp_string))
23307 /* LISP_STRING is the one returned by decode_mode_spec. We should
23308 ignore its text properties. */
23309 it->stop_charpos = it->end_charpos;
23310
23311 /* If displaying STRING, set up the face of the iterator from
23312 FACE_STRING, if that's given. */
23313 if (STRINGP (face_string))
23314 {
23315 ptrdiff_t endptr;
23316 struct face *face;
23317
23318 it->face_id
23319 = face_at_string_position (it->w, face_string, face_string_pos,
23320 0, &endptr, it->base_face_id, 0);
23321 face = FACE_FROM_ID (it->f, it->face_id);
23322 it->face_box_p = face->box != FACE_NO_BOX;
23323 }
23324
23325 /* Set max_x to the maximum allowed X position. Don't let it go
23326 beyond the right edge of the window. */
23327 if (max_x <= 0)
23328 max_x = it->last_visible_x;
23329 else
23330 max_x = min (max_x, it->last_visible_x);
23331
23332 /* Skip over display elements that are not visible. because IT->w is
23333 hscrolled. */
23334 if (it->current_x < it->first_visible_x)
23335 move_it_in_display_line_to (it, 100000, it->first_visible_x,
23336 MOVE_TO_POS | MOVE_TO_X);
23337
23338 row->ascent = it->max_ascent;
23339 row->height = it->max_ascent + it->max_descent;
23340 row->phys_ascent = it->max_phys_ascent;
23341 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
23342 row->extra_line_spacing = it->max_extra_line_spacing;
23343
23344 if (STRINGP (it->string))
23345 it_charpos = IT_STRING_CHARPOS (*it);
23346 else
23347 it_charpos = IT_CHARPOS (*it);
23348
23349 /* This condition is for the case that we are called with current_x
23350 past last_visible_x. */
23351 while (it->current_x < max_x)
23352 {
23353 int x_before, x, n_glyphs_before, i, nglyphs;
23354
23355 /* Get the next display element. */
23356 if (!get_next_display_element (it))
23357 break;
23358
23359 /* Produce glyphs. */
23360 x_before = it->current_x;
23361 n_glyphs_before = row->used[TEXT_AREA];
23362 PRODUCE_GLYPHS (it);
23363
23364 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
23365 i = 0;
23366 x = x_before;
23367 while (i < nglyphs)
23368 {
23369 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
23370
23371 if (it->line_wrap != TRUNCATE
23372 && x + glyph->pixel_width > max_x)
23373 {
23374 /* End of continued line or max_x reached. */
23375 if (CHAR_GLYPH_PADDING_P (*glyph))
23376 {
23377 /* A wide character is unbreakable. */
23378 if (row->reversed_p)
23379 unproduce_glyphs (it, row->used[TEXT_AREA]
23380 - n_glyphs_before);
23381 row->used[TEXT_AREA] = n_glyphs_before;
23382 it->current_x = x_before;
23383 }
23384 else
23385 {
23386 if (row->reversed_p)
23387 unproduce_glyphs (it, row->used[TEXT_AREA]
23388 - (n_glyphs_before + i));
23389 row->used[TEXT_AREA] = n_glyphs_before + i;
23390 it->current_x = x;
23391 }
23392 break;
23393 }
23394 else if (x + glyph->pixel_width >= it->first_visible_x)
23395 {
23396 /* Glyph is at least partially visible. */
23397 ++it->hpos;
23398 if (x < it->first_visible_x)
23399 row->x = x - it->first_visible_x;
23400 }
23401 else
23402 {
23403 /* Glyph is off the left margin of the display area.
23404 Should not happen. */
23405 emacs_abort ();
23406 }
23407
23408 row->ascent = max (row->ascent, it->max_ascent);
23409 row->height = max (row->height, it->max_ascent + it->max_descent);
23410 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
23411 row->phys_height = max (row->phys_height,
23412 it->max_phys_ascent + it->max_phys_descent);
23413 row->extra_line_spacing = max (row->extra_line_spacing,
23414 it->max_extra_line_spacing);
23415 x += glyph->pixel_width;
23416 ++i;
23417 }
23418
23419 /* Stop if max_x reached. */
23420 if (i < nglyphs)
23421 break;
23422
23423 /* Stop at line ends. */
23424 if (ITERATOR_AT_END_OF_LINE_P (it))
23425 {
23426 it->continuation_lines_width = 0;
23427 break;
23428 }
23429
23430 set_iterator_to_next (it, 1);
23431 if (STRINGP (it->string))
23432 it_charpos = IT_STRING_CHARPOS (*it);
23433 else
23434 it_charpos = IT_CHARPOS (*it);
23435
23436 /* Stop if truncating at the right edge. */
23437 if (it->line_wrap == TRUNCATE
23438 && it->current_x >= it->last_visible_x)
23439 {
23440 /* Add truncation mark, but don't do it if the line is
23441 truncated at a padding space. */
23442 if (it_charpos < it->string_nchars)
23443 {
23444 if (!FRAME_WINDOW_P (it->f))
23445 {
23446 int ii, n;
23447
23448 if (it->current_x > it->last_visible_x)
23449 {
23450 if (!row->reversed_p)
23451 {
23452 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
23453 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23454 break;
23455 }
23456 else
23457 {
23458 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
23459 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23460 break;
23461 unproduce_glyphs (it, ii + 1);
23462 ii = row->used[TEXT_AREA] - (ii + 1);
23463 }
23464 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
23465 {
23466 row->used[TEXT_AREA] = ii;
23467 produce_special_glyphs (it, IT_TRUNCATION);
23468 }
23469 }
23470 produce_special_glyphs (it, IT_TRUNCATION);
23471 }
23472 row->truncated_on_right_p = 1;
23473 }
23474 break;
23475 }
23476 }
23477
23478 /* Maybe insert a truncation at the left. */
23479 if (it->first_visible_x
23480 && it_charpos > 0)
23481 {
23482 if (!FRAME_WINDOW_P (it->f)
23483 || (row->reversed_p
23484 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23485 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
23486 insert_left_trunc_glyphs (it);
23487 row->truncated_on_left_p = 1;
23488 }
23489
23490 it->face_id = saved_face_id;
23491
23492 /* Value is number of columns displayed. */
23493 return it->hpos - hpos_at_start;
23494 }
23495
23496
23497 \f
23498 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
23499 appears as an element of LIST or as the car of an element of LIST.
23500 If PROPVAL is a list, compare each element against LIST in that
23501 way, and return 1/2 if any element of PROPVAL is found in LIST.
23502 Otherwise return 0. This function cannot quit.
23503 The return value is 2 if the text is invisible but with an ellipsis
23504 and 1 if it's invisible and without an ellipsis. */
23505
23506 int
23507 invisible_p (register Lisp_Object propval, Lisp_Object list)
23508 {
23509 register Lisp_Object tail, proptail;
23510
23511 for (tail = list; CONSP (tail); tail = XCDR (tail))
23512 {
23513 register Lisp_Object tem;
23514 tem = XCAR (tail);
23515 if (EQ (propval, tem))
23516 return 1;
23517 if (CONSP (tem) && EQ (propval, XCAR (tem)))
23518 return NILP (XCDR (tem)) ? 1 : 2;
23519 }
23520
23521 if (CONSP (propval))
23522 {
23523 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
23524 {
23525 Lisp_Object propelt;
23526 propelt = XCAR (proptail);
23527 for (tail = list; CONSP (tail); tail = XCDR (tail))
23528 {
23529 register Lisp_Object tem;
23530 tem = XCAR (tail);
23531 if (EQ (propelt, tem))
23532 return 1;
23533 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
23534 return NILP (XCDR (tem)) ? 1 : 2;
23535 }
23536 }
23537 }
23538
23539 return 0;
23540 }
23541
23542 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
23543 doc: /* Non-nil if the property makes the text invisible.
23544 POS-OR-PROP can be a marker or number, in which case it is taken to be
23545 a position in the current buffer and the value of the `invisible' property
23546 is checked; or it can be some other value, which is then presumed to be the
23547 value of the `invisible' property of the text of interest.
23548 The non-nil value returned can be t for truly invisible text or something
23549 else if the text is replaced by an ellipsis. */)
23550 (Lisp_Object pos_or_prop)
23551 {
23552 Lisp_Object prop
23553 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
23554 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
23555 : pos_or_prop);
23556 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
23557 return (invis == 0 ? Qnil
23558 : invis == 1 ? Qt
23559 : make_number (invis));
23560 }
23561
23562 /* Calculate a width or height in pixels from a specification using
23563 the following elements:
23564
23565 SPEC ::=
23566 NUM - a (fractional) multiple of the default font width/height
23567 (NUM) - specifies exactly NUM pixels
23568 UNIT - a fixed number of pixels, see below.
23569 ELEMENT - size of a display element in pixels, see below.
23570 (NUM . SPEC) - equals NUM * SPEC
23571 (+ SPEC SPEC ...) - add pixel values
23572 (- SPEC SPEC ...) - subtract pixel values
23573 (- SPEC) - negate pixel value
23574
23575 NUM ::=
23576 INT or FLOAT - a number constant
23577 SYMBOL - use symbol's (buffer local) variable binding.
23578
23579 UNIT ::=
23580 in - pixels per inch *)
23581 mm - pixels per 1/1000 meter *)
23582 cm - pixels per 1/100 meter *)
23583 width - width of current font in pixels.
23584 height - height of current font in pixels.
23585
23586 *) using the ratio(s) defined in display-pixels-per-inch.
23587
23588 ELEMENT ::=
23589
23590 left-fringe - left fringe width in pixels
23591 right-fringe - right fringe width in pixels
23592
23593 left-margin - left margin width in pixels
23594 right-margin - right margin width in pixels
23595
23596 scroll-bar - scroll-bar area width in pixels
23597
23598 Examples:
23599
23600 Pixels corresponding to 5 inches:
23601 (5 . in)
23602
23603 Total width of non-text areas on left side of window (if scroll-bar is on left):
23604 '(space :width (+ left-fringe left-margin scroll-bar))
23605
23606 Align to first text column (in header line):
23607 '(space :align-to 0)
23608
23609 Align to middle of text area minus half the width of variable `my-image'
23610 containing a loaded image:
23611 '(space :align-to (0.5 . (- text my-image)))
23612
23613 Width of left margin minus width of 1 character in the default font:
23614 '(space :width (- left-margin 1))
23615
23616 Width of left margin minus width of 2 characters in the current font:
23617 '(space :width (- left-margin (2 . width)))
23618
23619 Center 1 character over left-margin (in header line):
23620 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
23621
23622 Different ways to express width of left fringe plus left margin minus one pixel:
23623 '(space :width (- (+ left-fringe left-margin) (1)))
23624 '(space :width (+ left-fringe left-margin (- (1))))
23625 '(space :width (+ left-fringe left-margin (-1)))
23626
23627 */
23628
23629 static int
23630 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
23631 struct font *font, int width_p, int *align_to)
23632 {
23633 double pixels;
23634
23635 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
23636 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
23637
23638 if (NILP (prop))
23639 return OK_PIXELS (0);
23640
23641 eassert (FRAME_LIVE_P (it->f));
23642
23643 if (SYMBOLP (prop))
23644 {
23645 if (SCHARS (SYMBOL_NAME (prop)) == 2)
23646 {
23647 char *unit = SSDATA (SYMBOL_NAME (prop));
23648
23649 if (unit[0] == 'i' && unit[1] == 'n')
23650 pixels = 1.0;
23651 else if (unit[0] == 'm' && unit[1] == 'm')
23652 pixels = 25.4;
23653 else if (unit[0] == 'c' && unit[1] == 'm')
23654 pixels = 2.54;
23655 else
23656 pixels = 0;
23657 if (pixels > 0)
23658 {
23659 double ppi = (width_p ? FRAME_RES_X (it->f)
23660 : FRAME_RES_Y (it->f));
23661
23662 if (ppi > 0)
23663 return OK_PIXELS (ppi / pixels);
23664 return 0;
23665 }
23666 }
23667
23668 #ifdef HAVE_WINDOW_SYSTEM
23669 if (EQ (prop, Qheight))
23670 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
23671 if (EQ (prop, Qwidth))
23672 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
23673 #else
23674 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
23675 return OK_PIXELS (1);
23676 #endif
23677
23678 if (EQ (prop, Qtext))
23679 return OK_PIXELS (width_p
23680 ? window_box_width (it->w, TEXT_AREA)
23681 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
23682
23683 if (align_to && *align_to < 0)
23684 {
23685 *res = 0;
23686 if (EQ (prop, Qleft))
23687 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
23688 if (EQ (prop, Qright))
23689 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
23690 if (EQ (prop, Qcenter))
23691 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
23692 + window_box_width (it->w, TEXT_AREA) / 2);
23693 if (EQ (prop, Qleft_fringe))
23694 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23695 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
23696 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
23697 if (EQ (prop, Qright_fringe))
23698 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23699 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
23700 : window_box_right_offset (it->w, TEXT_AREA));
23701 if (EQ (prop, Qleft_margin))
23702 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
23703 if (EQ (prop, Qright_margin))
23704 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
23705 if (EQ (prop, Qscroll_bar))
23706 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
23707 ? 0
23708 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
23709 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23710 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23711 : 0)));
23712 }
23713 else
23714 {
23715 if (EQ (prop, Qleft_fringe))
23716 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
23717 if (EQ (prop, Qright_fringe))
23718 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
23719 if (EQ (prop, Qleft_margin))
23720 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
23721 if (EQ (prop, Qright_margin))
23722 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
23723 if (EQ (prop, Qscroll_bar))
23724 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
23725 }
23726
23727 prop = buffer_local_value (prop, it->w->contents);
23728 if (EQ (prop, Qunbound))
23729 prop = Qnil;
23730 }
23731
23732 if (INTEGERP (prop) || FLOATP (prop))
23733 {
23734 int base_unit = (width_p
23735 ? FRAME_COLUMN_WIDTH (it->f)
23736 : FRAME_LINE_HEIGHT (it->f));
23737 return OK_PIXELS (XFLOATINT (prop) * base_unit);
23738 }
23739
23740 if (CONSP (prop))
23741 {
23742 Lisp_Object car = XCAR (prop);
23743 Lisp_Object cdr = XCDR (prop);
23744
23745 if (SYMBOLP (car))
23746 {
23747 #ifdef HAVE_WINDOW_SYSTEM
23748 if (FRAME_WINDOW_P (it->f)
23749 && valid_image_p (prop))
23750 {
23751 ptrdiff_t id = lookup_image (it->f, prop);
23752 struct image *img = IMAGE_FROM_ID (it->f, id);
23753
23754 return OK_PIXELS (width_p ? img->width : img->height);
23755 }
23756 #endif
23757 if (EQ (car, Qplus) || EQ (car, Qminus))
23758 {
23759 int first = 1;
23760 double px;
23761
23762 pixels = 0;
23763 while (CONSP (cdr))
23764 {
23765 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
23766 font, width_p, align_to))
23767 return 0;
23768 if (first)
23769 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
23770 else
23771 pixels += px;
23772 cdr = XCDR (cdr);
23773 }
23774 if (EQ (car, Qminus))
23775 pixels = -pixels;
23776 return OK_PIXELS (pixels);
23777 }
23778
23779 car = buffer_local_value (car, it->w->contents);
23780 if (EQ (car, Qunbound))
23781 car = Qnil;
23782 }
23783
23784 if (INTEGERP (car) || FLOATP (car))
23785 {
23786 double fact;
23787 pixels = XFLOATINT (car);
23788 if (NILP (cdr))
23789 return OK_PIXELS (pixels);
23790 if (calc_pixel_width_or_height (&fact, it, cdr,
23791 font, width_p, align_to))
23792 return OK_PIXELS (pixels * fact);
23793 return 0;
23794 }
23795
23796 return 0;
23797 }
23798
23799 return 0;
23800 }
23801
23802 \f
23803 /***********************************************************************
23804 Glyph Display
23805 ***********************************************************************/
23806
23807 #ifdef HAVE_WINDOW_SYSTEM
23808
23809 #ifdef GLYPH_DEBUG
23810
23811 void
23812 dump_glyph_string (struct glyph_string *s)
23813 {
23814 fprintf (stderr, "glyph string\n");
23815 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
23816 s->x, s->y, s->width, s->height);
23817 fprintf (stderr, " ybase = %d\n", s->ybase);
23818 fprintf (stderr, " hl = %d\n", s->hl);
23819 fprintf (stderr, " left overhang = %d, right = %d\n",
23820 s->left_overhang, s->right_overhang);
23821 fprintf (stderr, " nchars = %d\n", s->nchars);
23822 fprintf (stderr, " extends to end of line = %d\n",
23823 s->extends_to_end_of_line_p);
23824 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
23825 fprintf (stderr, " bg width = %d\n", s->background_width);
23826 }
23827
23828 #endif /* GLYPH_DEBUG */
23829
23830 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
23831 of XChar2b structures for S; it can't be allocated in
23832 init_glyph_string because it must be allocated via `alloca'. W
23833 is the window on which S is drawn. ROW and AREA are the glyph row
23834 and area within the row from which S is constructed. START is the
23835 index of the first glyph structure covered by S. HL is a
23836 face-override for drawing S. */
23837
23838 #ifdef HAVE_NTGUI
23839 #define OPTIONAL_HDC(hdc) HDC hdc,
23840 #define DECLARE_HDC(hdc) HDC hdc;
23841 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
23842 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
23843 #endif
23844
23845 #ifndef OPTIONAL_HDC
23846 #define OPTIONAL_HDC(hdc)
23847 #define DECLARE_HDC(hdc)
23848 #define ALLOCATE_HDC(hdc, f)
23849 #define RELEASE_HDC(hdc, f)
23850 #endif
23851
23852 static void
23853 init_glyph_string (struct glyph_string *s,
23854 OPTIONAL_HDC (hdc)
23855 XChar2b *char2b, struct window *w, struct glyph_row *row,
23856 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
23857 {
23858 memset (s, 0, sizeof *s);
23859 s->w = w;
23860 s->f = XFRAME (w->frame);
23861 #ifdef HAVE_NTGUI
23862 s->hdc = hdc;
23863 #endif
23864 s->display = FRAME_X_DISPLAY (s->f);
23865 s->window = FRAME_X_WINDOW (s->f);
23866 s->char2b = char2b;
23867 s->hl = hl;
23868 s->row = row;
23869 s->area = area;
23870 s->first_glyph = row->glyphs[area] + start;
23871 s->height = row->height;
23872 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
23873 s->ybase = s->y + row->ascent;
23874 }
23875
23876
23877 /* Append the list of glyph strings with head H and tail T to the list
23878 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
23879
23880 static void
23881 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
23882 struct glyph_string *h, struct glyph_string *t)
23883 {
23884 if (h)
23885 {
23886 if (*head)
23887 (*tail)->next = h;
23888 else
23889 *head = h;
23890 h->prev = *tail;
23891 *tail = t;
23892 }
23893 }
23894
23895
23896 /* Prepend the list of glyph strings with head H and tail T to the
23897 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
23898 result. */
23899
23900 static void
23901 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
23902 struct glyph_string *h, struct glyph_string *t)
23903 {
23904 if (h)
23905 {
23906 if (*head)
23907 (*head)->prev = t;
23908 else
23909 *tail = t;
23910 t->next = *head;
23911 *head = h;
23912 }
23913 }
23914
23915
23916 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
23917 Set *HEAD and *TAIL to the resulting list. */
23918
23919 static void
23920 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
23921 struct glyph_string *s)
23922 {
23923 s->next = s->prev = NULL;
23924 append_glyph_string_lists (head, tail, s, s);
23925 }
23926
23927
23928 /* Get face and two-byte form of character C in face FACE_ID on frame F.
23929 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
23930 make sure that X resources for the face returned are allocated.
23931 Value is a pointer to a realized face that is ready for display if
23932 DISPLAY_P is non-zero. */
23933
23934 static struct face *
23935 get_char_face_and_encoding (struct frame *f, int c, int face_id,
23936 XChar2b *char2b, int display_p)
23937 {
23938 struct face *face = FACE_FROM_ID (f, face_id);
23939 unsigned code = 0;
23940
23941 if (face->font)
23942 {
23943 code = face->font->driver->encode_char (face->font, c);
23944
23945 if (code == FONT_INVALID_CODE)
23946 code = 0;
23947 }
23948 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23949
23950 /* Make sure X resources of the face are allocated. */
23951 #ifdef HAVE_X_WINDOWS
23952 if (display_p)
23953 #endif
23954 {
23955 eassert (face != NULL);
23956 prepare_face_for_display (f, face);
23957 }
23958
23959 return face;
23960 }
23961
23962
23963 /* Get face and two-byte form of character glyph GLYPH on frame F.
23964 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
23965 a pointer to a realized face that is ready for display. */
23966
23967 static struct face *
23968 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
23969 XChar2b *char2b, int *two_byte_p)
23970 {
23971 struct face *face;
23972 unsigned code = 0;
23973
23974 eassert (glyph->type == CHAR_GLYPH);
23975 face = FACE_FROM_ID (f, glyph->face_id);
23976
23977 /* Make sure X resources of the face are allocated. */
23978 eassert (face != NULL);
23979 prepare_face_for_display (f, face);
23980
23981 if (two_byte_p)
23982 *two_byte_p = 0;
23983
23984 if (face->font)
23985 {
23986 if (CHAR_BYTE8_P (glyph->u.ch))
23987 code = CHAR_TO_BYTE8 (glyph->u.ch);
23988 else
23989 code = face->font->driver->encode_char (face->font, glyph->u.ch);
23990
23991 if (code == FONT_INVALID_CODE)
23992 code = 0;
23993 }
23994
23995 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23996 return face;
23997 }
23998
23999
24000 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
24001 Return 1 if FONT has a glyph for C, otherwise return 0. */
24002
24003 static int
24004 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
24005 {
24006 unsigned code;
24007
24008 if (CHAR_BYTE8_P (c))
24009 code = CHAR_TO_BYTE8 (c);
24010 else
24011 code = font->driver->encode_char (font, c);
24012
24013 if (code == FONT_INVALID_CODE)
24014 return 0;
24015 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24016 return 1;
24017 }
24018
24019
24020 /* Fill glyph string S with composition components specified by S->cmp.
24021
24022 BASE_FACE is the base face of the composition.
24023 S->cmp_from is the index of the first component for S.
24024
24025 OVERLAPS non-zero means S should draw the foreground only, and use
24026 its physical height for clipping. See also draw_glyphs.
24027
24028 Value is the index of a component not in S. */
24029
24030 static int
24031 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
24032 int overlaps)
24033 {
24034 int i;
24035 /* For all glyphs of this composition, starting at the offset
24036 S->cmp_from, until we reach the end of the definition or encounter a
24037 glyph that requires the different face, add it to S. */
24038 struct face *face;
24039
24040 eassert (s);
24041
24042 s->for_overlaps = overlaps;
24043 s->face = NULL;
24044 s->font = NULL;
24045 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
24046 {
24047 int c = COMPOSITION_GLYPH (s->cmp, i);
24048
24049 /* TAB in a composition means display glyphs with padding space
24050 on the left or right. */
24051 if (c != '\t')
24052 {
24053 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
24054 -1, Qnil);
24055
24056 face = get_char_face_and_encoding (s->f, c, face_id,
24057 s->char2b + i, 1);
24058 if (face)
24059 {
24060 if (! s->face)
24061 {
24062 s->face = face;
24063 s->font = s->face->font;
24064 }
24065 else if (s->face != face)
24066 break;
24067 }
24068 }
24069 ++s->nchars;
24070 }
24071 s->cmp_to = i;
24072
24073 if (s->face == NULL)
24074 {
24075 s->face = base_face->ascii_face;
24076 s->font = s->face->font;
24077 }
24078
24079 /* All glyph strings for the same composition has the same width,
24080 i.e. the width set for the first component of the composition. */
24081 s->width = s->first_glyph->pixel_width;
24082
24083 /* If the specified font could not be loaded, use the frame's
24084 default font, but record the fact that we couldn't load it in
24085 the glyph string so that we can draw rectangles for the
24086 characters of the glyph string. */
24087 if (s->font == NULL)
24088 {
24089 s->font_not_found_p = 1;
24090 s->font = FRAME_FONT (s->f);
24091 }
24092
24093 /* Adjust base line for subscript/superscript text. */
24094 s->ybase += s->first_glyph->voffset;
24095
24096 /* This glyph string must always be drawn with 16-bit functions. */
24097 s->two_byte_p = 1;
24098
24099 return s->cmp_to;
24100 }
24101
24102 static int
24103 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
24104 int start, int end, int overlaps)
24105 {
24106 struct glyph *glyph, *last;
24107 Lisp_Object lgstring;
24108 int i;
24109
24110 s->for_overlaps = overlaps;
24111 glyph = s->row->glyphs[s->area] + start;
24112 last = s->row->glyphs[s->area] + end;
24113 s->cmp_id = glyph->u.cmp.id;
24114 s->cmp_from = glyph->slice.cmp.from;
24115 s->cmp_to = glyph->slice.cmp.to + 1;
24116 s->face = FACE_FROM_ID (s->f, face_id);
24117 lgstring = composition_gstring_from_id (s->cmp_id);
24118 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
24119 glyph++;
24120 while (glyph < last
24121 && glyph->u.cmp.automatic
24122 && glyph->u.cmp.id == s->cmp_id
24123 && s->cmp_to == glyph->slice.cmp.from)
24124 s->cmp_to = (glyph++)->slice.cmp.to + 1;
24125
24126 for (i = s->cmp_from; i < s->cmp_to; i++)
24127 {
24128 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
24129 unsigned code = LGLYPH_CODE (lglyph);
24130
24131 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
24132 }
24133 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
24134 return glyph - s->row->glyphs[s->area];
24135 }
24136
24137
24138 /* Fill glyph string S from a sequence glyphs for glyphless characters.
24139 See the comment of fill_glyph_string for arguments.
24140 Value is the index of the first glyph not in S. */
24141
24142
24143 static int
24144 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
24145 int start, int end, int overlaps)
24146 {
24147 struct glyph *glyph, *last;
24148 int voffset;
24149
24150 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
24151 s->for_overlaps = overlaps;
24152 glyph = s->row->glyphs[s->area] + start;
24153 last = s->row->glyphs[s->area] + end;
24154 voffset = glyph->voffset;
24155 s->face = FACE_FROM_ID (s->f, face_id);
24156 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
24157 s->nchars = 1;
24158 s->width = glyph->pixel_width;
24159 glyph++;
24160 while (glyph < last
24161 && glyph->type == GLYPHLESS_GLYPH
24162 && glyph->voffset == voffset
24163 && glyph->face_id == face_id)
24164 {
24165 s->nchars++;
24166 s->width += glyph->pixel_width;
24167 glyph++;
24168 }
24169 s->ybase += voffset;
24170 return glyph - s->row->glyphs[s->area];
24171 }
24172
24173
24174 /* Fill glyph string S from a sequence of character glyphs.
24175
24176 FACE_ID is the face id of the string. START is the index of the
24177 first glyph to consider, END is the index of the last + 1.
24178 OVERLAPS non-zero means S should draw the foreground only, and use
24179 its physical height for clipping. See also draw_glyphs.
24180
24181 Value is the index of the first glyph not in S. */
24182
24183 static int
24184 fill_glyph_string (struct glyph_string *s, int face_id,
24185 int start, int end, int overlaps)
24186 {
24187 struct glyph *glyph, *last;
24188 int voffset;
24189 int glyph_not_available_p;
24190
24191 eassert (s->f == XFRAME (s->w->frame));
24192 eassert (s->nchars == 0);
24193 eassert (start >= 0 && end > start);
24194
24195 s->for_overlaps = overlaps;
24196 glyph = s->row->glyphs[s->area] + start;
24197 last = s->row->glyphs[s->area] + end;
24198 voffset = glyph->voffset;
24199 s->padding_p = glyph->padding_p;
24200 glyph_not_available_p = glyph->glyph_not_available_p;
24201
24202 while (glyph < last
24203 && glyph->type == CHAR_GLYPH
24204 && glyph->voffset == voffset
24205 /* Same face id implies same font, nowadays. */
24206 && glyph->face_id == face_id
24207 && glyph->glyph_not_available_p == glyph_not_available_p)
24208 {
24209 int two_byte_p;
24210
24211 s->face = get_glyph_face_and_encoding (s->f, glyph,
24212 s->char2b + s->nchars,
24213 &two_byte_p);
24214 s->two_byte_p = two_byte_p;
24215 ++s->nchars;
24216 eassert (s->nchars <= end - start);
24217 s->width += glyph->pixel_width;
24218 if (glyph++->padding_p != s->padding_p)
24219 break;
24220 }
24221
24222 s->font = s->face->font;
24223
24224 /* If the specified font could not be loaded, use the frame's font,
24225 but record the fact that we couldn't load it in
24226 S->font_not_found_p so that we can draw rectangles for the
24227 characters of the glyph string. */
24228 if (s->font == NULL || glyph_not_available_p)
24229 {
24230 s->font_not_found_p = 1;
24231 s->font = FRAME_FONT (s->f);
24232 }
24233
24234 /* Adjust base line for subscript/superscript text. */
24235 s->ybase += voffset;
24236
24237 eassert (s->face && s->face->gc);
24238 return glyph - s->row->glyphs[s->area];
24239 }
24240
24241
24242 /* Fill glyph string S from image glyph S->first_glyph. */
24243
24244 static void
24245 fill_image_glyph_string (struct glyph_string *s)
24246 {
24247 eassert (s->first_glyph->type == IMAGE_GLYPH);
24248 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
24249 eassert (s->img);
24250 s->slice = s->first_glyph->slice.img;
24251 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
24252 s->font = s->face->font;
24253 s->width = s->first_glyph->pixel_width;
24254
24255 /* Adjust base line for subscript/superscript text. */
24256 s->ybase += s->first_glyph->voffset;
24257 }
24258
24259
24260 /* Fill glyph string S from a sequence of stretch glyphs.
24261
24262 START is the index of the first glyph to consider,
24263 END is the index of the last + 1.
24264
24265 Value is the index of the first glyph not in S. */
24266
24267 static int
24268 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
24269 {
24270 struct glyph *glyph, *last;
24271 int voffset, face_id;
24272
24273 eassert (s->first_glyph->type == STRETCH_GLYPH);
24274
24275 glyph = s->row->glyphs[s->area] + start;
24276 last = s->row->glyphs[s->area] + end;
24277 face_id = glyph->face_id;
24278 s->face = FACE_FROM_ID (s->f, face_id);
24279 s->font = s->face->font;
24280 s->width = glyph->pixel_width;
24281 s->nchars = 1;
24282 voffset = glyph->voffset;
24283
24284 for (++glyph;
24285 (glyph < last
24286 && glyph->type == STRETCH_GLYPH
24287 && glyph->voffset == voffset
24288 && glyph->face_id == face_id);
24289 ++glyph)
24290 s->width += glyph->pixel_width;
24291
24292 /* Adjust base line for subscript/superscript text. */
24293 s->ybase += voffset;
24294
24295 /* The case that face->gc == 0 is handled when drawing the glyph
24296 string by calling prepare_face_for_display. */
24297 eassert (s->face);
24298 return glyph - s->row->glyphs[s->area];
24299 }
24300
24301 static struct font_metrics *
24302 get_per_char_metric (struct font *font, XChar2b *char2b)
24303 {
24304 static struct font_metrics metrics;
24305 unsigned code;
24306
24307 if (! font)
24308 return NULL;
24309 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
24310 if (code == FONT_INVALID_CODE)
24311 return NULL;
24312 font->driver->text_extents (font, &code, 1, &metrics);
24313 return &metrics;
24314 }
24315
24316 /* EXPORT for RIF:
24317 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
24318 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
24319 assumed to be zero. */
24320
24321 void
24322 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
24323 {
24324 *left = *right = 0;
24325
24326 if (glyph->type == CHAR_GLYPH)
24327 {
24328 struct face *face;
24329 XChar2b char2b;
24330 struct font_metrics *pcm;
24331
24332 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
24333 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
24334 {
24335 if (pcm->rbearing > pcm->width)
24336 *right = pcm->rbearing - pcm->width;
24337 if (pcm->lbearing < 0)
24338 *left = -pcm->lbearing;
24339 }
24340 }
24341 else if (glyph->type == COMPOSITE_GLYPH)
24342 {
24343 if (! glyph->u.cmp.automatic)
24344 {
24345 struct composition *cmp = composition_table[glyph->u.cmp.id];
24346
24347 if (cmp->rbearing > cmp->pixel_width)
24348 *right = cmp->rbearing - cmp->pixel_width;
24349 if (cmp->lbearing < 0)
24350 *left = - cmp->lbearing;
24351 }
24352 else
24353 {
24354 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
24355 struct font_metrics metrics;
24356
24357 composition_gstring_width (gstring, glyph->slice.cmp.from,
24358 glyph->slice.cmp.to + 1, &metrics);
24359 if (metrics.rbearing > metrics.width)
24360 *right = metrics.rbearing - metrics.width;
24361 if (metrics.lbearing < 0)
24362 *left = - metrics.lbearing;
24363 }
24364 }
24365 }
24366
24367
24368 /* Return the index of the first glyph preceding glyph string S that
24369 is overwritten by S because of S's left overhang. Value is -1
24370 if no glyphs are overwritten. */
24371
24372 static int
24373 left_overwritten (struct glyph_string *s)
24374 {
24375 int k;
24376
24377 if (s->left_overhang)
24378 {
24379 int x = 0, i;
24380 struct glyph *glyphs = s->row->glyphs[s->area];
24381 int first = s->first_glyph - glyphs;
24382
24383 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
24384 x -= glyphs[i].pixel_width;
24385
24386 k = i + 1;
24387 }
24388 else
24389 k = -1;
24390
24391 return k;
24392 }
24393
24394
24395 /* Return the index of the first glyph preceding glyph string S that
24396 is overwriting S because of its right overhang. Value is -1 if no
24397 glyph in front of S overwrites S. */
24398
24399 static int
24400 left_overwriting (struct glyph_string *s)
24401 {
24402 int i, k, x;
24403 struct glyph *glyphs = s->row->glyphs[s->area];
24404 int first = s->first_glyph - glyphs;
24405
24406 k = -1;
24407 x = 0;
24408 for (i = first - 1; i >= 0; --i)
24409 {
24410 int left, right;
24411 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24412 if (x + right > 0)
24413 k = i;
24414 x -= glyphs[i].pixel_width;
24415 }
24416
24417 return k;
24418 }
24419
24420
24421 /* Return the index of the last glyph following glyph string S that is
24422 overwritten by S because of S's right overhang. Value is -1 if
24423 no such glyph is found. */
24424
24425 static int
24426 right_overwritten (struct glyph_string *s)
24427 {
24428 int k = -1;
24429
24430 if (s->right_overhang)
24431 {
24432 int x = 0, i;
24433 struct glyph *glyphs = s->row->glyphs[s->area];
24434 int first = (s->first_glyph - glyphs
24435 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24436 int end = s->row->used[s->area];
24437
24438 for (i = first; i < end && s->right_overhang > x; ++i)
24439 x += glyphs[i].pixel_width;
24440
24441 k = i;
24442 }
24443
24444 return k;
24445 }
24446
24447
24448 /* Return the index of the last glyph following glyph string S that
24449 overwrites S because of its left overhang. Value is negative
24450 if no such glyph is found. */
24451
24452 static int
24453 right_overwriting (struct glyph_string *s)
24454 {
24455 int i, k, x;
24456 int end = s->row->used[s->area];
24457 struct glyph *glyphs = s->row->glyphs[s->area];
24458 int first = (s->first_glyph - glyphs
24459 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24460
24461 k = -1;
24462 x = 0;
24463 for (i = first; i < end; ++i)
24464 {
24465 int left, right;
24466 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24467 if (x - left < 0)
24468 k = i;
24469 x += glyphs[i].pixel_width;
24470 }
24471
24472 return k;
24473 }
24474
24475
24476 /* Set background width of glyph string S. START is the index of the
24477 first glyph following S. LAST_X is the right-most x-position + 1
24478 in the drawing area. */
24479
24480 static void
24481 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
24482 {
24483 /* If the face of this glyph string has to be drawn to the end of
24484 the drawing area, set S->extends_to_end_of_line_p. */
24485
24486 if (start == s->row->used[s->area]
24487 && ((s->row->fill_line_p
24488 && (s->hl == DRAW_NORMAL_TEXT
24489 || s->hl == DRAW_IMAGE_RAISED
24490 || s->hl == DRAW_IMAGE_SUNKEN))
24491 || s->hl == DRAW_MOUSE_FACE))
24492 s->extends_to_end_of_line_p = 1;
24493
24494 /* If S extends its face to the end of the line, set its
24495 background_width to the distance to the right edge of the drawing
24496 area. */
24497 if (s->extends_to_end_of_line_p)
24498 s->background_width = last_x - s->x + 1;
24499 else
24500 s->background_width = s->width;
24501 }
24502
24503
24504 /* Compute overhangs and x-positions for glyph string S and its
24505 predecessors, or successors. X is the starting x-position for S.
24506 BACKWARD_P non-zero means process predecessors. */
24507
24508 static void
24509 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
24510 {
24511 if (backward_p)
24512 {
24513 while (s)
24514 {
24515 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24516 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24517 x -= s->width;
24518 s->x = x;
24519 s = s->prev;
24520 }
24521 }
24522 else
24523 {
24524 while (s)
24525 {
24526 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24527 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24528 s->x = x;
24529 x += s->width;
24530 s = s->next;
24531 }
24532 }
24533 }
24534
24535
24536
24537 /* The following macros are only called from draw_glyphs below.
24538 They reference the following parameters of that function directly:
24539 `w', `row', `area', and `overlap_p'
24540 as well as the following local variables:
24541 `s', `f', and `hdc' (in W32) */
24542
24543 #ifdef HAVE_NTGUI
24544 /* On W32, silently add local `hdc' variable to argument list of
24545 init_glyph_string. */
24546 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
24547 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
24548 #else
24549 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
24550 init_glyph_string (s, char2b, w, row, area, start, hl)
24551 #endif
24552
24553 /* Add a glyph string for a stretch glyph to the list of strings
24554 between HEAD and TAIL. START is the index of the stretch glyph in
24555 row area AREA of glyph row ROW. END is the index of the last glyph
24556 in that glyph row area. X is the current output position assigned
24557 to the new glyph string constructed. HL overrides that face of the
24558 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
24559 is the right-most x-position of the drawing area. */
24560
24561 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
24562 and below -- keep them on one line. */
24563 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24564 do \
24565 { \
24566 s = alloca (sizeof *s); \
24567 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24568 START = fill_stretch_glyph_string (s, START, END); \
24569 append_glyph_string (&HEAD, &TAIL, s); \
24570 s->x = (X); \
24571 } \
24572 while (0)
24573
24574
24575 /* Add a glyph string for an image glyph to the list of strings
24576 between HEAD and TAIL. START is the index of the image glyph in
24577 row area AREA of glyph row ROW. END is the index of the last glyph
24578 in that glyph row area. X is the current output position assigned
24579 to the new glyph string constructed. HL overrides that face of the
24580 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
24581 is the right-most x-position of the drawing area. */
24582
24583 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24584 do \
24585 { \
24586 s = alloca (sizeof *s); \
24587 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24588 fill_image_glyph_string (s); \
24589 append_glyph_string (&HEAD, &TAIL, s); \
24590 ++START; \
24591 s->x = (X); \
24592 } \
24593 while (0)
24594
24595
24596 /* Add a glyph string for a sequence of character glyphs to the list
24597 of strings between HEAD and TAIL. START is the index of the first
24598 glyph in row area AREA of glyph row ROW that is part of the new
24599 glyph string. END is the index of the last glyph in that glyph row
24600 area. X is the current output position assigned to the new glyph
24601 string constructed. HL overrides that face of the glyph; e.g. it
24602 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
24603 right-most x-position of the drawing area. */
24604
24605 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
24606 do \
24607 { \
24608 int face_id; \
24609 XChar2b *char2b; \
24610 \
24611 face_id = (row)->glyphs[area][START].face_id; \
24612 \
24613 s = alloca (sizeof *s); \
24614 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
24615 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24616 append_glyph_string (&HEAD, &TAIL, s); \
24617 s->x = (X); \
24618 START = fill_glyph_string (s, face_id, START, END, overlaps); \
24619 } \
24620 while (0)
24621
24622
24623 /* Add a glyph string for a composite sequence to the list of strings
24624 between HEAD and TAIL. START is the index of the first glyph in
24625 row area AREA of glyph row ROW that is part of the new glyph
24626 string. END is the index of the last glyph in that glyph row area.
24627 X is the current output position assigned to the new glyph string
24628 constructed. HL overrides that face of the glyph; e.g. it is
24629 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
24630 x-position of the drawing area. */
24631
24632 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24633 do { \
24634 int face_id = (row)->glyphs[area][START].face_id; \
24635 struct face *base_face = FACE_FROM_ID (f, face_id); \
24636 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
24637 struct composition *cmp = composition_table[cmp_id]; \
24638 XChar2b *char2b; \
24639 struct glyph_string *first_s = NULL; \
24640 int n; \
24641 \
24642 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
24643 \
24644 /* Make glyph_strings for each glyph sequence that is drawable by \
24645 the same face, and append them to HEAD/TAIL. */ \
24646 for (n = 0; n < cmp->glyph_len;) \
24647 { \
24648 s = alloca (sizeof *s); \
24649 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24650 append_glyph_string (&(HEAD), &(TAIL), s); \
24651 s->cmp = cmp; \
24652 s->cmp_from = n; \
24653 s->x = (X); \
24654 if (n == 0) \
24655 first_s = s; \
24656 n = fill_composite_glyph_string (s, base_face, overlaps); \
24657 } \
24658 \
24659 ++START; \
24660 s = first_s; \
24661 } while (0)
24662
24663
24664 /* Add a glyph string for a glyph-string sequence to the list of strings
24665 between HEAD and TAIL. */
24666
24667 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24668 do { \
24669 int face_id; \
24670 XChar2b *char2b; \
24671 Lisp_Object gstring; \
24672 \
24673 face_id = (row)->glyphs[area][START].face_id; \
24674 gstring = (composition_gstring_from_id \
24675 ((row)->glyphs[area][START].u.cmp.id)); \
24676 s = alloca (sizeof *s); \
24677 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
24678 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24679 append_glyph_string (&(HEAD), &(TAIL), s); \
24680 s->x = (X); \
24681 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
24682 } while (0)
24683
24684
24685 /* Add a glyph string for a sequence of glyphless character's glyphs
24686 to the list of strings between HEAD and TAIL. The meanings of
24687 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
24688
24689 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24690 do \
24691 { \
24692 int face_id; \
24693 \
24694 face_id = (row)->glyphs[area][START].face_id; \
24695 \
24696 s = alloca (sizeof *s); \
24697 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24698 append_glyph_string (&HEAD, &TAIL, s); \
24699 s->x = (X); \
24700 START = fill_glyphless_glyph_string (s, face_id, START, END, \
24701 overlaps); \
24702 } \
24703 while (0)
24704
24705
24706 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
24707 of AREA of glyph row ROW on window W between indices START and END.
24708 HL overrides the face for drawing glyph strings, e.g. it is
24709 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
24710 x-positions of the drawing area.
24711
24712 This is an ugly monster macro construct because we must use alloca
24713 to allocate glyph strings (because draw_glyphs can be called
24714 asynchronously). */
24715
24716 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
24717 do \
24718 { \
24719 HEAD = TAIL = NULL; \
24720 while (START < END) \
24721 { \
24722 struct glyph *first_glyph = (row)->glyphs[area] + START; \
24723 switch (first_glyph->type) \
24724 { \
24725 case CHAR_GLYPH: \
24726 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
24727 HL, X, LAST_X); \
24728 break; \
24729 \
24730 case COMPOSITE_GLYPH: \
24731 if (first_glyph->u.cmp.automatic) \
24732 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
24733 HL, X, LAST_X); \
24734 else \
24735 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
24736 HL, X, LAST_X); \
24737 break; \
24738 \
24739 case STRETCH_GLYPH: \
24740 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
24741 HL, X, LAST_X); \
24742 break; \
24743 \
24744 case IMAGE_GLYPH: \
24745 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
24746 HL, X, LAST_X); \
24747 break; \
24748 \
24749 case GLYPHLESS_GLYPH: \
24750 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
24751 HL, X, LAST_X); \
24752 break; \
24753 \
24754 default: \
24755 emacs_abort (); \
24756 } \
24757 \
24758 if (s) \
24759 { \
24760 set_glyph_string_background_width (s, START, LAST_X); \
24761 (X) += s->width; \
24762 } \
24763 } \
24764 } while (0)
24765
24766
24767 /* Draw glyphs between START and END in AREA of ROW on window W,
24768 starting at x-position X. X is relative to AREA in W. HL is a
24769 face-override with the following meaning:
24770
24771 DRAW_NORMAL_TEXT draw normally
24772 DRAW_CURSOR draw in cursor face
24773 DRAW_MOUSE_FACE draw in mouse face.
24774 DRAW_INVERSE_VIDEO draw in mode line face
24775 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
24776 DRAW_IMAGE_RAISED draw an image with a raised relief around it
24777
24778 If OVERLAPS is non-zero, draw only the foreground of characters and
24779 clip to the physical height of ROW. Non-zero value also defines
24780 the overlapping part to be drawn:
24781
24782 OVERLAPS_PRED overlap with preceding rows
24783 OVERLAPS_SUCC overlap with succeeding rows
24784 OVERLAPS_BOTH overlap with both preceding/succeeding rows
24785 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
24786
24787 Value is the x-position reached, relative to AREA of W. */
24788
24789 static int
24790 draw_glyphs (struct window *w, int x, struct glyph_row *row,
24791 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
24792 enum draw_glyphs_face hl, int overlaps)
24793 {
24794 struct glyph_string *head, *tail;
24795 struct glyph_string *s;
24796 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
24797 int i, j, x_reached, last_x, area_left = 0;
24798 struct frame *f = XFRAME (WINDOW_FRAME (w));
24799 DECLARE_HDC (hdc);
24800
24801 ALLOCATE_HDC (hdc, f);
24802
24803 /* Let's rather be paranoid than getting a SEGV. */
24804 end = min (end, row->used[area]);
24805 start = clip_to_bounds (0, start, end);
24806
24807 /* Translate X to frame coordinates. Set last_x to the right
24808 end of the drawing area. */
24809 if (row->full_width_p)
24810 {
24811 /* X is relative to the left edge of W, without scroll bars
24812 or fringes. */
24813 area_left = WINDOW_LEFT_EDGE_X (w);
24814 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
24815 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
24816 }
24817 else
24818 {
24819 area_left = window_box_left (w, area);
24820 last_x = area_left + window_box_width (w, area);
24821 }
24822 x += area_left;
24823
24824 /* Build a doubly-linked list of glyph_string structures between
24825 head and tail from what we have to draw. Note that the macro
24826 BUILD_GLYPH_STRINGS will modify its start parameter. That's
24827 the reason we use a separate variable `i'. */
24828 i = start;
24829 USE_SAFE_ALLOCA;
24830 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
24831 if (tail)
24832 x_reached = tail->x + tail->background_width;
24833 else
24834 x_reached = x;
24835
24836 /* If there are any glyphs with lbearing < 0 or rbearing > width in
24837 the row, redraw some glyphs in front or following the glyph
24838 strings built above. */
24839 if (head && !overlaps && row->contains_overlapping_glyphs_p)
24840 {
24841 struct glyph_string *h, *t;
24842 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24843 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
24844 int check_mouse_face = 0;
24845 int dummy_x = 0;
24846
24847 /* If mouse highlighting is on, we may need to draw adjacent
24848 glyphs using mouse-face highlighting. */
24849 if (area == TEXT_AREA && row->mouse_face_p
24850 && hlinfo->mouse_face_beg_row >= 0
24851 && hlinfo->mouse_face_end_row >= 0)
24852 {
24853 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
24854
24855 if (row_vpos >= hlinfo->mouse_face_beg_row
24856 && row_vpos <= hlinfo->mouse_face_end_row)
24857 {
24858 check_mouse_face = 1;
24859 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
24860 ? hlinfo->mouse_face_beg_col : 0;
24861 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
24862 ? hlinfo->mouse_face_end_col
24863 : row->used[TEXT_AREA];
24864 }
24865 }
24866
24867 /* Compute overhangs for all glyph strings. */
24868 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
24869 for (s = head; s; s = s->next)
24870 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
24871
24872 /* Prepend glyph strings for glyphs in front of the first glyph
24873 string that are overwritten because of the first glyph
24874 string's left overhang. The background of all strings
24875 prepended must be drawn because the first glyph string
24876 draws over it. */
24877 i = left_overwritten (head);
24878 if (i >= 0)
24879 {
24880 enum draw_glyphs_face overlap_hl;
24881
24882 /* If this row contains mouse highlighting, attempt to draw
24883 the overlapped glyphs with the correct highlight. This
24884 code fails if the overlap encompasses more than one glyph
24885 and mouse-highlight spans only some of these glyphs.
24886 However, making it work perfectly involves a lot more
24887 code, and I don't know if the pathological case occurs in
24888 practice, so we'll stick to this for now. --- cyd */
24889 if (check_mouse_face
24890 && mouse_beg_col < start && mouse_end_col > i)
24891 overlap_hl = DRAW_MOUSE_FACE;
24892 else
24893 overlap_hl = DRAW_NORMAL_TEXT;
24894
24895 if (hl != overlap_hl)
24896 clip_head = head;
24897 j = i;
24898 BUILD_GLYPH_STRINGS (j, start, h, t,
24899 overlap_hl, dummy_x, last_x);
24900 start = i;
24901 compute_overhangs_and_x (t, head->x, 1);
24902 prepend_glyph_string_lists (&head, &tail, h, t);
24903 if (clip_head == NULL)
24904 clip_head = head;
24905 }
24906
24907 /* Prepend glyph strings for glyphs in front of the first glyph
24908 string that overwrite that glyph string because of their
24909 right overhang. For these strings, only the foreground must
24910 be drawn, because it draws over the glyph string at `head'.
24911 The background must not be drawn because this would overwrite
24912 right overhangs of preceding glyphs for which no glyph
24913 strings exist. */
24914 i = left_overwriting (head);
24915 if (i >= 0)
24916 {
24917 enum draw_glyphs_face overlap_hl;
24918
24919 if (check_mouse_face
24920 && mouse_beg_col < start && mouse_end_col > i)
24921 overlap_hl = DRAW_MOUSE_FACE;
24922 else
24923 overlap_hl = DRAW_NORMAL_TEXT;
24924
24925 if (hl == overlap_hl || clip_head == NULL)
24926 clip_head = head;
24927 BUILD_GLYPH_STRINGS (i, start, h, t,
24928 overlap_hl, dummy_x, last_x);
24929 for (s = h; s; s = s->next)
24930 s->background_filled_p = 1;
24931 compute_overhangs_and_x (t, head->x, 1);
24932 prepend_glyph_string_lists (&head, &tail, h, t);
24933 }
24934
24935 /* Append glyphs strings for glyphs following the last glyph
24936 string tail that are overwritten by tail. The background of
24937 these strings has to be drawn because tail's foreground draws
24938 over it. */
24939 i = right_overwritten (tail);
24940 if (i >= 0)
24941 {
24942 enum draw_glyphs_face overlap_hl;
24943
24944 if (check_mouse_face
24945 && mouse_beg_col < i && mouse_end_col > end)
24946 overlap_hl = DRAW_MOUSE_FACE;
24947 else
24948 overlap_hl = DRAW_NORMAL_TEXT;
24949
24950 if (hl != overlap_hl)
24951 clip_tail = tail;
24952 BUILD_GLYPH_STRINGS (end, i, h, t,
24953 overlap_hl, x, last_x);
24954 /* Because BUILD_GLYPH_STRINGS updates the first argument,
24955 we don't have `end = i;' here. */
24956 compute_overhangs_and_x (h, tail->x + tail->width, 0);
24957 append_glyph_string_lists (&head, &tail, h, t);
24958 if (clip_tail == NULL)
24959 clip_tail = tail;
24960 }
24961
24962 /* Append glyph strings for glyphs following the last glyph
24963 string tail that overwrite tail. The foreground of such
24964 glyphs has to be drawn because it writes into the background
24965 of tail. The background must not be drawn because it could
24966 paint over the foreground of following glyphs. */
24967 i = right_overwriting (tail);
24968 if (i >= 0)
24969 {
24970 enum draw_glyphs_face overlap_hl;
24971 if (check_mouse_face
24972 && mouse_beg_col < i && mouse_end_col > end)
24973 overlap_hl = DRAW_MOUSE_FACE;
24974 else
24975 overlap_hl = DRAW_NORMAL_TEXT;
24976
24977 if (hl == overlap_hl || clip_tail == NULL)
24978 clip_tail = tail;
24979 i++; /* We must include the Ith glyph. */
24980 BUILD_GLYPH_STRINGS (end, i, h, t,
24981 overlap_hl, x, last_x);
24982 for (s = h; s; s = s->next)
24983 s->background_filled_p = 1;
24984 compute_overhangs_and_x (h, tail->x + tail->width, 0);
24985 append_glyph_string_lists (&head, &tail, h, t);
24986 }
24987 if (clip_head || clip_tail)
24988 for (s = head; s; s = s->next)
24989 {
24990 s->clip_head = clip_head;
24991 s->clip_tail = clip_tail;
24992 }
24993 }
24994
24995 /* Draw all strings. */
24996 for (s = head; s; s = s->next)
24997 FRAME_RIF (f)->draw_glyph_string (s);
24998
24999 #ifndef HAVE_NS
25000 /* When focus a sole frame and move horizontally, this sets on_p to 0
25001 causing a failure to erase prev cursor position. */
25002 if (area == TEXT_AREA
25003 && !row->full_width_p
25004 /* When drawing overlapping rows, only the glyph strings'
25005 foreground is drawn, which doesn't erase a cursor
25006 completely. */
25007 && !overlaps)
25008 {
25009 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
25010 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
25011 : (tail ? tail->x + tail->background_width : x));
25012 x0 -= area_left;
25013 x1 -= area_left;
25014
25015 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
25016 row->y, MATRIX_ROW_BOTTOM_Y (row));
25017 }
25018 #endif
25019
25020 /* Value is the x-position up to which drawn, relative to AREA of W.
25021 This doesn't include parts drawn because of overhangs. */
25022 if (row->full_width_p)
25023 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
25024 else
25025 x_reached -= area_left;
25026
25027 RELEASE_HDC (hdc, f);
25028
25029 SAFE_FREE ();
25030 return x_reached;
25031 }
25032
25033 /* Expand row matrix if too narrow. Don't expand if area
25034 is not present. */
25035
25036 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
25037 { \
25038 if (!it->f->fonts_changed \
25039 && (it->glyph_row->glyphs[area] \
25040 < it->glyph_row->glyphs[area + 1])) \
25041 { \
25042 it->w->ncols_scale_factor++; \
25043 it->f->fonts_changed = 1; \
25044 } \
25045 }
25046
25047 /* Store one glyph for IT->char_to_display in IT->glyph_row.
25048 Called from x_produce_glyphs when IT->glyph_row is non-null. */
25049
25050 static void
25051 append_glyph (struct it *it)
25052 {
25053 struct glyph *glyph;
25054 enum glyph_row_area area = it->area;
25055
25056 eassert (it->glyph_row);
25057 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
25058
25059 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25060 if (glyph < it->glyph_row->glyphs[area + 1])
25061 {
25062 /* If the glyph row is reversed, we need to prepend the glyph
25063 rather than append it. */
25064 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25065 {
25066 struct glyph *g;
25067
25068 /* Make room for the additional glyph. */
25069 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25070 g[1] = *g;
25071 glyph = it->glyph_row->glyphs[area];
25072 }
25073 glyph->charpos = CHARPOS (it->position);
25074 glyph->object = it->object;
25075 if (it->pixel_width > 0)
25076 {
25077 glyph->pixel_width = it->pixel_width;
25078 glyph->padding_p = 0;
25079 }
25080 else
25081 {
25082 /* Assure at least 1-pixel width. Otherwise, cursor can't
25083 be displayed correctly. */
25084 glyph->pixel_width = 1;
25085 glyph->padding_p = 1;
25086 }
25087 glyph->ascent = it->ascent;
25088 glyph->descent = it->descent;
25089 glyph->voffset = it->voffset;
25090 glyph->type = CHAR_GLYPH;
25091 glyph->avoid_cursor_p = it->avoid_cursor_p;
25092 glyph->multibyte_p = it->multibyte_p;
25093 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25094 {
25095 /* In R2L rows, the left and the right box edges need to be
25096 drawn in reverse direction. */
25097 glyph->right_box_line_p = it->start_of_box_run_p;
25098 glyph->left_box_line_p = it->end_of_box_run_p;
25099 }
25100 else
25101 {
25102 glyph->left_box_line_p = it->start_of_box_run_p;
25103 glyph->right_box_line_p = it->end_of_box_run_p;
25104 }
25105 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25106 || it->phys_descent > it->descent);
25107 glyph->glyph_not_available_p = it->glyph_not_available_p;
25108 glyph->face_id = it->face_id;
25109 glyph->u.ch = it->char_to_display;
25110 glyph->slice.img = null_glyph_slice;
25111 glyph->font_type = FONT_TYPE_UNKNOWN;
25112 if (it->bidi_p)
25113 {
25114 glyph->resolved_level = it->bidi_it.resolved_level;
25115 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25116 emacs_abort ();
25117 glyph->bidi_type = it->bidi_it.type;
25118 }
25119 else
25120 {
25121 glyph->resolved_level = 0;
25122 glyph->bidi_type = UNKNOWN_BT;
25123 }
25124 ++it->glyph_row->used[area];
25125 }
25126 else
25127 IT_EXPAND_MATRIX_WIDTH (it, area);
25128 }
25129
25130 /* Store one glyph for the composition IT->cmp_it.id in
25131 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
25132 non-null. */
25133
25134 static void
25135 append_composite_glyph (struct it *it)
25136 {
25137 struct glyph *glyph;
25138 enum glyph_row_area area = it->area;
25139
25140 eassert (it->glyph_row);
25141
25142 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25143 if (glyph < it->glyph_row->glyphs[area + 1])
25144 {
25145 /* If the glyph row is reversed, we need to prepend the glyph
25146 rather than append it. */
25147 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
25148 {
25149 struct glyph *g;
25150
25151 /* Make room for the new glyph. */
25152 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
25153 g[1] = *g;
25154 glyph = it->glyph_row->glyphs[it->area];
25155 }
25156 glyph->charpos = it->cmp_it.charpos;
25157 glyph->object = it->object;
25158 glyph->pixel_width = it->pixel_width;
25159 glyph->ascent = it->ascent;
25160 glyph->descent = it->descent;
25161 glyph->voffset = it->voffset;
25162 glyph->type = COMPOSITE_GLYPH;
25163 if (it->cmp_it.ch < 0)
25164 {
25165 glyph->u.cmp.automatic = 0;
25166 glyph->u.cmp.id = it->cmp_it.id;
25167 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
25168 }
25169 else
25170 {
25171 glyph->u.cmp.automatic = 1;
25172 glyph->u.cmp.id = it->cmp_it.id;
25173 glyph->slice.cmp.from = it->cmp_it.from;
25174 glyph->slice.cmp.to = it->cmp_it.to - 1;
25175 }
25176 glyph->avoid_cursor_p = it->avoid_cursor_p;
25177 glyph->multibyte_p = it->multibyte_p;
25178 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25179 {
25180 /* In R2L rows, the left and the right box edges need to be
25181 drawn in reverse direction. */
25182 glyph->right_box_line_p = it->start_of_box_run_p;
25183 glyph->left_box_line_p = it->end_of_box_run_p;
25184 }
25185 else
25186 {
25187 glyph->left_box_line_p = it->start_of_box_run_p;
25188 glyph->right_box_line_p = it->end_of_box_run_p;
25189 }
25190 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25191 || it->phys_descent > it->descent);
25192 glyph->padding_p = 0;
25193 glyph->glyph_not_available_p = 0;
25194 glyph->face_id = it->face_id;
25195 glyph->font_type = FONT_TYPE_UNKNOWN;
25196 if (it->bidi_p)
25197 {
25198 glyph->resolved_level = it->bidi_it.resolved_level;
25199 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25200 emacs_abort ();
25201 glyph->bidi_type = it->bidi_it.type;
25202 }
25203 ++it->glyph_row->used[area];
25204 }
25205 else
25206 IT_EXPAND_MATRIX_WIDTH (it, area);
25207 }
25208
25209
25210 /* Change IT->ascent and IT->height according to the setting of
25211 IT->voffset. */
25212
25213 static void
25214 take_vertical_position_into_account (struct it *it)
25215 {
25216 if (it->voffset)
25217 {
25218 if (it->voffset < 0)
25219 /* Increase the ascent so that we can display the text higher
25220 in the line. */
25221 it->ascent -= it->voffset;
25222 else
25223 /* Increase the descent so that we can display the text lower
25224 in the line. */
25225 it->descent += it->voffset;
25226 }
25227 }
25228
25229
25230 /* Produce glyphs/get display metrics for the image IT is loaded with.
25231 See the description of struct display_iterator in dispextern.h for
25232 an overview of struct display_iterator. */
25233
25234 static void
25235 produce_image_glyph (struct it *it)
25236 {
25237 struct image *img;
25238 struct face *face;
25239 int glyph_ascent, crop;
25240 struct glyph_slice slice;
25241
25242 eassert (it->what == IT_IMAGE);
25243
25244 face = FACE_FROM_ID (it->f, it->face_id);
25245 eassert (face);
25246 /* Make sure X resources of the face is loaded. */
25247 prepare_face_for_display (it->f, face);
25248
25249 if (it->image_id < 0)
25250 {
25251 /* Fringe bitmap. */
25252 it->ascent = it->phys_ascent = 0;
25253 it->descent = it->phys_descent = 0;
25254 it->pixel_width = 0;
25255 it->nglyphs = 0;
25256 return;
25257 }
25258
25259 img = IMAGE_FROM_ID (it->f, it->image_id);
25260 eassert (img);
25261 /* Make sure X resources of the image is loaded. */
25262 prepare_image_for_display (it->f, img);
25263
25264 slice.x = slice.y = 0;
25265 slice.width = img->width;
25266 slice.height = img->height;
25267
25268 if (INTEGERP (it->slice.x))
25269 slice.x = XINT (it->slice.x);
25270 else if (FLOATP (it->slice.x))
25271 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
25272
25273 if (INTEGERP (it->slice.y))
25274 slice.y = XINT (it->slice.y);
25275 else if (FLOATP (it->slice.y))
25276 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
25277
25278 if (INTEGERP (it->slice.width))
25279 slice.width = XINT (it->slice.width);
25280 else if (FLOATP (it->slice.width))
25281 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
25282
25283 if (INTEGERP (it->slice.height))
25284 slice.height = XINT (it->slice.height);
25285 else if (FLOATP (it->slice.height))
25286 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
25287
25288 if (slice.x >= img->width)
25289 slice.x = img->width;
25290 if (slice.y >= img->height)
25291 slice.y = img->height;
25292 if (slice.x + slice.width >= img->width)
25293 slice.width = img->width - slice.x;
25294 if (slice.y + slice.height > img->height)
25295 slice.height = img->height - slice.y;
25296
25297 if (slice.width == 0 || slice.height == 0)
25298 return;
25299
25300 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
25301
25302 it->descent = slice.height - glyph_ascent;
25303 if (slice.y == 0)
25304 it->descent += img->vmargin;
25305 if (slice.y + slice.height == img->height)
25306 it->descent += img->vmargin;
25307 it->phys_descent = it->descent;
25308
25309 it->pixel_width = slice.width;
25310 if (slice.x == 0)
25311 it->pixel_width += img->hmargin;
25312 if (slice.x + slice.width == img->width)
25313 it->pixel_width += img->hmargin;
25314
25315 /* It's quite possible for images to have an ascent greater than
25316 their height, so don't get confused in that case. */
25317 if (it->descent < 0)
25318 it->descent = 0;
25319
25320 it->nglyphs = 1;
25321
25322 if (face->box != FACE_NO_BOX)
25323 {
25324 if (face->box_line_width > 0)
25325 {
25326 if (slice.y == 0)
25327 it->ascent += face->box_line_width;
25328 if (slice.y + slice.height == img->height)
25329 it->descent += face->box_line_width;
25330 }
25331
25332 if (it->start_of_box_run_p && slice.x == 0)
25333 it->pixel_width += eabs (face->box_line_width);
25334 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
25335 it->pixel_width += eabs (face->box_line_width);
25336 }
25337
25338 take_vertical_position_into_account (it);
25339
25340 /* Automatically crop wide image glyphs at right edge so we can
25341 draw the cursor on same display row. */
25342 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
25343 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
25344 {
25345 it->pixel_width -= crop;
25346 slice.width -= crop;
25347 }
25348
25349 if (it->glyph_row)
25350 {
25351 struct glyph *glyph;
25352 enum glyph_row_area area = it->area;
25353
25354 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25355 if (glyph < it->glyph_row->glyphs[area + 1])
25356 {
25357 glyph->charpos = CHARPOS (it->position);
25358 glyph->object = it->object;
25359 glyph->pixel_width = it->pixel_width;
25360 glyph->ascent = glyph_ascent;
25361 glyph->descent = it->descent;
25362 glyph->voffset = it->voffset;
25363 glyph->type = IMAGE_GLYPH;
25364 glyph->avoid_cursor_p = it->avoid_cursor_p;
25365 glyph->multibyte_p = it->multibyte_p;
25366 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25367 {
25368 /* In R2L rows, the left and the right box edges need to be
25369 drawn in reverse direction. */
25370 glyph->right_box_line_p = it->start_of_box_run_p;
25371 glyph->left_box_line_p = it->end_of_box_run_p;
25372 }
25373 else
25374 {
25375 glyph->left_box_line_p = it->start_of_box_run_p;
25376 glyph->right_box_line_p = it->end_of_box_run_p;
25377 }
25378 glyph->overlaps_vertically_p = 0;
25379 glyph->padding_p = 0;
25380 glyph->glyph_not_available_p = 0;
25381 glyph->face_id = it->face_id;
25382 glyph->u.img_id = img->id;
25383 glyph->slice.img = slice;
25384 glyph->font_type = FONT_TYPE_UNKNOWN;
25385 if (it->bidi_p)
25386 {
25387 glyph->resolved_level = it->bidi_it.resolved_level;
25388 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25389 emacs_abort ();
25390 glyph->bidi_type = it->bidi_it.type;
25391 }
25392 ++it->glyph_row->used[area];
25393 }
25394 else
25395 IT_EXPAND_MATRIX_WIDTH (it, area);
25396 }
25397 }
25398
25399
25400 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
25401 of the glyph, WIDTH and HEIGHT are the width and height of the
25402 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
25403
25404 static void
25405 append_stretch_glyph (struct it *it, Lisp_Object object,
25406 int width, int height, int ascent)
25407 {
25408 struct glyph *glyph;
25409 enum glyph_row_area area = it->area;
25410
25411 eassert (ascent >= 0 && ascent <= height);
25412
25413 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25414 if (glyph < it->glyph_row->glyphs[area + 1])
25415 {
25416 /* If the glyph row is reversed, we need to prepend the glyph
25417 rather than append it. */
25418 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25419 {
25420 struct glyph *g;
25421
25422 /* Make room for the additional glyph. */
25423 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25424 g[1] = *g;
25425 glyph = it->glyph_row->glyphs[area];
25426
25427 /* Decrease the width of the first glyph of the row that
25428 begins before first_visible_x (e.g., due to hscroll).
25429 This is so the overall width of the row becomes smaller
25430 by the scroll amount, and the stretch glyph appended by
25431 extend_face_to_end_of_line will be wider, to shift the
25432 row glyphs to the right. (In L2R rows, the corresponding
25433 left-shift effect is accomplished by setting row->x to a
25434 negative value, which won't work with R2L rows.)
25435
25436 This must leave us with a positive value of WIDTH, since
25437 otherwise the call to move_it_in_display_line_to at the
25438 beginning of display_line would have got past the entire
25439 first glyph, and then it->current_x would have been
25440 greater or equal to it->first_visible_x. */
25441 if (it->current_x < it->first_visible_x)
25442 width -= it->first_visible_x - it->current_x;
25443 eassert (width > 0);
25444 }
25445 glyph->charpos = CHARPOS (it->position);
25446 glyph->object = object;
25447 glyph->pixel_width = width;
25448 glyph->ascent = ascent;
25449 glyph->descent = height - ascent;
25450 glyph->voffset = it->voffset;
25451 glyph->type = STRETCH_GLYPH;
25452 glyph->avoid_cursor_p = it->avoid_cursor_p;
25453 glyph->multibyte_p = it->multibyte_p;
25454 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25455 {
25456 /* In R2L rows, the left and the right box edges need to be
25457 drawn in reverse direction. */
25458 glyph->right_box_line_p = it->start_of_box_run_p;
25459 glyph->left_box_line_p = it->end_of_box_run_p;
25460 }
25461 else
25462 {
25463 glyph->left_box_line_p = it->start_of_box_run_p;
25464 glyph->right_box_line_p = it->end_of_box_run_p;
25465 }
25466 glyph->overlaps_vertically_p = 0;
25467 glyph->padding_p = 0;
25468 glyph->glyph_not_available_p = 0;
25469 glyph->face_id = it->face_id;
25470 glyph->u.stretch.ascent = ascent;
25471 glyph->u.stretch.height = height;
25472 glyph->slice.img = null_glyph_slice;
25473 glyph->font_type = FONT_TYPE_UNKNOWN;
25474 if (it->bidi_p)
25475 {
25476 glyph->resolved_level = it->bidi_it.resolved_level;
25477 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25478 emacs_abort ();
25479 glyph->bidi_type = it->bidi_it.type;
25480 }
25481 else
25482 {
25483 glyph->resolved_level = 0;
25484 glyph->bidi_type = UNKNOWN_BT;
25485 }
25486 ++it->glyph_row->used[area];
25487 }
25488 else
25489 IT_EXPAND_MATRIX_WIDTH (it, area);
25490 }
25491
25492 #endif /* HAVE_WINDOW_SYSTEM */
25493
25494 /* Produce a stretch glyph for iterator IT. IT->object is the value
25495 of the glyph property displayed. The value must be a list
25496 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
25497 being recognized:
25498
25499 1. `:width WIDTH' specifies that the space should be WIDTH *
25500 canonical char width wide. WIDTH may be an integer or floating
25501 point number.
25502
25503 2. `:relative-width FACTOR' specifies that the width of the stretch
25504 should be computed from the width of the first character having the
25505 `glyph' property, and should be FACTOR times that width.
25506
25507 3. `:align-to HPOS' specifies that the space should be wide enough
25508 to reach HPOS, a value in canonical character units.
25509
25510 Exactly one of the above pairs must be present.
25511
25512 4. `:height HEIGHT' specifies that the height of the stretch produced
25513 should be HEIGHT, measured in canonical character units.
25514
25515 5. `:relative-height FACTOR' specifies that the height of the
25516 stretch should be FACTOR times the height of the characters having
25517 the glyph property.
25518
25519 Either none or exactly one of 4 or 5 must be present.
25520
25521 6. `:ascent ASCENT' specifies that ASCENT percent of the height
25522 of the stretch should be used for the ascent of the stretch.
25523 ASCENT must be in the range 0 <= ASCENT <= 100. */
25524
25525 void
25526 produce_stretch_glyph (struct it *it)
25527 {
25528 /* (space :width WIDTH :height HEIGHT ...) */
25529 Lisp_Object prop, plist;
25530 int width = 0, height = 0, align_to = -1;
25531 int zero_width_ok_p = 0;
25532 double tem;
25533 struct font *font = NULL;
25534
25535 #ifdef HAVE_WINDOW_SYSTEM
25536 int ascent = 0;
25537 int zero_height_ok_p = 0;
25538
25539 if (FRAME_WINDOW_P (it->f))
25540 {
25541 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25542 font = face->font ? face->font : FRAME_FONT (it->f);
25543 prepare_face_for_display (it->f, face);
25544 }
25545 #endif
25546
25547 /* List should start with `space'. */
25548 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
25549 plist = XCDR (it->object);
25550
25551 /* Compute the width of the stretch. */
25552 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
25553 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
25554 {
25555 /* Absolute width `:width WIDTH' specified and valid. */
25556 zero_width_ok_p = 1;
25557 width = (int)tem;
25558 }
25559 #ifdef HAVE_WINDOW_SYSTEM
25560 else if (FRAME_WINDOW_P (it->f)
25561 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
25562 {
25563 /* Relative width `:relative-width FACTOR' specified and valid.
25564 Compute the width of the characters having the `glyph'
25565 property. */
25566 struct it it2;
25567 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
25568
25569 it2 = *it;
25570 if (it->multibyte_p)
25571 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
25572 else
25573 {
25574 it2.c = it2.char_to_display = *p, it2.len = 1;
25575 if (! ASCII_CHAR_P (it2.c))
25576 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
25577 }
25578
25579 it2.glyph_row = NULL;
25580 it2.what = IT_CHARACTER;
25581 x_produce_glyphs (&it2);
25582 width = NUMVAL (prop) * it2.pixel_width;
25583 }
25584 #endif /* HAVE_WINDOW_SYSTEM */
25585 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
25586 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
25587 {
25588 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
25589 align_to = (align_to < 0
25590 ? 0
25591 : align_to - window_box_left_offset (it->w, TEXT_AREA));
25592 else if (align_to < 0)
25593 align_to = window_box_left_offset (it->w, TEXT_AREA);
25594 width = max (0, (int)tem + align_to - it->current_x);
25595 zero_width_ok_p = 1;
25596 }
25597 else
25598 /* Nothing specified -> width defaults to canonical char width. */
25599 width = FRAME_COLUMN_WIDTH (it->f);
25600
25601 if (width <= 0 && (width < 0 || !zero_width_ok_p))
25602 width = 1;
25603
25604 #ifdef HAVE_WINDOW_SYSTEM
25605 /* Compute height. */
25606 if (FRAME_WINDOW_P (it->f))
25607 {
25608 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
25609 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
25610 {
25611 height = (int)tem;
25612 zero_height_ok_p = 1;
25613 }
25614 else if (prop = Fplist_get (plist, QCrelative_height),
25615 NUMVAL (prop) > 0)
25616 height = FONT_HEIGHT (font) * NUMVAL (prop);
25617 else
25618 height = FONT_HEIGHT (font);
25619
25620 if (height <= 0 && (height < 0 || !zero_height_ok_p))
25621 height = 1;
25622
25623 /* Compute percentage of height used for ascent. If
25624 `:ascent ASCENT' is present and valid, use that. Otherwise,
25625 derive the ascent from the font in use. */
25626 if (prop = Fplist_get (plist, QCascent),
25627 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
25628 ascent = height * NUMVAL (prop) / 100.0;
25629 else if (!NILP (prop)
25630 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
25631 ascent = min (max (0, (int)tem), height);
25632 else
25633 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
25634 }
25635 else
25636 #endif /* HAVE_WINDOW_SYSTEM */
25637 height = 1;
25638
25639 if (width > 0 && it->line_wrap != TRUNCATE
25640 && it->current_x + width > it->last_visible_x)
25641 {
25642 width = it->last_visible_x - it->current_x;
25643 #ifdef HAVE_WINDOW_SYSTEM
25644 /* Subtract one more pixel from the stretch width, but only on
25645 GUI frames, since on a TTY each glyph is one "pixel" wide. */
25646 width -= FRAME_WINDOW_P (it->f);
25647 #endif
25648 }
25649
25650 if (width > 0 && height > 0 && it->glyph_row)
25651 {
25652 Lisp_Object o_object = it->object;
25653 Lisp_Object object = it->stack[it->sp - 1].string;
25654 int n = width;
25655
25656 if (!STRINGP (object))
25657 object = it->w->contents;
25658 #ifdef HAVE_WINDOW_SYSTEM
25659 if (FRAME_WINDOW_P (it->f))
25660 append_stretch_glyph (it, object, width, height, ascent);
25661 else
25662 #endif
25663 {
25664 it->object = object;
25665 it->char_to_display = ' ';
25666 it->pixel_width = it->len = 1;
25667 while (n--)
25668 tty_append_glyph (it);
25669 it->object = o_object;
25670 }
25671 }
25672
25673 it->pixel_width = width;
25674 #ifdef HAVE_WINDOW_SYSTEM
25675 if (FRAME_WINDOW_P (it->f))
25676 {
25677 it->ascent = it->phys_ascent = ascent;
25678 it->descent = it->phys_descent = height - it->ascent;
25679 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
25680 take_vertical_position_into_account (it);
25681 }
25682 else
25683 #endif
25684 it->nglyphs = width;
25685 }
25686
25687 /* Get information about special display element WHAT in an
25688 environment described by IT. WHAT is one of IT_TRUNCATION or
25689 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
25690 non-null glyph_row member. This function ensures that fields like
25691 face_id, c, len of IT are left untouched. */
25692
25693 static void
25694 produce_special_glyphs (struct it *it, enum display_element_type what)
25695 {
25696 struct it temp_it;
25697 Lisp_Object gc;
25698 GLYPH glyph;
25699
25700 temp_it = *it;
25701 temp_it.object = make_number (0);
25702 memset (&temp_it.current, 0, sizeof temp_it.current);
25703
25704 if (what == IT_CONTINUATION)
25705 {
25706 /* Continuation glyph. For R2L lines, we mirror it by hand. */
25707 if (it->bidi_it.paragraph_dir == R2L)
25708 SET_GLYPH_FROM_CHAR (glyph, '/');
25709 else
25710 SET_GLYPH_FROM_CHAR (glyph, '\\');
25711 if (it->dp
25712 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
25713 {
25714 /* FIXME: Should we mirror GC for R2L lines? */
25715 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
25716 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
25717 }
25718 }
25719 else if (what == IT_TRUNCATION)
25720 {
25721 /* Truncation glyph. */
25722 SET_GLYPH_FROM_CHAR (glyph, '$');
25723 if (it->dp
25724 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
25725 {
25726 /* FIXME: Should we mirror GC for R2L lines? */
25727 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
25728 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
25729 }
25730 }
25731 else
25732 emacs_abort ();
25733
25734 #ifdef HAVE_WINDOW_SYSTEM
25735 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
25736 is turned off, we precede the truncation/continuation glyphs by a
25737 stretch glyph whose width is computed such that these special
25738 glyphs are aligned at the window margin, even when very different
25739 fonts are used in different glyph rows. */
25740 if (FRAME_WINDOW_P (temp_it.f)
25741 /* init_iterator calls this with it->glyph_row == NULL, and it
25742 wants only the pixel width of the truncation/continuation
25743 glyphs. */
25744 && temp_it.glyph_row
25745 /* insert_left_trunc_glyphs calls us at the beginning of the
25746 row, and it has its own calculation of the stretch glyph
25747 width. */
25748 && temp_it.glyph_row->used[TEXT_AREA] > 0
25749 && (temp_it.glyph_row->reversed_p
25750 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
25751 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
25752 {
25753 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
25754
25755 if (stretch_width > 0)
25756 {
25757 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
25758 struct font *font =
25759 face->font ? face->font : FRAME_FONT (temp_it.f);
25760 int stretch_ascent =
25761 (((temp_it.ascent + temp_it.descent)
25762 * FONT_BASE (font)) / FONT_HEIGHT (font));
25763
25764 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
25765 temp_it.ascent + temp_it.descent,
25766 stretch_ascent);
25767 }
25768 }
25769 #endif
25770
25771 temp_it.dp = NULL;
25772 temp_it.what = IT_CHARACTER;
25773 temp_it.len = 1;
25774 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
25775 temp_it.face_id = GLYPH_FACE (glyph);
25776 temp_it.len = CHAR_BYTES (temp_it.c);
25777
25778 PRODUCE_GLYPHS (&temp_it);
25779 it->pixel_width = temp_it.pixel_width;
25780 it->nglyphs = temp_it.pixel_width;
25781 }
25782
25783 #ifdef HAVE_WINDOW_SYSTEM
25784
25785 /* Calculate line-height and line-spacing properties.
25786 An integer value specifies explicit pixel value.
25787 A float value specifies relative value to current face height.
25788 A cons (float . face-name) specifies relative value to
25789 height of specified face font.
25790
25791 Returns height in pixels, or nil. */
25792
25793
25794 static Lisp_Object
25795 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
25796 int boff, int override)
25797 {
25798 Lisp_Object face_name = Qnil;
25799 int ascent, descent, height;
25800
25801 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
25802 return val;
25803
25804 if (CONSP (val))
25805 {
25806 face_name = XCAR (val);
25807 val = XCDR (val);
25808 if (!NUMBERP (val))
25809 val = make_number (1);
25810 if (NILP (face_name))
25811 {
25812 height = it->ascent + it->descent;
25813 goto scale;
25814 }
25815 }
25816
25817 if (NILP (face_name))
25818 {
25819 font = FRAME_FONT (it->f);
25820 boff = FRAME_BASELINE_OFFSET (it->f);
25821 }
25822 else if (EQ (face_name, Qt))
25823 {
25824 override = 0;
25825 }
25826 else
25827 {
25828 int face_id;
25829 struct face *face;
25830
25831 face_id = lookup_named_face (it->f, face_name, 0);
25832 if (face_id < 0)
25833 return make_number (-1);
25834
25835 face = FACE_FROM_ID (it->f, face_id);
25836 font = face->font;
25837 if (font == NULL)
25838 return make_number (-1);
25839 boff = font->baseline_offset;
25840 if (font->vertical_centering)
25841 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25842 }
25843
25844 ascent = FONT_BASE (font) + boff;
25845 descent = FONT_DESCENT (font) - boff;
25846
25847 if (override)
25848 {
25849 it->override_ascent = ascent;
25850 it->override_descent = descent;
25851 it->override_boff = boff;
25852 }
25853
25854 height = ascent + descent;
25855
25856 scale:
25857 if (FLOATP (val))
25858 height = (int)(XFLOAT_DATA (val) * height);
25859 else if (INTEGERP (val))
25860 height *= XINT (val);
25861
25862 return make_number (height);
25863 }
25864
25865
25866 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
25867 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
25868 and only if this is for a character for which no font was found.
25869
25870 If the display method (it->glyphless_method) is
25871 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
25872 length of the acronym or the hexadecimal string, UPPER_XOFF and
25873 UPPER_YOFF are pixel offsets for the upper part of the string,
25874 LOWER_XOFF and LOWER_YOFF are for the lower part.
25875
25876 For the other display methods, LEN through LOWER_YOFF are zero. */
25877
25878 static void
25879 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
25880 short upper_xoff, short upper_yoff,
25881 short lower_xoff, short lower_yoff)
25882 {
25883 struct glyph *glyph;
25884 enum glyph_row_area area = it->area;
25885
25886 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25887 if (glyph < it->glyph_row->glyphs[area + 1])
25888 {
25889 /* If the glyph row is reversed, we need to prepend the glyph
25890 rather than append it. */
25891 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25892 {
25893 struct glyph *g;
25894
25895 /* Make room for the additional glyph. */
25896 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25897 g[1] = *g;
25898 glyph = it->glyph_row->glyphs[area];
25899 }
25900 glyph->charpos = CHARPOS (it->position);
25901 glyph->object = it->object;
25902 glyph->pixel_width = it->pixel_width;
25903 glyph->ascent = it->ascent;
25904 glyph->descent = it->descent;
25905 glyph->voffset = it->voffset;
25906 glyph->type = GLYPHLESS_GLYPH;
25907 glyph->u.glyphless.method = it->glyphless_method;
25908 glyph->u.glyphless.for_no_font = for_no_font;
25909 glyph->u.glyphless.len = len;
25910 glyph->u.glyphless.ch = it->c;
25911 glyph->slice.glyphless.upper_xoff = upper_xoff;
25912 glyph->slice.glyphless.upper_yoff = upper_yoff;
25913 glyph->slice.glyphless.lower_xoff = lower_xoff;
25914 glyph->slice.glyphless.lower_yoff = lower_yoff;
25915 glyph->avoid_cursor_p = it->avoid_cursor_p;
25916 glyph->multibyte_p = it->multibyte_p;
25917 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25918 {
25919 /* In R2L rows, the left and the right box edges need to be
25920 drawn in reverse direction. */
25921 glyph->right_box_line_p = it->start_of_box_run_p;
25922 glyph->left_box_line_p = it->end_of_box_run_p;
25923 }
25924 else
25925 {
25926 glyph->left_box_line_p = it->start_of_box_run_p;
25927 glyph->right_box_line_p = it->end_of_box_run_p;
25928 }
25929 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25930 || it->phys_descent > it->descent);
25931 glyph->padding_p = 0;
25932 glyph->glyph_not_available_p = 0;
25933 glyph->face_id = face_id;
25934 glyph->font_type = FONT_TYPE_UNKNOWN;
25935 if (it->bidi_p)
25936 {
25937 glyph->resolved_level = it->bidi_it.resolved_level;
25938 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25939 emacs_abort ();
25940 glyph->bidi_type = it->bidi_it.type;
25941 }
25942 ++it->glyph_row->used[area];
25943 }
25944 else
25945 IT_EXPAND_MATRIX_WIDTH (it, area);
25946 }
25947
25948
25949 /* Produce a glyph for a glyphless character for iterator IT.
25950 IT->glyphless_method specifies which method to use for displaying
25951 the character. See the description of enum
25952 glyphless_display_method in dispextern.h for the detail.
25953
25954 FOR_NO_FONT is nonzero if and only if this is for a character for
25955 which no font was found. ACRONYM, if non-nil, is an acronym string
25956 for the character. */
25957
25958 static void
25959 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
25960 {
25961 int face_id;
25962 struct face *face;
25963 struct font *font;
25964 int base_width, base_height, width, height;
25965 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
25966 int len;
25967
25968 /* Get the metrics of the base font. We always refer to the current
25969 ASCII face. */
25970 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
25971 font = face->font ? face->font : FRAME_FONT (it->f);
25972 it->ascent = FONT_BASE (font) + font->baseline_offset;
25973 it->descent = FONT_DESCENT (font) - font->baseline_offset;
25974 base_height = it->ascent + it->descent;
25975 base_width = font->average_width;
25976
25977 face_id = merge_glyphless_glyph_face (it);
25978
25979 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
25980 {
25981 it->pixel_width = THIN_SPACE_WIDTH;
25982 len = 0;
25983 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
25984 }
25985 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
25986 {
25987 width = CHAR_WIDTH (it->c);
25988 if (width == 0)
25989 width = 1;
25990 else if (width > 4)
25991 width = 4;
25992 it->pixel_width = base_width * width;
25993 len = 0;
25994 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
25995 }
25996 else
25997 {
25998 char buf[7];
25999 const char *str;
26000 unsigned int code[6];
26001 int upper_len;
26002 int ascent, descent;
26003 struct font_metrics metrics_upper, metrics_lower;
26004
26005 face = FACE_FROM_ID (it->f, face_id);
26006 font = face->font ? face->font : FRAME_FONT (it->f);
26007 prepare_face_for_display (it->f, face);
26008
26009 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
26010 {
26011 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
26012 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
26013 if (CONSP (acronym))
26014 acronym = XCAR (acronym);
26015 str = STRINGP (acronym) ? SSDATA (acronym) : "";
26016 }
26017 else
26018 {
26019 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
26020 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
26021 str = buf;
26022 }
26023 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
26024 code[len] = font->driver->encode_char (font, str[len]);
26025 upper_len = (len + 1) / 2;
26026 font->driver->text_extents (font, code, upper_len,
26027 &metrics_upper);
26028 font->driver->text_extents (font, code + upper_len, len - upper_len,
26029 &metrics_lower);
26030
26031
26032
26033 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
26034 width = max (metrics_upper.width, metrics_lower.width) + 4;
26035 upper_xoff = upper_yoff = 2; /* the typical case */
26036 if (base_width >= width)
26037 {
26038 /* Align the upper to the left, the lower to the right. */
26039 it->pixel_width = base_width;
26040 lower_xoff = base_width - 2 - metrics_lower.width;
26041 }
26042 else
26043 {
26044 /* Center the shorter one. */
26045 it->pixel_width = width;
26046 if (metrics_upper.width >= metrics_lower.width)
26047 lower_xoff = (width - metrics_lower.width) / 2;
26048 else
26049 {
26050 /* FIXME: This code doesn't look right. It formerly was
26051 missing the "lower_xoff = 0;", which couldn't have
26052 been right since it left lower_xoff uninitialized. */
26053 lower_xoff = 0;
26054 upper_xoff = (width - metrics_upper.width) / 2;
26055 }
26056 }
26057
26058 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
26059 top, bottom, and between upper and lower strings. */
26060 height = (metrics_upper.ascent + metrics_upper.descent
26061 + metrics_lower.ascent + metrics_lower.descent) + 5;
26062 /* Center vertically.
26063 H:base_height, D:base_descent
26064 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
26065
26066 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
26067 descent = D - H/2 + h/2;
26068 lower_yoff = descent - 2 - ld;
26069 upper_yoff = lower_yoff - la - 1 - ud; */
26070 ascent = - (it->descent - (base_height + height + 1) / 2);
26071 descent = it->descent - (base_height - height) / 2;
26072 lower_yoff = descent - 2 - metrics_lower.descent;
26073 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
26074 - metrics_upper.descent);
26075 /* Don't make the height shorter than the base height. */
26076 if (height > base_height)
26077 {
26078 it->ascent = ascent;
26079 it->descent = descent;
26080 }
26081 }
26082
26083 it->phys_ascent = it->ascent;
26084 it->phys_descent = it->descent;
26085 if (it->glyph_row)
26086 append_glyphless_glyph (it, face_id, for_no_font, len,
26087 upper_xoff, upper_yoff,
26088 lower_xoff, lower_yoff);
26089 it->nglyphs = 1;
26090 take_vertical_position_into_account (it);
26091 }
26092
26093
26094 /* RIF:
26095 Produce glyphs/get display metrics for the display element IT is
26096 loaded with. See the description of struct it in dispextern.h
26097 for an overview of struct it. */
26098
26099 void
26100 x_produce_glyphs (struct it *it)
26101 {
26102 int extra_line_spacing = it->extra_line_spacing;
26103
26104 it->glyph_not_available_p = 0;
26105
26106 if (it->what == IT_CHARACTER)
26107 {
26108 XChar2b char2b;
26109 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26110 struct font *font = face->font;
26111 struct font_metrics *pcm = NULL;
26112 int boff; /* Baseline offset. */
26113
26114 if (font == NULL)
26115 {
26116 /* When no suitable font is found, display this character by
26117 the method specified in the first extra slot of
26118 Vglyphless_char_display. */
26119 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
26120
26121 eassert (it->what == IT_GLYPHLESS);
26122 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
26123 goto done;
26124 }
26125
26126 boff = font->baseline_offset;
26127 if (font->vertical_centering)
26128 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26129
26130 if (it->char_to_display != '\n' && it->char_to_display != '\t')
26131 {
26132 int stretched_p;
26133
26134 it->nglyphs = 1;
26135
26136 if (it->override_ascent >= 0)
26137 {
26138 it->ascent = it->override_ascent;
26139 it->descent = it->override_descent;
26140 boff = it->override_boff;
26141 }
26142 else
26143 {
26144 it->ascent = FONT_BASE (font) + boff;
26145 it->descent = FONT_DESCENT (font) - boff;
26146 }
26147
26148 if (get_char_glyph_code (it->char_to_display, font, &char2b))
26149 {
26150 pcm = get_per_char_metric (font, &char2b);
26151 if (pcm->width == 0
26152 && pcm->rbearing == 0 && pcm->lbearing == 0)
26153 pcm = NULL;
26154 }
26155
26156 if (pcm)
26157 {
26158 it->phys_ascent = pcm->ascent + boff;
26159 it->phys_descent = pcm->descent - boff;
26160 it->pixel_width = pcm->width;
26161 }
26162 else
26163 {
26164 it->glyph_not_available_p = 1;
26165 it->phys_ascent = it->ascent;
26166 it->phys_descent = it->descent;
26167 it->pixel_width = font->space_width;
26168 }
26169
26170 if (it->constrain_row_ascent_descent_p)
26171 {
26172 if (it->descent > it->max_descent)
26173 {
26174 it->ascent += it->descent - it->max_descent;
26175 it->descent = it->max_descent;
26176 }
26177 if (it->ascent > it->max_ascent)
26178 {
26179 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26180 it->ascent = it->max_ascent;
26181 }
26182 it->phys_ascent = min (it->phys_ascent, it->ascent);
26183 it->phys_descent = min (it->phys_descent, it->descent);
26184 extra_line_spacing = 0;
26185 }
26186
26187 /* If this is a space inside a region of text with
26188 `space-width' property, change its width. */
26189 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
26190 if (stretched_p)
26191 it->pixel_width *= XFLOATINT (it->space_width);
26192
26193 /* If face has a box, add the box thickness to the character
26194 height. If character has a box line to the left and/or
26195 right, add the box line width to the character's width. */
26196 if (face->box != FACE_NO_BOX)
26197 {
26198 int thick = face->box_line_width;
26199
26200 if (thick > 0)
26201 {
26202 it->ascent += thick;
26203 it->descent += thick;
26204 }
26205 else
26206 thick = -thick;
26207
26208 if (it->start_of_box_run_p)
26209 it->pixel_width += thick;
26210 if (it->end_of_box_run_p)
26211 it->pixel_width += thick;
26212 }
26213
26214 /* If face has an overline, add the height of the overline
26215 (1 pixel) and a 1 pixel margin to the character height. */
26216 if (face->overline_p)
26217 it->ascent += overline_margin;
26218
26219 if (it->constrain_row_ascent_descent_p)
26220 {
26221 if (it->ascent > it->max_ascent)
26222 it->ascent = it->max_ascent;
26223 if (it->descent > it->max_descent)
26224 it->descent = it->max_descent;
26225 }
26226
26227 take_vertical_position_into_account (it);
26228
26229 /* If we have to actually produce glyphs, do it. */
26230 if (it->glyph_row)
26231 {
26232 if (stretched_p)
26233 {
26234 /* Translate a space with a `space-width' property
26235 into a stretch glyph. */
26236 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
26237 / FONT_HEIGHT (font));
26238 append_stretch_glyph (it, it->object, it->pixel_width,
26239 it->ascent + it->descent, ascent);
26240 }
26241 else
26242 append_glyph (it);
26243
26244 /* If characters with lbearing or rbearing are displayed
26245 in this line, record that fact in a flag of the
26246 glyph row. This is used to optimize X output code. */
26247 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
26248 it->glyph_row->contains_overlapping_glyphs_p = 1;
26249 }
26250 if (! stretched_p && it->pixel_width == 0)
26251 /* We assure that all visible glyphs have at least 1-pixel
26252 width. */
26253 it->pixel_width = 1;
26254 }
26255 else if (it->char_to_display == '\n')
26256 {
26257 /* A newline has no width, but we need the height of the
26258 line. But if previous part of the line sets a height,
26259 don't increase that height. */
26260
26261 Lisp_Object height;
26262 Lisp_Object total_height = Qnil;
26263
26264 it->override_ascent = -1;
26265 it->pixel_width = 0;
26266 it->nglyphs = 0;
26267
26268 height = get_it_property (it, Qline_height);
26269 /* Split (line-height total-height) list. */
26270 if (CONSP (height)
26271 && CONSP (XCDR (height))
26272 && NILP (XCDR (XCDR (height))))
26273 {
26274 total_height = XCAR (XCDR (height));
26275 height = XCAR (height);
26276 }
26277 height = calc_line_height_property (it, height, font, boff, 1);
26278
26279 if (it->override_ascent >= 0)
26280 {
26281 it->ascent = it->override_ascent;
26282 it->descent = it->override_descent;
26283 boff = it->override_boff;
26284 }
26285 else
26286 {
26287 it->ascent = FONT_BASE (font) + boff;
26288 it->descent = FONT_DESCENT (font) - boff;
26289 }
26290
26291 if (EQ (height, Qt))
26292 {
26293 if (it->descent > it->max_descent)
26294 {
26295 it->ascent += it->descent - it->max_descent;
26296 it->descent = it->max_descent;
26297 }
26298 if (it->ascent > it->max_ascent)
26299 {
26300 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26301 it->ascent = it->max_ascent;
26302 }
26303 it->phys_ascent = min (it->phys_ascent, it->ascent);
26304 it->phys_descent = min (it->phys_descent, it->descent);
26305 it->constrain_row_ascent_descent_p = 1;
26306 extra_line_spacing = 0;
26307 }
26308 else
26309 {
26310 Lisp_Object spacing;
26311
26312 it->phys_ascent = it->ascent;
26313 it->phys_descent = it->descent;
26314
26315 if ((it->max_ascent > 0 || it->max_descent > 0)
26316 && face->box != FACE_NO_BOX
26317 && face->box_line_width > 0)
26318 {
26319 it->ascent += face->box_line_width;
26320 it->descent += face->box_line_width;
26321 }
26322 if (!NILP (height)
26323 && XINT (height) > it->ascent + it->descent)
26324 it->ascent = XINT (height) - it->descent;
26325
26326 if (!NILP (total_height))
26327 spacing = calc_line_height_property (it, total_height, font, boff, 0);
26328 else
26329 {
26330 spacing = get_it_property (it, Qline_spacing);
26331 spacing = calc_line_height_property (it, spacing, font, boff, 0);
26332 }
26333 if (INTEGERP (spacing))
26334 {
26335 extra_line_spacing = XINT (spacing);
26336 if (!NILP (total_height))
26337 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
26338 }
26339 }
26340 }
26341 else /* i.e. (it->char_to_display == '\t') */
26342 {
26343 if (font->space_width > 0)
26344 {
26345 int tab_width = it->tab_width * font->space_width;
26346 int x = it->current_x + it->continuation_lines_width;
26347 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
26348
26349 /* If the distance from the current position to the next tab
26350 stop is less than a space character width, use the
26351 tab stop after that. */
26352 if (next_tab_x - x < font->space_width)
26353 next_tab_x += tab_width;
26354
26355 it->pixel_width = next_tab_x - x;
26356 it->nglyphs = 1;
26357 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
26358 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
26359
26360 if (it->glyph_row)
26361 {
26362 append_stretch_glyph (it, it->object, it->pixel_width,
26363 it->ascent + it->descent, it->ascent);
26364 }
26365 }
26366 else
26367 {
26368 it->pixel_width = 0;
26369 it->nglyphs = 1;
26370 }
26371 }
26372 }
26373 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
26374 {
26375 /* A static composition.
26376
26377 Note: A composition is represented as one glyph in the
26378 glyph matrix. There are no padding glyphs.
26379
26380 Important note: pixel_width, ascent, and descent are the
26381 values of what is drawn by draw_glyphs (i.e. the values of
26382 the overall glyphs composed). */
26383 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26384 int boff; /* baseline offset */
26385 struct composition *cmp = composition_table[it->cmp_it.id];
26386 int glyph_len = cmp->glyph_len;
26387 struct font *font = face->font;
26388
26389 it->nglyphs = 1;
26390
26391 /* If we have not yet calculated pixel size data of glyphs of
26392 the composition for the current face font, calculate them
26393 now. Theoretically, we have to check all fonts for the
26394 glyphs, but that requires much time and memory space. So,
26395 here we check only the font of the first glyph. This may
26396 lead to incorrect display, but it's very rare, and C-l
26397 (recenter-top-bottom) can correct the display anyway. */
26398 if (! cmp->font || cmp->font != font)
26399 {
26400 /* Ascent and descent of the font of the first character
26401 of this composition (adjusted by baseline offset).
26402 Ascent and descent of overall glyphs should not be less
26403 than these, respectively. */
26404 int font_ascent, font_descent, font_height;
26405 /* Bounding box of the overall glyphs. */
26406 int leftmost, rightmost, lowest, highest;
26407 int lbearing, rbearing;
26408 int i, width, ascent, descent;
26409 int left_padded = 0, right_padded = 0;
26410 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
26411 XChar2b char2b;
26412 struct font_metrics *pcm;
26413 int font_not_found_p;
26414 ptrdiff_t pos;
26415
26416 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
26417 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
26418 break;
26419 if (glyph_len < cmp->glyph_len)
26420 right_padded = 1;
26421 for (i = 0; i < glyph_len; i++)
26422 {
26423 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
26424 break;
26425 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
26426 }
26427 if (i > 0)
26428 left_padded = 1;
26429
26430 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
26431 : IT_CHARPOS (*it));
26432 /* If no suitable font is found, use the default font. */
26433 font_not_found_p = font == NULL;
26434 if (font_not_found_p)
26435 {
26436 face = face->ascii_face;
26437 font = face->font;
26438 }
26439 boff = font->baseline_offset;
26440 if (font->vertical_centering)
26441 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26442 font_ascent = FONT_BASE (font) + boff;
26443 font_descent = FONT_DESCENT (font) - boff;
26444 font_height = FONT_HEIGHT (font);
26445
26446 cmp->font = font;
26447
26448 pcm = NULL;
26449 if (! font_not_found_p)
26450 {
26451 get_char_face_and_encoding (it->f, c, it->face_id,
26452 &char2b, 0);
26453 pcm = get_per_char_metric (font, &char2b);
26454 }
26455
26456 /* Initialize the bounding box. */
26457 if (pcm)
26458 {
26459 width = cmp->glyph_len > 0 ? pcm->width : 0;
26460 ascent = pcm->ascent;
26461 descent = pcm->descent;
26462 lbearing = pcm->lbearing;
26463 rbearing = pcm->rbearing;
26464 }
26465 else
26466 {
26467 width = cmp->glyph_len > 0 ? font->space_width : 0;
26468 ascent = FONT_BASE (font);
26469 descent = FONT_DESCENT (font);
26470 lbearing = 0;
26471 rbearing = width;
26472 }
26473
26474 rightmost = width;
26475 leftmost = 0;
26476 lowest = - descent + boff;
26477 highest = ascent + boff;
26478
26479 if (! font_not_found_p
26480 && font->default_ascent
26481 && CHAR_TABLE_P (Vuse_default_ascent)
26482 && !NILP (Faref (Vuse_default_ascent,
26483 make_number (it->char_to_display))))
26484 highest = font->default_ascent + boff;
26485
26486 /* Draw the first glyph at the normal position. It may be
26487 shifted to right later if some other glyphs are drawn
26488 at the left. */
26489 cmp->offsets[i * 2] = 0;
26490 cmp->offsets[i * 2 + 1] = boff;
26491 cmp->lbearing = lbearing;
26492 cmp->rbearing = rbearing;
26493
26494 /* Set cmp->offsets for the remaining glyphs. */
26495 for (i++; i < glyph_len; i++)
26496 {
26497 int left, right, btm, top;
26498 int ch = COMPOSITION_GLYPH (cmp, i);
26499 int face_id;
26500 struct face *this_face;
26501
26502 if (ch == '\t')
26503 ch = ' ';
26504 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
26505 this_face = FACE_FROM_ID (it->f, face_id);
26506 font = this_face->font;
26507
26508 if (font == NULL)
26509 pcm = NULL;
26510 else
26511 {
26512 get_char_face_and_encoding (it->f, ch, face_id,
26513 &char2b, 0);
26514 pcm = get_per_char_metric (font, &char2b);
26515 }
26516 if (! pcm)
26517 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
26518 else
26519 {
26520 width = pcm->width;
26521 ascent = pcm->ascent;
26522 descent = pcm->descent;
26523 lbearing = pcm->lbearing;
26524 rbearing = pcm->rbearing;
26525 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
26526 {
26527 /* Relative composition with or without
26528 alternate chars. */
26529 left = (leftmost + rightmost - width) / 2;
26530 btm = - descent + boff;
26531 if (font->relative_compose
26532 && (! CHAR_TABLE_P (Vignore_relative_composition)
26533 || NILP (Faref (Vignore_relative_composition,
26534 make_number (ch)))))
26535 {
26536
26537 if (- descent >= font->relative_compose)
26538 /* One extra pixel between two glyphs. */
26539 btm = highest + 1;
26540 else if (ascent <= 0)
26541 /* One extra pixel between two glyphs. */
26542 btm = lowest - 1 - ascent - descent;
26543 }
26544 }
26545 else
26546 {
26547 /* A composition rule is specified by an integer
26548 value that encodes global and new reference
26549 points (GREF and NREF). GREF and NREF are
26550 specified by numbers as below:
26551
26552 0---1---2 -- ascent
26553 | |
26554 | |
26555 | |
26556 9--10--11 -- center
26557 | |
26558 ---3---4---5--- baseline
26559 | |
26560 6---7---8 -- descent
26561 */
26562 int rule = COMPOSITION_RULE (cmp, i);
26563 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
26564
26565 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
26566 grefx = gref % 3, nrefx = nref % 3;
26567 grefy = gref / 3, nrefy = nref / 3;
26568 if (xoff)
26569 xoff = font_height * (xoff - 128) / 256;
26570 if (yoff)
26571 yoff = font_height * (yoff - 128) / 256;
26572
26573 left = (leftmost
26574 + grefx * (rightmost - leftmost) / 2
26575 - nrefx * width / 2
26576 + xoff);
26577
26578 btm = ((grefy == 0 ? highest
26579 : grefy == 1 ? 0
26580 : grefy == 2 ? lowest
26581 : (highest + lowest) / 2)
26582 - (nrefy == 0 ? ascent + descent
26583 : nrefy == 1 ? descent - boff
26584 : nrefy == 2 ? 0
26585 : (ascent + descent) / 2)
26586 + yoff);
26587 }
26588
26589 cmp->offsets[i * 2] = left;
26590 cmp->offsets[i * 2 + 1] = btm + descent;
26591
26592 /* Update the bounding box of the overall glyphs. */
26593 if (width > 0)
26594 {
26595 right = left + width;
26596 if (left < leftmost)
26597 leftmost = left;
26598 if (right > rightmost)
26599 rightmost = right;
26600 }
26601 top = btm + descent + ascent;
26602 if (top > highest)
26603 highest = top;
26604 if (btm < lowest)
26605 lowest = btm;
26606
26607 if (cmp->lbearing > left + lbearing)
26608 cmp->lbearing = left + lbearing;
26609 if (cmp->rbearing < left + rbearing)
26610 cmp->rbearing = left + rbearing;
26611 }
26612 }
26613
26614 /* If there are glyphs whose x-offsets are negative,
26615 shift all glyphs to the right and make all x-offsets
26616 non-negative. */
26617 if (leftmost < 0)
26618 {
26619 for (i = 0; i < cmp->glyph_len; i++)
26620 cmp->offsets[i * 2] -= leftmost;
26621 rightmost -= leftmost;
26622 cmp->lbearing -= leftmost;
26623 cmp->rbearing -= leftmost;
26624 }
26625
26626 if (left_padded && cmp->lbearing < 0)
26627 {
26628 for (i = 0; i < cmp->glyph_len; i++)
26629 cmp->offsets[i * 2] -= cmp->lbearing;
26630 rightmost -= cmp->lbearing;
26631 cmp->rbearing -= cmp->lbearing;
26632 cmp->lbearing = 0;
26633 }
26634 if (right_padded && rightmost < cmp->rbearing)
26635 {
26636 rightmost = cmp->rbearing;
26637 }
26638
26639 cmp->pixel_width = rightmost;
26640 cmp->ascent = highest;
26641 cmp->descent = - lowest;
26642 if (cmp->ascent < font_ascent)
26643 cmp->ascent = font_ascent;
26644 if (cmp->descent < font_descent)
26645 cmp->descent = font_descent;
26646 }
26647
26648 if (it->glyph_row
26649 && (cmp->lbearing < 0
26650 || cmp->rbearing > cmp->pixel_width))
26651 it->glyph_row->contains_overlapping_glyphs_p = 1;
26652
26653 it->pixel_width = cmp->pixel_width;
26654 it->ascent = it->phys_ascent = cmp->ascent;
26655 it->descent = it->phys_descent = cmp->descent;
26656 if (face->box != FACE_NO_BOX)
26657 {
26658 int thick = face->box_line_width;
26659
26660 if (thick > 0)
26661 {
26662 it->ascent += thick;
26663 it->descent += thick;
26664 }
26665 else
26666 thick = - thick;
26667
26668 if (it->start_of_box_run_p)
26669 it->pixel_width += thick;
26670 if (it->end_of_box_run_p)
26671 it->pixel_width += thick;
26672 }
26673
26674 /* If face has an overline, add the height of the overline
26675 (1 pixel) and a 1 pixel margin to the character height. */
26676 if (face->overline_p)
26677 it->ascent += overline_margin;
26678
26679 take_vertical_position_into_account (it);
26680 if (it->ascent < 0)
26681 it->ascent = 0;
26682 if (it->descent < 0)
26683 it->descent = 0;
26684
26685 if (it->glyph_row && cmp->glyph_len > 0)
26686 append_composite_glyph (it);
26687 }
26688 else if (it->what == IT_COMPOSITION)
26689 {
26690 /* A dynamic (automatic) composition. */
26691 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26692 Lisp_Object gstring;
26693 struct font_metrics metrics;
26694
26695 it->nglyphs = 1;
26696
26697 gstring = composition_gstring_from_id (it->cmp_it.id);
26698 it->pixel_width
26699 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
26700 &metrics);
26701 if (it->glyph_row
26702 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
26703 it->glyph_row->contains_overlapping_glyphs_p = 1;
26704 it->ascent = it->phys_ascent = metrics.ascent;
26705 it->descent = it->phys_descent = metrics.descent;
26706 if (face->box != FACE_NO_BOX)
26707 {
26708 int thick = face->box_line_width;
26709
26710 if (thick > 0)
26711 {
26712 it->ascent += thick;
26713 it->descent += thick;
26714 }
26715 else
26716 thick = - thick;
26717
26718 if (it->start_of_box_run_p)
26719 it->pixel_width += thick;
26720 if (it->end_of_box_run_p)
26721 it->pixel_width += thick;
26722 }
26723 /* If face has an overline, add the height of the overline
26724 (1 pixel) and a 1 pixel margin to the character height. */
26725 if (face->overline_p)
26726 it->ascent += overline_margin;
26727 take_vertical_position_into_account (it);
26728 if (it->ascent < 0)
26729 it->ascent = 0;
26730 if (it->descent < 0)
26731 it->descent = 0;
26732
26733 if (it->glyph_row)
26734 append_composite_glyph (it);
26735 }
26736 else if (it->what == IT_GLYPHLESS)
26737 produce_glyphless_glyph (it, 0, Qnil);
26738 else if (it->what == IT_IMAGE)
26739 produce_image_glyph (it);
26740 else if (it->what == IT_STRETCH)
26741 produce_stretch_glyph (it);
26742
26743 done:
26744 /* Accumulate dimensions. Note: can't assume that it->descent > 0
26745 because this isn't true for images with `:ascent 100'. */
26746 eassert (it->ascent >= 0 && it->descent >= 0);
26747 if (it->area == TEXT_AREA)
26748 it->current_x += it->pixel_width;
26749
26750 if (extra_line_spacing > 0)
26751 {
26752 it->descent += extra_line_spacing;
26753 if (extra_line_spacing > it->max_extra_line_spacing)
26754 it->max_extra_line_spacing = extra_line_spacing;
26755 }
26756
26757 it->max_ascent = max (it->max_ascent, it->ascent);
26758 it->max_descent = max (it->max_descent, it->descent);
26759 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
26760 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
26761 }
26762
26763 /* EXPORT for RIF:
26764 Output LEN glyphs starting at START at the nominal cursor position.
26765 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
26766 being updated, and UPDATED_AREA is the area of that row being updated. */
26767
26768 void
26769 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
26770 struct glyph *start, enum glyph_row_area updated_area, int len)
26771 {
26772 int x, hpos, chpos = w->phys_cursor.hpos;
26773
26774 eassert (updated_row);
26775 /* When the window is hscrolled, cursor hpos can legitimately be out
26776 of bounds, but we draw the cursor at the corresponding window
26777 margin in that case. */
26778 if (!updated_row->reversed_p && chpos < 0)
26779 chpos = 0;
26780 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
26781 chpos = updated_row->used[TEXT_AREA] - 1;
26782
26783 block_input ();
26784
26785 /* Write glyphs. */
26786
26787 hpos = start - updated_row->glyphs[updated_area];
26788 x = draw_glyphs (w, w->output_cursor.x,
26789 updated_row, updated_area,
26790 hpos, hpos + len,
26791 DRAW_NORMAL_TEXT, 0);
26792
26793 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
26794 if (updated_area == TEXT_AREA
26795 && w->phys_cursor_on_p
26796 && w->phys_cursor.vpos == w->output_cursor.vpos
26797 && chpos >= hpos
26798 && chpos < hpos + len)
26799 w->phys_cursor_on_p = 0;
26800
26801 unblock_input ();
26802
26803 /* Advance the output cursor. */
26804 w->output_cursor.hpos += len;
26805 w->output_cursor.x = x;
26806 }
26807
26808
26809 /* EXPORT for RIF:
26810 Insert LEN glyphs from START at the nominal cursor position. */
26811
26812 void
26813 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
26814 struct glyph *start, enum glyph_row_area updated_area, int len)
26815 {
26816 struct frame *f;
26817 int line_height, shift_by_width, shifted_region_width;
26818 struct glyph_row *row;
26819 struct glyph *glyph;
26820 int frame_x, frame_y;
26821 ptrdiff_t hpos;
26822
26823 eassert (updated_row);
26824 block_input ();
26825 f = XFRAME (WINDOW_FRAME (w));
26826
26827 /* Get the height of the line we are in. */
26828 row = updated_row;
26829 line_height = row->height;
26830
26831 /* Get the width of the glyphs to insert. */
26832 shift_by_width = 0;
26833 for (glyph = start; glyph < start + len; ++glyph)
26834 shift_by_width += glyph->pixel_width;
26835
26836 /* Get the width of the region to shift right. */
26837 shifted_region_width = (window_box_width (w, updated_area)
26838 - w->output_cursor.x
26839 - shift_by_width);
26840
26841 /* Shift right. */
26842 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
26843 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
26844
26845 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
26846 line_height, shift_by_width);
26847
26848 /* Write the glyphs. */
26849 hpos = start - row->glyphs[updated_area];
26850 draw_glyphs (w, w->output_cursor.x, row, updated_area,
26851 hpos, hpos + len,
26852 DRAW_NORMAL_TEXT, 0);
26853
26854 /* Advance the output cursor. */
26855 w->output_cursor.hpos += len;
26856 w->output_cursor.x += shift_by_width;
26857 unblock_input ();
26858 }
26859
26860
26861 /* EXPORT for RIF:
26862 Erase the current text line from the nominal cursor position
26863 (inclusive) to pixel column TO_X (exclusive). The idea is that
26864 everything from TO_X onward is already erased.
26865
26866 TO_X is a pixel position relative to UPDATED_AREA of currently
26867 updated window W. TO_X == -1 means clear to the end of this area. */
26868
26869 void
26870 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
26871 enum glyph_row_area updated_area, int to_x)
26872 {
26873 struct frame *f;
26874 int max_x, min_y, max_y;
26875 int from_x, from_y, to_y;
26876
26877 eassert (updated_row);
26878 f = XFRAME (w->frame);
26879
26880 if (updated_row->full_width_p)
26881 max_x = (WINDOW_PIXEL_WIDTH (w)
26882 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26883 else
26884 max_x = window_box_width (w, updated_area);
26885 max_y = window_text_bottom_y (w);
26886
26887 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
26888 of window. For TO_X > 0, truncate to end of drawing area. */
26889 if (to_x == 0)
26890 return;
26891 else if (to_x < 0)
26892 to_x = max_x;
26893 else
26894 to_x = min (to_x, max_x);
26895
26896 to_y = min (max_y, w->output_cursor.y + updated_row->height);
26897
26898 /* Notice if the cursor will be cleared by this operation. */
26899 if (!updated_row->full_width_p)
26900 notice_overwritten_cursor (w, updated_area,
26901 w->output_cursor.x, -1,
26902 updated_row->y,
26903 MATRIX_ROW_BOTTOM_Y (updated_row));
26904
26905 from_x = w->output_cursor.x;
26906
26907 /* Translate to frame coordinates. */
26908 if (updated_row->full_width_p)
26909 {
26910 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
26911 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
26912 }
26913 else
26914 {
26915 int area_left = window_box_left (w, updated_area);
26916 from_x += area_left;
26917 to_x += area_left;
26918 }
26919
26920 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
26921 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
26922 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
26923
26924 /* Prevent inadvertently clearing to end of the X window. */
26925 if (to_x > from_x && to_y > from_y)
26926 {
26927 block_input ();
26928 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
26929 to_x - from_x, to_y - from_y);
26930 unblock_input ();
26931 }
26932 }
26933
26934 #endif /* HAVE_WINDOW_SYSTEM */
26935
26936
26937 \f
26938 /***********************************************************************
26939 Cursor types
26940 ***********************************************************************/
26941
26942 /* Value is the internal representation of the specified cursor type
26943 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
26944 of the bar cursor. */
26945
26946 static enum text_cursor_kinds
26947 get_specified_cursor_type (Lisp_Object arg, int *width)
26948 {
26949 enum text_cursor_kinds type;
26950
26951 if (NILP (arg))
26952 return NO_CURSOR;
26953
26954 if (EQ (arg, Qbox))
26955 return FILLED_BOX_CURSOR;
26956
26957 if (EQ (arg, Qhollow))
26958 return HOLLOW_BOX_CURSOR;
26959
26960 if (EQ (arg, Qbar))
26961 {
26962 *width = 2;
26963 return BAR_CURSOR;
26964 }
26965
26966 if (CONSP (arg)
26967 && EQ (XCAR (arg), Qbar)
26968 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
26969 {
26970 *width = XINT (XCDR (arg));
26971 return BAR_CURSOR;
26972 }
26973
26974 if (EQ (arg, Qhbar))
26975 {
26976 *width = 2;
26977 return HBAR_CURSOR;
26978 }
26979
26980 if (CONSP (arg)
26981 && EQ (XCAR (arg), Qhbar)
26982 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
26983 {
26984 *width = XINT (XCDR (arg));
26985 return HBAR_CURSOR;
26986 }
26987
26988 /* Treat anything unknown as "hollow box cursor".
26989 It was bad to signal an error; people have trouble fixing
26990 .Xdefaults with Emacs, when it has something bad in it. */
26991 type = HOLLOW_BOX_CURSOR;
26992
26993 return type;
26994 }
26995
26996 /* Set the default cursor types for specified frame. */
26997 void
26998 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
26999 {
27000 int width = 1;
27001 Lisp_Object tem;
27002
27003 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
27004 FRAME_CURSOR_WIDTH (f) = width;
27005
27006 /* By default, set up the blink-off state depending on the on-state. */
27007
27008 tem = Fassoc (arg, Vblink_cursor_alist);
27009 if (!NILP (tem))
27010 {
27011 FRAME_BLINK_OFF_CURSOR (f)
27012 = get_specified_cursor_type (XCDR (tem), &width);
27013 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
27014 }
27015 else
27016 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
27017
27018 /* Make sure the cursor gets redrawn. */
27019 f->cursor_type_changed = 1;
27020 }
27021
27022
27023 #ifdef HAVE_WINDOW_SYSTEM
27024
27025 /* Return the cursor we want to be displayed in window W. Return
27026 width of bar/hbar cursor through WIDTH arg. Return with
27027 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
27028 (i.e. if the `system caret' should track this cursor).
27029
27030 In a mini-buffer window, we want the cursor only to appear if we
27031 are reading input from this window. For the selected window, we
27032 want the cursor type given by the frame parameter or buffer local
27033 setting of cursor-type. If explicitly marked off, draw no cursor.
27034 In all other cases, we want a hollow box cursor. */
27035
27036 static enum text_cursor_kinds
27037 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
27038 int *active_cursor)
27039 {
27040 struct frame *f = XFRAME (w->frame);
27041 struct buffer *b = XBUFFER (w->contents);
27042 int cursor_type = DEFAULT_CURSOR;
27043 Lisp_Object alt_cursor;
27044 int non_selected = 0;
27045
27046 *active_cursor = 1;
27047
27048 /* Echo area */
27049 if (cursor_in_echo_area
27050 && FRAME_HAS_MINIBUF_P (f)
27051 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
27052 {
27053 if (w == XWINDOW (echo_area_window))
27054 {
27055 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
27056 {
27057 *width = FRAME_CURSOR_WIDTH (f);
27058 return FRAME_DESIRED_CURSOR (f);
27059 }
27060 else
27061 return get_specified_cursor_type (BVAR (b, cursor_type), width);
27062 }
27063
27064 *active_cursor = 0;
27065 non_selected = 1;
27066 }
27067
27068 /* Detect a nonselected window or nonselected frame. */
27069 else if (w != XWINDOW (f->selected_window)
27070 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
27071 {
27072 *active_cursor = 0;
27073
27074 if (MINI_WINDOW_P (w) && minibuf_level == 0)
27075 return NO_CURSOR;
27076
27077 non_selected = 1;
27078 }
27079
27080 /* Never display a cursor in a window in which cursor-type is nil. */
27081 if (NILP (BVAR (b, cursor_type)))
27082 return NO_CURSOR;
27083
27084 /* Get the normal cursor type for this window. */
27085 if (EQ (BVAR (b, cursor_type), Qt))
27086 {
27087 cursor_type = FRAME_DESIRED_CURSOR (f);
27088 *width = FRAME_CURSOR_WIDTH (f);
27089 }
27090 else
27091 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
27092
27093 /* Use cursor-in-non-selected-windows instead
27094 for non-selected window or frame. */
27095 if (non_selected)
27096 {
27097 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
27098 if (!EQ (Qt, alt_cursor))
27099 return get_specified_cursor_type (alt_cursor, width);
27100 /* t means modify the normal cursor type. */
27101 if (cursor_type == FILLED_BOX_CURSOR)
27102 cursor_type = HOLLOW_BOX_CURSOR;
27103 else if (cursor_type == BAR_CURSOR && *width > 1)
27104 --*width;
27105 return cursor_type;
27106 }
27107
27108 /* Use normal cursor if not blinked off. */
27109 if (!w->cursor_off_p)
27110 {
27111 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27112 {
27113 if (cursor_type == FILLED_BOX_CURSOR)
27114 {
27115 /* Using a block cursor on large images can be very annoying.
27116 So use a hollow cursor for "large" images.
27117 If image is not transparent (no mask), also use hollow cursor. */
27118 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27119 if (img != NULL && IMAGEP (img->spec))
27120 {
27121 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
27122 where N = size of default frame font size.
27123 This should cover most of the "tiny" icons people may use. */
27124 if (!img->mask
27125 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
27126 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
27127 cursor_type = HOLLOW_BOX_CURSOR;
27128 }
27129 }
27130 else if (cursor_type != NO_CURSOR)
27131 {
27132 /* Display current only supports BOX and HOLLOW cursors for images.
27133 So for now, unconditionally use a HOLLOW cursor when cursor is
27134 not a solid box cursor. */
27135 cursor_type = HOLLOW_BOX_CURSOR;
27136 }
27137 }
27138 return cursor_type;
27139 }
27140
27141 /* Cursor is blinked off, so determine how to "toggle" it. */
27142
27143 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
27144 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
27145 return get_specified_cursor_type (XCDR (alt_cursor), width);
27146
27147 /* Then see if frame has specified a specific blink off cursor type. */
27148 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
27149 {
27150 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
27151 return FRAME_BLINK_OFF_CURSOR (f);
27152 }
27153
27154 #if 0
27155 /* Some people liked having a permanently visible blinking cursor,
27156 while others had very strong opinions against it. So it was
27157 decided to remove it. KFS 2003-09-03 */
27158
27159 /* Finally perform built-in cursor blinking:
27160 filled box <-> hollow box
27161 wide [h]bar <-> narrow [h]bar
27162 narrow [h]bar <-> no cursor
27163 other type <-> no cursor */
27164
27165 if (cursor_type == FILLED_BOX_CURSOR)
27166 return HOLLOW_BOX_CURSOR;
27167
27168 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
27169 {
27170 *width = 1;
27171 return cursor_type;
27172 }
27173 #endif
27174
27175 return NO_CURSOR;
27176 }
27177
27178
27179 /* Notice when the text cursor of window W has been completely
27180 overwritten by a drawing operation that outputs glyphs in AREA
27181 starting at X0 and ending at X1 in the line starting at Y0 and
27182 ending at Y1. X coordinates are area-relative. X1 < 0 means all
27183 the rest of the line after X0 has been written. Y coordinates
27184 are window-relative. */
27185
27186 static void
27187 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
27188 int x0, int x1, int y0, int y1)
27189 {
27190 int cx0, cx1, cy0, cy1;
27191 struct glyph_row *row;
27192
27193 if (!w->phys_cursor_on_p)
27194 return;
27195 if (area != TEXT_AREA)
27196 return;
27197
27198 if (w->phys_cursor.vpos < 0
27199 || w->phys_cursor.vpos >= w->current_matrix->nrows
27200 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
27201 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
27202 return;
27203
27204 if (row->cursor_in_fringe_p)
27205 {
27206 row->cursor_in_fringe_p = 0;
27207 draw_fringe_bitmap (w, row, row->reversed_p);
27208 w->phys_cursor_on_p = 0;
27209 return;
27210 }
27211
27212 cx0 = w->phys_cursor.x;
27213 cx1 = cx0 + w->phys_cursor_width;
27214 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
27215 return;
27216
27217 /* The cursor image will be completely removed from the
27218 screen if the output area intersects the cursor area in
27219 y-direction. When we draw in [y0 y1[, and some part of
27220 the cursor is at y < y0, that part must have been drawn
27221 before. When scrolling, the cursor is erased before
27222 actually scrolling, so we don't come here. When not
27223 scrolling, the rows above the old cursor row must have
27224 changed, and in this case these rows must have written
27225 over the cursor image.
27226
27227 Likewise if part of the cursor is below y1, with the
27228 exception of the cursor being in the first blank row at
27229 the buffer and window end because update_text_area
27230 doesn't draw that row. (Except when it does, but
27231 that's handled in update_text_area.) */
27232
27233 cy0 = w->phys_cursor.y;
27234 cy1 = cy0 + w->phys_cursor_height;
27235 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
27236 return;
27237
27238 w->phys_cursor_on_p = 0;
27239 }
27240
27241 #endif /* HAVE_WINDOW_SYSTEM */
27242
27243 \f
27244 /************************************************************************
27245 Mouse Face
27246 ************************************************************************/
27247
27248 #ifdef HAVE_WINDOW_SYSTEM
27249
27250 /* EXPORT for RIF:
27251 Fix the display of area AREA of overlapping row ROW in window W
27252 with respect to the overlapping part OVERLAPS. */
27253
27254 void
27255 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
27256 enum glyph_row_area area, int overlaps)
27257 {
27258 int i, x;
27259
27260 block_input ();
27261
27262 x = 0;
27263 for (i = 0; i < row->used[area];)
27264 {
27265 if (row->glyphs[area][i].overlaps_vertically_p)
27266 {
27267 int start = i, start_x = x;
27268
27269 do
27270 {
27271 x += row->glyphs[area][i].pixel_width;
27272 ++i;
27273 }
27274 while (i < row->used[area]
27275 && row->glyphs[area][i].overlaps_vertically_p);
27276
27277 draw_glyphs (w, start_x, row, area,
27278 start, i,
27279 DRAW_NORMAL_TEXT, overlaps);
27280 }
27281 else
27282 {
27283 x += row->glyphs[area][i].pixel_width;
27284 ++i;
27285 }
27286 }
27287
27288 unblock_input ();
27289 }
27290
27291
27292 /* EXPORT:
27293 Draw the cursor glyph of window W in glyph row ROW. See the
27294 comment of draw_glyphs for the meaning of HL. */
27295
27296 void
27297 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
27298 enum draw_glyphs_face hl)
27299 {
27300 /* If cursor hpos is out of bounds, don't draw garbage. This can
27301 happen in mini-buffer windows when switching between echo area
27302 glyphs and mini-buffer. */
27303 if ((row->reversed_p
27304 ? (w->phys_cursor.hpos >= 0)
27305 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
27306 {
27307 int on_p = w->phys_cursor_on_p;
27308 int x1;
27309 int hpos = w->phys_cursor.hpos;
27310
27311 /* When the window is hscrolled, cursor hpos can legitimately be
27312 out of bounds, but we draw the cursor at the corresponding
27313 window margin in that case. */
27314 if (!row->reversed_p && hpos < 0)
27315 hpos = 0;
27316 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27317 hpos = row->used[TEXT_AREA] - 1;
27318
27319 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
27320 hl, 0);
27321 w->phys_cursor_on_p = on_p;
27322
27323 if (hl == DRAW_CURSOR)
27324 w->phys_cursor_width = x1 - w->phys_cursor.x;
27325 /* When we erase the cursor, and ROW is overlapped by other
27326 rows, make sure that these overlapping parts of other rows
27327 are redrawn. */
27328 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
27329 {
27330 w->phys_cursor_width = x1 - w->phys_cursor.x;
27331
27332 if (row > w->current_matrix->rows
27333 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
27334 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
27335 OVERLAPS_ERASED_CURSOR);
27336
27337 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
27338 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
27339 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
27340 OVERLAPS_ERASED_CURSOR);
27341 }
27342 }
27343 }
27344
27345
27346 /* Erase the image of a cursor of window W from the screen. */
27347
27348 void
27349 erase_phys_cursor (struct window *w)
27350 {
27351 struct frame *f = XFRAME (w->frame);
27352 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27353 int hpos = w->phys_cursor.hpos;
27354 int vpos = w->phys_cursor.vpos;
27355 int mouse_face_here_p = 0;
27356 struct glyph_matrix *active_glyphs = w->current_matrix;
27357 struct glyph_row *cursor_row;
27358 struct glyph *cursor_glyph;
27359 enum draw_glyphs_face hl;
27360
27361 /* No cursor displayed or row invalidated => nothing to do on the
27362 screen. */
27363 if (w->phys_cursor_type == NO_CURSOR)
27364 goto mark_cursor_off;
27365
27366 /* VPOS >= active_glyphs->nrows means that window has been resized.
27367 Don't bother to erase the cursor. */
27368 if (vpos >= active_glyphs->nrows)
27369 goto mark_cursor_off;
27370
27371 /* If row containing cursor is marked invalid, there is nothing we
27372 can do. */
27373 cursor_row = MATRIX_ROW (active_glyphs, vpos);
27374 if (!cursor_row->enabled_p)
27375 goto mark_cursor_off;
27376
27377 /* If line spacing is > 0, old cursor may only be partially visible in
27378 window after split-window. So adjust visible height. */
27379 cursor_row->visible_height = min (cursor_row->visible_height,
27380 window_text_bottom_y (w) - cursor_row->y);
27381
27382 /* If row is completely invisible, don't attempt to delete a cursor which
27383 isn't there. This can happen if cursor is at top of a window, and
27384 we switch to a buffer with a header line in that window. */
27385 if (cursor_row->visible_height <= 0)
27386 goto mark_cursor_off;
27387
27388 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
27389 if (cursor_row->cursor_in_fringe_p)
27390 {
27391 cursor_row->cursor_in_fringe_p = 0;
27392 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
27393 goto mark_cursor_off;
27394 }
27395
27396 /* This can happen when the new row is shorter than the old one.
27397 In this case, either draw_glyphs or clear_end_of_line
27398 should have cleared the cursor. Note that we wouldn't be
27399 able to erase the cursor in this case because we don't have a
27400 cursor glyph at hand. */
27401 if ((cursor_row->reversed_p
27402 ? (w->phys_cursor.hpos < 0)
27403 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
27404 goto mark_cursor_off;
27405
27406 /* When the window is hscrolled, cursor hpos can legitimately be out
27407 of bounds, but we draw the cursor at the corresponding window
27408 margin in that case. */
27409 if (!cursor_row->reversed_p && hpos < 0)
27410 hpos = 0;
27411 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
27412 hpos = cursor_row->used[TEXT_AREA] - 1;
27413
27414 /* If the cursor is in the mouse face area, redisplay that when
27415 we clear the cursor. */
27416 if (! NILP (hlinfo->mouse_face_window)
27417 && coords_in_mouse_face_p (w, hpos, vpos)
27418 /* Don't redraw the cursor's spot in mouse face if it is at the
27419 end of a line (on a newline). The cursor appears there, but
27420 mouse highlighting does not. */
27421 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
27422 mouse_face_here_p = 1;
27423
27424 /* Maybe clear the display under the cursor. */
27425 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
27426 {
27427 int x, y;
27428 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
27429 int width;
27430
27431 cursor_glyph = get_phys_cursor_glyph (w);
27432 if (cursor_glyph == NULL)
27433 goto mark_cursor_off;
27434
27435 width = cursor_glyph->pixel_width;
27436 x = w->phys_cursor.x;
27437 if (x < 0)
27438 {
27439 width += x;
27440 x = 0;
27441 }
27442 width = min (width, window_box_width (w, TEXT_AREA) - x);
27443 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
27444 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
27445
27446 if (width > 0)
27447 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
27448 }
27449
27450 /* Erase the cursor by redrawing the character underneath it. */
27451 if (mouse_face_here_p)
27452 hl = DRAW_MOUSE_FACE;
27453 else
27454 hl = DRAW_NORMAL_TEXT;
27455 draw_phys_cursor_glyph (w, cursor_row, hl);
27456
27457 mark_cursor_off:
27458 w->phys_cursor_on_p = 0;
27459 w->phys_cursor_type = NO_CURSOR;
27460 }
27461
27462
27463 /* EXPORT:
27464 Display or clear cursor of window W. If ON is zero, clear the
27465 cursor. If it is non-zero, display the cursor. If ON is nonzero,
27466 where to put the cursor is specified by HPOS, VPOS, X and Y. */
27467
27468 void
27469 display_and_set_cursor (struct window *w, bool on,
27470 int hpos, int vpos, int x, int y)
27471 {
27472 struct frame *f = XFRAME (w->frame);
27473 int new_cursor_type;
27474 int new_cursor_width;
27475 int active_cursor;
27476 struct glyph_row *glyph_row;
27477 struct glyph *glyph;
27478
27479 /* This is pointless on invisible frames, and dangerous on garbaged
27480 windows and frames; in the latter case, the frame or window may
27481 be in the midst of changing its size, and x and y may be off the
27482 window. */
27483 if (! FRAME_VISIBLE_P (f)
27484 || FRAME_GARBAGED_P (f)
27485 || vpos >= w->current_matrix->nrows
27486 || hpos >= w->current_matrix->matrix_w)
27487 return;
27488
27489 /* If cursor is off and we want it off, return quickly. */
27490 if (!on && !w->phys_cursor_on_p)
27491 return;
27492
27493 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
27494 /* If cursor row is not enabled, we don't really know where to
27495 display the cursor. */
27496 if (!glyph_row->enabled_p)
27497 {
27498 w->phys_cursor_on_p = 0;
27499 return;
27500 }
27501
27502 glyph = NULL;
27503 if (!glyph_row->exact_window_width_line_p
27504 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
27505 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
27506
27507 eassert (input_blocked_p ());
27508
27509 /* Set new_cursor_type to the cursor we want to be displayed. */
27510 new_cursor_type = get_window_cursor_type (w, glyph,
27511 &new_cursor_width, &active_cursor);
27512
27513 /* If cursor is currently being shown and we don't want it to be or
27514 it is in the wrong place, or the cursor type is not what we want,
27515 erase it. */
27516 if (w->phys_cursor_on_p
27517 && (!on
27518 || w->phys_cursor.x != x
27519 || w->phys_cursor.y != y
27520 /* HPOS can be negative in R2L rows whose
27521 exact_window_width_line_p flag is set (i.e. their newline
27522 would "overflow into the fringe"). */
27523 || hpos < 0
27524 || new_cursor_type != w->phys_cursor_type
27525 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
27526 && new_cursor_width != w->phys_cursor_width)))
27527 erase_phys_cursor (w);
27528
27529 /* Don't check phys_cursor_on_p here because that flag is only set
27530 to zero in some cases where we know that the cursor has been
27531 completely erased, to avoid the extra work of erasing the cursor
27532 twice. In other words, phys_cursor_on_p can be 1 and the cursor
27533 still not be visible, or it has only been partly erased. */
27534 if (on)
27535 {
27536 w->phys_cursor_ascent = glyph_row->ascent;
27537 w->phys_cursor_height = glyph_row->height;
27538
27539 /* Set phys_cursor_.* before x_draw_.* is called because some
27540 of them may need the information. */
27541 w->phys_cursor.x = x;
27542 w->phys_cursor.y = glyph_row->y;
27543 w->phys_cursor.hpos = hpos;
27544 w->phys_cursor.vpos = vpos;
27545 }
27546
27547 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
27548 new_cursor_type, new_cursor_width,
27549 on, active_cursor);
27550 }
27551
27552
27553 /* Switch the display of W's cursor on or off, according to the value
27554 of ON. */
27555
27556 static void
27557 update_window_cursor (struct window *w, bool on)
27558 {
27559 /* Don't update cursor in windows whose frame is in the process
27560 of being deleted. */
27561 if (w->current_matrix)
27562 {
27563 int hpos = w->phys_cursor.hpos;
27564 int vpos = w->phys_cursor.vpos;
27565 struct glyph_row *row;
27566
27567 if (vpos >= w->current_matrix->nrows
27568 || hpos >= w->current_matrix->matrix_w)
27569 return;
27570
27571 row = MATRIX_ROW (w->current_matrix, vpos);
27572
27573 /* When the window is hscrolled, cursor hpos can legitimately be
27574 out of bounds, but we draw the cursor at the corresponding
27575 window margin in that case. */
27576 if (!row->reversed_p && hpos < 0)
27577 hpos = 0;
27578 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27579 hpos = row->used[TEXT_AREA] - 1;
27580
27581 block_input ();
27582 display_and_set_cursor (w, on, hpos, vpos,
27583 w->phys_cursor.x, w->phys_cursor.y);
27584 unblock_input ();
27585 }
27586 }
27587
27588
27589 /* Call update_window_cursor with parameter ON_P on all leaf windows
27590 in the window tree rooted at W. */
27591
27592 static void
27593 update_cursor_in_window_tree (struct window *w, bool on_p)
27594 {
27595 while (w)
27596 {
27597 if (WINDOWP (w->contents))
27598 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
27599 else
27600 update_window_cursor (w, on_p);
27601
27602 w = NILP (w->next) ? 0 : XWINDOW (w->next);
27603 }
27604 }
27605
27606
27607 /* EXPORT:
27608 Display the cursor on window W, or clear it, according to ON_P.
27609 Don't change the cursor's position. */
27610
27611 void
27612 x_update_cursor (struct frame *f, bool on_p)
27613 {
27614 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
27615 }
27616
27617
27618 /* EXPORT:
27619 Clear the cursor of window W to background color, and mark the
27620 cursor as not shown. This is used when the text where the cursor
27621 is about to be rewritten. */
27622
27623 void
27624 x_clear_cursor (struct window *w)
27625 {
27626 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
27627 update_window_cursor (w, 0);
27628 }
27629
27630 #endif /* HAVE_WINDOW_SYSTEM */
27631
27632 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
27633 and MSDOS. */
27634 static void
27635 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
27636 int start_hpos, int end_hpos,
27637 enum draw_glyphs_face draw)
27638 {
27639 #ifdef HAVE_WINDOW_SYSTEM
27640 if (FRAME_WINDOW_P (XFRAME (w->frame)))
27641 {
27642 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
27643 return;
27644 }
27645 #endif
27646 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
27647 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
27648 #endif
27649 }
27650
27651 /* Display the active region described by mouse_face_* according to DRAW. */
27652
27653 static void
27654 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
27655 {
27656 struct window *w = XWINDOW (hlinfo->mouse_face_window);
27657 struct frame *f = XFRAME (WINDOW_FRAME (w));
27658
27659 if (/* If window is in the process of being destroyed, don't bother
27660 to do anything. */
27661 w->current_matrix != NULL
27662 /* Don't update mouse highlight if hidden. */
27663 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
27664 /* Recognize when we are called to operate on rows that don't exist
27665 anymore. This can happen when a window is split. */
27666 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
27667 {
27668 int phys_cursor_on_p = w->phys_cursor_on_p;
27669 struct glyph_row *row, *first, *last;
27670
27671 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
27672 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
27673
27674 for (row = first; row <= last && row->enabled_p; ++row)
27675 {
27676 int start_hpos, end_hpos, start_x;
27677
27678 /* For all but the first row, the highlight starts at column 0. */
27679 if (row == first)
27680 {
27681 /* R2L rows have BEG and END in reversed order, but the
27682 screen drawing geometry is always left to right. So
27683 we need to mirror the beginning and end of the
27684 highlighted area in R2L rows. */
27685 if (!row->reversed_p)
27686 {
27687 start_hpos = hlinfo->mouse_face_beg_col;
27688 start_x = hlinfo->mouse_face_beg_x;
27689 }
27690 else if (row == last)
27691 {
27692 start_hpos = hlinfo->mouse_face_end_col;
27693 start_x = hlinfo->mouse_face_end_x;
27694 }
27695 else
27696 {
27697 start_hpos = 0;
27698 start_x = 0;
27699 }
27700 }
27701 else if (row->reversed_p && row == last)
27702 {
27703 start_hpos = hlinfo->mouse_face_end_col;
27704 start_x = hlinfo->mouse_face_end_x;
27705 }
27706 else
27707 {
27708 start_hpos = 0;
27709 start_x = 0;
27710 }
27711
27712 if (row == last)
27713 {
27714 if (!row->reversed_p)
27715 end_hpos = hlinfo->mouse_face_end_col;
27716 else if (row == first)
27717 end_hpos = hlinfo->mouse_face_beg_col;
27718 else
27719 {
27720 end_hpos = row->used[TEXT_AREA];
27721 if (draw == DRAW_NORMAL_TEXT)
27722 row->fill_line_p = 1; /* Clear to end of line */
27723 }
27724 }
27725 else if (row->reversed_p && row == first)
27726 end_hpos = hlinfo->mouse_face_beg_col;
27727 else
27728 {
27729 end_hpos = row->used[TEXT_AREA];
27730 if (draw == DRAW_NORMAL_TEXT)
27731 row->fill_line_p = 1; /* Clear to end of line */
27732 }
27733
27734 if (end_hpos > start_hpos)
27735 {
27736 draw_row_with_mouse_face (w, start_x, row,
27737 start_hpos, end_hpos, draw);
27738
27739 row->mouse_face_p
27740 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
27741 }
27742 }
27743
27744 #ifdef HAVE_WINDOW_SYSTEM
27745 /* When we've written over the cursor, arrange for it to
27746 be displayed again. */
27747 if (FRAME_WINDOW_P (f)
27748 && phys_cursor_on_p && !w->phys_cursor_on_p)
27749 {
27750 int hpos = w->phys_cursor.hpos;
27751
27752 /* When the window is hscrolled, cursor hpos can legitimately be
27753 out of bounds, but we draw the cursor at the corresponding
27754 window margin in that case. */
27755 if (!row->reversed_p && hpos < 0)
27756 hpos = 0;
27757 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27758 hpos = row->used[TEXT_AREA] - 1;
27759
27760 block_input ();
27761 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
27762 w->phys_cursor.x, w->phys_cursor.y);
27763 unblock_input ();
27764 }
27765 #endif /* HAVE_WINDOW_SYSTEM */
27766 }
27767
27768 #ifdef HAVE_WINDOW_SYSTEM
27769 /* Change the mouse cursor. */
27770 if (FRAME_WINDOW_P (f))
27771 {
27772 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
27773 if (draw == DRAW_NORMAL_TEXT
27774 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
27775 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
27776 else
27777 #endif
27778 if (draw == DRAW_MOUSE_FACE)
27779 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
27780 else
27781 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
27782 }
27783 #endif /* HAVE_WINDOW_SYSTEM */
27784 }
27785
27786 /* EXPORT:
27787 Clear out the mouse-highlighted active region.
27788 Redraw it un-highlighted first. Value is non-zero if mouse
27789 face was actually drawn unhighlighted. */
27790
27791 int
27792 clear_mouse_face (Mouse_HLInfo *hlinfo)
27793 {
27794 int cleared = 0;
27795
27796 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
27797 {
27798 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
27799 cleared = 1;
27800 }
27801
27802 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
27803 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
27804 hlinfo->mouse_face_window = Qnil;
27805 hlinfo->mouse_face_overlay = Qnil;
27806 return cleared;
27807 }
27808
27809 /* Return true if the coordinates HPOS and VPOS on windows W are
27810 within the mouse face on that window. */
27811 static bool
27812 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
27813 {
27814 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
27815
27816 /* Quickly resolve the easy cases. */
27817 if (!(WINDOWP (hlinfo->mouse_face_window)
27818 && XWINDOW (hlinfo->mouse_face_window) == w))
27819 return false;
27820 if (vpos < hlinfo->mouse_face_beg_row
27821 || vpos > hlinfo->mouse_face_end_row)
27822 return false;
27823 if (vpos > hlinfo->mouse_face_beg_row
27824 && vpos < hlinfo->mouse_face_end_row)
27825 return true;
27826
27827 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
27828 {
27829 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
27830 {
27831 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
27832 return true;
27833 }
27834 else if ((vpos == hlinfo->mouse_face_beg_row
27835 && hpos >= hlinfo->mouse_face_beg_col)
27836 || (vpos == hlinfo->mouse_face_end_row
27837 && hpos < hlinfo->mouse_face_end_col))
27838 return true;
27839 }
27840 else
27841 {
27842 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
27843 {
27844 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
27845 return true;
27846 }
27847 else if ((vpos == hlinfo->mouse_face_beg_row
27848 && hpos <= hlinfo->mouse_face_beg_col)
27849 || (vpos == hlinfo->mouse_face_end_row
27850 && hpos > hlinfo->mouse_face_end_col))
27851 return true;
27852 }
27853 return false;
27854 }
27855
27856
27857 /* EXPORT:
27858 True if physical cursor of window W is within mouse face. */
27859
27860 bool
27861 cursor_in_mouse_face_p (struct window *w)
27862 {
27863 int hpos = w->phys_cursor.hpos;
27864 int vpos = w->phys_cursor.vpos;
27865 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
27866
27867 /* When the window is hscrolled, cursor hpos can legitimately be out
27868 of bounds, but we draw the cursor at the corresponding window
27869 margin in that case. */
27870 if (!row->reversed_p && hpos < 0)
27871 hpos = 0;
27872 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27873 hpos = row->used[TEXT_AREA] - 1;
27874
27875 return coords_in_mouse_face_p (w, hpos, vpos);
27876 }
27877
27878
27879 \f
27880 /* Find the glyph rows START_ROW and END_ROW of window W that display
27881 characters between buffer positions START_CHARPOS and END_CHARPOS
27882 (excluding END_CHARPOS). DISP_STRING is a display string that
27883 covers these buffer positions. This is similar to
27884 row_containing_pos, but is more accurate when bidi reordering makes
27885 buffer positions change non-linearly with glyph rows. */
27886 static void
27887 rows_from_pos_range (struct window *w,
27888 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
27889 Lisp_Object disp_string,
27890 struct glyph_row **start, struct glyph_row **end)
27891 {
27892 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27893 int last_y = window_text_bottom_y (w);
27894 struct glyph_row *row;
27895
27896 *start = NULL;
27897 *end = NULL;
27898
27899 while (!first->enabled_p
27900 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
27901 first++;
27902
27903 /* Find the START row. */
27904 for (row = first;
27905 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
27906 row++)
27907 {
27908 /* A row can potentially be the START row if the range of the
27909 characters it displays intersects the range
27910 [START_CHARPOS..END_CHARPOS). */
27911 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
27912 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
27913 /* See the commentary in row_containing_pos, for the
27914 explanation of the complicated way to check whether
27915 some position is beyond the end of the characters
27916 displayed by a row. */
27917 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
27918 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
27919 && !row->ends_at_zv_p
27920 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
27921 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
27922 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
27923 && !row->ends_at_zv_p
27924 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
27925 {
27926 /* Found a candidate row. Now make sure at least one of the
27927 glyphs it displays has a charpos from the range
27928 [START_CHARPOS..END_CHARPOS).
27929
27930 This is not obvious because bidi reordering could make
27931 buffer positions of a row be 1,2,3,102,101,100, and if we
27932 want to highlight characters in [50..60), we don't want
27933 this row, even though [50..60) does intersect [1..103),
27934 the range of character positions given by the row's start
27935 and end positions. */
27936 struct glyph *g = row->glyphs[TEXT_AREA];
27937 struct glyph *e = g + row->used[TEXT_AREA];
27938
27939 while (g < e)
27940 {
27941 if (((BUFFERP (g->object) || INTEGERP (g->object))
27942 && start_charpos <= g->charpos && g->charpos < end_charpos)
27943 /* A glyph that comes from DISP_STRING is by
27944 definition to be highlighted. */
27945 || EQ (g->object, disp_string))
27946 *start = row;
27947 g++;
27948 }
27949 if (*start)
27950 break;
27951 }
27952 }
27953
27954 /* Find the END row. */
27955 if (!*start
27956 /* If the last row is partially visible, start looking for END
27957 from that row, instead of starting from FIRST. */
27958 && !(row->enabled_p
27959 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
27960 row = first;
27961 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
27962 {
27963 struct glyph_row *next = row + 1;
27964 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
27965
27966 if (!next->enabled_p
27967 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
27968 /* The first row >= START whose range of displayed characters
27969 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
27970 is the row END + 1. */
27971 || (start_charpos < next_start
27972 && end_charpos < next_start)
27973 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
27974 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
27975 && !next->ends_at_zv_p
27976 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
27977 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
27978 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
27979 && !next->ends_at_zv_p
27980 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
27981 {
27982 *end = row;
27983 break;
27984 }
27985 else
27986 {
27987 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
27988 but none of the characters it displays are in the range, it is
27989 also END + 1. */
27990 struct glyph *g = next->glyphs[TEXT_AREA];
27991 struct glyph *s = g;
27992 struct glyph *e = g + next->used[TEXT_AREA];
27993
27994 while (g < e)
27995 {
27996 if (((BUFFERP (g->object) || INTEGERP (g->object))
27997 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
27998 /* If the buffer position of the first glyph in
27999 the row is equal to END_CHARPOS, it means
28000 the last character to be highlighted is the
28001 newline of ROW, and we must consider NEXT as
28002 END, not END+1. */
28003 || (((!next->reversed_p && g == s)
28004 || (next->reversed_p && g == e - 1))
28005 && (g->charpos == end_charpos
28006 /* Special case for when NEXT is an
28007 empty line at ZV. */
28008 || (g->charpos == -1
28009 && !row->ends_at_zv_p
28010 && next_start == end_charpos)))))
28011 /* A glyph that comes from DISP_STRING is by
28012 definition to be highlighted. */
28013 || EQ (g->object, disp_string))
28014 break;
28015 g++;
28016 }
28017 if (g == e)
28018 {
28019 *end = row;
28020 break;
28021 }
28022 /* The first row that ends at ZV must be the last to be
28023 highlighted. */
28024 else if (next->ends_at_zv_p)
28025 {
28026 *end = next;
28027 break;
28028 }
28029 }
28030 }
28031 }
28032
28033 /* This function sets the mouse_face_* elements of HLINFO, assuming
28034 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
28035 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
28036 for the overlay or run of text properties specifying the mouse
28037 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
28038 before-string and after-string that must also be highlighted.
28039 DISP_STRING, if non-nil, is a display string that may cover some
28040 or all of the highlighted text. */
28041
28042 static void
28043 mouse_face_from_buffer_pos (Lisp_Object window,
28044 Mouse_HLInfo *hlinfo,
28045 ptrdiff_t mouse_charpos,
28046 ptrdiff_t start_charpos,
28047 ptrdiff_t end_charpos,
28048 Lisp_Object before_string,
28049 Lisp_Object after_string,
28050 Lisp_Object disp_string)
28051 {
28052 struct window *w = XWINDOW (window);
28053 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28054 struct glyph_row *r1, *r2;
28055 struct glyph *glyph, *end;
28056 ptrdiff_t ignore, pos;
28057 int x;
28058
28059 eassert (NILP (disp_string) || STRINGP (disp_string));
28060 eassert (NILP (before_string) || STRINGP (before_string));
28061 eassert (NILP (after_string) || STRINGP (after_string));
28062
28063 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
28064 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
28065 if (r1 == NULL)
28066 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28067 /* If the before-string or display-string contains newlines,
28068 rows_from_pos_range skips to its last row. Move back. */
28069 if (!NILP (before_string) || !NILP (disp_string))
28070 {
28071 struct glyph_row *prev;
28072 while ((prev = r1 - 1, prev >= first)
28073 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
28074 && prev->used[TEXT_AREA] > 0)
28075 {
28076 struct glyph *beg = prev->glyphs[TEXT_AREA];
28077 glyph = beg + prev->used[TEXT_AREA];
28078 while (--glyph >= beg && INTEGERP (glyph->object));
28079 if (glyph < beg
28080 || !(EQ (glyph->object, before_string)
28081 || EQ (glyph->object, disp_string)))
28082 break;
28083 r1 = prev;
28084 }
28085 }
28086 if (r2 == NULL)
28087 {
28088 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28089 hlinfo->mouse_face_past_end = 1;
28090 }
28091 else if (!NILP (after_string))
28092 {
28093 /* If the after-string has newlines, advance to its last row. */
28094 struct glyph_row *next;
28095 struct glyph_row *last
28096 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28097
28098 for (next = r2 + 1;
28099 next <= last
28100 && next->used[TEXT_AREA] > 0
28101 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
28102 ++next)
28103 r2 = next;
28104 }
28105 /* The rest of the display engine assumes that mouse_face_beg_row is
28106 either above mouse_face_end_row or identical to it. But with
28107 bidi-reordered continued lines, the row for START_CHARPOS could
28108 be below the row for END_CHARPOS. If so, swap the rows and store
28109 them in correct order. */
28110 if (r1->y > r2->y)
28111 {
28112 struct glyph_row *tem = r2;
28113
28114 r2 = r1;
28115 r1 = tem;
28116 }
28117
28118 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
28119 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
28120
28121 /* For a bidi-reordered row, the positions of BEFORE_STRING,
28122 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
28123 could be anywhere in the row and in any order. The strategy
28124 below is to find the leftmost and the rightmost glyph that
28125 belongs to either of these 3 strings, or whose position is
28126 between START_CHARPOS and END_CHARPOS, and highlight all the
28127 glyphs between those two. This may cover more than just the text
28128 between START_CHARPOS and END_CHARPOS if the range of characters
28129 strides the bidi level boundary, e.g. if the beginning is in R2L
28130 text while the end is in L2R text or vice versa. */
28131 if (!r1->reversed_p)
28132 {
28133 /* This row is in a left to right paragraph. Scan it left to
28134 right. */
28135 glyph = r1->glyphs[TEXT_AREA];
28136 end = glyph + r1->used[TEXT_AREA];
28137 x = r1->x;
28138
28139 /* Skip truncation glyphs at the start of the glyph row. */
28140 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28141 for (; glyph < end
28142 && INTEGERP (glyph->object)
28143 && glyph->charpos < 0;
28144 ++glyph)
28145 x += glyph->pixel_width;
28146
28147 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28148 or DISP_STRING, and the first glyph from buffer whose
28149 position is between START_CHARPOS and END_CHARPOS. */
28150 for (; glyph < end
28151 && !INTEGERP (glyph->object)
28152 && !EQ (glyph->object, disp_string)
28153 && !(BUFFERP (glyph->object)
28154 && (glyph->charpos >= start_charpos
28155 && glyph->charpos < end_charpos));
28156 ++glyph)
28157 {
28158 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28159 are present at buffer positions between START_CHARPOS and
28160 END_CHARPOS, or if they come from an overlay. */
28161 if (EQ (glyph->object, before_string))
28162 {
28163 pos = string_buffer_position (before_string,
28164 start_charpos);
28165 /* If pos == 0, it means before_string came from an
28166 overlay, not from a buffer position. */
28167 if (!pos || (pos >= start_charpos && pos < end_charpos))
28168 break;
28169 }
28170 else if (EQ (glyph->object, after_string))
28171 {
28172 pos = string_buffer_position (after_string, end_charpos);
28173 if (!pos || (pos >= start_charpos && pos < end_charpos))
28174 break;
28175 }
28176 x += glyph->pixel_width;
28177 }
28178 hlinfo->mouse_face_beg_x = x;
28179 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28180 }
28181 else
28182 {
28183 /* This row is in a right to left paragraph. Scan it right to
28184 left. */
28185 struct glyph *g;
28186
28187 end = r1->glyphs[TEXT_AREA] - 1;
28188 glyph = end + r1->used[TEXT_AREA];
28189
28190 /* Skip truncation glyphs at the start of the glyph row. */
28191 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28192 for (; glyph > end
28193 && INTEGERP (glyph->object)
28194 && glyph->charpos < 0;
28195 --glyph)
28196 ;
28197
28198 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28199 or DISP_STRING, and the first glyph from buffer whose
28200 position is between START_CHARPOS and END_CHARPOS. */
28201 for (; glyph > end
28202 && !INTEGERP (glyph->object)
28203 && !EQ (glyph->object, disp_string)
28204 && !(BUFFERP (glyph->object)
28205 && (glyph->charpos >= start_charpos
28206 && glyph->charpos < end_charpos));
28207 --glyph)
28208 {
28209 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28210 are present at buffer positions between START_CHARPOS and
28211 END_CHARPOS, or if they come from an overlay. */
28212 if (EQ (glyph->object, before_string))
28213 {
28214 pos = string_buffer_position (before_string, start_charpos);
28215 /* If pos == 0, it means before_string came from an
28216 overlay, not from a buffer position. */
28217 if (!pos || (pos >= start_charpos && pos < end_charpos))
28218 break;
28219 }
28220 else if (EQ (glyph->object, after_string))
28221 {
28222 pos = string_buffer_position (after_string, end_charpos);
28223 if (!pos || (pos >= start_charpos && pos < end_charpos))
28224 break;
28225 }
28226 }
28227
28228 glyph++; /* first glyph to the right of the highlighted area */
28229 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
28230 x += g->pixel_width;
28231 hlinfo->mouse_face_beg_x = x;
28232 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28233 }
28234
28235 /* If the highlight ends in a different row, compute GLYPH and END
28236 for the end row. Otherwise, reuse the values computed above for
28237 the row where the highlight begins. */
28238 if (r2 != r1)
28239 {
28240 if (!r2->reversed_p)
28241 {
28242 glyph = r2->glyphs[TEXT_AREA];
28243 end = glyph + r2->used[TEXT_AREA];
28244 x = r2->x;
28245 }
28246 else
28247 {
28248 end = r2->glyphs[TEXT_AREA] - 1;
28249 glyph = end + r2->used[TEXT_AREA];
28250 }
28251 }
28252
28253 if (!r2->reversed_p)
28254 {
28255 /* Skip truncation and continuation glyphs near the end of the
28256 row, and also blanks and stretch glyphs inserted by
28257 extend_face_to_end_of_line. */
28258 while (end > glyph
28259 && INTEGERP ((end - 1)->object))
28260 --end;
28261 /* Scan the rest of the glyph row from the end, looking for the
28262 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28263 DISP_STRING, or whose position is between START_CHARPOS
28264 and END_CHARPOS */
28265 for (--end;
28266 end > glyph
28267 && !INTEGERP (end->object)
28268 && !EQ (end->object, disp_string)
28269 && !(BUFFERP (end->object)
28270 && (end->charpos >= start_charpos
28271 && end->charpos < end_charpos));
28272 --end)
28273 {
28274 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28275 are present at buffer positions between START_CHARPOS and
28276 END_CHARPOS, or if they come from an overlay. */
28277 if (EQ (end->object, before_string))
28278 {
28279 pos = string_buffer_position (before_string, start_charpos);
28280 if (!pos || (pos >= start_charpos && pos < end_charpos))
28281 break;
28282 }
28283 else if (EQ (end->object, after_string))
28284 {
28285 pos = string_buffer_position (after_string, end_charpos);
28286 if (!pos || (pos >= start_charpos && pos < end_charpos))
28287 break;
28288 }
28289 }
28290 /* Find the X coordinate of the last glyph to be highlighted. */
28291 for (; glyph <= end; ++glyph)
28292 x += glyph->pixel_width;
28293
28294 hlinfo->mouse_face_end_x = x;
28295 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
28296 }
28297 else
28298 {
28299 /* Skip truncation and continuation glyphs near the end of the
28300 row, and also blanks and stretch glyphs inserted by
28301 extend_face_to_end_of_line. */
28302 x = r2->x;
28303 end++;
28304 while (end < glyph
28305 && INTEGERP (end->object))
28306 {
28307 x += end->pixel_width;
28308 ++end;
28309 }
28310 /* Scan the rest of the glyph row from the end, looking for the
28311 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28312 DISP_STRING, or whose position is between START_CHARPOS
28313 and END_CHARPOS */
28314 for ( ;
28315 end < glyph
28316 && !INTEGERP (end->object)
28317 && !EQ (end->object, disp_string)
28318 && !(BUFFERP (end->object)
28319 && (end->charpos >= start_charpos
28320 && end->charpos < end_charpos));
28321 ++end)
28322 {
28323 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28324 are present at buffer positions between START_CHARPOS and
28325 END_CHARPOS, or if they come from an overlay. */
28326 if (EQ (end->object, before_string))
28327 {
28328 pos = string_buffer_position (before_string, start_charpos);
28329 if (!pos || (pos >= start_charpos && pos < end_charpos))
28330 break;
28331 }
28332 else if (EQ (end->object, after_string))
28333 {
28334 pos = string_buffer_position (after_string, end_charpos);
28335 if (!pos || (pos >= start_charpos && pos < end_charpos))
28336 break;
28337 }
28338 x += end->pixel_width;
28339 }
28340 /* If we exited the above loop because we arrived at the last
28341 glyph of the row, and its buffer position is still not in
28342 range, it means the last character in range is the preceding
28343 newline. Bump the end column and x values to get past the
28344 last glyph. */
28345 if (end == glyph
28346 && BUFFERP (end->object)
28347 && (end->charpos < start_charpos
28348 || end->charpos >= end_charpos))
28349 {
28350 x += end->pixel_width;
28351 ++end;
28352 }
28353 hlinfo->mouse_face_end_x = x;
28354 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
28355 }
28356
28357 hlinfo->mouse_face_window = window;
28358 hlinfo->mouse_face_face_id
28359 = face_at_buffer_position (w, mouse_charpos, &ignore,
28360 mouse_charpos + 1,
28361 !hlinfo->mouse_face_hidden, -1);
28362 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28363 }
28364
28365 /* The following function is not used anymore (replaced with
28366 mouse_face_from_string_pos), but I leave it here for the time
28367 being, in case someone would. */
28368
28369 #if 0 /* not used */
28370
28371 /* Find the position of the glyph for position POS in OBJECT in
28372 window W's current matrix, and return in *X, *Y the pixel
28373 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
28374
28375 RIGHT_P non-zero means return the position of the right edge of the
28376 glyph, RIGHT_P zero means return the left edge position.
28377
28378 If no glyph for POS exists in the matrix, return the position of
28379 the glyph with the next smaller position that is in the matrix, if
28380 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
28381 exists in the matrix, return the position of the glyph with the
28382 next larger position in OBJECT.
28383
28384 Value is non-zero if a glyph was found. */
28385
28386 static int
28387 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
28388 int *hpos, int *vpos, int *x, int *y, int right_p)
28389 {
28390 int yb = window_text_bottom_y (w);
28391 struct glyph_row *r;
28392 struct glyph *best_glyph = NULL;
28393 struct glyph_row *best_row = NULL;
28394 int best_x = 0;
28395
28396 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28397 r->enabled_p && r->y < yb;
28398 ++r)
28399 {
28400 struct glyph *g = r->glyphs[TEXT_AREA];
28401 struct glyph *e = g + r->used[TEXT_AREA];
28402 int gx;
28403
28404 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
28405 if (EQ (g->object, object))
28406 {
28407 if (g->charpos == pos)
28408 {
28409 best_glyph = g;
28410 best_x = gx;
28411 best_row = r;
28412 goto found;
28413 }
28414 else if (best_glyph == NULL
28415 || ((eabs (g->charpos - pos)
28416 < eabs (best_glyph->charpos - pos))
28417 && (right_p
28418 ? g->charpos < pos
28419 : g->charpos > pos)))
28420 {
28421 best_glyph = g;
28422 best_x = gx;
28423 best_row = r;
28424 }
28425 }
28426 }
28427
28428 found:
28429
28430 if (best_glyph)
28431 {
28432 *x = best_x;
28433 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
28434
28435 if (right_p)
28436 {
28437 *x += best_glyph->pixel_width;
28438 ++*hpos;
28439 }
28440
28441 *y = best_row->y;
28442 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
28443 }
28444
28445 return best_glyph != NULL;
28446 }
28447 #endif /* not used */
28448
28449 /* Find the positions of the first and the last glyphs in window W's
28450 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
28451 (assumed to be a string), and return in HLINFO's mouse_face_*
28452 members the pixel and column/row coordinates of those glyphs. */
28453
28454 static void
28455 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
28456 Lisp_Object object,
28457 ptrdiff_t startpos, ptrdiff_t endpos)
28458 {
28459 int yb = window_text_bottom_y (w);
28460 struct glyph_row *r;
28461 struct glyph *g, *e;
28462 int gx;
28463 int found = 0;
28464
28465 /* Find the glyph row with at least one position in the range
28466 [STARTPOS..ENDPOS), and the first glyph in that row whose
28467 position belongs to that range. */
28468 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28469 r->enabled_p && r->y < yb;
28470 ++r)
28471 {
28472 if (!r->reversed_p)
28473 {
28474 g = r->glyphs[TEXT_AREA];
28475 e = g + r->used[TEXT_AREA];
28476 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
28477 if (EQ (g->object, object)
28478 && startpos <= g->charpos && g->charpos < endpos)
28479 {
28480 hlinfo->mouse_face_beg_row
28481 = MATRIX_ROW_VPOS (r, w->current_matrix);
28482 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
28483 hlinfo->mouse_face_beg_x = gx;
28484 found = 1;
28485 break;
28486 }
28487 }
28488 else
28489 {
28490 struct glyph *g1;
28491
28492 e = r->glyphs[TEXT_AREA];
28493 g = e + r->used[TEXT_AREA];
28494 for ( ; g > e; --g)
28495 if (EQ ((g-1)->object, object)
28496 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
28497 {
28498 hlinfo->mouse_face_beg_row
28499 = MATRIX_ROW_VPOS (r, w->current_matrix);
28500 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
28501 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
28502 gx += g1->pixel_width;
28503 hlinfo->mouse_face_beg_x = gx;
28504 found = 1;
28505 break;
28506 }
28507 }
28508 if (found)
28509 break;
28510 }
28511
28512 if (!found)
28513 return;
28514
28515 /* Starting with the next row, look for the first row which does NOT
28516 include any glyphs whose positions are in the range. */
28517 for (++r; r->enabled_p && r->y < yb; ++r)
28518 {
28519 g = r->glyphs[TEXT_AREA];
28520 e = g + r->used[TEXT_AREA];
28521 found = 0;
28522 for ( ; g < e; ++g)
28523 if (EQ (g->object, object)
28524 && startpos <= g->charpos && g->charpos < endpos)
28525 {
28526 found = 1;
28527 break;
28528 }
28529 if (!found)
28530 break;
28531 }
28532
28533 /* The highlighted region ends on the previous row. */
28534 r--;
28535
28536 /* Set the end row. */
28537 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
28538
28539 /* Compute and set the end column and the end column's horizontal
28540 pixel coordinate. */
28541 if (!r->reversed_p)
28542 {
28543 g = r->glyphs[TEXT_AREA];
28544 e = g + r->used[TEXT_AREA];
28545 for ( ; e > g; --e)
28546 if (EQ ((e-1)->object, object)
28547 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
28548 break;
28549 hlinfo->mouse_face_end_col = e - g;
28550
28551 for (gx = r->x; g < e; ++g)
28552 gx += g->pixel_width;
28553 hlinfo->mouse_face_end_x = gx;
28554 }
28555 else
28556 {
28557 e = r->glyphs[TEXT_AREA];
28558 g = e + r->used[TEXT_AREA];
28559 for (gx = r->x ; e < g; ++e)
28560 {
28561 if (EQ (e->object, object)
28562 && startpos <= e->charpos && e->charpos < endpos)
28563 break;
28564 gx += e->pixel_width;
28565 }
28566 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
28567 hlinfo->mouse_face_end_x = gx;
28568 }
28569 }
28570
28571 #ifdef HAVE_WINDOW_SYSTEM
28572
28573 /* See if position X, Y is within a hot-spot of an image. */
28574
28575 static int
28576 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
28577 {
28578 if (!CONSP (hot_spot))
28579 return 0;
28580
28581 if (EQ (XCAR (hot_spot), Qrect))
28582 {
28583 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
28584 Lisp_Object rect = XCDR (hot_spot);
28585 Lisp_Object tem;
28586 if (!CONSP (rect))
28587 return 0;
28588 if (!CONSP (XCAR (rect)))
28589 return 0;
28590 if (!CONSP (XCDR (rect)))
28591 return 0;
28592 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
28593 return 0;
28594 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
28595 return 0;
28596 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
28597 return 0;
28598 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
28599 return 0;
28600 return 1;
28601 }
28602 else if (EQ (XCAR (hot_spot), Qcircle))
28603 {
28604 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
28605 Lisp_Object circ = XCDR (hot_spot);
28606 Lisp_Object lr, lx0, ly0;
28607 if (CONSP (circ)
28608 && CONSP (XCAR (circ))
28609 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
28610 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
28611 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
28612 {
28613 double r = XFLOATINT (lr);
28614 double dx = XINT (lx0) - x;
28615 double dy = XINT (ly0) - y;
28616 return (dx * dx + dy * dy <= r * r);
28617 }
28618 }
28619 else if (EQ (XCAR (hot_spot), Qpoly))
28620 {
28621 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
28622 if (VECTORP (XCDR (hot_spot)))
28623 {
28624 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
28625 Lisp_Object *poly = v->contents;
28626 ptrdiff_t n = v->header.size;
28627 ptrdiff_t i;
28628 int inside = 0;
28629 Lisp_Object lx, ly;
28630 int x0, y0;
28631
28632 /* Need an even number of coordinates, and at least 3 edges. */
28633 if (n < 6 || n & 1)
28634 return 0;
28635
28636 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
28637 If count is odd, we are inside polygon. Pixels on edges
28638 may or may not be included depending on actual geometry of the
28639 polygon. */
28640 if ((lx = poly[n-2], !INTEGERP (lx))
28641 || (ly = poly[n-1], !INTEGERP (lx)))
28642 return 0;
28643 x0 = XINT (lx), y0 = XINT (ly);
28644 for (i = 0; i < n; i += 2)
28645 {
28646 int x1 = x0, y1 = y0;
28647 if ((lx = poly[i], !INTEGERP (lx))
28648 || (ly = poly[i+1], !INTEGERP (ly)))
28649 return 0;
28650 x0 = XINT (lx), y0 = XINT (ly);
28651
28652 /* Does this segment cross the X line? */
28653 if (x0 >= x)
28654 {
28655 if (x1 >= x)
28656 continue;
28657 }
28658 else if (x1 < x)
28659 continue;
28660 if (y > y0 && y > y1)
28661 continue;
28662 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
28663 inside = !inside;
28664 }
28665 return inside;
28666 }
28667 }
28668 return 0;
28669 }
28670
28671 Lisp_Object
28672 find_hot_spot (Lisp_Object map, int x, int y)
28673 {
28674 while (CONSP (map))
28675 {
28676 if (CONSP (XCAR (map))
28677 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
28678 return XCAR (map);
28679 map = XCDR (map);
28680 }
28681
28682 return Qnil;
28683 }
28684
28685 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
28686 3, 3, 0,
28687 doc: /* Lookup in image map MAP coordinates X and Y.
28688 An image map is an alist where each element has the format (AREA ID PLIST).
28689 An AREA is specified as either a rectangle, a circle, or a polygon:
28690 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
28691 pixel coordinates of the upper left and bottom right corners.
28692 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
28693 and the radius of the circle; r may be a float or integer.
28694 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
28695 vector describes one corner in the polygon.
28696 Returns the alist element for the first matching AREA in MAP. */)
28697 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
28698 {
28699 if (NILP (map))
28700 return Qnil;
28701
28702 CHECK_NUMBER (x);
28703 CHECK_NUMBER (y);
28704
28705 return find_hot_spot (map,
28706 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
28707 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
28708 }
28709
28710
28711 /* Display frame CURSOR, optionally using shape defined by POINTER. */
28712 static void
28713 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
28714 {
28715 /* Do not change cursor shape while dragging mouse. */
28716 if (!NILP (do_mouse_tracking))
28717 return;
28718
28719 if (!NILP (pointer))
28720 {
28721 if (EQ (pointer, Qarrow))
28722 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28723 else if (EQ (pointer, Qhand))
28724 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
28725 else if (EQ (pointer, Qtext))
28726 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28727 else if (EQ (pointer, intern ("hdrag")))
28728 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28729 else if (EQ (pointer, intern ("nhdrag")))
28730 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
28731 #ifdef HAVE_X_WINDOWS
28732 else if (EQ (pointer, intern ("vdrag")))
28733 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
28734 #endif
28735 else if (EQ (pointer, intern ("hourglass")))
28736 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
28737 else if (EQ (pointer, Qmodeline))
28738 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
28739 else
28740 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28741 }
28742
28743 if (cursor != No_Cursor)
28744 FRAME_RIF (f)->define_frame_cursor (f, cursor);
28745 }
28746
28747 #endif /* HAVE_WINDOW_SYSTEM */
28748
28749 /* Take proper action when mouse has moved to the mode or header line
28750 or marginal area AREA of window W, x-position X and y-position Y.
28751 X is relative to the start of the text display area of W, so the
28752 width of bitmap areas and scroll bars must be subtracted to get a
28753 position relative to the start of the mode line. */
28754
28755 static void
28756 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
28757 enum window_part area)
28758 {
28759 struct window *w = XWINDOW (window);
28760 struct frame *f = XFRAME (w->frame);
28761 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28762 #ifdef HAVE_WINDOW_SYSTEM
28763 Display_Info *dpyinfo;
28764 #endif
28765 Cursor cursor = No_Cursor;
28766 Lisp_Object pointer = Qnil;
28767 int dx, dy, width, height;
28768 ptrdiff_t charpos;
28769 Lisp_Object string, object = Qnil;
28770 Lisp_Object pos IF_LINT (= Qnil), help;
28771
28772 Lisp_Object mouse_face;
28773 int original_x_pixel = x;
28774 struct glyph * glyph = NULL, * row_start_glyph = NULL;
28775 struct glyph_row *row IF_LINT (= 0);
28776
28777 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
28778 {
28779 int x0;
28780 struct glyph *end;
28781
28782 /* Kludge alert: mode_line_string takes X/Y in pixels, but
28783 returns them in row/column units! */
28784 string = mode_line_string (w, area, &x, &y, &charpos,
28785 &object, &dx, &dy, &width, &height);
28786
28787 row = (area == ON_MODE_LINE
28788 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
28789 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
28790
28791 /* Find the glyph under the mouse pointer. */
28792 if (row->mode_line_p && row->enabled_p)
28793 {
28794 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
28795 end = glyph + row->used[TEXT_AREA];
28796
28797 for (x0 = original_x_pixel;
28798 glyph < end && x0 >= glyph->pixel_width;
28799 ++glyph)
28800 x0 -= glyph->pixel_width;
28801
28802 if (glyph >= end)
28803 glyph = NULL;
28804 }
28805 }
28806 else
28807 {
28808 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
28809 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
28810 returns them in row/column units! */
28811 string = marginal_area_string (w, area, &x, &y, &charpos,
28812 &object, &dx, &dy, &width, &height);
28813 }
28814
28815 help = Qnil;
28816
28817 #ifdef HAVE_WINDOW_SYSTEM
28818 if (IMAGEP (object))
28819 {
28820 Lisp_Object image_map, hotspot;
28821 if ((image_map = Fplist_get (XCDR (object), QCmap),
28822 !NILP (image_map))
28823 && (hotspot = find_hot_spot (image_map, dx, dy),
28824 CONSP (hotspot))
28825 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28826 {
28827 Lisp_Object plist;
28828
28829 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
28830 If so, we could look for mouse-enter, mouse-leave
28831 properties in PLIST (and do something...). */
28832 hotspot = XCDR (hotspot);
28833 if (CONSP (hotspot)
28834 && (plist = XCAR (hotspot), CONSP (plist)))
28835 {
28836 pointer = Fplist_get (plist, Qpointer);
28837 if (NILP (pointer))
28838 pointer = Qhand;
28839 help = Fplist_get (plist, Qhelp_echo);
28840 if (!NILP (help))
28841 {
28842 help_echo_string = help;
28843 XSETWINDOW (help_echo_window, w);
28844 help_echo_object = w->contents;
28845 help_echo_pos = charpos;
28846 }
28847 }
28848 }
28849 if (NILP (pointer))
28850 pointer = Fplist_get (XCDR (object), QCpointer);
28851 }
28852 #endif /* HAVE_WINDOW_SYSTEM */
28853
28854 if (STRINGP (string))
28855 pos = make_number (charpos);
28856
28857 /* Set the help text and mouse pointer. If the mouse is on a part
28858 of the mode line without any text (e.g. past the right edge of
28859 the mode line text), use the default help text and pointer. */
28860 if (STRINGP (string) || area == ON_MODE_LINE)
28861 {
28862 /* Arrange to display the help by setting the global variables
28863 help_echo_string, help_echo_object, and help_echo_pos. */
28864 if (NILP (help))
28865 {
28866 if (STRINGP (string))
28867 help = Fget_text_property (pos, Qhelp_echo, string);
28868
28869 if (!NILP (help))
28870 {
28871 help_echo_string = help;
28872 XSETWINDOW (help_echo_window, w);
28873 help_echo_object = string;
28874 help_echo_pos = charpos;
28875 }
28876 else if (area == ON_MODE_LINE)
28877 {
28878 Lisp_Object default_help
28879 = buffer_local_value (Qmode_line_default_help_echo,
28880 w->contents);
28881
28882 if (STRINGP (default_help))
28883 {
28884 help_echo_string = default_help;
28885 XSETWINDOW (help_echo_window, w);
28886 help_echo_object = Qnil;
28887 help_echo_pos = -1;
28888 }
28889 }
28890 }
28891
28892 #ifdef HAVE_WINDOW_SYSTEM
28893 /* Change the mouse pointer according to what is under it. */
28894 if (FRAME_WINDOW_P (f))
28895 {
28896 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
28897 || minibuf_level
28898 || NILP (Vresize_mini_windows));
28899
28900 dpyinfo = FRAME_DISPLAY_INFO (f);
28901 if (STRINGP (string))
28902 {
28903 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28904
28905 if (NILP (pointer))
28906 pointer = Fget_text_property (pos, Qpointer, string);
28907
28908 /* Change the mouse pointer according to what is under X/Y. */
28909 if (NILP (pointer)
28910 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
28911 {
28912 Lisp_Object map;
28913 map = Fget_text_property (pos, Qlocal_map, string);
28914 if (!KEYMAPP (map))
28915 map = Fget_text_property (pos, Qkeymap, string);
28916 if (!KEYMAPP (map) && draggable)
28917 cursor = dpyinfo->vertical_scroll_bar_cursor;
28918 }
28919 }
28920 else if (draggable)
28921 /* Default mode-line pointer. */
28922 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
28923 }
28924 #endif
28925 }
28926
28927 /* Change the mouse face according to what is under X/Y. */
28928 if (STRINGP (string))
28929 {
28930 mouse_face = Fget_text_property (pos, Qmouse_face, string);
28931 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
28932 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28933 && glyph)
28934 {
28935 Lisp_Object b, e;
28936
28937 struct glyph * tmp_glyph;
28938
28939 int gpos;
28940 int gseq_length;
28941 int total_pixel_width;
28942 ptrdiff_t begpos, endpos, ignore;
28943
28944 int vpos, hpos;
28945
28946 b = Fprevious_single_property_change (make_number (charpos + 1),
28947 Qmouse_face, string, Qnil);
28948 if (NILP (b))
28949 begpos = 0;
28950 else
28951 begpos = XINT (b);
28952
28953 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
28954 if (NILP (e))
28955 endpos = SCHARS (string);
28956 else
28957 endpos = XINT (e);
28958
28959 /* Calculate the glyph position GPOS of GLYPH in the
28960 displayed string, relative to the beginning of the
28961 highlighted part of the string.
28962
28963 Note: GPOS is different from CHARPOS. CHARPOS is the
28964 position of GLYPH in the internal string object. A mode
28965 line string format has structures which are converted to
28966 a flattened string by the Emacs Lisp interpreter. The
28967 internal string is an element of those structures. The
28968 displayed string is the flattened string. */
28969 tmp_glyph = row_start_glyph;
28970 while (tmp_glyph < glyph
28971 && (!(EQ (tmp_glyph->object, glyph->object)
28972 && begpos <= tmp_glyph->charpos
28973 && tmp_glyph->charpos < endpos)))
28974 tmp_glyph++;
28975 gpos = glyph - tmp_glyph;
28976
28977 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
28978 the highlighted part of the displayed string to which
28979 GLYPH belongs. Note: GSEQ_LENGTH is different from
28980 SCHARS (STRING), because the latter returns the length of
28981 the internal string. */
28982 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
28983 tmp_glyph > glyph
28984 && (!(EQ (tmp_glyph->object, glyph->object)
28985 && begpos <= tmp_glyph->charpos
28986 && tmp_glyph->charpos < endpos));
28987 tmp_glyph--)
28988 ;
28989 gseq_length = gpos + (tmp_glyph - glyph) + 1;
28990
28991 /* Calculate the total pixel width of all the glyphs between
28992 the beginning of the highlighted area and GLYPH. */
28993 total_pixel_width = 0;
28994 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
28995 total_pixel_width += tmp_glyph->pixel_width;
28996
28997 /* Pre calculation of re-rendering position. Note: X is in
28998 column units here, after the call to mode_line_string or
28999 marginal_area_string. */
29000 hpos = x - gpos;
29001 vpos = (area == ON_MODE_LINE
29002 ? (w->current_matrix)->nrows - 1
29003 : 0);
29004
29005 /* If GLYPH's position is included in the region that is
29006 already drawn in mouse face, we have nothing to do. */
29007 if ( EQ (window, hlinfo->mouse_face_window)
29008 && (!row->reversed_p
29009 ? (hlinfo->mouse_face_beg_col <= hpos
29010 && hpos < hlinfo->mouse_face_end_col)
29011 /* In R2L rows we swap BEG and END, see below. */
29012 : (hlinfo->mouse_face_end_col <= hpos
29013 && hpos < hlinfo->mouse_face_beg_col))
29014 && hlinfo->mouse_face_beg_row == vpos )
29015 return;
29016
29017 if (clear_mouse_face (hlinfo))
29018 cursor = No_Cursor;
29019
29020 if (!row->reversed_p)
29021 {
29022 hlinfo->mouse_face_beg_col = hpos;
29023 hlinfo->mouse_face_beg_x = original_x_pixel
29024 - (total_pixel_width + dx);
29025 hlinfo->mouse_face_end_col = hpos + gseq_length;
29026 hlinfo->mouse_face_end_x = 0;
29027 }
29028 else
29029 {
29030 /* In R2L rows, show_mouse_face expects BEG and END
29031 coordinates to be swapped. */
29032 hlinfo->mouse_face_end_col = hpos;
29033 hlinfo->mouse_face_end_x = original_x_pixel
29034 - (total_pixel_width + dx);
29035 hlinfo->mouse_face_beg_col = hpos + gseq_length;
29036 hlinfo->mouse_face_beg_x = 0;
29037 }
29038
29039 hlinfo->mouse_face_beg_row = vpos;
29040 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
29041 hlinfo->mouse_face_past_end = 0;
29042 hlinfo->mouse_face_window = window;
29043
29044 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
29045 charpos,
29046 0, &ignore,
29047 glyph->face_id,
29048 1);
29049 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29050
29051 if (NILP (pointer))
29052 pointer = Qhand;
29053 }
29054 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
29055 clear_mouse_face (hlinfo);
29056 }
29057 #ifdef HAVE_WINDOW_SYSTEM
29058 if (FRAME_WINDOW_P (f))
29059 define_frame_cursor1 (f, cursor, pointer);
29060 #endif
29061 }
29062
29063
29064 /* EXPORT:
29065 Take proper action when the mouse has moved to position X, Y on
29066 frame F with regards to highlighting portions of display that have
29067 mouse-face properties. Also de-highlight portions of display where
29068 the mouse was before, set the mouse pointer shape as appropriate
29069 for the mouse coordinates, and activate help echo (tooltips).
29070 X and Y can be negative or out of range. */
29071
29072 void
29073 note_mouse_highlight (struct frame *f, int x, int y)
29074 {
29075 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29076 enum window_part part = ON_NOTHING;
29077 Lisp_Object window;
29078 struct window *w;
29079 Cursor cursor = No_Cursor;
29080 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
29081 struct buffer *b;
29082
29083 /* When a menu is active, don't highlight because this looks odd. */
29084 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
29085 if (popup_activated ())
29086 return;
29087 #endif
29088
29089 if (!f->glyphs_initialized_p
29090 || f->pointer_invisible)
29091 return;
29092
29093 hlinfo->mouse_face_mouse_x = x;
29094 hlinfo->mouse_face_mouse_y = y;
29095 hlinfo->mouse_face_mouse_frame = f;
29096
29097 if (hlinfo->mouse_face_defer)
29098 return;
29099
29100 /* Which window is that in? */
29101 window = window_from_coordinates (f, x, y, &part, 1);
29102
29103 /* If displaying active text in another window, clear that. */
29104 if (! EQ (window, hlinfo->mouse_face_window)
29105 /* Also clear if we move out of text area in same window. */
29106 || (!NILP (hlinfo->mouse_face_window)
29107 && !NILP (window)
29108 && part != ON_TEXT
29109 && part != ON_MODE_LINE
29110 && part != ON_HEADER_LINE))
29111 clear_mouse_face (hlinfo);
29112
29113 /* Not on a window -> return. */
29114 if (!WINDOWP (window))
29115 return;
29116
29117 /* Reset help_echo_string. It will get recomputed below. */
29118 help_echo_string = Qnil;
29119
29120 /* Convert to window-relative pixel coordinates. */
29121 w = XWINDOW (window);
29122 frame_to_window_pixel_xy (w, &x, &y);
29123
29124 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
29125 /* Handle tool-bar window differently since it doesn't display a
29126 buffer. */
29127 if (EQ (window, f->tool_bar_window))
29128 {
29129 note_tool_bar_highlight (f, x, y);
29130 return;
29131 }
29132 #endif
29133
29134 /* Mouse is on the mode, header line or margin? */
29135 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
29136 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29137 {
29138 note_mode_line_or_margin_highlight (window, x, y, part);
29139
29140 #ifdef HAVE_WINDOW_SYSTEM
29141 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29142 {
29143 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29144 /* Show non-text cursor (Bug#16647). */
29145 goto set_cursor;
29146 }
29147 else
29148 #endif
29149 return;
29150 }
29151
29152 #ifdef HAVE_WINDOW_SYSTEM
29153 if (part == ON_VERTICAL_BORDER)
29154 {
29155 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29156 help_echo_string = build_string ("drag-mouse-1: resize");
29157 }
29158 else if (part == ON_RIGHT_DIVIDER)
29159 {
29160 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29161 help_echo_string = build_string ("drag-mouse-1: resize");
29162 }
29163 else if (part == ON_BOTTOM_DIVIDER)
29164 if (! WINDOW_BOTTOMMOST_P (w)
29165 || minibuf_level
29166 || NILP (Vresize_mini_windows))
29167 {
29168 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
29169 help_echo_string = build_string ("drag-mouse-1: resize");
29170 }
29171 else
29172 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29173 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
29174 || part == ON_VERTICAL_SCROLL_BAR
29175 || part == ON_HORIZONTAL_SCROLL_BAR)
29176 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29177 else
29178 cursor = FRAME_X_OUTPUT (f)->text_cursor;
29179 #endif
29180
29181 /* Are we in a window whose display is up to date?
29182 And verify the buffer's text has not changed. */
29183 b = XBUFFER (w->contents);
29184 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
29185 {
29186 int hpos, vpos, dx, dy, area = LAST_AREA;
29187 ptrdiff_t pos;
29188 struct glyph *glyph;
29189 Lisp_Object object;
29190 Lisp_Object mouse_face = Qnil, position;
29191 Lisp_Object *overlay_vec = NULL;
29192 ptrdiff_t i, noverlays;
29193 struct buffer *obuf;
29194 ptrdiff_t obegv, ozv;
29195 int same_region;
29196
29197 /* Find the glyph under X/Y. */
29198 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
29199
29200 #ifdef HAVE_WINDOW_SYSTEM
29201 /* Look for :pointer property on image. */
29202 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29203 {
29204 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
29205 if (img != NULL && IMAGEP (img->spec))
29206 {
29207 Lisp_Object image_map, hotspot;
29208 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
29209 !NILP (image_map))
29210 && (hotspot = find_hot_spot (image_map,
29211 glyph->slice.img.x + dx,
29212 glyph->slice.img.y + dy),
29213 CONSP (hotspot))
29214 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
29215 {
29216 Lisp_Object plist;
29217
29218 /* Could check XCAR (hotspot) to see if we enter/leave
29219 this hot-spot.
29220 If so, we could look for mouse-enter, mouse-leave
29221 properties in PLIST (and do something...). */
29222 hotspot = XCDR (hotspot);
29223 if (CONSP (hotspot)
29224 && (plist = XCAR (hotspot), CONSP (plist)))
29225 {
29226 pointer = Fplist_get (plist, Qpointer);
29227 if (NILP (pointer))
29228 pointer = Qhand;
29229 help_echo_string = Fplist_get (plist, Qhelp_echo);
29230 if (!NILP (help_echo_string))
29231 {
29232 help_echo_window = window;
29233 help_echo_object = glyph->object;
29234 help_echo_pos = glyph->charpos;
29235 }
29236 }
29237 }
29238 if (NILP (pointer))
29239 pointer = Fplist_get (XCDR (img->spec), QCpointer);
29240 }
29241 }
29242 #endif /* HAVE_WINDOW_SYSTEM */
29243
29244 /* Clear mouse face if X/Y not over text. */
29245 if (glyph == NULL
29246 || area != TEXT_AREA
29247 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
29248 /* Glyph's OBJECT is an integer for glyphs inserted by the
29249 display engine for its internal purposes, like truncation
29250 and continuation glyphs and blanks beyond the end of
29251 line's text on text terminals. If we are over such a
29252 glyph, we are not over any text. */
29253 || INTEGERP (glyph->object)
29254 /* R2L rows have a stretch glyph at their front, which
29255 stands for no text, whereas L2R rows have no glyphs at
29256 all beyond the end of text. Treat such stretch glyphs
29257 like we do with NULL glyphs in L2R rows. */
29258 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
29259 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
29260 && glyph->type == STRETCH_GLYPH
29261 && glyph->avoid_cursor_p))
29262 {
29263 if (clear_mouse_face (hlinfo))
29264 cursor = No_Cursor;
29265 #ifdef HAVE_WINDOW_SYSTEM
29266 if (FRAME_WINDOW_P (f) && NILP (pointer))
29267 {
29268 if (area != TEXT_AREA)
29269 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29270 else
29271 pointer = Vvoid_text_area_pointer;
29272 }
29273 #endif
29274 goto set_cursor;
29275 }
29276
29277 pos = glyph->charpos;
29278 object = glyph->object;
29279 if (!STRINGP (object) && !BUFFERP (object))
29280 goto set_cursor;
29281
29282 /* If we get an out-of-range value, return now; avoid an error. */
29283 if (BUFFERP (object) && pos > BUF_Z (b))
29284 goto set_cursor;
29285
29286 /* Make the window's buffer temporarily current for
29287 overlays_at and compute_char_face. */
29288 obuf = current_buffer;
29289 current_buffer = b;
29290 obegv = BEGV;
29291 ozv = ZV;
29292 BEGV = BEG;
29293 ZV = Z;
29294
29295 /* Is this char mouse-active or does it have help-echo? */
29296 position = make_number (pos);
29297
29298 USE_SAFE_ALLOCA;
29299
29300 if (BUFFERP (object))
29301 {
29302 /* Put all the overlays we want in a vector in overlay_vec. */
29303 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
29304 /* Sort overlays into increasing priority order. */
29305 noverlays = sort_overlays (overlay_vec, noverlays, w);
29306 }
29307 else
29308 noverlays = 0;
29309
29310 if (NILP (Vmouse_highlight))
29311 {
29312 clear_mouse_face (hlinfo);
29313 goto check_help_echo;
29314 }
29315
29316 same_region = coords_in_mouse_face_p (w, hpos, vpos);
29317
29318 if (same_region)
29319 cursor = No_Cursor;
29320
29321 /* Check mouse-face highlighting. */
29322 if (! same_region
29323 /* If there exists an overlay with mouse-face overlapping
29324 the one we are currently highlighting, we have to
29325 check if we enter the overlapping overlay, and then
29326 highlight only that. */
29327 || (OVERLAYP (hlinfo->mouse_face_overlay)
29328 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
29329 {
29330 /* Find the highest priority overlay with a mouse-face. */
29331 Lisp_Object overlay = Qnil;
29332 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
29333 {
29334 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
29335 if (!NILP (mouse_face))
29336 overlay = overlay_vec[i];
29337 }
29338
29339 /* If we're highlighting the same overlay as before, there's
29340 no need to do that again. */
29341 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
29342 goto check_help_echo;
29343 hlinfo->mouse_face_overlay = overlay;
29344
29345 /* Clear the display of the old active region, if any. */
29346 if (clear_mouse_face (hlinfo))
29347 cursor = No_Cursor;
29348
29349 /* If no overlay applies, get a text property. */
29350 if (NILP (overlay))
29351 mouse_face = Fget_text_property (position, Qmouse_face, object);
29352
29353 /* Next, compute the bounds of the mouse highlighting and
29354 display it. */
29355 if (!NILP (mouse_face) && STRINGP (object))
29356 {
29357 /* The mouse-highlighting comes from a display string
29358 with a mouse-face. */
29359 Lisp_Object s, e;
29360 ptrdiff_t ignore;
29361
29362 s = Fprevious_single_property_change
29363 (make_number (pos + 1), Qmouse_face, object, Qnil);
29364 e = Fnext_single_property_change
29365 (position, Qmouse_face, object, Qnil);
29366 if (NILP (s))
29367 s = make_number (0);
29368 if (NILP (e))
29369 e = make_number (SCHARS (object));
29370 mouse_face_from_string_pos (w, hlinfo, object,
29371 XINT (s), XINT (e));
29372 hlinfo->mouse_face_past_end = 0;
29373 hlinfo->mouse_face_window = window;
29374 hlinfo->mouse_face_face_id
29375 = face_at_string_position (w, object, pos, 0, &ignore,
29376 glyph->face_id, 1);
29377 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29378 cursor = No_Cursor;
29379 }
29380 else
29381 {
29382 /* The mouse-highlighting, if any, comes from an overlay
29383 or text property in the buffer. */
29384 Lisp_Object buffer IF_LINT (= Qnil);
29385 Lisp_Object disp_string IF_LINT (= Qnil);
29386
29387 if (STRINGP (object))
29388 {
29389 /* If we are on a display string with no mouse-face,
29390 check if the text under it has one. */
29391 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
29392 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29393 pos = string_buffer_position (object, start);
29394 if (pos > 0)
29395 {
29396 mouse_face = get_char_property_and_overlay
29397 (make_number (pos), Qmouse_face, w->contents, &overlay);
29398 buffer = w->contents;
29399 disp_string = object;
29400 }
29401 }
29402 else
29403 {
29404 buffer = object;
29405 disp_string = Qnil;
29406 }
29407
29408 if (!NILP (mouse_face))
29409 {
29410 Lisp_Object before, after;
29411 Lisp_Object before_string, after_string;
29412 /* To correctly find the limits of mouse highlight
29413 in a bidi-reordered buffer, we must not use the
29414 optimization of limiting the search in
29415 previous-single-property-change and
29416 next-single-property-change, because
29417 rows_from_pos_range needs the real start and end
29418 positions to DTRT in this case. That's because
29419 the first row visible in a window does not
29420 necessarily display the character whose position
29421 is the smallest. */
29422 Lisp_Object lim1
29423 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
29424 ? Fmarker_position (w->start)
29425 : Qnil;
29426 Lisp_Object lim2
29427 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
29428 ? make_number (BUF_Z (XBUFFER (buffer))
29429 - w->window_end_pos)
29430 : Qnil;
29431
29432 if (NILP (overlay))
29433 {
29434 /* Handle the text property case. */
29435 before = Fprevious_single_property_change
29436 (make_number (pos + 1), Qmouse_face, buffer, lim1);
29437 after = Fnext_single_property_change
29438 (make_number (pos), Qmouse_face, buffer, lim2);
29439 before_string = after_string = Qnil;
29440 }
29441 else
29442 {
29443 /* Handle the overlay case. */
29444 before = Foverlay_start (overlay);
29445 after = Foverlay_end (overlay);
29446 before_string = Foverlay_get (overlay, Qbefore_string);
29447 after_string = Foverlay_get (overlay, Qafter_string);
29448
29449 if (!STRINGP (before_string)) before_string = Qnil;
29450 if (!STRINGP (after_string)) after_string = Qnil;
29451 }
29452
29453 mouse_face_from_buffer_pos (window, hlinfo, pos,
29454 NILP (before)
29455 ? 1
29456 : XFASTINT (before),
29457 NILP (after)
29458 ? BUF_Z (XBUFFER (buffer))
29459 : XFASTINT (after),
29460 before_string, after_string,
29461 disp_string);
29462 cursor = No_Cursor;
29463 }
29464 }
29465 }
29466
29467 check_help_echo:
29468
29469 /* Look for a `help-echo' property. */
29470 if (NILP (help_echo_string)) {
29471 Lisp_Object help, overlay;
29472
29473 /* Check overlays first. */
29474 help = overlay = Qnil;
29475 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
29476 {
29477 overlay = overlay_vec[i];
29478 help = Foverlay_get (overlay, Qhelp_echo);
29479 }
29480
29481 if (!NILP (help))
29482 {
29483 help_echo_string = help;
29484 help_echo_window = window;
29485 help_echo_object = overlay;
29486 help_echo_pos = pos;
29487 }
29488 else
29489 {
29490 Lisp_Object obj = glyph->object;
29491 ptrdiff_t charpos = glyph->charpos;
29492
29493 /* Try text properties. */
29494 if (STRINGP (obj)
29495 && charpos >= 0
29496 && charpos < SCHARS (obj))
29497 {
29498 help = Fget_text_property (make_number (charpos),
29499 Qhelp_echo, obj);
29500 if (NILP (help))
29501 {
29502 /* If the string itself doesn't specify a help-echo,
29503 see if the buffer text ``under'' it does. */
29504 struct glyph_row *r
29505 = MATRIX_ROW (w->current_matrix, vpos);
29506 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29507 ptrdiff_t p = string_buffer_position (obj, start);
29508 if (p > 0)
29509 {
29510 help = Fget_char_property (make_number (p),
29511 Qhelp_echo, w->contents);
29512 if (!NILP (help))
29513 {
29514 charpos = p;
29515 obj = w->contents;
29516 }
29517 }
29518 }
29519 }
29520 else if (BUFFERP (obj)
29521 && charpos >= BEGV
29522 && charpos < ZV)
29523 help = Fget_text_property (make_number (charpos), Qhelp_echo,
29524 obj);
29525
29526 if (!NILP (help))
29527 {
29528 help_echo_string = help;
29529 help_echo_window = window;
29530 help_echo_object = obj;
29531 help_echo_pos = charpos;
29532 }
29533 }
29534 }
29535
29536 #ifdef HAVE_WINDOW_SYSTEM
29537 /* Look for a `pointer' property. */
29538 if (FRAME_WINDOW_P (f) && NILP (pointer))
29539 {
29540 /* Check overlays first. */
29541 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
29542 pointer = Foverlay_get (overlay_vec[i], Qpointer);
29543
29544 if (NILP (pointer))
29545 {
29546 Lisp_Object obj = glyph->object;
29547 ptrdiff_t charpos = glyph->charpos;
29548
29549 /* Try text properties. */
29550 if (STRINGP (obj)
29551 && charpos >= 0
29552 && charpos < SCHARS (obj))
29553 {
29554 pointer = Fget_text_property (make_number (charpos),
29555 Qpointer, obj);
29556 if (NILP (pointer))
29557 {
29558 /* If the string itself doesn't specify a pointer,
29559 see if the buffer text ``under'' it does. */
29560 struct glyph_row *r
29561 = MATRIX_ROW (w->current_matrix, vpos);
29562 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29563 ptrdiff_t p = string_buffer_position (obj, start);
29564 if (p > 0)
29565 pointer = Fget_char_property (make_number (p),
29566 Qpointer, w->contents);
29567 }
29568 }
29569 else if (BUFFERP (obj)
29570 && charpos >= BEGV
29571 && charpos < ZV)
29572 pointer = Fget_text_property (make_number (charpos),
29573 Qpointer, obj);
29574 }
29575 }
29576 #endif /* HAVE_WINDOW_SYSTEM */
29577
29578 BEGV = obegv;
29579 ZV = ozv;
29580 current_buffer = obuf;
29581 SAFE_FREE ();
29582 }
29583
29584 set_cursor:
29585
29586 #ifdef HAVE_WINDOW_SYSTEM
29587 if (FRAME_WINDOW_P (f))
29588 define_frame_cursor1 (f, cursor, pointer);
29589 #else
29590 /* This is here to prevent a compiler error, about "label at end of
29591 compound statement". */
29592 return;
29593 #endif
29594 }
29595
29596
29597 /* EXPORT for RIF:
29598 Clear any mouse-face on window W. This function is part of the
29599 redisplay interface, and is called from try_window_id and similar
29600 functions to ensure the mouse-highlight is off. */
29601
29602 void
29603 x_clear_window_mouse_face (struct window *w)
29604 {
29605 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29606 Lisp_Object window;
29607
29608 block_input ();
29609 XSETWINDOW (window, w);
29610 if (EQ (window, hlinfo->mouse_face_window))
29611 clear_mouse_face (hlinfo);
29612 unblock_input ();
29613 }
29614
29615
29616 /* EXPORT:
29617 Just discard the mouse face information for frame F, if any.
29618 This is used when the size of F is changed. */
29619
29620 void
29621 cancel_mouse_face (struct frame *f)
29622 {
29623 Lisp_Object window;
29624 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29625
29626 window = hlinfo->mouse_face_window;
29627 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
29628 reset_mouse_highlight (hlinfo);
29629 }
29630
29631
29632 \f
29633 /***********************************************************************
29634 Exposure Events
29635 ***********************************************************************/
29636
29637 #ifdef HAVE_WINDOW_SYSTEM
29638
29639 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
29640 which intersects rectangle R. R is in window-relative coordinates. */
29641
29642 static void
29643 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
29644 enum glyph_row_area area)
29645 {
29646 struct glyph *first = row->glyphs[area];
29647 struct glyph *end = row->glyphs[area] + row->used[area];
29648 struct glyph *last;
29649 int first_x, start_x, x;
29650
29651 if (area == TEXT_AREA && row->fill_line_p)
29652 /* If row extends face to end of line write the whole line. */
29653 draw_glyphs (w, 0, row, area,
29654 0, row->used[area],
29655 DRAW_NORMAL_TEXT, 0);
29656 else
29657 {
29658 /* Set START_X to the window-relative start position for drawing glyphs of
29659 AREA. The first glyph of the text area can be partially visible.
29660 The first glyphs of other areas cannot. */
29661 start_x = window_box_left_offset (w, area);
29662 x = start_x;
29663 if (area == TEXT_AREA)
29664 x += row->x;
29665
29666 /* Find the first glyph that must be redrawn. */
29667 while (first < end
29668 && x + first->pixel_width < r->x)
29669 {
29670 x += first->pixel_width;
29671 ++first;
29672 }
29673
29674 /* Find the last one. */
29675 last = first;
29676 first_x = x;
29677 while (last < end
29678 && x < r->x + r->width)
29679 {
29680 x += last->pixel_width;
29681 ++last;
29682 }
29683
29684 /* Repaint. */
29685 if (last > first)
29686 draw_glyphs (w, first_x - start_x, row, area,
29687 first - row->glyphs[area], last - row->glyphs[area],
29688 DRAW_NORMAL_TEXT, 0);
29689 }
29690 }
29691
29692
29693 /* Redraw the parts of the glyph row ROW on window W intersecting
29694 rectangle R. R is in window-relative coordinates. Value is
29695 non-zero if mouse-face was overwritten. */
29696
29697 static int
29698 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
29699 {
29700 eassert (row->enabled_p);
29701
29702 if (row->mode_line_p || w->pseudo_window_p)
29703 draw_glyphs (w, 0, row, TEXT_AREA,
29704 0, row->used[TEXT_AREA],
29705 DRAW_NORMAL_TEXT, 0);
29706 else
29707 {
29708 if (row->used[LEFT_MARGIN_AREA])
29709 expose_area (w, row, r, LEFT_MARGIN_AREA);
29710 if (row->used[TEXT_AREA])
29711 expose_area (w, row, r, TEXT_AREA);
29712 if (row->used[RIGHT_MARGIN_AREA])
29713 expose_area (w, row, r, RIGHT_MARGIN_AREA);
29714 draw_row_fringe_bitmaps (w, row);
29715 }
29716
29717 return row->mouse_face_p;
29718 }
29719
29720
29721 /* Redraw those parts of glyphs rows during expose event handling that
29722 overlap other rows. Redrawing of an exposed line writes over parts
29723 of lines overlapping that exposed line; this function fixes that.
29724
29725 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
29726 row in W's current matrix that is exposed and overlaps other rows.
29727 LAST_OVERLAPPING_ROW is the last such row. */
29728
29729 static void
29730 expose_overlaps (struct window *w,
29731 struct glyph_row *first_overlapping_row,
29732 struct glyph_row *last_overlapping_row,
29733 XRectangle *r)
29734 {
29735 struct glyph_row *row;
29736
29737 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
29738 if (row->overlapping_p)
29739 {
29740 eassert (row->enabled_p && !row->mode_line_p);
29741
29742 row->clip = r;
29743 if (row->used[LEFT_MARGIN_AREA])
29744 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
29745
29746 if (row->used[TEXT_AREA])
29747 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
29748
29749 if (row->used[RIGHT_MARGIN_AREA])
29750 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
29751 row->clip = NULL;
29752 }
29753 }
29754
29755
29756 /* Return non-zero if W's cursor intersects rectangle R. */
29757
29758 static int
29759 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
29760 {
29761 XRectangle cr, result;
29762 struct glyph *cursor_glyph;
29763 struct glyph_row *row;
29764
29765 if (w->phys_cursor.vpos >= 0
29766 && w->phys_cursor.vpos < w->current_matrix->nrows
29767 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
29768 row->enabled_p)
29769 && row->cursor_in_fringe_p)
29770 {
29771 /* Cursor is in the fringe. */
29772 cr.x = window_box_right_offset (w,
29773 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
29774 ? RIGHT_MARGIN_AREA
29775 : TEXT_AREA));
29776 cr.y = row->y;
29777 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
29778 cr.height = row->height;
29779 return x_intersect_rectangles (&cr, r, &result);
29780 }
29781
29782 cursor_glyph = get_phys_cursor_glyph (w);
29783 if (cursor_glyph)
29784 {
29785 /* r is relative to W's box, but w->phys_cursor.x is relative
29786 to left edge of W's TEXT area. Adjust it. */
29787 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
29788 cr.y = w->phys_cursor.y;
29789 cr.width = cursor_glyph->pixel_width;
29790 cr.height = w->phys_cursor_height;
29791 /* ++KFS: W32 version used W32-specific IntersectRect here, but
29792 I assume the effect is the same -- and this is portable. */
29793 return x_intersect_rectangles (&cr, r, &result);
29794 }
29795 /* If we don't understand the format, pretend we're not in the hot-spot. */
29796 return 0;
29797 }
29798
29799
29800 /* EXPORT:
29801 Draw a vertical window border to the right of window W if W doesn't
29802 have vertical scroll bars. */
29803
29804 void
29805 x_draw_vertical_border (struct window *w)
29806 {
29807 struct frame *f = XFRAME (WINDOW_FRAME (w));
29808
29809 /* We could do better, if we knew what type of scroll-bar the adjacent
29810 windows (on either side) have... But we don't :-(
29811 However, I think this works ok. ++KFS 2003-04-25 */
29812
29813 /* Redraw borders between horizontally adjacent windows. Don't
29814 do it for frames with vertical scroll bars because either the
29815 right scroll bar of a window, or the left scroll bar of its
29816 neighbor will suffice as a border. */
29817 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
29818 return;
29819
29820 /* Note: It is necessary to redraw both the left and the right
29821 borders, for when only this single window W is being
29822 redisplayed. */
29823 if (!WINDOW_RIGHTMOST_P (w)
29824 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
29825 {
29826 int x0, x1, y0, y1;
29827
29828 window_box_edges (w, &x0, &y0, &x1, &y1);
29829 y1 -= 1;
29830
29831 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
29832 x1 -= 1;
29833
29834 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
29835 }
29836
29837 if (!WINDOW_LEFTMOST_P (w)
29838 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
29839 {
29840 int x0, x1, y0, y1;
29841
29842 window_box_edges (w, &x0, &y0, &x1, &y1);
29843 y1 -= 1;
29844
29845 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
29846 x0 -= 1;
29847
29848 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
29849 }
29850 }
29851
29852
29853 /* Draw window dividers for window W. */
29854
29855 void
29856 x_draw_right_divider (struct window *w)
29857 {
29858 struct frame *f = WINDOW_XFRAME (w);
29859
29860 if (w->mini || w->pseudo_window_p)
29861 return;
29862 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
29863 {
29864 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
29865 int x1 = WINDOW_RIGHT_EDGE_X (w);
29866 int y0 = WINDOW_TOP_EDGE_Y (w);
29867 /* The bottom divider prevails. */
29868 int y1 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
29869
29870 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
29871 }
29872 }
29873
29874 static void
29875 x_draw_bottom_divider (struct window *w)
29876 {
29877 struct frame *f = XFRAME (WINDOW_FRAME (w));
29878
29879 if (w->mini || w->pseudo_window_p)
29880 return;
29881 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
29882 {
29883 int x0 = WINDOW_LEFT_EDGE_X (w);
29884 int x1 = WINDOW_RIGHT_EDGE_X (w);
29885 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
29886 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
29887
29888 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
29889 }
29890 }
29891
29892 /* Redraw the part of window W intersection rectangle FR. Pixel
29893 coordinates in FR are frame-relative. Call this function with
29894 input blocked. Value is non-zero if the exposure overwrites
29895 mouse-face. */
29896
29897 static int
29898 expose_window (struct window *w, XRectangle *fr)
29899 {
29900 struct frame *f = XFRAME (w->frame);
29901 XRectangle wr, r;
29902 int mouse_face_overwritten_p = 0;
29903
29904 /* If window is not yet fully initialized, do nothing. This can
29905 happen when toolkit scroll bars are used and a window is split.
29906 Reconfiguring the scroll bar will generate an expose for a newly
29907 created window. */
29908 if (w->current_matrix == NULL)
29909 return 0;
29910
29911 /* When we're currently updating the window, display and current
29912 matrix usually don't agree. Arrange for a thorough display
29913 later. */
29914 if (w->must_be_updated_p)
29915 {
29916 SET_FRAME_GARBAGED (f);
29917 return 0;
29918 }
29919
29920 /* Frame-relative pixel rectangle of W. */
29921 wr.x = WINDOW_LEFT_EDGE_X (w);
29922 wr.y = WINDOW_TOP_EDGE_Y (w);
29923 wr.width = WINDOW_PIXEL_WIDTH (w);
29924 wr.height = WINDOW_PIXEL_HEIGHT (w);
29925
29926 if (x_intersect_rectangles (fr, &wr, &r))
29927 {
29928 int yb = window_text_bottom_y (w);
29929 struct glyph_row *row;
29930 int cursor_cleared_p, phys_cursor_on_p;
29931 struct glyph_row *first_overlapping_row, *last_overlapping_row;
29932
29933 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
29934 r.x, r.y, r.width, r.height));
29935
29936 /* Convert to window coordinates. */
29937 r.x -= WINDOW_LEFT_EDGE_X (w);
29938 r.y -= WINDOW_TOP_EDGE_Y (w);
29939
29940 /* Turn off the cursor. */
29941 if (!w->pseudo_window_p
29942 && phys_cursor_in_rect_p (w, &r))
29943 {
29944 x_clear_cursor (w);
29945 cursor_cleared_p = 1;
29946 }
29947 else
29948 cursor_cleared_p = 0;
29949
29950 /* If the row containing the cursor extends face to end of line,
29951 then expose_area might overwrite the cursor outside the
29952 rectangle and thus notice_overwritten_cursor might clear
29953 w->phys_cursor_on_p. We remember the original value and
29954 check later if it is changed. */
29955 phys_cursor_on_p = w->phys_cursor_on_p;
29956
29957 /* Update lines intersecting rectangle R. */
29958 first_overlapping_row = last_overlapping_row = NULL;
29959 for (row = w->current_matrix->rows;
29960 row->enabled_p;
29961 ++row)
29962 {
29963 int y0 = row->y;
29964 int y1 = MATRIX_ROW_BOTTOM_Y (row);
29965
29966 if ((y0 >= r.y && y0 < r.y + r.height)
29967 || (y1 > r.y && y1 < r.y + r.height)
29968 || (r.y >= y0 && r.y < y1)
29969 || (r.y + r.height > y0 && r.y + r.height < y1))
29970 {
29971 /* A header line may be overlapping, but there is no need
29972 to fix overlapping areas for them. KFS 2005-02-12 */
29973 if (row->overlapping_p && !row->mode_line_p)
29974 {
29975 if (first_overlapping_row == NULL)
29976 first_overlapping_row = row;
29977 last_overlapping_row = row;
29978 }
29979
29980 row->clip = fr;
29981 if (expose_line (w, row, &r))
29982 mouse_face_overwritten_p = 1;
29983 row->clip = NULL;
29984 }
29985 else if (row->overlapping_p)
29986 {
29987 /* We must redraw a row overlapping the exposed area. */
29988 if (y0 < r.y
29989 ? y0 + row->phys_height > r.y
29990 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
29991 {
29992 if (first_overlapping_row == NULL)
29993 first_overlapping_row = row;
29994 last_overlapping_row = row;
29995 }
29996 }
29997
29998 if (y1 >= yb)
29999 break;
30000 }
30001
30002 /* Display the mode line if there is one. */
30003 if (WINDOW_WANTS_MODELINE_P (w)
30004 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
30005 row->enabled_p)
30006 && row->y < r.y + r.height)
30007 {
30008 if (expose_line (w, row, &r))
30009 mouse_face_overwritten_p = 1;
30010 }
30011
30012 if (!w->pseudo_window_p)
30013 {
30014 /* Fix the display of overlapping rows. */
30015 if (first_overlapping_row)
30016 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
30017 fr);
30018
30019 /* Draw border between windows. */
30020 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
30021 x_draw_right_divider (w);
30022 else
30023 x_draw_vertical_border (w);
30024
30025 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
30026 x_draw_bottom_divider (w);
30027
30028 /* Turn the cursor on again. */
30029 if (cursor_cleared_p
30030 || (phys_cursor_on_p && !w->phys_cursor_on_p))
30031 update_window_cursor (w, 1);
30032 }
30033 }
30034
30035 return mouse_face_overwritten_p;
30036 }
30037
30038
30039
30040 /* Redraw (parts) of all windows in the window tree rooted at W that
30041 intersect R. R contains frame pixel coordinates. Value is
30042 non-zero if the exposure overwrites mouse-face. */
30043
30044 static int
30045 expose_window_tree (struct window *w, XRectangle *r)
30046 {
30047 struct frame *f = XFRAME (w->frame);
30048 int mouse_face_overwritten_p = 0;
30049
30050 while (w && !FRAME_GARBAGED_P (f))
30051 {
30052 if (WINDOWP (w->contents))
30053 mouse_face_overwritten_p
30054 |= expose_window_tree (XWINDOW (w->contents), r);
30055 else
30056 mouse_face_overwritten_p |= expose_window (w, r);
30057
30058 w = NILP (w->next) ? NULL : XWINDOW (w->next);
30059 }
30060
30061 return mouse_face_overwritten_p;
30062 }
30063
30064
30065 /* EXPORT:
30066 Redisplay an exposed area of frame F. X and Y are the upper-left
30067 corner of the exposed rectangle. W and H are width and height of
30068 the exposed area. All are pixel values. W or H zero means redraw
30069 the entire frame. */
30070
30071 void
30072 expose_frame (struct frame *f, int x, int y, int w, int h)
30073 {
30074 XRectangle r;
30075 int mouse_face_overwritten_p = 0;
30076
30077 TRACE ((stderr, "expose_frame "));
30078
30079 /* No need to redraw if frame will be redrawn soon. */
30080 if (FRAME_GARBAGED_P (f))
30081 {
30082 TRACE ((stderr, " garbaged\n"));
30083 return;
30084 }
30085
30086 /* If basic faces haven't been realized yet, there is no point in
30087 trying to redraw anything. This can happen when we get an expose
30088 event while Emacs is starting, e.g. by moving another window. */
30089 if (FRAME_FACE_CACHE (f) == NULL
30090 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
30091 {
30092 TRACE ((stderr, " no faces\n"));
30093 return;
30094 }
30095
30096 if (w == 0 || h == 0)
30097 {
30098 r.x = r.y = 0;
30099 r.width = FRAME_TEXT_WIDTH (f);
30100 r.height = FRAME_TEXT_HEIGHT (f);
30101 /** r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f); **/
30102 /** r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f); **/
30103 }
30104 else
30105 {
30106 r.x = x;
30107 r.y = y;
30108 r.width = w;
30109 r.height = h;
30110 }
30111
30112 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
30113 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
30114
30115 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
30116 if (WINDOWP (f->tool_bar_window))
30117 mouse_face_overwritten_p
30118 |= expose_window (XWINDOW (f->tool_bar_window), &r);
30119 #endif
30120
30121 #ifdef HAVE_X_WINDOWS
30122 #ifndef MSDOS
30123 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
30124 if (WINDOWP (f->menu_bar_window))
30125 mouse_face_overwritten_p
30126 |= expose_window (XWINDOW (f->menu_bar_window), &r);
30127 #endif /* not USE_X_TOOLKIT and not USE_GTK */
30128 #endif
30129 #endif
30130
30131 /* Some window managers support a focus-follows-mouse style with
30132 delayed raising of frames. Imagine a partially obscured frame,
30133 and moving the mouse into partially obscured mouse-face on that
30134 frame. The visible part of the mouse-face will be highlighted,
30135 then the WM raises the obscured frame. With at least one WM, KDE
30136 2.1, Emacs is not getting any event for the raising of the frame
30137 (even tried with SubstructureRedirectMask), only Expose events.
30138 These expose events will draw text normally, i.e. not
30139 highlighted. Which means we must redo the highlight here.
30140 Subsume it under ``we love X''. --gerd 2001-08-15 */
30141 /* Included in Windows version because Windows most likely does not
30142 do the right thing if any third party tool offers
30143 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
30144 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
30145 {
30146 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30147 if (f == hlinfo->mouse_face_mouse_frame)
30148 {
30149 int mouse_x = hlinfo->mouse_face_mouse_x;
30150 int mouse_y = hlinfo->mouse_face_mouse_y;
30151 clear_mouse_face (hlinfo);
30152 note_mouse_highlight (f, mouse_x, mouse_y);
30153 }
30154 }
30155 }
30156
30157
30158 /* EXPORT:
30159 Determine the intersection of two rectangles R1 and R2. Return
30160 the intersection in *RESULT. Value is non-zero if RESULT is not
30161 empty. */
30162
30163 int
30164 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
30165 {
30166 XRectangle *left, *right;
30167 XRectangle *upper, *lower;
30168 int intersection_p = 0;
30169
30170 /* Rearrange so that R1 is the left-most rectangle. */
30171 if (r1->x < r2->x)
30172 left = r1, right = r2;
30173 else
30174 left = r2, right = r1;
30175
30176 /* X0 of the intersection is right.x0, if this is inside R1,
30177 otherwise there is no intersection. */
30178 if (right->x <= left->x + left->width)
30179 {
30180 result->x = right->x;
30181
30182 /* The right end of the intersection is the minimum of
30183 the right ends of left and right. */
30184 result->width = (min (left->x + left->width, right->x + right->width)
30185 - result->x);
30186
30187 /* Same game for Y. */
30188 if (r1->y < r2->y)
30189 upper = r1, lower = r2;
30190 else
30191 upper = r2, lower = r1;
30192
30193 /* The upper end of the intersection is lower.y0, if this is inside
30194 of upper. Otherwise, there is no intersection. */
30195 if (lower->y <= upper->y + upper->height)
30196 {
30197 result->y = lower->y;
30198
30199 /* The lower end of the intersection is the minimum of the lower
30200 ends of upper and lower. */
30201 result->height = (min (lower->y + lower->height,
30202 upper->y + upper->height)
30203 - result->y);
30204 intersection_p = 1;
30205 }
30206 }
30207
30208 return intersection_p;
30209 }
30210
30211 #endif /* HAVE_WINDOW_SYSTEM */
30212
30213 \f
30214 /***********************************************************************
30215 Initialization
30216 ***********************************************************************/
30217
30218 void
30219 syms_of_xdisp (void)
30220 {
30221 Vwith_echo_area_save_vector = Qnil;
30222 staticpro (&Vwith_echo_area_save_vector);
30223
30224 Vmessage_stack = Qnil;
30225 staticpro (&Vmessage_stack);
30226
30227 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
30228 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
30229
30230 message_dolog_marker1 = Fmake_marker ();
30231 staticpro (&message_dolog_marker1);
30232 message_dolog_marker2 = Fmake_marker ();
30233 staticpro (&message_dolog_marker2);
30234 message_dolog_marker3 = Fmake_marker ();
30235 staticpro (&message_dolog_marker3);
30236
30237 #ifdef GLYPH_DEBUG
30238 defsubr (&Sdump_frame_glyph_matrix);
30239 defsubr (&Sdump_glyph_matrix);
30240 defsubr (&Sdump_glyph_row);
30241 defsubr (&Sdump_tool_bar_row);
30242 defsubr (&Strace_redisplay);
30243 defsubr (&Strace_to_stderr);
30244 #endif
30245 #ifdef HAVE_WINDOW_SYSTEM
30246 defsubr (&Stool_bar_height);
30247 defsubr (&Slookup_image_map);
30248 #endif
30249 defsubr (&Sline_pixel_height);
30250 defsubr (&Sformat_mode_line);
30251 defsubr (&Sinvisible_p);
30252 defsubr (&Scurrent_bidi_paragraph_direction);
30253 defsubr (&Swindow_text_pixel_size);
30254 defsubr (&Smove_point_visually);
30255
30256 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
30257 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
30258 DEFSYM (Qoverriding_local_map, "overriding-local-map");
30259 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
30260 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
30261 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
30262 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
30263 DEFSYM (Qeval, "eval");
30264 DEFSYM (QCdata, ":data");
30265 DEFSYM (Qdisplay, "display");
30266 DEFSYM (Qspace_width, "space-width");
30267 DEFSYM (Qraise, "raise");
30268 DEFSYM (Qslice, "slice");
30269 DEFSYM (Qspace, "space");
30270 DEFSYM (Qmargin, "margin");
30271 DEFSYM (Qpointer, "pointer");
30272 DEFSYM (Qleft_margin, "left-margin");
30273 DEFSYM (Qright_margin, "right-margin");
30274 DEFSYM (Qcenter, "center");
30275 DEFSYM (Qline_height, "line-height");
30276 DEFSYM (QCalign_to, ":align-to");
30277 DEFSYM (QCrelative_width, ":relative-width");
30278 DEFSYM (QCrelative_height, ":relative-height");
30279 DEFSYM (QCeval, ":eval");
30280 DEFSYM (QCpropertize, ":propertize");
30281 DEFSYM (QCfile, ":file");
30282 DEFSYM (Qfontified, "fontified");
30283 DEFSYM (Qfontification_functions, "fontification-functions");
30284 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
30285 DEFSYM (Qescape_glyph, "escape-glyph");
30286 DEFSYM (Qnobreak_space, "nobreak-space");
30287 DEFSYM (Qimage, "image");
30288 DEFSYM (Qtext, "text");
30289 DEFSYM (Qboth, "both");
30290 DEFSYM (Qboth_horiz, "both-horiz");
30291 DEFSYM (Qtext_image_horiz, "text-image-horiz");
30292 DEFSYM (QCmap, ":map");
30293 DEFSYM (QCpointer, ":pointer");
30294 DEFSYM (Qrect, "rect");
30295 DEFSYM (Qcircle, "circle");
30296 DEFSYM (Qpoly, "poly");
30297 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
30298 DEFSYM (Qgrow_only, "grow-only");
30299 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
30300 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
30301 DEFSYM (Qposition, "position");
30302 DEFSYM (Qbuffer_position, "buffer-position");
30303 DEFSYM (Qobject, "object");
30304 DEFSYM (Qbar, "bar");
30305 DEFSYM (Qhbar, "hbar");
30306 DEFSYM (Qbox, "box");
30307 DEFSYM (Qhollow, "hollow");
30308 DEFSYM (Qhand, "hand");
30309 DEFSYM (Qarrow, "arrow");
30310 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
30311
30312 list_of_error = list1 (list2 (intern_c_string ("error"),
30313 intern_c_string ("void-variable")));
30314 staticpro (&list_of_error);
30315
30316 DEFSYM (Qlast_arrow_position, "last-arrow-position");
30317 DEFSYM (Qlast_arrow_string, "last-arrow-string");
30318 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
30319 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
30320
30321 echo_buffer[0] = echo_buffer[1] = Qnil;
30322 staticpro (&echo_buffer[0]);
30323 staticpro (&echo_buffer[1]);
30324
30325 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
30326 staticpro (&echo_area_buffer[0]);
30327 staticpro (&echo_area_buffer[1]);
30328
30329 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
30330 staticpro (&Vmessages_buffer_name);
30331
30332 mode_line_proptrans_alist = Qnil;
30333 staticpro (&mode_line_proptrans_alist);
30334 mode_line_string_list = Qnil;
30335 staticpro (&mode_line_string_list);
30336 mode_line_string_face = Qnil;
30337 staticpro (&mode_line_string_face);
30338 mode_line_string_face_prop = Qnil;
30339 staticpro (&mode_line_string_face_prop);
30340 Vmode_line_unwind_vector = Qnil;
30341 staticpro (&Vmode_line_unwind_vector);
30342
30343 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
30344
30345 help_echo_string = Qnil;
30346 staticpro (&help_echo_string);
30347 help_echo_object = Qnil;
30348 staticpro (&help_echo_object);
30349 help_echo_window = Qnil;
30350 staticpro (&help_echo_window);
30351 previous_help_echo_string = Qnil;
30352 staticpro (&previous_help_echo_string);
30353 help_echo_pos = -1;
30354
30355 DEFSYM (Qright_to_left, "right-to-left");
30356 DEFSYM (Qleft_to_right, "left-to-right");
30357
30358 #ifdef HAVE_WINDOW_SYSTEM
30359 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
30360 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
30361 For example, if a block cursor is over a tab, it will be drawn as
30362 wide as that tab on the display. */);
30363 x_stretch_cursor_p = 0;
30364 #endif
30365
30366 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
30367 doc: /* Non-nil means highlight trailing whitespace.
30368 The face used for trailing whitespace is `trailing-whitespace'. */);
30369 Vshow_trailing_whitespace = Qnil;
30370
30371 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
30372 doc: /* Control highlighting of non-ASCII space and hyphen chars.
30373 If the value is t, Emacs highlights non-ASCII chars which have the
30374 same appearance as an ASCII space or hyphen, using the `nobreak-space'
30375 or `escape-glyph' face respectively.
30376
30377 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
30378 U+2011 (non-breaking hyphen) are affected.
30379
30380 Any other non-nil value means to display these characters as a escape
30381 glyph followed by an ordinary space or hyphen.
30382
30383 A value of nil means no special handling of these characters. */);
30384 Vnobreak_char_display = Qt;
30385
30386 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
30387 doc: /* The pointer shape to show in void text areas.
30388 A value of nil means to show the text pointer. Other options are
30389 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
30390 `hourglass'. */);
30391 Vvoid_text_area_pointer = Qarrow;
30392
30393 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
30394 doc: /* Non-nil means don't actually do any redisplay.
30395 This is used for internal purposes. */);
30396 Vinhibit_redisplay = Qnil;
30397
30398 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
30399 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
30400 Vglobal_mode_string = Qnil;
30401
30402 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
30403 doc: /* Marker for where to display an arrow on top of the buffer text.
30404 This must be the beginning of a line in order to work.
30405 See also `overlay-arrow-string'. */);
30406 Voverlay_arrow_position = Qnil;
30407
30408 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
30409 doc: /* String to display as an arrow in non-window frames.
30410 See also `overlay-arrow-position'. */);
30411 Voverlay_arrow_string = build_pure_c_string ("=>");
30412
30413 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
30414 doc: /* List of variables (symbols) which hold markers for overlay arrows.
30415 The symbols on this list are examined during redisplay to determine
30416 where to display overlay arrows. */);
30417 Voverlay_arrow_variable_list
30418 = list1 (intern_c_string ("overlay-arrow-position"));
30419
30420 DEFVAR_INT ("scroll-step", emacs_scroll_step,
30421 doc: /* The number of lines to try scrolling a window by when point moves out.
30422 If that fails to bring point back on frame, point is centered instead.
30423 If this is zero, point is always centered after it moves off frame.
30424 If you want scrolling to always be a line at a time, you should set
30425 `scroll-conservatively' to a large value rather than set this to 1. */);
30426
30427 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
30428 doc: /* Scroll up to this many lines, to bring point back on screen.
30429 If point moves off-screen, redisplay will scroll by up to
30430 `scroll-conservatively' lines in order to bring point just barely
30431 onto the screen again. If that cannot be done, then redisplay
30432 recenters point as usual.
30433
30434 If the value is greater than 100, redisplay will never recenter point,
30435 but will always scroll just enough text to bring point into view, even
30436 if you move far away.
30437
30438 A value of zero means always recenter point if it moves off screen. */);
30439 scroll_conservatively = 0;
30440
30441 DEFVAR_INT ("scroll-margin", scroll_margin,
30442 doc: /* Number of lines of margin at the top and bottom of a window.
30443 Recenter the window whenever point gets within this many lines
30444 of the top or bottom of the window. */);
30445 scroll_margin = 0;
30446
30447 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
30448 doc: /* Pixels per inch value for non-window system displays.
30449 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
30450 Vdisplay_pixels_per_inch = make_float (72.0);
30451
30452 #ifdef GLYPH_DEBUG
30453 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
30454 #endif
30455
30456 DEFVAR_LISP ("truncate-partial-width-windows",
30457 Vtruncate_partial_width_windows,
30458 doc: /* Non-nil means truncate lines in windows narrower than the frame.
30459 For an integer value, truncate lines in each window narrower than the
30460 full frame width, provided the window width is less than that integer;
30461 otherwise, respect the value of `truncate-lines'.
30462
30463 For any other non-nil value, truncate lines in all windows that do
30464 not span the full frame width.
30465
30466 A value of nil means to respect the value of `truncate-lines'.
30467
30468 If `word-wrap' is enabled, you might want to reduce this. */);
30469 Vtruncate_partial_width_windows = make_number (50);
30470
30471 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
30472 doc: /* Maximum buffer size for which line number should be displayed.
30473 If the buffer is bigger than this, the line number does not appear
30474 in the mode line. A value of nil means no limit. */);
30475 Vline_number_display_limit = Qnil;
30476
30477 DEFVAR_INT ("line-number-display-limit-width",
30478 line_number_display_limit_width,
30479 doc: /* Maximum line width (in characters) for line number display.
30480 If the average length of the lines near point is bigger than this, then the
30481 line number may be omitted from the mode line. */);
30482 line_number_display_limit_width = 200;
30483
30484 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
30485 doc: /* Non-nil means highlight region even in nonselected windows. */);
30486 highlight_nonselected_windows = 0;
30487
30488 DEFVAR_BOOL ("multiple-frames", multiple_frames,
30489 doc: /* Non-nil if more than one frame is visible on this display.
30490 Minibuffer-only frames don't count, but iconified frames do.
30491 This variable is not guaranteed to be accurate except while processing
30492 `frame-title-format' and `icon-title-format'. */);
30493
30494 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
30495 doc: /* Template for displaying the title bar of visible frames.
30496 \(Assuming the window manager supports this feature.)
30497
30498 This variable has the same structure as `mode-line-format', except that
30499 the %c and %l constructs are ignored. It is used only on frames for
30500 which no explicit name has been set \(see `modify-frame-parameters'). */);
30501
30502 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
30503 doc: /* Template for displaying the title bar of an iconified frame.
30504 \(Assuming the window manager supports this feature.)
30505 This variable has the same structure as `mode-line-format' (which see),
30506 and is used only on frames for which no explicit name has been set
30507 \(see `modify-frame-parameters'). */);
30508 Vicon_title_format
30509 = Vframe_title_format
30510 = listn (CONSTYPE_PURE, 3,
30511 intern_c_string ("multiple-frames"),
30512 build_pure_c_string ("%b"),
30513 listn (CONSTYPE_PURE, 4,
30514 empty_unibyte_string,
30515 intern_c_string ("invocation-name"),
30516 build_pure_c_string ("@"),
30517 intern_c_string ("system-name")));
30518
30519 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
30520 doc: /* Maximum number of lines to keep in the message log buffer.
30521 If nil, disable message logging. If t, log messages but don't truncate
30522 the buffer when it becomes large. */);
30523 Vmessage_log_max = make_number (1000);
30524
30525 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
30526 doc: /* Functions called before redisplay, if window sizes have changed.
30527 The value should be a list of functions that take one argument.
30528 Just before redisplay, for each frame, if any of its windows have changed
30529 size since the last redisplay, or have been split or deleted,
30530 all the functions in the list are called, with the frame as argument. */);
30531 Vwindow_size_change_functions = Qnil;
30532
30533 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
30534 doc: /* List of functions to call before redisplaying a window with scrolling.
30535 Each function is called with two arguments, the window and its new
30536 display-start position. Note that these functions are also called by
30537 `set-window-buffer'. Also note that the value of `window-end' is not
30538 valid when these functions are called.
30539
30540 Warning: Do not use this feature to alter the way the window
30541 is scrolled. It is not designed for that, and such use probably won't
30542 work. */);
30543 Vwindow_scroll_functions = Qnil;
30544
30545 DEFVAR_LISP ("window-text-change-functions",
30546 Vwindow_text_change_functions,
30547 doc: /* Functions to call in redisplay when text in the window might change. */);
30548 Vwindow_text_change_functions = Qnil;
30549
30550 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
30551 doc: /* Functions called when redisplay of a window reaches the end trigger.
30552 Each function is called with two arguments, the window and the end trigger value.
30553 See `set-window-redisplay-end-trigger'. */);
30554 Vredisplay_end_trigger_functions = Qnil;
30555
30556 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
30557 doc: /* Non-nil means autoselect window with mouse pointer.
30558 If nil, do not autoselect windows.
30559 A positive number means delay autoselection by that many seconds: a
30560 window is autoselected only after the mouse has remained in that
30561 window for the duration of the delay.
30562 A negative number has a similar effect, but causes windows to be
30563 autoselected only after the mouse has stopped moving. \(Because of
30564 the way Emacs compares mouse events, you will occasionally wait twice
30565 that time before the window gets selected.\)
30566 Any other value means to autoselect window instantaneously when the
30567 mouse pointer enters it.
30568
30569 Autoselection selects the minibuffer only if it is active, and never
30570 unselects the minibuffer if it is active.
30571
30572 When customizing this variable make sure that the actual value of
30573 `focus-follows-mouse' matches the behavior of your window manager. */);
30574 Vmouse_autoselect_window = Qnil;
30575
30576 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
30577 doc: /* Non-nil means automatically resize tool-bars.
30578 This dynamically changes the tool-bar's height to the minimum height
30579 that is needed to make all tool-bar items visible.
30580 If value is `grow-only', the tool-bar's height is only increased
30581 automatically; to decrease the tool-bar height, use \\[recenter]. */);
30582 Vauto_resize_tool_bars = Qt;
30583
30584 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
30585 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
30586 auto_raise_tool_bar_buttons_p = 1;
30587
30588 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
30589 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
30590 make_cursor_line_fully_visible_p = 1;
30591
30592 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
30593 doc: /* Border below tool-bar in pixels.
30594 If an integer, use it as the height of the border.
30595 If it is one of `internal-border-width' or `border-width', use the
30596 value of the corresponding frame parameter.
30597 Otherwise, no border is added below the tool-bar. */);
30598 Vtool_bar_border = Qinternal_border_width;
30599
30600 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
30601 doc: /* Margin around tool-bar buttons in pixels.
30602 If an integer, use that for both horizontal and vertical margins.
30603 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
30604 HORZ specifying the horizontal margin, and VERT specifying the
30605 vertical margin. */);
30606 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
30607
30608 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
30609 doc: /* Relief thickness of tool-bar buttons. */);
30610 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
30611
30612 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
30613 doc: /* Tool bar style to use.
30614 It can be one of
30615 image - show images only
30616 text - show text only
30617 both - show both, text below image
30618 both-horiz - show text to the right of the image
30619 text-image-horiz - show text to the left of the image
30620 any other - use system default or image if no system default.
30621
30622 This variable only affects the GTK+ toolkit version of Emacs. */);
30623 Vtool_bar_style = Qnil;
30624
30625 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
30626 doc: /* Maximum number of characters a label can have to be shown.
30627 The tool bar style must also show labels for this to have any effect, see
30628 `tool-bar-style'. */);
30629 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
30630
30631 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
30632 doc: /* List of functions to call to fontify regions of text.
30633 Each function is called with one argument POS. Functions must
30634 fontify a region starting at POS in the current buffer, and give
30635 fontified regions the property `fontified'. */);
30636 Vfontification_functions = Qnil;
30637 Fmake_variable_buffer_local (Qfontification_functions);
30638
30639 DEFVAR_BOOL ("unibyte-display-via-language-environment",
30640 unibyte_display_via_language_environment,
30641 doc: /* Non-nil means display unibyte text according to language environment.
30642 Specifically, this means that raw bytes in the range 160-255 decimal
30643 are displayed by converting them to the equivalent multibyte characters
30644 according to the current language environment. As a result, they are
30645 displayed according to the current fontset.
30646
30647 Note that this variable affects only how these bytes are displayed,
30648 but does not change the fact they are interpreted as raw bytes. */);
30649 unibyte_display_via_language_environment = 0;
30650
30651 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
30652 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
30653 If a float, it specifies a fraction of the mini-window frame's height.
30654 If an integer, it specifies a number of lines. */);
30655 Vmax_mini_window_height = make_float (0.25);
30656
30657 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
30658 doc: /* How to resize mini-windows (the minibuffer and the echo area).
30659 A value of nil means don't automatically resize mini-windows.
30660 A value of t means resize them to fit the text displayed in them.
30661 A value of `grow-only', the default, means let mini-windows grow only;
30662 they return to their normal size when the minibuffer is closed, or the
30663 echo area becomes empty. */);
30664 Vresize_mini_windows = Qgrow_only;
30665
30666 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
30667 doc: /* Alist specifying how to blink the cursor off.
30668 Each element has the form (ON-STATE . OFF-STATE). Whenever the
30669 `cursor-type' frame-parameter or variable equals ON-STATE,
30670 comparing using `equal', Emacs uses OFF-STATE to specify
30671 how to blink it off. ON-STATE and OFF-STATE are values for
30672 the `cursor-type' frame parameter.
30673
30674 If a frame's ON-STATE has no entry in this list,
30675 the frame's other specifications determine how to blink the cursor off. */);
30676 Vblink_cursor_alist = Qnil;
30677
30678 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
30679 doc: /* Allow or disallow automatic horizontal scrolling of windows.
30680 If non-nil, windows are automatically scrolled horizontally to make
30681 point visible. */);
30682 automatic_hscrolling_p = 1;
30683 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
30684
30685 DEFVAR_INT ("hscroll-margin", hscroll_margin,
30686 doc: /* How many columns away from the window edge point is allowed to get
30687 before automatic hscrolling will horizontally scroll the window. */);
30688 hscroll_margin = 5;
30689
30690 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
30691 doc: /* How many columns to scroll the window when point gets too close to the edge.
30692 When point is less than `hscroll-margin' columns from the window
30693 edge, automatic hscrolling will scroll the window by the amount of columns
30694 determined by this variable. If its value is a positive integer, scroll that
30695 many columns. If it's a positive floating-point number, it specifies the
30696 fraction of the window's width to scroll. If it's nil or zero, point will be
30697 centered horizontally after the scroll. Any other value, including negative
30698 numbers, are treated as if the value were zero.
30699
30700 Automatic hscrolling always moves point outside the scroll margin, so if
30701 point was more than scroll step columns inside the margin, the window will
30702 scroll more than the value given by the scroll step.
30703
30704 Note that the lower bound for automatic hscrolling specified by `scroll-left'
30705 and `scroll-right' overrides this variable's effect. */);
30706 Vhscroll_step = make_number (0);
30707
30708 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
30709 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
30710 Bind this around calls to `message' to let it take effect. */);
30711 message_truncate_lines = 0;
30712
30713 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
30714 doc: /* Normal hook run to update the menu bar definitions.
30715 Redisplay runs this hook before it redisplays the menu bar.
30716 This is used to update menus such as Buffers, whose contents depend on
30717 various data. */);
30718 Vmenu_bar_update_hook = Qnil;
30719
30720 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
30721 doc: /* Frame for which we are updating a menu.
30722 The enable predicate for a menu binding should check this variable. */);
30723 Vmenu_updating_frame = Qnil;
30724
30725 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
30726 doc: /* Non-nil means don't update menu bars. Internal use only. */);
30727 inhibit_menubar_update = 0;
30728
30729 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
30730 doc: /* Prefix prepended to all continuation lines at display time.
30731 The value may be a string, an image, or a stretch-glyph; it is
30732 interpreted in the same way as the value of a `display' text property.
30733
30734 This variable is overridden by any `wrap-prefix' text or overlay
30735 property.
30736
30737 To add a prefix to non-continuation lines, use `line-prefix'. */);
30738 Vwrap_prefix = Qnil;
30739 DEFSYM (Qwrap_prefix, "wrap-prefix");
30740 Fmake_variable_buffer_local (Qwrap_prefix);
30741
30742 DEFVAR_LISP ("line-prefix", Vline_prefix,
30743 doc: /* Prefix prepended to all non-continuation lines at display time.
30744 The value may be a string, an image, or a stretch-glyph; it is
30745 interpreted in the same way as the value of a `display' text property.
30746
30747 This variable is overridden by any `line-prefix' text or overlay
30748 property.
30749
30750 To add a prefix to continuation lines, use `wrap-prefix'. */);
30751 Vline_prefix = Qnil;
30752 DEFSYM (Qline_prefix, "line-prefix");
30753 Fmake_variable_buffer_local (Qline_prefix);
30754
30755 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
30756 doc: /* Non-nil means don't eval Lisp during redisplay. */);
30757 inhibit_eval_during_redisplay = 0;
30758
30759 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
30760 doc: /* Non-nil means don't free realized faces. Internal use only. */);
30761 inhibit_free_realized_faces = 0;
30762
30763 #ifdef GLYPH_DEBUG
30764 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
30765 doc: /* Inhibit try_window_id display optimization. */);
30766 inhibit_try_window_id = 0;
30767
30768 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
30769 doc: /* Inhibit try_window_reusing display optimization. */);
30770 inhibit_try_window_reusing = 0;
30771
30772 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
30773 doc: /* Inhibit try_cursor_movement display optimization. */);
30774 inhibit_try_cursor_movement = 0;
30775 #endif /* GLYPH_DEBUG */
30776
30777 DEFVAR_INT ("overline-margin", overline_margin,
30778 doc: /* Space between overline and text, in pixels.
30779 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
30780 margin to the character height. */);
30781 overline_margin = 2;
30782
30783 DEFVAR_INT ("underline-minimum-offset",
30784 underline_minimum_offset,
30785 doc: /* Minimum distance between baseline and underline.
30786 This can improve legibility of underlined text at small font sizes,
30787 particularly when using variable `x-use-underline-position-properties'
30788 with fonts that specify an UNDERLINE_POSITION relatively close to the
30789 baseline. The default value is 1. */);
30790 underline_minimum_offset = 1;
30791
30792 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
30793 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
30794 This feature only works when on a window system that can change
30795 cursor shapes. */);
30796 display_hourglass_p = 1;
30797
30798 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
30799 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
30800 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
30801
30802 #ifdef HAVE_WINDOW_SYSTEM
30803 hourglass_atimer = NULL;
30804 hourglass_shown_p = 0;
30805 #endif /* HAVE_WINDOW_SYSTEM */
30806
30807 DEFSYM (Qglyphless_char, "glyphless-char");
30808 DEFSYM (Qhex_code, "hex-code");
30809 DEFSYM (Qempty_box, "empty-box");
30810 DEFSYM (Qthin_space, "thin-space");
30811 DEFSYM (Qzero_width, "zero-width");
30812
30813 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
30814 doc: /* Function run just before redisplay.
30815 It is called with one argument, which is the set of windows that are to
30816 be redisplayed. This set can be nil (meaning, only the selected window),
30817 or t (meaning all windows). */);
30818 Vpre_redisplay_function = intern ("ignore");
30819
30820 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
30821 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
30822
30823 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
30824 doc: /* Char-table defining glyphless characters.
30825 Each element, if non-nil, should be one of the following:
30826 an ASCII acronym string: display this string in a box
30827 `hex-code': display the hexadecimal code of a character in a box
30828 `empty-box': display as an empty box
30829 `thin-space': display as 1-pixel width space
30830 `zero-width': don't display
30831 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
30832 display method for graphical terminals and text terminals respectively.
30833 GRAPHICAL and TEXT should each have one of the values listed above.
30834
30835 The char-table has one extra slot to control the display of a character for
30836 which no font is found. This slot only takes effect on graphical terminals.
30837 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
30838 `thin-space'. The default is `empty-box'.
30839
30840 If a character has a non-nil entry in an active display table, the
30841 display table takes effect; in this case, Emacs does not consult
30842 `glyphless-char-display' at all. */);
30843 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
30844 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
30845 Qempty_box);
30846
30847 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
30848 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
30849 Vdebug_on_message = Qnil;
30850
30851 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
30852 doc: /* */);
30853 Vredisplay__all_windows_cause
30854 = Fmake_vector (make_number (100), make_number (0));
30855
30856 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
30857 doc: /* */);
30858 Vredisplay__mode_lines_cause
30859 = Fmake_vector (make_number (100), make_number (0));
30860 }
30861
30862
30863 /* Initialize this module when Emacs starts. */
30864
30865 void
30866 init_xdisp (void)
30867 {
30868 CHARPOS (this_line_start_pos) = 0;
30869
30870 if (!noninteractive)
30871 {
30872 struct window *m = XWINDOW (minibuf_window);
30873 Lisp_Object frame = m->frame;
30874 struct frame *f = XFRAME (frame);
30875 Lisp_Object root = FRAME_ROOT_WINDOW (f);
30876 struct window *r = XWINDOW (root);
30877 int i;
30878
30879 echo_area_window = minibuf_window;
30880
30881 r->top_line = FRAME_TOP_MARGIN (f);
30882 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
30883 r->total_cols = FRAME_COLS (f);
30884 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
30885 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
30886 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
30887
30888 m->top_line = FRAME_TOTAL_LINES (f) - 1;
30889 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
30890 m->total_cols = FRAME_COLS (f);
30891 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
30892 m->total_lines = 1;
30893 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
30894
30895 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
30896 scratch_glyph_row.glyphs[TEXT_AREA + 1]
30897 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
30898
30899 /* The default ellipsis glyphs `...'. */
30900 for (i = 0; i < 3; ++i)
30901 default_invis_vector[i] = make_number ('.');
30902 }
30903
30904 {
30905 /* Allocate the buffer for frame titles.
30906 Also used for `format-mode-line'. */
30907 int size = 100;
30908 mode_line_noprop_buf = xmalloc (size);
30909 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
30910 mode_line_noprop_ptr = mode_line_noprop_buf;
30911 mode_line_target = MODE_LINE_DISPLAY;
30912 }
30913
30914 help_echo_showing_p = 0;
30915 }
30916
30917 #ifdef HAVE_WINDOW_SYSTEM
30918
30919 /* Platform-independent portion of hourglass implementation. */
30920
30921 /* Timer function of hourglass_atimer. */
30922
30923 static void
30924 show_hourglass (struct atimer *timer)
30925 {
30926 /* The timer implementation will cancel this timer automatically
30927 after this function has run. Set hourglass_atimer to null
30928 so that we know the timer doesn't have to be canceled. */
30929 hourglass_atimer = NULL;
30930
30931 if (!hourglass_shown_p)
30932 {
30933 Lisp_Object tail, frame;
30934
30935 block_input ();
30936
30937 FOR_EACH_FRAME (tail, frame)
30938 {
30939 struct frame *f = XFRAME (frame);
30940
30941 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
30942 && FRAME_RIF (f)->show_hourglass)
30943 FRAME_RIF (f)->show_hourglass (f);
30944 }
30945
30946 hourglass_shown_p = 1;
30947 unblock_input ();
30948 }
30949 }
30950
30951 /* Cancel a currently active hourglass timer, and start a new one. */
30952
30953 void
30954 start_hourglass (void)
30955 {
30956 struct timespec delay;
30957
30958 cancel_hourglass ();
30959
30960 if (INTEGERP (Vhourglass_delay)
30961 && XINT (Vhourglass_delay) > 0)
30962 delay = make_timespec (min (XINT (Vhourglass_delay),
30963 TYPE_MAXIMUM (time_t)),
30964 0);
30965 else if (FLOATP (Vhourglass_delay)
30966 && XFLOAT_DATA (Vhourglass_delay) > 0)
30967 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
30968 else
30969 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
30970
30971 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
30972 show_hourglass, NULL);
30973 }
30974
30975 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
30976 shown. */
30977
30978 void
30979 cancel_hourglass (void)
30980 {
30981 if (hourglass_atimer)
30982 {
30983 cancel_atimer (hourglass_atimer);
30984 hourglass_atimer = NULL;
30985 }
30986
30987 if (hourglass_shown_p)
30988 {
30989 Lisp_Object tail, frame;
30990
30991 block_input ();
30992
30993 FOR_EACH_FRAME (tail, frame)
30994 {
30995 struct frame *f = XFRAME (frame);
30996
30997 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
30998 && FRAME_RIF (f)->hide_hourglass)
30999 FRAME_RIF (f)->hide_hourglass (f);
31000 #ifdef HAVE_NTGUI
31001 /* No cursors on non GUI frames - restore to stock arrow cursor. */
31002 else if (!FRAME_W32_P (f))
31003 w32_arrow_cursor ();
31004 #endif
31005 }
31006
31007 hourglass_shown_p = 0;
31008 unblock_input ();
31009 }
31010 }
31011
31012 #endif /* HAVE_WINDOW_SYSTEM */