Attempt to make redisplay more selective when changing cursor type.
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2
3 Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
4 Inc.
5
6 This file is part of GNU Emacs.
7
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
22
23 Redisplay.
24
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
29
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
35
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa. Under window systems
38 like X, some portions of the redisplay code are also called
39 asynchronously during mouse movement or expose events. It is very
40 important that these code parts do NOT use the C library (malloc,
41 free) because many C libraries under Unix are not reentrant. They
42 may also NOT call functions of the Lisp interpreter which could
43 change the interpreter's state. If you don't follow these rules,
44 you will encounter bugs which are very hard to explain.
45
46 +--------------+ redisplay +----------------+
47 | Lisp machine |---------------->| Redisplay code |<--+
48 +--------------+ (xdisp.c) +----------------+ |
49 ^ | |
50 +----------------------------------+ |
51 Don't use this path when called |
52 asynchronously! |
53 |
54 expose_window (asynchronous) |
55 |
56 X expose events -----+
57
58 What does redisplay do? Obviously, it has to figure out somehow what
59 has been changed since the last time the display has been updated,
60 and to make these changes visible. Preferably it would do that in
61 a moderately intelligent way, i.e. fast.
62
63 Changes in buffer text can be deduced from window and buffer
64 structures, and from some global variables like `beg_unchanged' and
65 `end_unchanged'. The contents of the display are additionally
66 recorded in a `glyph matrix', a two-dimensional matrix of glyph
67 structures. Each row in such a matrix corresponds to a line on the
68 display, and each glyph in a row corresponds to a column displaying
69 a character, an image, or what else. This matrix is called the
70 `current glyph matrix' or `current matrix' in redisplay
71 terminology.
72
73 For buffer parts that have been changed since the last update, a
74 second glyph matrix is constructed, the so called `desired glyph
75 matrix' or short `desired matrix'. Current and desired matrix are
76 then compared to find a cheap way to update the display, e.g. by
77 reusing part of the display by scrolling lines.
78
79 You will find a lot of redisplay optimizations when you start
80 looking at the innards of redisplay. The overall goal of all these
81 optimizations is to make redisplay fast because it is done
82 frequently. Some of these optimizations are implemented by the
83 following functions:
84
85 . try_cursor_movement
86
87 This function tries to update the display if the text in the
88 window did not change and did not scroll, only point moved, and
89 it did not move off the displayed portion of the text.
90
91 . try_window_reusing_current_matrix
92
93 This function reuses the current matrix of a window when text
94 has not changed, but the window start changed (e.g., due to
95 scrolling).
96
97 . try_window_id
98
99 This function attempts to redisplay a window by reusing parts of
100 its existing display. It finds and reuses the part that was not
101 changed, and redraws the rest.
102
103 . try_window
104
105 This function performs the full redisplay of a single window
106 assuming that its fonts were not changed and that the cursor
107 will not end up in the scroll margins. (Loading fonts requires
108 re-adjustment of dimensions of glyph matrices, which makes this
109 method impossible to use.)
110
111 These optimizations are tried in sequence (some can be skipped if
112 it is known that they are not applicable). If none of the
113 optimizations were successful, redisplay calls redisplay_windows,
114 which performs a full redisplay of all windows.
115
116 Desired matrices.
117
118 Desired matrices are always built per Emacs window. The function
119 `display_line' is the central function to look at if you are
120 interested. It constructs one row in a desired matrix given an
121 iterator structure containing both a buffer position and a
122 description of the environment in which the text is to be
123 displayed. But this is too early, read on.
124
125 Characters and pixmaps displayed for a range of buffer text depend
126 on various settings of buffers and windows, on overlays and text
127 properties, on display tables, on selective display. The good news
128 is that all this hairy stuff is hidden behind a small set of
129 interface functions taking an iterator structure (struct it)
130 argument.
131
132 Iteration over things to be displayed is then simple. It is
133 started by initializing an iterator with a call to init_iterator,
134 passing it the buffer position where to start iteration. For
135 iteration over strings, pass -1 as the position to init_iterator,
136 and call reseat_to_string when the string is ready, to initialize
137 the iterator for that string. Thereafter, calls to
138 get_next_display_element fill the iterator structure with relevant
139 information about the next thing to display. Calls to
140 set_iterator_to_next move the iterator to the next thing.
141
142 Besides this, an iterator also contains information about the
143 display environment in which glyphs for display elements are to be
144 produced. It has fields for the width and height of the display,
145 the information whether long lines are truncated or continued, a
146 current X and Y position, and lots of other stuff you can better
147 see in dispextern.h.
148
149 Glyphs in a desired matrix are normally constructed in a loop
150 calling get_next_display_element and then PRODUCE_GLYPHS. The call
151 to PRODUCE_GLYPHS will fill the iterator structure with pixel
152 information about the element being displayed and at the same time
153 produce glyphs for it. If the display element fits on the line
154 being displayed, set_iterator_to_next is called next, otherwise the
155 glyphs produced are discarded. The function display_line is the
156 workhorse of filling glyph rows in the desired matrix with glyphs.
157 In addition to producing glyphs, it also handles line truncation
158 and continuation, word wrap, and cursor positioning (for the
159 latter, see also set_cursor_from_row).
160
161 Frame matrices.
162
163 That just couldn't be all, could it? What about terminal types not
164 supporting operations on sub-windows of the screen? To update the
165 display on such a terminal, window-based glyph matrices are not
166 well suited. To be able to reuse part of the display (scrolling
167 lines up and down), we must instead have a view of the whole
168 screen. This is what `frame matrices' are for. They are a trick.
169
170 Frames on terminals like above have a glyph pool. Windows on such
171 a frame sub-allocate their glyph memory from their frame's glyph
172 pool. The frame itself is given its own glyph matrices. By
173 coincidence---or maybe something else---rows in window glyph
174 matrices are slices of corresponding rows in frame matrices. Thus
175 writing to window matrices implicitly updates a frame matrix which
176 provides us with the view of the whole screen that we originally
177 wanted to have without having to move many bytes around. To be
178 honest, there is a little bit more done, but not much more. If you
179 plan to extend that code, take a look at dispnew.c. The function
180 build_frame_matrix is a good starting point.
181
182 Bidirectional display.
183
184 Bidirectional display adds quite some hair to this already complex
185 design. The good news are that a large portion of that hairy stuff
186 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
187 reordering engine which is called by set_iterator_to_next and
188 returns the next character to display in the visual order. See
189 commentary on bidi.c for more details. As far as redisplay is
190 concerned, the effect of calling bidi_move_to_visually_next, the
191 main interface of the reordering engine, is that the iterator gets
192 magically placed on the buffer or string position that is to be
193 displayed next. In other words, a linear iteration through the
194 buffer/string is replaced with a non-linear one. All the rest of
195 the redisplay is oblivious to the bidi reordering.
196
197 Well, almost oblivious---there are still complications, most of
198 them due to the fact that buffer and string positions no longer
199 change monotonously with glyph indices in a glyph row. Moreover,
200 for continued lines, the buffer positions may not even be
201 monotonously changing with vertical positions. Also, accounting
202 for face changes, overlays, etc. becomes more complex because
203 non-linear iteration could potentially skip many positions with
204 changes, and then cross them again on the way back...
205
206 One other prominent effect of bidirectional display is that some
207 paragraphs of text need to be displayed starting at the right
208 margin of the window---the so-called right-to-left, or R2L
209 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
210 which have their reversed_p flag set. The bidi reordering engine
211 produces characters in such rows starting from the character which
212 should be the rightmost on display. PRODUCE_GLYPHS then reverses
213 the order, when it fills up the glyph row whose reversed_p flag is
214 set, by prepending each new glyph to what is already there, instead
215 of appending it. When the glyph row is complete, the function
216 extend_face_to_end_of_line fills the empty space to the left of the
217 leftmost character with special glyphs, which will display as,
218 well, empty. On text terminals, these special glyphs are simply
219 blank characters. On graphics terminals, there's a single stretch
220 glyph of a suitably computed width. Both the blanks and the
221 stretch glyph are given the face of the background of the line.
222 This way, the terminal-specific back-end can still draw the glyphs
223 left to right, even for R2L lines.
224
225 Bidirectional display and character compositions
226
227 Some scripts cannot be displayed by drawing each character
228 individually, because adjacent characters change each other's shape
229 on display. For example, Arabic and Indic scripts belong to this
230 category.
231
232 Emacs display supports this by providing "character compositions",
233 most of which is implemented in composite.c. During the buffer
234 scan that delivers characters to PRODUCE_GLYPHS, if the next
235 character to be delivered is a composed character, the iteration
236 calls composition_reseat_it and next_element_from_composition. If
237 they succeed to compose the character with one or more of the
238 following characters, the whole sequence of characters that where
239 composed is recorded in the `struct composition_it' object that is
240 part of the buffer iterator. The composed sequence could produce
241 one or more font glyphs (called "grapheme clusters") on the screen.
242 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
243 in the direction corresponding to the current bidi scan direction
244 (recorded in the scan_dir member of the `struct bidi_it' object
245 that is part of the buffer iterator). In particular, if the bidi
246 iterator currently scans the buffer backwards, the grapheme
247 clusters are delivered back to front. This reorders the grapheme
248 clusters as appropriate for the current bidi context. Note that
249 this means that the grapheme clusters are always stored in the
250 LGSTRING object (see composite.c) in the logical order.
251
252 Moving an iterator in bidirectional text
253 without producing glyphs
254
255 Note one important detail mentioned above: that the bidi reordering
256 engine, driven by the iterator, produces characters in R2L rows
257 starting at the character that will be the rightmost on display.
258 As far as the iterator is concerned, the geometry of such rows is
259 still left to right, i.e. the iterator "thinks" the first character
260 is at the leftmost pixel position. The iterator does not know that
261 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
262 delivers. This is important when functions from the move_it_*
263 family are used to get to certain screen position or to match
264 screen coordinates with buffer coordinates: these functions use the
265 iterator geometry, which is left to right even in R2L paragraphs.
266 This works well with most callers of move_it_*, because they need
267 to get to a specific column, and columns are still numbered in the
268 reading order, i.e. the rightmost character in a R2L paragraph is
269 still column zero. But some callers do not get well with this; a
270 notable example is mouse clicks that need to find the character
271 that corresponds to certain pixel coordinates. See
272 buffer_posn_from_coords in dispnew.c for how this is handled. */
273
274 #include <config.h>
275 #include <stdio.h>
276 #include <limits.h>
277
278 #include "lisp.h"
279 #include "atimer.h"
280 #include "keyboard.h"
281 #include "frame.h"
282 #include "window.h"
283 #include "termchar.h"
284 #include "dispextern.h"
285 #include "character.h"
286 #include "buffer.h"
287 #include "charset.h"
288 #include "indent.h"
289 #include "commands.h"
290 #include "keymap.h"
291 #include "macros.h"
292 #include "disptab.h"
293 #include "termhooks.h"
294 #include "termopts.h"
295 #include "intervals.h"
296 #include "coding.h"
297 #include "process.h"
298 #include "region-cache.h"
299 #include "font.h"
300 #include "fontset.h"
301 #include "blockinput.h"
302 #ifdef HAVE_WINDOW_SYSTEM
303 #include TERM_HEADER
304 #endif /* HAVE_WINDOW_SYSTEM */
305
306 #ifndef FRAME_X_OUTPUT
307 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
308 #endif
309
310 #define INFINITY 10000000
311
312 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
313 Lisp_Object Qwindow_scroll_functions;
314 static Lisp_Object Qwindow_text_change_functions;
315 static Lisp_Object Qredisplay_end_trigger_functions;
316 Lisp_Object Qinhibit_point_motion_hooks;
317 static Lisp_Object QCeval, QCpropertize;
318 Lisp_Object QCfile, QCdata;
319 static Lisp_Object Qfontified;
320 static Lisp_Object Qgrow_only;
321 static Lisp_Object Qinhibit_eval_during_redisplay;
322 static Lisp_Object Qbuffer_position, Qposition, Qobject;
323 static Lisp_Object Qright_to_left, Qleft_to_right;
324
325 /* Cursor shapes. */
326 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
327
328 /* Pointer shapes. */
329 static Lisp_Object Qarrow, Qhand;
330 Lisp_Object Qtext;
331
332 /* Holds the list (error). */
333 static Lisp_Object list_of_error;
334
335 static Lisp_Object Qfontification_functions;
336
337 static Lisp_Object Qwrap_prefix;
338 static Lisp_Object Qline_prefix;
339 static Lisp_Object Qredisplay_internal;
340
341 /* Non-nil means don't actually do any redisplay. */
342
343 Lisp_Object Qinhibit_redisplay;
344
345 /* Names of text properties relevant for redisplay. */
346
347 Lisp_Object Qdisplay;
348
349 Lisp_Object Qspace, QCalign_to;
350 static Lisp_Object QCrelative_width, QCrelative_height;
351 Lisp_Object Qleft_margin, Qright_margin;
352 static Lisp_Object Qspace_width, Qraise;
353 static Lisp_Object Qslice;
354 Lisp_Object Qcenter;
355 static Lisp_Object Qmargin, Qpointer;
356 static Lisp_Object Qline_height;
357
358 #ifdef HAVE_WINDOW_SYSTEM
359
360 /* Test if overflow newline into fringe. Called with iterator IT
361 at or past right window margin, and with IT->current_x set. */
362
363 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
364 (!NILP (Voverflow_newline_into_fringe) \
365 && FRAME_WINDOW_P ((IT)->f) \
366 && ((IT)->bidi_it.paragraph_dir == R2L \
367 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
368 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
369 && (IT)->current_x == (IT)->last_visible_x)
370
371 #else /* !HAVE_WINDOW_SYSTEM */
372 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
373 #endif /* HAVE_WINDOW_SYSTEM */
374
375 /* Test if the display element loaded in IT, or the underlying buffer
376 or string character, is a space or a TAB character. This is used
377 to determine where word wrapping can occur. */
378
379 #define IT_DISPLAYING_WHITESPACE(it) \
380 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
381 || ((STRINGP (it->string) \
382 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
383 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
384 || (it->s \
385 && (it->s[IT_BYTEPOS (*it)] == ' ' \
386 || it->s[IT_BYTEPOS (*it)] == '\t')) \
387 || (IT_BYTEPOS (*it) < ZV_BYTE \
388 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
389 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
390
391 /* Name of the face used to highlight trailing whitespace. */
392
393 static Lisp_Object Qtrailing_whitespace;
394
395 /* Name and number of the face used to highlight escape glyphs. */
396
397 static Lisp_Object Qescape_glyph;
398
399 /* Name and number of the face used to highlight non-breaking spaces. */
400
401 static Lisp_Object Qnobreak_space;
402
403 /* The symbol `image' which is the car of the lists used to represent
404 images in Lisp. Also a tool bar style. */
405
406 Lisp_Object Qimage;
407
408 /* The image map types. */
409 Lisp_Object QCmap;
410 static Lisp_Object QCpointer;
411 static Lisp_Object Qrect, Qcircle, Qpoly;
412
413 /* Tool bar styles */
414 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
415
416 /* Non-zero means print newline to stdout before next mini-buffer
417 message. */
418
419 int noninteractive_need_newline;
420
421 /* Non-zero means print newline to message log before next message. */
422
423 static int message_log_need_newline;
424
425 /* Three markers that message_dolog uses.
426 It could allocate them itself, but that causes trouble
427 in handling memory-full errors. */
428 static Lisp_Object message_dolog_marker1;
429 static Lisp_Object message_dolog_marker2;
430 static Lisp_Object message_dolog_marker3;
431 \f
432 /* The buffer position of the first character appearing entirely or
433 partially on the line of the selected window which contains the
434 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
435 redisplay optimization in redisplay_internal. */
436
437 static struct text_pos this_line_start_pos;
438
439 /* Number of characters past the end of the line above, including the
440 terminating newline. */
441
442 static struct text_pos this_line_end_pos;
443
444 /* The vertical positions and the height of this line. */
445
446 static int this_line_vpos;
447 static int this_line_y;
448 static int this_line_pixel_height;
449
450 /* X position at which this display line starts. Usually zero;
451 negative if first character is partially visible. */
452
453 static int this_line_start_x;
454
455 /* The smallest character position seen by move_it_* functions as they
456 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
457 hscrolled lines, see display_line. */
458
459 static struct text_pos this_line_min_pos;
460
461 /* Buffer that this_line_.* variables are referring to. */
462
463 static struct buffer *this_line_buffer;
464
465
466 /* Values of those variables at last redisplay are stored as
467 properties on `overlay-arrow-position' symbol. However, if
468 Voverlay_arrow_position is a marker, last-arrow-position is its
469 numerical position. */
470
471 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
472
473 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
474 properties on a symbol in overlay-arrow-variable-list. */
475
476 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
477
478 Lisp_Object Qmenu_bar_update_hook;
479
480 /* Nonzero if an overlay arrow has been displayed in this window. */
481
482 static int overlay_arrow_seen;
483
484 /* Vector containing glyphs for an ellipsis `...'. */
485
486 static Lisp_Object default_invis_vector[3];
487
488 /* This is the window where the echo area message was displayed. It
489 is always a mini-buffer window, but it may not be the same window
490 currently active as a mini-buffer. */
491
492 Lisp_Object echo_area_window;
493
494 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
495 pushes the current message and the value of
496 message_enable_multibyte on the stack, the function restore_message
497 pops the stack and displays MESSAGE again. */
498
499 static Lisp_Object Vmessage_stack;
500
501 /* Nonzero means multibyte characters were enabled when the echo area
502 message was specified. */
503
504 static int message_enable_multibyte;
505
506 /* Nonzero if we should redraw the mode lines on the next redisplay. */
507
508 int update_mode_lines;
509
510 /* Nonzero if window sizes or contents have changed since last
511 redisplay that finished. */
512
513 int windows_or_buffers_changed;
514
515 /* Nonzero after display_mode_line if %l was used and it displayed a
516 line number. */
517
518 static int line_number_displayed;
519
520 /* The name of the *Messages* buffer, a string. */
521
522 static Lisp_Object Vmessages_buffer_name;
523
524 /* Current, index 0, and last displayed echo area message. Either
525 buffers from echo_buffers, or nil to indicate no message. */
526
527 Lisp_Object echo_area_buffer[2];
528
529 /* The buffers referenced from echo_area_buffer. */
530
531 static Lisp_Object echo_buffer[2];
532
533 /* A vector saved used in with_area_buffer to reduce consing. */
534
535 static Lisp_Object Vwith_echo_area_save_vector;
536
537 /* Non-zero means display_echo_area should display the last echo area
538 message again. Set by redisplay_preserve_echo_area. */
539
540 static int display_last_displayed_message_p;
541
542 /* Nonzero if echo area is being used by print; zero if being used by
543 message. */
544
545 static int message_buf_print;
546
547 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
548
549 static Lisp_Object Qinhibit_menubar_update;
550 static Lisp_Object Qmessage_truncate_lines;
551
552 /* Set to 1 in clear_message to make redisplay_internal aware
553 of an emptied echo area. */
554
555 static int message_cleared_p;
556
557 /* A scratch glyph row with contents used for generating truncation
558 glyphs. Also used in direct_output_for_insert. */
559
560 #define MAX_SCRATCH_GLYPHS 100
561 static struct glyph_row scratch_glyph_row;
562 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
563
564 /* Ascent and height of the last line processed by move_it_to. */
565
566 static int last_height;
567
568 /* Non-zero if there's a help-echo in the echo area. */
569
570 int help_echo_showing_p;
571
572 /* The maximum distance to look ahead for text properties. Values
573 that are too small let us call compute_char_face and similar
574 functions too often which is expensive. Values that are too large
575 let us call compute_char_face and alike too often because we
576 might not be interested in text properties that far away. */
577
578 #define TEXT_PROP_DISTANCE_LIMIT 100
579
580 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
581 iterator state and later restore it. This is needed because the
582 bidi iterator on bidi.c keeps a stacked cache of its states, which
583 is really a singleton. When we use scratch iterator objects to
584 move around the buffer, we can cause the bidi cache to be pushed or
585 popped, and therefore we need to restore the cache state when we
586 return to the original iterator. */
587 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
588 do { \
589 if (CACHE) \
590 bidi_unshelve_cache (CACHE, 1); \
591 ITCOPY = ITORIG; \
592 CACHE = bidi_shelve_cache (); \
593 } while (0)
594
595 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
596 do { \
597 if (pITORIG != pITCOPY) \
598 *(pITORIG) = *(pITCOPY); \
599 bidi_unshelve_cache (CACHE, 0); \
600 CACHE = NULL; \
601 } while (0)
602
603 #ifdef GLYPH_DEBUG
604
605 /* Non-zero means print traces of redisplay if compiled with
606 GLYPH_DEBUG defined. */
607
608 int trace_redisplay_p;
609
610 #endif /* GLYPH_DEBUG */
611
612 #ifdef DEBUG_TRACE_MOVE
613 /* Non-zero means trace with TRACE_MOVE to stderr. */
614 int trace_move;
615
616 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
617 #else
618 #define TRACE_MOVE(x) (void) 0
619 #endif
620
621 static Lisp_Object Qauto_hscroll_mode;
622
623 /* Buffer being redisplayed -- for redisplay_window_error. */
624
625 static struct buffer *displayed_buffer;
626
627 /* Value returned from text property handlers (see below). */
628
629 enum prop_handled
630 {
631 HANDLED_NORMALLY,
632 HANDLED_RECOMPUTE_PROPS,
633 HANDLED_OVERLAY_STRING_CONSUMED,
634 HANDLED_RETURN
635 };
636
637 /* A description of text properties that redisplay is interested
638 in. */
639
640 struct props
641 {
642 /* The name of the property. */
643 Lisp_Object *name;
644
645 /* A unique index for the property. */
646 enum prop_idx idx;
647
648 /* A handler function called to set up iterator IT from the property
649 at IT's current position. Value is used to steer handle_stop. */
650 enum prop_handled (*handler) (struct it *it);
651 };
652
653 static enum prop_handled handle_face_prop (struct it *);
654 static enum prop_handled handle_invisible_prop (struct it *);
655 static enum prop_handled handle_display_prop (struct it *);
656 static enum prop_handled handle_composition_prop (struct it *);
657 static enum prop_handled handle_overlay_change (struct it *);
658 static enum prop_handled handle_fontified_prop (struct it *);
659
660 /* Properties handled by iterators. */
661
662 static struct props it_props[] =
663 {
664 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
665 /* Handle `face' before `display' because some sub-properties of
666 `display' need to know the face. */
667 {&Qface, FACE_PROP_IDX, handle_face_prop},
668 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
669 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
670 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
671 {NULL, 0, NULL}
672 };
673
674 /* Value is the position described by X. If X is a marker, value is
675 the marker_position of X. Otherwise, value is X. */
676
677 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
678
679 /* Enumeration returned by some move_it_.* functions internally. */
680
681 enum move_it_result
682 {
683 /* Not used. Undefined value. */
684 MOVE_UNDEFINED,
685
686 /* Move ended at the requested buffer position or ZV. */
687 MOVE_POS_MATCH_OR_ZV,
688
689 /* Move ended at the requested X pixel position. */
690 MOVE_X_REACHED,
691
692 /* Move within a line ended at the end of a line that must be
693 continued. */
694 MOVE_LINE_CONTINUED,
695
696 /* Move within a line ended at the end of a line that would
697 be displayed truncated. */
698 MOVE_LINE_TRUNCATED,
699
700 /* Move within a line ended at a line end. */
701 MOVE_NEWLINE_OR_CR
702 };
703
704 /* This counter is used to clear the face cache every once in a while
705 in redisplay_internal. It is incremented for each redisplay.
706 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
707 cleared. */
708
709 #define CLEAR_FACE_CACHE_COUNT 500
710 static int clear_face_cache_count;
711
712 /* Similarly for the image cache. */
713
714 #ifdef HAVE_WINDOW_SYSTEM
715 #define CLEAR_IMAGE_CACHE_COUNT 101
716 static int clear_image_cache_count;
717
718 /* Null glyph slice */
719 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
720 #endif
721
722 /* True while redisplay_internal is in progress. */
723
724 bool redisplaying_p;
725
726 static Lisp_Object Qinhibit_free_realized_faces;
727 static Lisp_Object Qmode_line_default_help_echo;
728
729 /* If a string, XTread_socket generates an event to display that string.
730 (The display is done in read_char.) */
731
732 Lisp_Object help_echo_string;
733 Lisp_Object help_echo_window;
734 Lisp_Object help_echo_object;
735 ptrdiff_t help_echo_pos;
736
737 /* Temporary variable for XTread_socket. */
738
739 Lisp_Object previous_help_echo_string;
740
741 /* Platform-independent portion of hourglass implementation. */
742
743 #ifdef HAVE_WINDOW_SYSTEM
744
745 /* Non-zero means an hourglass cursor is currently shown. */
746 int hourglass_shown_p;
747
748 /* If non-null, an asynchronous timer that, when it expires, displays
749 an hourglass cursor on all frames. */
750 struct atimer *hourglass_atimer;
751
752 #endif /* HAVE_WINDOW_SYSTEM */
753
754 /* Name of the face used to display glyphless characters. */
755 Lisp_Object Qglyphless_char;
756
757 /* Symbol for the purpose of Vglyphless_char_display. */
758 static Lisp_Object Qglyphless_char_display;
759
760 /* Method symbols for Vglyphless_char_display. */
761 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
762
763 /* Default number of seconds to wait before displaying an hourglass
764 cursor. */
765 #define DEFAULT_HOURGLASS_DELAY 1
766
767 #ifdef HAVE_WINDOW_SYSTEM
768
769 /* Default pixel width of `thin-space' display method. */
770 #define THIN_SPACE_WIDTH 1
771
772 #endif /* HAVE_WINDOW_SYSTEM */
773
774 /* Function prototypes. */
775
776 static void setup_for_ellipsis (struct it *, int);
777 static void set_iterator_to_next (struct it *, int);
778 static void mark_window_display_accurate_1 (struct window *, int);
779 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
780 static int display_prop_string_p (Lisp_Object, Lisp_Object);
781 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
782 static int cursor_row_p (struct glyph_row *);
783 static int redisplay_mode_lines (Lisp_Object, int);
784 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
785
786 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
787
788 static void handle_line_prefix (struct it *);
789
790 static void pint2str (char *, int, ptrdiff_t);
791 static void pint2hrstr (char *, int, ptrdiff_t);
792 static struct text_pos run_window_scroll_functions (Lisp_Object,
793 struct text_pos);
794 static int text_outside_line_unchanged_p (struct window *,
795 ptrdiff_t, ptrdiff_t);
796 static void store_mode_line_noprop_char (char);
797 static int store_mode_line_noprop (const char *, int, int);
798 static void handle_stop (struct it *);
799 static void handle_stop_backwards (struct it *, ptrdiff_t);
800 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
801 static void ensure_echo_area_buffers (void);
802 static void unwind_with_echo_area_buffer (Lisp_Object);
803 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
804 static int with_echo_area_buffer (struct window *, int,
805 int (*) (ptrdiff_t, Lisp_Object),
806 ptrdiff_t, Lisp_Object);
807 static void clear_garbaged_frames (void);
808 static int current_message_1 (ptrdiff_t, Lisp_Object);
809 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
810 static void set_message (Lisp_Object);
811 static int set_message_1 (ptrdiff_t, Lisp_Object);
812 static int display_echo_area (struct window *);
813 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
814 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
815 static void unwind_redisplay (void);
816 static int string_char_and_length (const unsigned char *, int *);
817 static struct text_pos display_prop_end (struct it *, Lisp_Object,
818 struct text_pos);
819 static int compute_window_start_on_continuation_line (struct window *);
820 static void insert_left_trunc_glyphs (struct it *);
821 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
822 Lisp_Object);
823 static void extend_face_to_end_of_line (struct it *);
824 static int append_space_for_newline (struct it *, int);
825 static int cursor_row_fully_visible_p (struct window *, int, int);
826 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
827 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
828 static int trailing_whitespace_p (ptrdiff_t);
829 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
830 static void push_it (struct it *, struct text_pos *);
831 static void iterate_out_of_display_property (struct it *);
832 static void pop_it (struct it *);
833 static void sync_frame_with_window_matrix_rows (struct window *);
834 static void redisplay_internal (void);
835 static int echo_area_display (int);
836 static void redisplay_windows (Lisp_Object);
837 static void redisplay_window (Lisp_Object, int);
838 static Lisp_Object redisplay_window_error (Lisp_Object);
839 static Lisp_Object redisplay_window_0 (Lisp_Object);
840 static Lisp_Object redisplay_window_1 (Lisp_Object);
841 static int set_cursor_from_row (struct window *, struct glyph_row *,
842 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
843 int, int);
844 static int update_menu_bar (struct frame *, int, int);
845 static int try_window_reusing_current_matrix (struct window *);
846 static int try_window_id (struct window *);
847 static int display_line (struct it *);
848 static int display_mode_lines (struct window *);
849 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
850 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
851 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
852 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
853 static void display_menu_bar (struct window *);
854 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
855 ptrdiff_t *);
856 static int display_string (const char *, Lisp_Object, Lisp_Object,
857 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
858 static void compute_line_metrics (struct it *);
859 static void run_redisplay_end_trigger_hook (struct it *);
860 static int get_overlay_strings (struct it *, ptrdiff_t);
861 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
862 static void next_overlay_string (struct it *);
863 static void reseat (struct it *, struct text_pos, int);
864 static void reseat_1 (struct it *, struct text_pos, int);
865 static void back_to_previous_visible_line_start (struct it *);
866 static void reseat_at_next_visible_line_start (struct it *, int);
867 static int next_element_from_ellipsis (struct it *);
868 static int next_element_from_display_vector (struct it *);
869 static int next_element_from_string (struct it *);
870 static int next_element_from_c_string (struct it *);
871 static int next_element_from_buffer (struct it *);
872 static int next_element_from_composition (struct it *);
873 static int next_element_from_image (struct it *);
874 static int next_element_from_stretch (struct it *);
875 static void load_overlay_strings (struct it *, ptrdiff_t);
876 static int init_from_display_pos (struct it *, struct window *,
877 struct display_pos *);
878 static void reseat_to_string (struct it *, const char *,
879 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
880 static int get_next_display_element (struct it *);
881 static enum move_it_result
882 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
883 enum move_operation_enum);
884 static void get_visually_first_element (struct it *);
885 static void init_to_row_start (struct it *, struct window *,
886 struct glyph_row *);
887 static int init_to_row_end (struct it *, struct window *,
888 struct glyph_row *);
889 static void back_to_previous_line_start (struct it *);
890 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
891 static struct text_pos string_pos_nchars_ahead (struct text_pos,
892 Lisp_Object, ptrdiff_t);
893 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
894 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
895 static ptrdiff_t number_of_chars (const char *, bool);
896 static void compute_stop_pos (struct it *);
897 static void compute_string_pos (struct text_pos *, struct text_pos,
898 Lisp_Object);
899 static int face_before_or_after_it_pos (struct it *, int);
900 static ptrdiff_t next_overlay_change (ptrdiff_t);
901 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
902 Lisp_Object, struct text_pos *, ptrdiff_t, int);
903 static int handle_single_display_spec (struct it *, Lisp_Object,
904 Lisp_Object, Lisp_Object,
905 struct text_pos *, ptrdiff_t, int, int);
906 static int underlying_face_id (struct it *);
907 static int in_ellipses_for_invisible_text_p (struct display_pos *,
908 struct window *);
909
910 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
911 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
912
913 #ifdef HAVE_WINDOW_SYSTEM
914
915 static void x_consider_frame_title (Lisp_Object);
916 static int tool_bar_lines_needed (struct frame *, int *);
917 static void update_tool_bar (struct frame *, int);
918 static void build_desired_tool_bar_string (struct frame *f);
919 static int redisplay_tool_bar (struct frame *);
920 static void display_tool_bar_line (struct it *, int);
921 static void notice_overwritten_cursor (struct window *,
922 enum glyph_row_area,
923 int, int, int, int);
924 static void append_stretch_glyph (struct it *, Lisp_Object,
925 int, int, int);
926
927
928 #endif /* HAVE_WINDOW_SYSTEM */
929
930 static void produce_special_glyphs (struct it *, enum display_element_type);
931 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
932 static int coords_in_mouse_face_p (struct window *, int, int);
933
934
935 \f
936 /***********************************************************************
937 Window display dimensions
938 ***********************************************************************/
939
940 /* Return the bottom boundary y-position for text lines in window W.
941 This is the first y position at which a line cannot start.
942 It is relative to the top of the window.
943
944 This is the height of W minus the height of a mode line, if any. */
945
946 int
947 window_text_bottom_y (struct window *w)
948 {
949 int height = WINDOW_TOTAL_HEIGHT (w);
950
951 if (WINDOW_WANTS_MODELINE_P (w))
952 height -= CURRENT_MODE_LINE_HEIGHT (w);
953 return height;
954 }
955
956 /* Return the pixel width of display area AREA of window W.
957 ANY_AREA means return the total width of W, not including
958 fringes to the left and right of the window. */
959
960 int
961 window_box_width (struct window *w, enum glyph_row_area area)
962 {
963 int cols = w->total_cols;
964 int pixels = 0;
965
966 if (!w->pseudo_window_p)
967 {
968 cols -= WINDOW_SCROLL_BAR_COLS (w);
969
970 if (area == TEXT_AREA)
971 {
972 cols -= max (0, w->left_margin_cols);
973 cols -= max (0, w->right_margin_cols);
974 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
975 }
976 else if (area == LEFT_MARGIN_AREA)
977 {
978 cols = max (0, w->left_margin_cols);
979 pixels = 0;
980 }
981 else if (area == RIGHT_MARGIN_AREA)
982 {
983 cols = max (0, w->right_margin_cols);
984 pixels = 0;
985 }
986 }
987
988 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
989 }
990
991
992 /* Return the pixel height of the display area of window W, not
993 including mode lines of W, if any. */
994
995 int
996 window_box_height (struct window *w)
997 {
998 struct frame *f = XFRAME (w->frame);
999 int height = WINDOW_TOTAL_HEIGHT (w);
1000
1001 eassert (height >= 0);
1002
1003 /* Note: the code below that determines the mode-line/header-line
1004 height is essentially the same as that contained in the macro
1005 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1006 the appropriate glyph row has its `mode_line_p' flag set,
1007 and if it doesn't, uses estimate_mode_line_height instead. */
1008
1009 if (WINDOW_WANTS_MODELINE_P (w))
1010 {
1011 struct glyph_row *ml_row
1012 = (w->current_matrix && w->current_matrix->rows
1013 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1014 : 0);
1015 if (ml_row && ml_row->mode_line_p)
1016 height -= ml_row->height;
1017 else
1018 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1019 }
1020
1021 if (WINDOW_WANTS_HEADER_LINE_P (w))
1022 {
1023 struct glyph_row *hl_row
1024 = (w->current_matrix && w->current_matrix->rows
1025 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1026 : 0);
1027 if (hl_row && hl_row->mode_line_p)
1028 height -= hl_row->height;
1029 else
1030 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1031 }
1032
1033 /* With a very small font and a mode-line that's taller than
1034 default, we might end up with a negative height. */
1035 return max (0, height);
1036 }
1037
1038 /* Return the window-relative coordinate of the left edge of display
1039 area AREA of window W. ANY_AREA means return the left edge of the
1040 whole window, to the right of the left fringe of W. */
1041
1042 int
1043 window_box_left_offset (struct window *w, enum glyph_row_area area)
1044 {
1045 int x;
1046
1047 if (w->pseudo_window_p)
1048 return 0;
1049
1050 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1051
1052 if (area == TEXT_AREA)
1053 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1054 + window_box_width (w, LEFT_MARGIN_AREA));
1055 else if (area == RIGHT_MARGIN_AREA)
1056 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1057 + window_box_width (w, LEFT_MARGIN_AREA)
1058 + window_box_width (w, TEXT_AREA)
1059 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1060 ? 0
1061 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1062 else if (area == LEFT_MARGIN_AREA
1063 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1064 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1065
1066 return x;
1067 }
1068
1069
1070 /* Return the window-relative coordinate of the right edge of display
1071 area AREA of window W. ANY_AREA means return the right edge of the
1072 whole window, to the left of the right fringe of W. */
1073
1074 int
1075 window_box_right_offset (struct window *w, enum glyph_row_area area)
1076 {
1077 return window_box_left_offset (w, area) + window_box_width (w, area);
1078 }
1079
1080 /* Return the frame-relative coordinate of the left edge of display
1081 area AREA of window W. ANY_AREA means return the left edge of the
1082 whole window, to the right of the left fringe of W. */
1083
1084 int
1085 window_box_left (struct window *w, enum glyph_row_area area)
1086 {
1087 struct frame *f = XFRAME (w->frame);
1088 int x;
1089
1090 if (w->pseudo_window_p)
1091 return FRAME_INTERNAL_BORDER_WIDTH (f);
1092
1093 x = (WINDOW_LEFT_EDGE_X (w)
1094 + window_box_left_offset (w, area));
1095
1096 return x;
1097 }
1098
1099
1100 /* Return the frame-relative coordinate of the right edge of display
1101 area AREA of window W. ANY_AREA means return the right edge of the
1102 whole window, to the left of the right fringe of W. */
1103
1104 int
1105 window_box_right (struct window *w, enum glyph_row_area area)
1106 {
1107 return window_box_left (w, area) + window_box_width (w, area);
1108 }
1109
1110 /* Get the bounding box of the display area AREA of window W, without
1111 mode lines, in frame-relative coordinates. ANY_AREA means the
1112 whole window, not including the left and right fringes of
1113 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1114 coordinates of the upper-left corner of the box. Return in
1115 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1116
1117 void
1118 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1119 int *box_y, int *box_width, int *box_height)
1120 {
1121 if (box_width)
1122 *box_width = window_box_width (w, area);
1123 if (box_height)
1124 *box_height = window_box_height (w);
1125 if (box_x)
1126 *box_x = window_box_left (w, area);
1127 if (box_y)
1128 {
1129 *box_y = WINDOW_TOP_EDGE_Y (w);
1130 if (WINDOW_WANTS_HEADER_LINE_P (w))
1131 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1132 }
1133 }
1134
1135 #ifdef HAVE_WINDOW_SYSTEM
1136
1137 /* Get the bounding box of the display area AREA of window W, without
1138 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1139 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1140 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1141 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1142 box. */
1143
1144 static void
1145 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1146 int *bottom_right_x, int *bottom_right_y)
1147 {
1148 window_box (w, ANY_AREA, top_left_x, top_left_y,
1149 bottom_right_x, bottom_right_y);
1150 *bottom_right_x += *top_left_x;
1151 *bottom_right_y += *top_left_y;
1152 }
1153
1154 #endif /* HAVE_WINDOW_SYSTEM */
1155
1156 /***********************************************************************
1157 Utilities
1158 ***********************************************************************/
1159
1160 /* Return the bottom y-position of the line the iterator IT is in.
1161 This can modify IT's settings. */
1162
1163 int
1164 line_bottom_y (struct it *it)
1165 {
1166 int line_height = it->max_ascent + it->max_descent;
1167 int line_top_y = it->current_y;
1168
1169 if (line_height == 0)
1170 {
1171 if (last_height)
1172 line_height = last_height;
1173 else if (IT_CHARPOS (*it) < ZV)
1174 {
1175 move_it_by_lines (it, 1);
1176 line_height = (it->max_ascent || it->max_descent
1177 ? it->max_ascent + it->max_descent
1178 : last_height);
1179 }
1180 else
1181 {
1182 struct glyph_row *row = it->glyph_row;
1183
1184 /* Use the default character height. */
1185 it->glyph_row = NULL;
1186 it->what = IT_CHARACTER;
1187 it->c = ' ';
1188 it->len = 1;
1189 PRODUCE_GLYPHS (it);
1190 line_height = it->ascent + it->descent;
1191 it->glyph_row = row;
1192 }
1193 }
1194
1195 return line_top_y + line_height;
1196 }
1197
1198 DEFUN ("line-pixel-height", Fline_pixel_height,
1199 Sline_pixel_height, 0, 0, 0,
1200 doc: /* Return height in pixels of text line in the selected window.
1201
1202 Value is the height in pixels of the line at point. */)
1203 (void)
1204 {
1205 struct it it;
1206 struct text_pos pt;
1207 struct window *w = XWINDOW (selected_window);
1208
1209 SET_TEXT_POS (pt, PT, PT_BYTE);
1210 start_display (&it, w, pt);
1211 it.vpos = it.current_y = 0;
1212 last_height = 0;
1213 return make_number (line_bottom_y (&it));
1214 }
1215
1216 /* Return the default pixel height of text lines in window W. The
1217 value is the canonical height of the W frame's default font, plus
1218 any extra space required by the line-spacing variable or frame
1219 parameter.
1220
1221 Implementation note: this ignores any line-spacing text properties
1222 put on the newline characters. This is because those properties
1223 only affect the _screen_ line ending in the newline (i.e., in a
1224 continued line, only the last screen line will be affected), which
1225 means only a small number of lines in a buffer can ever use this
1226 feature. Since this function is used to compute the default pixel
1227 equivalent of text lines in a window, we can safely ignore those
1228 few lines. For the same reasons, we ignore the line-height
1229 properties. */
1230 int
1231 default_line_pixel_height (struct window *w)
1232 {
1233 struct frame *f = WINDOW_XFRAME (w);
1234 int height = FRAME_LINE_HEIGHT (f);
1235
1236 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1237 {
1238 struct buffer *b = XBUFFER (w->contents);
1239 Lisp_Object val = BVAR (b, extra_line_spacing);
1240
1241 if (NILP (val))
1242 val = BVAR (&buffer_defaults, extra_line_spacing);
1243 if (!NILP (val))
1244 {
1245 if (RANGED_INTEGERP (0, val, INT_MAX))
1246 height += XFASTINT (val);
1247 else if (FLOATP (val))
1248 {
1249 int addon = XFLOAT_DATA (val) * height + 0.5;
1250
1251 if (addon >= 0)
1252 height += addon;
1253 }
1254 }
1255 else
1256 height += f->extra_line_spacing;
1257 }
1258
1259 return height;
1260 }
1261
1262 /* Subroutine of pos_visible_p below. Extracts a display string, if
1263 any, from the display spec given as its argument. */
1264 static Lisp_Object
1265 string_from_display_spec (Lisp_Object spec)
1266 {
1267 if (CONSP (spec))
1268 {
1269 while (CONSP (spec))
1270 {
1271 if (STRINGP (XCAR (spec)))
1272 return XCAR (spec);
1273 spec = XCDR (spec);
1274 }
1275 }
1276 else if (VECTORP (spec))
1277 {
1278 ptrdiff_t i;
1279
1280 for (i = 0; i < ASIZE (spec); i++)
1281 {
1282 if (STRINGP (AREF (spec, i)))
1283 return AREF (spec, i);
1284 }
1285 return Qnil;
1286 }
1287
1288 return spec;
1289 }
1290
1291
1292 /* Limit insanely large values of W->hscroll on frame F to the largest
1293 value that will still prevent first_visible_x and last_visible_x of
1294 'struct it' from overflowing an int. */
1295 static int
1296 window_hscroll_limited (struct window *w, struct frame *f)
1297 {
1298 ptrdiff_t window_hscroll = w->hscroll;
1299 int window_text_width = window_box_width (w, TEXT_AREA);
1300 int colwidth = FRAME_COLUMN_WIDTH (f);
1301
1302 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1303 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1304
1305 return window_hscroll;
1306 }
1307
1308 /* Return 1 if position CHARPOS is visible in window W.
1309 CHARPOS < 0 means return info about WINDOW_END position.
1310 If visible, set *X and *Y to pixel coordinates of top left corner.
1311 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1312 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1313
1314 int
1315 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1316 int *rtop, int *rbot, int *rowh, int *vpos)
1317 {
1318 struct it it;
1319 void *itdata = bidi_shelve_cache ();
1320 struct text_pos top;
1321 int visible_p = 0;
1322 struct buffer *old_buffer = NULL;
1323
1324 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1325 return visible_p;
1326
1327 if (XBUFFER (w->contents) != current_buffer)
1328 {
1329 old_buffer = current_buffer;
1330 set_buffer_internal_1 (XBUFFER (w->contents));
1331 }
1332
1333 SET_TEXT_POS_FROM_MARKER (top, w->start);
1334 /* Scrolling a minibuffer window via scroll bar when the echo area
1335 shows long text sometimes resets the minibuffer contents behind
1336 our backs. */
1337 if (CHARPOS (top) > ZV)
1338 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1339
1340 /* Compute exact mode line heights. */
1341 if (WINDOW_WANTS_MODELINE_P (w))
1342 w->mode_line_height
1343 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1344 BVAR (current_buffer, mode_line_format));
1345
1346 if (WINDOW_WANTS_HEADER_LINE_P (w))
1347 w->header_line_height
1348 = display_mode_line (w, HEADER_LINE_FACE_ID,
1349 BVAR (current_buffer, header_line_format));
1350
1351 start_display (&it, w, top);
1352 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1353 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1354
1355 if (charpos >= 0
1356 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1357 && IT_CHARPOS (it) >= charpos)
1358 /* When scanning backwards under bidi iteration, move_it_to
1359 stops at or _before_ CHARPOS, because it stops at or to
1360 the _right_ of the character at CHARPOS. */
1361 || (it.bidi_p && it.bidi_it.scan_dir == -1
1362 && IT_CHARPOS (it) <= charpos)))
1363 {
1364 /* We have reached CHARPOS, or passed it. How the call to
1365 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1366 or covered by a display property, move_it_to stops at the end
1367 of the invisible text, to the right of CHARPOS. (ii) If
1368 CHARPOS is in a display vector, move_it_to stops on its last
1369 glyph. */
1370 int top_x = it.current_x;
1371 int top_y = it.current_y;
1372 /* Calling line_bottom_y may change it.method, it.position, etc. */
1373 enum it_method it_method = it.method;
1374 int bottom_y = (last_height = 0, line_bottom_y (&it));
1375 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1376
1377 if (top_y < window_top_y)
1378 visible_p = bottom_y > window_top_y;
1379 else if (top_y < it.last_visible_y)
1380 visible_p = 1;
1381 if (bottom_y >= it.last_visible_y
1382 && it.bidi_p && it.bidi_it.scan_dir == -1
1383 && IT_CHARPOS (it) < charpos)
1384 {
1385 /* When the last line of the window is scanned backwards
1386 under bidi iteration, we could be duped into thinking
1387 that we have passed CHARPOS, when in fact move_it_to
1388 simply stopped short of CHARPOS because it reached
1389 last_visible_y. To see if that's what happened, we call
1390 move_it_to again with a slightly larger vertical limit,
1391 and see if it actually moved vertically; if it did, we
1392 didn't really reach CHARPOS, which is beyond window end. */
1393 struct it save_it = it;
1394 /* Why 10? because we don't know how many canonical lines
1395 will the height of the next line(s) be. So we guess. */
1396 int ten_more_lines = 10 * default_line_pixel_height (w);
1397
1398 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1399 MOVE_TO_POS | MOVE_TO_Y);
1400 if (it.current_y > top_y)
1401 visible_p = 0;
1402
1403 it = save_it;
1404 }
1405 if (visible_p)
1406 {
1407 if (it_method == GET_FROM_DISPLAY_VECTOR)
1408 {
1409 /* We stopped on the last glyph of a display vector.
1410 Try and recompute. Hack alert! */
1411 if (charpos < 2 || top.charpos >= charpos)
1412 top_x = it.glyph_row->x;
1413 else
1414 {
1415 struct it it2, it2_prev;
1416 /* The idea is to get to the previous buffer
1417 position, consume the character there, and use
1418 the pixel coordinates we get after that. But if
1419 the previous buffer position is also displayed
1420 from a display vector, we need to consume all of
1421 the glyphs from that display vector. */
1422 start_display (&it2, w, top);
1423 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1424 /* If we didn't get to CHARPOS - 1, there's some
1425 replacing display property at that position, and
1426 we stopped after it. That is exactly the place
1427 whose coordinates we want. */
1428 if (IT_CHARPOS (it2) != charpos - 1)
1429 it2_prev = it2;
1430 else
1431 {
1432 /* Iterate until we get out of the display
1433 vector that displays the character at
1434 CHARPOS - 1. */
1435 do {
1436 get_next_display_element (&it2);
1437 PRODUCE_GLYPHS (&it2);
1438 it2_prev = it2;
1439 set_iterator_to_next (&it2, 1);
1440 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1441 && IT_CHARPOS (it2) < charpos);
1442 }
1443 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1444 || it2_prev.current_x > it2_prev.last_visible_x)
1445 top_x = it.glyph_row->x;
1446 else
1447 {
1448 top_x = it2_prev.current_x;
1449 top_y = it2_prev.current_y;
1450 }
1451 }
1452 }
1453 else if (IT_CHARPOS (it) != charpos)
1454 {
1455 Lisp_Object cpos = make_number (charpos);
1456 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1457 Lisp_Object string = string_from_display_spec (spec);
1458 struct text_pos tpos;
1459 int replacing_spec_p;
1460 bool newline_in_string
1461 = (STRINGP (string)
1462 && memchr (SDATA (string), '\n', SBYTES (string)));
1463
1464 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1465 replacing_spec_p
1466 = (!NILP (spec)
1467 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1468 charpos, FRAME_WINDOW_P (it.f)));
1469 /* The tricky code below is needed because there's a
1470 discrepancy between move_it_to and how we set cursor
1471 when PT is at the beginning of a portion of text
1472 covered by a display property or an overlay with a
1473 display property, or the display line ends in a
1474 newline from a display string. move_it_to will stop
1475 _after_ such display strings, whereas
1476 set_cursor_from_row conspires with cursor_row_p to
1477 place the cursor on the first glyph produced from the
1478 display string. */
1479
1480 /* We have overshoot PT because it is covered by a
1481 display property that replaces the text it covers.
1482 If the string includes embedded newlines, we are also
1483 in the wrong display line. Backtrack to the correct
1484 line, where the display property begins. */
1485 if (replacing_spec_p)
1486 {
1487 Lisp_Object startpos, endpos;
1488 EMACS_INT start, end;
1489 struct it it3;
1490 int it3_moved;
1491
1492 /* Find the first and the last buffer positions
1493 covered by the display string. */
1494 endpos =
1495 Fnext_single_char_property_change (cpos, Qdisplay,
1496 Qnil, Qnil);
1497 startpos =
1498 Fprevious_single_char_property_change (endpos, Qdisplay,
1499 Qnil, Qnil);
1500 start = XFASTINT (startpos);
1501 end = XFASTINT (endpos);
1502 /* Move to the last buffer position before the
1503 display property. */
1504 start_display (&it3, w, top);
1505 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1506 /* Move forward one more line if the position before
1507 the display string is a newline or if it is the
1508 rightmost character on a line that is
1509 continued or word-wrapped. */
1510 if (it3.method == GET_FROM_BUFFER
1511 && (it3.c == '\n'
1512 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1513 move_it_by_lines (&it3, 1);
1514 else if (move_it_in_display_line_to (&it3, -1,
1515 it3.current_x
1516 + it3.pixel_width,
1517 MOVE_TO_X)
1518 == MOVE_LINE_CONTINUED)
1519 {
1520 move_it_by_lines (&it3, 1);
1521 /* When we are under word-wrap, the #$@%!
1522 move_it_by_lines moves 2 lines, so we need to
1523 fix that up. */
1524 if (it3.line_wrap == WORD_WRAP)
1525 move_it_by_lines (&it3, -1);
1526 }
1527
1528 /* Record the vertical coordinate of the display
1529 line where we wound up. */
1530 top_y = it3.current_y;
1531 if (it3.bidi_p)
1532 {
1533 /* When characters are reordered for display,
1534 the character displayed to the left of the
1535 display string could be _after_ the display
1536 property in the logical order. Use the
1537 smallest vertical position of these two. */
1538 start_display (&it3, w, top);
1539 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1540 if (it3.current_y < top_y)
1541 top_y = it3.current_y;
1542 }
1543 /* Move from the top of the window to the beginning
1544 of the display line where the display string
1545 begins. */
1546 start_display (&it3, w, top);
1547 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1548 /* If it3_moved stays zero after the 'while' loop
1549 below, that means we already were at a newline
1550 before the loop (e.g., the display string begins
1551 with a newline), so we don't need to (and cannot)
1552 inspect the glyphs of it3.glyph_row, because
1553 PRODUCE_GLYPHS will not produce anything for a
1554 newline, and thus it3.glyph_row stays at its
1555 stale content it got at top of the window. */
1556 it3_moved = 0;
1557 /* Finally, advance the iterator until we hit the
1558 first display element whose character position is
1559 CHARPOS, or until the first newline from the
1560 display string, which signals the end of the
1561 display line. */
1562 while (get_next_display_element (&it3))
1563 {
1564 PRODUCE_GLYPHS (&it3);
1565 if (IT_CHARPOS (it3) == charpos
1566 || ITERATOR_AT_END_OF_LINE_P (&it3))
1567 break;
1568 it3_moved = 1;
1569 set_iterator_to_next (&it3, 0);
1570 }
1571 top_x = it3.current_x - it3.pixel_width;
1572 /* Normally, we would exit the above loop because we
1573 found the display element whose character
1574 position is CHARPOS. For the contingency that we
1575 didn't, and stopped at the first newline from the
1576 display string, move back over the glyphs
1577 produced from the string, until we find the
1578 rightmost glyph not from the string. */
1579 if (it3_moved
1580 && newline_in_string
1581 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1582 {
1583 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1584 + it3.glyph_row->used[TEXT_AREA];
1585
1586 while (EQ ((g - 1)->object, string))
1587 {
1588 --g;
1589 top_x -= g->pixel_width;
1590 }
1591 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1592 + it3.glyph_row->used[TEXT_AREA]);
1593 }
1594 }
1595 }
1596
1597 *x = top_x;
1598 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1599 *rtop = max (0, window_top_y - top_y);
1600 *rbot = max (0, bottom_y - it.last_visible_y);
1601 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1602 - max (top_y, window_top_y)));
1603 *vpos = it.vpos;
1604 }
1605 }
1606 else
1607 {
1608 /* We were asked to provide info about WINDOW_END. */
1609 struct it it2;
1610 void *it2data = NULL;
1611
1612 SAVE_IT (it2, it, it2data);
1613 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1614 move_it_by_lines (&it, 1);
1615 if (charpos < IT_CHARPOS (it)
1616 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1617 {
1618 visible_p = 1;
1619 RESTORE_IT (&it2, &it2, it2data);
1620 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1621 *x = it2.current_x;
1622 *y = it2.current_y + it2.max_ascent - it2.ascent;
1623 *rtop = max (0, -it2.current_y);
1624 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1625 - it.last_visible_y));
1626 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1627 it.last_visible_y)
1628 - max (it2.current_y,
1629 WINDOW_HEADER_LINE_HEIGHT (w))));
1630 *vpos = it2.vpos;
1631 }
1632 else
1633 bidi_unshelve_cache (it2data, 1);
1634 }
1635 bidi_unshelve_cache (itdata, 0);
1636
1637 if (old_buffer)
1638 set_buffer_internal_1 (old_buffer);
1639
1640 if (visible_p && w->hscroll > 0)
1641 *x -=
1642 window_hscroll_limited (w, WINDOW_XFRAME (w))
1643 * WINDOW_FRAME_COLUMN_WIDTH (w);
1644
1645 #if 0
1646 /* Debugging code. */
1647 if (visible_p)
1648 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1649 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1650 else
1651 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1652 #endif
1653
1654 return visible_p;
1655 }
1656
1657
1658 /* Return the next character from STR. Return in *LEN the length of
1659 the character. This is like STRING_CHAR_AND_LENGTH but never
1660 returns an invalid character. If we find one, we return a `?', but
1661 with the length of the invalid character. */
1662
1663 static int
1664 string_char_and_length (const unsigned char *str, int *len)
1665 {
1666 int c;
1667
1668 c = STRING_CHAR_AND_LENGTH (str, *len);
1669 if (!CHAR_VALID_P (c))
1670 /* We may not change the length here because other places in Emacs
1671 don't use this function, i.e. they silently accept invalid
1672 characters. */
1673 c = '?';
1674
1675 return c;
1676 }
1677
1678
1679
1680 /* Given a position POS containing a valid character and byte position
1681 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1682
1683 static struct text_pos
1684 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1685 {
1686 eassert (STRINGP (string) && nchars >= 0);
1687
1688 if (STRING_MULTIBYTE (string))
1689 {
1690 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1691 int len;
1692
1693 while (nchars--)
1694 {
1695 string_char_and_length (p, &len);
1696 p += len;
1697 CHARPOS (pos) += 1;
1698 BYTEPOS (pos) += len;
1699 }
1700 }
1701 else
1702 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1703
1704 return pos;
1705 }
1706
1707
1708 /* Value is the text position, i.e. character and byte position,
1709 for character position CHARPOS in STRING. */
1710
1711 static struct text_pos
1712 string_pos (ptrdiff_t charpos, Lisp_Object string)
1713 {
1714 struct text_pos pos;
1715 eassert (STRINGP (string));
1716 eassert (charpos >= 0);
1717 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1718 return pos;
1719 }
1720
1721
1722 /* Value is a text position, i.e. character and byte position, for
1723 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1724 means recognize multibyte characters. */
1725
1726 static struct text_pos
1727 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1728 {
1729 struct text_pos pos;
1730
1731 eassert (s != NULL);
1732 eassert (charpos >= 0);
1733
1734 if (multibyte_p)
1735 {
1736 int len;
1737
1738 SET_TEXT_POS (pos, 0, 0);
1739 while (charpos--)
1740 {
1741 string_char_and_length ((const unsigned char *) s, &len);
1742 s += len;
1743 CHARPOS (pos) += 1;
1744 BYTEPOS (pos) += len;
1745 }
1746 }
1747 else
1748 SET_TEXT_POS (pos, charpos, charpos);
1749
1750 return pos;
1751 }
1752
1753
1754 /* Value is the number of characters in C string S. MULTIBYTE_P
1755 non-zero means recognize multibyte characters. */
1756
1757 static ptrdiff_t
1758 number_of_chars (const char *s, bool multibyte_p)
1759 {
1760 ptrdiff_t nchars;
1761
1762 if (multibyte_p)
1763 {
1764 ptrdiff_t rest = strlen (s);
1765 int len;
1766 const unsigned char *p = (const unsigned char *) s;
1767
1768 for (nchars = 0; rest > 0; ++nchars)
1769 {
1770 string_char_and_length (p, &len);
1771 rest -= len, p += len;
1772 }
1773 }
1774 else
1775 nchars = strlen (s);
1776
1777 return nchars;
1778 }
1779
1780
1781 /* Compute byte position NEWPOS->bytepos corresponding to
1782 NEWPOS->charpos. POS is a known position in string STRING.
1783 NEWPOS->charpos must be >= POS.charpos. */
1784
1785 static void
1786 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1787 {
1788 eassert (STRINGP (string));
1789 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1790
1791 if (STRING_MULTIBYTE (string))
1792 *newpos = string_pos_nchars_ahead (pos, string,
1793 CHARPOS (*newpos) - CHARPOS (pos));
1794 else
1795 BYTEPOS (*newpos) = CHARPOS (*newpos);
1796 }
1797
1798 /* EXPORT:
1799 Return an estimation of the pixel height of mode or header lines on
1800 frame F. FACE_ID specifies what line's height to estimate. */
1801
1802 int
1803 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1804 {
1805 #ifdef HAVE_WINDOW_SYSTEM
1806 if (FRAME_WINDOW_P (f))
1807 {
1808 int height = FONT_HEIGHT (FRAME_FONT (f));
1809
1810 /* This function is called so early when Emacs starts that the face
1811 cache and mode line face are not yet initialized. */
1812 if (FRAME_FACE_CACHE (f))
1813 {
1814 struct face *face = FACE_FROM_ID (f, face_id);
1815 if (face)
1816 {
1817 if (face->font)
1818 height = FONT_HEIGHT (face->font);
1819 if (face->box_line_width > 0)
1820 height += 2 * face->box_line_width;
1821 }
1822 }
1823
1824 return height;
1825 }
1826 #endif
1827
1828 return 1;
1829 }
1830
1831 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1832 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1833 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1834 not force the value into range. */
1835
1836 void
1837 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1838 int *x, int *y, NativeRectangle *bounds, int noclip)
1839 {
1840
1841 #ifdef HAVE_WINDOW_SYSTEM
1842 if (FRAME_WINDOW_P (f))
1843 {
1844 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1845 even for negative values. */
1846 if (pix_x < 0)
1847 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1848 if (pix_y < 0)
1849 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1850
1851 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1852 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1853
1854 if (bounds)
1855 STORE_NATIVE_RECT (*bounds,
1856 FRAME_COL_TO_PIXEL_X (f, pix_x),
1857 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1858 FRAME_COLUMN_WIDTH (f) - 1,
1859 FRAME_LINE_HEIGHT (f) - 1);
1860
1861 if (!noclip)
1862 {
1863 if (pix_x < 0)
1864 pix_x = 0;
1865 else if (pix_x > FRAME_TOTAL_COLS (f))
1866 pix_x = FRAME_TOTAL_COLS (f);
1867
1868 if (pix_y < 0)
1869 pix_y = 0;
1870 else if (pix_y > FRAME_LINES (f))
1871 pix_y = FRAME_LINES (f);
1872 }
1873 }
1874 #endif
1875
1876 *x = pix_x;
1877 *y = pix_y;
1878 }
1879
1880
1881 /* Find the glyph under window-relative coordinates X/Y in window W.
1882 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1883 strings. Return in *HPOS and *VPOS the row and column number of
1884 the glyph found. Return in *AREA the glyph area containing X.
1885 Value is a pointer to the glyph found or null if X/Y is not on
1886 text, or we can't tell because W's current matrix is not up to
1887 date. */
1888
1889 static
1890 struct glyph *
1891 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1892 int *dx, int *dy, int *area)
1893 {
1894 struct glyph *glyph, *end;
1895 struct glyph_row *row = NULL;
1896 int x0, i;
1897
1898 /* Find row containing Y. Give up if some row is not enabled. */
1899 for (i = 0; i < w->current_matrix->nrows; ++i)
1900 {
1901 row = MATRIX_ROW (w->current_matrix, i);
1902 if (!row->enabled_p)
1903 return NULL;
1904 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1905 break;
1906 }
1907
1908 *vpos = i;
1909 *hpos = 0;
1910
1911 /* Give up if Y is not in the window. */
1912 if (i == w->current_matrix->nrows)
1913 return NULL;
1914
1915 /* Get the glyph area containing X. */
1916 if (w->pseudo_window_p)
1917 {
1918 *area = TEXT_AREA;
1919 x0 = 0;
1920 }
1921 else
1922 {
1923 if (x < window_box_left_offset (w, TEXT_AREA))
1924 {
1925 *area = LEFT_MARGIN_AREA;
1926 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1927 }
1928 else if (x < window_box_right_offset (w, TEXT_AREA))
1929 {
1930 *area = TEXT_AREA;
1931 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1932 }
1933 else
1934 {
1935 *area = RIGHT_MARGIN_AREA;
1936 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1937 }
1938 }
1939
1940 /* Find glyph containing X. */
1941 glyph = row->glyphs[*area];
1942 end = glyph + row->used[*area];
1943 x -= x0;
1944 while (glyph < end && x >= glyph->pixel_width)
1945 {
1946 x -= glyph->pixel_width;
1947 ++glyph;
1948 }
1949
1950 if (glyph == end)
1951 return NULL;
1952
1953 if (dx)
1954 {
1955 *dx = x;
1956 *dy = y - (row->y + row->ascent - glyph->ascent);
1957 }
1958
1959 *hpos = glyph - row->glyphs[*area];
1960 return glyph;
1961 }
1962
1963 /* Convert frame-relative x/y to coordinates relative to window W.
1964 Takes pseudo-windows into account. */
1965
1966 static void
1967 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1968 {
1969 if (w->pseudo_window_p)
1970 {
1971 /* A pseudo-window is always full-width, and starts at the
1972 left edge of the frame, plus a frame border. */
1973 struct frame *f = XFRAME (w->frame);
1974 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1975 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1976 }
1977 else
1978 {
1979 *x -= WINDOW_LEFT_EDGE_X (w);
1980 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1981 }
1982 }
1983
1984 #ifdef HAVE_WINDOW_SYSTEM
1985
1986 /* EXPORT:
1987 Return in RECTS[] at most N clipping rectangles for glyph string S.
1988 Return the number of stored rectangles. */
1989
1990 int
1991 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1992 {
1993 XRectangle r;
1994
1995 if (n <= 0)
1996 return 0;
1997
1998 if (s->row->full_width_p)
1999 {
2000 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2001 r.x = WINDOW_LEFT_EDGE_X (s->w);
2002 r.width = WINDOW_TOTAL_WIDTH (s->w);
2003
2004 /* Unless displaying a mode or menu bar line, which are always
2005 fully visible, clip to the visible part of the row. */
2006 if (s->w->pseudo_window_p)
2007 r.height = s->row->visible_height;
2008 else
2009 r.height = s->height;
2010 }
2011 else
2012 {
2013 /* This is a text line that may be partially visible. */
2014 r.x = window_box_left (s->w, s->area);
2015 r.width = window_box_width (s->w, s->area);
2016 r.height = s->row->visible_height;
2017 }
2018
2019 if (s->clip_head)
2020 if (r.x < s->clip_head->x)
2021 {
2022 if (r.width >= s->clip_head->x - r.x)
2023 r.width -= s->clip_head->x - r.x;
2024 else
2025 r.width = 0;
2026 r.x = s->clip_head->x;
2027 }
2028 if (s->clip_tail)
2029 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2030 {
2031 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2032 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2033 else
2034 r.width = 0;
2035 }
2036
2037 /* If S draws overlapping rows, it's sufficient to use the top and
2038 bottom of the window for clipping because this glyph string
2039 intentionally draws over other lines. */
2040 if (s->for_overlaps)
2041 {
2042 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2043 r.height = window_text_bottom_y (s->w) - r.y;
2044
2045 /* Alas, the above simple strategy does not work for the
2046 environments with anti-aliased text: if the same text is
2047 drawn onto the same place multiple times, it gets thicker.
2048 If the overlap we are processing is for the erased cursor, we
2049 take the intersection with the rectangle of the cursor. */
2050 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2051 {
2052 XRectangle rc, r_save = r;
2053
2054 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2055 rc.y = s->w->phys_cursor.y;
2056 rc.width = s->w->phys_cursor_width;
2057 rc.height = s->w->phys_cursor_height;
2058
2059 x_intersect_rectangles (&r_save, &rc, &r);
2060 }
2061 }
2062 else
2063 {
2064 /* Don't use S->y for clipping because it doesn't take partially
2065 visible lines into account. For example, it can be negative for
2066 partially visible lines at the top of a window. */
2067 if (!s->row->full_width_p
2068 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2069 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2070 else
2071 r.y = max (0, s->row->y);
2072 }
2073
2074 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2075
2076 /* If drawing the cursor, don't let glyph draw outside its
2077 advertised boundaries. Cleartype does this under some circumstances. */
2078 if (s->hl == DRAW_CURSOR)
2079 {
2080 struct glyph *glyph = s->first_glyph;
2081 int height, max_y;
2082
2083 if (s->x > r.x)
2084 {
2085 r.width -= s->x - r.x;
2086 r.x = s->x;
2087 }
2088 r.width = min (r.width, glyph->pixel_width);
2089
2090 /* If r.y is below window bottom, ensure that we still see a cursor. */
2091 height = min (glyph->ascent + glyph->descent,
2092 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2093 max_y = window_text_bottom_y (s->w) - height;
2094 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2095 if (s->ybase - glyph->ascent > max_y)
2096 {
2097 r.y = max_y;
2098 r.height = height;
2099 }
2100 else
2101 {
2102 /* Don't draw cursor glyph taller than our actual glyph. */
2103 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2104 if (height < r.height)
2105 {
2106 max_y = r.y + r.height;
2107 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2108 r.height = min (max_y - r.y, height);
2109 }
2110 }
2111 }
2112
2113 if (s->row->clip)
2114 {
2115 XRectangle r_save = r;
2116
2117 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2118 r.width = 0;
2119 }
2120
2121 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2122 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2123 {
2124 #ifdef CONVERT_FROM_XRECT
2125 CONVERT_FROM_XRECT (r, *rects);
2126 #else
2127 *rects = r;
2128 #endif
2129 return 1;
2130 }
2131 else
2132 {
2133 /* If we are processing overlapping and allowed to return
2134 multiple clipping rectangles, we exclude the row of the glyph
2135 string from the clipping rectangle. This is to avoid drawing
2136 the same text on the environment with anti-aliasing. */
2137 #ifdef CONVERT_FROM_XRECT
2138 XRectangle rs[2];
2139 #else
2140 XRectangle *rs = rects;
2141 #endif
2142 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2143
2144 if (s->for_overlaps & OVERLAPS_PRED)
2145 {
2146 rs[i] = r;
2147 if (r.y + r.height > row_y)
2148 {
2149 if (r.y < row_y)
2150 rs[i].height = row_y - r.y;
2151 else
2152 rs[i].height = 0;
2153 }
2154 i++;
2155 }
2156 if (s->for_overlaps & OVERLAPS_SUCC)
2157 {
2158 rs[i] = r;
2159 if (r.y < row_y + s->row->visible_height)
2160 {
2161 if (r.y + r.height > row_y + s->row->visible_height)
2162 {
2163 rs[i].y = row_y + s->row->visible_height;
2164 rs[i].height = r.y + r.height - rs[i].y;
2165 }
2166 else
2167 rs[i].height = 0;
2168 }
2169 i++;
2170 }
2171
2172 n = i;
2173 #ifdef CONVERT_FROM_XRECT
2174 for (i = 0; i < n; i++)
2175 CONVERT_FROM_XRECT (rs[i], rects[i]);
2176 #endif
2177 return n;
2178 }
2179 }
2180
2181 /* EXPORT:
2182 Return in *NR the clipping rectangle for glyph string S. */
2183
2184 void
2185 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2186 {
2187 get_glyph_string_clip_rects (s, nr, 1);
2188 }
2189
2190
2191 /* EXPORT:
2192 Return the position and height of the phys cursor in window W.
2193 Set w->phys_cursor_width to width of phys cursor.
2194 */
2195
2196 void
2197 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2198 struct glyph *glyph, int *xp, int *yp, int *heightp)
2199 {
2200 struct frame *f = XFRAME (WINDOW_FRAME (w));
2201 int x, y, wd, h, h0, y0;
2202
2203 /* Compute the width of the rectangle to draw. If on a stretch
2204 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2205 rectangle as wide as the glyph, but use a canonical character
2206 width instead. */
2207 wd = glyph->pixel_width - 1;
2208 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2209 wd++; /* Why? */
2210 #endif
2211
2212 x = w->phys_cursor.x;
2213 if (x < 0)
2214 {
2215 wd += x;
2216 x = 0;
2217 }
2218
2219 if (glyph->type == STRETCH_GLYPH
2220 && !x_stretch_cursor_p)
2221 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2222 w->phys_cursor_width = wd;
2223
2224 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2225
2226 /* If y is below window bottom, ensure that we still see a cursor. */
2227 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2228
2229 h = max (h0, glyph->ascent + glyph->descent);
2230 h0 = min (h0, glyph->ascent + glyph->descent);
2231
2232 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2233 if (y < y0)
2234 {
2235 h = max (h - (y0 - y) + 1, h0);
2236 y = y0 - 1;
2237 }
2238 else
2239 {
2240 y0 = window_text_bottom_y (w) - h0;
2241 if (y > y0)
2242 {
2243 h += y - y0;
2244 y = y0;
2245 }
2246 }
2247
2248 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2249 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2250 *heightp = h;
2251 }
2252
2253 /*
2254 * Remember which glyph the mouse is over.
2255 */
2256
2257 void
2258 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2259 {
2260 Lisp_Object window;
2261 struct window *w;
2262 struct glyph_row *r, *gr, *end_row;
2263 enum window_part part;
2264 enum glyph_row_area area;
2265 int x, y, width, height;
2266
2267 /* Try to determine frame pixel position and size of the glyph under
2268 frame pixel coordinates X/Y on frame F. */
2269
2270 if (!f->glyphs_initialized_p
2271 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2272 NILP (window)))
2273 {
2274 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2275 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2276 goto virtual_glyph;
2277 }
2278
2279 w = XWINDOW (window);
2280 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2281 height = WINDOW_FRAME_LINE_HEIGHT (w);
2282
2283 x = window_relative_x_coord (w, part, gx);
2284 y = gy - WINDOW_TOP_EDGE_Y (w);
2285
2286 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2287 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2288
2289 if (w->pseudo_window_p)
2290 {
2291 area = TEXT_AREA;
2292 part = ON_MODE_LINE; /* Don't adjust margin. */
2293 goto text_glyph;
2294 }
2295
2296 switch (part)
2297 {
2298 case ON_LEFT_MARGIN:
2299 area = LEFT_MARGIN_AREA;
2300 goto text_glyph;
2301
2302 case ON_RIGHT_MARGIN:
2303 area = RIGHT_MARGIN_AREA;
2304 goto text_glyph;
2305
2306 case ON_HEADER_LINE:
2307 case ON_MODE_LINE:
2308 gr = (part == ON_HEADER_LINE
2309 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2310 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2311 gy = gr->y;
2312 area = TEXT_AREA;
2313 goto text_glyph_row_found;
2314
2315 case ON_TEXT:
2316 area = TEXT_AREA;
2317
2318 text_glyph:
2319 gr = 0; gy = 0;
2320 for (; r <= end_row && r->enabled_p; ++r)
2321 if (r->y + r->height > y)
2322 {
2323 gr = r; gy = r->y;
2324 break;
2325 }
2326
2327 text_glyph_row_found:
2328 if (gr && gy <= y)
2329 {
2330 struct glyph *g = gr->glyphs[area];
2331 struct glyph *end = g + gr->used[area];
2332
2333 height = gr->height;
2334 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2335 if (gx + g->pixel_width > x)
2336 break;
2337
2338 if (g < end)
2339 {
2340 if (g->type == IMAGE_GLYPH)
2341 {
2342 /* Don't remember when mouse is over image, as
2343 image may have hot-spots. */
2344 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2345 return;
2346 }
2347 width = g->pixel_width;
2348 }
2349 else
2350 {
2351 /* Use nominal char spacing at end of line. */
2352 x -= gx;
2353 gx += (x / width) * width;
2354 }
2355
2356 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2357 gx += window_box_left_offset (w, area);
2358 }
2359 else
2360 {
2361 /* Use nominal line height at end of window. */
2362 gx = (x / width) * width;
2363 y -= gy;
2364 gy += (y / height) * height;
2365 }
2366 break;
2367
2368 case ON_LEFT_FRINGE:
2369 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2370 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2371 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2372 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2373 goto row_glyph;
2374
2375 case ON_RIGHT_FRINGE:
2376 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2377 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2378 : window_box_right_offset (w, TEXT_AREA));
2379 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2380 goto row_glyph;
2381
2382 case ON_SCROLL_BAR:
2383 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2384 ? 0
2385 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2386 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2387 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2388 : 0)));
2389 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2390
2391 row_glyph:
2392 gr = 0, gy = 0;
2393 for (; r <= end_row && r->enabled_p; ++r)
2394 if (r->y + r->height > y)
2395 {
2396 gr = r; gy = r->y;
2397 break;
2398 }
2399
2400 if (gr && gy <= y)
2401 height = gr->height;
2402 else
2403 {
2404 /* Use nominal line height at end of window. */
2405 y -= gy;
2406 gy += (y / height) * height;
2407 }
2408 break;
2409
2410 default:
2411 ;
2412 virtual_glyph:
2413 /* If there is no glyph under the mouse, then we divide the screen
2414 into a grid of the smallest glyph in the frame, and use that
2415 as our "glyph". */
2416
2417 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2418 round down even for negative values. */
2419 if (gx < 0)
2420 gx -= width - 1;
2421 if (gy < 0)
2422 gy -= height - 1;
2423
2424 gx = (gx / width) * width;
2425 gy = (gy / height) * height;
2426
2427 goto store_rect;
2428 }
2429
2430 gx += WINDOW_LEFT_EDGE_X (w);
2431 gy += WINDOW_TOP_EDGE_Y (w);
2432
2433 store_rect:
2434 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2435
2436 /* Visible feedback for debugging. */
2437 #if 0
2438 #if HAVE_X_WINDOWS
2439 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2440 f->output_data.x->normal_gc,
2441 gx, gy, width, height);
2442 #endif
2443 #endif
2444 }
2445
2446
2447 #endif /* HAVE_WINDOW_SYSTEM */
2448
2449 static void
2450 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2451 {
2452 eassert (w);
2453 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2454 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2455 w->window_end_vpos
2456 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2457 }
2458
2459 /***********************************************************************
2460 Lisp form evaluation
2461 ***********************************************************************/
2462
2463 /* Error handler for safe_eval and safe_call. */
2464
2465 static Lisp_Object
2466 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2467 {
2468 add_to_log ("Error during redisplay: %S signaled %S",
2469 Flist (nargs, args), arg);
2470 return Qnil;
2471 }
2472
2473 /* Call function FUNC with the rest of NARGS - 1 arguments
2474 following. Return the result, or nil if something went
2475 wrong. Prevent redisplay during the evaluation. */
2476
2477 Lisp_Object
2478 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2479 {
2480 Lisp_Object val;
2481
2482 if (inhibit_eval_during_redisplay)
2483 val = Qnil;
2484 else
2485 {
2486 va_list ap;
2487 ptrdiff_t i;
2488 ptrdiff_t count = SPECPDL_INDEX ();
2489 struct gcpro gcpro1;
2490 Lisp_Object *args = alloca (nargs * word_size);
2491
2492 args[0] = func;
2493 va_start (ap, func);
2494 for (i = 1; i < nargs; i++)
2495 args[i] = va_arg (ap, Lisp_Object);
2496 va_end (ap);
2497
2498 GCPRO1 (args[0]);
2499 gcpro1.nvars = nargs;
2500 specbind (Qinhibit_redisplay, Qt);
2501 /* Use Qt to ensure debugger does not run,
2502 so there is no possibility of wanting to redisplay. */
2503 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2504 safe_eval_handler);
2505 UNGCPRO;
2506 val = unbind_to (count, val);
2507 }
2508
2509 return val;
2510 }
2511
2512
2513 /* Call function FN with one argument ARG.
2514 Return the result, or nil if something went wrong. */
2515
2516 Lisp_Object
2517 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2518 {
2519 return safe_call (2, fn, arg);
2520 }
2521
2522 static Lisp_Object Qeval;
2523
2524 Lisp_Object
2525 safe_eval (Lisp_Object sexpr)
2526 {
2527 return safe_call1 (Qeval, sexpr);
2528 }
2529
2530 /* Call function FN with two arguments ARG1 and ARG2.
2531 Return the result, or nil if something went wrong. */
2532
2533 Lisp_Object
2534 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2535 {
2536 return safe_call (3, fn, arg1, arg2);
2537 }
2538
2539
2540 \f
2541 /***********************************************************************
2542 Debugging
2543 ***********************************************************************/
2544
2545 #if 0
2546
2547 /* Define CHECK_IT to perform sanity checks on iterators.
2548 This is for debugging. It is too slow to do unconditionally. */
2549
2550 static void
2551 check_it (struct it *it)
2552 {
2553 if (it->method == GET_FROM_STRING)
2554 {
2555 eassert (STRINGP (it->string));
2556 eassert (IT_STRING_CHARPOS (*it) >= 0);
2557 }
2558 else
2559 {
2560 eassert (IT_STRING_CHARPOS (*it) < 0);
2561 if (it->method == GET_FROM_BUFFER)
2562 {
2563 /* Check that character and byte positions agree. */
2564 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2565 }
2566 }
2567
2568 if (it->dpvec)
2569 eassert (it->current.dpvec_index >= 0);
2570 else
2571 eassert (it->current.dpvec_index < 0);
2572 }
2573
2574 #define CHECK_IT(IT) check_it ((IT))
2575
2576 #else /* not 0 */
2577
2578 #define CHECK_IT(IT) (void) 0
2579
2580 #endif /* not 0 */
2581
2582
2583 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2584
2585 /* Check that the window end of window W is what we expect it
2586 to be---the last row in the current matrix displaying text. */
2587
2588 static void
2589 check_window_end (struct window *w)
2590 {
2591 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2592 {
2593 struct glyph_row *row;
2594 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2595 !row->enabled_p
2596 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2597 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2598 }
2599 }
2600
2601 #define CHECK_WINDOW_END(W) check_window_end ((W))
2602
2603 #else
2604
2605 #define CHECK_WINDOW_END(W) (void) 0
2606
2607 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2608
2609 /* Return mark position if current buffer has the region of non-zero length,
2610 or -1 otherwise. */
2611
2612 static ptrdiff_t
2613 markpos_of_region (void)
2614 {
2615 if (!NILP (Vtransient_mark_mode)
2616 && !NILP (BVAR (current_buffer, mark_active))
2617 && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
2618 {
2619 ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
2620
2621 if (markpos != PT)
2622 return markpos;
2623 }
2624 return -1;
2625 }
2626
2627 /***********************************************************************
2628 Iterator initialization
2629 ***********************************************************************/
2630
2631 /* Initialize IT for displaying current_buffer in window W, starting
2632 at character position CHARPOS. CHARPOS < 0 means that no buffer
2633 position is specified which is useful when the iterator is assigned
2634 a position later. BYTEPOS is the byte position corresponding to
2635 CHARPOS.
2636
2637 If ROW is not null, calls to produce_glyphs with IT as parameter
2638 will produce glyphs in that row.
2639
2640 BASE_FACE_ID is the id of a base face to use. It must be one of
2641 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2642 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2643 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2644
2645 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2646 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2647 will be initialized to use the corresponding mode line glyph row of
2648 the desired matrix of W. */
2649
2650 void
2651 init_iterator (struct it *it, struct window *w,
2652 ptrdiff_t charpos, ptrdiff_t bytepos,
2653 struct glyph_row *row, enum face_id base_face_id)
2654 {
2655 ptrdiff_t markpos;
2656 enum face_id remapped_base_face_id = base_face_id;
2657
2658 /* Some precondition checks. */
2659 eassert (w != NULL && it != NULL);
2660 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2661 && charpos <= ZV));
2662
2663 /* If face attributes have been changed since the last redisplay,
2664 free realized faces now because they depend on face definitions
2665 that might have changed. Don't free faces while there might be
2666 desired matrices pending which reference these faces. */
2667 if (face_change_count && !inhibit_free_realized_faces)
2668 {
2669 face_change_count = 0;
2670 free_all_realized_faces (Qnil);
2671 }
2672
2673 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2674 if (! NILP (Vface_remapping_alist))
2675 remapped_base_face_id
2676 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2677
2678 /* Use one of the mode line rows of W's desired matrix if
2679 appropriate. */
2680 if (row == NULL)
2681 {
2682 if (base_face_id == MODE_LINE_FACE_ID
2683 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2684 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2685 else if (base_face_id == HEADER_LINE_FACE_ID)
2686 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2687 }
2688
2689 /* Clear IT. */
2690 memset (it, 0, sizeof *it);
2691 it->current.overlay_string_index = -1;
2692 it->current.dpvec_index = -1;
2693 it->base_face_id = remapped_base_face_id;
2694 it->string = Qnil;
2695 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2696 it->paragraph_embedding = L2R;
2697 it->bidi_it.string.lstring = Qnil;
2698 it->bidi_it.string.s = NULL;
2699 it->bidi_it.string.bufpos = 0;
2700 it->bidi_it.w = w;
2701
2702 /* The window in which we iterate over current_buffer: */
2703 XSETWINDOW (it->window, w);
2704 it->w = w;
2705 it->f = XFRAME (w->frame);
2706
2707 it->cmp_it.id = -1;
2708
2709 /* Extra space between lines (on window systems only). */
2710 if (base_face_id == DEFAULT_FACE_ID
2711 && FRAME_WINDOW_P (it->f))
2712 {
2713 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2714 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2715 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2716 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2717 * FRAME_LINE_HEIGHT (it->f));
2718 else if (it->f->extra_line_spacing > 0)
2719 it->extra_line_spacing = it->f->extra_line_spacing;
2720 it->max_extra_line_spacing = 0;
2721 }
2722
2723 /* If realized faces have been removed, e.g. because of face
2724 attribute changes of named faces, recompute them. When running
2725 in batch mode, the face cache of the initial frame is null. If
2726 we happen to get called, make a dummy face cache. */
2727 if (FRAME_FACE_CACHE (it->f) == NULL)
2728 init_frame_faces (it->f);
2729 if (FRAME_FACE_CACHE (it->f)->used == 0)
2730 recompute_basic_faces (it->f);
2731
2732 /* Current value of the `slice', `space-width', and 'height' properties. */
2733 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2734 it->space_width = Qnil;
2735 it->font_height = Qnil;
2736 it->override_ascent = -1;
2737
2738 /* Are control characters displayed as `^C'? */
2739 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2740
2741 /* -1 means everything between a CR and the following line end
2742 is invisible. >0 means lines indented more than this value are
2743 invisible. */
2744 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2745 ? (clip_to_bounds
2746 (-1, XINT (BVAR (current_buffer, selective_display)),
2747 PTRDIFF_MAX))
2748 : (!NILP (BVAR (current_buffer, selective_display))
2749 ? -1 : 0));
2750 it->selective_display_ellipsis_p
2751 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2752
2753 /* Display table to use. */
2754 it->dp = window_display_table (w);
2755
2756 /* Are multibyte characters enabled in current_buffer? */
2757 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2758
2759 /* If visible region is of non-zero length, set IT->region_beg_charpos
2760 and IT->region_end_charpos to the start and end of a visible region
2761 in window IT->w. Set both to -1 to indicate no region. */
2762 markpos = markpos_of_region ();
2763 if (markpos >= 0
2764 /* Maybe highlight only in selected window. */
2765 && (/* Either show region everywhere. */
2766 highlight_nonselected_windows
2767 /* Or show region in the selected window. */
2768 || w == XWINDOW (selected_window)
2769 /* Or show the region if we are in the mini-buffer and W is
2770 the window the mini-buffer refers to. */
2771 || (MINI_WINDOW_P (XWINDOW (selected_window))
2772 && WINDOWP (minibuf_selected_window)
2773 && w == XWINDOW (minibuf_selected_window))))
2774 {
2775 it->region_beg_charpos = min (PT, markpos);
2776 it->region_end_charpos = max (PT, markpos);
2777 }
2778 else
2779 it->region_beg_charpos = it->region_end_charpos = -1;
2780
2781 /* Get the position at which the redisplay_end_trigger hook should
2782 be run, if it is to be run at all. */
2783 if (MARKERP (w->redisplay_end_trigger)
2784 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2785 it->redisplay_end_trigger_charpos
2786 = marker_position (w->redisplay_end_trigger);
2787 else if (INTEGERP (w->redisplay_end_trigger))
2788 it->redisplay_end_trigger_charpos =
2789 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2790
2791 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2792
2793 /* Are lines in the display truncated? */
2794 if (base_face_id != DEFAULT_FACE_ID
2795 || it->w->hscroll
2796 || (! WINDOW_FULL_WIDTH_P (it->w)
2797 && ((!NILP (Vtruncate_partial_width_windows)
2798 && !INTEGERP (Vtruncate_partial_width_windows))
2799 || (INTEGERP (Vtruncate_partial_width_windows)
2800 && (WINDOW_TOTAL_COLS (it->w)
2801 < XINT (Vtruncate_partial_width_windows))))))
2802 it->line_wrap = TRUNCATE;
2803 else if (NILP (BVAR (current_buffer, truncate_lines)))
2804 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2805 ? WINDOW_WRAP : WORD_WRAP;
2806 else
2807 it->line_wrap = TRUNCATE;
2808
2809 /* Get dimensions of truncation and continuation glyphs. These are
2810 displayed as fringe bitmaps under X, but we need them for such
2811 frames when the fringes are turned off. But leave the dimensions
2812 zero for tooltip frames, as these glyphs look ugly there and also
2813 sabotage calculations of tooltip dimensions in x-show-tip. */
2814 #ifdef HAVE_WINDOW_SYSTEM
2815 if (!(FRAME_WINDOW_P (it->f)
2816 && FRAMEP (tip_frame)
2817 && it->f == XFRAME (tip_frame)))
2818 #endif
2819 {
2820 if (it->line_wrap == TRUNCATE)
2821 {
2822 /* We will need the truncation glyph. */
2823 eassert (it->glyph_row == NULL);
2824 produce_special_glyphs (it, IT_TRUNCATION);
2825 it->truncation_pixel_width = it->pixel_width;
2826 }
2827 else
2828 {
2829 /* We will need the continuation glyph. */
2830 eassert (it->glyph_row == NULL);
2831 produce_special_glyphs (it, IT_CONTINUATION);
2832 it->continuation_pixel_width = it->pixel_width;
2833 }
2834 }
2835
2836 /* Reset these values to zero because the produce_special_glyphs
2837 above has changed them. */
2838 it->pixel_width = it->ascent = it->descent = 0;
2839 it->phys_ascent = it->phys_descent = 0;
2840
2841 /* Set this after getting the dimensions of truncation and
2842 continuation glyphs, so that we don't produce glyphs when calling
2843 produce_special_glyphs, above. */
2844 it->glyph_row = row;
2845 it->area = TEXT_AREA;
2846
2847 /* Forget any previous info about this row being reversed. */
2848 if (it->glyph_row)
2849 it->glyph_row->reversed_p = 0;
2850
2851 /* Get the dimensions of the display area. The display area
2852 consists of the visible window area plus a horizontally scrolled
2853 part to the left of the window. All x-values are relative to the
2854 start of this total display area. */
2855 if (base_face_id != DEFAULT_FACE_ID)
2856 {
2857 /* Mode lines, menu bar in terminal frames. */
2858 it->first_visible_x = 0;
2859 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2860 }
2861 else
2862 {
2863 it->first_visible_x =
2864 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2865 it->last_visible_x = (it->first_visible_x
2866 + window_box_width (w, TEXT_AREA));
2867
2868 /* If we truncate lines, leave room for the truncation glyph(s) at
2869 the right margin. Otherwise, leave room for the continuation
2870 glyph(s). Done only if the window has no fringes. Since we
2871 don't know at this point whether there will be any R2L lines in
2872 the window, we reserve space for truncation/continuation glyphs
2873 even if only one of the fringes is absent. */
2874 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2875 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2876 {
2877 if (it->line_wrap == TRUNCATE)
2878 it->last_visible_x -= it->truncation_pixel_width;
2879 else
2880 it->last_visible_x -= it->continuation_pixel_width;
2881 }
2882
2883 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2884 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2885 }
2886
2887 /* Leave room for a border glyph. */
2888 if (!FRAME_WINDOW_P (it->f)
2889 && !WINDOW_RIGHTMOST_P (it->w))
2890 it->last_visible_x -= 1;
2891
2892 it->last_visible_y = window_text_bottom_y (w);
2893
2894 /* For mode lines and alike, arrange for the first glyph having a
2895 left box line if the face specifies a box. */
2896 if (base_face_id != DEFAULT_FACE_ID)
2897 {
2898 struct face *face;
2899
2900 it->face_id = remapped_base_face_id;
2901
2902 /* If we have a boxed mode line, make the first character appear
2903 with a left box line. */
2904 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2905 if (face->box != FACE_NO_BOX)
2906 it->start_of_box_run_p = 1;
2907 }
2908
2909 /* If a buffer position was specified, set the iterator there,
2910 getting overlays and face properties from that position. */
2911 if (charpos >= BUF_BEG (current_buffer))
2912 {
2913 it->end_charpos = ZV;
2914 eassert (charpos == BYTE_TO_CHAR (bytepos));
2915 IT_CHARPOS (*it) = charpos;
2916 IT_BYTEPOS (*it) = bytepos;
2917
2918 /* We will rely on `reseat' to set this up properly, via
2919 handle_face_prop. */
2920 it->face_id = it->base_face_id;
2921
2922 it->start = it->current;
2923 /* Do we need to reorder bidirectional text? Not if this is a
2924 unibyte buffer: by definition, none of the single-byte
2925 characters are strong R2L, so no reordering is needed. And
2926 bidi.c doesn't support unibyte buffers anyway. Also, don't
2927 reorder while we are loading loadup.el, since the tables of
2928 character properties needed for reordering are not yet
2929 available. */
2930 it->bidi_p =
2931 NILP (Vpurify_flag)
2932 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2933 && it->multibyte_p;
2934
2935 /* If we are to reorder bidirectional text, init the bidi
2936 iterator. */
2937 if (it->bidi_p)
2938 {
2939 /* Note the paragraph direction that this buffer wants to
2940 use. */
2941 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2942 Qleft_to_right))
2943 it->paragraph_embedding = L2R;
2944 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2945 Qright_to_left))
2946 it->paragraph_embedding = R2L;
2947 else
2948 it->paragraph_embedding = NEUTRAL_DIR;
2949 bidi_unshelve_cache (NULL, 0);
2950 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2951 &it->bidi_it);
2952 }
2953
2954 /* Compute faces etc. */
2955 reseat (it, it->current.pos, 1);
2956 }
2957
2958 CHECK_IT (it);
2959 }
2960
2961
2962 /* Initialize IT for the display of window W with window start POS. */
2963
2964 void
2965 start_display (struct it *it, struct window *w, struct text_pos pos)
2966 {
2967 struct glyph_row *row;
2968 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2969
2970 row = w->desired_matrix->rows + first_vpos;
2971 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2972 it->first_vpos = first_vpos;
2973
2974 /* Don't reseat to previous visible line start if current start
2975 position is in a string or image. */
2976 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2977 {
2978 int start_at_line_beg_p;
2979 int first_y = it->current_y;
2980
2981 /* If window start is not at a line start, skip forward to POS to
2982 get the correct continuation lines width. */
2983 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2984 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2985 if (!start_at_line_beg_p)
2986 {
2987 int new_x;
2988
2989 reseat_at_previous_visible_line_start (it);
2990 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2991
2992 new_x = it->current_x + it->pixel_width;
2993
2994 /* If lines are continued, this line may end in the middle
2995 of a multi-glyph character (e.g. a control character
2996 displayed as \003, or in the middle of an overlay
2997 string). In this case move_it_to above will not have
2998 taken us to the start of the continuation line but to the
2999 end of the continued line. */
3000 if (it->current_x > 0
3001 && it->line_wrap != TRUNCATE /* Lines are continued. */
3002 && (/* And glyph doesn't fit on the line. */
3003 new_x > it->last_visible_x
3004 /* Or it fits exactly and we're on a window
3005 system frame. */
3006 || (new_x == it->last_visible_x
3007 && FRAME_WINDOW_P (it->f)
3008 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3009 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3010 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3011 {
3012 if ((it->current.dpvec_index >= 0
3013 || it->current.overlay_string_index >= 0)
3014 /* If we are on a newline from a display vector or
3015 overlay string, then we are already at the end of
3016 a screen line; no need to go to the next line in
3017 that case, as this line is not really continued.
3018 (If we do go to the next line, C-e will not DTRT.) */
3019 && it->c != '\n')
3020 {
3021 set_iterator_to_next (it, 1);
3022 move_it_in_display_line_to (it, -1, -1, 0);
3023 }
3024
3025 it->continuation_lines_width += it->current_x;
3026 }
3027 /* If the character at POS is displayed via a display
3028 vector, move_it_to above stops at the final glyph of
3029 IT->dpvec. To make the caller redisplay that character
3030 again (a.k.a. start at POS), we need to reset the
3031 dpvec_index to the beginning of IT->dpvec. */
3032 else if (it->current.dpvec_index >= 0)
3033 it->current.dpvec_index = 0;
3034
3035 /* We're starting a new display line, not affected by the
3036 height of the continued line, so clear the appropriate
3037 fields in the iterator structure. */
3038 it->max_ascent = it->max_descent = 0;
3039 it->max_phys_ascent = it->max_phys_descent = 0;
3040
3041 it->current_y = first_y;
3042 it->vpos = 0;
3043 it->current_x = it->hpos = 0;
3044 }
3045 }
3046 }
3047
3048
3049 /* Return 1 if POS is a position in ellipses displayed for invisible
3050 text. W is the window we display, for text property lookup. */
3051
3052 static int
3053 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3054 {
3055 Lisp_Object prop, window;
3056 int ellipses_p = 0;
3057 ptrdiff_t charpos = CHARPOS (pos->pos);
3058
3059 /* If POS specifies a position in a display vector, this might
3060 be for an ellipsis displayed for invisible text. We won't
3061 get the iterator set up for delivering that ellipsis unless
3062 we make sure that it gets aware of the invisible text. */
3063 if (pos->dpvec_index >= 0
3064 && pos->overlay_string_index < 0
3065 && CHARPOS (pos->string_pos) < 0
3066 && charpos > BEGV
3067 && (XSETWINDOW (window, w),
3068 prop = Fget_char_property (make_number (charpos),
3069 Qinvisible, window),
3070 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3071 {
3072 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3073 window);
3074 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3075 }
3076
3077 return ellipses_p;
3078 }
3079
3080
3081 /* Initialize IT for stepping through current_buffer in window W,
3082 starting at position POS that includes overlay string and display
3083 vector/ control character translation position information. Value
3084 is zero if there are overlay strings with newlines at POS. */
3085
3086 static int
3087 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3088 {
3089 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3090 int i, overlay_strings_with_newlines = 0;
3091
3092 /* If POS specifies a position in a display vector, this might
3093 be for an ellipsis displayed for invisible text. We won't
3094 get the iterator set up for delivering that ellipsis unless
3095 we make sure that it gets aware of the invisible text. */
3096 if (in_ellipses_for_invisible_text_p (pos, w))
3097 {
3098 --charpos;
3099 bytepos = 0;
3100 }
3101
3102 /* Keep in mind: the call to reseat in init_iterator skips invisible
3103 text, so we might end up at a position different from POS. This
3104 is only a problem when POS is a row start after a newline and an
3105 overlay starts there with an after-string, and the overlay has an
3106 invisible property. Since we don't skip invisible text in
3107 display_line and elsewhere immediately after consuming the
3108 newline before the row start, such a POS will not be in a string,
3109 but the call to init_iterator below will move us to the
3110 after-string. */
3111 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3112
3113 /* This only scans the current chunk -- it should scan all chunks.
3114 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3115 to 16 in 22.1 to make this a lesser problem. */
3116 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3117 {
3118 const char *s = SSDATA (it->overlay_strings[i]);
3119 const char *e = s + SBYTES (it->overlay_strings[i]);
3120
3121 while (s < e && *s != '\n')
3122 ++s;
3123
3124 if (s < e)
3125 {
3126 overlay_strings_with_newlines = 1;
3127 break;
3128 }
3129 }
3130
3131 /* If position is within an overlay string, set up IT to the right
3132 overlay string. */
3133 if (pos->overlay_string_index >= 0)
3134 {
3135 int relative_index;
3136
3137 /* If the first overlay string happens to have a `display'
3138 property for an image, the iterator will be set up for that
3139 image, and we have to undo that setup first before we can
3140 correct the overlay string index. */
3141 if (it->method == GET_FROM_IMAGE)
3142 pop_it (it);
3143
3144 /* We already have the first chunk of overlay strings in
3145 IT->overlay_strings. Load more until the one for
3146 pos->overlay_string_index is in IT->overlay_strings. */
3147 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3148 {
3149 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3150 it->current.overlay_string_index = 0;
3151 while (n--)
3152 {
3153 load_overlay_strings (it, 0);
3154 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3155 }
3156 }
3157
3158 it->current.overlay_string_index = pos->overlay_string_index;
3159 relative_index = (it->current.overlay_string_index
3160 % OVERLAY_STRING_CHUNK_SIZE);
3161 it->string = it->overlay_strings[relative_index];
3162 eassert (STRINGP (it->string));
3163 it->current.string_pos = pos->string_pos;
3164 it->method = GET_FROM_STRING;
3165 it->end_charpos = SCHARS (it->string);
3166 /* Set up the bidi iterator for this overlay string. */
3167 if (it->bidi_p)
3168 {
3169 it->bidi_it.string.lstring = it->string;
3170 it->bidi_it.string.s = NULL;
3171 it->bidi_it.string.schars = SCHARS (it->string);
3172 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3173 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3174 it->bidi_it.string.unibyte = !it->multibyte_p;
3175 it->bidi_it.w = it->w;
3176 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3177 FRAME_WINDOW_P (it->f), &it->bidi_it);
3178
3179 /* Synchronize the state of the bidi iterator with
3180 pos->string_pos. For any string position other than
3181 zero, this will be done automagically when we resume
3182 iteration over the string and get_visually_first_element
3183 is called. But if string_pos is zero, and the string is
3184 to be reordered for display, we need to resync manually,
3185 since it could be that the iteration state recorded in
3186 pos ended at string_pos of 0 moving backwards in string. */
3187 if (CHARPOS (pos->string_pos) == 0)
3188 {
3189 get_visually_first_element (it);
3190 if (IT_STRING_CHARPOS (*it) != 0)
3191 do {
3192 /* Paranoia. */
3193 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3194 bidi_move_to_visually_next (&it->bidi_it);
3195 } while (it->bidi_it.charpos != 0);
3196 }
3197 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3198 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3199 }
3200 }
3201
3202 if (CHARPOS (pos->string_pos) >= 0)
3203 {
3204 /* Recorded position is not in an overlay string, but in another
3205 string. This can only be a string from a `display' property.
3206 IT should already be filled with that string. */
3207 it->current.string_pos = pos->string_pos;
3208 eassert (STRINGP (it->string));
3209 if (it->bidi_p)
3210 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3211 FRAME_WINDOW_P (it->f), &it->bidi_it);
3212 }
3213
3214 /* Restore position in display vector translations, control
3215 character translations or ellipses. */
3216 if (pos->dpvec_index >= 0)
3217 {
3218 if (it->dpvec == NULL)
3219 get_next_display_element (it);
3220 eassert (it->dpvec && it->current.dpvec_index == 0);
3221 it->current.dpvec_index = pos->dpvec_index;
3222 }
3223
3224 CHECK_IT (it);
3225 return !overlay_strings_with_newlines;
3226 }
3227
3228
3229 /* Initialize IT for stepping through current_buffer in window W
3230 starting at ROW->start. */
3231
3232 static void
3233 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3234 {
3235 init_from_display_pos (it, w, &row->start);
3236 it->start = row->start;
3237 it->continuation_lines_width = row->continuation_lines_width;
3238 CHECK_IT (it);
3239 }
3240
3241
3242 /* Initialize IT for stepping through current_buffer in window W
3243 starting in the line following ROW, i.e. starting at ROW->end.
3244 Value is zero if there are overlay strings with newlines at ROW's
3245 end position. */
3246
3247 static int
3248 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3249 {
3250 int success = 0;
3251
3252 if (init_from_display_pos (it, w, &row->end))
3253 {
3254 if (row->continued_p)
3255 it->continuation_lines_width
3256 = row->continuation_lines_width + row->pixel_width;
3257 CHECK_IT (it);
3258 success = 1;
3259 }
3260
3261 return success;
3262 }
3263
3264
3265
3266 \f
3267 /***********************************************************************
3268 Text properties
3269 ***********************************************************************/
3270
3271 /* Called when IT reaches IT->stop_charpos. Handle text property and
3272 overlay changes. Set IT->stop_charpos to the next position where
3273 to stop. */
3274
3275 static void
3276 handle_stop (struct it *it)
3277 {
3278 enum prop_handled handled;
3279 int handle_overlay_change_p;
3280 struct props *p;
3281
3282 it->dpvec = NULL;
3283 it->current.dpvec_index = -1;
3284 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3285 it->ignore_overlay_strings_at_pos_p = 0;
3286 it->ellipsis_p = 0;
3287
3288 /* Use face of preceding text for ellipsis (if invisible) */
3289 if (it->selective_display_ellipsis_p)
3290 it->saved_face_id = it->face_id;
3291
3292 do
3293 {
3294 handled = HANDLED_NORMALLY;
3295
3296 /* Call text property handlers. */
3297 for (p = it_props; p->handler; ++p)
3298 {
3299 handled = p->handler (it);
3300
3301 if (handled == HANDLED_RECOMPUTE_PROPS)
3302 break;
3303 else if (handled == HANDLED_RETURN)
3304 {
3305 /* We still want to show before and after strings from
3306 overlays even if the actual buffer text is replaced. */
3307 if (!handle_overlay_change_p
3308 || it->sp > 1
3309 /* Don't call get_overlay_strings_1 if we already
3310 have overlay strings loaded, because doing so
3311 will load them again and push the iterator state
3312 onto the stack one more time, which is not
3313 expected by the rest of the code that processes
3314 overlay strings. */
3315 || (it->current.overlay_string_index < 0
3316 ? !get_overlay_strings_1 (it, 0, 0)
3317 : 0))
3318 {
3319 if (it->ellipsis_p)
3320 setup_for_ellipsis (it, 0);
3321 /* When handling a display spec, we might load an
3322 empty string. In that case, discard it here. We
3323 used to discard it in handle_single_display_spec,
3324 but that causes get_overlay_strings_1, above, to
3325 ignore overlay strings that we must check. */
3326 if (STRINGP (it->string) && !SCHARS (it->string))
3327 pop_it (it);
3328 return;
3329 }
3330 else if (STRINGP (it->string) && !SCHARS (it->string))
3331 pop_it (it);
3332 else
3333 {
3334 it->ignore_overlay_strings_at_pos_p = 1;
3335 it->string_from_display_prop_p = 0;
3336 it->from_disp_prop_p = 0;
3337 handle_overlay_change_p = 0;
3338 }
3339 handled = HANDLED_RECOMPUTE_PROPS;
3340 break;
3341 }
3342 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3343 handle_overlay_change_p = 0;
3344 }
3345
3346 if (handled != HANDLED_RECOMPUTE_PROPS)
3347 {
3348 /* Don't check for overlay strings below when set to deliver
3349 characters from a display vector. */
3350 if (it->method == GET_FROM_DISPLAY_VECTOR)
3351 handle_overlay_change_p = 0;
3352
3353 /* Handle overlay changes.
3354 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3355 if it finds overlays. */
3356 if (handle_overlay_change_p)
3357 handled = handle_overlay_change (it);
3358 }
3359
3360 if (it->ellipsis_p)
3361 {
3362 setup_for_ellipsis (it, 0);
3363 break;
3364 }
3365 }
3366 while (handled == HANDLED_RECOMPUTE_PROPS);
3367
3368 /* Determine where to stop next. */
3369 if (handled == HANDLED_NORMALLY)
3370 compute_stop_pos (it);
3371 }
3372
3373
3374 /* Compute IT->stop_charpos from text property and overlay change
3375 information for IT's current position. */
3376
3377 static void
3378 compute_stop_pos (struct it *it)
3379 {
3380 register INTERVAL iv, next_iv;
3381 Lisp_Object object, limit, position;
3382 ptrdiff_t charpos, bytepos;
3383
3384 if (STRINGP (it->string))
3385 {
3386 /* Strings are usually short, so don't limit the search for
3387 properties. */
3388 it->stop_charpos = it->end_charpos;
3389 object = it->string;
3390 limit = Qnil;
3391 charpos = IT_STRING_CHARPOS (*it);
3392 bytepos = IT_STRING_BYTEPOS (*it);
3393 }
3394 else
3395 {
3396 ptrdiff_t pos;
3397
3398 /* If end_charpos is out of range for some reason, such as a
3399 misbehaving display function, rationalize it (Bug#5984). */
3400 if (it->end_charpos > ZV)
3401 it->end_charpos = ZV;
3402 it->stop_charpos = it->end_charpos;
3403
3404 /* If next overlay change is in front of the current stop pos
3405 (which is IT->end_charpos), stop there. Note: value of
3406 next_overlay_change is point-max if no overlay change
3407 follows. */
3408 charpos = IT_CHARPOS (*it);
3409 bytepos = IT_BYTEPOS (*it);
3410 pos = next_overlay_change (charpos);
3411 if (pos < it->stop_charpos)
3412 it->stop_charpos = pos;
3413
3414 /* If showing the region, we have to stop at the region
3415 start or end because the face might change there. */
3416 if (it->region_beg_charpos > 0)
3417 {
3418 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3419 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3420 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3421 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3422 }
3423
3424 /* Set up variables for computing the stop position from text
3425 property changes. */
3426 XSETBUFFER (object, current_buffer);
3427 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3428 }
3429
3430 /* Get the interval containing IT's position. Value is a null
3431 interval if there isn't such an interval. */
3432 position = make_number (charpos);
3433 iv = validate_interval_range (object, &position, &position, 0);
3434 if (iv)
3435 {
3436 Lisp_Object values_here[LAST_PROP_IDX];
3437 struct props *p;
3438
3439 /* Get properties here. */
3440 for (p = it_props; p->handler; ++p)
3441 values_here[p->idx] = textget (iv->plist, *p->name);
3442
3443 /* Look for an interval following iv that has different
3444 properties. */
3445 for (next_iv = next_interval (iv);
3446 (next_iv
3447 && (NILP (limit)
3448 || XFASTINT (limit) > next_iv->position));
3449 next_iv = next_interval (next_iv))
3450 {
3451 for (p = it_props; p->handler; ++p)
3452 {
3453 Lisp_Object new_value;
3454
3455 new_value = textget (next_iv->plist, *p->name);
3456 if (!EQ (values_here[p->idx], new_value))
3457 break;
3458 }
3459
3460 if (p->handler)
3461 break;
3462 }
3463
3464 if (next_iv)
3465 {
3466 if (INTEGERP (limit)
3467 && next_iv->position >= XFASTINT (limit))
3468 /* No text property change up to limit. */
3469 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3470 else
3471 /* Text properties change in next_iv. */
3472 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3473 }
3474 }
3475
3476 if (it->cmp_it.id < 0)
3477 {
3478 ptrdiff_t stoppos = it->end_charpos;
3479
3480 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3481 stoppos = -1;
3482 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3483 stoppos, it->string);
3484 }
3485
3486 eassert (STRINGP (it->string)
3487 || (it->stop_charpos >= BEGV
3488 && it->stop_charpos >= IT_CHARPOS (*it)));
3489 }
3490
3491
3492 /* Return the position of the next overlay change after POS in
3493 current_buffer. Value is point-max if no overlay change
3494 follows. This is like `next-overlay-change' but doesn't use
3495 xmalloc. */
3496
3497 static ptrdiff_t
3498 next_overlay_change (ptrdiff_t pos)
3499 {
3500 ptrdiff_t i, noverlays;
3501 ptrdiff_t endpos;
3502 Lisp_Object *overlays;
3503
3504 /* Get all overlays at the given position. */
3505 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3506
3507 /* If any of these overlays ends before endpos,
3508 use its ending point instead. */
3509 for (i = 0; i < noverlays; ++i)
3510 {
3511 Lisp_Object oend;
3512 ptrdiff_t oendpos;
3513
3514 oend = OVERLAY_END (overlays[i]);
3515 oendpos = OVERLAY_POSITION (oend);
3516 endpos = min (endpos, oendpos);
3517 }
3518
3519 return endpos;
3520 }
3521
3522 /* How many characters forward to search for a display property or
3523 display string. Searching too far forward makes the bidi display
3524 sluggish, especially in small windows. */
3525 #define MAX_DISP_SCAN 250
3526
3527 /* Return the character position of a display string at or after
3528 position specified by POSITION. If no display string exists at or
3529 after POSITION, return ZV. A display string is either an overlay
3530 with `display' property whose value is a string, or a `display'
3531 text property whose value is a string. STRING is data about the
3532 string to iterate; if STRING->lstring is nil, we are iterating a
3533 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3534 on a GUI frame. DISP_PROP is set to zero if we searched
3535 MAX_DISP_SCAN characters forward without finding any display
3536 strings, non-zero otherwise. It is set to 2 if the display string
3537 uses any kind of `(space ...)' spec that will produce a stretch of
3538 white space in the text area. */
3539 ptrdiff_t
3540 compute_display_string_pos (struct text_pos *position,
3541 struct bidi_string_data *string,
3542 struct window *w,
3543 int frame_window_p, int *disp_prop)
3544 {
3545 /* OBJECT = nil means current buffer. */
3546 Lisp_Object object, object1;
3547 Lisp_Object pos, spec, limpos;
3548 int string_p = (string && (STRINGP (string->lstring) || string->s));
3549 ptrdiff_t eob = string_p ? string->schars : ZV;
3550 ptrdiff_t begb = string_p ? 0 : BEGV;
3551 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3552 ptrdiff_t lim =
3553 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3554 struct text_pos tpos;
3555 int rv = 0;
3556
3557 if (string && STRINGP (string->lstring))
3558 object1 = object = string->lstring;
3559 else if (w && !string_p)
3560 {
3561 XSETWINDOW (object, w);
3562 object1 = Qnil;
3563 }
3564 else
3565 object1 = object = Qnil;
3566
3567 *disp_prop = 1;
3568
3569 if (charpos >= eob
3570 /* We don't support display properties whose values are strings
3571 that have display string properties. */
3572 || string->from_disp_str
3573 /* C strings cannot have display properties. */
3574 || (string->s && !STRINGP (object)))
3575 {
3576 *disp_prop = 0;
3577 return eob;
3578 }
3579
3580 /* If the character at CHARPOS is where the display string begins,
3581 return CHARPOS. */
3582 pos = make_number (charpos);
3583 if (STRINGP (object))
3584 bufpos = string->bufpos;
3585 else
3586 bufpos = charpos;
3587 tpos = *position;
3588 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3589 && (charpos <= begb
3590 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3591 object),
3592 spec))
3593 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3594 frame_window_p)))
3595 {
3596 if (rv == 2)
3597 *disp_prop = 2;
3598 return charpos;
3599 }
3600
3601 /* Look forward for the first character with a `display' property
3602 that will replace the underlying text when displayed. */
3603 limpos = make_number (lim);
3604 do {
3605 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3606 CHARPOS (tpos) = XFASTINT (pos);
3607 if (CHARPOS (tpos) >= lim)
3608 {
3609 *disp_prop = 0;
3610 break;
3611 }
3612 if (STRINGP (object))
3613 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3614 else
3615 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3616 spec = Fget_char_property (pos, Qdisplay, object);
3617 if (!STRINGP (object))
3618 bufpos = CHARPOS (tpos);
3619 } while (NILP (spec)
3620 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3621 bufpos, frame_window_p)));
3622 if (rv == 2)
3623 *disp_prop = 2;
3624
3625 return CHARPOS (tpos);
3626 }
3627
3628 /* Return the character position of the end of the display string that
3629 started at CHARPOS. If there's no display string at CHARPOS,
3630 return -1. A display string is either an overlay with `display'
3631 property whose value is a string or a `display' text property whose
3632 value is a string. */
3633 ptrdiff_t
3634 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3635 {
3636 /* OBJECT = nil means current buffer. */
3637 Lisp_Object object =
3638 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3639 Lisp_Object pos = make_number (charpos);
3640 ptrdiff_t eob =
3641 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3642
3643 if (charpos >= eob || (string->s && !STRINGP (object)))
3644 return eob;
3645
3646 /* It could happen that the display property or overlay was removed
3647 since we found it in compute_display_string_pos above. One way
3648 this can happen is if JIT font-lock was called (through
3649 handle_fontified_prop), and jit-lock-functions remove text
3650 properties or overlays from the portion of buffer that includes
3651 CHARPOS. Muse mode is known to do that, for example. In this
3652 case, we return -1 to the caller, to signal that no display
3653 string is actually present at CHARPOS. See bidi_fetch_char for
3654 how this is handled.
3655
3656 An alternative would be to never look for display properties past
3657 it->stop_charpos. But neither compute_display_string_pos nor
3658 bidi_fetch_char that calls it know or care where the next
3659 stop_charpos is. */
3660 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3661 return -1;
3662
3663 /* Look forward for the first character where the `display' property
3664 changes. */
3665 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3666
3667 return XFASTINT (pos);
3668 }
3669
3670
3671 \f
3672 /***********************************************************************
3673 Fontification
3674 ***********************************************************************/
3675
3676 /* Handle changes in the `fontified' property of the current buffer by
3677 calling hook functions from Qfontification_functions to fontify
3678 regions of text. */
3679
3680 static enum prop_handled
3681 handle_fontified_prop (struct it *it)
3682 {
3683 Lisp_Object prop, pos;
3684 enum prop_handled handled = HANDLED_NORMALLY;
3685
3686 if (!NILP (Vmemory_full))
3687 return handled;
3688
3689 /* Get the value of the `fontified' property at IT's current buffer
3690 position. (The `fontified' property doesn't have a special
3691 meaning in strings.) If the value is nil, call functions from
3692 Qfontification_functions. */
3693 if (!STRINGP (it->string)
3694 && it->s == NULL
3695 && !NILP (Vfontification_functions)
3696 && !NILP (Vrun_hooks)
3697 && (pos = make_number (IT_CHARPOS (*it)),
3698 prop = Fget_char_property (pos, Qfontified, Qnil),
3699 /* Ignore the special cased nil value always present at EOB since
3700 no amount of fontifying will be able to change it. */
3701 NILP (prop) && IT_CHARPOS (*it) < Z))
3702 {
3703 ptrdiff_t count = SPECPDL_INDEX ();
3704 Lisp_Object val;
3705 struct buffer *obuf = current_buffer;
3706 int begv = BEGV, zv = ZV;
3707 int old_clip_changed = current_buffer->clip_changed;
3708
3709 val = Vfontification_functions;
3710 specbind (Qfontification_functions, Qnil);
3711
3712 eassert (it->end_charpos == ZV);
3713
3714 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3715 safe_call1 (val, pos);
3716 else
3717 {
3718 Lisp_Object fns, fn;
3719 struct gcpro gcpro1, gcpro2;
3720
3721 fns = Qnil;
3722 GCPRO2 (val, fns);
3723
3724 for (; CONSP (val); val = XCDR (val))
3725 {
3726 fn = XCAR (val);
3727
3728 if (EQ (fn, Qt))
3729 {
3730 /* A value of t indicates this hook has a local
3731 binding; it means to run the global binding too.
3732 In a global value, t should not occur. If it
3733 does, we must ignore it to avoid an endless
3734 loop. */
3735 for (fns = Fdefault_value (Qfontification_functions);
3736 CONSP (fns);
3737 fns = XCDR (fns))
3738 {
3739 fn = XCAR (fns);
3740 if (!EQ (fn, Qt))
3741 safe_call1 (fn, pos);
3742 }
3743 }
3744 else
3745 safe_call1 (fn, pos);
3746 }
3747
3748 UNGCPRO;
3749 }
3750
3751 unbind_to (count, Qnil);
3752
3753 /* Fontification functions routinely call `save-restriction'.
3754 Normally, this tags clip_changed, which can confuse redisplay
3755 (see discussion in Bug#6671). Since we don't perform any
3756 special handling of fontification changes in the case where
3757 `save-restriction' isn't called, there's no point doing so in
3758 this case either. So, if the buffer's restrictions are
3759 actually left unchanged, reset clip_changed. */
3760 if (obuf == current_buffer)
3761 {
3762 if (begv == BEGV && zv == ZV)
3763 current_buffer->clip_changed = old_clip_changed;
3764 }
3765 /* There isn't much we can reasonably do to protect against
3766 misbehaving fontification, but here's a fig leaf. */
3767 else if (BUFFER_LIVE_P (obuf))
3768 set_buffer_internal_1 (obuf);
3769
3770 /* The fontification code may have added/removed text.
3771 It could do even a lot worse, but let's at least protect against
3772 the most obvious case where only the text past `pos' gets changed',
3773 as is/was done in grep.el where some escapes sequences are turned
3774 into face properties (bug#7876). */
3775 it->end_charpos = ZV;
3776
3777 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3778 something. This avoids an endless loop if they failed to
3779 fontify the text for which reason ever. */
3780 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3781 handled = HANDLED_RECOMPUTE_PROPS;
3782 }
3783
3784 return handled;
3785 }
3786
3787
3788 \f
3789 /***********************************************************************
3790 Faces
3791 ***********************************************************************/
3792
3793 /* Set up iterator IT from face properties at its current position.
3794 Called from handle_stop. */
3795
3796 static enum prop_handled
3797 handle_face_prop (struct it *it)
3798 {
3799 int new_face_id;
3800 ptrdiff_t next_stop;
3801
3802 if (!STRINGP (it->string))
3803 {
3804 new_face_id
3805 = face_at_buffer_position (it->w,
3806 IT_CHARPOS (*it),
3807 it->region_beg_charpos,
3808 it->region_end_charpos,
3809 &next_stop,
3810 (IT_CHARPOS (*it)
3811 + TEXT_PROP_DISTANCE_LIMIT),
3812 0, it->base_face_id);
3813
3814 /* Is this a start of a run of characters with box face?
3815 Caveat: this can be called for a freshly initialized
3816 iterator; face_id is -1 in this case. We know that the new
3817 face will not change until limit, i.e. if the new face has a
3818 box, all characters up to limit will have one. But, as
3819 usual, we don't know whether limit is really the end. */
3820 if (new_face_id != it->face_id)
3821 {
3822 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3823 /* If it->face_id is -1, old_face below will be NULL, see
3824 the definition of FACE_FROM_ID. This will happen if this
3825 is the initial call that gets the face. */
3826 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3827
3828 /* If the value of face_id of the iterator is -1, we have to
3829 look in front of IT's position and see whether there is a
3830 face there that's different from new_face_id. */
3831 if (!old_face && IT_CHARPOS (*it) > BEG)
3832 {
3833 int prev_face_id = face_before_it_pos (it);
3834
3835 old_face = FACE_FROM_ID (it->f, prev_face_id);
3836 }
3837
3838 /* If the new face has a box, but the old face does not,
3839 this is the start of a run of characters with box face,
3840 i.e. this character has a shadow on the left side. */
3841 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3842 && (old_face == NULL || !old_face->box));
3843 it->face_box_p = new_face->box != FACE_NO_BOX;
3844 }
3845 }
3846 else
3847 {
3848 int base_face_id;
3849 ptrdiff_t bufpos;
3850 int i;
3851 Lisp_Object from_overlay
3852 = (it->current.overlay_string_index >= 0
3853 ? it->string_overlays[it->current.overlay_string_index
3854 % OVERLAY_STRING_CHUNK_SIZE]
3855 : Qnil);
3856
3857 /* See if we got to this string directly or indirectly from
3858 an overlay property. That includes the before-string or
3859 after-string of an overlay, strings in display properties
3860 provided by an overlay, their text properties, etc.
3861
3862 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3863 if (! NILP (from_overlay))
3864 for (i = it->sp - 1; i >= 0; i--)
3865 {
3866 if (it->stack[i].current.overlay_string_index >= 0)
3867 from_overlay
3868 = it->string_overlays[it->stack[i].current.overlay_string_index
3869 % OVERLAY_STRING_CHUNK_SIZE];
3870 else if (! NILP (it->stack[i].from_overlay))
3871 from_overlay = it->stack[i].from_overlay;
3872
3873 if (!NILP (from_overlay))
3874 break;
3875 }
3876
3877 if (! NILP (from_overlay))
3878 {
3879 bufpos = IT_CHARPOS (*it);
3880 /* For a string from an overlay, the base face depends
3881 only on text properties and ignores overlays. */
3882 base_face_id
3883 = face_for_overlay_string (it->w,
3884 IT_CHARPOS (*it),
3885 it->region_beg_charpos,
3886 it->region_end_charpos,
3887 &next_stop,
3888 (IT_CHARPOS (*it)
3889 + TEXT_PROP_DISTANCE_LIMIT),
3890 0,
3891 from_overlay);
3892 }
3893 else
3894 {
3895 bufpos = 0;
3896
3897 /* For strings from a `display' property, use the face at
3898 IT's current buffer position as the base face to merge
3899 with, so that overlay strings appear in the same face as
3900 surrounding text, unless they specify their own faces.
3901 For strings from wrap-prefix and line-prefix properties,
3902 use the default face, possibly remapped via
3903 Vface_remapping_alist. */
3904 base_face_id = it->string_from_prefix_prop_p
3905 ? (!NILP (Vface_remapping_alist)
3906 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
3907 : DEFAULT_FACE_ID)
3908 : underlying_face_id (it);
3909 }
3910
3911 new_face_id = face_at_string_position (it->w,
3912 it->string,
3913 IT_STRING_CHARPOS (*it),
3914 bufpos,
3915 it->region_beg_charpos,
3916 it->region_end_charpos,
3917 &next_stop,
3918 base_face_id, 0);
3919
3920 /* Is this a start of a run of characters with box? Caveat:
3921 this can be called for a freshly allocated iterator; face_id
3922 is -1 is this case. We know that the new face will not
3923 change until the next check pos, i.e. if the new face has a
3924 box, all characters up to that position will have a
3925 box. But, as usual, we don't know whether that position
3926 is really the end. */
3927 if (new_face_id != it->face_id)
3928 {
3929 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3930 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3931
3932 /* If new face has a box but old face hasn't, this is the
3933 start of a run of characters with box, i.e. it has a
3934 shadow on the left side. */
3935 it->start_of_box_run_p
3936 = new_face->box && (old_face == NULL || !old_face->box);
3937 it->face_box_p = new_face->box != FACE_NO_BOX;
3938 }
3939 }
3940
3941 it->face_id = new_face_id;
3942 return HANDLED_NORMALLY;
3943 }
3944
3945
3946 /* Return the ID of the face ``underlying'' IT's current position,
3947 which is in a string. If the iterator is associated with a
3948 buffer, return the face at IT's current buffer position.
3949 Otherwise, use the iterator's base_face_id. */
3950
3951 static int
3952 underlying_face_id (struct it *it)
3953 {
3954 int face_id = it->base_face_id, i;
3955
3956 eassert (STRINGP (it->string));
3957
3958 for (i = it->sp - 1; i >= 0; --i)
3959 if (NILP (it->stack[i].string))
3960 face_id = it->stack[i].face_id;
3961
3962 return face_id;
3963 }
3964
3965
3966 /* Compute the face one character before or after the current position
3967 of IT, in the visual order. BEFORE_P non-zero means get the face
3968 in front (to the left in L2R paragraphs, to the right in R2L
3969 paragraphs) of IT's screen position. Value is the ID of the face. */
3970
3971 static int
3972 face_before_or_after_it_pos (struct it *it, int before_p)
3973 {
3974 int face_id, limit;
3975 ptrdiff_t next_check_charpos;
3976 struct it it_copy;
3977 void *it_copy_data = NULL;
3978
3979 eassert (it->s == NULL);
3980
3981 if (STRINGP (it->string))
3982 {
3983 ptrdiff_t bufpos, charpos;
3984 int base_face_id;
3985
3986 /* No face change past the end of the string (for the case
3987 we are padding with spaces). No face change before the
3988 string start. */
3989 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3990 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3991 return it->face_id;
3992
3993 if (!it->bidi_p)
3994 {
3995 /* Set charpos to the position before or after IT's current
3996 position, in the logical order, which in the non-bidi
3997 case is the same as the visual order. */
3998 if (before_p)
3999 charpos = IT_STRING_CHARPOS (*it) - 1;
4000 else if (it->what == IT_COMPOSITION)
4001 /* For composition, we must check the character after the
4002 composition. */
4003 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4004 else
4005 charpos = IT_STRING_CHARPOS (*it) + 1;
4006 }
4007 else
4008 {
4009 if (before_p)
4010 {
4011 /* With bidi iteration, the character before the current
4012 in the visual order cannot be found by simple
4013 iteration, because "reverse" reordering is not
4014 supported. Instead, we need to use the move_it_*
4015 family of functions. */
4016 /* Ignore face changes before the first visible
4017 character on this display line. */
4018 if (it->current_x <= it->first_visible_x)
4019 return it->face_id;
4020 SAVE_IT (it_copy, *it, it_copy_data);
4021 /* Implementation note: Since move_it_in_display_line
4022 works in the iterator geometry, and thinks the first
4023 character is always the leftmost, even in R2L lines,
4024 we don't need to distinguish between the R2L and L2R
4025 cases here. */
4026 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4027 it_copy.current_x - 1, MOVE_TO_X);
4028 charpos = IT_STRING_CHARPOS (it_copy);
4029 RESTORE_IT (it, it, it_copy_data);
4030 }
4031 else
4032 {
4033 /* Set charpos to the string position of the character
4034 that comes after IT's current position in the visual
4035 order. */
4036 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4037
4038 it_copy = *it;
4039 while (n--)
4040 bidi_move_to_visually_next (&it_copy.bidi_it);
4041
4042 charpos = it_copy.bidi_it.charpos;
4043 }
4044 }
4045 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4046
4047 if (it->current.overlay_string_index >= 0)
4048 bufpos = IT_CHARPOS (*it);
4049 else
4050 bufpos = 0;
4051
4052 base_face_id = underlying_face_id (it);
4053
4054 /* Get the face for ASCII, or unibyte. */
4055 face_id = face_at_string_position (it->w,
4056 it->string,
4057 charpos,
4058 bufpos,
4059 it->region_beg_charpos,
4060 it->region_end_charpos,
4061 &next_check_charpos,
4062 base_face_id, 0);
4063
4064 /* Correct the face for charsets different from ASCII. Do it
4065 for the multibyte case only. The face returned above is
4066 suitable for unibyte text if IT->string is unibyte. */
4067 if (STRING_MULTIBYTE (it->string))
4068 {
4069 struct text_pos pos1 = string_pos (charpos, it->string);
4070 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4071 int c, len;
4072 struct face *face = FACE_FROM_ID (it->f, face_id);
4073
4074 c = string_char_and_length (p, &len);
4075 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4076 }
4077 }
4078 else
4079 {
4080 struct text_pos pos;
4081
4082 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4083 || (IT_CHARPOS (*it) <= BEGV && before_p))
4084 return it->face_id;
4085
4086 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4087 pos = it->current.pos;
4088
4089 if (!it->bidi_p)
4090 {
4091 if (before_p)
4092 DEC_TEXT_POS (pos, it->multibyte_p);
4093 else
4094 {
4095 if (it->what == IT_COMPOSITION)
4096 {
4097 /* For composition, we must check the position after
4098 the composition. */
4099 pos.charpos += it->cmp_it.nchars;
4100 pos.bytepos += it->len;
4101 }
4102 else
4103 INC_TEXT_POS (pos, it->multibyte_p);
4104 }
4105 }
4106 else
4107 {
4108 if (before_p)
4109 {
4110 /* With bidi iteration, the character before the current
4111 in the visual order cannot be found by simple
4112 iteration, because "reverse" reordering is not
4113 supported. Instead, we need to use the move_it_*
4114 family of functions. */
4115 /* Ignore face changes before the first visible
4116 character on this display line. */
4117 if (it->current_x <= it->first_visible_x)
4118 return it->face_id;
4119 SAVE_IT (it_copy, *it, it_copy_data);
4120 /* Implementation note: Since move_it_in_display_line
4121 works in the iterator geometry, and thinks the first
4122 character is always the leftmost, even in R2L lines,
4123 we don't need to distinguish between the R2L and L2R
4124 cases here. */
4125 move_it_in_display_line (&it_copy, ZV,
4126 it_copy.current_x - 1, MOVE_TO_X);
4127 pos = it_copy.current.pos;
4128 RESTORE_IT (it, it, it_copy_data);
4129 }
4130 else
4131 {
4132 /* Set charpos to the buffer position of the character
4133 that comes after IT's current position in the visual
4134 order. */
4135 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4136
4137 it_copy = *it;
4138 while (n--)
4139 bidi_move_to_visually_next (&it_copy.bidi_it);
4140
4141 SET_TEXT_POS (pos,
4142 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4143 }
4144 }
4145 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4146
4147 /* Determine face for CHARSET_ASCII, or unibyte. */
4148 face_id = face_at_buffer_position (it->w,
4149 CHARPOS (pos),
4150 it->region_beg_charpos,
4151 it->region_end_charpos,
4152 &next_check_charpos,
4153 limit, 0, -1);
4154
4155 /* Correct the face for charsets different from ASCII. Do it
4156 for the multibyte case only. The face returned above is
4157 suitable for unibyte text if current_buffer is unibyte. */
4158 if (it->multibyte_p)
4159 {
4160 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4161 struct face *face = FACE_FROM_ID (it->f, face_id);
4162 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4163 }
4164 }
4165
4166 return face_id;
4167 }
4168
4169
4170 \f
4171 /***********************************************************************
4172 Invisible text
4173 ***********************************************************************/
4174
4175 /* Set up iterator IT from invisible properties at its current
4176 position. Called from handle_stop. */
4177
4178 static enum prop_handled
4179 handle_invisible_prop (struct it *it)
4180 {
4181 enum prop_handled handled = HANDLED_NORMALLY;
4182 int invis_p;
4183 Lisp_Object prop;
4184
4185 if (STRINGP (it->string))
4186 {
4187 Lisp_Object end_charpos, limit, charpos;
4188
4189 /* Get the value of the invisible text property at the
4190 current position. Value will be nil if there is no such
4191 property. */
4192 charpos = make_number (IT_STRING_CHARPOS (*it));
4193 prop = Fget_text_property (charpos, Qinvisible, it->string);
4194 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4195
4196 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4197 {
4198 /* Record whether we have to display an ellipsis for the
4199 invisible text. */
4200 int display_ellipsis_p = (invis_p == 2);
4201 ptrdiff_t len, endpos;
4202
4203 handled = HANDLED_RECOMPUTE_PROPS;
4204
4205 /* Get the position at which the next visible text can be
4206 found in IT->string, if any. */
4207 endpos = len = SCHARS (it->string);
4208 XSETINT (limit, len);
4209 do
4210 {
4211 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4212 it->string, limit);
4213 if (INTEGERP (end_charpos))
4214 {
4215 endpos = XFASTINT (end_charpos);
4216 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4217 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4218 if (invis_p == 2)
4219 display_ellipsis_p = 1;
4220 }
4221 }
4222 while (invis_p && endpos < len);
4223
4224 if (display_ellipsis_p)
4225 it->ellipsis_p = 1;
4226
4227 if (endpos < len)
4228 {
4229 /* Text at END_CHARPOS is visible. Move IT there. */
4230 struct text_pos old;
4231 ptrdiff_t oldpos;
4232
4233 old = it->current.string_pos;
4234 oldpos = CHARPOS (old);
4235 if (it->bidi_p)
4236 {
4237 if (it->bidi_it.first_elt
4238 && it->bidi_it.charpos < SCHARS (it->string))
4239 bidi_paragraph_init (it->paragraph_embedding,
4240 &it->bidi_it, 1);
4241 /* Bidi-iterate out of the invisible text. */
4242 do
4243 {
4244 bidi_move_to_visually_next (&it->bidi_it);
4245 }
4246 while (oldpos <= it->bidi_it.charpos
4247 && it->bidi_it.charpos < endpos);
4248
4249 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4250 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4251 if (IT_CHARPOS (*it) >= endpos)
4252 it->prev_stop = endpos;
4253 }
4254 else
4255 {
4256 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4257 compute_string_pos (&it->current.string_pos, old, it->string);
4258 }
4259 }
4260 else
4261 {
4262 /* The rest of the string is invisible. If this is an
4263 overlay string, proceed with the next overlay string
4264 or whatever comes and return a character from there. */
4265 if (it->current.overlay_string_index >= 0
4266 && !display_ellipsis_p)
4267 {
4268 next_overlay_string (it);
4269 /* Don't check for overlay strings when we just
4270 finished processing them. */
4271 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4272 }
4273 else
4274 {
4275 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4276 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4277 }
4278 }
4279 }
4280 }
4281 else
4282 {
4283 ptrdiff_t newpos, next_stop, start_charpos, tem;
4284 Lisp_Object pos, overlay;
4285
4286 /* First of all, is there invisible text at this position? */
4287 tem = start_charpos = IT_CHARPOS (*it);
4288 pos = make_number (tem);
4289 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4290 &overlay);
4291 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4292
4293 /* If we are on invisible text, skip over it. */
4294 if (invis_p && start_charpos < it->end_charpos)
4295 {
4296 /* Record whether we have to display an ellipsis for the
4297 invisible text. */
4298 int display_ellipsis_p = invis_p == 2;
4299
4300 handled = HANDLED_RECOMPUTE_PROPS;
4301
4302 /* Loop skipping over invisible text. The loop is left at
4303 ZV or with IT on the first char being visible again. */
4304 do
4305 {
4306 /* Try to skip some invisible text. Return value is the
4307 position reached which can be equal to where we start
4308 if there is nothing invisible there. This skips both
4309 over invisible text properties and overlays with
4310 invisible property. */
4311 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4312
4313 /* If we skipped nothing at all we weren't at invisible
4314 text in the first place. If everything to the end of
4315 the buffer was skipped, end the loop. */
4316 if (newpos == tem || newpos >= ZV)
4317 invis_p = 0;
4318 else
4319 {
4320 /* We skipped some characters but not necessarily
4321 all there are. Check if we ended up on visible
4322 text. Fget_char_property returns the property of
4323 the char before the given position, i.e. if we
4324 get invis_p = 0, this means that the char at
4325 newpos is visible. */
4326 pos = make_number (newpos);
4327 prop = Fget_char_property (pos, Qinvisible, it->window);
4328 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4329 }
4330
4331 /* If we ended up on invisible text, proceed to
4332 skip starting with next_stop. */
4333 if (invis_p)
4334 tem = next_stop;
4335
4336 /* If there are adjacent invisible texts, don't lose the
4337 second one's ellipsis. */
4338 if (invis_p == 2)
4339 display_ellipsis_p = 1;
4340 }
4341 while (invis_p);
4342
4343 /* The position newpos is now either ZV or on visible text. */
4344 if (it->bidi_p)
4345 {
4346 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4347 int on_newline =
4348 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4349 int after_newline =
4350 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4351
4352 /* If the invisible text ends on a newline or on a
4353 character after a newline, we can avoid the costly,
4354 character by character, bidi iteration to NEWPOS, and
4355 instead simply reseat the iterator there. That's
4356 because all bidi reordering information is tossed at
4357 the newline. This is a big win for modes that hide
4358 complete lines, like Outline, Org, etc. */
4359 if (on_newline || after_newline)
4360 {
4361 struct text_pos tpos;
4362 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4363
4364 SET_TEXT_POS (tpos, newpos, bpos);
4365 reseat_1 (it, tpos, 0);
4366 /* If we reseat on a newline/ZV, we need to prep the
4367 bidi iterator for advancing to the next character
4368 after the newline/EOB, keeping the current paragraph
4369 direction (so that PRODUCE_GLYPHS does TRT wrt
4370 prepending/appending glyphs to a glyph row). */
4371 if (on_newline)
4372 {
4373 it->bidi_it.first_elt = 0;
4374 it->bidi_it.paragraph_dir = pdir;
4375 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4376 it->bidi_it.nchars = 1;
4377 it->bidi_it.ch_len = 1;
4378 }
4379 }
4380 else /* Must use the slow method. */
4381 {
4382 /* With bidi iteration, the region of invisible text
4383 could start and/or end in the middle of a
4384 non-base embedding level. Therefore, we need to
4385 skip invisible text using the bidi iterator,
4386 starting at IT's current position, until we find
4387 ourselves outside of the invisible text.
4388 Skipping invisible text _after_ bidi iteration
4389 avoids affecting the visual order of the
4390 displayed text when invisible properties are
4391 added or removed. */
4392 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4393 {
4394 /* If we were `reseat'ed to a new paragraph,
4395 determine the paragraph base direction. We
4396 need to do it now because
4397 next_element_from_buffer may not have a
4398 chance to do it, if we are going to skip any
4399 text at the beginning, which resets the
4400 FIRST_ELT flag. */
4401 bidi_paragraph_init (it->paragraph_embedding,
4402 &it->bidi_it, 1);
4403 }
4404 do
4405 {
4406 bidi_move_to_visually_next (&it->bidi_it);
4407 }
4408 while (it->stop_charpos <= it->bidi_it.charpos
4409 && it->bidi_it.charpos < newpos);
4410 IT_CHARPOS (*it) = it->bidi_it.charpos;
4411 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4412 /* If we overstepped NEWPOS, record its position in
4413 the iterator, so that we skip invisible text if
4414 later the bidi iteration lands us in the
4415 invisible region again. */
4416 if (IT_CHARPOS (*it) >= newpos)
4417 it->prev_stop = newpos;
4418 }
4419 }
4420 else
4421 {
4422 IT_CHARPOS (*it) = newpos;
4423 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4424 }
4425
4426 /* If there are before-strings at the start of invisible
4427 text, and the text is invisible because of a text
4428 property, arrange to show before-strings because 20.x did
4429 it that way. (If the text is invisible because of an
4430 overlay property instead of a text property, this is
4431 already handled in the overlay code.) */
4432 if (NILP (overlay)
4433 && get_overlay_strings (it, it->stop_charpos))
4434 {
4435 handled = HANDLED_RECOMPUTE_PROPS;
4436 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4437 }
4438 else if (display_ellipsis_p)
4439 {
4440 /* Make sure that the glyphs of the ellipsis will get
4441 correct `charpos' values. If we would not update
4442 it->position here, the glyphs would belong to the
4443 last visible character _before_ the invisible
4444 text, which confuses `set_cursor_from_row'.
4445
4446 We use the last invisible position instead of the
4447 first because this way the cursor is always drawn on
4448 the first "." of the ellipsis, whenever PT is inside
4449 the invisible text. Otherwise the cursor would be
4450 placed _after_ the ellipsis when the point is after the
4451 first invisible character. */
4452 if (!STRINGP (it->object))
4453 {
4454 it->position.charpos = newpos - 1;
4455 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4456 }
4457 it->ellipsis_p = 1;
4458 /* Let the ellipsis display before
4459 considering any properties of the following char.
4460 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4461 handled = HANDLED_RETURN;
4462 }
4463 }
4464 }
4465
4466 return handled;
4467 }
4468
4469
4470 /* Make iterator IT return `...' next.
4471 Replaces LEN characters from buffer. */
4472
4473 static void
4474 setup_for_ellipsis (struct it *it, int len)
4475 {
4476 /* Use the display table definition for `...'. Invalid glyphs
4477 will be handled by the method returning elements from dpvec. */
4478 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4479 {
4480 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4481 it->dpvec = v->contents;
4482 it->dpend = v->contents + v->header.size;
4483 }
4484 else
4485 {
4486 /* Default `...'. */
4487 it->dpvec = default_invis_vector;
4488 it->dpend = default_invis_vector + 3;
4489 }
4490
4491 it->dpvec_char_len = len;
4492 it->current.dpvec_index = 0;
4493 it->dpvec_face_id = -1;
4494
4495 /* Remember the current face id in case glyphs specify faces.
4496 IT's face is restored in set_iterator_to_next.
4497 saved_face_id was set to preceding char's face in handle_stop. */
4498 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4499 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4500
4501 it->method = GET_FROM_DISPLAY_VECTOR;
4502 it->ellipsis_p = 1;
4503 }
4504
4505
4506 \f
4507 /***********************************************************************
4508 'display' property
4509 ***********************************************************************/
4510
4511 /* Set up iterator IT from `display' property at its current position.
4512 Called from handle_stop.
4513 We return HANDLED_RETURN if some part of the display property
4514 overrides the display of the buffer text itself.
4515 Otherwise we return HANDLED_NORMALLY. */
4516
4517 static enum prop_handled
4518 handle_display_prop (struct it *it)
4519 {
4520 Lisp_Object propval, object, overlay;
4521 struct text_pos *position;
4522 ptrdiff_t bufpos;
4523 /* Nonzero if some property replaces the display of the text itself. */
4524 int display_replaced_p = 0;
4525
4526 if (STRINGP (it->string))
4527 {
4528 object = it->string;
4529 position = &it->current.string_pos;
4530 bufpos = CHARPOS (it->current.pos);
4531 }
4532 else
4533 {
4534 XSETWINDOW (object, it->w);
4535 position = &it->current.pos;
4536 bufpos = CHARPOS (*position);
4537 }
4538
4539 /* Reset those iterator values set from display property values. */
4540 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4541 it->space_width = Qnil;
4542 it->font_height = Qnil;
4543 it->voffset = 0;
4544
4545 /* We don't support recursive `display' properties, i.e. string
4546 values that have a string `display' property, that have a string
4547 `display' property etc. */
4548 if (!it->string_from_display_prop_p)
4549 it->area = TEXT_AREA;
4550
4551 propval = get_char_property_and_overlay (make_number (position->charpos),
4552 Qdisplay, object, &overlay);
4553 if (NILP (propval))
4554 return HANDLED_NORMALLY;
4555 /* Now OVERLAY is the overlay that gave us this property, or nil
4556 if it was a text property. */
4557
4558 if (!STRINGP (it->string))
4559 object = it->w->contents;
4560
4561 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4562 position, bufpos,
4563 FRAME_WINDOW_P (it->f));
4564
4565 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4566 }
4567
4568 /* Subroutine of handle_display_prop. Returns non-zero if the display
4569 specification in SPEC is a replacing specification, i.e. it would
4570 replace the text covered by `display' property with something else,
4571 such as an image or a display string. If SPEC includes any kind or
4572 `(space ...) specification, the value is 2; this is used by
4573 compute_display_string_pos, which see.
4574
4575 See handle_single_display_spec for documentation of arguments.
4576 frame_window_p is non-zero if the window being redisplayed is on a
4577 GUI frame; this argument is used only if IT is NULL, see below.
4578
4579 IT can be NULL, if this is called by the bidi reordering code
4580 through compute_display_string_pos, which see. In that case, this
4581 function only examines SPEC, but does not otherwise "handle" it, in
4582 the sense that it doesn't set up members of IT from the display
4583 spec. */
4584 static int
4585 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4586 Lisp_Object overlay, struct text_pos *position,
4587 ptrdiff_t bufpos, int frame_window_p)
4588 {
4589 int replacing_p = 0;
4590 int rv;
4591
4592 if (CONSP (spec)
4593 /* Simple specifications. */
4594 && !EQ (XCAR (spec), Qimage)
4595 && !EQ (XCAR (spec), Qspace)
4596 && !EQ (XCAR (spec), Qwhen)
4597 && !EQ (XCAR (spec), Qslice)
4598 && !EQ (XCAR (spec), Qspace_width)
4599 && !EQ (XCAR (spec), Qheight)
4600 && !EQ (XCAR (spec), Qraise)
4601 /* Marginal area specifications. */
4602 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4603 && !EQ (XCAR (spec), Qleft_fringe)
4604 && !EQ (XCAR (spec), Qright_fringe)
4605 && !NILP (XCAR (spec)))
4606 {
4607 for (; CONSP (spec); spec = XCDR (spec))
4608 {
4609 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4610 overlay, position, bufpos,
4611 replacing_p, frame_window_p)))
4612 {
4613 replacing_p = rv;
4614 /* If some text in a string is replaced, `position' no
4615 longer points to the position of `object'. */
4616 if (!it || STRINGP (object))
4617 break;
4618 }
4619 }
4620 }
4621 else if (VECTORP (spec))
4622 {
4623 ptrdiff_t i;
4624 for (i = 0; i < ASIZE (spec); ++i)
4625 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4626 overlay, position, bufpos,
4627 replacing_p, frame_window_p)))
4628 {
4629 replacing_p = rv;
4630 /* If some text in a string is replaced, `position' no
4631 longer points to the position of `object'. */
4632 if (!it || STRINGP (object))
4633 break;
4634 }
4635 }
4636 else
4637 {
4638 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4639 position, bufpos, 0,
4640 frame_window_p)))
4641 replacing_p = rv;
4642 }
4643
4644 return replacing_p;
4645 }
4646
4647 /* Value is the position of the end of the `display' property starting
4648 at START_POS in OBJECT. */
4649
4650 static struct text_pos
4651 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4652 {
4653 Lisp_Object end;
4654 struct text_pos end_pos;
4655
4656 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4657 Qdisplay, object, Qnil);
4658 CHARPOS (end_pos) = XFASTINT (end);
4659 if (STRINGP (object))
4660 compute_string_pos (&end_pos, start_pos, it->string);
4661 else
4662 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4663
4664 return end_pos;
4665 }
4666
4667
4668 /* Set up IT from a single `display' property specification SPEC. OBJECT
4669 is the object in which the `display' property was found. *POSITION
4670 is the position in OBJECT at which the `display' property was found.
4671 BUFPOS is the buffer position of OBJECT (different from POSITION if
4672 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4673 previously saw a display specification which already replaced text
4674 display with something else, for example an image; we ignore such
4675 properties after the first one has been processed.
4676
4677 OVERLAY is the overlay this `display' property came from,
4678 or nil if it was a text property.
4679
4680 If SPEC is a `space' or `image' specification, and in some other
4681 cases too, set *POSITION to the position where the `display'
4682 property ends.
4683
4684 If IT is NULL, only examine the property specification in SPEC, but
4685 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4686 is intended to be displayed in a window on a GUI frame.
4687
4688 Value is non-zero if something was found which replaces the display
4689 of buffer or string text. */
4690
4691 static int
4692 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4693 Lisp_Object overlay, struct text_pos *position,
4694 ptrdiff_t bufpos, int display_replaced_p,
4695 int frame_window_p)
4696 {
4697 Lisp_Object form;
4698 Lisp_Object location, value;
4699 struct text_pos start_pos = *position;
4700 int valid_p;
4701
4702 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4703 If the result is non-nil, use VALUE instead of SPEC. */
4704 form = Qt;
4705 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4706 {
4707 spec = XCDR (spec);
4708 if (!CONSP (spec))
4709 return 0;
4710 form = XCAR (spec);
4711 spec = XCDR (spec);
4712 }
4713
4714 if (!NILP (form) && !EQ (form, Qt))
4715 {
4716 ptrdiff_t count = SPECPDL_INDEX ();
4717 struct gcpro gcpro1;
4718
4719 /* Bind `object' to the object having the `display' property, a
4720 buffer or string. Bind `position' to the position in the
4721 object where the property was found, and `buffer-position'
4722 to the current position in the buffer. */
4723
4724 if (NILP (object))
4725 XSETBUFFER (object, current_buffer);
4726 specbind (Qobject, object);
4727 specbind (Qposition, make_number (CHARPOS (*position)));
4728 specbind (Qbuffer_position, make_number (bufpos));
4729 GCPRO1 (form);
4730 form = safe_eval (form);
4731 UNGCPRO;
4732 unbind_to (count, Qnil);
4733 }
4734
4735 if (NILP (form))
4736 return 0;
4737
4738 /* Handle `(height HEIGHT)' specifications. */
4739 if (CONSP (spec)
4740 && EQ (XCAR (spec), Qheight)
4741 && CONSP (XCDR (spec)))
4742 {
4743 if (it)
4744 {
4745 if (!FRAME_WINDOW_P (it->f))
4746 return 0;
4747
4748 it->font_height = XCAR (XCDR (spec));
4749 if (!NILP (it->font_height))
4750 {
4751 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4752 int new_height = -1;
4753
4754 if (CONSP (it->font_height)
4755 && (EQ (XCAR (it->font_height), Qplus)
4756 || EQ (XCAR (it->font_height), Qminus))
4757 && CONSP (XCDR (it->font_height))
4758 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4759 {
4760 /* `(+ N)' or `(- N)' where N is an integer. */
4761 int steps = XINT (XCAR (XCDR (it->font_height)));
4762 if (EQ (XCAR (it->font_height), Qplus))
4763 steps = - steps;
4764 it->face_id = smaller_face (it->f, it->face_id, steps);
4765 }
4766 else if (FUNCTIONP (it->font_height))
4767 {
4768 /* Call function with current height as argument.
4769 Value is the new height. */
4770 Lisp_Object height;
4771 height = safe_call1 (it->font_height,
4772 face->lface[LFACE_HEIGHT_INDEX]);
4773 if (NUMBERP (height))
4774 new_height = XFLOATINT (height);
4775 }
4776 else if (NUMBERP (it->font_height))
4777 {
4778 /* Value is a multiple of the canonical char height. */
4779 struct face *f;
4780
4781 f = FACE_FROM_ID (it->f,
4782 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4783 new_height = (XFLOATINT (it->font_height)
4784 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4785 }
4786 else
4787 {
4788 /* Evaluate IT->font_height with `height' bound to the
4789 current specified height to get the new height. */
4790 ptrdiff_t count = SPECPDL_INDEX ();
4791
4792 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4793 value = safe_eval (it->font_height);
4794 unbind_to (count, Qnil);
4795
4796 if (NUMBERP (value))
4797 new_height = XFLOATINT (value);
4798 }
4799
4800 if (new_height > 0)
4801 it->face_id = face_with_height (it->f, it->face_id, new_height);
4802 }
4803 }
4804
4805 return 0;
4806 }
4807
4808 /* Handle `(space-width WIDTH)'. */
4809 if (CONSP (spec)
4810 && EQ (XCAR (spec), Qspace_width)
4811 && CONSP (XCDR (spec)))
4812 {
4813 if (it)
4814 {
4815 if (!FRAME_WINDOW_P (it->f))
4816 return 0;
4817
4818 value = XCAR (XCDR (spec));
4819 if (NUMBERP (value) && XFLOATINT (value) > 0)
4820 it->space_width = value;
4821 }
4822
4823 return 0;
4824 }
4825
4826 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4827 if (CONSP (spec)
4828 && EQ (XCAR (spec), Qslice))
4829 {
4830 Lisp_Object tem;
4831
4832 if (it)
4833 {
4834 if (!FRAME_WINDOW_P (it->f))
4835 return 0;
4836
4837 if (tem = XCDR (spec), CONSP (tem))
4838 {
4839 it->slice.x = XCAR (tem);
4840 if (tem = XCDR (tem), CONSP (tem))
4841 {
4842 it->slice.y = XCAR (tem);
4843 if (tem = XCDR (tem), CONSP (tem))
4844 {
4845 it->slice.width = XCAR (tem);
4846 if (tem = XCDR (tem), CONSP (tem))
4847 it->slice.height = XCAR (tem);
4848 }
4849 }
4850 }
4851 }
4852
4853 return 0;
4854 }
4855
4856 /* Handle `(raise FACTOR)'. */
4857 if (CONSP (spec)
4858 && EQ (XCAR (spec), Qraise)
4859 && CONSP (XCDR (spec)))
4860 {
4861 if (it)
4862 {
4863 if (!FRAME_WINDOW_P (it->f))
4864 return 0;
4865
4866 #ifdef HAVE_WINDOW_SYSTEM
4867 value = XCAR (XCDR (spec));
4868 if (NUMBERP (value))
4869 {
4870 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4871 it->voffset = - (XFLOATINT (value)
4872 * (FONT_HEIGHT (face->font)));
4873 }
4874 #endif /* HAVE_WINDOW_SYSTEM */
4875 }
4876
4877 return 0;
4878 }
4879
4880 /* Don't handle the other kinds of display specifications
4881 inside a string that we got from a `display' property. */
4882 if (it && it->string_from_display_prop_p)
4883 return 0;
4884
4885 /* Characters having this form of property are not displayed, so
4886 we have to find the end of the property. */
4887 if (it)
4888 {
4889 start_pos = *position;
4890 *position = display_prop_end (it, object, start_pos);
4891 }
4892 value = Qnil;
4893
4894 /* Stop the scan at that end position--we assume that all
4895 text properties change there. */
4896 if (it)
4897 it->stop_charpos = position->charpos;
4898
4899 /* Handle `(left-fringe BITMAP [FACE])'
4900 and `(right-fringe BITMAP [FACE])'. */
4901 if (CONSP (spec)
4902 && (EQ (XCAR (spec), Qleft_fringe)
4903 || EQ (XCAR (spec), Qright_fringe))
4904 && CONSP (XCDR (spec)))
4905 {
4906 int fringe_bitmap;
4907
4908 if (it)
4909 {
4910 if (!FRAME_WINDOW_P (it->f))
4911 /* If we return here, POSITION has been advanced
4912 across the text with this property. */
4913 {
4914 /* Synchronize the bidi iterator with POSITION. This is
4915 needed because we are not going to push the iterator
4916 on behalf of this display property, so there will be
4917 no pop_it call to do this synchronization for us. */
4918 if (it->bidi_p)
4919 {
4920 it->position = *position;
4921 iterate_out_of_display_property (it);
4922 *position = it->position;
4923 }
4924 return 1;
4925 }
4926 }
4927 else if (!frame_window_p)
4928 return 1;
4929
4930 #ifdef HAVE_WINDOW_SYSTEM
4931 value = XCAR (XCDR (spec));
4932 if (!SYMBOLP (value)
4933 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4934 /* If we return here, POSITION has been advanced
4935 across the text with this property. */
4936 {
4937 if (it && it->bidi_p)
4938 {
4939 it->position = *position;
4940 iterate_out_of_display_property (it);
4941 *position = it->position;
4942 }
4943 return 1;
4944 }
4945
4946 if (it)
4947 {
4948 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4949
4950 if (CONSP (XCDR (XCDR (spec))))
4951 {
4952 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4953 int face_id2 = lookup_derived_face (it->f, face_name,
4954 FRINGE_FACE_ID, 0);
4955 if (face_id2 >= 0)
4956 face_id = face_id2;
4957 }
4958
4959 /* Save current settings of IT so that we can restore them
4960 when we are finished with the glyph property value. */
4961 push_it (it, position);
4962
4963 it->area = TEXT_AREA;
4964 it->what = IT_IMAGE;
4965 it->image_id = -1; /* no image */
4966 it->position = start_pos;
4967 it->object = NILP (object) ? it->w->contents : object;
4968 it->method = GET_FROM_IMAGE;
4969 it->from_overlay = Qnil;
4970 it->face_id = face_id;
4971 it->from_disp_prop_p = 1;
4972
4973 /* Say that we haven't consumed the characters with
4974 `display' property yet. The call to pop_it in
4975 set_iterator_to_next will clean this up. */
4976 *position = start_pos;
4977
4978 if (EQ (XCAR (spec), Qleft_fringe))
4979 {
4980 it->left_user_fringe_bitmap = fringe_bitmap;
4981 it->left_user_fringe_face_id = face_id;
4982 }
4983 else
4984 {
4985 it->right_user_fringe_bitmap = fringe_bitmap;
4986 it->right_user_fringe_face_id = face_id;
4987 }
4988 }
4989 #endif /* HAVE_WINDOW_SYSTEM */
4990 return 1;
4991 }
4992
4993 /* Prepare to handle `((margin left-margin) ...)',
4994 `((margin right-margin) ...)' and `((margin nil) ...)'
4995 prefixes for display specifications. */
4996 location = Qunbound;
4997 if (CONSP (spec) && CONSP (XCAR (spec)))
4998 {
4999 Lisp_Object tem;
5000
5001 value = XCDR (spec);
5002 if (CONSP (value))
5003 value = XCAR (value);
5004
5005 tem = XCAR (spec);
5006 if (EQ (XCAR (tem), Qmargin)
5007 && (tem = XCDR (tem),
5008 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5009 (NILP (tem)
5010 || EQ (tem, Qleft_margin)
5011 || EQ (tem, Qright_margin))))
5012 location = tem;
5013 }
5014
5015 if (EQ (location, Qunbound))
5016 {
5017 location = Qnil;
5018 value = spec;
5019 }
5020
5021 /* After this point, VALUE is the property after any
5022 margin prefix has been stripped. It must be a string,
5023 an image specification, or `(space ...)'.
5024
5025 LOCATION specifies where to display: `left-margin',
5026 `right-margin' or nil. */
5027
5028 valid_p = (STRINGP (value)
5029 #ifdef HAVE_WINDOW_SYSTEM
5030 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5031 && valid_image_p (value))
5032 #endif /* not HAVE_WINDOW_SYSTEM */
5033 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5034
5035 if (valid_p && !display_replaced_p)
5036 {
5037 int retval = 1;
5038
5039 if (!it)
5040 {
5041 /* Callers need to know whether the display spec is any kind
5042 of `(space ...)' spec that is about to affect text-area
5043 display. */
5044 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5045 retval = 2;
5046 return retval;
5047 }
5048
5049 /* Save current settings of IT so that we can restore them
5050 when we are finished with the glyph property value. */
5051 push_it (it, position);
5052 it->from_overlay = overlay;
5053 it->from_disp_prop_p = 1;
5054
5055 if (NILP (location))
5056 it->area = TEXT_AREA;
5057 else if (EQ (location, Qleft_margin))
5058 it->area = LEFT_MARGIN_AREA;
5059 else
5060 it->area = RIGHT_MARGIN_AREA;
5061
5062 if (STRINGP (value))
5063 {
5064 it->string = value;
5065 it->multibyte_p = STRING_MULTIBYTE (it->string);
5066 it->current.overlay_string_index = -1;
5067 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5068 it->end_charpos = it->string_nchars = SCHARS (it->string);
5069 it->method = GET_FROM_STRING;
5070 it->stop_charpos = 0;
5071 it->prev_stop = 0;
5072 it->base_level_stop = 0;
5073 it->string_from_display_prop_p = 1;
5074 /* Say that we haven't consumed the characters with
5075 `display' property yet. The call to pop_it in
5076 set_iterator_to_next will clean this up. */
5077 if (BUFFERP (object))
5078 *position = start_pos;
5079
5080 /* Force paragraph direction to be that of the parent
5081 object. If the parent object's paragraph direction is
5082 not yet determined, default to L2R. */
5083 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5084 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5085 else
5086 it->paragraph_embedding = L2R;
5087
5088 /* Set up the bidi iterator for this display string. */
5089 if (it->bidi_p)
5090 {
5091 it->bidi_it.string.lstring = it->string;
5092 it->bidi_it.string.s = NULL;
5093 it->bidi_it.string.schars = it->end_charpos;
5094 it->bidi_it.string.bufpos = bufpos;
5095 it->bidi_it.string.from_disp_str = 1;
5096 it->bidi_it.string.unibyte = !it->multibyte_p;
5097 it->bidi_it.w = it->w;
5098 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5099 }
5100 }
5101 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5102 {
5103 it->method = GET_FROM_STRETCH;
5104 it->object = value;
5105 *position = it->position = start_pos;
5106 retval = 1 + (it->area == TEXT_AREA);
5107 }
5108 #ifdef HAVE_WINDOW_SYSTEM
5109 else
5110 {
5111 it->what = IT_IMAGE;
5112 it->image_id = lookup_image (it->f, value);
5113 it->position = start_pos;
5114 it->object = NILP (object) ? it->w->contents : object;
5115 it->method = GET_FROM_IMAGE;
5116
5117 /* Say that we haven't consumed the characters with
5118 `display' property yet. The call to pop_it in
5119 set_iterator_to_next will clean this up. */
5120 *position = start_pos;
5121 }
5122 #endif /* HAVE_WINDOW_SYSTEM */
5123
5124 return retval;
5125 }
5126
5127 /* Invalid property or property not supported. Restore
5128 POSITION to what it was before. */
5129 *position = start_pos;
5130 return 0;
5131 }
5132
5133 /* Check if PROP is a display property value whose text should be
5134 treated as intangible. OVERLAY is the overlay from which PROP
5135 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5136 specify the buffer position covered by PROP. */
5137
5138 int
5139 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5140 ptrdiff_t charpos, ptrdiff_t bytepos)
5141 {
5142 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5143 struct text_pos position;
5144
5145 SET_TEXT_POS (position, charpos, bytepos);
5146 return handle_display_spec (NULL, prop, Qnil, overlay,
5147 &position, charpos, frame_window_p);
5148 }
5149
5150
5151 /* Return 1 if PROP is a display sub-property value containing STRING.
5152
5153 Implementation note: this and the following function are really
5154 special cases of handle_display_spec and
5155 handle_single_display_spec, and should ideally use the same code.
5156 Until they do, these two pairs must be consistent and must be
5157 modified in sync. */
5158
5159 static int
5160 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5161 {
5162 if (EQ (string, prop))
5163 return 1;
5164
5165 /* Skip over `when FORM'. */
5166 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5167 {
5168 prop = XCDR (prop);
5169 if (!CONSP (prop))
5170 return 0;
5171 /* Actually, the condition following `when' should be eval'ed,
5172 like handle_single_display_spec does, and we should return
5173 zero if it evaluates to nil. However, this function is
5174 called only when the buffer was already displayed and some
5175 glyph in the glyph matrix was found to come from a display
5176 string. Therefore, the condition was already evaluated, and
5177 the result was non-nil, otherwise the display string wouldn't
5178 have been displayed and we would have never been called for
5179 this property. Thus, we can skip the evaluation and assume
5180 its result is non-nil. */
5181 prop = XCDR (prop);
5182 }
5183
5184 if (CONSP (prop))
5185 /* Skip over `margin LOCATION'. */
5186 if (EQ (XCAR (prop), Qmargin))
5187 {
5188 prop = XCDR (prop);
5189 if (!CONSP (prop))
5190 return 0;
5191
5192 prop = XCDR (prop);
5193 if (!CONSP (prop))
5194 return 0;
5195 }
5196
5197 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5198 }
5199
5200
5201 /* Return 1 if STRING appears in the `display' property PROP. */
5202
5203 static int
5204 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5205 {
5206 if (CONSP (prop)
5207 && !EQ (XCAR (prop), Qwhen)
5208 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5209 {
5210 /* A list of sub-properties. */
5211 while (CONSP (prop))
5212 {
5213 if (single_display_spec_string_p (XCAR (prop), string))
5214 return 1;
5215 prop = XCDR (prop);
5216 }
5217 }
5218 else if (VECTORP (prop))
5219 {
5220 /* A vector of sub-properties. */
5221 ptrdiff_t i;
5222 for (i = 0; i < ASIZE (prop); ++i)
5223 if (single_display_spec_string_p (AREF (prop, i), string))
5224 return 1;
5225 }
5226 else
5227 return single_display_spec_string_p (prop, string);
5228
5229 return 0;
5230 }
5231
5232 /* Look for STRING in overlays and text properties in the current
5233 buffer, between character positions FROM and TO (excluding TO).
5234 BACK_P non-zero means look back (in this case, TO is supposed to be
5235 less than FROM).
5236 Value is the first character position where STRING was found, or
5237 zero if it wasn't found before hitting TO.
5238
5239 This function may only use code that doesn't eval because it is
5240 called asynchronously from note_mouse_highlight. */
5241
5242 static ptrdiff_t
5243 string_buffer_position_lim (Lisp_Object string,
5244 ptrdiff_t from, ptrdiff_t to, int back_p)
5245 {
5246 Lisp_Object limit, prop, pos;
5247 int found = 0;
5248
5249 pos = make_number (max (from, BEGV));
5250
5251 if (!back_p) /* looking forward */
5252 {
5253 limit = make_number (min (to, ZV));
5254 while (!found && !EQ (pos, limit))
5255 {
5256 prop = Fget_char_property (pos, Qdisplay, Qnil);
5257 if (!NILP (prop) && display_prop_string_p (prop, string))
5258 found = 1;
5259 else
5260 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5261 limit);
5262 }
5263 }
5264 else /* looking back */
5265 {
5266 limit = make_number (max (to, BEGV));
5267 while (!found && !EQ (pos, limit))
5268 {
5269 prop = Fget_char_property (pos, Qdisplay, Qnil);
5270 if (!NILP (prop) && display_prop_string_p (prop, string))
5271 found = 1;
5272 else
5273 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5274 limit);
5275 }
5276 }
5277
5278 return found ? XINT (pos) : 0;
5279 }
5280
5281 /* Determine which buffer position in current buffer STRING comes from.
5282 AROUND_CHARPOS is an approximate position where it could come from.
5283 Value is the buffer position or 0 if it couldn't be determined.
5284
5285 This function is necessary because we don't record buffer positions
5286 in glyphs generated from strings (to keep struct glyph small).
5287 This function may only use code that doesn't eval because it is
5288 called asynchronously from note_mouse_highlight. */
5289
5290 static ptrdiff_t
5291 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5292 {
5293 const int MAX_DISTANCE = 1000;
5294 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5295 around_charpos + MAX_DISTANCE,
5296 0);
5297
5298 if (!found)
5299 found = string_buffer_position_lim (string, around_charpos,
5300 around_charpos - MAX_DISTANCE, 1);
5301 return found;
5302 }
5303
5304
5305 \f
5306 /***********************************************************************
5307 `composition' property
5308 ***********************************************************************/
5309
5310 /* Set up iterator IT from `composition' property at its current
5311 position. Called from handle_stop. */
5312
5313 static enum prop_handled
5314 handle_composition_prop (struct it *it)
5315 {
5316 Lisp_Object prop, string;
5317 ptrdiff_t pos, pos_byte, start, end;
5318
5319 if (STRINGP (it->string))
5320 {
5321 unsigned char *s;
5322
5323 pos = IT_STRING_CHARPOS (*it);
5324 pos_byte = IT_STRING_BYTEPOS (*it);
5325 string = it->string;
5326 s = SDATA (string) + pos_byte;
5327 it->c = STRING_CHAR (s);
5328 }
5329 else
5330 {
5331 pos = IT_CHARPOS (*it);
5332 pos_byte = IT_BYTEPOS (*it);
5333 string = Qnil;
5334 it->c = FETCH_CHAR (pos_byte);
5335 }
5336
5337 /* If there's a valid composition and point is not inside of the
5338 composition (in the case that the composition is from the current
5339 buffer), draw a glyph composed from the composition components. */
5340 if (find_composition (pos, -1, &start, &end, &prop, string)
5341 && composition_valid_p (start, end, prop)
5342 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5343 {
5344 if (start < pos)
5345 /* As we can't handle this situation (perhaps font-lock added
5346 a new composition), we just return here hoping that next
5347 redisplay will detect this composition much earlier. */
5348 return HANDLED_NORMALLY;
5349 if (start != pos)
5350 {
5351 if (STRINGP (it->string))
5352 pos_byte = string_char_to_byte (it->string, start);
5353 else
5354 pos_byte = CHAR_TO_BYTE (start);
5355 }
5356 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5357 prop, string);
5358
5359 if (it->cmp_it.id >= 0)
5360 {
5361 it->cmp_it.ch = -1;
5362 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5363 it->cmp_it.nglyphs = -1;
5364 }
5365 }
5366
5367 return HANDLED_NORMALLY;
5368 }
5369
5370
5371 \f
5372 /***********************************************************************
5373 Overlay strings
5374 ***********************************************************************/
5375
5376 /* The following structure is used to record overlay strings for
5377 later sorting in load_overlay_strings. */
5378
5379 struct overlay_entry
5380 {
5381 Lisp_Object overlay;
5382 Lisp_Object string;
5383 EMACS_INT priority;
5384 int after_string_p;
5385 };
5386
5387
5388 /* Set up iterator IT from overlay strings at its current position.
5389 Called from handle_stop. */
5390
5391 static enum prop_handled
5392 handle_overlay_change (struct it *it)
5393 {
5394 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5395 return HANDLED_RECOMPUTE_PROPS;
5396 else
5397 return HANDLED_NORMALLY;
5398 }
5399
5400
5401 /* Set up the next overlay string for delivery by IT, if there is an
5402 overlay string to deliver. Called by set_iterator_to_next when the
5403 end of the current overlay string is reached. If there are more
5404 overlay strings to display, IT->string and
5405 IT->current.overlay_string_index are set appropriately here.
5406 Otherwise IT->string is set to nil. */
5407
5408 static void
5409 next_overlay_string (struct it *it)
5410 {
5411 ++it->current.overlay_string_index;
5412 if (it->current.overlay_string_index == it->n_overlay_strings)
5413 {
5414 /* No more overlay strings. Restore IT's settings to what
5415 they were before overlay strings were processed, and
5416 continue to deliver from current_buffer. */
5417
5418 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5419 pop_it (it);
5420 eassert (it->sp > 0
5421 || (NILP (it->string)
5422 && it->method == GET_FROM_BUFFER
5423 && it->stop_charpos >= BEGV
5424 && it->stop_charpos <= it->end_charpos));
5425 it->current.overlay_string_index = -1;
5426 it->n_overlay_strings = 0;
5427 it->overlay_strings_charpos = -1;
5428 /* If there's an empty display string on the stack, pop the
5429 stack, to resync the bidi iterator with IT's position. Such
5430 empty strings are pushed onto the stack in
5431 get_overlay_strings_1. */
5432 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5433 pop_it (it);
5434
5435 /* If we're at the end of the buffer, record that we have
5436 processed the overlay strings there already, so that
5437 next_element_from_buffer doesn't try it again. */
5438 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5439 it->overlay_strings_at_end_processed_p = 1;
5440 }
5441 else
5442 {
5443 /* There are more overlay strings to process. If
5444 IT->current.overlay_string_index has advanced to a position
5445 where we must load IT->overlay_strings with more strings, do
5446 it. We must load at the IT->overlay_strings_charpos where
5447 IT->n_overlay_strings was originally computed; when invisible
5448 text is present, this might not be IT_CHARPOS (Bug#7016). */
5449 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5450
5451 if (it->current.overlay_string_index && i == 0)
5452 load_overlay_strings (it, it->overlay_strings_charpos);
5453
5454 /* Initialize IT to deliver display elements from the overlay
5455 string. */
5456 it->string = it->overlay_strings[i];
5457 it->multibyte_p = STRING_MULTIBYTE (it->string);
5458 SET_TEXT_POS (it->current.string_pos, 0, 0);
5459 it->method = GET_FROM_STRING;
5460 it->stop_charpos = 0;
5461 it->end_charpos = SCHARS (it->string);
5462 if (it->cmp_it.stop_pos >= 0)
5463 it->cmp_it.stop_pos = 0;
5464 it->prev_stop = 0;
5465 it->base_level_stop = 0;
5466
5467 /* Set up the bidi iterator for this overlay string. */
5468 if (it->bidi_p)
5469 {
5470 it->bidi_it.string.lstring = it->string;
5471 it->bidi_it.string.s = NULL;
5472 it->bidi_it.string.schars = SCHARS (it->string);
5473 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5474 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5475 it->bidi_it.string.unibyte = !it->multibyte_p;
5476 it->bidi_it.w = it->w;
5477 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5478 }
5479 }
5480
5481 CHECK_IT (it);
5482 }
5483
5484
5485 /* Compare two overlay_entry structures E1 and E2. Used as a
5486 comparison function for qsort in load_overlay_strings. Overlay
5487 strings for the same position are sorted so that
5488
5489 1. All after-strings come in front of before-strings, except
5490 when they come from the same overlay.
5491
5492 2. Within after-strings, strings are sorted so that overlay strings
5493 from overlays with higher priorities come first.
5494
5495 2. Within before-strings, strings are sorted so that overlay
5496 strings from overlays with higher priorities come last.
5497
5498 Value is analogous to strcmp. */
5499
5500
5501 static int
5502 compare_overlay_entries (const void *e1, const void *e2)
5503 {
5504 struct overlay_entry const *entry1 = e1;
5505 struct overlay_entry const *entry2 = e2;
5506 int result;
5507
5508 if (entry1->after_string_p != entry2->after_string_p)
5509 {
5510 /* Let after-strings appear in front of before-strings if
5511 they come from different overlays. */
5512 if (EQ (entry1->overlay, entry2->overlay))
5513 result = entry1->after_string_p ? 1 : -1;
5514 else
5515 result = entry1->after_string_p ? -1 : 1;
5516 }
5517 else if (entry1->priority != entry2->priority)
5518 {
5519 if (entry1->after_string_p)
5520 /* After-strings sorted in order of decreasing priority. */
5521 result = entry2->priority < entry1->priority ? -1 : 1;
5522 else
5523 /* Before-strings sorted in order of increasing priority. */
5524 result = entry1->priority < entry2->priority ? -1 : 1;
5525 }
5526 else
5527 result = 0;
5528
5529 return result;
5530 }
5531
5532
5533 /* Load the vector IT->overlay_strings with overlay strings from IT's
5534 current buffer position, or from CHARPOS if that is > 0. Set
5535 IT->n_overlays to the total number of overlay strings found.
5536
5537 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5538 a time. On entry into load_overlay_strings,
5539 IT->current.overlay_string_index gives the number of overlay
5540 strings that have already been loaded by previous calls to this
5541 function.
5542
5543 IT->add_overlay_start contains an additional overlay start
5544 position to consider for taking overlay strings from, if non-zero.
5545 This position comes into play when the overlay has an `invisible'
5546 property, and both before and after-strings. When we've skipped to
5547 the end of the overlay, because of its `invisible' property, we
5548 nevertheless want its before-string to appear.
5549 IT->add_overlay_start will contain the overlay start position
5550 in this case.
5551
5552 Overlay strings are sorted so that after-string strings come in
5553 front of before-string strings. Within before and after-strings,
5554 strings are sorted by overlay priority. See also function
5555 compare_overlay_entries. */
5556
5557 static void
5558 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5559 {
5560 Lisp_Object overlay, window, str, invisible;
5561 struct Lisp_Overlay *ov;
5562 ptrdiff_t start, end;
5563 ptrdiff_t size = 20;
5564 ptrdiff_t n = 0, i, j;
5565 int invis_p;
5566 struct overlay_entry *entries = alloca (size * sizeof *entries);
5567 USE_SAFE_ALLOCA;
5568
5569 if (charpos <= 0)
5570 charpos = IT_CHARPOS (*it);
5571
5572 /* Append the overlay string STRING of overlay OVERLAY to vector
5573 `entries' which has size `size' and currently contains `n'
5574 elements. AFTER_P non-zero means STRING is an after-string of
5575 OVERLAY. */
5576 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5577 do \
5578 { \
5579 Lisp_Object priority; \
5580 \
5581 if (n == size) \
5582 { \
5583 struct overlay_entry *old = entries; \
5584 SAFE_NALLOCA (entries, 2, size); \
5585 memcpy (entries, old, size * sizeof *entries); \
5586 size *= 2; \
5587 } \
5588 \
5589 entries[n].string = (STRING); \
5590 entries[n].overlay = (OVERLAY); \
5591 priority = Foverlay_get ((OVERLAY), Qpriority); \
5592 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5593 entries[n].after_string_p = (AFTER_P); \
5594 ++n; \
5595 } \
5596 while (0)
5597
5598 /* Process overlay before the overlay center. */
5599 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5600 {
5601 XSETMISC (overlay, ov);
5602 eassert (OVERLAYP (overlay));
5603 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5604 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5605
5606 if (end < charpos)
5607 break;
5608
5609 /* Skip this overlay if it doesn't start or end at IT's current
5610 position. */
5611 if (end != charpos && start != charpos)
5612 continue;
5613
5614 /* Skip this overlay if it doesn't apply to IT->w. */
5615 window = Foverlay_get (overlay, Qwindow);
5616 if (WINDOWP (window) && XWINDOW (window) != it->w)
5617 continue;
5618
5619 /* If the text ``under'' the overlay is invisible, both before-
5620 and after-strings from this overlay are visible; start and
5621 end position are indistinguishable. */
5622 invisible = Foverlay_get (overlay, Qinvisible);
5623 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5624
5625 /* If overlay has a non-empty before-string, record it. */
5626 if ((start == charpos || (end == charpos && invis_p))
5627 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5628 && SCHARS (str))
5629 RECORD_OVERLAY_STRING (overlay, str, 0);
5630
5631 /* If overlay has a non-empty after-string, record it. */
5632 if ((end == charpos || (start == charpos && invis_p))
5633 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5634 && SCHARS (str))
5635 RECORD_OVERLAY_STRING (overlay, str, 1);
5636 }
5637
5638 /* Process overlays after the overlay center. */
5639 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5640 {
5641 XSETMISC (overlay, ov);
5642 eassert (OVERLAYP (overlay));
5643 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5644 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5645
5646 if (start > charpos)
5647 break;
5648
5649 /* Skip this overlay if it doesn't start or end at IT's current
5650 position. */
5651 if (end != charpos && start != charpos)
5652 continue;
5653
5654 /* Skip this overlay if it doesn't apply to IT->w. */
5655 window = Foverlay_get (overlay, Qwindow);
5656 if (WINDOWP (window) && XWINDOW (window) != it->w)
5657 continue;
5658
5659 /* If the text ``under'' the overlay is invisible, it has a zero
5660 dimension, and both before- and after-strings apply. */
5661 invisible = Foverlay_get (overlay, Qinvisible);
5662 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5663
5664 /* If overlay has a non-empty before-string, record it. */
5665 if ((start == charpos || (end == charpos && invis_p))
5666 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5667 && SCHARS (str))
5668 RECORD_OVERLAY_STRING (overlay, str, 0);
5669
5670 /* If overlay has a non-empty after-string, record it. */
5671 if ((end == charpos || (start == charpos && invis_p))
5672 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5673 && SCHARS (str))
5674 RECORD_OVERLAY_STRING (overlay, str, 1);
5675 }
5676
5677 #undef RECORD_OVERLAY_STRING
5678
5679 /* Sort entries. */
5680 if (n > 1)
5681 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5682
5683 /* Record number of overlay strings, and where we computed it. */
5684 it->n_overlay_strings = n;
5685 it->overlay_strings_charpos = charpos;
5686
5687 /* IT->current.overlay_string_index is the number of overlay strings
5688 that have already been consumed by IT. Copy some of the
5689 remaining overlay strings to IT->overlay_strings. */
5690 i = 0;
5691 j = it->current.overlay_string_index;
5692 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5693 {
5694 it->overlay_strings[i] = entries[j].string;
5695 it->string_overlays[i++] = entries[j++].overlay;
5696 }
5697
5698 CHECK_IT (it);
5699 SAFE_FREE ();
5700 }
5701
5702
5703 /* Get the first chunk of overlay strings at IT's current buffer
5704 position, or at CHARPOS if that is > 0. Value is non-zero if at
5705 least one overlay string was found. */
5706
5707 static int
5708 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5709 {
5710 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5711 process. This fills IT->overlay_strings with strings, and sets
5712 IT->n_overlay_strings to the total number of strings to process.
5713 IT->pos.overlay_string_index has to be set temporarily to zero
5714 because load_overlay_strings needs this; it must be set to -1
5715 when no overlay strings are found because a zero value would
5716 indicate a position in the first overlay string. */
5717 it->current.overlay_string_index = 0;
5718 load_overlay_strings (it, charpos);
5719
5720 /* If we found overlay strings, set up IT to deliver display
5721 elements from the first one. Otherwise set up IT to deliver
5722 from current_buffer. */
5723 if (it->n_overlay_strings)
5724 {
5725 /* Make sure we know settings in current_buffer, so that we can
5726 restore meaningful values when we're done with the overlay
5727 strings. */
5728 if (compute_stop_p)
5729 compute_stop_pos (it);
5730 eassert (it->face_id >= 0);
5731
5732 /* Save IT's settings. They are restored after all overlay
5733 strings have been processed. */
5734 eassert (!compute_stop_p || it->sp == 0);
5735
5736 /* When called from handle_stop, there might be an empty display
5737 string loaded. In that case, don't bother saving it. But
5738 don't use this optimization with the bidi iterator, since we
5739 need the corresponding pop_it call to resync the bidi
5740 iterator's position with IT's position, after we are done
5741 with the overlay strings. (The corresponding call to pop_it
5742 in case of an empty display string is in
5743 next_overlay_string.) */
5744 if (!(!it->bidi_p
5745 && STRINGP (it->string) && !SCHARS (it->string)))
5746 push_it (it, NULL);
5747
5748 /* Set up IT to deliver display elements from the first overlay
5749 string. */
5750 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5751 it->string = it->overlay_strings[0];
5752 it->from_overlay = Qnil;
5753 it->stop_charpos = 0;
5754 eassert (STRINGP (it->string));
5755 it->end_charpos = SCHARS (it->string);
5756 it->prev_stop = 0;
5757 it->base_level_stop = 0;
5758 it->multibyte_p = STRING_MULTIBYTE (it->string);
5759 it->method = GET_FROM_STRING;
5760 it->from_disp_prop_p = 0;
5761
5762 /* Force paragraph direction to be that of the parent
5763 buffer. */
5764 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5765 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5766 else
5767 it->paragraph_embedding = L2R;
5768
5769 /* Set up the bidi iterator for this overlay string. */
5770 if (it->bidi_p)
5771 {
5772 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5773
5774 it->bidi_it.string.lstring = it->string;
5775 it->bidi_it.string.s = NULL;
5776 it->bidi_it.string.schars = SCHARS (it->string);
5777 it->bidi_it.string.bufpos = pos;
5778 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5779 it->bidi_it.string.unibyte = !it->multibyte_p;
5780 it->bidi_it.w = it->w;
5781 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5782 }
5783 return 1;
5784 }
5785
5786 it->current.overlay_string_index = -1;
5787 return 0;
5788 }
5789
5790 static int
5791 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5792 {
5793 it->string = Qnil;
5794 it->method = GET_FROM_BUFFER;
5795
5796 (void) get_overlay_strings_1 (it, charpos, 1);
5797
5798 CHECK_IT (it);
5799
5800 /* Value is non-zero if we found at least one overlay string. */
5801 return STRINGP (it->string);
5802 }
5803
5804
5805 \f
5806 /***********************************************************************
5807 Saving and restoring state
5808 ***********************************************************************/
5809
5810 /* Save current settings of IT on IT->stack. Called, for example,
5811 before setting up IT for an overlay string, to be able to restore
5812 IT's settings to what they were after the overlay string has been
5813 processed. If POSITION is non-NULL, it is the position to save on
5814 the stack instead of IT->position. */
5815
5816 static void
5817 push_it (struct it *it, struct text_pos *position)
5818 {
5819 struct iterator_stack_entry *p;
5820
5821 eassert (it->sp < IT_STACK_SIZE);
5822 p = it->stack + it->sp;
5823
5824 p->stop_charpos = it->stop_charpos;
5825 p->prev_stop = it->prev_stop;
5826 p->base_level_stop = it->base_level_stop;
5827 p->cmp_it = it->cmp_it;
5828 eassert (it->face_id >= 0);
5829 p->face_id = it->face_id;
5830 p->string = it->string;
5831 p->method = it->method;
5832 p->from_overlay = it->from_overlay;
5833 switch (p->method)
5834 {
5835 case GET_FROM_IMAGE:
5836 p->u.image.object = it->object;
5837 p->u.image.image_id = it->image_id;
5838 p->u.image.slice = it->slice;
5839 break;
5840 case GET_FROM_STRETCH:
5841 p->u.stretch.object = it->object;
5842 break;
5843 }
5844 p->position = position ? *position : it->position;
5845 p->current = it->current;
5846 p->end_charpos = it->end_charpos;
5847 p->string_nchars = it->string_nchars;
5848 p->area = it->area;
5849 p->multibyte_p = it->multibyte_p;
5850 p->avoid_cursor_p = it->avoid_cursor_p;
5851 p->space_width = it->space_width;
5852 p->font_height = it->font_height;
5853 p->voffset = it->voffset;
5854 p->string_from_display_prop_p = it->string_from_display_prop_p;
5855 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5856 p->display_ellipsis_p = 0;
5857 p->line_wrap = it->line_wrap;
5858 p->bidi_p = it->bidi_p;
5859 p->paragraph_embedding = it->paragraph_embedding;
5860 p->from_disp_prop_p = it->from_disp_prop_p;
5861 ++it->sp;
5862
5863 /* Save the state of the bidi iterator as well. */
5864 if (it->bidi_p)
5865 bidi_push_it (&it->bidi_it);
5866 }
5867
5868 static void
5869 iterate_out_of_display_property (struct it *it)
5870 {
5871 int buffer_p = !STRINGP (it->string);
5872 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5873 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5874
5875 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5876
5877 /* Maybe initialize paragraph direction. If we are at the beginning
5878 of a new paragraph, next_element_from_buffer may not have a
5879 chance to do that. */
5880 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5881 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5882 /* prev_stop can be zero, so check against BEGV as well. */
5883 while (it->bidi_it.charpos >= bob
5884 && it->prev_stop <= it->bidi_it.charpos
5885 && it->bidi_it.charpos < CHARPOS (it->position)
5886 && it->bidi_it.charpos < eob)
5887 bidi_move_to_visually_next (&it->bidi_it);
5888 /* Record the stop_pos we just crossed, for when we cross it
5889 back, maybe. */
5890 if (it->bidi_it.charpos > CHARPOS (it->position))
5891 it->prev_stop = CHARPOS (it->position);
5892 /* If we ended up not where pop_it put us, resync IT's
5893 positional members with the bidi iterator. */
5894 if (it->bidi_it.charpos != CHARPOS (it->position))
5895 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5896 if (buffer_p)
5897 it->current.pos = it->position;
5898 else
5899 it->current.string_pos = it->position;
5900 }
5901
5902 /* Restore IT's settings from IT->stack. Called, for example, when no
5903 more overlay strings must be processed, and we return to delivering
5904 display elements from a buffer, or when the end of a string from a
5905 `display' property is reached and we return to delivering display
5906 elements from an overlay string, or from a buffer. */
5907
5908 static void
5909 pop_it (struct it *it)
5910 {
5911 struct iterator_stack_entry *p;
5912 int from_display_prop = it->from_disp_prop_p;
5913
5914 eassert (it->sp > 0);
5915 --it->sp;
5916 p = it->stack + it->sp;
5917 it->stop_charpos = p->stop_charpos;
5918 it->prev_stop = p->prev_stop;
5919 it->base_level_stop = p->base_level_stop;
5920 it->cmp_it = p->cmp_it;
5921 it->face_id = p->face_id;
5922 it->current = p->current;
5923 it->position = p->position;
5924 it->string = p->string;
5925 it->from_overlay = p->from_overlay;
5926 if (NILP (it->string))
5927 SET_TEXT_POS (it->current.string_pos, -1, -1);
5928 it->method = p->method;
5929 switch (it->method)
5930 {
5931 case GET_FROM_IMAGE:
5932 it->image_id = p->u.image.image_id;
5933 it->object = p->u.image.object;
5934 it->slice = p->u.image.slice;
5935 break;
5936 case GET_FROM_STRETCH:
5937 it->object = p->u.stretch.object;
5938 break;
5939 case GET_FROM_BUFFER:
5940 it->object = it->w->contents;
5941 break;
5942 case GET_FROM_STRING:
5943 it->object = it->string;
5944 break;
5945 case GET_FROM_DISPLAY_VECTOR:
5946 if (it->s)
5947 it->method = GET_FROM_C_STRING;
5948 else if (STRINGP (it->string))
5949 it->method = GET_FROM_STRING;
5950 else
5951 {
5952 it->method = GET_FROM_BUFFER;
5953 it->object = it->w->contents;
5954 }
5955 }
5956 it->end_charpos = p->end_charpos;
5957 it->string_nchars = p->string_nchars;
5958 it->area = p->area;
5959 it->multibyte_p = p->multibyte_p;
5960 it->avoid_cursor_p = p->avoid_cursor_p;
5961 it->space_width = p->space_width;
5962 it->font_height = p->font_height;
5963 it->voffset = p->voffset;
5964 it->string_from_display_prop_p = p->string_from_display_prop_p;
5965 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5966 it->line_wrap = p->line_wrap;
5967 it->bidi_p = p->bidi_p;
5968 it->paragraph_embedding = p->paragraph_embedding;
5969 it->from_disp_prop_p = p->from_disp_prop_p;
5970 if (it->bidi_p)
5971 {
5972 bidi_pop_it (&it->bidi_it);
5973 /* Bidi-iterate until we get out of the portion of text, if any,
5974 covered by a `display' text property or by an overlay with
5975 `display' property. (We cannot just jump there, because the
5976 internal coherency of the bidi iterator state can not be
5977 preserved across such jumps.) We also must determine the
5978 paragraph base direction if the overlay we just processed is
5979 at the beginning of a new paragraph. */
5980 if (from_display_prop
5981 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5982 iterate_out_of_display_property (it);
5983
5984 eassert ((BUFFERP (it->object)
5985 && IT_CHARPOS (*it) == it->bidi_it.charpos
5986 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5987 || (STRINGP (it->object)
5988 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5989 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5990 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5991 }
5992 }
5993
5994
5995 \f
5996 /***********************************************************************
5997 Moving over lines
5998 ***********************************************************************/
5999
6000 /* Set IT's current position to the previous line start. */
6001
6002 static void
6003 back_to_previous_line_start (struct it *it)
6004 {
6005 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6006
6007 DEC_BOTH (cp, bp);
6008 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6009 }
6010
6011
6012 /* Move IT to the next line start.
6013
6014 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6015 we skipped over part of the text (as opposed to moving the iterator
6016 continuously over the text). Otherwise, don't change the value
6017 of *SKIPPED_P.
6018
6019 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6020 iterator on the newline, if it was found.
6021
6022 Newlines may come from buffer text, overlay strings, or strings
6023 displayed via the `display' property. That's the reason we can't
6024 simply use find_newline_no_quit.
6025
6026 Note that this function may not skip over invisible text that is so
6027 because of text properties and immediately follows a newline. If
6028 it would, function reseat_at_next_visible_line_start, when called
6029 from set_iterator_to_next, would effectively make invisible
6030 characters following a newline part of the wrong glyph row, which
6031 leads to wrong cursor motion. */
6032
6033 static int
6034 forward_to_next_line_start (struct it *it, int *skipped_p,
6035 struct bidi_it *bidi_it_prev)
6036 {
6037 ptrdiff_t old_selective;
6038 int newline_found_p, n;
6039 const int MAX_NEWLINE_DISTANCE = 500;
6040
6041 /* If already on a newline, just consume it to avoid unintended
6042 skipping over invisible text below. */
6043 if (it->what == IT_CHARACTER
6044 && it->c == '\n'
6045 && CHARPOS (it->position) == IT_CHARPOS (*it))
6046 {
6047 if (it->bidi_p && bidi_it_prev)
6048 *bidi_it_prev = it->bidi_it;
6049 set_iterator_to_next (it, 0);
6050 it->c = 0;
6051 return 1;
6052 }
6053
6054 /* Don't handle selective display in the following. It's (a)
6055 unnecessary because it's done by the caller, and (b) leads to an
6056 infinite recursion because next_element_from_ellipsis indirectly
6057 calls this function. */
6058 old_selective = it->selective;
6059 it->selective = 0;
6060
6061 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6062 from buffer text. */
6063 for (n = newline_found_p = 0;
6064 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6065 n += STRINGP (it->string) ? 0 : 1)
6066 {
6067 if (!get_next_display_element (it))
6068 return 0;
6069 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6070 if (newline_found_p && it->bidi_p && bidi_it_prev)
6071 *bidi_it_prev = it->bidi_it;
6072 set_iterator_to_next (it, 0);
6073 }
6074
6075 /* If we didn't find a newline near enough, see if we can use a
6076 short-cut. */
6077 if (!newline_found_p)
6078 {
6079 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6080 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6081 1, &bytepos);
6082 Lisp_Object pos;
6083
6084 eassert (!STRINGP (it->string));
6085
6086 /* If there isn't any `display' property in sight, and no
6087 overlays, we can just use the position of the newline in
6088 buffer text. */
6089 if (it->stop_charpos >= limit
6090 || ((pos = Fnext_single_property_change (make_number (start),
6091 Qdisplay, Qnil,
6092 make_number (limit)),
6093 NILP (pos))
6094 && next_overlay_change (start) == ZV))
6095 {
6096 if (!it->bidi_p)
6097 {
6098 IT_CHARPOS (*it) = limit;
6099 IT_BYTEPOS (*it) = bytepos;
6100 }
6101 else
6102 {
6103 struct bidi_it bprev;
6104
6105 /* Help bidi.c avoid expensive searches for display
6106 properties and overlays, by telling it that there are
6107 none up to `limit'. */
6108 if (it->bidi_it.disp_pos < limit)
6109 {
6110 it->bidi_it.disp_pos = limit;
6111 it->bidi_it.disp_prop = 0;
6112 }
6113 do {
6114 bprev = it->bidi_it;
6115 bidi_move_to_visually_next (&it->bidi_it);
6116 } while (it->bidi_it.charpos != limit);
6117 IT_CHARPOS (*it) = limit;
6118 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6119 if (bidi_it_prev)
6120 *bidi_it_prev = bprev;
6121 }
6122 *skipped_p = newline_found_p = 1;
6123 }
6124 else
6125 {
6126 while (get_next_display_element (it)
6127 && !newline_found_p)
6128 {
6129 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6130 if (newline_found_p && it->bidi_p && bidi_it_prev)
6131 *bidi_it_prev = it->bidi_it;
6132 set_iterator_to_next (it, 0);
6133 }
6134 }
6135 }
6136
6137 it->selective = old_selective;
6138 return newline_found_p;
6139 }
6140
6141
6142 /* Set IT's current position to the previous visible line start. Skip
6143 invisible text that is so either due to text properties or due to
6144 selective display. Caution: this does not change IT->current_x and
6145 IT->hpos. */
6146
6147 static void
6148 back_to_previous_visible_line_start (struct it *it)
6149 {
6150 while (IT_CHARPOS (*it) > BEGV)
6151 {
6152 back_to_previous_line_start (it);
6153
6154 if (IT_CHARPOS (*it) <= BEGV)
6155 break;
6156
6157 /* If selective > 0, then lines indented more than its value are
6158 invisible. */
6159 if (it->selective > 0
6160 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6161 it->selective))
6162 continue;
6163
6164 /* Check the newline before point for invisibility. */
6165 {
6166 Lisp_Object prop;
6167 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6168 Qinvisible, it->window);
6169 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6170 continue;
6171 }
6172
6173 if (IT_CHARPOS (*it) <= BEGV)
6174 break;
6175
6176 {
6177 struct it it2;
6178 void *it2data = NULL;
6179 ptrdiff_t pos;
6180 ptrdiff_t beg, end;
6181 Lisp_Object val, overlay;
6182
6183 SAVE_IT (it2, *it, it2data);
6184
6185 /* If newline is part of a composition, continue from start of composition */
6186 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6187 && beg < IT_CHARPOS (*it))
6188 goto replaced;
6189
6190 /* If newline is replaced by a display property, find start of overlay
6191 or interval and continue search from that point. */
6192 pos = --IT_CHARPOS (it2);
6193 --IT_BYTEPOS (it2);
6194 it2.sp = 0;
6195 bidi_unshelve_cache (NULL, 0);
6196 it2.string_from_display_prop_p = 0;
6197 it2.from_disp_prop_p = 0;
6198 if (handle_display_prop (&it2) == HANDLED_RETURN
6199 && !NILP (val = get_char_property_and_overlay
6200 (make_number (pos), Qdisplay, Qnil, &overlay))
6201 && (OVERLAYP (overlay)
6202 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6203 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6204 {
6205 RESTORE_IT (it, it, it2data);
6206 goto replaced;
6207 }
6208
6209 /* Newline is not replaced by anything -- so we are done. */
6210 RESTORE_IT (it, it, it2data);
6211 break;
6212
6213 replaced:
6214 if (beg < BEGV)
6215 beg = BEGV;
6216 IT_CHARPOS (*it) = beg;
6217 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6218 }
6219 }
6220
6221 it->continuation_lines_width = 0;
6222
6223 eassert (IT_CHARPOS (*it) >= BEGV);
6224 eassert (IT_CHARPOS (*it) == BEGV
6225 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6226 CHECK_IT (it);
6227 }
6228
6229
6230 /* Reseat iterator IT at the previous visible line start. Skip
6231 invisible text that is so either due to text properties or due to
6232 selective display. At the end, update IT's overlay information,
6233 face information etc. */
6234
6235 void
6236 reseat_at_previous_visible_line_start (struct it *it)
6237 {
6238 back_to_previous_visible_line_start (it);
6239 reseat (it, it->current.pos, 1);
6240 CHECK_IT (it);
6241 }
6242
6243
6244 /* Reseat iterator IT on the next visible line start in the current
6245 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6246 preceding the line start. Skip over invisible text that is so
6247 because of selective display. Compute faces, overlays etc at the
6248 new position. Note that this function does not skip over text that
6249 is invisible because of text properties. */
6250
6251 static void
6252 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6253 {
6254 int newline_found_p, skipped_p = 0;
6255 struct bidi_it bidi_it_prev;
6256
6257 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6258
6259 /* Skip over lines that are invisible because they are indented
6260 more than the value of IT->selective. */
6261 if (it->selective > 0)
6262 while (IT_CHARPOS (*it) < ZV
6263 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6264 it->selective))
6265 {
6266 eassert (IT_BYTEPOS (*it) == BEGV
6267 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6268 newline_found_p =
6269 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6270 }
6271
6272 /* Position on the newline if that's what's requested. */
6273 if (on_newline_p && newline_found_p)
6274 {
6275 if (STRINGP (it->string))
6276 {
6277 if (IT_STRING_CHARPOS (*it) > 0)
6278 {
6279 if (!it->bidi_p)
6280 {
6281 --IT_STRING_CHARPOS (*it);
6282 --IT_STRING_BYTEPOS (*it);
6283 }
6284 else
6285 {
6286 /* We need to restore the bidi iterator to the state
6287 it had on the newline, and resync the IT's
6288 position with that. */
6289 it->bidi_it = bidi_it_prev;
6290 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6291 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6292 }
6293 }
6294 }
6295 else if (IT_CHARPOS (*it) > BEGV)
6296 {
6297 if (!it->bidi_p)
6298 {
6299 --IT_CHARPOS (*it);
6300 --IT_BYTEPOS (*it);
6301 }
6302 else
6303 {
6304 /* We need to restore the bidi iterator to the state it
6305 had on the newline and resync IT with that. */
6306 it->bidi_it = bidi_it_prev;
6307 IT_CHARPOS (*it) = it->bidi_it.charpos;
6308 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6309 }
6310 reseat (it, it->current.pos, 0);
6311 }
6312 }
6313 else if (skipped_p)
6314 reseat (it, it->current.pos, 0);
6315
6316 CHECK_IT (it);
6317 }
6318
6319
6320 \f
6321 /***********************************************************************
6322 Changing an iterator's position
6323 ***********************************************************************/
6324
6325 /* Change IT's current position to POS in current_buffer. If FORCE_P
6326 is non-zero, always check for text properties at the new position.
6327 Otherwise, text properties are only looked up if POS >=
6328 IT->check_charpos of a property. */
6329
6330 static void
6331 reseat (struct it *it, struct text_pos pos, int force_p)
6332 {
6333 ptrdiff_t original_pos = IT_CHARPOS (*it);
6334
6335 reseat_1 (it, pos, 0);
6336
6337 /* Determine where to check text properties. Avoid doing it
6338 where possible because text property lookup is very expensive. */
6339 if (force_p
6340 || CHARPOS (pos) > it->stop_charpos
6341 || CHARPOS (pos) < original_pos)
6342 {
6343 if (it->bidi_p)
6344 {
6345 /* For bidi iteration, we need to prime prev_stop and
6346 base_level_stop with our best estimations. */
6347 /* Implementation note: Of course, POS is not necessarily a
6348 stop position, so assigning prev_pos to it is a lie; we
6349 should have called compute_stop_backwards. However, if
6350 the current buffer does not include any R2L characters,
6351 that call would be a waste of cycles, because the
6352 iterator will never move back, and thus never cross this
6353 "fake" stop position. So we delay that backward search
6354 until the time we really need it, in next_element_from_buffer. */
6355 if (CHARPOS (pos) != it->prev_stop)
6356 it->prev_stop = CHARPOS (pos);
6357 if (CHARPOS (pos) < it->base_level_stop)
6358 it->base_level_stop = 0; /* meaning it's unknown */
6359 handle_stop (it);
6360 }
6361 else
6362 {
6363 handle_stop (it);
6364 it->prev_stop = it->base_level_stop = 0;
6365 }
6366
6367 }
6368
6369 CHECK_IT (it);
6370 }
6371
6372
6373 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6374 IT->stop_pos to POS, also. */
6375
6376 static void
6377 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6378 {
6379 /* Don't call this function when scanning a C string. */
6380 eassert (it->s == NULL);
6381
6382 /* POS must be a reasonable value. */
6383 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6384
6385 it->current.pos = it->position = pos;
6386 it->end_charpos = ZV;
6387 it->dpvec = NULL;
6388 it->current.dpvec_index = -1;
6389 it->current.overlay_string_index = -1;
6390 IT_STRING_CHARPOS (*it) = -1;
6391 IT_STRING_BYTEPOS (*it) = -1;
6392 it->string = Qnil;
6393 it->method = GET_FROM_BUFFER;
6394 it->object = it->w->contents;
6395 it->area = TEXT_AREA;
6396 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6397 it->sp = 0;
6398 it->string_from_display_prop_p = 0;
6399 it->string_from_prefix_prop_p = 0;
6400
6401 it->from_disp_prop_p = 0;
6402 it->face_before_selective_p = 0;
6403 if (it->bidi_p)
6404 {
6405 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6406 &it->bidi_it);
6407 bidi_unshelve_cache (NULL, 0);
6408 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6409 it->bidi_it.string.s = NULL;
6410 it->bidi_it.string.lstring = Qnil;
6411 it->bidi_it.string.bufpos = 0;
6412 it->bidi_it.string.unibyte = 0;
6413 it->bidi_it.w = it->w;
6414 }
6415
6416 if (set_stop_p)
6417 {
6418 it->stop_charpos = CHARPOS (pos);
6419 it->base_level_stop = CHARPOS (pos);
6420 }
6421 /* This make the information stored in it->cmp_it invalidate. */
6422 it->cmp_it.id = -1;
6423 }
6424
6425
6426 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6427 If S is non-null, it is a C string to iterate over. Otherwise,
6428 STRING gives a Lisp string to iterate over.
6429
6430 If PRECISION > 0, don't return more then PRECISION number of
6431 characters from the string.
6432
6433 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6434 characters have been returned. FIELD_WIDTH < 0 means an infinite
6435 field width.
6436
6437 MULTIBYTE = 0 means disable processing of multibyte characters,
6438 MULTIBYTE > 0 means enable it,
6439 MULTIBYTE < 0 means use IT->multibyte_p.
6440
6441 IT must be initialized via a prior call to init_iterator before
6442 calling this function. */
6443
6444 static void
6445 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6446 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6447 int multibyte)
6448 {
6449 /* No region in strings. */
6450 it->region_beg_charpos = it->region_end_charpos = -1;
6451
6452 /* No text property checks performed by default, but see below. */
6453 it->stop_charpos = -1;
6454
6455 /* Set iterator position and end position. */
6456 memset (&it->current, 0, sizeof it->current);
6457 it->current.overlay_string_index = -1;
6458 it->current.dpvec_index = -1;
6459 eassert (charpos >= 0);
6460
6461 /* If STRING is specified, use its multibyteness, otherwise use the
6462 setting of MULTIBYTE, if specified. */
6463 if (multibyte >= 0)
6464 it->multibyte_p = multibyte > 0;
6465
6466 /* Bidirectional reordering of strings is controlled by the default
6467 value of bidi-display-reordering. Don't try to reorder while
6468 loading loadup.el, as the necessary character property tables are
6469 not yet available. */
6470 it->bidi_p =
6471 NILP (Vpurify_flag)
6472 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6473
6474 if (s == NULL)
6475 {
6476 eassert (STRINGP (string));
6477 it->string = string;
6478 it->s = NULL;
6479 it->end_charpos = it->string_nchars = SCHARS (string);
6480 it->method = GET_FROM_STRING;
6481 it->current.string_pos = string_pos (charpos, string);
6482
6483 if (it->bidi_p)
6484 {
6485 it->bidi_it.string.lstring = string;
6486 it->bidi_it.string.s = NULL;
6487 it->bidi_it.string.schars = it->end_charpos;
6488 it->bidi_it.string.bufpos = 0;
6489 it->bidi_it.string.from_disp_str = 0;
6490 it->bidi_it.string.unibyte = !it->multibyte_p;
6491 it->bidi_it.w = it->w;
6492 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6493 FRAME_WINDOW_P (it->f), &it->bidi_it);
6494 }
6495 }
6496 else
6497 {
6498 it->s = (const unsigned char *) s;
6499 it->string = Qnil;
6500
6501 /* Note that we use IT->current.pos, not it->current.string_pos,
6502 for displaying C strings. */
6503 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6504 if (it->multibyte_p)
6505 {
6506 it->current.pos = c_string_pos (charpos, s, 1);
6507 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6508 }
6509 else
6510 {
6511 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6512 it->end_charpos = it->string_nchars = strlen (s);
6513 }
6514
6515 if (it->bidi_p)
6516 {
6517 it->bidi_it.string.lstring = Qnil;
6518 it->bidi_it.string.s = (const unsigned char *) s;
6519 it->bidi_it.string.schars = it->end_charpos;
6520 it->bidi_it.string.bufpos = 0;
6521 it->bidi_it.string.from_disp_str = 0;
6522 it->bidi_it.string.unibyte = !it->multibyte_p;
6523 it->bidi_it.w = it->w;
6524 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6525 &it->bidi_it);
6526 }
6527 it->method = GET_FROM_C_STRING;
6528 }
6529
6530 /* PRECISION > 0 means don't return more than PRECISION characters
6531 from the string. */
6532 if (precision > 0 && it->end_charpos - charpos > precision)
6533 {
6534 it->end_charpos = it->string_nchars = charpos + precision;
6535 if (it->bidi_p)
6536 it->bidi_it.string.schars = it->end_charpos;
6537 }
6538
6539 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6540 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6541 FIELD_WIDTH < 0 means infinite field width. This is useful for
6542 padding with `-' at the end of a mode line. */
6543 if (field_width < 0)
6544 field_width = INFINITY;
6545 /* Implementation note: We deliberately don't enlarge
6546 it->bidi_it.string.schars here to fit it->end_charpos, because
6547 the bidi iterator cannot produce characters out of thin air. */
6548 if (field_width > it->end_charpos - charpos)
6549 it->end_charpos = charpos + field_width;
6550
6551 /* Use the standard display table for displaying strings. */
6552 if (DISP_TABLE_P (Vstandard_display_table))
6553 it->dp = XCHAR_TABLE (Vstandard_display_table);
6554
6555 it->stop_charpos = charpos;
6556 it->prev_stop = charpos;
6557 it->base_level_stop = 0;
6558 if (it->bidi_p)
6559 {
6560 it->bidi_it.first_elt = 1;
6561 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6562 it->bidi_it.disp_pos = -1;
6563 }
6564 if (s == NULL && it->multibyte_p)
6565 {
6566 ptrdiff_t endpos = SCHARS (it->string);
6567 if (endpos > it->end_charpos)
6568 endpos = it->end_charpos;
6569 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6570 it->string);
6571 }
6572 CHECK_IT (it);
6573 }
6574
6575
6576 \f
6577 /***********************************************************************
6578 Iteration
6579 ***********************************************************************/
6580
6581 /* Map enum it_method value to corresponding next_element_from_* function. */
6582
6583 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6584 {
6585 next_element_from_buffer,
6586 next_element_from_display_vector,
6587 next_element_from_string,
6588 next_element_from_c_string,
6589 next_element_from_image,
6590 next_element_from_stretch
6591 };
6592
6593 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6594
6595
6596 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6597 (possibly with the following characters). */
6598
6599 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6600 ((IT)->cmp_it.id >= 0 \
6601 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6602 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6603 END_CHARPOS, (IT)->w, \
6604 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6605 (IT)->string)))
6606
6607
6608 /* Lookup the char-table Vglyphless_char_display for character C (-1
6609 if we want information for no-font case), and return the display
6610 method symbol. By side-effect, update it->what and
6611 it->glyphless_method. This function is called from
6612 get_next_display_element for each character element, and from
6613 x_produce_glyphs when no suitable font was found. */
6614
6615 Lisp_Object
6616 lookup_glyphless_char_display (int c, struct it *it)
6617 {
6618 Lisp_Object glyphless_method = Qnil;
6619
6620 if (CHAR_TABLE_P (Vglyphless_char_display)
6621 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6622 {
6623 if (c >= 0)
6624 {
6625 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6626 if (CONSP (glyphless_method))
6627 glyphless_method = FRAME_WINDOW_P (it->f)
6628 ? XCAR (glyphless_method)
6629 : XCDR (glyphless_method);
6630 }
6631 else
6632 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6633 }
6634
6635 retry:
6636 if (NILP (glyphless_method))
6637 {
6638 if (c >= 0)
6639 /* The default is to display the character by a proper font. */
6640 return Qnil;
6641 /* The default for the no-font case is to display an empty box. */
6642 glyphless_method = Qempty_box;
6643 }
6644 if (EQ (glyphless_method, Qzero_width))
6645 {
6646 if (c >= 0)
6647 return glyphless_method;
6648 /* This method can't be used for the no-font case. */
6649 glyphless_method = Qempty_box;
6650 }
6651 if (EQ (glyphless_method, Qthin_space))
6652 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6653 else if (EQ (glyphless_method, Qempty_box))
6654 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6655 else if (EQ (glyphless_method, Qhex_code))
6656 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6657 else if (STRINGP (glyphless_method))
6658 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6659 else
6660 {
6661 /* Invalid value. We use the default method. */
6662 glyphless_method = Qnil;
6663 goto retry;
6664 }
6665 it->what = IT_GLYPHLESS;
6666 return glyphless_method;
6667 }
6668
6669 /* Load IT's display element fields with information about the next
6670 display element from the current position of IT. Value is zero if
6671 end of buffer (or C string) is reached. */
6672
6673 static struct frame *last_escape_glyph_frame = NULL;
6674 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6675 static int last_escape_glyph_merged_face_id = 0;
6676
6677 struct frame *last_glyphless_glyph_frame = NULL;
6678 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6679 int last_glyphless_glyph_merged_face_id = 0;
6680
6681 static int
6682 get_next_display_element (struct it *it)
6683 {
6684 /* Non-zero means that we found a display element. Zero means that
6685 we hit the end of what we iterate over. Performance note: the
6686 function pointer `method' used here turns out to be faster than
6687 using a sequence of if-statements. */
6688 int success_p;
6689
6690 get_next:
6691 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6692
6693 if (it->what == IT_CHARACTER)
6694 {
6695 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6696 and only if (a) the resolved directionality of that character
6697 is R..." */
6698 /* FIXME: Do we need an exception for characters from display
6699 tables? */
6700 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6701 it->c = bidi_mirror_char (it->c);
6702 /* Map via display table or translate control characters.
6703 IT->c, IT->len etc. have been set to the next character by
6704 the function call above. If we have a display table, and it
6705 contains an entry for IT->c, translate it. Don't do this if
6706 IT->c itself comes from a display table, otherwise we could
6707 end up in an infinite recursion. (An alternative could be to
6708 count the recursion depth of this function and signal an
6709 error when a certain maximum depth is reached.) Is it worth
6710 it? */
6711 if (success_p && it->dpvec == NULL)
6712 {
6713 Lisp_Object dv;
6714 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6715 int nonascii_space_p = 0;
6716 int nonascii_hyphen_p = 0;
6717 int c = it->c; /* This is the character to display. */
6718
6719 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6720 {
6721 eassert (SINGLE_BYTE_CHAR_P (c));
6722 if (unibyte_display_via_language_environment)
6723 {
6724 c = DECODE_CHAR (unibyte, c);
6725 if (c < 0)
6726 c = BYTE8_TO_CHAR (it->c);
6727 }
6728 else
6729 c = BYTE8_TO_CHAR (it->c);
6730 }
6731
6732 if (it->dp
6733 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6734 VECTORP (dv)))
6735 {
6736 struct Lisp_Vector *v = XVECTOR (dv);
6737
6738 /* Return the first character from the display table
6739 entry, if not empty. If empty, don't display the
6740 current character. */
6741 if (v->header.size)
6742 {
6743 it->dpvec_char_len = it->len;
6744 it->dpvec = v->contents;
6745 it->dpend = v->contents + v->header.size;
6746 it->current.dpvec_index = 0;
6747 it->dpvec_face_id = -1;
6748 it->saved_face_id = it->face_id;
6749 it->method = GET_FROM_DISPLAY_VECTOR;
6750 it->ellipsis_p = 0;
6751 }
6752 else
6753 {
6754 set_iterator_to_next (it, 0);
6755 }
6756 goto get_next;
6757 }
6758
6759 if (! NILP (lookup_glyphless_char_display (c, it)))
6760 {
6761 if (it->what == IT_GLYPHLESS)
6762 goto done;
6763 /* Don't display this character. */
6764 set_iterator_to_next (it, 0);
6765 goto get_next;
6766 }
6767
6768 /* If `nobreak-char-display' is non-nil, we display
6769 non-ASCII spaces and hyphens specially. */
6770 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6771 {
6772 if (c == 0xA0)
6773 nonascii_space_p = 1;
6774 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6775 nonascii_hyphen_p = 1;
6776 }
6777
6778 /* Translate control characters into `\003' or `^C' form.
6779 Control characters coming from a display table entry are
6780 currently not translated because we use IT->dpvec to hold
6781 the translation. This could easily be changed but I
6782 don't believe that it is worth doing.
6783
6784 The characters handled by `nobreak-char-display' must be
6785 translated too.
6786
6787 Non-printable characters and raw-byte characters are also
6788 translated to octal form. */
6789 if (((c < ' ' || c == 127) /* ASCII control chars */
6790 ? (it->area != TEXT_AREA
6791 /* In mode line, treat \n, \t like other crl chars. */
6792 || (c != '\t'
6793 && it->glyph_row
6794 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6795 || (c != '\n' && c != '\t'))
6796 : (nonascii_space_p
6797 || nonascii_hyphen_p
6798 || CHAR_BYTE8_P (c)
6799 || ! CHAR_PRINTABLE_P (c))))
6800 {
6801 /* C is a control character, non-ASCII space/hyphen,
6802 raw-byte, or a non-printable character which must be
6803 displayed either as '\003' or as `^C' where the '\\'
6804 and '^' can be defined in the display table. Fill
6805 IT->ctl_chars with glyphs for what we have to
6806 display. Then, set IT->dpvec to these glyphs. */
6807 Lisp_Object gc;
6808 int ctl_len;
6809 int face_id;
6810 int lface_id = 0;
6811 int escape_glyph;
6812
6813 /* Handle control characters with ^. */
6814
6815 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6816 {
6817 int g;
6818
6819 g = '^'; /* default glyph for Control */
6820 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6821 if (it->dp
6822 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6823 {
6824 g = GLYPH_CODE_CHAR (gc);
6825 lface_id = GLYPH_CODE_FACE (gc);
6826 }
6827 if (lface_id)
6828 {
6829 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6830 }
6831 else if (it->f == last_escape_glyph_frame
6832 && it->face_id == last_escape_glyph_face_id)
6833 {
6834 face_id = last_escape_glyph_merged_face_id;
6835 }
6836 else
6837 {
6838 /* Merge the escape-glyph face into the current face. */
6839 face_id = merge_faces (it->f, Qescape_glyph, 0,
6840 it->face_id);
6841 last_escape_glyph_frame = it->f;
6842 last_escape_glyph_face_id = it->face_id;
6843 last_escape_glyph_merged_face_id = face_id;
6844 }
6845
6846 XSETINT (it->ctl_chars[0], g);
6847 XSETINT (it->ctl_chars[1], c ^ 0100);
6848 ctl_len = 2;
6849 goto display_control;
6850 }
6851
6852 /* Handle non-ascii space in the mode where it only gets
6853 highlighting. */
6854
6855 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6856 {
6857 /* Merge `nobreak-space' into the current face. */
6858 face_id = merge_faces (it->f, Qnobreak_space, 0,
6859 it->face_id);
6860 XSETINT (it->ctl_chars[0], ' ');
6861 ctl_len = 1;
6862 goto display_control;
6863 }
6864
6865 /* Handle sequences that start with the "escape glyph". */
6866
6867 /* the default escape glyph is \. */
6868 escape_glyph = '\\';
6869
6870 if (it->dp
6871 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6872 {
6873 escape_glyph = GLYPH_CODE_CHAR (gc);
6874 lface_id = GLYPH_CODE_FACE (gc);
6875 }
6876 if (lface_id)
6877 {
6878 /* The display table specified a face.
6879 Merge it into face_id and also into escape_glyph. */
6880 face_id = merge_faces (it->f, Qt, lface_id,
6881 it->face_id);
6882 }
6883 else if (it->f == last_escape_glyph_frame
6884 && it->face_id == last_escape_glyph_face_id)
6885 {
6886 face_id = last_escape_glyph_merged_face_id;
6887 }
6888 else
6889 {
6890 /* Merge the escape-glyph face into the current face. */
6891 face_id = merge_faces (it->f, Qescape_glyph, 0,
6892 it->face_id);
6893 last_escape_glyph_frame = it->f;
6894 last_escape_glyph_face_id = it->face_id;
6895 last_escape_glyph_merged_face_id = face_id;
6896 }
6897
6898 /* Draw non-ASCII hyphen with just highlighting: */
6899
6900 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6901 {
6902 XSETINT (it->ctl_chars[0], '-');
6903 ctl_len = 1;
6904 goto display_control;
6905 }
6906
6907 /* Draw non-ASCII space/hyphen with escape glyph: */
6908
6909 if (nonascii_space_p || nonascii_hyphen_p)
6910 {
6911 XSETINT (it->ctl_chars[0], escape_glyph);
6912 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6913 ctl_len = 2;
6914 goto display_control;
6915 }
6916
6917 {
6918 char str[10];
6919 int len, i;
6920
6921 if (CHAR_BYTE8_P (c))
6922 /* Display \200 instead of \17777600. */
6923 c = CHAR_TO_BYTE8 (c);
6924 len = sprintf (str, "%03o", c);
6925
6926 XSETINT (it->ctl_chars[0], escape_glyph);
6927 for (i = 0; i < len; i++)
6928 XSETINT (it->ctl_chars[i + 1], str[i]);
6929 ctl_len = len + 1;
6930 }
6931
6932 display_control:
6933 /* Set up IT->dpvec and return first character from it. */
6934 it->dpvec_char_len = it->len;
6935 it->dpvec = it->ctl_chars;
6936 it->dpend = it->dpvec + ctl_len;
6937 it->current.dpvec_index = 0;
6938 it->dpvec_face_id = face_id;
6939 it->saved_face_id = it->face_id;
6940 it->method = GET_FROM_DISPLAY_VECTOR;
6941 it->ellipsis_p = 0;
6942 goto get_next;
6943 }
6944 it->char_to_display = c;
6945 }
6946 else if (success_p)
6947 {
6948 it->char_to_display = it->c;
6949 }
6950 }
6951
6952 /* Adjust face id for a multibyte character. There are no multibyte
6953 character in unibyte text. */
6954 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6955 && it->multibyte_p
6956 && success_p
6957 && FRAME_WINDOW_P (it->f))
6958 {
6959 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6960
6961 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6962 {
6963 /* Automatic composition with glyph-string. */
6964 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6965
6966 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6967 }
6968 else
6969 {
6970 ptrdiff_t pos = (it->s ? -1
6971 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6972 : IT_CHARPOS (*it));
6973 int c;
6974
6975 if (it->what == IT_CHARACTER)
6976 c = it->char_to_display;
6977 else
6978 {
6979 struct composition *cmp = composition_table[it->cmp_it.id];
6980 int i;
6981
6982 c = ' ';
6983 for (i = 0; i < cmp->glyph_len; i++)
6984 /* TAB in a composition means display glyphs with
6985 padding space on the left or right. */
6986 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6987 break;
6988 }
6989 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6990 }
6991 }
6992
6993 done:
6994 /* Is this character the last one of a run of characters with
6995 box? If yes, set IT->end_of_box_run_p to 1. */
6996 if (it->face_box_p
6997 && it->s == NULL)
6998 {
6999 if (it->method == GET_FROM_STRING && it->sp)
7000 {
7001 int face_id = underlying_face_id (it);
7002 struct face *face = FACE_FROM_ID (it->f, face_id);
7003
7004 if (face)
7005 {
7006 if (face->box == FACE_NO_BOX)
7007 {
7008 /* If the box comes from face properties in a
7009 display string, check faces in that string. */
7010 int string_face_id = face_after_it_pos (it);
7011 it->end_of_box_run_p
7012 = (FACE_FROM_ID (it->f, string_face_id)->box
7013 == FACE_NO_BOX);
7014 }
7015 /* Otherwise, the box comes from the underlying face.
7016 If this is the last string character displayed, check
7017 the next buffer location. */
7018 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7019 && (it->current.overlay_string_index
7020 == it->n_overlay_strings - 1))
7021 {
7022 ptrdiff_t ignore;
7023 int next_face_id;
7024 struct text_pos pos = it->current.pos;
7025 INC_TEXT_POS (pos, it->multibyte_p);
7026
7027 next_face_id = face_at_buffer_position
7028 (it->w, CHARPOS (pos), it->region_beg_charpos,
7029 it->region_end_charpos, &ignore,
7030 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
7031 -1);
7032 it->end_of_box_run_p
7033 = (FACE_FROM_ID (it->f, next_face_id)->box
7034 == FACE_NO_BOX);
7035 }
7036 }
7037 }
7038 /* next_element_from_display_vector sets this flag according to
7039 faces of the display vector glyphs, see there. */
7040 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7041 {
7042 int face_id = face_after_it_pos (it);
7043 it->end_of_box_run_p
7044 = (face_id != it->face_id
7045 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7046 }
7047 }
7048 /* If we reached the end of the object we've been iterating (e.g., a
7049 display string or an overlay string), and there's something on
7050 IT->stack, proceed with what's on the stack. It doesn't make
7051 sense to return zero if there's unprocessed stuff on the stack,
7052 because otherwise that stuff will never be displayed. */
7053 if (!success_p && it->sp > 0)
7054 {
7055 set_iterator_to_next (it, 0);
7056 success_p = get_next_display_element (it);
7057 }
7058
7059 /* Value is 0 if end of buffer or string reached. */
7060 return success_p;
7061 }
7062
7063
7064 /* Move IT to the next display element.
7065
7066 RESEAT_P non-zero means if called on a newline in buffer text,
7067 skip to the next visible line start.
7068
7069 Functions get_next_display_element and set_iterator_to_next are
7070 separate because I find this arrangement easier to handle than a
7071 get_next_display_element function that also increments IT's
7072 position. The way it is we can first look at an iterator's current
7073 display element, decide whether it fits on a line, and if it does,
7074 increment the iterator position. The other way around we probably
7075 would either need a flag indicating whether the iterator has to be
7076 incremented the next time, or we would have to implement a
7077 decrement position function which would not be easy to write. */
7078
7079 void
7080 set_iterator_to_next (struct it *it, int reseat_p)
7081 {
7082 /* Reset flags indicating start and end of a sequence of characters
7083 with box. Reset them at the start of this function because
7084 moving the iterator to a new position might set them. */
7085 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7086
7087 switch (it->method)
7088 {
7089 case GET_FROM_BUFFER:
7090 /* The current display element of IT is a character from
7091 current_buffer. Advance in the buffer, and maybe skip over
7092 invisible lines that are so because of selective display. */
7093 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7094 reseat_at_next_visible_line_start (it, 0);
7095 else if (it->cmp_it.id >= 0)
7096 {
7097 /* We are currently getting glyphs from a composition. */
7098 int i;
7099
7100 if (! it->bidi_p)
7101 {
7102 IT_CHARPOS (*it) += it->cmp_it.nchars;
7103 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7104 if (it->cmp_it.to < it->cmp_it.nglyphs)
7105 {
7106 it->cmp_it.from = it->cmp_it.to;
7107 }
7108 else
7109 {
7110 it->cmp_it.id = -1;
7111 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7112 IT_BYTEPOS (*it),
7113 it->end_charpos, Qnil);
7114 }
7115 }
7116 else if (! it->cmp_it.reversed_p)
7117 {
7118 /* Composition created while scanning forward. */
7119 /* Update IT's char/byte positions to point to the first
7120 character of the next grapheme cluster, or to the
7121 character visually after the current composition. */
7122 for (i = 0; i < it->cmp_it.nchars; i++)
7123 bidi_move_to_visually_next (&it->bidi_it);
7124 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7125 IT_CHARPOS (*it) = it->bidi_it.charpos;
7126
7127 if (it->cmp_it.to < it->cmp_it.nglyphs)
7128 {
7129 /* Proceed to the next grapheme cluster. */
7130 it->cmp_it.from = it->cmp_it.to;
7131 }
7132 else
7133 {
7134 /* No more grapheme clusters in this composition.
7135 Find the next stop position. */
7136 ptrdiff_t stop = it->end_charpos;
7137 if (it->bidi_it.scan_dir < 0)
7138 /* Now we are scanning backward and don't know
7139 where to stop. */
7140 stop = -1;
7141 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7142 IT_BYTEPOS (*it), stop, Qnil);
7143 }
7144 }
7145 else
7146 {
7147 /* Composition created while scanning backward. */
7148 /* Update IT's char/byte positions to point to the last
7149 character of the previous grapheme cluster, or the
7150 character visually after the current composition. */
7151 for (i = 0; i < it->cmp_it.nchars; i++)
7152 bidi_move_to_visually_next (&it->bidi_it);
7153 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7154 IT_CHARPOS (*it) = it->bidi_it.charpos;
7155 if (it->cmp_it.from > 0)
7156 {
7157 /* Proceed to the previous grapheme cluster. */
7158 it->cmp_it.to = it->cmp_it.from;
7159 }
7160 else
7161 {
7162 /* No more grapheme clusters in this composition.
7163 Find the next stop position. */
7164 ptrdiff_t stop = it->end_charpos;
7165 if (it->bidi_it.scan_dir < 0)
7166 /* Now we are scanning backward and don't know
7167 where to stop. */
7168 stop = -1;
7169 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7170 IT_BYTEPOS (*it), stop, Qnil);
7171 }
7172 }
7173 }
7174 else
7175 {
7176 eassert (it->len != 0);
7177
7178 if (!it->bidi_p)
7179 {
7180 IT_BYTEPOS (*it) += it->len;
7181 IT_CHARPOS (*it) += 1;
7182 }
7183 else
7184 {
7185 int prev_scan_dir = it->bidi_it.scan_dir;
7186 /* If this is a new paragraph, determine its base
7187 direction (a.k.a. its base embedding level). */
7188 if (it->bidi_it.new_paragraph)
7189 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7190 bidi_move_to_visually_next (&it->bidi_it);
7191 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7192 IT_CHARPOS (*it) = it->bidi_it.charpos;
7193 if (prev_scan_dir != it->bidi_it.scan_dir)
7194 {
7195 /* As the scan direction was changed, we must
7196 re-compute the stop position for composition. */
7197 ptrdiff_t stop = it->end_charpos;
7198 if (it->bidi_it.scan_dir < 0)
7199 stop = -1;
7200 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7201 IT_BYTEPOS (*it), stop, Qnil);
7202 }
7203 }
7204 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7205 }
7206 break;
7207
7208 case GET_FROM_C_STRING:
7209 /* Current display element of IT is from a C string. */
7210 if (!it->bidi_p
7211 /* If the string position is beyond string's end, it means
7212 next_element_from_c_string is padding the string with
7213 blanks, in which case we bypass the bidi iterator,
7214 because it cannot deal with such virtual characters. */
7215 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7216 {
7217 IT_BYTEPOS (*it) += it->len;
7218 IT_CHARPOS (*it) += 1;
7219 }
7220 else
7221 {
7222 bidi_move_to_visually_next (&it->bidi_it);
7223 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7224 IT_CHARPOS (*it) = it->bidi_it.charpos;
7225 }
7226 break;
7227
7228 case GET_FROM_DISPLAY_VECTOR:
7229 /* Current display element of IT is from a display table entry.
7230 Advance in the display table definition. Reset it to null if
7231 end reached, and continue with characters from buffers/
7232 strings. */
7233 ++it->current.dpvec_index;
7234
7235 /* Restore face of the iterator to what they were before the
7236 display vector entry (these entries may contain faces). */
7237 it->face_id = it->saved_face_id;
7238
7239 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7240 {
7241 int recheck_faces = it->ellipsis_p;
7242
7243 if (it->s)
7244 it->method = GET_FROM_C_STRING;
7245 else if (STRINGP (it->string))
7246 it->method = GET_FROM_STRING;
7247 else
7248 {
7249 it->method = GET_FROM_BUFFER;
7250 it->object = it->w->contents;
7251 }
7252
7253 it->dpvec = NULL;
7254 it->current.dpvec_index = -1;
7255
7256 /* Skip over characters which were displayed via IT->dpvec. */
7257 if (it->dpvec_char_len < 0)
7258 reseat_at_next_visible_line_start (it, 1);
7259 else if (it->dpvec_char_len > 0)
7260 {
7261 if (it->method == GET_FROM_STRING
7262 && it->current.overlay_string_index >= 0
7263 && it->n_overlay_strings > 0)
7264 it->ignore_overlay_strings_at_pos_p = 1;
7265 it->len = it->dpvec_char_len;
7266 set_iterator_to_next (it, reseat_p);
7267 }
7268
7269 /* Maybe recheck faces after display vector */
7270 if (recheck_faces)
7271 it->stop_charpos = IT_CHARPOS (*it);
7272 }
7273 break;
7274
7275 case GET_FROM_STRING:
7276 /* Current display element is a character from a Lisp string. */
7277 eassert (it->s == NULL && STRINGP (it->string));
7278 /* Don't advance past string end. These conditions are true
7279 when set_iterator_to_next is called at the end of
7280 get_next_display_element, in which case the Lisp string is
7281 already exhausted, and all we want is pop the iterator
7282 stack. */
7283 if (it->current.overlay_string_index >= 0)
7284 {
7285 /* This is an overlay string, so there's no padding with
7286 spaces, and the number of characters in the string is
7287 where the string ends. */
7288 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7289 goto consider_string_end;
7290 }
7291 else
7292 {
7293 /* Not an overlay string. There could be padding, so test
7294 against it->end_charpos . */
7295 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7296 goto consider_string_end;
7297 }
7298 if (it->cmp_it.id >= 0)
7299 {
7300 int i;
7301
7302 if (! it->bidi_p)
7303 {
7304 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7305 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7306 if (it->cmp_it.to < it->cmp_it.nglyphs)
7307 it->cmp_it.from = it->cmp_it.to;
7308 else
7309 {
7310 it->cmp_it.id = -1;
7311 composition_compute_stop_pos (&it->cmp_it,
7312 IT_STRING_CHARPOS (*it),
7313 IT_STRING_BYTEPOS (*it),
7314 it->end_charpos, it->string);
7315 }
7316 }
7317 else if (! it->cmp_it.reversed_p)
7318 {
7319 for (i = 0; i < it->cmp_it.nchars; i++)
7320 bidi_move_to_visually_next (&it->bidi_it);
7321 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7322 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7323
7324 if (it->cmp_it.to < it->cmp_it.nglyphs)
7325 it->cmp_it.from = it->cmp_it.to;
7326 else
7327 {
7328 ptrdiff_t stop = it->end_charpos;
7329 if (it->bidi_it.scan_dir < 0)
7330 stop = -1;
7331 composition_compute_stop_pos (&it->cmp_it,
7332 IT_STRING_CHARPOS (*it),
7333 IT_STRING_BYTEPOS (*it), stop,
7334 it->string);
7335 }
7336 }
7337 else
7338 {
7339 for (i = 0; i < it->cmp_it.nchars; i++)
7340 bidi_move_to_visually_next (&it->bidi_it);
7341 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7342 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7343 if (it->cmp_it.from > 0)
7344 it->cmp_it.to = it->cmp_it.from;
7345 else
7346 {
7347 ptrdiff_t stop = it->end_charpos;
7348 if (it->bidi_it.scan_dir < 0)
7349 stop = -1;
7350 composition_compute_stop_pos (&it->cmp_it,
7351 IT_STRING_CHARPOS (*it),
7352 IT_STRING_BYTEPOS (*it), stop,
7353 it->string);
7354 }
7355 }
7356 }
7357 else
7358 {
7359 if (!it->bidi_p
7360 /* If the string position is beyond string's end, it
7361 means next_element_from_string is padding the string
7362 with blanks, in which case we bypass the bidi
7363 iterator, because it cannot deal with such virtual
7364 characters. */
7365 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7366 {
7367 IT_STRING_BYTEPOS (*it) += it->len;
7368 IT_STRING_CHARPOS (*it) += 1;
7369 }
7370 else
7371 {
7372 int prev_scan_dir = it->bidi_it.scan_dir;
7373
7374 bidi_move_to_visually_next (&it->bidi_it);
7375 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7376 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7377 if (prev_scan_dir != it->bidi_it.scan_dir)
7378 {
7379 ptrdiff_t stop = it->end_charpos;
7380
7381 if (it->bidi_it.scan_dir < 0)
7382 stop = -1;
7383 composition_compute_stop_pos (&it->cmp_it,
7384 IT_STRING_CHARPOS (*it),
7385 IT_STRING_BYTEPOS (*it), stop,
7386 it->string);
7387 }
7388 }
7389 }
7390
7391 consider_string_end:
7392
7393 if (it->current.overlay_string_index >= 0)
7394 {
7395 /* IT->string is an overlay string. Advance to the
7396 next, if there is one. */
7397 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7398 {
7399 it->ellipsis_p = 0;
7400 next_overlay_string (it);
7401 if (it->ellipsis_p)
7402 setup_for_ellipsis (it, 0);
7403 }
7404 }
7405 else
7406 {
7407 /* IT->string is not an overlay string. If we reached
7408 its end, and there is something on IT->stack, proceed
7409 with what is on the stack. This can be either another
7410 string, this time an overlay string, or a buffer. */
7411 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7412 && it->sp > 0)
7413 {
7414 pop_it (it);
7415 if (it->method == GET_FROM_STRING)
7416 goto consider_string_end;
7417 }
7418 }
7419 break;
7420
7421 case GET_FROM_IMAGE:
7422 case GET_FROM_STRETCH:
7423 /* The position etc with which we have to proceed are on
7424 the stack. The position may be at the end of a string,
7425 if the `display' property takes up the whole string. */
7426 eassert (it->sp > 0);
7427 pop_it (it);
7428 if (it->method == GET_FROM_STRING)
7429 goto consider_string_end;
7430 break;
7431
7432 default:
7433 /* There are no other methods defined, so this should be a bug. */
7434 emacs_abort ();
7435 }
7436
7437 eassert (it->method != GET_FROM_STRING
7438 || (STRINGP (it->string)
7439 && IT_STRING_CHARPOS (*it) >= 0));
7440 }
7441
7442 /* Load IT's display element fields with information about the next
7443 display element which comes from a display table entry or from the
7444 result of translating a control character to one of the forms `^C'
7445 or `\003'.
7446
7447 IT->dpvec holds the glyphs to return as characters.
7448 IT->saved_face_id holds the face id before the display vector--it
7449 is restored into IT->face_id in set_iterator_to_next. */
7450
7451 static int
7452 next_element_from_display_vector (struct it *it)
7453 {
7454 Lisp_Object gc;
7455 int prev_face_id = it->face_id;
7456 int next_face_id;
7457
7458 /* Precondition. */
7459 eassert (it->dpvec && it->current.dpvec_index >= 0);
7460
7461 it->face_id = it->saved_face_id;
7462
7463 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7464 That seemed totally bogus - so I changed it... */
7465 gc = it->dpvec[it->current.dpvec_index];
7466
7467 if (GLYPH_CODE_P (gc))
7468 {
7469 struct face *this_face, *prev_face, *next_face;
7470
7471 it->c = GLYPH_CODE_CHAR (gc);
7472 it->len = CHAR_BYTES (it->c);
7473
7474 /* The entry may contain a face id to use. Such a face id is
7475 the id of a Lisp face, not a realized face. A face id of
7476 zero means no face is specified. */
7477 if (it->dpvec_face_id >= 0)
7478 it->face_id = it->dpvec_face_id;
7479 else
7480 {
7481 int lface_id = GLYPH_CODE_FACE (gc);
7482 if (lface_id > 0)
7483 it->face_id = merge_faces (it->f, Qt, lface_id,
7484 it->saved_face_id);
7485 }
7486
7487 /* Glyphs in the display vector could have the box face, so we
7488 need to set the related flags in the iterator, as
7489 appropriate. */
7490 this_face = FACE_FROM_ID (it->f, it->face_id);
7491 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7492
7493 /* Is this character the first character of a box-face run? */
7494 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7495 && (!prev_face
7496 || prev_face->box == FACE_NO_BOX));
7497
7498 /* For the last character of the box-face run, we need to look
7499 either at the next glyph from the display vector, or at the
7500 face we saw before the display vector. */
7501 next_face_id = it->saved_face_id;
7502 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7503 {
7504 if (it->dpvec_face_id >= 0)
7505 next_face_id = it->dpvec_face_id;
7506 else
7507 {
7508 int lface_id =
7509 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7510
7511 if (lface_id > 0)
7512 next_face_id = merge_faces (it->f, Qt, lface_id,
7513 it->saved_face_id);
7514 }
7515 }
7516 next_face = FACE_FROM_ID (it->f, next_face_id);
7517 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7518 && (!next_face
7519 || next_face->box == FACE_NO_BOX));
7520 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7521 }
7522 else
7523 /* Display table entry is invalid. Return a space. */
7524 it->c = ' ', it->len = 1;
7525
7526 /* Don't change position and object of the iterator here. They are
7527 still the values of the character that had this display table
7528 entry or was translated, and that's what we want. */
7529 it->what = IT_CHARACTER;
7530 return 1;
7531 }
7532
7533 /* Get the first element of string/buffer in the visual order, after
7534 being reseated to a new position in a string or a buffer. */
7535 static void
7536 get_visually_first_element (struct it *it)
7537 {
7538 int string_p = STRINGP (it->string) || it->s;
7539 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7540 ptrdiff_t bob = (string_p ? 0 : BEGV);
7541
7542 if (STRINGP (it->string))
7543 {
7544 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7545 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7546 }
7547 else
7548 {
7549 it->bidi_it.charpos = IT_CHARPOS (*it);
7550 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7551 }
7552
7553 if (it->bidi_it.charpos == eob)
7554 {
7555 /* Nothing to do, but reset the FIRST_ELT flag, like
7556 bidi_paragraph_init does, because we are not going to
7557 call it. */
7558 it->bidi_it.first_elt = 0;
7559 }
7560 else if (it->bidi_it.charpos == bob
7561 || (!string_p
7562 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7563 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7564 {
7565 /* If we are at the beginning of a line/string, we can produce
7566 the next element right away. */
7567 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7568 bidi_move_to_visually_next (&it->bidi_it);
7569 }
7570 else
7571 {
7572 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7573
7574 /* We need to prime the bidi iterator starting at the line's or
7575 string's beginning, before we will be able to produce the
7576 next element. */
7577 if (string_p)
7578 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7579 else
7580 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7581 IT_BYTEPOS (*it), -1,
7582 &it->bidi_it.bytepos);
7583 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7584 do
7585 {
7586 /* Now return to buffer/string position where we were asked
7587 to get the next display element, and produce that. */
7588 bidi_move_to_visually_next (&it->bidi_it);
7589 }
7590 while (it->bidi_it.bytepos != orig_bytepos
7591 && it->bidi_it.charpos < eob);
7592 }
7593
7594 /* Adjust IT's position information to where we ended up. */
7595 if (STRINGP (it->string))
7596 {
7597 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7598 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7599 }
7600 else
7601 {
7602 IT_CHARPOS (*it) = it->bidi_it.charpos;
7603 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7604 }
7605
7606 if (STRINGP (it->string) || !it->s)
7607 {
7608 ptrdiff_t stop, charpos, bytepos;
7609
7610 if (STRINGP (it->string))
7611 {
7612 eassert (!it->s);
7613 stop = SCHARS (it->string);
7614 if (stop > it->end_charpos)
7615 stop = it->end_charpos;
7616 charpos = IT_STRING_CHARPOS (*it);
7617 bytepos = IT_STRING_BYTEPOS (*it);
7618 }
7619 else
7620 {
7621 stop = it->end_charpos;
7622 charpos = IT_CHARPOS (*it);
7623 bytepos = IT_BYTEPOS (*it);
7624 }
7625 if (it->bidi_it.scan_dir < 0)
7626 stop = -1;
7627 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7628 it->string);
7629 }
7630 }
7631
7632 /* Load IT with the next display element from Lisp string IT->string.
7633 IT->current.string_pos is the current position within the string.
7634 If IT->current.overlay_string_index >= 0, the Lisp string is an
7635 overlay string. */
7636
7637 static int
7638 next_element_from_string (struct it *it)
7639 {
7640 struct text_pos position;
7641
7642 eassert (STRINGP (it->string));
7643 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7644 eassert (IT_STRING_CHARPOS (*it) >= 0);
7645 position = it->current.string_pos;
7646
7647 /* With bidi reordering, the character to display might not be the
7648 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7649 that we were reseat()ed to a new string, whose paragraph
7650 direction is not known. */
7651 if (it->bidi_p && it->bidi_it.first_elt)
7652 {
7653 get_visually_first_element (it);
7654 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7655 }
7656
7657 /* Time to check for invisible text? */
7658 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7659 {
7660 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7661 {
7662 if (!(!it->bidi_p
7663 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7664 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7665 {
7666 /* With bidi non-linear iteration, we could find
7667 ourselves far beyond the last computed stop_charpos,
7668 with several other stop positions in between that we
7669 missed. Scan them all now, in buffer's logical
7670 order, until we find and handle the last stop_charpos
7671 that precedes our current position. */
7672 handle_stop_backwards (it, it->stop_charpos);
7673 return GET_NEXT_DISPLAY_ELEMENT (it);
7674 }
7675 else
7676 {
7677 if (it->bidi_p)
7678 {
7679 /* Take note of the stop position we just moved
7680 across, for when we will move back across it. */
7681 it->prev_stop = it->stop_charpos;
7682 /* If we are at base paragraph embedding level, take
7683 note of the last stop position seen at this
7684 level. */
7685 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7686 it->base_level_stop = it->stop_charpos;
7687 }
7688 handle_stop (it);
7689
7690 /* Since a handler may have changed IT->method, we must
7691 recurse here. */
7692 return GET_NEXT_DISPLAY_ELEMENT (it);
7693 }
7694 }
7695 else if (it->bidi_p
7696 /* If we are before prev_stop, we may have overstepped
7697 on our way backwards a stop_pos, and if so, we need
7698 to handle that stop_pos. */
7699 && IT_STRING_CHARPOS (*it) < it->prev_stop
7700 /* We can sometimes back up for reasons that have nothing
7701 to do with bidi reordering. E.g., compositions. The
7702 code below is only needed when we are above the base
7703 embedding level, so test for that explicitly. */
7704 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7705 {
7706 /* If we lost track of base_level_stop, we have no better
7707 place for handle_stop_backwards to start from than string
7708 beginning. This happens, e.g., when we were reseated to
7709 the previous screenful of text by vertical-motion. */
7710 if (it->base_level_stop <= 0
7711 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7712 it->base_level_stop = 0;
7713 handle_stop_backwards (it, it->base_level_stop);
7714 return GET_NEXT_DISPLAY_ELEMENT (it);
7715 }
7716 }
7717
7718 if (it->current.overlay_string_index >= 0)
7719 {
7720 /* Get the next character from an overlay string. In overlay
7721 strings, there is no field width or padding with spaces to
7722 do. */
7723 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7724 {
7725 it->what = IT_EOB;
7726 return 0;
7727 }
7728 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7729 IT_STRING_BYTEPOS (*it),
7730 it->bidi_it.scan_dir < 0
7731 ? -1
7732 : SCHARS (it->string))
7733 && next_element_from_composition (it))
7734 {
7735 return 1;
7736 }
7737 else if (STRING_MULTIBYTE (it->string))
7738 {
7739 const unsigned char *s = (SDATA (it->string)
7740 + IT_STRING_BYTEPOS (*it));
7741 it->c = string_char_and_length (s, &it->len);
7742 }
7743 else
7744 {
7745 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7746 it->len = 1;
7747 }
7748 }
7749 else
7750 {
7751 /* Get the next character from a Lisp string that is not an
7752 overlay string. Such strings come from the mode line, for
7753 example. We may have to pad with spaces, or truncate the
7754 string. See also next_element_from_c_string. */
7755 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7756 {
7757 it->what = IT_EOB;
7758 return 0;
7759 }
7760 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7761 {
7762 /* Pad with spaces. */
7763 it->c = ' ', it->len = 1;
7764 CHARPOS (position) = BYTEPOS (position) = -1;
7765 }
7766 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7767 IT_STRING_BYTEPOS (*it),
7768 it->bidi_it.scan_dir < 0
7769 ? -1
7770 : it->string_nchars)
7771 && next_element_from_composition (it))
7772 {
7773 return 1;
7774 }
7775 else if (STRING_MULTIBYTE (it->string))
7776 {
7777 const unsigned char *s = (SDATA (it->string)
7778 + IT_STRING_BYTEPOS (*it));
7779 it->c = string_char_and_length (s, &it->len);
7780 }
7781 else
7782 {
7783 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7784 it->len = 1;
7785 }
7786 }
7787
7788 /* Record what we have and where it came from. */
7789 it->what = IT_CHARACTER;
7790 it->object = it->string;
7791 it->position = position;
7792 return 1;
7793 }
7794
7795
7796 /* Load IT with next display element from C string IT->s.
7797 IT->string_nchars is the maximum number of characters to return
7798 from the string. IT->end_charpos may be greater than
7799 IT->string_nchars when this function is called, in which case we
7800 may have to return padding spaces. Value is zero if end of string
7801 reached, including padding spaces. */
7802
7803 static int
7804 next_element_from_c_string (struct it *it)
7805 {
7806 int success_p = 1;
7807
7808 eassert (it->s);
7809 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7810 it->what = IT_CHARACTER;
7811 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7812 it->object = Qnil;
7813
7814 /* With bidi reordering, the character to display might not be the
7815 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7816 we were reseated to a new string, whose paragraph direction is
7817 not known. */
7818 if (it->bidi_p && it->bidi_it.first_elt)
7819 get_visually_first_element (it);
7820
7821 /* IT's position can be greater than IT->string_nchars in case a
7822 field width or precision has been specified when the iterator was
7823 initialized. */
7824 if (IT_CHARPOS (*it) >= it->end_charpos)
7825 {
7826 /* End of the game. */
7827 it->what = IT_EOB;
7828 success_p = 0;
7829 }
7830 else if (IT_CHARPOS (*it) >= it->string_nchars)
7831 {
7832 /* Pad with spaces. */
7833 it->c = ' ', it->len = 1;
7834 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7835 }
7836 else if (it->multibyte_p)
7837 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7838 else
7839 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7840
7841 return success_p;
7842 }
7843
7844
7845 /* Set up IT to return characters from an ellipsis, if appropriate.
7846 The definition of the ellipsis glyphs may come from a display table
7847 entry. This function fills IT with the first glyph from the
7848 ellipsis if an ellipsis is to be displayed. */
7849
7850 static int
7851 next_element_from_ellipsis (struct it *it)
7852 {
7853 if (it->selective_display_ellipsis_p)
7854 setup_for_ellipsis (it, it->len);
7855 else
7856 {
7857 /* The face at the current position may be different from the
7858 face we find after the invisible text. Remember what it
7859 was in IT->saved_face_id, and signal that it's there by
7860 setting face_before_selective_p. */
7861 it->saved_face_id = it->face_id;
7862 it->method = GET_FROM_BUFFER;
7863 it->object = it->w->contents;
7864 reseat_at_next_visible_line_start (it, 1);
7865 it->face_before_selective_p = 1;
7866 }
7867
7868 return GET_NEXT_DISPLAY_ELEMENT (it);
7869 }
7870
7871
7872 /* Deliver an image display element. The iterator IT is already
7873 filled with image information (done in handle_display_prop). Value
7874 is always 1. */
7875
7876
7877 static int
7878 next_element_from_image (struct it *it)
7879 {
7880 it->what = IT_IMAGE;
7881 it->ignore_overlay_strings_at_pos_p = 0;
7882 return 1;
7883 }
7884
7885
7886 /* Fill iterator IT with next display element from a stretch glyph
7887 property. IT->object is the value of the text property. Value is
7888 always 1. */
7889
7890 static int
7891 next_element_from_stretch (struct it *it)
7892 {
7893 it->what = IT_STRETCH;
7894 return 1;
7895 }
7896
7897 /* Scan backwards from IT's current position until we find a stop
7898 position, or until BEGV. This is called when we find ourself
7899 before both the last known prev_stop and base_level_stop while
7900 reordering bidirectional text. */
7901
7902 static void
7903 compute_stop_pos_backwards (struct it *it)
7904 {
7905 const int SCAN_BACK_LIMIT = 1000;
7906 struct text_pos pos;
7907 struct display_pos save_current = it->current;
7908 struct text_pos save_position = it->position;
7909 ptrdiff_t charpos = IT_CHARPOS (*it);
7910 ptrdiff_t where_we_are = charpos;
7911 ptrdiff_t save_stop_pos = it->stop_charpos;
7912 ptrdiff_t save_end_pos = it->end_charpos;
7913
7914 eassert (NILP (it->string) && !it->s);
7915 eassert (it->bidi_p);
7916 it->bidi_p = 0;
7917 do
7918 {
7919 it->end_charpos = min (charpos + 1, ZV);
7920 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7921 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7922 reseat_1 (it, pos, 0);
7923 compute_stop_pos (it);
7924 /* We must advance forward, right? */
7925 if (it->stop_charpos <= charpos)
7926 emacs_abort ();
7927 }
7928 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7929
7930 if (it->stop_charpos <= where_we_are)
7931 it->prev_stop = it->stop_charpos;
7932 else
7933 it->prev_stop = BEGV;
7934 it->bidi_p = 1;
7935 it->current = save_current;
7936 it->position = save_position;
7937 it->stop_charpos = save_stop_pos;
7938 it->end_charpos = save_end_pos;
7939 }
7940
7941 /* Scan forward from CHARPOS in the current buffer/string, until we
7942 find a stop position > current IT's position. Then handle the stop
7943 position before that. This is called when we bump into a stop
7944 position while reordering bidirectional text. CHARPOS should be
7945 the last previously processed stop_pos (or BEGV/0, if none were
7946 processed yet) whose position is less that IT's current
7947 position. */
7948
7949 static void
7950 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7951 {
7952 int bufp = !STRINGP (it->string);
7953 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7954 struct display_pos save_current = it->current;
7955 struct text_pos save_position = it->position;
7956 struct text_pos pos1;
7957 ptrdiff_t next_stop;
7958
7959 /* Scan in strict logical order. */
7960 eassert (it->bidi_p);
7961 it->bidi_p = 0;
7962 do
7963 {
7964 it->prev_stop = charpos;
7965 if (bufp)
7966 {
7967 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7968 reseat_1 (it, pos1, 0);
7969 }
7970 else
7971 it->current.string_pos = string_pos (charpos, it->string);
7972 compute_stop_pos (it);
7973 /* We must advance forward, right? */
7974 if (it->stop_charpos <= it->prev_stop)
7975 emacs_abort ();
7976 charpos = it->stop_charpos;
7977 }
7978 while (charpos <= where_we_are);
7979
7980 it->bidi_p = 1;
7981 it->current = save_current;
7982 it->position = save_position;
7983 next_stop = it->stop_charpos;
7984 it->stop_charpos = it->prev_stop;
7985 handle_stop (it);
7986 it->stop_charpos = next_stop;
7987 }
7988
7989 /* Load IT with the next display element from current_buffer. Value
7990 is zero if end of buffer reached. IT->stop_charpos is the next
7991 position at which to stop and check for text properties or buffer
7992 end. */
7993
7994 static int
7995 next_element_from_buffer (struct it *it)
7996 {
7997 int success_p = 1;
7998
7999 eassert (IT_CHARPOS (*it) >= BEGV);
8000 eassert (NILP (it->string) && !it->s);
8001 eassert (!it->bidi_p
8002 || (EQ (it->bidi_it.string.lstring, Qnil)
8003 && it->bidi_it.string.s == NULL));
8004
8005 /* With bidi reordering, the character to display might not be the
8006 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8007 we were reseat()ed to a new buffer position, which is potentially
8008 a different paragraph. */
8009 if (it->bidi_p && it->bidi_it.first_elt)
8010 {
8011 get_visually_first_element (it);
8012 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8013 }
8014
8015 if (IT_CHARPOS (*it) >= it->stop_charpos)
8016 {
8017 if (IT_CHARPOS (*it) >= it->end_charpos)
8018 {
8019 int overlay_strings_follow_p;
8020
8021 /* End of the game, except when overlay strings follow that
8022 haven't been returned yet. */
8023 if (it->overlay_strings_at_end_processed_p)
8024 overlay_strings_follow_p = 0;
8025 else
8026 {
8027 it->overlay_strings_at_end_processed_p = 1;
8028 overlay_strings_follow_p = get_overlay_strings (it, 0);
8029 }
8030
8031 if (overlay_strings_follow_p)
8032 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8033 else
8034 {
8035 it->what = IT_EOB;
8036 it->position = it->current.pos;
8037 success_p = 0;
8038 }
8039 }
8040 else if (!(!it->bidi_p
8041 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8042 || IT_CHARPOS (*it) == it->stop_charpos))
8043 {
8044 /* With bidi non-linear iteration, we could find ourselves
8045 far beyond the last computed stop_charpos, with several
8046 other stop positions in between that we missed. Scan
8047 them all now, in buffer's logical order, until we find
8048 and handle the last stop_charpos that precedes our
8049 current position. */
8050 handle_stop_backwards (it, it->stop_charpos);
8051 return GET_NEXT_DISPLAY_ELEMENT (it);
8052 }
8053 else
8054 {
8055 if (it->bidi_p)
8056 {
8057 /* Take note of the stop position we just moved across,
8058 for when we will move back across it. */
8059 it->prev_stop = it->stop_charpos;
8060 /* If we are at base paragraph embedding level, take
8061 note of the last stop position seen at this
8062 level. */
8063 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8064 it->base_level_stop = it->stop_charpos;
8065 }
8066 handle_stop (it);
8067 return GET_NEXT_DISPLAY_ELEMENT (it);
8068 }
8069 }
8070 else if (it->bidi_p
8071 /* If we are before prev_stop, we may have overstepped on
8072 our way backwards a stop_pos, and if so, we need to
8073 handle that stop_pos. */
8074 && IT_CHARPOS (*it) < it->prev_stop
8075 /* We can sometimes back up for reasons that have nothing
8076 to do with bidi reordering. E.g., compositions. The
8077 code below is only needed when we are above the base
8078 embedding level, so test for that explicitly. */
8079 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8080 {
8081 if (it->base_level_stop <= 0
8082 || IT_CHARPOS (*it) < it->base_level_stop)
8083 {
8084 /* If we lost track of base_level_stop, we need to find
8085 prev_stop by looking backwards. This happens, e.g., when
8086 we were reseated to the previous screenful of text by
8087 vertical-motion. */
8088 it->base_level_stop = BEGV;
8089 compute_stop_pos_backwards (it);
8090 handle_stop_backwards (it, it->prev_stop);
8091 }
8092 else
8093 handle_stop_backwards (it, it->base_level_stop);
8094 return GET_NEXT_DISPLAY_ELEMENT (it);
8095 }
8096 else
8097 {
8098 /* No face changes, overlays etc. in sight, so just return a
8099 character from current_buffer. */
8100 unsigned char *p;
8101 ptrdiff_t stop;
8102
8103 /* Maybe run the redisplay end trigger hook. Performance note:
8104 This doesn't seem to cost measurable time. */
8105 if (it->redisplay_end_trigger_charpos
8106 && it->glyph_row
8107 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8108 run_redisplay_end_trigger_hook (it);
8109
8110 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8111 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8112 stop)
8113 && next_element_from_composition (it))
8114 {
8115 return 1;
8116 }
8117
8118 /* Get the next character, maybe multibyte. */
8119 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8120 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8121 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8122 else
8123 it->c = *p, it->len = 1;
8124
8125 /* Record what we have and where it came from. */
8126 it->what = IT_CHARACTER;
8127 it->object = it->w->contents;
8128 it->position = it->current.pos;
8129
8130 /* Normally we return the character found above, except when we
8131 really want to return an ellipsis for selective display. */
8132 if (it->selective)
8133 {
8134 if (it->c == '\n')
8135 {
8136 /* A value of selective > 0 means hide lines indented more
8137 than that number of columns. */
8138 if (it->selective > 0
8139 && IT_CHARPOS (*it) + 1 < ZV
8140 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8141 IT_BYTEPOS (*it) + 1,
8142 it->selective))
8143 {
8144 success_p = next_element_from_ellipsis (it);
8145 it->dpvec_char_len = -1;
8146 }
8147 }
8148 else if (it->c == '\r' && it->selective == -1)
8149 {
8150 /* A value of selective == -1 means that everything from the
8151 CR to the end of the line is invisible, with maybe an
8152 ellipsis displayed for it. */
8153 success_p = next_element_from_ellipsis (it);
8154 it->dpvec_char_len = -1;
8155 }
8156 }
8157 }
8158
8159 /* Value is zero if end of buffer reached. */
8160 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8161 return success_p;
8162 }
8163
8164
8165 /* Run the redisplay end trigger hook for IT. */
8166
8167 static void
8168 run_redisplay_end_trigger_hook (struct it *it)
8169 {
8170 Lisp_Object args[3];
8171
8172 /* IT->glyph_row should be non-null, i.e. we should be actually
8173 displaying something, or otherwise we should not run the hook. */
8174 eassert (it->glyph_row);
8175
8176 /* Set up hook arguments. */
8177 args[0] = Qredisplay_end_trigger_functions;
8178 args[1] = it->window;
8179 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8180 it->redisplay_end_trigger_charpos = 0;
8181
8182 /* Since we are *trying* to run these functions, don't try to run
8183 them again, even if they get an error. */
8184 wset_redisplay_end_trigger (it->w, Qnil);
8185 Frun_hook_with_args (3, args);
8186
8187 /* Notice if it changed the face of the character we are on. */
8188 handle_face_prop (it);
8189 }
8190
8191
8192 /* Deliver a composition display element. Unlike the other
8193 next_element_from_XXX, this function is not registered in the array
8194 get_next_element[]. It is called from next_element_from_buffer and
8195 next_element_from_string when necessary. */
8196
8197 static int
8198 next_element_from_composition (struct it *it)
8199 {
8200 it->what = IT_COMPOSITION;
8201 it->len = it->cmp_it.nbytes;
8202 if (STRINGP (it->string))
8203 {
8204 if (it->c < 0)
8205 {
8206 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8207 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8208 return 0;
8209 }
8210 it->position = it->current.string_pos;
8211 it->object = it->string;
8212 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8213 IT_STRING_BYTEPOS (*it), it->string);
8214 }
8215 else
8216 {
8217 if (it->c < 0)
8218 {
8219 IT_CHARPOS (*it) += it->cmp_it.nchars;
8220 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8221 if (it->bidi_p)
8222 {
8223 if (it->bidi_it.new_paragraph)
8224 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8225 /* Resync the bidi iterator with IT's new position.
8226 FIXME: this doesn't support bidirectional text. */
8227 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8228 bidi_move_to_visually_next (&it->bidi_it);
8229 }
8230 return 0;
8231 }
8232 it->position = it->current.pos;
8233 it->object = it->w->contents;
8234 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8235 IT_BYTEPOS (*it), Qnil);
8236 }
8237 return 1;
8238 }
8239
8240
8241 \f
8242 /***********************************************************************
8243 Moving an iterator without producing glyphs
8244 ***********************************************************************/
8245
8246 /* Check if iterator is at a position corresponding to a valid buffer
8247 position after some move_it_ call. */
8248
8249 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8250 ((it)->method == GET_FROM_STRING \
8251 ? IT_STRING_CHARPOS (*it) == 0 \
8252 : 1)
8253
8254
8255 /* Move iterator IT to a specified buffer or X position within one
8256 line on the display without producing glyphs.
8257
8258 OP should be a bit mask including some or all of these bits:
8259 MOVE_TO_X: Stop upon reaching x-position TO_X.
8260 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8261 Regardless of OP's value, stop upon reaching the end of the display line.
8262
8263 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8264 This means, in particular, that TO_X includes window's horizontal
8265 scroll amount.
8266
8267 The return value has several possible values that
8268 say what condition caused the scan to stop:
8269
8270 MOVE_POS_MATCH_OR_ZV
8271 - when TO_POS or ZV was reached.
8272
8273 MOVE_X_REACHED
8274 -when TO_X was reached before TO_POS or ZV were reached.
8275
8276 MOVE_LINE_CONTINUED
8277 - when we reached the end of the display area and the line must
8278 be continued.
8279
8280 MOVE_LINE_TRUNCATED
8281 - when we reached the end of the display area and the line is
8282 truncated.
8283
8284 MOVE_NEWLINE_OR_CR
8285 - when we stopped at a line end, i.e. a newline or a CR and selective
8286 display is on. */
8287
8288 static enum move_it_result
8289 move_it_in_display_line_to (struct it *it,
8290 ptrdiff_t to_charpos, int to_x,
8291 enum move_operation_enum op)
8292 {
8293 enum move_it_result result = MOVE_UNDEFINED;
8294 struct glyph_row *saved_glyph_row;
8295 struct it wrap_it, atpos_it, atx_it, ppos_it;
8296 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8297 void *ppos_data = NULL;
8298 int may_wrap = 0;
8299 enum it_method prev_method = it->method;
8300 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8301 int saw_smaller_pos = prev_pos < to_charpos;
8302
8303 /* Don't produce glyphs in produce_glyphs. */
8304 saved_glyph_row = it->glyph_row;
8305 it->glyph_row = NULL;
8306
8307 /* Use wrap_it to save a copy of IT wherever a word wrap could
8308 occur. Use atpos_it to save a copy of IT at the desired buffer
8309 position, if found, so that we can scan ahead and check if the
8310 word later overshoots the window edge. Use atx_it similarly, for
8311 pixel positions. */
8312 wrap_it.sp = -1;
8313 atpos_it.sp = -1;
8314 atx_it.sp = -1;
8315
8316 /* Use ppos_it under bidi reordering to save a copy of IT for the
8317 position > CHARPOS that is the closest to CHARPOS. We restore
8318 that position in IT when we have scanned the entire display line
8319 without finding a match for CHARPOS and all the character
8320 positions are greater than CHARPOS. */
8321 if (it->bidi_p)
8322 {
8323 SAVE_IT (ppos_it, *it, ppos_data);
8324 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8325 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8326 SAVE_IT (ppos_it, *it, ppos_data);
8327 }
8328
8329 #define BUFFER_POS_REACHED_P() \
8330 ((op & MOVE_TO_POS) != 0 \
8331 && BUFFERP (it->object) \
8332 && (IT_CHARPOS (*it) == to_charpos \
8333 || ((!it->bidi_p \
8334 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8335 && IT_CHARPOS (*it) > to_charpos) \
8336 || (it->what == IT_COMPOSITION \
8337 && ((IT_CHARPOS (*it) > to_charpos \
8338 && to_charpos >= it->cmp_it.charpos) \
8339 || (IT_CHARPOS (*it) < to_charpos \
8340 && to_charpos <= it->cmp_it.charpos)))) \
8341 && (it->method == GET_FROM_BUFFER \
8342 || (it->method == GET_FROM_DISPLAY_VECTOR \
8343 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8344
8345 /* If there's a line-/wrap-prefix, handle it. */
8346 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8347 && it->current_y < it->last_visible_y)
8348 handle_line_prefix (it);
8349
8350 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8351 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8352
8353 while (1)
8354 {
8355 int x, i, ascent = 0, descent = 0;
8356
8357 /* Utility macro to reset an iterator with x, ascent, and descent. */
8358 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8359 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8360 (IT)->max_descent = descent)
8361
8362 /* Stop if we move beyond TO_CHARPOS (after an image or a
8363 display string or stretch glyph). */
8364 if ((op & MOVE_TO_POS) != 0
8365 && BUFFERP (it->object)
8366 && it->method == GET_FROM_BUFFER
8367 && (((!it->bidi_p
8368 /* When the iterator is at base embedding level, we
8369 are guaranteed that characters are delivered for
8370 display in strictly increasing order of their
8371 buffer positions. */
8372 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8373 && IT_CHARPOS (*it) > to_charpos)
8374 || (it->bidi_p
8375 && (prev_method == GET_FROM_IMAGE
8376 || prev_method == GET_FROM_STRETCH
8377 || prev_method == GET_FROM_STRING)
8378 /* Passed TO_CHARPOS from left to right. */
8379 && ((prev_pos < to_charpos
8380 && IT_CHARPOS (*it) > to_charpos)
8381 /* Passed TO_CHARPOS from right to left. */
8382 || (prev_pos > to_charpos
8383 && IT_CHARPOS (*it) < to_charpos)))))
8384 {
8385 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8386 {
8387 result = MOVE_POS_MATCH_OR_ZV;
8388 break;
8389 }
8390 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8391 /* If wrap_it is valid, the current position might be in a
8392 word that is wrapped. So, save the iterator in
8393 atpos_it and continue to see if wrapping happens. */
8394 SAVE_IT (atpos_it, *it, atpos_data);
8395 }
8396
8397 /* Stop when ZV reached.
8398 We used to stop here when TO_CHARPOS reached as well, but that is
8399 too soon if this glyph does not fit on this line. So we handle it
8400 explicitly below. */
8401 if (!get_next_display_element (it))
8402 {
8403 result = MOVE_POS_MATCH_OR_ZV;
8404 break;
8405 }
8406
8407 if (it->line_wrap == TRUNCATE)
8408 {
8409 if (BUFFER_POS_REACHED_P ())
8410 {
8411 result = MOVE_POS_MATCH_OR_ZV;
8412 break;
8413 }
8414 }
8415 else
8416 {
8417 if (it->line_wrap == WORD_WRAP)
8418 {
8419 if (IT_DISPLAYING_WHITESPACE (it))
8420 may_wrap = 1;
8421 else if (may_wrap)
8422 {
8423 /* We have reached a glyph that follows one or more
8424 whitespace characters. If the position is
8425 already found, we are done. */
8426 if (atpos_it.sp >= 0)
8427 {
8428 RESTORE_IT (it, &atpos_it, atpos_data);
8429 result = MOVE_POS_MATCH_OR_ZV;
8430 goto done;
8431 }
8432 if (atx_it.sp >= 0)
8433 {
8434 RESTORE_IT (it, &atx_it, atx_data);
8435 result = MOVE_X_REACHED;
8436 goto done;
8437 }
8438 /* Otherwise, we can wrap here. */
8439 SAVE_IT (wrap_it, *it, wrap_data);
8440 may_wrap = 0;
8441 }
8442 }
8443 }
8444
8445 /* Remember the line height for the current line, in case
8446 the next element doesn't fit on the line. */
8447 ascent = it->max_ascent;
8448 descent = it->max_descent;
8449
8450 /* The call to produce_glyphs will get the metrics of the
8451 display element IT is loaded with. Record the x-position
8452 before this display element, in case it doesn't fit on the
8453 line. */
8454 x = it->current_x;
8455
8456 PRODUCE_GLYPHS (it);
8457
8458 if (it->area != TEXT_AREA)
8459 {
8460 prev_method = it->method;
8461 if (it->method == GET_FROM_BUFFER)
8462 prev_pos = IT_CHARPOS (*it);
8463 set_iterator_to_next (it, 1);
8464 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8465 SET_TEXT_POS (this_line_min_pos,
8466 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8467 if (it->bidi_p
8468 && (op & MOVE_TO_POS)
8469 && IT_CHARPOS (*it) > to_charpos
8470 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8471 SAVE_IT (ppos_it, *it, ppos_data);
8472 continue;
8473 }
8474
8475 /* The number of glyphs we get back in IT->nglyphs will normally
8476 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8477 character on a terminal frame, or (iii) a line end. For the
8478 second case, IT->nglyphs - 1 padding glyphs will be present.
8479 (On X frames, there is only one glyph produced for a
8480 composite character.)
8481
8482 The behavior implemented below means, for continuation lines,
8483 that as many spaces of a TAB as fit on the current line are
8484 displayed there. For terminal frames, as many glyphs of a
8485 multi-glyph character are displayed in the current line, too.
8486 This is what the old redisplay code did, and we keep it that
8487 way. Under X, the whole shape of a complex character must
8488 fit on the line or it will be completely displayed in the
8489 next line.
8490
8491 Note that both for tabs and padding glyphs, all glyphs have
8492 the same width. */
8493 if (it->nglyphs)
8494 {
8495 /* More than one glyph or glyph doesn't fit on line. All
8496 glyphs have the same width. */
8497 int single_glyph_width = it->pixel_width / it->nglyphs;
8498 int new_x;
8499 int x_before_this_char = x;
8500 int hpos_before_this_char = it->hpos;
8501
8502 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8503 {
8504 new_x = x + single_glyph_width;
8505
8506 /* We want to leave anything reaching TO_X to the caller. */
8507 if ((op & MOVE_TO_X) && new_x > to_x)
8508 {
8509 if (BUFFER_POS_REACHED_P ())
8510 {
8511 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8512 goto buffer_pos_reached;
8513 if (atpos_it.sp < 0)
8514 {
8515 SAVE_IT (atpos_it, *it, atpos_data);
8516 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8517 }
8518 }
8519 else
8520 {
8521 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8522 {
8523 it->current_x = x;
8524 result = MOVE_X_REACHED;
8525 break;
8526 }
8527 if (atx_it.sp < 0)
8528 {
8529 SAVE_IT (atx_it, *it, atx_data);
8530 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8531 }
8532 }
8533 }
8534
8535 if (/* Lines are continued. */
8536 it->line_wrap != TRUNCATE
8537 && (/* And glyph doesn't fit on the line. */
8538 new_x > it->last_visible_x
8539 /* Or it fits exactly and we're on a window
8540 system frame. */
8541 || (new_x == it->last_visible_x
8542 && FRAME_WINDOW_P (it->f)
8543 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8544 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8545 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8546 {
8547 if (/* IT->hpos == 0 means the very first glyph
8548 doesn't fit on the line, e.g. a wide image. */
8549 it->hpos == 0
8550 || (new_x == it->last_visible_x
8551 && FRAME_WINDOW_P (it->f)))
8552 {
8553 ++it->hpos;
8554 it->current_x = new_x;
8555
8556 /* The character's last glyph just barely fits
8557 in this row. */
8558 if (i == it->nglyphs - 1)
8559 {
8560 /* If this is the destination position,
8561 return a position *before* it in this row,
8562 now that we know it fits in this row. */
8563 if (BUFFER_POS_REACHED_P ())
8564 {
8565 if (it->line_wrap != WORD_WRAP
8566 || wrap_it.sp < 0)
8567 {
8568 it->hpos = hpos_before_this_char;
8569 it->current_x = x_before_this_char;
8570 result = MOVE_POS_MATCH_OR_ZV;
8571 break;
8572 }
8573 if (it->line_wrap == WORD_WRAP
8574 && atpos_it.sp < 0)
8575 {
8576 SAVE_IT (atpos_it, *it, atpos_data);
8577 atpos_it.current_x = x_before_this_char;
8578 atpos_it.hpos = hpos_before_this_char;
8579 }
8580 }
8581
8582 prev_method = it->method;
8583 if (it->method == GET_FROM_BUFFER)
8584 prev_pos = IT_CHARPOS (*it);
8585 set_iterator_to_next (it, 1);
8586 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8587 SET_TEXT_POS (this_line_min_pos,
8588 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8589 /* On graphical terminals, newlines may
8590 "overflow" into the fringe if
8591 overflow-newline-into-fringe is non-nil.
8592 On text terminals, and on graphical
8593 terminals with no right margin, newlines
8594 may overflow into the last glyph on the
8595 display line.*/
8596 if (!FRAME_WINDOW_P (it->f)
8597 || ((it->bidi_p
8598 && it->bidi_it.paragraph_dir == R2L)
8599 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8600 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8601 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8602 {
8603 if (!get_next_display_element (it))
8604 {
8605 result = MOVE_POS_MATCH_OR_ZV;
8606 break;
8607 }
8608 if (BUFFER_POS_REACHED_P ())
8609 {
8610 if (ITERATOR_AT_END_OF_LINE_P (it))
8611 result = MOVE_POS_MATCH_OR_ZV;
8612 else
8613 result = MOVE_LINE_CONTINUED;
8614 break;
8615 }
8616 if (ITERATOR_AT_END_OF_LINE_P (it)
8617 && (it->line_wrap != WORD_WRAP
8618 || wrap_it.sp < 0))
8619 {
8620 result = MOVE_NEWLINE_OR_CR;
8621 break;
8622 }
8623 }
8624 }
8625 }
8626 else
8627 IT_RESET_X_ASCENT_DESCENT (it);
8628
8629 if (wrap_it.sp >= 0)
8630 {
8631 RESTORE_IT (it, &wrap_it, wrap_data);
8632 atpos_it.sp = -1;
8633 atx_it.sp = -1;
8634 }
8635
8636 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8637 IT_CHARPOS (*it)));
8638 result = MOVE_LINE_CONTINUED;
8639 break;
8640 }
8641
8642 if (BUFFER_POS_REACHED_P ())
8643 {
8644 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8645 goto buffer_pos_reached;
8646 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8647 {
8648 SAVE_IT (atpos_it, *it, atpos_data);
8649 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8650 }
8651 }
8652
8653 if (new_x > it->first_visible_x)
8654 {
8655 /* Glyph is visible. Increment number of glyphs that
8656 would be displayed. */
8657 ++it->hpos;
8658 }
8659 }
8660
8661 if (result != MOVE_UNDEFINED)
8662 break;
8663 }
8664 else if (BUFFER_POS_REACHED_P ())
8665 {
8666 buffer_pos_reached:
8667 IT_RESET_X_ASCENT_DESCENT (it);
8668 result = MOVE_POS_MATCH_OR_ZV;
8669 break;
8670 }
8671 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8672 {
8673 /* Stop when TO_X specified and reached. This check is
8674 necessary here because of lines consisting of a line end,
8675 only. The line end will not produce any glyphs and we
8676 would never get MOVE_X_REACHED. */
8677 eassert (it->nglyphs == 0);
8678 result = MOVE_X_REACHED;
8679 break;
8680 }
8681
8682 /* Is this a line end? If yes, we're done. */
8683 if (ITERATOR_AT_END_OF_LINE_P (it))
8684 {
8685 /* If we are past TO_CHARPOS, but never saw any character
8686 positions smaller than TO_CHARPOS, return
8687 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8688 did. */
8689 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8690 {
8691 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8692 {
8693 if (IT_CHARPOS (ppos_it) < ZV)
8694 {
8695 RESTORE_IT (it, &ppos_it, ppos_data);
8696 result = MOVE_POS_MATCH_OR_ZV;
8697 }
8698 else
8699 goto buffer_pos_reached;
8700 }
8701 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8702 && IT_CHARPOS (*it) > to_charpos)
8703 goto buffer_pos_reached;
8704 else
8705 result = MOVE_NEWLINE_OR_CR;
8706 }
8707 else
8708 result = MOVE_NEWLINE_OR_CR;
8709 break;
8710 }
8711
8712 prev_method = it->method;
8713 if (it->method == GET_FROM_BUFFER)
8714 prev_pos = IT_CHARPOS (*it);
8715 /* The current display element has been consumed. Advance
8716 to the next. */
8717 set_iterator_to_next (it, 1);
8718 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8719 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8720 if (IT_CHARPOS (*it) < to_charpos)
8721 saw_smaller_pos = 1;
8722 if (it->bidi_p
8723 && (op & MOVE_TO_POS)
8724 && IT_CHARPOS (*it) >= to_charpos
8725 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8726 SAVE_IT (ppos_it, *it, ppos_data);
8727
8728 /* Stop if lines are truncated and IT's current x-position is
8729 past the right edge of the window now. */
8730 if (it->line_wrap == TRUNCATE
8731 && it->current_x >= it->last_visible_x)
8732 {
8733 if (!FRAME_WINDOW_P (it->f)
8734 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8735 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8736 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8737 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8738 {
8739 int at_eob_p = 0;
8740
8741 if ((at_eob_p = !get_next_display_element (it))
8742 || BUFFER_POS_REACHED_P ()
8743 /* If we are past TO_CHARPOS, but never saw any
8744 character positions smaller than TO_CHARPOS,
8745 return MOVE_POS_MATCH_OR_ZV, like the
8746 unidirectional display did. */
8747 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8748 && !saw_smaller_pos
8749 && IT_CHARPOS (*it) > to_charpos))
8750 {
8751 if (it->bidi_p
8752 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8753 RESTORE_IT (it, &ppos_it, ppos_data);
8754 result = MOVE_POS_MATCH_OR_ZV;
8755 break;
8756 }
8757 if (ITERATOR_AT_END_OF_LINE_P (it))
8758 {
8759 result = MOVE_NEWLINE_OR_CR;
8760 break;
8761 }
8762 }
8763 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8764 && !saw_smaller_pos
8765 && IT_CHARPOS (*it) > to_charpos)
8766 {
8767 if (IT_CHARPOS (ppos_it) < ZV)
8768 RESTORE_IT (it, &ppos_it, ppos_data);
8769 result = MOVE_POS_MATCH_OR_ZV;
8770 break;
8771 }
8772 result = MOVE_LINE_TRUNCATED;
8773 break;
8774 }
8775 #undef IT_RESET_X_ASCENT_DESCENT
8776 }
8777
8778 #undef BUFFER_POS_REACHED_P
8779
8780 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8781 restore the saved iterator. */
8782 if (atpos_it.sp >= 0)
8783 RESTORE_IT (it, &atpos_it, atpos_data);
8784 else if (atx_it.sp >= 0)
8785 RESTORE_IT (it, &atx_it, atx_data);
8786
8787 done:
8788
8789 if (atpos_data)
8790 bidi_unshelve_cache (atpos_data, 1);
8791 if (atx_data)
8792 bidi_unshelve_cache (atx_data, 1);
8793 if (wrap_data)
8794 bidi_unshelve_cache (wrap_data, 1);
8795 if (ppos_data)
8796 bidi_unshelve_cache (ppos_data, 1);
8797
8798 /* Restore the iterator settings altered at the beginning of this
8799 function. */
8800 it->glyph_row = saved_glyph_row;
8801 return result;
8802 }
8803
8804 /* For external use. */
8805 void
8806 move_it_in_display_line (struct it *it,
8807 ptrdiff_t to_charpos, int to_x,
8808 enum move_operation_enum op)
8809 {
8810 if (it->line_wrap == WORD_WRAP
8811 && (op & MOVE_TO_X))
8812 {
8813 struct it save_it;
8814 void *save_data = NULL;
8815 int skip;
8816
8817 SAVE_IT (save_it, *it, save_data);
8818 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8819 /* When word-wrap is on, TO_X may lie past the end
8820 of a wrapped line. Then it->current is the
8821 character on the next line, so backtrack to the
8822 space before the wrap point. */
8823 if (skip == MOVE_LINE_CONTINUED)
8824 {
8825 int prev_x = max (it->current_x - 1, 0);
8826 RESTORE_IT (it, &save_it, save_data);
8827 move_it_in_display_line_to
8828 (it, -1, prev_x, MOVE_TO_X);
8829 }
8830 else
8831 bidi_unshelve_cache (save_data, 1);
8832 }
8833 else
8834 move_it_in_display_line_to (it, to_charpos, to_x, op);
8835 }
8836
8837
8838 /* Move IT forward until it satisfies one or more of the criteria in
8839 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8840
8841 OP is a bit-mask that specifies where to stop, and in particular,
8842 which of those four position arguments makes a difference. See the
8843 description of enum move_operation_enum.
8844
8845 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8846 screen line, this function will set IT to the next position that is
8847 displayed to the right of TO_CHARPOS on the screen. */
8848
8849 void
8850 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8851 {
8852 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8853 int line_height, line_start_x = 0, reached = 0;
8854 void *backup_data = NULL;
8855
8856 for (;;)
8857 {
8858 if (op & MOVE_TO_VPOS)
8859 {
8860 /* If no TO_CHARPOS and no TO_X specified, stop at the
8861 start of the line TO_VPOS. */
8862 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8863 {
8864 if (it->vpos == to_vpos)
8865 {
8866 reached = 1;
8867 break;
8868 }
8869 else
8870 skip = move_it_in_display_line_to (it, -1, -1, 0);
8871 }
8872 else
8873 {
8874 /* TO_VPOS >= 0 means stop at TO_X in the line at
8875 TO_VPOS, or at TO_POS, whichever comes first. */
8876 if (it->vpos == to_vpos)
8877 {
8878 reached = 2;
8879 break;
8880 }
8881
8882 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8883
8884 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8885 {
8886 reached = 3;
8887 break;
8888 }
8889 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8890 {
8891 /* We have reached TO_X but not in the line we want. */
8892 skip = move_it_in_display_line_to (it, to_charpos,
8893 -1, MOVE_TO_POS);
8894 if (skip == MOVE_POS_MATCH_OR_ZV)
8895 {
8896 reached = 4;
8897 break;
8898 }
8899 }
8900 }
8901 }
8902 else if (op & MOVE_TO_Y)
8903 {
8904 struct it it_backup;
8905
8906 if (it->line_wrap == WORD_WRAP)
8907 SAVE_IT (it_backup, *it, backup_data);
8908
8909 /* TO_Y specified means stop at TO_X in the line containing
8910 TO_Y---or at TO_CHARPOS if this is reached first. The
8911 problem is that we can't really tell whether the line
8912 contains TO_Y before we have completely scanned it, and
8913 this may skip past TO_X. What we do is to first scan to
8914 TO_X.
8915
8916 If TO_X is not specified, use a TO_X of zero. The reason
8917 is to make the outcome of this function more predictable.
8918 If we didn't use TO_X == 0, we would stop at the end of
8919 the line which is probably not what a caller would expect
8920 to happen. */
8921 skip = move_it_in_display_line_to
8922 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8923 (MOVE_TO_X | (op & MOVE_TO_POS)));
8924
8925 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8926 if (skip == MOVE_POS_MATCH_OR_ZV)
8927 reached = 5;
8928 else if (skip == MOVE_X_REACHED)
8929 {
8930 /* If TO_X was reached, we want to know whether TO_Y is
8931 in the line. We know this is the case if the already
8932 scanned glyphs make the line tall enough. Otherwise,
8933 we must check by scanning the rest of the line. */
8934 line_height = it->max_ascent + it->max_descent;
8935 if (to_y >= it->current_y
8936 && to_y < it->current_y + line_height)
8937 {
8938 reached = 6;
8939 break;
8940 }
8941 SAVE_IT (it_backup, *it, backup_data);
8942 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8943 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8944 op & MOVE_TO_POS);
8945 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8946 line_height = it->max_ascent + it->max_descent;
8947 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8948
8949 if (to_y >= it->current_y
8950 && to_y < it->current_y + line_height)
8951 {
8952 /* If TO_Y is in this line and TO_X was reached
8953 above, we scanned too far. We have to restore
8954 IT's settings to the ones before skipping. But
8955 keep the more accurate values of max_ascent and
8956 max_descent we've found while skipping the rest
8957 of the line, for the sake of callers, such as
8958 pos_visible_p, that need to know the line
8959 height. */
8960 int max_ascent = it->max_ascent;
8961 int max_descent = it->max_descent;
8962
8963 RESTORE_IT (it, &it_backup, backup_data);
8964 it->max_ascent = max_ascent;
8965 it->max_descent = max_descent;
8966 reached = 6;
8967 }
8968 else
8969 {
8970 skip = skip2;
8971 if (skip == MOVE_POS_MATCH_OR_ZV)
8972 reached = 7;
8973 }
8974 }
8975 else
8976 {
8977 /* Check whether TO_Y is in this line. */
8978 line_height = it->max_ascent + it->max_descent;
8979 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8980
8981 if (to_y >= it->current_y
8982 && to_y < it->current_y + line_height)
8983 {
8984 /* When word-wrap is on, TO_X may lie past the end
8985 of a wrapped line. Then it->current is the
8986 character on the next line, so backtrack to the
8987 space before the wrap point. */
8988 if (skip == MOVE_LINE_CONTINUED
8989 && it->line_wrap == WORD_WRAP)
8990 {
8991 int prev_x = max (it->current_x - 1, 0);
8992 RESTORE_IT (it, &it_backup, backup_data);
8993 skip = move_it_in_display_line_to
8994 (it, -1, prev_x, MOVE_TO_X);
8995 }
8996 reached = 6;
8997 }
8998 }
8999
9000 if (reached)
9001 break;
9002 }
9003 else if (BUFFERP (it->object)
9004 && (it->method == GET_FROM_BUFFER
9005 || it->method == GET_FROM_STRETCH)
9006 && IT_CHARPOS (*it) >= to_charpos
9007 /* Under bidi iteration, a call to set_iterator_to_next
9008 can scan far beyond to_charpos if the initial
9009 portion of the next line needs to be reordered. In
9010 that case, give move_it_in_display_line_to another
9011 chance below. */
9012 && !(it->bidi_p
9013 && it->bidi_it.scan_dir == -1))
9014 skip = MOVE_POS_MATCH_OR_ZV;
9015 else
9016 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9017
9018 switch (skip)
9019 {
9020 case MOVE_POS_MATCH_OR_ZV:
9021 reached = 8;
9022 goto out;
9023
9024 case MOVE_NEWLINE_OR_CR:
9025 set_iterator_to_next (it, 1);
9026 it->continuation_lines_width = 0;
9027 break;
9028
9029 case MOVE_LINE_TRUNCATED:
9030 it->continuation_lines_width = 0;
9031 reseat_at_next_visible_line_start (it, 0);
9032 if ((op & MOVE_TO_POS) != 0
9033 && IT_CHARPOS (*it) > to_charpos)
9034 {
9035 reached = 9;
9036 goto out;
9037 }
9038 break;
9039
9040 case MOVE_LINE_CONTINUED:
9041 /* For continued lines ending in a tab, some of the glyphs
9042 associated with the tab are displayed on the current
9043 line. Since it->current_x does not include these glyphs,
9044 we use it->last_visible_x instead. */
9045 if (it->c == '\t')
9046 {
9047 it->continuation_lines_width += it->last_visible_x;
9048 /* When moving by vpos, ensure that the iterator really
9049 advances to the next line (bug#847, bug#969). Fixme:
9050 do we need to do this in other circumstances? */
9051 if (it->current_x != it->last_visible_x
9052 && (op & MOVE_TO_VPOS)
9053 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9054 {
9055 line_start_x = it->current_x + it->pixel_width
9056 - it->last_visible_x;
9057 set_iterator_to_next (it, 0);
9058 }
9059 }
9060 else
9061 it->continuation_lines_width += it->current_x;
9062 break;
9063
9064 default:
9065 emacs_abort ();
9066 }
9067
9068 /* Reset/increment for the next run. */
9069 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9070 it->current_x = line_start_x;
9071 line_start_x = 0;
9072 it->hpos = 0;
9073 it->current_y += it->max_ascent + it->max_descent;
9074 ++it->vpos;
9075 last_height = it->max_ascent + it->max_descent;
9076 it->max_ascent = it->max_descent = 0;
9077 }
9078
9079 out:
9080
9081 /* On text terminals, we may stop at the end of a line in the middle
9082 of a multi-character glyph. If the glyph itself is continued,
9083 i.e. it is actually displayed on the next line, don't treat this
9084 stopping point as valid; move to the next line instead (unless
9085 that brings us offscreen). */
9086 if (!FRAME_WINDOW_P (it->f)
9087 && op & MOVE_TO_POS
9088 && IT_CHARPOS (*it) == to_charpos
9089 && it->what == IT_CHARACTER
9090 && it->nglyphs > 1
9091 && it->line_wrap == WINDOW_WRAP
9092 && it->current_x == it->last_visible_x - 1
9093 && it->c != '\n'
9094 && it->c != '\t'
9095 && it->vpos < it->w->window_end_vpos)
9096 {
9097 it->continuation_lines_width += it->current_x;
9098 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9099 it->current_y += it->max_ascent + it->max_descent;
9100 ++it->vpos;
9101 last_height = it->max_ascent + it->max_descent;
9102 }
9103
9104 if (backup_data)
9105 bidi_unshelve_cache (backup_data, 1);
9106
9107 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9108 }
9109
9110
9111 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9112
9113 If DY > 0, move IT backward at least that many pixels. DY = 0
9114 means move IT backward to the preceding line start or BEGV. This
9115 function may move over more than DY pixels if IT->current_y - DY
9116 ends up in the middle of a line; in this case IT->current_y will be
9117 set to the top of the line moved to. */
9118
9119 void
9120 move_it_vertically_backward (struct it *it, int dy)
9121 {
9122 int nlines, h;
9123 struct it it2, it3;
9124 void *it2data = NULL, *it3data = NULL;
9125 ptrdiff_t start_pos;
9126 int nchars_per_row
9127 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9128 ptrdiff_t pos_limit;
9129
9130 move_further_back:
9131 eassert (dy >= 0);
9132
9133 start_pos = IT_CHARPOS (*it);
9134
9135 /* Estimate how many newlines we must move back. */
9136 nlines = max (1, dy / default_line_pixel_height (it->w));
9137 if (it->line_wrap == TRUNCATE)
9138 pos_limit = BEGV;
9139 else
9140 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9141
9142 /* Set the iterator's position that many lines back. But don't go
9143 back more than NLINES full screen lines -- this wins a day with
9144 buffers which have very long lines. */
9145 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9146 back_to_previous_visible_line_start (it);
9147
9148 /* Reseat the iterator here. When moving backward, we don't want
9149 reseat to skip forward over invisible text, set up the iterator
9150 to deliver from overlay strings at the new position etc. So,
9151 use reseat_1 here. */
9152 reseat_1 (it, it->current.pos, 1);
9153
9154 /* We are now surely at a line start. */
9155 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9156 reordering is in effect. */
9157 it->continuation_lines_width = 0;
9158
9159 /* Move forward and see what y-distance we moved. First move to the
9160 start of the next line so that we get its height. We need this
9161 height to be able to tell whether we reached the specified
9162 y-distance. */
9163 SAVE_IT (it2, *it, it2data);
9164 it2.max_ascent = it2.max_descent = 0;
9165 do
9166 {
9167 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9168 MOVE_TO_POS | MOVE_TO_VPOS);
9169 }
9170 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9171 /* If we are in a display string which starts at START_POS,
9172 and that display string includes a newline, and we are
9173 right after that newline (i.e. at the beginning of a
9174 display line), exit the loop, because otherwise we will
9175 infloop, since move_it_to will see that it is already at
9176 START_POS and will not move. */
9177 || (it2.method == GET_FROM_STRING
9178 && IT_CHARPOS (it2) == start_pos
9179 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9180 eassert (IT_CHARPOS (*it) >= BEGV);
9181 SAVE_IT (it3, it2, it3data);
9182
9183 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9184 eassert (IT_CHARPOS (*it) >= BEGV);
9185 /* H is the actual vertical distance from the position in *IT
9186 and the starting position. */
9187 h = it2.current_y - it->current_y;
9188 /* NLINES is the distance in number of lines. */
9189 nlines = it2.vpos - it->vpos;
9190
9191 /* Correct IT's y and vpos position
9192 so that they are relative to the starting point. */
9193 it->vpos -= nlines;
9194 it->current_y -= h;
9195
9196 if (dy == 0)
9197 {
9198 /* DY == 0 means move to the start of the screen line. The
9199 value of nlines is > 0 if continuation lines were involved,
9200 or if the original IT position was at start of a line. */
9201 RESTORE_IT (it, it, it2data);
9202 if (nlines > 0)
9203 move_it_by_lines (it, nlines);
9204 /* The above code moves us to some position NLINES down,
9205 usually to its first glyph (leftmost in an L2R line), but
9206 that's not necessarily the start of the line, under bidi
9207 reordering. We want to get to the character position
9208 that is immediately after the newline of the previous
9209 line. */
9210 if (it->bidi_p
9211 && !it->continuation_lines_width
9212 && !STRINGP (it->string)
9213 && IT_CHARPOS (*it) > BEGV
9214 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9215 {
9216 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9217
9218 DEC_BOTH (cp, bp);
9219 cp = find_newline_no_quit (cp, bp, -1, NULL);
9220 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9221 }
9222 bidi_unshelve_cache (it3data, 1);
9223 }
9224 else
9225 {
9226 /* The y-position we try to reach, relative to *IT.
9227 Note that H has been subtracted in front of the if-statement. */
9228 int target_y = it->current_y + h - dy;
9229 int y0 = it3.current_y;
9230 int y1;
9231 int line_height;
9232
9233 RESTORE_IT (&it3, &it3, it3data);
9234 y1 = line_bottom_y (&it3);
9235 line_height = y1 - y0;
9236 RESTORE_IT (it, it, it2data);
9237 /* If we did not reach target_y, try to move further backward if
9238 we can. If we moved too far backward, try to move forward. */
9239 if (target_y < it->current_y
9240 /* This is heuristic. In a window that's 3 lines high, with
9241 a line height of 13 pixels each, recentering with point
9242 on the bottom line will try to move -39/2 = 19 pixels
9243 backward. Try to avoid moving into the first line. */
9244 && (it->current_y - target_y
9245 > min (window_box_height (it->w), line_height * 2 / 3))
9246 && IT_CHARPOS (*it) > BEGV)
9247 {
9248 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9249 target_y - it->current_y));
9250 dy = it->current_y - target_y;
9251 goto move_further_back;
9252 }
9253 else if (target_y >= it->current_y + line_height
9254 && IT_CHARPOS (*it) < ZV)
9255 {
9256 /* Should move forward by at least one line, maybe more.
9257
9258 Note: Calling move_it_by_lines can be expensive on
9259 terminal frames, where compute_motion is used (via
9260 vmotion) to do the job, when there are very long lines
9261 and truncate-lines is nil. That's the reason for
9262 treating terminal frames specially here. */
9263
9264 if (!FRAME_WINDOW_P (it->f))
9265 move_it_vertically (it, target_y - (it->current_y + line_height));
9266 else
9267 {
9268 do
9269 {
9270 move_it_by_lines (it, 1);
9271 }
9272 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9273 }
9274 }
9275 }
9276 }
9277
9278
9279 /* Move IT by a specified amount of pixel lines DY. DY negative means
9280 move backwards. DY = 0 means move to start of screen line. At the
9281 end, IT will be on the start of a screen line. */
9282
9283 void
9284 move_it_vertically (struct it *it, int dy)
9285 {
9286 if (dy <= 0)
9287 move_it_vertically_backward (it, -dy);
9288 else
9289 {
9290 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9291 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9292 MOVE_TO_POS | MOVE_TO_Y);
9293 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9294
9295 /* If buffer ends in ZV without a newline, move to the start of
9296 the line to satisfy the post-condition. */
9297 if (IT_CHARPOS (*it) == ZV
9298 && ZV > BEGV
9299 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9300 move_it_by_lines (it, 0);
9301 }
9302 }
9303
9304
9305 /* Move iterator IT past the end of the text line it is in. */
9306
9307 void
9308 move_it_past_eol (struct it *it)
9309 {
9310 enum move_it_result rc;
9311
9312 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9313 if (rc == MOVE_NEWLINE_OR_CR)
9314 set_iterator_to_next (it, 0);
9315 }
9316
9317
9318 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9319 negative means move up. DVPOS == 0 means move to the start of the
9320 screen line.
9321
9322 Optimization idea: If we would know that IT->f doesn't use
9323 a face with proportional font, we could be faster for
9324 truncate-lines nil. */
9325
9326 void
9327 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9328 {
9329
9330 /* The commented-out optimization uses vmotion on terminals. This
9331 gives bad results, because elements like it->what, on which
9332 callers such as pos_visible_p rely, aren't updated. */
9333 /* struct position pos;
9334 if (!FRAME_WINDOW_P (it->f))
9335 {
9336 struct text_pos textpos;
9337
9338 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9339 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9340 reseat (it, textpos, 1);
9341 it->vpos += pos.vpos;
9342 it->current_y += pos.vpos;
9343 }
9344 else */
9345
9346 if (dvpos == 0)
9347 {
9348 /* DVPOS == 0 means move to the start of the screen line. */
9349 move_it_vertically_backward (it, 0);
9350 /* Let next call to line_bottom_y calculate real line height */
9351 last_height = 0;
9352 }
9353 else if (dvpos > 0)
9354 {
9355 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9356 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9357 {
9358 /* Only move to the next buffer position if we ended up in a
9359 string from display property, not in an overlay string
9360 (before-string or after-string). That is because the
9361 latter don't conceal the underlying buffer position, so
9362 we can ask to move the iterator to the exact position we
9363 are interested in. Note that, even if we are already at
9364 IT_CHARPOS (*it), the call below is not a no-op, as it
9365 will detect that we are at the end of the string, pop the
9366 iterator, and compute it->current_x and it->hpos
9367 correctly. */
9368 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9369 -1, -1, -1, MOVE_TO_POS);
9370 }
9371 }
9372 else
9373 {
9374 struct it it2;
9375 void *it2data = NULL;
9376 ptrdiff_t start_charpos, i;
9377 int nchars_per_row
9378 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9379 ptrdiff_t pos_limit;
9380
9381 /* Start at the beginning of the screen line containing IT's
9382 position. This may actually move vertically backwards,
9383 in case of overlays, so adjust dvpos accordingly. */
9384 dvpos += it->vpos;
9385 move_it_vertically_backward (it, 0);
9386 dvpos -= it->vpos;
9387
9388 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9389 screen lines, and reseat the iterator there. */
9390 start_charpos = IT_CHARPOS (*it);
9391 if (it->line_wrap == TRUNCATE)
9392 pos_limit = BEGV;
9393 else
9394 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9395 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9396 back_to_previous_visible_line_start (it);
9397 reseat (it, it->current.pos, 1);
9398
9399 /* Move further back if we end up in a string or an image. */
9400 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9401 {
9402 /* First try to move to start of display line. */
9403 dvpos += it->vpos;
9404 move_it_vertically_backward (it, 0);
9405 dvpos -= it->vpos;
9406 if (IT_POS_VALID_AFTER_MOVE_P (it))
9407 break;
9408 /* If start of line is still in string or image,
9409 move further back. */
9410 back_to_previous_visible_line_start (it);
9411 reseat (it, it->current.pos, 1);
9412 dvpos--;
9413 }
9414
9415 it->current_x = it->hpos = 0;
9416
9417 /* Above call may have moved too far if continuation lines
9418 are involved. Scan forward and see if it did. */
9419 SAVE_IT (it2, *it, it2data);
9420 it2.vpos = it2.current_y = 0;
9421 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9422 it->vpos -= it2.vpos;
9423 it->current_y -= it2.current_y;
9424 it->current_x = it->hpos = 0;
9425
9426 /* If we moved too far back, move IT some lines forward. */
9427 if (it2.vpos > -dvpos)
9428 {
9429 int delta = it2.vpos + dvpos;
9430
9431 RESTORE_IT (&it2, &it2, it2data);
9432 SAVE_IT (it2, *it, it2data);
9433 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9434 /* Move back again if we got too far ahead. */
9435 if (IT_CHARPOS (*it) >= start_charpos)
9436 RESTORE_IT (it, &it2, it2data);
9437 else
9438 bidi_unshelve_cache (it2data, 1);
9439 }
9440 else
9441 RESTORE_IT (it, it, it2data);
9442 }
9443 }
9444
9445 /* Return 1 if IT points into the middle of a display vector. */
9446
9447 int
9448 in_display_vector_p (struct it *it)
9449 {
9450 return (it->method == GET_FROM_DISPLAY_VECTOR
9451 && it->current.dpvec_index > 0
9452 && it->dpvec + it->current.dpvec_index != it->dpend);
9453 }
9454
9455 \f
9456 /***********************************************************************
9457 Messages
9458 ***********************************************************************/
9459
9460
9461 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9462 to *Messages*. */
9463
9464 void
9465 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9466 {
9467 Lisp_Object args[3];
9468 Lisp_Object msg, fmt;
9469 char *buffer;
9470 ptrdiff_t len;
9471 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9472 USE_SAFE_ALLOCA;
9473
9474 fmt = msg = Qnil;
9475 GCPRO4 (fmt, msg, arg1, arg2);
9476
9477 args[0] = fmt = build_string (format);
9478 args[1] = arg1;
9479 args[2] = arg2;
9480 msg = Fformat (3, args);
9481
9482 len = SBYTES (msg) + 1;
9483 buffer = SAFE_ALLOCA (len);
9484 memcpy (buffer, SDATA (msg), len);
9485
9486 message_dolog (buffer, len - 1, 1, 0);
9487 SAFE_FREE ();
9488
9489 UNGCPRO;
9490 }
9491
9492
9493 /* Output a newline in the *Messages* buffer if "needs" one. */
9494
9495 void
9496 message_log_maybe_newline (void)
9497 {
9498 if (message_log_need_newline)
9499 message_dolog ("", 0, 1, 0);
9500 }
9501
9502
9503 /* Add a string M of length NBYTES to the message log, optionally
9504 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9505 true, means interpret the contents of M as multibyte. This
9506 function calls low-level routines in order to bypass text property
9507 hooks, etc. which might not be safe to run.
9508
9509 This may GC (insert may run before/after change hooks),
9510 so the buffer M must NOT point to a Lisp string. */
9511
9512 void
9513 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9514 {
9515 const unsigned char *msg = (const unsigned char *) m;
9516
9517 if (!NILP (Vmemory_full))
9518 return;
9519
9520 if (!NILP (Vmessage_log_max))
9521 {
9522 struct buffer *oldbuf;
9523 Lisp_Object oldpoint, oldbegv, oldzv;
9524 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9525 ptrdiff_t point_at_end = 0;
9526 ptrdiff_t zv_at_end = 0;
9527 Lisp_Object old_deactivate_mark;
9528 bool shown;
9529 struct gcpro gcpro1;
9530
9531 old_deactivate_mark = Vdeactivate_mark;
9532 oldbuf = current_buffer;
9533 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9534 bset_undo_list (current_buffer, Qt);
9535
9536 oldpoint = message_dolog_marker1;
9537 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9538 oldbegv = message_dolog_marker2;
9539 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9540 oldzv = message_dolog_marker3;
9541 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9542 GCPRO1 (old_deactivate_mark);
9543
9544 if (PT == Z)
9545 point_at_end = 1;
9546 if (ZV == Z)
9547 zv_at_end = 1;
9548
9549 BEGV = BEG;
9550 BEGV_BYTE = BEG_BYTE;
9551 ZV = Z;
9552 ZV_BYTE = Z_BYTE;
9553 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9554
9555 /* Insert the string--maybe converting multibyte to single byte
9556 or vice versa, so that all the text fits the buffer. */
9557 if (multibyte
9558 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9559 {
9560 ptrdiff_t i;
9561 int c, char_bytes;
9562 char work[1];
9563
9564 /* Convert a multibyte string to single-byte
9565 for the *Message* buffer. */
9566 for (i = 0; i < nbytes; i += char_bytes)
9567 {
9568 c = string_char_and_length (msg + i, &char_bytes);
9569 work[0] = (ASCII_CHAR_P (c)
9570 ? c
9571 : multibyte_char_to_unibyte (c));
9572 insert_1_both (work, 1, 1, 1, 0, 0);
9573 }
9574 }
9575 else if (! multibyte
9576 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9577 {
9578 ptrdiff_t i;
9579 int c, char_bytes;
9580 unsigned char str[MAX_MULTIBYTE_LENGTH];
9581 /* Convert a single-byte string to multibyte
9582 for the *Message* buffer. */
9583 for (i = 0; i < nbytes; i++)
9584 {
9585 c = msg[i];
9586 MAKE_CHAR_MULTIBYTE (c);
9587 char_bytes = CHAR_STRING (c, str);
9588 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9589 }
9590 }
9591 else if (nbytes)
9592 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9593
9594 if (nlflag)
9595 {
9596 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9597 printmax_t dups;
9598
9599 insert_1_both ("\n", 1, 1, 1, 0, 0);
9600
9601 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9602 this_bol = PT;
9603 this_bol_byte = PT_BYTE;
9604
9605 /* See if this line duplicates the previous one.
9606 If so, combine duplicates. */
9607 if (this_bol > BEG)
9608 {
9609 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9610 prev_bol = PT;
9611 prev_bol_byte = PT_BYTE;
9612
9613 dups = message_log_check_duplicate (prev_bol_byte,
9614 this_bol_byte);
9615 if (dups)
9616 {
9617 del_range_both (prev_bol, prev_bol_byte,
9618 this_bol, this_bol_byte, 0);
9619 if (dups > 1)
9620 {
9621 char dupstr[sizeof " [ times]"
9622 + INT_STRLEN_BOUND (printmax_t)];
9623
9624 /* If you change this format, don't forget to also
9625 change message_log_check_duplicate. */
9626 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9627 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9628 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9629 }
9630 }
9631 }
9632
9633 /* If we have more than the desired maximum number of lines
9634 in the *Messages* buffer now, delete the oldest ones.
9635 This is safe because we don't have undo in this buffer. */
9636
9637 if (NATNUMP (Vmessage_log_max))
9638 {
9639 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9640 -XFASTINT (Vmessage_log_max) - 1, 0);
9641 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9642 }
9643 }
9644 BEGV = marker_position (oldbegv);
9645 BEGV_BYTE = marker_byte_position (oldbegv);
9646
9647 if (zv_at_end)
9648 {
9649 ZV = Z;
9650 ZV_BYTE = Z_BYTE;
9651 }
9652 else
9653 {
9654 ZV = marker_position (oldzv);
9655 ZV_BYTE = marker_byte_position (oldzv);
9656 }
9657
9658 if (point_at_end)
9659 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9660 else
9661 /* We can't do Fgoto_char (oldpoint) because it will run some
9662 Lisp code. */
9663 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9664 marker_byte_position (oldpoint));
9665
9666 UNGCPRO;
9667 unchain_marker (XMARKER (oldpoint));
9668 unchain_marker (XMARKER (oldbegv));
9669 unchain_marker (XMARKER (oldzv));
9670
9671 shown = buffer_window_count (current_buffer) > 0;
9672 set_buffer_internal (oldbuf);
9673 /* We called insert_1_both above with its 5th argument (PREPARE)
9674 zero, which prevents insert_1_both from calling
9675 prepare_to_modify_buffer, which in turns prevents us from
9676 incrementing windows_or_buffers_changed even if *Messages* is
9677 shown in some window. So we must manually incrementing
9678 windows_or_buffers_changed here to make up for that. */
9679 if (shown)
9680 windows_or_buffers_changed++;
9681 else
9682 windows_or_buffers_changed = old_windows_or_buffers_changed;
9683 message_log_need_newline = !nlflag;
9684 Vdeactivate_mark = old_deactivate_mark;
9685 }
9686 }
9687
9688
9689 /* We are at the end of the buffer after just having inserted a newline.
9690 (Note: We depend on the fact we won't be crossing the gap.)
9691 Check to see if the most recent message looks a lot like the previous one.
9692 Return 0 if different, 1 if the new one should just replace it, or a
9693 value N > 1 if we should also append " [N times]". */
9694
9695 static intmax_t
9696 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9697 {
9698 ptrdiff_t i;
9699 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9700 int seen_dots = 0;
9701 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9702 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9703
9704 for (i = 0; i < len; i++)
9705 {
9706 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9707 seen_dots = 1;
9708 if (p1[i] != p2[i])
9709 return seen_dots;
9710 }
9711 p1 += len;
9712 if (*p1 == '\n')
9713 return 2;
9714 if (*p1++ == ' ' && *p1++ == '[')
9715 {
9716 char *pend;
9717 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9718 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9719 return n + 1;
9720 }
9721 return 0;
9722 }
9723 \f
9724
9725 /* Display an echo area message M with a specified length of NBYTES
9726 bytes. The string may include null characters. If M is not a
9727 string, clear out any existing message, and let the mini-buffer
9728 text show through.
9729
9730 This function cancels echoing. */
9731
9732 void
9733 message3 (Lisp_Object m)
9734 {
9735 struct gcpro gcpro1;
9736
9737 GCPRO1 (m);
9738 clear_message (1,1);
9739 cancel_echoing ();
9740
9741 /* First flush out any partial line written with print. */
9742 message_log_maybe_newline ();
9743 if (STRINGP (m))
9744 {
9745 ptrdiff_t nbytes = SBYTES (m);
9746 bool multibyte = STRING_MULTIBYTE (m);
9747 USE_SAFE_ALLOCA;
9748 char *buffer = SAFE_ALLOCA (nbytes);
9749 memcpy (buffer, SDATA (m), nbytes);
9750 message_dolog (buffer, nbytes, 1, multibyte);
9751 SAFE_FREE ();
9752 }
9753 message3_nolog (m);
9754
9755 UNGCPRO;
9756 }
9757
9758
9759 /* The non-logging version of message3.
9760 This does not cancel echoing, because it is used for echoing.
9761 Perhaps we need to make a separate function for echoing
9762 and make this cancel echoing. */
9763
9764 void
9765 message3_nolog (Lisp_Object m)
9766 {
9767 struct frame *sf = SELECTED_FRAME ();
9768
9769 if (FRAME_INITIAL_P (sf))
9770 {
9771 if (noninteractive_need_newline)
9772 putc ('\n', stderr);
9773 noninteractive_need_newline = 0;
9774 if (STRINGP (m))
9775 fwrite (SDATA (m), SBYTES (m), 1, stderr);
9776 if (cursor_in_echo_area == 0)
9777 fprintf (stderr, "\n");
9778 fflush (stderr);
9779 }
9780 /* Error messages get reported properly by cmd_error, so this must be just an
9781 informative message; if the frame hasn't really been initialized yet, just
9782 toss it. */
9783 else if (INTERACTIVE && sf->glyphs_initialized_p)
9784 {
9785 /* Get the frame containing the mini-buffer
9786 that the selected frame is using. */
9787 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9788 Lisp_Object frame = XWINDOW (mini_window)->frame;
9789 struct frame *f = XFRAME (frame);
9790
9791 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9792 Fmake_frame_visible (frame);
9793
9794 if (STRINGP (m) && SCHARS (m) > 0)
9795 {
9796 set_message (m);
9797 if (minibuffer_auto_raise)
9798 Fraise_frame (frame);
9799 /* Assume we are not echoing.
9800 (If we are, echo_now will override this.) */
9801 echo_message_buffer = Qnil;
9802 }
9803 else
9804 clear_message (1, 1);
9805
9806 do_pending_window_change (0);
9807 echo_area_display (1);
9808 do_pending_window_change (0);
9809 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9810 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9811 }
9812 }
9813
9814
9815 /* Display a null-terminated echo area message M. If M is 0, clear
9816 out any existing message, and let the mini-buffer text show through.
9817
9818 The buffer M must continue to exist until after the echo area gets
9819 cleared or some other message gets displayed there. Do not pass
9820 text that is stored in a Lisp string. Do not pass text in a buffer
9821 that was alloca'd. */
9822
9823 void
9824 message1 (const char *m)
9825 {
9826 message3 (m ? build_unibyte_string (m) : Qnil);
9827 }
9828
9829
9830 /* The non-logging counterpart of message1. */
9831
9832 void
9833 message1_nolog (const char *m)
9834 {
9835 message3_nolog (m ? build_unibyte_string (m) : Qnil);
9836 }
9837
9838 /* Display a message M which contains a single %s
9839 which gets replaced with STRING. */
9840
9841 void
9842 message_with_string (const char *m, Lisp_Object string, int log)
9843 {
9844 CHECK_STRING (string);
9845
9846 if (noninteractive)
9847 {
9848 if (m)
9849 {
9850 if (noninteractive_need_newline)
9851 putc ('\n', stderr);
9852 noninteractive_need_newline = 0;
9853 fprintf (stderr, m, SDATA (string));
9854 if (!cursor_in_echo_area)
9855 fprintf (stderr, "\n");
9856 fflush (stderr);
9857 }
9858 }
9859 else if (INTERACTIVE)
9860 {
9861 /* The frame whose minibuffer we're going to display the message on.
9862 It may be larger than the selected frame, so we need
9863 to use its buffer, not the selected frame's buffer. */
9864 Lisp_Object mini_window;
9865 struct frame *f, *sf = SELECTED_FRAME ();
9866
9867 /* Get the frame containing the minibuffer
9868 that the selected frame is using. */
9869 mini_window = FRAME_MINIBUF_WINDOW (sf);
9870 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9871
9872 /* Error messages get reported properly by cmd_error, so this must be
9873 just an informative message; if the frame hasn't really been
9874 initialized yet, just toss it. */
9875 if (f->glyphs_initialized_p)
9876 {
9877 Lisp_Object args[2], msg;
9878 struct gcpro gcpro1, gcpro2;
9879
9880 args[0] = build_string (m);
9881 args[1] = msg = string;
9882 GCPRO2 (args[0], msg);
9883 gcpro1.nvars = 2;
9884
9885 msg = Fformat (2, args);
9886
9887 if (log)
9888 message3 (msg);
9889 else
9890 message3_nolog (msg);
9891
9892 UNGCPRO;
9893
9894 /* Print should start at the beginning of the message
9895 buffer next time. */
9896 message_buf_print = 0;
9897 }
9898 }
9899 }
9900
9901
9902 /* Dump an informative message to the minibuf. If M is 0, clear out
9903 any existing message, and let the mini-buffer text show through. */
9904
9905 static void
9906 vmessage (const char *m, va_list ap)
9907 {
9908 if (noninteractive)
9909 {
9910 if (m)
9911 {
9912 if (noninteractive_need_newline)
9913 putc ('\n', stderr);
9914 noninteractive_need_newline = 0;
9915 vfprintf (stderr, m, ap);
9916 if (cursor_in_echo_area == 0)
9917 fprintf (stderr, "\n");
9918 fflush (stderr);
9919 }
9920 }
9921 else if (INTERACTIVE)
9922 {
9923 /* The frame whose mini-buffer we're going to display the message
9924 on. It may be larger than the selected frame, so we need to
9925 use its buffer, not the selected frame's buffer. */
9926 Lisp_Object mini_window;
9927 struct frame *f, *sf = SELECTED_FRAME ();
9928
9929 /* Get the frame containing the mini-buffer
9930 that the selected frame is using. */
9931 mini_window = FRAME_MINIBUF_WINDOW (sf);
9932 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9933
9934 /* Error messages get reported properly by cmd_error, so this must be
9935 just an informative message; if the frame hasn't really been
9936 initialized yet, just toss it. */
9937 if (f->glyphs_initialized_p)
9938 {
9939 if (m)
9940 {
9941 ptrdiff_t len;
9942 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9943 char *message_buf = alloca (maxsize + 1);
9944
9945 len = doprnt (message_buf, maxsize, m, 0, ap);
9946
9947 message3 (make_string (message_buf, len));
9948 }
9949 else
9950 message1 (0);
9951
9952 /* Print should start at the beginning of the message
9953 buffer next time. */
9954 message_buf_print = 0;
9955 }
9956 }
9957 }
9958
9959 void
9960 message (const char *m, ...)
9961 {
9962 va_list ap;
9963 va_start (ap, m);
9964 vmessage (m, ap);
9965 va_end (ap);
9966 }
9967
9968
9969 #if 0
9970 /* The non-logging version of message. */
9971
9972 void
9973 message_nolog (const char *m, ...)
9974 {
9975 Lisp_Object old_log_max;
9976 va_list ap;
9977 va_start (ap, m);
9978 old_log_max = Vmessage_log_max;
9979 Vmessage_log_max = Qnil;
9980 vmessage (m, ap);
9981 Vmessage_log_max = old_log_max;
9982 va_end (ap);
9983 }
9984 #endif
9985
9986
9987 /* Display the current message in the current mini-buffer. This is
9988 only called from error handlers in process.c, and is not time
9989 critical. */
9990
9991 void
9992 update_echo_area (void)
9993 {
9994 if (!NILP (echo_area_buffer[0]))
9995 {
9996 Lisp_Object string;
9997 string = Fcurrent_message ();
9998 message3 (string);
9999 }
10000 }
10001
10002
10003 /* Make sure echo area buffers in `echo_buffers' are live.
10004 If they aren't, make new ones. */
10005
10006 static void
10007 ensure_echo_area_buffers (void)
10008 {
10009 int i;
10010
10011 for (i = 0; i < 2; ++i)
10012 if (!BUFFERP (echo_buffer[i])
10013 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10014 {
10015 char name[30];
10016 Lisp_Object old_buffer;
10017 int j;
10018
10019 old_buffer = echo_buffer[i];
10020 echo_buffer[i] = Fget_buffer_create
10021 (make_formatted_string (name, " *Echo Area %d*", i));
10022 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10023 /* to force word wrap in echo area -
10024 it was decided to postpone this*/
10025 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10026
10027 for (j = 0; j < 2; ++j)
10028 if (EQ (old_buffer, echo_area_buffer[j]))
10029 echo_area_buffer[j] = echo_buffer[i];
10030 }
10031 }
10032
10033
10034 /* Call FN with args A1..A2 with either the current or last displayed
10035 echo_area_buffer as current buffer.
10036
10037 WHICH zero means use the current message buffer
10038 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10039 from echo_buffer[] and clear it.
10040
10041 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10042 suitable buffer from echo_buffer[] and clear it.
10043
10044 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10045 that the current message becomes the last displayed one, make
10046 choose a suitable buffer for echo_area_buffer[0], and clear it.
10047
10048 Value is what FN returns. */
10049
10050 static int
10051 with_echo_area_buffer (struct window *w, int which,
10052 int (*fn) (ptrdiff_t, Lisp_Object),
10053 ptrdiff_t a1, Lisp_Object a2)
10054 {
10055 Lisp_Object buffer;
10056 int this_one, the_other, clear_buffer_p, rc;
10057 ptrdiff_t count = SPECPDL_INDEX ();
10058
10059 /* If buffers aren't live, make new ones. */
10060 ensure_echo_area_buffers ();
10061
10062 clear_buffer_p = 0;
10063
10064 if (which == 0)
10065 this_one = 0, the_other = 1;
10066 else if (which > 0)
10067 this_one = 1, the_other = 0;
10068 else
10069 {
10070 this_one = 0, the_other = 1;
10071 clear_buffer_p = 1;
10072
10073 /* We need a fresh one in case the current echo buffer equals
10074 the one containing the last displayed echo area message. */
10075 if (!NILP (echo_area_buffer[this_one])
10076 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10077 echo_area_buffer[this_one] = Qnil;
10078 }
10079
10080 /* Choose a suitable buffer from echo_buffer[] is we don't
10081 have one. */
10082 if (NILP (echo_area_buffer[this_one]))
10083 {
10084 echo_area_buffer[this_one]
10085 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10086 ? echo_buffer[the_other]
10087 : echo_buffer[this_one]);
10088 clear_buffer_p = 1;
10089 }
10090
10091 buffer = echo_area_buffer[this_one];
10092
10093 /* Don't get confused by reusing the buffer used for echoing
10094 for a different purpose. */
10095 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10096 cancel_echoing ();
10097
10098 record_unwind_protect (unwind_with_echo_area_buffer,
10099 with_echo_area_buffer_unwind_data (w));
10100
10101 /* Make the echo area buffer current. Note that for display
10102 purposes, it is not necessary that the displayed window's buffer
10103 == current_buffer, except for text property lookup. So, let's
10104 only set that buffer temporarily here without doing a full
10105 Fset_window_buffer. We must also change w->pointm, though,
10106 because otherwise an assertions in unshow_buffer fails, and Emacs
10107 aborts. */
10108 set_buffer_internal_1 (XBUFFER (buffer));
10109 if (w)
10110 {
10111 wset_buffer (w, buffer);
10112 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10113 }
10114
10115 bset_undo_list (current_buffer, Qt);
10116 bset_read_only (current_buffer, Qnil);
10117 specbind (Qinhibit_read_only, Qt);
10118 specbind (Qinhibit_modification_hooks, Qt);
10119
10120 if (clear_buffer_p && Z > BEG)
10121 del_range (BEG, Z);
10122
10123 eassert (BEGV >= BEG);
10124 eassert (ZV <= Z && ZV >= BEGV);
10125
10126 rc = fn (a1, a2);
10127
10128 eassert (BEGV >= BEG);
10129 eassert (ZV <= Z && ZV >= BEGV);
10130
10131 unbind_to (count, Qnil);
10132 return rc;
10133 }
10134
10135
10136 /* Save state that should be preserved around the call to the function
10137 FN called in with_echo_area_buffer. */
10138
10139 static Lisp_Object
10140 with_echo_area_buffer_unwind_data (struct window *w)
10141 {
10142 int i = 0;
10143 Lisp_Object vector, tmp;
10144
10145 /* Reduce consing by keeping one vector in
10146 Vwith_echo_area_save_vector. */
10147 vector = Vwith_echo_area_save_vector;
10148 Vwith_echo_area_save_vector = Qnil;
10149
10150 if (NILP (vector))
10151 vector = Fmake_vector (make_number (9), Qnil);
10152
10153 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10154 ASET (vector, i, Vdeactivate_mark); ++i;
10155 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10156
10157 if (w)
10158 {
10159 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10160 ASET (vector, i, w->contents); ++i;
10161 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10162 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10163 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10164 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10165 }
10166 else
10167 {
10168 int end = i + 6;
10169 for (; i < end; ++i)
10170 ASET (vector, i, Qnil);
10171 }
10172
10173 eassert (i == ASIZE (vector));
10174 return vector;
10175 }
10176
10177
10178 /* Restore global state from VECTOR which was created by
10179 with_echo_area_buffer_unwind_data. */
10180
10181 static void
10182 unwind_with_echo_area_buffer (Lisp_Object vector)
10183 {
10184 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10185 Vdeactivate_mark = AREF (vector, 1);
10186 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10187
10188 if (WINDOWP (AREF (vector, 3)))
10189 {
10190 struct window *w;
10191 Lisp_Object buffer;
10192
10193 w = XWINDOW (AREF (vector, 3));
10194 buffer = AREF (vector, 4);
10195
10196 wset_buffer (w, buffer);
10197 set_marker_both (w->pointm, buffer,
10198 XFASTINT (AREF (vector, 5)),
10199 XFASTINT (AREF (vector, 6)));
10200 set_marker_both (w->start, buffer,
10201 XFASTINT (AREF (vector, 7)),
10202 XFASTINT (AREF (vector, 8)));
10203 }
10204
10205 Vwith_echo_area_save_vector = vector;
10206 }
10207
10208
10209 /* Set up the echo area for use by print functions. MULTIBYTE_P
10210 non-zero means we will print multibyte. */
10211
10212 void
10213 setup_echo_area_for_printing (int multibyte_p)
10214 {
10215 /* If we can't find an echo area any more, exit. */
10216 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10217 Fkill_emacs (Qnil);
10218
10219 ensure_echo_area_buffers ();
10220
10221 if (!message_buf_print)
10222 {
10223 /* A message has been output since the last time we printed.
10224 Choose a fresh echo area buffer. */
10225 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10226 echo_area_buffer[0] = echo_buffer[1];
10227 else
10228 echo_area_buffer[0] = echo_buffer[0];
10229
10230 /* Switch to that buffer and clear it. */
10231 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10232 bset_truncate_lines (current_buffer, Qnil);
10233
10234 if (Z > BEG)
10235 {
10236 ptrdiff_t count = SPECPDL_INDEX ();
10237 specbind (Qinhibit_read_only, Qt);
10238 /* Note that undo recording is always disabled. */
10239 del_range (BEG, Z);
10240 unbind_to (count, Qnil);
10241 }
10242 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10243
10244 /* Set up the buffer for the multibyteness we need. */
10245 if (multibyte_p
10246 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10247 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10248
10249 /* Raise the frame containing the echo area. */
10250 if (minibuffer_auto_raise)
10251 {
10252 struct frame *sf = SELECTED_FRAME ();
10253 Lisp_Object mini_window;
10254 mini_window = FRAME_MINIBUF_WINDOW (sf);
10255 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10256 }
10257
10258 message_log_maybe_newline ();
10259 message_buf_print = 1;
10260 }
10261 else
10262 {
10263 if (NILP (echo_area_buffer[0]))
10264 {
10265 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10266 echo_area_buffer[0] = echo_buffer[1];
10267 else
10268 echo_area_buffer[0] = echo_buffer[0];
10269 }
10270
10271 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10272 {
10273 /* Someone switched buffers between print requests. */
10274 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10275 bset_truncate_lines (current_buffer, Qnil);
10276 }
10277 }
10278 }
10279
10280
10281 /* Display an echo area message in window W. Value is non-zero if W's
10282 height is changed. If display_last_displayed_message_p is
10283 non-zero, display the message that was last displayed, otherwise
10284 display the current message. */
10285
10286 static int
10287 display_echo_area (struct window *w)
10288 {
10289 int i, no_message_p, window_height_changed_p;
10290
10291 /* Temporarily disable garbage collections while displaying the echo
10292 area. This is done because a GC can print a message itself.
10293 That message would modify the echo area buffer's contents while a
10294 redisplay of the buffer is going on, and seriously confuse
10295 redisplay. */
10296 ptrdiff_t count = inhibit_garbage_collection ();
10297
10298 /* If there is no message, we must call display_echo_area_1
10299 nevertheless because it resizes the window. But we will have to
10300 reset the echo_area_buffer in question to nil at the end because
10301 with_echo_area_buffer will sets it to an empty buffer. */
10302 i = display_last_displayed_message_p ? 1 : 0;
10303 no_message_p = NILP (echo_area_buffer[i]);
10304
10305 window_height_changed_p
10306 = with_echo_area_buffer (w, display_last_displayed_message_p,
10307 display_echo_area_1,
10308 (intptr_t) w, Qnil);
10309
10310 if (no_message_p)
10311 echo_area_buffer[i] = Qnil;
10312
10313 unbind_to (count, Qnil);
10314 return window_height_changed_p;
10315 }
10316
10317
10318 /* Helper for display_echo_area. Display the current buffer which
10319 contains the current echo area message in window W, a mini-window,
10320 a pointer to which is passed in A1. A2..A4 are currently not used.
10321 Change the height of W so that all of the message is displayed.
10322 Value is non-zero if height of W was changed. */
10323
10324 static int
10325 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10326 {
10327 intptr_t i1 = a1;
10328 struct window *w = (struct window *) i1;
10329 Lisp_Object window;
10330 struct text_pos start;
10331 int window_height_changed_p = 0;
10332
10333 /* Do this before displaying, so that we have a large enough glyph
10334 matrix for the display. If we can't get enough space for the
10335 whole text, display the last N lines. That works by setting w->start. */
10336 window_height_changed_p = resize_mini_window (w, 0);
10337
10338 /* Use the starting position chosen by resize_mini_window. */
10339 SET_TEXT_POS_FROM_MARKER (start, w->start);
10340
10341 /* Display. */
10342 clear_glyph_matrix (w->desired_matrix);
10343 XSETWINDOW (window, w);
10344 try_window (window, start, 0);
10345
10346 return window_height_changed_p;
10347 }
10348
10349
10350 /* Resize the echo area window to exactly the size needed for the
10351 currently displayed message, if there is one. If a mini-buffer
10352 is active, don't shrink it. */
10353
10354 void
10355 resize_echo_area_exactly (void)
10356 {
10357 if (BUFFERP (echo_area_buffer[0])
10358 && WINDOWP (echo_area_window))
10359 {
10360 struct window *w = XWINDOW (echo_area_window);
10361 int resized_p;
10362 Lisp_Object resize_exactly;
10363
10364 if (minibuf_level == 0)
10365 resize_exactly = Qt;
10366 else
10367 resize_exactly = Qnil;
10368
10369 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10370 (intptr_t) w, resize_exactly);
10371 if (resized_p)
10372 {
10373 ++windows_or_buffers_changed;
10374 ++update_mode_lines;
10375 redisplay_internal ();
10376 }
10377 }
10378 }
10379
10380
10381 /* Callback function for with_echo_area_buffer, when used from
10382 resize_echo_area_exactly. A1 contains a pointer to the window to
10383 resize, EXACTLY non-nil means resize the mini-window exactly to the
10384 size of the text displayed. A3 and A4 are not used. Value is what
10385 resize_mini_window returns. */
10386
10387 static int
10388 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10389 {
10390 intptr_t i1 = a1;
10391 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10392 }
10393
10394
10395 /* Resize mini-window W to fit the size of its contents. EXACT_P
10396 means size the window exactly to the size needed. Otherwise, it's
10397 only enlarged until W's buffer is empty.
10398
10399 Set W->start to the right place to begin display. If the whole
10400 contents fit, start at the beginning. Otherwise, start so as
10401 to make the end of the contents appear. This is particularly
10402 important for y-or-n-p, but seems desirable generally.
10403
10404 Value is non-zero if the window height has been changed. */
10405
10406 int
10407 resize_mini_window (struct window *w, int exact_p)
10408 {
10409 struct frame *f = XFRAME (w->frame);
10410 int window_height_changed_p = 0;
10411
10412 eassert (MINI_WINDOW_P (w));
10413
10414 /* By default, start display at the beginning. */
10415 set_marker_both (w->start, w->contents,
10416 BUF_BEGV (XBUFFER (w->contents)),
10417 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10418
10419 /* Don't resize windows while redisplaying a window; it would
10420 confuse redisplay functions when the size of the window they are
10421 displaying changes from under them. Such a resizing can happen,
10422 for instance, when which-func prints a long message while
10423 we are running fontification-functions. We're running these
10424 functions with safe_call which binds inhibit-redisplay to t. */
10425 if (!NILP (Vinhibit_redisplay))
10426 return 0;
10427
10428 /* Nil means don't try to resize. */
10429 if (NILP (Vresize_mini_windows)
10430 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10431 return 0;
10432
10433 if (!FRAME_MINIBUF_ONLY_P (f))
10434 {
10435 struct it it;
10436 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10437 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10438 int height;
10439 EMACS_INT max_height;
10440 int unit = FRAME_LINE_HEIGHT (f);
10441 struct text_pos start;
10442 struct buffer *old_current_buffer = NULL;
10443
10444 if (current_buffer != XBUFFER (w->contents))
10445 {
10446 old_current_buffer = current_buffer;
10447 set_buffer_internal (XBUFFER (w->contents));
10448 }
10449
10450 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10451
10452 /* Compute the max. number of lines specified by the user. */
10453 if (FLOATP (Vmax_mini_window_height))
10454 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10455 else if (INTEGERP (Vmax_mini_window_height))
10456 max_height = XINT (Vmax_mini_window_height);
10457 else
10458 max_height = total_height / 4;
10459
10460 /* Correct that max. height if it's bogus. */
10461 max_height = clip_to_bounds (1, max_height, total_height);
10462
10463 /* Find out the height of the text in the window. */
10464 if (it.line_wrap == TRUNCATE)
10465 height = 1;
10466 else
10467 {
10468 last_height = 0;
10469 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10470 if (it.max_ascent == 0 && it.max_descent == 0)
10471 height = it.current_y + last_height;
10472 else
10473 height = it.current_y + it.max_ascent + it.max_descent;
10474 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10475 height = (height + unit - 1) / unit;
10476 }
10477
10478 /* Compute a suitable window start. */
10479 if (height > max_height)
10480 {
10481 height = max_height;
10482 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10483 move_it_vertically_backward (&it, (height - 1) * unit);
10484 start = it.current.pos;
10485 }
10486 else
10487 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10488 SET_MARKER_FROM_TEXT_POS (w->start, start);
10489
10490 if (EQ (Vresize_mini_windows, Qgrow_only))
10491 {
10492 /* Let it grow only, until we display an empty message, in which
10493 case the window shrinks again. */
10494 if (height > WINDOW_TOTAL_LINES (w))
10495 {
10496 int old_height = WINDOW_TOTAL_LINES (w);
10497
10498 FRAME_WINDOWS_FROZEN (f) = 1;
10499 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10500 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10501 }
10502 else if (height < WINDOW_TOTAL_LINES (w)
10503 && (exact_p || BEGV == ZV))
10504 {
10505 int old_height = WINDOW_TOTAL_LINES (w);
10506
10507 FRAME_WINDOWS_FROZEN (f) = 0;
10508 shrink_mini_window (w);
10509 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10510 }
10511 }
10512 else
10513 {
10514 /* Always resize to exact size needed. */
10515 if (height > WINDOW_TOTAL_LINES (w))
10516 {
10517 int old_height = WINDOW_TOTAL_LINES (w);
10518
10519 FRAME_WINDOWS_FROZEN (f) = 1;
10520 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10521 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10522 }
10523 else if (height < WINDOW_TOTAL_LINES (w))
10524 {
10525 int old_height = WINDOW_TOTAL_LINES (w);
10526
10527 FRAME_WINDOWS_FROZEN (f) = 0;
10528 shrink_mini_window (w);
10529
10530 if (height)
10531 {
10532 FRAME_WINDOWS_FROZEN (f) = 1;
10533 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10534 }
10535
10536 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10537 }
10538 }
10539
10540 if (old_current_buffer)
10541 set_buffer_internal (old_current_buffer);
10542 }
10543
10544 return window_height_changed_p;
10545 }
10546
10547
10548 /* Value is the current message, a string, or nil if there is no
10549 current message. */
10550
10551 Lisp_Object
10552 current_message (void)
10553 {
10554 Lisp_Object msg;
10555
10556 if (!BUFFERP (echo_area_buffer[0]))
10557 msg = Qnil;
10558 else
10559 {
10560 with_echo_area_buffer (0, 0, current_message_1,
10561 (intptr_t) &msg, Qnil);
10562 if (NILP (msg))
10563 echo_area_buffer[0] = Qnil;
10564 }
10565
10566 return msg;
10567 }
10568
10569
10570 static int
10571 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10572 {
10573 intptr_t i1 = a1;
10574 Lisp_Object *msg = (Lisp_Object *) i1;
10575
10576 if (Z > BEG)
10577 *msg = make_buffer_string (BEG, Z, 1);
10578 else
10579 *msg = Qnil;
10580 return 0;
10581 }
10582
10583
10584 /* Push the current message on Vmessage_stack for later restoration
10585 by restore_message. Value is non-zero if the current message isn't
10586 empty. This is a relatively infrequent operation, so it's not
10587 worth optimizing. */
10588
10589 bool
10590 push_message (void)
10591 {
10592 Lisp_Object msg = current_message ();
10593 Vmessage_stack = Fcons (msg, Vmessage_stack);
10594 return STRINGP (msg);
10595 }
10596
10597
10598 /* Restore message display from the top of Vmessage_stack. */
10599
10600 void
10601 restore_message (void)
10602 {
10603 eassert (CONSP (Vmessage_stack));
10604 message3_nolog (XCAR (Vmessage_stack));
10605 }
10606
10607
10608 /* Handler for unwind-protect calling pop_message. */
10609
10610 void
10611 pop_message_unwind (void)
10612 {
10613 /* Pop the top-most entry off Vmessage_stack. */
10614 eassert (CONSP (Vmessage_stack));
10615 Vmessage_stack = XCDR (Vmessage_stack);
10616 }
10617
10618
10619 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10620 exits. If the stack is not empty, we have a missing pop_message
10621 somewhere. */
10622
10623 void
10624 check_message_stack (void)
10625 {
10626 if (!NILP (Vmessage_stack))
10627 emacs_abort ();
10628 }
10629
10630
10631 /* Truncate to NCHARS what will be displayed in the echo area the next
10632 time we display it---but don't redisplay it now. */
10633
10634 void
10635 truncate_echo_area (ptrdiff_t nchars)
10636 {
10637 if (nchars == 0)
10638 echo_area_buffer[0] = Qnil;
10639 else if (!noninteractive
10640 && INTERACTIVE
10641 && !NILP (echo_area_buffer[0]))
10642 {
10643 struct frame *sf = SELECTED_FRAME ();
10644 /* Error messages get reported properly by cmd_error, so this must be
10645 just an informative message; if the frame hasn't really been
10646 initialized yet, just toss it. */
10647 if (sf->glyphs_initialized_p)
10648 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10649 }
10650 }
10651
10652
10653 /* Helper function for truncate_echo_area. Truncate the current
10654 message to at most NCHARS characters. */
10655
10656 static int
10657 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10658 {
10659 if (BEG + nchars < Z)
10660 del_range (BEG + nchars, Z);
10661 if (Z == BEG)
10662 echo_area_buffer[0] = Qnil;
10663 return 0;
10664 }
10665
10666 /* Set the current message to STRING. */
10667
10668 static void
10669 set_message (Lisp_Object string)
10670 {
10671 eassert (STRINGP (string));
10672
10673 message_enable_multibyte = STRING_MULTIBYTE (string);
10674
10675 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10676 message_buf_print = 0;
10677 help_echo_showing_p = 0;
10678
10679 if (STRINGP (Vdebug_on_message)
10680 && STRINGP (string)
10681 && fast_string_match (Vdebug_on_message, string) >= 0)
10682 call_debugger (list2 (Qerror, string));
10683 }
10684
10685
10686 /* Helper function for set_message. First argument is ignored and second
10687 argument has the same meaning as for set_message.
10688 This function is called with the echo area buffer being current. */
10689
10690 static int
10691 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10692 {
10693 eassert (STRINGP (string));
10694
10695 /* Change multibyteness of the echo buffer appropriately. */
10696 if (message_enable_multibyte
10697 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10698 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10699
10700 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10701 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10702 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10703
10704 /* Insert new message at BEG. */
10705 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10706
10707 /* This function takes care of single/multibyte conversion.
10708 We just have to ensure that the echo area buffer has the right
10709 setting of enable_multibyte_characters. */
10710 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10711
10712 return 0;
10713 }
10714
10715
10716 /* Clear messages. CURRENT_P non-zero means clear the current
10717 message. LAST_DISPLAYED_P non-zero means clear the message
10718 last displayed. */
10719
10720 void
10721 clear_message (int current_p, int last_displayed_p)
10722 {
10723 if (current_p)
10724 {
10725 echo_area_buffer[0] = Qnil;
10726 message_cleared_p = 1;
10727 }
10728
10729 if (last_displayed_p)
10730 echo_area_buffer[1] = Qnil;
10731
10732 message_buf_print = 0;
10733 }
10734
10735 /* Clear garbaged frames.
10736
10737 This function is used where the old redisplay called
10738 redraw_garbaged_frames which in turn called redraw_frame which in
10739 turn called clear_frame. The call to clear_frame was a source of
10740 flickering. I believe a clear_frame is not necessary. It should
10741 suffice in the new redisplay to invalidate all current matrices,
10742 and ensure a complete redisplay of all windows. */
10743
10744 static void
10745 clear_garbaged_frames (void)
10746 {
10747 if (frame_garbaged)
10748 {
10749 Lisp_Object tail, frame;
10750 int changed_count = 0;
10751
10752 FOR_EACH_FRAME (tail, frame)
10753 {
10754 struct frame *f = XFRAME (frame);
10755
10756 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10757 {
10758 if (f->resized_p)
10759 {
10760 redraw_frame (f);
10761 f->force_flush_display_p = 1;
10762 }
10763 clear_current_matrices (f);
10764 changed_count++;
10765 f->garbaged = 0;
10766 f->resized_p = 0;
10767 }
10768 }
10769
10770 frame_garbaged = 0;
10771 if (changed_count)
10772 ++windows_or_buffers_changed;
10773 }
10774 }
10775
10776
10777 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10778 is non-zero update selected_frame. Value is non-zero if the
10779 mini-windows height has been changed. */
10780
10781 static int
10782 echo_area_display (int update_frame_p)
10783 {
10784 Lisp_Object mini_window;
10785 struct window *w;
10786 struct frame *f;
10787 int window_height_changed_p = 0;
10788 struct frame *sf = SELECTED_FRAME ();
10789
10790 mini_window = FRAME_MINIBUF_WINDOW (sf);
10791 w = XWINDOW (mini_window);
10792 f = XFRAME (WINDOW_FRAME (w));
10793
10794 /* Don't display if frame is invisible or not yet initialized. */
10795 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10796 return 0;
10797
10798 #ifdef HAVE_WINDOW_SYSTEM
10799 /* When Emacs starts, selected_frame may be the initial terminal
10800 frame. If we let this through, a message would be displayed on
10801 the terminal. */
10802 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10803 return 0;
10804 #endif /* HAVE_WINDOW_SYSTEM */
10805
10806 /* Redraw garbaged frames. */
10807 clear_garbaged_frames ();
10808
10809 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10810 {
10811 echo_area_window = mini_window;
10812 window_height_changed_p = display_echo_area (w);
10813 w->must_be_updated_p = 1;
10814
10815 /* Update the display, unless called from redisplay_internal.
10816 Also don't update the screen during redisplay itself. The
10817 update will happen at the end of redisplay, and an update
10818 here could cause confusion. */
10819 if (update_frame_p && !redisplaying_p)
10820 {
10821 int n = 0;
10822
10823 /* If the display update has been interrupted by pending
10824 input, update mode lines in the frame. Due to the
10825 pending input, it might have been that redisplay hasn't
10826 been called, so that mode lines above the echo area are
10827 garbaged. This looks odd, so we prevent it here. */
10828 if (!display_completed)
10829 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10830
10831 if (window_height_changed_p
10832 /* Don't do this if Emacs is shutting down. Redisplay
10833 needs to run hooks. */
10834 && !NILP (Vrun_hooks))
10835 {
10836 /* Must update other windows. Likewise as in other
10837 cases, don't let this update be interrupted by
10838 pending input. */
10839 ptrdiff_t count = SPECPDL_INDEX ();
10840 specbind (Qredisplay_dont_pause, Qt);
10841 windows_or_buffers_changed = 1;
10842 redisplay_internal ();
10843 unbind_to (count, Qnil);
10844 }
10845 else if (FRAME_WINDOW_P (f) && n == 0)
10846 {
10847 /* Window configuration is the same as before.
10848 Can do with a display update of the echo area,
10849 unless we displayed some mode lines. */
10850 update_single_window (w, 1);
10851 FRAME_RIF (f)->flush_display (f);
10852 }
10853 else
10854 update_frame (f, 1, 1);
10855
10856 /* If cursor is in the echo area, make sure that the next
10857 redisplay displays the minibuffer, so that the cursor will
10858 be replaced with what the minibuffer wants. */
10859 if (cursor_in_echo_area)
10860 ++windows_or_buffers_changed;
10861 }
10862 }
10863 else if (!EQ (mini_window, selected_window))
10864 windows_or_buffers_changed++;
10865
10866 /* Last displayed message is now the current message. */
10867 echo_area_buffer[1] = echo_area_buffer[0];
10868 /* Inform read_char that we're not echoing. */
10869 echo_message_buffer = Qnil;
10870
10871 /* Prevent redisplay optimization in redisplay_internal by resetting
10872 this_line_start_pos. This is done because the mini-buffer now
10873 displays the message instead of its buffer text. */
10874 if (EQ (mini_window, selected_window))
10875 CHARPOS (this_line_start_pos) = 0;
10876
10877 return window_height_changed_p;
10878 }
10879
10880 /* Nonzero if the current window's buffer is shown in more than one
10881 window and was modified since last redisplay. */
10882
10883 static int
10884 buffer_shared_and_changed (void)
10885 {
10886 return (buffer_window_count (current_buffer) > 1
10887 && UNCHANGED_MODIFIED < MODIFF);
10888 }
10889
10890 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10891 is enabled and mark of W's buffer was changed since last W's update. */
10892
10893 static int
10894 window_buffer_changed (struct window *w)
10895 {
10896 struct buffer *b = XBUFFER (w->contents);
10897
10898 eassert (BUFFER_LIVE_P (b));
10899
10900 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10901 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10902 != (w->region_showing != 0)));
10903 }
10904
10905 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10906
10907 static int
10908 mode_line_update_needed (struct window *w)
10909 {
10910 return (w->column_number_displayed != -1
10911 && !(PT == w->last_point && !window_outdated (w))
10912 && (w->column_number_displayed != current_column ()));
10913 }
10914
10915 /* Nonzero if window start of W is frozen and may not be changed during
10916 redisplay. */
10917
10918 static bool
10919 window_frozen_p (struct window *w)
10920 {
10921 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
10922 {
10923 Lisp_Object window;
10924
10925 XSETWINDOW (window, w);
10926 if (MINI_WINDOW_P (w))
10927 return 0;
10928 else if (EQ (window, selected_window))
10929 return 0;
10930 else if (MINI_WINDOW_P (XWINDOW (selected_window))
10931 && EQ (window, Vminibuf_scroll_window))
10932 /* This special window can't be frozen too. */
10933 return 0;
10934 else
10935 return 1;
10936 }
10937 return 0;
10938 }
10939
10940 /***********************************************************************
10941 Mode Lines and Frame Titles
10942 ***********************************************************************/
10943
10944 /* A buffer for constructing non-propertized mode-line strings and
10945 frame titles in it; allocated from the heap in init_xdisp and
10946 resized as needed in store_mode_line_noprop_char. */
10947
10948 static char *mode_line_noprop_buf;
10949
10950 /* The buffer's end, and a current output position in it. */
10951
10952 static char *mode_line_noprop_buf_end;
10953 static char *mode_line_noprop_ptr;
10954
10955 #define MODE_LINE_NOPROP_LEN(start) \
10956 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10957
10958 static enum {
10959 MODE_LINE_DISPLAY = 0,
10960 MODE_LINE_TITLE,
10961 MODE_LINE_NOPROP,
10962 MODE_LINE_STRING
10963 } mode_line_target;
10964
10965 /* Alist that caches the results of :propertize.
10966 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10967 static Lisp_Object mode_line_proptrans_alist;
10968
10969 /* List of strings making up the mode-line. */
10970 static Lisp_Object mode_line_string_list;
10971
10972 /* Base face property when building propertized mode line string. */
10973 static Lisp_Object mode_line_string_face;
10974 static Lisp_Object mode_line_string_face_prop;
10975
10976
10977 /* Unwind data for mode line strings */
10978
10979 static Lisp_Object Vmode_line_unwind_vector;
10980
10981 static Lisp_Object
10982 format_mode_line_unwind_data (struct frame *target_frame,
10983 struct buffer *obuf,
10984 Lisp_Object owin,
10985 int save_proptrans)
10986 {
10987 Lisp_Object vector, tmp;
10988
10989 /* Reduce consing by keeping one vector in
10990 Vwith_echo_area_save_vector. */
10991 vector = Vmode_line_unwind_vector;
10992 Vmode_line_unwind_vector = Qnil;
10993
10994 if (NILP (vector))
10995 vector = Fmake_vector (make_number (10), Qnil);
10996
10997 ASET (vector, 0, make_number (mode_line_target));
10998 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10999 ASET (vector, 2, mode_line_string_list);
11000 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11001 ASET (vector, 4, mode_line_string_face);
11002 ASET (vector, 5, mode_line_string_face_prop);
11003
11004 if (obuf)
11005 XSETBUFFER (tmp, obuf);
11006 else
11007 tmp = Qnil;
11008 ASET (vector, 6, tmp);
11009 ASET (vector, 7, owin);
11010 if (target_frame)
11011 {
11012 /* Similarly to `with-selected-window', if the operation selects
11013 a window on another frame, we must restore that frame's
11014 selected window, and (for a tty) the top-frame. */
11015 ASET (vector, 8, target_frame->selected_window);
11016 if (FRAME_TERMCAP_P (target_frame))
11017 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11018 }
11019
11020 return vector;
11021 }
11022
11023 static void
11024 unwind_format_mode_line (Lisp_Object vector)
11025 {
11026 Lisp_Object old_window = AREF (vector, 7);
11027 Lisp_Object target_frame_window = AREF (vector, 8);
11028 Lisp_Object old_top_frame = AREF (vector, 9);
11029
11030 mode_line_target = XINT (AREF (vector, 0));
11031 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11032 mode_line_string_list = AREF (vector, 2);
11033 if (! EQ (AREF (vector, 3), Qt))
11034 mode_line_proptrans_alist = AREF (vector, 3);
11035 mode_line_string_face = AREF (vector, 4);
11036 mode_line_string_face_prop = AREF (vector, 5);
11037
11038 /* Select window before buffer, since it may change the buffer. */
11039 if (!NILP (old_window))
11040 {
11041 /* If the operation that we are unwinding had selected a window
11042 on a different frame, reset its frame-selected-window. For a
11043 text terminal, reset its top-frame if necessary. */
11044 if (!NILP (target_frame_window))
11045 {
11046 Lisp_Object frame
11047 = WINDOW_FRAME (XWINDOW (target_frame_window));
11048
11049 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11050 Fselect_window (target_frame_window, Qt);
11051
11052 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11053 Fselect_frame (old_top_frame, Qt);
11054 }
11055
11056 Fselect_window (old_window, Qt);
11057 }
11058
11059 if (!NILP (AREF (vector, 6)))
11060 {
11061 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11062 ASET (vector, 6, Qnil);
11063 }
11064
11065 Vmode_line_unwind_vector = vector;
11066 }
11067
11068
11069 /* Store a single character C for the frame title in mode_line_noprop_buf.
11070 Re-allocate mode_line_noprop_buf if necessary. */
11071
11072 static void
11073 store_mode_line_noprop_char (char c)
11074 {
11075 /* If output position has reached the end of the allocated buffer,
11076 increase the buffer's size. */
11077 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11078 {
11079 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11080 ptrdiff_t size = len;
11081 mode_line_noprop_buf =
11082 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11083 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11084 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11085 }
11086
11087 *mode_line_noprop_ptr++ = c;
11088 }
11089
11090
11091 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11092 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11093 characters that yield more columns than PRECISION; PRECISION <= 0
11094 means copy the whole string. Pad with spaces until FIELD_WIDTH
11095 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11096 pad. Called from display_mode_element when it is used to build a
11097 frame title. */
11098
11099 static int
11100 store_mode_line_noprop (const char *string, int field_width, int precision)
11101 {
11102 const unsigned char *str = (const unsigned char *) string;
11103 int n = 0;
11104 ptrdiff_t dummy, nbytes;
11105
11106 /* Copy at most PRECISION chars from STR. */
11107 nbytes = strlen (string);
11108 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11109 while (nbytes--)
11110 store_mode_line_noprop_char (*str++);
11111
11112 /* Fill up with spaces until FIELD_WIDTH reached. */
11113 while (field_width > 0
11114 && n < field_width)
11115 {
11116 store_mode_line_noprop_char (' ');
11117 ++n;
11118 }
11119
11120 return n;
11121 }
11122
11123 /***********************************************************************
11124 Frame Titles
11125 ***********************************************************************/
11126
11127 #ifdef HAVE_WINDOW_SYSTEM
11128
11129 /* Set the title of FRAME, if it has changed. The title format is
11130 Vicon_title_format if FRAME is iconified, otherwise it is
11131 frame_title_format. */
11132
11133 static void
11134 x_consider_frame_title (Lisp_Object frame)
11135 {
11136 struct frame *f = XFRAME (frame);
11137
11138 if (FRAME_WINDOW_P (f)
11139 || FRAME_MINIBUF_ONLY_P (f)
11140 || f->explicit_name)
11141 {
11142 /* Do we have more than one visible frame on this X display? */
11143 Lisp_Object tail, other_frame, fmt;
11144 ptrdiff_t title_start;
11145 char *title;
11146 ptrdiff_t len;
11147 struct it it;
11148 ptrdiff_t count = SPECPDL_INDEX ();
11149
11150 FOR_EACH_FRAME (tail, other_frame)
11151 {
11152 struct frame *tf = XFRAME (other_frame);
11153
11154 if (tf != f
11155 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11156 && !FRAME_MINIBUF_ONLY_P (tf)
11157 && !EQ (other_frame, tip_frame)
11158 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11159 break;
11160 }
11161
11162 /* Set global variable indicating that multiple frames exist. */
11163 multiple_frames = CONSP (tail);
11164
11165 /* Switch to the buffer of selected window of the frame. Set up
11166 mode_line_target so that display_mode_element will output into
11167 mode_line_noprop_buf; then display the title. */
11168 record_unwind_protect (unwind_format_mode_line,
11169 format_mode_line_unwind_data
11170 (f, current_buffer, selected_window, 0));
11171
11172 Fselect_window (f->selected_window, Qt);
11173 set_buffer_internal_1
11174 (XBUFFER (XWINDOW (f->selected_window)->contents));
11175 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11176
11177 mode_line_target = MODE_LINE_TITLE;
11178 title_start = MODE_LINE_NOPROP_LEN (0);
11179 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11180 NULL, DEFAULT_FACE_ID);
11181 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11182 len = MODE_LINE_NOPROP_LEN (title_start);
11183 title = mode_line_noprop_buf + title_start;
11184 unbind_to (count, Qnil);
11185
11186 /* Set the title only if it's changed. This avoids consing in
11187 the common case where it hasn't. (If it turns out that we've
11188 already wasted too much time by walking through the list with
11189 display_mode_element, then we might need to optimize at a
11190 higher level than this.) */
11191 if (! STRINGP (f->name)
11192 || SBYTES (f->name) != len
11193 || memcmp (title, SDATA (f->name), len) != 0)
11194 x_implicitly_set_name (f, make_string (title, len), Qnil);
11195 }
11196 }
11197
11198 #endif /* not HAVE_WINDOW_SYSTEM */
11199
11200 \f
11201 /***********************************************************************
11202 Menu Bars
11203 ***********************************************************************/
11204
11205
11206 /* Prepare for redisplay by updating menu-bar item lists when
11207 appropriate. This can call eval. */
11208
11209 void
11210 prepare_menu_bars (void)
11211 {
11212 int all_windows;
11213 struct gcpro gcpro1, gcpro2;
11214 struct frame *f;
11215 Lisp_Object tooltip_frame;
11216
11217 #ifdef HAVE_WINDOW_SYSTEM
11218 tooltip_frame = tip_frame;
11219 #else
11220 tooltip_frame = Qnil;
11221 #endif
11222
11223 /* Update all frame titles based on their buffer names, etc. We do
11224 this before the menu bars so that the buffer-menu will show the
11225 up-to-date frame titles. */
11226 #ifdef HAVE_WINDOW_SYSTEM
11227 if (windows_or_buffers_changed || update_mode_lines)
11228 {
11229 Lisp_Object tail, frame;
11230
11231 FOR_EACH_FRAME (tail, frame)
11232 {
11233 f = XFRAME (frame);
11234 if (!EQ (frame, tooltip_frame)
11235 && (FRAME_ICONIFIED_P (f)
11236 || FRAME_VISIBLE_P (f) == 1
11237 /* Exclude TTY frames that are obscured because they
11238 are not the top frame on their console. This is
11239 because x_consider_frame_title actually switches
11240 to the frame, which for TTY frames means it is
11241 marked as garbaged, and will be completely
11242 redrawn on the next redisplay cycle. This causes
11243 TTY frames to be completely redrawn, when there
11244 are more than one of them, even though nothing
11245 should be changed on display. */
11246 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11247 x_consider_frame_title (frame);
11248 }
11249 }
11250 #endif /* HAVE_WINDOW_SYSTEM */
11251
11252 /* Update the menu bar item lists, if appropriate. This has to be
11253 done before any actual redisplay or generation of display lines. */
11254 all_windows = (update_mode_lines
11255 || buffer_shared_and_changed ()
11256 || windows_or_buffers_changed);
11257 if (all_windows)
11258 {
11259 Lisp_Object tail, frame;
11260 ptrdiff_t count = SPECPDL_INDEX ();
11261 /* 1 means that update_menu_bar has run its hooks
11262 so any further calls to update_menu_bar shouldn't do so again. */
11263 int menu_bar_hooks_run = 0;
11264
11265 record_unwind_save_match_data ();
11266
11267 FOR_EACH_FRAME (tail, frame)
11268 {
11269 f = XFRAME (frame);
11270
11271 /* Ignore tooltip frame. */
11272 if (EQ (frame, tooltip_frame))
11273 continue;
11274
11275 /* If a window on this frame changed size, report that to
11276 the user and clear the size-change flag. */
11277 if (FRAME_WINDOW_SIZES_CHANGED (f))
11278 {
11279 Lisp_Object functions;
11280
11281 /* Clear flag first in case we get an error below. */
11282 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11283 functions = Vwindow_size_change_functions;
11284 GCPRO2 (tail, functions);
11285
11286 while (CONSP (functions))
11287 {
11288 if (!EQ (XCAR (functions), Qt))
11289 call1 (XCAR (functions), frame);
11290 functions = XCDR (functions);
11291 }
11292 UNGCPRO;
11293 }
11294
11295 GCPRO1 (tail);
11296 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11297 #ifdef HAVE_WINDOW_SYSTEM
11298 update_tool_bar (f, 0);
11299 #endif
11300 #ifdef HAVE_NS
11301 if (windows_or_buffers_changed
11302 && FRAME_NS_P (f))
11303 ns_set_doc_edited
11304 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11305 #endif
11306 UNGCPRO;
11307 }
11308
11309 unbind_to (count, Qnil);
11310 }
11311 else
11312 {
11313 struct frame *sf = SELECTED_FRAME ();
11314 update_menu_bar (sf, 1, 0);
11315 #ifdef HAVE_WINDOW_SYSTEM
11316 update_tool_bar (sf, 1);
11317 #endif
11318 }
11319 }
11320
11321
11322 /* Update the menu bar item list for frame F. This has to be done
11323 before we start to fill in any display lines, because it can call
11324 eval.
11325
11326 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11327
11328 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11329 already ran the menu bar hooks for this redisplay, so there
11330 is no need to run them again. The return value is the
11331 updated value of this flag, to pass to the next call. */
11332
11333 static int
11334 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11335 {
11336 Lisp_Object window;
11337 register struct window *w;
11338
11339 /* If called recursively during a menu update, do nothing. This can
11340 happen when, for instance, an activate-menubar-hook causes a
11341 redisplay. */
11342 if (inhibit_menubar_update)
11343 return hooks_run;
11344
11345 window = FRAME_SELECTED_WINDOW (f);
11346 w = XWINDOW (window);
11347
11348 if (FRAME_WINDOW_P (f)
11349 ?
11350 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11351 || defined (HAVE_NS) || defined (USE_GTK)
11352 FRAME_EXTERNAL_MENU_BAR (f)
11353 #else
11354 FRAME_MENU_BAR_LINES (f) > 0
11355 #endif
11356 : FRAME_MENU_BAR_LINES (f) > 0)
11357 {
11358 /* If the user has switched buffers or windows, we need to
11359 recompute to reflect the new bindings. But we'll
11360 recompute when update_mode_lines is set too; that means
11361 that people can use force-mode-line-update to request
11362 that the menu bar be recomputed. The adverse effect on
11363 the rest of the redisplay algorithm is about the same as
11364 windows_or_buffers_changed anyway. */
11365 if (windows_or_buffers_changed
11366 /* This used to test w->update_mode_line, but we believe
11367 there is no need to recompute the menu in that case. */
11368 || update_mode_lines
11369 || window_buffer_changed (w))
11370 {
11371 struct buffer *prev = current_buffer;
11372 ptrdiff_t count = SPECPDL_INDEX ();
11373
11374 specbind (Qinhibit_menubar_update, Qt);
11375
11376 set_buffer_internal_1 (XBUFFER (w->contents));
11377 if (save_match_data)
11378 record_unwind_save_match_data ();
11379 if (NILP (Voverriding_local_map_menu_flag))
11380 {
11381 specbind (Qoverriding_terminal_local_map, Qnil);
11382 specbind (Qoverriding_local_map, Qnil);
11383 }
11384
11385 if (!hooks_run)
11386 {
11387 /* Run the Lucid hook. */
11388 safe_run_hooks (Qactivate_menubar_hook);
11389
11390 /* If it has changed current-menubar from previous value,
11391 really recompute the menu-bar from the value. */
11392 if (! NILP (Vlucid_menu_bar_dirty_flag))
11393 call0 (Qrecompute_lucid_menubar);
11394
11395 safe_run_hooks (Qmenu_bar_update_hook);
11396
11397 hooks_run = 1;
11398 }
11399
11400 XSETFRAME (Vmenu_updating_frame, f);
11401 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11402
11403 /* Redisplay the menu bar in case we changed it. */
11404 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11405 || defined (HAVE_NS) || defined (USE_GTK)
11406 if (FRAME_WINDOW_P (f))
11407 {
11408 #if defined (HAVE_NS)
11409 /* All frames on Mac OS share the same menubar. So only
11410 the selected frame should be allowed to set it. */
11411 if (f == SELECTED_FRAME ())
11412 #endif
11413 set_frame_menubar (f, 0, 0);
11414 }
11415 else
11416 /* On a terminal screen, the menu bar is an ordinary screen
11417 line, and this makes it get updated. */
11418 w->update_mode_line = 1;
11419 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11420 /* In the non-toolkit version, the menu bar is an ordinary screen
11421 line, and this makes it get updated. */
11422 w->update_mode_line = 1;
11423 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11424
11425 unbind_to (count, Qnil);
11426 set_buffer_internal_1 (prev);
11427 }
11428 }
11429
11430 return hooks_run;
11431 }
11432
11433 /***********************************************************************
11434 Tool-bars
11435 ***********************************************************************/
11436
11437 #ifdef HAVE_WINDOW_SYSTEM
11438
11439 /* Where the mouse was last time we reported a mouse event. */
11440
11441 struct frame *last_mouse_frame;
11442
11443 /* Tool-bar item index of the item on which a mouse button was pressed
11444 or -1. */
11445
11446 int last_tool_bar_item;
11447
11448 /* Select `frame' temporarily without running all the code in
11449 do_switch_frame.
11450 FIXME: Maybe do_switch_frame should be trimmed down similarly
11451 when `norecord' is set. */
11452 static void
11453 fast_set_selected_frame (Lisp_Object frame)
11454 {
11455 if (!EQ (selected_frame, frame))
11456 {
11457 selected_frame = frame;
11458 selected_window = XFRAME (frame)->selected_window;
11459 }
11460 }
11461
11462 /* Update the tool-bar item list for frame F. This has to be done
11463 before we start to fill in any display lines. Called from
11464 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11465 and restore it here. */
11466
11467 static void
11468 update_tool_bar (struct frame *f, int save_match_data)
11469 {
11470 #if defined (USE_GTK) || defined (HAVE_NS)
11471 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11472 #else
11473 int do_update = WINDOWP (f->tool_bar_window)
11474 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11475 #endif
11476
11477 if (do_update)
11478 {
11479 Lisp_Object window;
11480 struct window *w;
11481
11482 window = FRAME_SELECTED_WINDOW (f);
11483 w = XWINDOW (window);
11484
11485 /* If the user has switched buffers or windows, we need to
11486 recompute to reflect the new bindings. But we'll
11487 recompute when update_mode_lines is set too; that means
11488 that people can use force-mode-line-update to request
11489 that the menu bar be recomputed. The adverse effect on
11490 the rest of the redisplay algorithm is about the same as
11491 windows_or_buffers_changed anyway. */
11492 if (windows_or_buffers_changed
11493 || w->update_mode_line
11494 || update_mode_lines
11495 || window_buffer_changed (w))
11496 {
11497 struct buffer *prev = current_buffer;
11498 ptrdiff_t count = SPECPDL_INDEX ();
11499 Lisp_Object frame, new_tool_bar;
11500 int new_n_tool_bar;
11501 struct gcpro gcpro1;
11502
11503 /* Set current_buffer to the buffer of the selected
11504 window of the frame, so that we get the right local
11505 keymaps. */
11506 set_buffer_internal_1 (XBUFFER (w->contents));
11507
11508 /* Save match data, if we must. */
11509 if (save_match_data)
11510 record_unwind_save_match_data ();
11511
11512 /* Make sure that we don't accidentally use bogus keymaps. */
11513 if (NILP (Voverriding_local_map_menu_flag))
11514 {
11515 specbind (Qoverriding_terminal_local_map, Qnil);
11516 specbind (Qoverriding_local_map, Qnil);
11517 }
11518
11519 GCPRO1 (new_tool_bar);
11520
11521 /* We must temporarily set the selected frame to this frame
11522 before calling tool_bar_items, because the calculation of
11523 the tool-bar keymap uses the selected frame (see
11524 `tool-bar-make-keymap' in tool-bar.el). */
11525 eassert (EQ (selected_window,
11526 /* Since we only explicitly preserve selected_frame,
11527 check that selected_window would be redundant. */
11528 XFRAME (selected_frame)->selected_window));
11529 record_unwind_protect (fast_set_selected_frame, selected_frame);
11530 XSETFRAME (frame, f);
11531 fast_set_selected_frame (frame);
11532
11533 /* Build desired tool-bar items from keymaps. */
11534 new_tool_bar
11535 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11536 &new_n_tool_bar);
11537
11538 /* Redisplay the tool-bar if we changed it. */
11539 if (new_n_tool_bar != f->n_tool_bar_items
11540 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11541 {
11542 /* Redisplay that happens asynchronously due to an expose event
11543 may access f->tool_bar_items. Make sure we update both
11544 variables within BLOCK_INPUT so no such event interrupts. */
11545 block_input ();
11546 fset_tool_bar_items (f, new_tool_bar);
11547 f->n_tool_bar_items = new_n_tool_bar;
11548 w->update_mode_line = 1;
11549 unblock_input ();
11550 }
11551
11552 UNGCPRO;
11553
11554 unbind_to (count, Qnil);
11555 set_buffer_internal_1 (prev);
11556 }
11557 }
11558 }
11559
11560
11561 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11562 F's desired tool-bar contents. F->tool_bar_items must have
11563 been set up previously by calling prepare_menu_bars. */
11564
11565 static void
11566 build_desired_tool_bar_string (struct frame *f)
11567 {
11568 int i, size, size_needed;
11569 struct gcpro gcpro1, gcpro2, gcpro3;
11570 Lisp_Object image, plist, props;
11571
11572 image = plist = props = Qnil;
11573 GCPRO3 (image, plist, props);
11574
11575 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11576 Otherwise, make a new string. */
11577
11578 /* The size of the string we might be able to reuse. */
11579 size = (STRINGP (f->desired_tool_bar_string)
11580 ? SCHARS (f->desired_tool_bar_string)
11581 : 0);
11582
11583 /* We need one space in the string for each image. */
11584 size_needed = f->n_tool_bar_items;
11585
11586 /* Reuse f->desired_tool_bar_string, if possible. */
11587 if (size < size_needed || NILP (f->desired_tool_bar_string))
11588 fset_desired_tool_bar_string
11589 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11590 else
11591 {
11592 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11593 Fremove_text_properties (make_number (0), make_number (size),
11594 props, f->desired_tool_bar_string);
11595 }
11596
11597 /* Put a `display' property on the string for the images to display,
11598 put a `menu_item' property on tool-bar items with a value that
11599 is the index of the item in F's tool-bar item vector. */
11600 for (i = 0; i < f->n_tool_bar_items; ++i)
11601 {
11602 #define PROP(IDX) \
11603 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11604
11605 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11606 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11607 int hmargin, vmargin, relief, idx, end;
11608
11609 /* If image is a vector, choose the image according to the
11610 button state. */
11611 image = PROP (TOOL_BAR_ITEM_IMAGES);
11612 if (VECTORP (image))
11613 {
11614 if (enabled_p)
11615 idx = (selected_p
11616 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11617 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11618 else
11619 idx = (selected_p
11620 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11621 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11622
11623 eassert (ASIZE (image) >= idx);
11624 image = AREF (image, idx);
11625 }
11626 else
11627 idx = -1;
11628
11629 /* Ignore invalid image specifications. */
11630 if (!valid_image_p (image))
11631 continue;
11632
11633 /* Display the tool-bar button pressed, or depressed. */
11634 plist = Fcopy_sequence (XCDR (image));
11635
11636 /* Compute margin and relief to draw. */
11637 relief = (tool_bar_button_relief >= 0
11638 ? tool_bar_button_relief
11639 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11640 hmargin = vmargin = relief;
11641
11642 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11643 INT_MAX - max (hmargin, vmargin)))
11644 {
11645 hmargin += XFASTINT (Vtool_bar_button_margin);
11646 vmargin += XFASTINT (Vtool_bar_button_margin);
11647 }
11648 else if (CONSP (Vtool_bar_button_margin))
11649 {
11650 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11651 INT_MAX - hmargin))
11652 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11653
11654 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11655 INT_MAX - vmargin))
11656 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11657 }
11658
11659 if (auto_raise_tool_bar_buttons_p)
11660 {
11661 /* Add a `:relief' property to the image spec if the item is
11662 selected. */
11663 if (selected_p)
11664 {
11665 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11666 hmargin -= relief;
11667 vmargin -= relief;
11668 }
11669 }
11670 else
11671 {
11672 /* If image is selected, display it pressed, i.e. with a
11673 negative relief. If it's not selected, display it with a
11674 raised relief. */
11675 plist = Fplist_put (plist, QCrelief,
11676 (selected_p
11677 ? make_number (-relief)
11678 : make_number (relief)));
11679 hmargin -= relief;
11680 vmargin -= relief;
11681 }
11682
11683 /* Put a margin around the image. */
11684 if (hmargin || vmargin)
11685 {
11686 if (hmargin == vmargin)
11687 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11688 else
11689 plist = Fplist_put (plist, QCmargin,
11690 Fcons (make_number (hmargin),
11691 make_number (vmargin)));
11692 }
11693
11694 /* If button is not enabled, and we don't have special images
11695 for the disabled state, make the image appear disabled by
11696 applying an appropriate algorithm to it. */
11697 if (!enabled_p && idx < 0)
11698 plist = Fplist_put (plist, QCconversion, Qdisabled);
11699
11700 /* Put a `display' text property on the string for the image to
11701 display. Put a `menu-item' property on the string that gives
11702 the start of this item's properties in the tool-bar items
11703 vector. */
11704 image = Fcons (Qimage, plist);
11705 props = list4 (Qdisplay, image,
11706 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11707
11708 /* Let the last image hide all remaining spaces in the tool bar
11709 string. The string can be longer than needed when we reuse a
11710 previous string. */
11711 if (i + 1 == f->n_tool_bar_items)
11712 end = SCHARS (f->desired_tool_bar_string);
11713 else
11714 end = i + 1;
11715 Fadd_text_properties (make_number (i), make_number (end),
11716 props, f->desired_tool_bar_string);
11717 #undef PROP
11718 }
11719
11720 UNGCPRO;
11721 }
11722
11723
11724 /* Display one line of the tool-bar of frame IT->f.
11725
11726 HEIGHT specifies the desired height of the tool-bar line.
11727 If the actual height of the glyph row is less than HEIGHT, the
11728 row's height is increased to HEIGHT, and the icons are centered
11729 vertically in the new height.
11730
11731 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11732 count a final empty row in case the tool-bar width exactly matches
11733 the window width.
11734 */
11735
11736 static void
11737 display_tool_bar_line (struct it *it, int height)
11738 {
11739 struct glyph_row *row = it->glyph_row;
11740 int max_x = it->last_visible_x;
11741 struct glyph *last;
11742
11743 prepare_desired_row (row);
11744 row->y = it->current_y;
11745
11746 /* Note that this isn't made use of if the face hasn't a box,
11747 so there's no need to check the face here. */
11748 it->start_of_box_run_p = 1;
11749
11750 while (it->current_x < max_x)
11751 {
11752 int x, n_glyphs_before, i, nglyphs;
11753 struct it it_before;
11754
11755 /* Get the next display element. */
11756 if (!get_next_display_element (it))
11757 {
11758 /* Don't count empty row if we are counting needed tool-bar lines. */
11759 if (height < 0 && !it->hpos)
11760 return;
11761 break;
11762 }
11763
11764 /* Produce glyphs. */
11765 n_glyphs_before = row->used[TEXT_AREA];
11766 it_before = *it;
11767
11768 PRODUCE_GLYPHS (it);
11769
11770 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11771 i = 0;
11772 x = it_before.current_x;
11773 while (i < nglyphs)
11774 {
11775 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11776
11777 if (x + glyph->pixel_width > max_x)
11778 {
11779 /* Glyph doesn't fit on line. Backtrack. */
11780 row->used[TEXT_AREA] = n_glyphs_before;
11781 *it = it_before;
11782 /* If this is the only glyph on this line, it will never fit on the
11783 tool-bar, so skip it. But ensure there is at least one glyph,
11784 so we don't accidentally disable the tool-bar. */
11785 if (n_glyphs_before == 0
11786 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11787 break;
11788 goto out;
11789 }
11790
11791 ++it->hpos;
11792 x += glyph->pixel_width;
11793 ++i;
11794 }
11795
11796 /* Stop at line end. */
11797 if (ITERATOR_AT_END_OF_LINE_P (it))
11798 break;
11799
11800 set_iterator_to_next (it, 1);
11801 }
11802
11803 out:;
11804
11805 row->displays_text_p = row->used[TEXT_AREA] != 0;
11806
11807 /* Use default face for the border below the tool bar.
11808
11809 FIXME: When auto-resize-tool-bars is grow-only, there is
11810 no additional border below the possibly empty tool-bar lines.
11811 So to make the extra empty lines look "normal", we have to
11812 use the tool-bar face for the border too. */
11813 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11814 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11815 it->face_id = DEFAULT_FACE_ID;
11816
11817 extend_face_to_end_of_line (it);
11818 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11819 last->right_box_line_p = 1;
11820 if (last == row->glyphs[TEXT_AREA])
11821 last->left_box_line_p = 1;
11822
11823 /* Make line the desired height and center it vertically. */
11824 if ((height -= it->max_ascent + it->max_descent) > 0)
11825 {
11826 /* Don't add more than one line height. */
11827 height %= FRAME_LINE_HEIGHT (it->f);
11828 it->max_ascent += height / 2;
11829 it->max_descent += (height + 1) / 2;
11830 }
11831
11832 compute_line_metrics (it);
11833
11834 /* If line is empty, make it occupy the rest of the tool-bar. */
11835 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11836 {
11837 row->height = row->phys_height = it->last_visible_y - row->y;
11838 row->visible_height = row->height;
11839 row->ascent = row->phys_ascent = 0;
11840 row->extra_line_spacing = 0;
11841 }
11842
11843 row->full_width_p = 1;
11844 row->continued_p = 0;
11845 row->truncated_on_left_p = 0;
11846 row->truncated_on_right_p = 0;
11847
11848 it->current_x = it->hpos = 0;
11849 it->current_y += row->height;
11850 ++it->vpos;
11851 ++it->glyph_row;
11852 }
11853
11854
11855 /* Max tool-bar height. */
11856
11857 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11858 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11859
11860 /* Value is the number of screen lines needed to make all tool-bar
11861 items of frame F visible. The number of actual rows needed is
11862 returned in *N_ROWS if non-NULL. */
11863
11864 static int
11865 tool_bar_lines_needed (struct frame *f, int *n_rows)
11866 {
11867 struct window *w = XWINDOW (f->tool_bar_window);
11868 struct it it;
11869 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11870 the desired matrix, so use (unused) mode-line row as temporary row to
11871 avoid destroying the first tool-bar row. */
11872 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11873
11874 /* Initialize an iterator for iteration over
11875 F->desired_tool_bar_string in the tool-bar window of frame F. */
11876 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11877 it.first_visible_x = 0;
11878 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11879 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11880 it.paragraph_embedding = L2R;
11881
11882 while (!ITERATOR_AT_END_P (&it))
11883 {
11884 clear_glyph_row (temp_row);
11885 it.glyph_row = temp_row;
11886 display_tool_bar_line (&it, -1);
11887 }
11888 clear_glyph_row (temp_row);
11889
11890 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11891 if (n_rows)
11892 *n_rows = it.vpos > 0 ? it.vpos : -1;
11893
11894 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11895 }
11896
11897
11898 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11899 0, 1, 0,
11900 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11901 If FRAME is nil or omitted, use the selected frame. */)
11902 (Lisp_Object frame)
11903 {
11904 struct frame *f = decode_any_frame (frame);
11905 struct window *w;
11906 int nlines = 0;
11907
11908 if (WINDOWP (f->tool_bar_window)
11909 && (w = XWINDOW (f->tool_bar_window),
11910 WINDOW_TOTAL_LINES (w) > 0))
11911 {
11912 update_tool_bar (f, 1);
11913 if (f->n_tool_bar_items)
11914 {
11915 build_desired_tool_bar_string (f);
11916 nlines = tool_bar_lines_needed (f, NULL);
11917 }
11918 }
11919
11920 return make_number (nlines);
11921 }
11922
11923
11924 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11925 height should be changed. */
11926
11927 static int
11928 redisplay_tool_bar (struct frame *f)
11929 {
11930 struct window *w;
11931 struct it it;
11932 struct glyph_row *row;
11933
11934 #if defined (USE_GTK) || defined (HAVE_NS)
11935 if (FRAME_EXTERNAL_TOOL_BAR (f))
11936 update_frame_tool_bar (f);
11937 return 0;
11938 #endif
11939
11940 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11941 do anything. This means you must start with tool-bar-lines
11942 non-zero to get the auto-sizing effect. Or in other words, you
11943 can turn off tool-bars by specifying tool-bar-lines zero. */
11944 if (!WINDOWP (f->tool_bar_window)
11945 || (w = XWINDOW (f->tool_bar_window),
11946 WINDOW_TOTAL_LINES (w) == 0))
11947 return 0;
11948
11949 /* Set up an iterator for the tool-bar window. */
11950 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11951 it.first_visible_x = 0;
11952 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11953 row = it.glyph_row;
11954
11955 /* Build a string that represents the contents of the tool-bar. */
11956 build_desired_tool_bar_string (f);
11957 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11958 /* FIXME: This should be controlled by a user option. But it
11959 doesn't make sense to have an R2L tool bar if the menu bar cannot
11960 be drawn also R2L, and making the menu bar R2L is tricky due
11961 toolkit-specific code that implements it. If an R2L tool bar is
11962 ever supported, display_tool_bar_line should also be augmented to
11963 call unproduce_glyphs like display_line and display_string
11964 do. */
11965 it.paragraph_embedding = L2R;
11966
11967 if (f->n_tool_bar_rows == 0)
11968 {
11969 int nlines;
11970
11971 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11972 nlines != WINDOW_TOTAL_LINES (w)))
11973 {
11974 Lisp_Object frame;
11975 int old_height = WINDOW_TOTAL_LINES (w);
11976
11977 XSETFRAME (frame, f);
11978 Fmodify_frame_parameters (frame,
11979 list1 (Fcons (Qtool_bar_lines,
11980 make_number (nlines))));
11981 if (WINDOW_TOTAL_LINES (w) != old_height)
11982 {
11983 clear_glyph_matrix (w->desired_matrix);
11984 f->fonts_changed = 1;
11985 return 1;
11986 }
11987 }
11988 }
11989
11990 /* Display as many lines as needed to display all tool-bar items. */
11991
11992 if (f->n_tool_bar_rows > 0)
11993 {
11994 int border, rows, height, extra;
11995
11996 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
11997 border = XINT (Vtool_bar_border);
11998 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11999 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12000 else if (EQ (Vtool_bar_border, Qborder_width))
12001 border = f->border_width;
12002 else
12003 border = 0;
12004 if (border < 0)
12005 border = 0;
12006
12007 rows = f->n_tool_bar_rows;
12008 height = max (1, (it.last_visible_y - border) / rows);
12009 extra = it.last_visible_y - border - height * rows;
12010
12011 while (it.current_y < it.last_visible_y)
12012 {
12013 int h = 0;
12014 if (extra > 0 && rows-- > 0)
12015 {
12016 h = (extra + rows - 1) / rows;
12017 extra -= h;
12018 }
12019 display_tool_bar_line (&it, height + h);
12020 }
12021 }
12022 else
12023 {
12024 while (it.current_y < it.last_visible_y)
12025 display_tool_bar_line (&it, 0);
12026 }
12027
12028 /* It doesn't make much sense to try scrolling in the tool-bar
12029 window, so don't do it. */
12030 w->desired_matrix->no_scrolling_p = 1;
12031 w->must_be_updated_p = 1;
12032
12033 if (!NILP (Vauto_resize_tool_bars))
12034 {
12035 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12036 int change_height_p = 0;
12037
12038 /* If we couldn't display everything, change the tool-bar's
12039 height if there is room for more. */
12040 if (IT_STRING_CHARPOS (it) < it.end_charpos
12041 && it.current_y < max_tool_bar_height)
12042 change_height_p = 1;
12043
12044 row = it.glyph_row - 1;
12045
12046 /* If there are blank lines at the end, except for a partially
12047 visible blank line at the end that is smaller than
12048 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12049 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12050 && row->height >= FRAME_LINE_HEIGHT (f))
12051 change_height_p = 1;
12052
12053 /* If row displays tool-bar items, but is partially visible,
12054 change the tool-bar's height. */
12055 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12056 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12057 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12058 change_height_p = 1;
12059
12060 /* Resize windows as needed by changing the `tool-bar-lines'
12061 frame parameter. */
12062 if (change_height_p)
12063 {
12064 Lisp_Object frame;
12065 int old_height = WINDOW_TOTAL_LINES (w);
12066 int nrows;
12067 int nlines = tool_bar_lines_needed (f, &nrows);
12068
12069 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12070 && !f->minimize_tool_bar_window_p)
12071 ? (nlines > old_height)
12072 : (nlines != old_height));
12073 f->minimize_tool_bar_window_p = 0;
12074
12075 if (change_height_p)
12076 {
12077 XSETFRAME (frame, f);
12078 Fmodify_frame_parameters (frame,
12079 list1 (Fcons (Qtool_bar_lines,
12080 make_number (nlines))));
12081 if (WINDOW_TOTAL_LINES (w) != old_height)
12082 {
12083 clear_glyph_matrix (w->desired_matrix);
12084 f->n_tool_bar_rows = nrows;
12085 f->fonts_changed = 1;
12086 return 1;
12087 }
12088 }
12089 }
12090 }
12091
12092 f->minimize_tool_bar_window_p = 0;
12093 return 0;
12094 }
12095
12096
12097 /* Get information about the tool-bar item which is displayed in GLYPH
12098 on frame F. Return in *PROP_IDX the index where tool-bar item
12099 properties start in F->tool_bar_items. Value is zero if
12100 GLYPH doesn't display a tool-bar item. */
12101
12102 static int
12103 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12104 {
12105 Lisp_Object prop;
12106 int success_p;
12107 int charpos;
12108
12109 /* This function can be called asynchronously, which means we must
12110 exclude any possibility that Fget_text_property signals an
12111 error. */
12112 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12113 charpos = max (0, charpos);
12114
12115 /* Get the text property `menu-item' at pos. The value of that
12116 property is the start index of this item's properties in
12117 F->tool_bar_items. */
12118 prop = Fget_text_property (make_number (charpos),
12119 Qmenu_item, f->current_tool_bar_string);
12120 if (INTEGERP (prop))
12121 {
12122 *prop_idx = XINT (prop);
12123 success_p = 1;
12124 }
12125 else
12126 success_p = 0;
12127
12128 return success_p;
12129 }
12130
12131 \f
12132 /* Get information about the tool-bar item at position X/Y on frame F.
12133 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12134 the current matrix of the tool-bar window of F, or NULL if not
12135 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12136 item in F->tool_bar_items. Value is
12137
12138 -1 if X/Y is not on a tool-bar item
12139 0 if X/Y is on the same item that was highlighted before.
12140 1 otherwise. */
12141
12142 static int
12143 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12144 int *hpos, int *vpos, int *prop_idx)
12145 {
12146 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12147 struct window *w = XWINDOW (f->tool_bar_window);
12148 int area;
12149
12150 /* Find the glyph under X/Y. */
12151 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12152 if (*glyph == NULL)
12153 return -1;
12154
12155 /* Get the start of this tool-bar item's properties in
12156 f->tool_bar_items. */
12157 if (!tool_bar_item_info (f, *glyph, prop_idx))
12158 return -1;
12159
12160 /* Is mouse on the highlighted item? */
12161 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12162 && *vpos >= hlinfo->mouse_face_beg_row
12163 && *vpos <= hlinfo->mouse_face_end_row
12164 && (*vpos > hlinfo->mouse_face_beg_row
12165 || *hpos >= hlinfo->mouse_face_beg_col)
12166 && (*vpos < hlinfo->mouse_face_end_row
12167 || *hpos < hlinfo->mouse_face_end_col
12168 || hlinfo->mouse_face_past_end))
12169 return 0;
12170
12171 return 1;
12172 }
12173
12174
12175 /* EXPORT:
12176 Handle mouse button event on the tool-bar of frame F, at
12177 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12178 0 for button release. MODIFIERS is event modifiers for button
12179 release. */
12180
12181 void
12182 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12183 int modifiers)
12184 {
12185 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12186 struct window *w = XWINDOW (f->tool_bar_window);
12187 int hpos, vpos, prop_idx;
12188 struct glyph *glyph;
12189 Lisp_Object enabled_p;
12190 int ts;
12191
12192 /* If not on the highlighted tool-bar item, and mouse-highlight is
12193 non-nil, return. This is so we generate the tool-bar button
12194 click only when the mouse button is released on the same item as
12195 where it was pressed. However, when mouse-highlight is disabled,
12196 generate the click when the button is released regardless of the
12197 highlight, since tool-bar items are not highlighted in that
12198 case. */
12199 frame_to_window_pixel_xy (w, &x, &y);
12200 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12201 if (ts == -1
12202 || (ts != 0 && !NILP (Vmouse_highlight)))
12203 return;
12204
12205 /* When mouse-highlight is off, generate the click for the item
12206 where the button was pressed, disregarding where it was
12207 released. */
12208 if (NILP (Vmouse_highlight) && !down_p)
12209 prop_idx = last_tool_bar_item;
12210
12211 /* If item is disabled, do nothing. */
12212 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12213 if (NILP (enabled_p))
12214 return;
12215
12216 if (down_p)
12217 {
12218 /* Show item in pressed state. */
12219 if (!NILP (Vmouse_highlight))
12220 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12221 last_tool_bar_item = prop_idx;
12222 }
12223 else
12224 {
12225 Lisp_Object key, frame;
12226 struct input_event event;
12227 EVENT_INIT (event);
12228
12229 /* Show item in released state. */
12230 if (!NILP (Vmouse_highlight))
12231 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12232
12233 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12234
12235 XSETFRAME (frame, f);
12236 event.kind = TOOL_BAR_EVENT;
12237 event.frame_or_window = frame;
12238 event.arg = frame;
12239 kbd_buffer_store_event (&event);
12240
12241 event.kind = TOOL_BAR_EVENT;
12242 event.frame_or_window = frame;
12243 event.arg = key;
12244 event.modifiers = modifiers;
12245 kbd_buffer_store_event (&event);
12246 last_tool_bar_item = -1;
12247 }
12248 }
12249
12250
12251 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12252 tool-bar window-relative coordinates X/Y. Called from
12253 note_mouse_highlight. */
12254
12255 static void
12256 note_tool_bar_highlight (struct frame *f, int x, int y)
12257 {
12258 Lisp_Object window = f->tool_bar_window;
12259 struct window *w = XWINDOW (window);
12260 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12261 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12262 int hpos, vpos;
12263 struct glyph *glyph;
12264 struct glyph_row *row;
12265 int i;
12266 Lisp_Object enabled_p;
12267 int prop_idx;
12268 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12269 int mouse_down_p, rc;
12270
12271 /* Function note_mouse_highlight is called with negative X/Y
12272 values when mouse moves outside of the frame. */
12273 if (x <= 0 || y <= 0)
12274 {
12275 clear_mouse_face (hlinfo);
12276 return;
12277 }
12278
12279 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12280 if (rc < 0)
12281 {
12282 /* Not on tool-bar item. */
12283 clear_mouse_face (hlinfo);
12284 return;
12285 }
12286 else if (rc == 0)
12287 /* On same tool-bar item as before. */
12288 goto set_help_echo;
12289
12290 clear_mouse_face (hlinfo);
12291
12292 /* Mouse is down, but on different tool-bar item? */
12293 mouse_down_p = (dpyinfo->grabbed
12294 && f == last_mouse_frame
12295 && FRAME_LIVE_P (f));
12296 if (mouse_down_p
12297 && last_tool_bar_item != prop_idx)
12298 return;
12299
12300 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12301
12302 /* If tool-bar item is not enabled, don't highlight it. */
12303 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12304 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12305 {
12306 /* Compute the x-position of the glyph. In front and past the
12307 image is a space. We include this in the highlighted area. */
12308 row = MATRIX_ROW (w->current_matrix, vpos);
12309 for (i = x = 0; i < hpos; ++i)
12310 x += row->glyphs[TEXT_AREA][i].pixel_width;
12311
12312 /* Record this as the current active region. */
12313 hlinfo->mouse_face_beg_col = hpos;
12314 hlinfo->mouse_face_beg_row = vpos;
12315 hlinfo->mouse_face_beg_x = x;
12316 hlinfo->mouse_face_past_end = 0;
12317
12318 hlinfo->mouse_face_end_col = hpos + 1;
12319 hlinfo->mouse_face_end_row = vpos;
12320 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12321 hlinfo->mouse_face_window = window;
12322 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12323
12324 /* Display it as active. */
12325 show_mouse_face (hlinfo, draw);
12326 }
12327
12328 set_help_echo:
12329
12330 /* Set help_echo_string to a help string to display for this tool-bar item.
12331 XTread_socket does the rest. */
12332 help_echo_object = help_echo_window = Qnil;
12333 help_echo_pos = -1;
12334 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12335 if (NILP (help_echo_string))
12336 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12337 }
12338
12339 #endif /* HAVE_WINDOW_SYSTEM */
12340
12341
12342 \f
12343 /************************************************************************
12344 Horizontal scrolling
12345 ************************************************************************/
12346
12347 static int hscroll_window_tree (Lisp_Object);
12348 static int hscroll_windows (Lisp_Object);
12349
12350 /* For all leaf windows in the window tree rooted at WINDOW, set their
12351 hscroll value so that PT is (i) visible in the window, and (ii) so
12352 that it is not within a certain margin at the window's left and
12353 right border. Value is non-zero if any window's hscroll has been
12354 changed. */
12355
12356 static int
12357 hscroll_window_tree (Lisp_Object window)
12358 {
12359 int hscrolled_p = 0;
12360 int hscroll_relative_p = FLOATP (Vhscroll_step);
12361 int hscroll_step_abs = 0;
12362 double hscroll_step_rel = 0;
12363
12364 if (hscroll_relative_p)
12365 {
12366 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12367 if (hscroll_step_rel < 0)
12368 {
12369 hscroll_relative_p = 0;
12370 hscroll_step_abs = 0;
12371 }
12372 }
12373 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12374 {
12375 hscroll_step_abs = XINT (Vhscroll_step);
12376 if (hscroll_step_abs < 0)
12377 hscroll_step_abs = 0;
12378 }
12379 else
12380 hscroll_step_abs = 0;
12381
12382 while (WINDOWP (window))
12383 {
12384 struct window *w = XWINDOW (window);
12385
12386 if (WINDOWP (w->contents))
12387 hscrolled_p |= hscroll_window_tree (w->contents);
12388 else if (w->cursor.vpos >= 0)
12389 {
12390 int h_margin;
12391 int text_area_width;
12392 struct glyph_row *current_cursor_row
12393 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12394 struct glyph_row *desired_cursor_row
12395 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12396 struct glyph_row *cursor_row
12397 = (desired_cursor_row->enabled_p
12398 ? desired_cursor_row
12399 : current_cursor_row);
12400 int row_r2l_p = cursor_row->reversed_p;
12401
12402 text_area_width = window_box_width (w, TEXT_AREA);
12403
12404 /* Scroll when cursor is inside this scroll margin. */
12405 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12406
12407 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12408 /* For left-to-right rows, hscroll when cursor is either
12409 (i) inside the right hscroll margin, or (ii) if it is
12410 inside the left margin and the window is already
12411 hscrolled. */
12412 && ((!row_r2l_p
12413 && ((w->hscroll
12414 && w->cursor.x <= h_margin)
12415 || (cursor_row->enabled_p
12416 && cursor_row->truncated_on_right_p
12417 && (w->cursor.x >= text_area_width - h_margin))))
12418 /* For right-to-left rows, the logic is similar,
12419 except that rules for scrolling to left and right
12420 are reversed. E.g., if cursor.x <= h_margin, we
12421 need to hscroll "to the right" unconditionally,
12422 and that will scroll the screen to the left so as
12423 to reveal the next portion of the row. */
12424 || (row_r2l_p
12425 && ((cursor_row->enabled_p
12426 /* FIXME: It is confusing to set the
12427 truncated_on_right_p flag when R2L rows
12428 are actually truncated on the left. */
12429 && cursor_row->truncated_on_right_p
12430 && w->cursor.x <= h_margin)
12431 || (w->hscroll
12432 && (w->cursor.x >= text_area_width - h_margin))))))
12433 {
12434 struct it it;
12435 ptrdiff_t hscroll;
12436 struct buffer *saved_current_buffer;
12437 ptrdiff_t pt;
12438 int wanted_x;
12439
12440 /* Find point in a display of infinite width. */
12441 saved_current_buffer = current_buffer;
12442 current_buffer = XBUFFER (w->contents);
12443
12444 if (w == XWINDOW (selected_window))
12445 pt = PT;
12446 else
12447 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12448
12449 /* Move iterator to pt starting at cursor_row->start in
12450 a line with infinite width. */
12451 init_to_row_start (&it, w, cursor_row);
12452 it.last_visible_x = INFINITY;
12453 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12454 current_buffer = saved_current_buffer;
12455
12456 /* Position cursor in window. */
12457 if (!hscroll_relative_p && hscroll_step_abs == 0)
12458 hscroll = max (0, (it.current_x
12459 - (ITERATOR_AT_END_OF_LINE_P (&it)
12460 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12461 : (text_area_width / 2))))
12462 / FRAME_COLUMN_WIDTH (it.f);
12463 else if ((!row_r2l_p
12464 && w->cursor.x >= text_area_width - h_margin)
12465 || (row_r2l_p && w->cursor.x <= h_margin))
12466 {
12467 if (hscroll_relative_p)
12468 wanted_x = text_area_width * (1 - hscroll_step_rel)
12469 - h_margin;
12470 else
12471 wanted_x = text_area_width
12472 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12473 - h_margin;
12474 hscroll
12475 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12476 }
12477 else
12478 {
12479 if (hscroll_relative_p)
12480 wanted_x = text_area_width * hscroll_step_rel
12481 + h_margin;
12482 else
12483 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12484 + h_margin;
12485 hscroll
12486 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12487 }
12488 hscroll = max (hscroll, w->min_hscroll);
12489
12490 /* Don't prevent redisplay optimizations if hscroll
12491 hasn't changed, as it will unnecessarily slow down
12492 redisplay. */
12493 if (w->hscroll != hscroll)
12494 {
12495 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12496 w->hscroll = hscroll;
12497 hscrolled_p = 1;
12498 }
12499 }
12500 }
12501
12502 window = w->next;
12503 }
12504
12505 /* Value is non-zero if hscroll of any leaf window has been changed. */
12506 return hscrolled_p;
12507 }
12508
12509
12510 /* Set hscroll so that cursor is visible and not inside horizontal
12511 scroll margins for all windows in the tree rooted at WINDOW. See
12512 also hscroll_window_tree above. Value is non-zero if any window's
12513 hscroll has been changed. If it has, desired matrices on the frame
12514 of WINDOW are cleared. */
12515
12516 static int
12517 hscroll_windows (Lisp_Object window)
12518 {
12519 int hscrolled_p = hscroll_window_tree (window);
12520 if (hscrolled_p)
12521 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12522 return hscrolled_p;
12523 }
12524
12525
12526 \f
12527 /************************************************************************
12528 Redisplay
12529 ************************************************************************/
12530
12531 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12532 to a non-zero value. This is sometimes handy to have in a debugger
12533 session. */
12534
12535 #ifdef GLYPH_DEBUG
12536
12537 /* First and last unchanged row for try_window_id. */
12538
12539 static int debug_first_unchanged_at_end_vpos;
12540 static int debug_last_unchanged_at_beg_vpos;
12541
12542 /* Delta vpos and y. */
12543
12544 static int debug_dvpos, debug_dy;
12545
12546 /* Delta in characters and bytes for try_window_id. */
12547
12548 static ptrdiff_t debug_delta, debug_delta_bytes;
12549
12550 /* Values of window_end_pos and window_end_vpos at the end of
12551 try_window_id. */
12552
12553 static ptrdiff_t debug_end_vpos;
12554
12555 /* Append a string to W->desired_matrix->method. FMT is a printf
12556 format string. If trace_redisplay_p is non-zero also printf the
12557 resulting string to stderr. */
12558
12559 static void debug_method_add (struct window *, char const *, ...)
12560 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12561
12562 static void
12563 debug_method_add (struct window *w, char const *fmt, ...)
12564 {
12565 void *ptr = w;
12566 char *method = w->desired_matrix->method;
12567 int len = strlen (method);
12568 int size = sizeof w->desired_matrix->method;
12569 int remaining = size - len - 1;
12570 va_list ap;
12571
12572 if (len && remaining)
12573 {
12574 method[len] = '|';
12575 --remaining, ++len;
12576 }
12577
12578 va_start (ap, fmt);
12579 vsnprintf (method + len, remaining + 1, fmt, ap);
12580 va_end (ap);
12581
12582 if (trace_redisplay_p)
12583 fprintf (stderr, "%p (%s): %s\n",
12584 ptr,
12585 ((BUFFERP (w->contents)
12586 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12587 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12588 : "no buffer"),
12589 method + len);
12590 }
12591
12592 #endif /* GLYPH_DEBUG */
12593
12594
12595 /* Value is non-zero if all changes in window W, which displays
12596 current_buffer, are in the text between START and END. START is a
12597 buffer position, END is given as a distance from Z. Used in
12598 redisplay_internal for display optimization. */
12599
12600 static int
12601 text_outside_line_unchanged_p (struct window *w,
12602 ptrdiff_t start, ptrdiff_t end)
12603 {
12604 int unchanged_p = 1;
12605
12606 /* If text or overlays have changed, see where. */
12607 if (window_outdated (w))
12608 {
12609 /* Gap in the line? */
12610 if (GPT < start || Z - GPT < end)
12611 unchanged_p = 0;
12612
12613 /* Changes start in front of the line, or end after it? */
12614 if (unchanged_p
12615 && (BEG_UNCHANGED < start - 1
12616 || END_UNCHANGED < end))
12617 unchanged_p = 0;
12618
12619 /* If selective display, can't optimize if changes start at the
12620 beginning of the line. */
12621 if (unchanged_p
12622 && INTEGERP (BVAR (current_buffer, selective_display))
12623 && XINT (BVAR (current_buffer, selective_display)) > 0
12624 && (BEG_UNCHANGED < start || GPT <= start))
12625 unchanged_p = 0;
12626
12627 /* If there are overlays at the start or end of the line, these
12628 may have overlay strings with newlines in them. A change at
12629 START, for instance, may actually concern the display of such
12630 overlay strings as well, and they are displayed on different
12631 lines. So, quickly rule out this case. (For the future, it
12632 might be desirable to implement something more telling than
12633 just BEG/END_UNCHANGED.) */
12634 if (unchanged_p)
12635 {
12636 if (BEG + BEG_UNCHANGED == start
12637 && overlay_touches_p (start))
12638 unchanged_p = 0;
12639 if (END_UNCHANGED == end
12640 && overlay_touches_p (Z - end))
12641 unchanged_p = 0;
12642 }
12643
12644 /* Under bidi reordering, adding or deleting a character in the
12645 beginning of a paragraph, before the first strong directional
12646 character, can change the base direction of the paragraph (unless
12647 the buffer specifies a fixed paragraph direction), which will
12648 require to redisplay the whole paragraph. It might be worthwhile
12649 to find the paragraph limits and widen the range of redisplayed
12650 lines to that, but for now just give up this optimization. */
12651 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12652 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12653 unchanged_p = 0;
12654 }
12655
12656 return unchanged_p;
12657 }
12658
12659
12660 /* Do a frame update, taking possible shortcuts into account. This is
12661 the main external entry point for redisplay.
12662
12663 If the last redisplay displayed an echo area message and that message
12664 is no longer requested, we clear the echo area or bring back the
12665 mini-buffer if that is in use. */
12666
12667 void
12668 redisplay (void)
12669 {
12670 redisplay_internal ();
12671 }
12672
12673
12674 static Lisp_Object
12675 overlay_arrow_string_or_property (Lisp_Object var)
12676 {
12677 Lisp_Object val;
12678
12679 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12680 return val;
12681
12682 return Voverlay_arrow_string;
12683 }
12684
12685 /* Return 1 if there are any overlay-arrows in current_buffer. */
12686 static int
12687 overlay_arrow_in_current_buffer_p (void)
12688 {
12689 Lisp_Object vlist;
12690
12691 for (vlist = Voverlay_arrow_variable_list;
12692 CONSP (vlist);
12693 vlist = XCDR (vlist))
12694 {
12695 Lisp_Object var = XCAR (vlist);
12696 Lisp_Object val;
12697
12698 if (!SYMBOLP (var))
12699 continue;
12700 val = find_symbol_value (var);
12701 if (MARKERP (val)
12702 && current_buffer == XMARKER (val)->buffer)
12703 return 1;
12704 }
12705 return 0;
12706 }
12707
12708
12709 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12710 has changed. */
12711
12712 static int
12713 overlay_arrows_changed_p (void)
12714 {
12715 Lisp_Object vlist;
12716
12717 for (vlist = Voverlay_arrow_variable_list;
12718 CONSP (vlist);
12719 vlist = XCDR (vlist))
12720 {
12721 Lisp_Object var = XCAR (vlist);
12722 Lisp_Object val, pstr;
12723
12724 if (!SYMBOLP (var))
12725 continue;
12726 val = find_symbol_value (var);
12727 if (!MARKERP (val))
12728 continue;
12729 if (! EQ (COERCE_MARKER (val),
12730 Fget (var, Qlast_arrow_position))
12731 || ! (pstr = overlay_arrow_string_or_property (var),
12732 EQ (pstr, Fget (var, Qlast_arrow_string))))
12733 return 1;
12734 }
12735 return 0;
12736 }
12737
12738 /* Mark overlay arrows to be updated on next redisplay. */
12739
12740 static void
12741 update_overlay_arrows (int up_to_date)
12742 {
12743 Lisp_Object vlist;
12744
12745 for (vlist = Voverlay_arrow_variable_list;
12746 CONSP (vlist);
12747 vlist = XCDR (vlist))
12748 {
12749 Lisp_Object var = XCAR (vlist);
12750
12751 if (!SYMBOLP (var))
12752 continue;
12753
12754 if (up_to_date > 0)
12755 {
12756 Lisp_Object val = find_symbol_value (var);
12757 Fput (var, Qlast_arrow_position,
12758 COERCE_MARKER (val));
12759 Fput (var, Qlast_arrow_string,
12760 overlay_arrow_string_or_property (var));
12761 }
12762 else if (up_to_date < 0
12763 || !NILP (Fget (var, Qlast_arrow_position)))
12764 {
12765 Fput (var, Qlast_arrow_position, Qt);
12766 Fput (var, Qlast_arrow_string, Qt);
12767 }
12768 }
12769 }
12770
12771
12772 /* Return overlay arrow string to display at row.
12773 Return integer (bitmap number) for arrow bitmap in left fringe.
12774 Return nil if no overlay arrow. */
12775
12776 static Lisp_Object
12777 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12778 {
12779 Lisp_Object vlist;
12780
12781 for (vlist = Voverlay_arrow_variable_list;
12782 CONSP (vlist);
12783 vlist = XCDR (vlist))
12784 {
12785 Lisp_Object var = XCAR (vlist);
12786 Lisp_Object val;
12787
12788 if (!SYMBOLP (var))
12789 continue;
12790
12791 val = find_symbol_value (var);
12792
12793 if (MARKERP (val)
12794 && current_buffer == XMARKER (val)->buffer
12795 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12796 {
12797 if (FRAME_WINDOW_P (it->f)
12798 /* FIXME: if ROW->reversed_p is set, this should test
12799 the right fringe, not the left one. */
12800 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12801 {
12802 #ifdef HAVE_WINDOW_SYSTEM
12803 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12804 {
12805 int fringe_bitmap;
12806 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12807 return make_number (fringe_bitmap);
12808 }
12809 #endif
12810 return make_number (-1); /* Use default arrow bitmap. */
12811 }
12812 return overlay_arrow_string_or_property (var);
12813 }
12814 }
12815
12816 return Qnil;
12817 }
12818
12819 /* Return 1 if point moved out of or into a composition. Otherwise
12820 return 0. PREV_BUF and PREV_PT are the last point buffer and
12821 position. BUF and PT are the current point buffer and position. */
12822
12823 static int
12824 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12825 struct buffer *buf, ptrdiff_t pt)
12826 {
12827 ptrdiff_t start, end;
12828 Lisp_Object prop;
12829 Lisp_Object buffer;
12830
12831 XSETBUFFER (buffer, buf);
12832 /* Check a composition at the last point if point moved within the
12833 same buffer. */
12834 if (prev_buf == buf)
12835 {
12836 if (prev_pt == pt)
12837 /* Point didn't move. */
12838 return 0;
12839
12840 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12841 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12842 && composition_valid_p (start, end, prop)
12843 && start < prev_pt && end > prev_pt)
12844 /* The last point was within the composition. Return 1 iff
12845 point moved out of the composition. */
12846 return (pt <= start || pt >= end);
12847 }
12848
12849 /* Check a composition at the current point. */
12850 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12851 && find_composition (pt, -1, &start, &end, &prop, buffer)
12852 && composition_valid_p (start, end, prop)
12853 && start < pt && end > pt);
12854 }
12855
12856 /* Reconsider the clip changes of buffer which is displayed in W. */
12857
12858 static void
12859 reconsider_clip_changes (struct window *w)
12860 {
12861 struct buffer *b = XBUFFER (w->contents);
12862
12863 if (b->clip_changed
12864 && w->window_end_valid
12865 && w->current_matrix->buffer == b
12866 && w->current_matrix->zv == BUF_ZV (b)
12867 && w->current_matrix->begv == BUF_BEGV (b))
12868 b->clip_changed = 0;
12869
12870 /* If display wasn't paused, and W is not a tool bar window, see if
12871 point has been moved into or out of a composition. In that case,
12872 we set b->clip_changed to 1 to force updating the screen. If
12873 b->clip_changed has already been set to 1, we can skip this
12874 check. */
12875 if (!b->clip_changed && w->window_end_valid)
12876 {
12877 ptrdiff_t pt = (w == XWINDOW (selected_window)
12878 ? PT : marker_position (w->pointm));
12879
12880 if ((w->current_matrix->buffer != b || pt != w->last_point)
12881 && check_point_in_composition (w->current_matrix->buffer,
12882 w->last_point, b, pt))
12883 b->clip_changed = 1;
12884 }
12885 }
12886
12887 #define STOP_POLLING \
12888 do { if (! polling_stopped_here) stop_polling (); \
12889 polling_stopped_here = 1; } while (0)
12890
12891 #define RESUME_POLLING \
12892 do { if (polling_stopped_here) start_polling (); \
12893 polling_stopped_here = 0; } while (0)
12894
12895
12896 /* Perhaps in the future avoid recentering windows if it
12897 is not necessary; currently that causes some problems. */
12898
12899 static void
12900 redisplay_internal (void)
12901 {
12902 struct window *w = XWINDOW (selected_window);
12903 struct window *sw;
12904 struct frame *fr;
12905 int pending;
12906 bool must_finish = 0, match_p;
12907 struct text_pos tlbufpos, tlendpos;
12908 int number_of_visible_frames;
12909 ptrdiff_t count;
12910 struct frame *sf;
12911 int polling_stopped_here = 0;
12912 Lisp_Object tail, frame;
12913
12914 /* Non-zero means redisplay has to consider all windows on all
12915 frames. Zero means, only selected_window is considered. */
12916 int consider_all_windows_p;
12917
12918 /* Non-zero means redisplay has to redisplay the miniwindow. */
12919 int update_miniwindow_p = 0;
12920
12921 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12922
12923 /* No redisplay if running in batch mode or frame is not yet fully
12924 initialized, or redisplay is explicitly turned off by setting
12925 Vinhibit_redisplay. */
12926 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12927 || !NILP (Vinhibit_redisplay))
12928 return;
12929
12930 /* Don't examine these until after testing Vinhibit_redisplay.
12931 When Emacs is shutting down, perhaps because its connection to
12932 X has dropped, we should not look at them at all. */
12933 fr = XFRAME (w->frame);
12934 sf = SELECTED_FRAME ();
12935
12936 if (!fr->glyphs_initialized_p)
12937 return;
12938
12939 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12940 if (popup_activated ())
12941 return;
12942 #endif
12943
12944 /* I don't think this happens but let's be paranoid. */
12945 if (redisplaying_p)
12946 return;
12947
12948 /* Record a function that clears redisplaying_p
12949 when we leave this function. */
12950 count = SPECPDL_INDEX ();
12951 record_unwind_protect_void (unwind_redisplay);
12952 redisplaying_p = 1;
12953 specbind (Qinhibit_free_realized_faces, Qnil);
12954
12955 /* Record this function, so it appears on the profiler's backtraces. */
12956 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
12957
12958 FOR_EACH_FRAME (tail, frame)
12959 XFRAME (frame)->already_hscrolled_p = 0;
12960
12961 retry:
12962 /* Remember the currently selected window. */
12963 sw = w;
12964
12965 pending = 0;
12966 last_escape_glyph_frame = NULL;
12967 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12968 last_glyphless_glyph_frame = NULL;
12969 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12970
12971 /* If face_change_count is non-zero, init_iterator will free all
12972 realized faces, which includes the faces referenced from current
12973 matrices. So, we can't reuse current matrices in this case. */
12974 if (face_change_count)
12975 ++windows_or_buffers_changed;
12976
12977 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12978 && FRAME_TTY (sf)->previous_frame != sf)
12979 {
12980 /* Since frames on a single ASCII terminal share the same
12981 display area, displaying a different frame means redisplay
12982 the whole thing. */
12983 windows_or_buffers_changed++;
12984 SET_FRAME_GARBAGED (sf);
12985 #ifndef DOS_NT
12986 set_tty_color_mode (FRAME_TTY (sf), sf);
12987 #endif
12988 FRAME_TTY (sf)->previous_frame = sf;
12989 }
12990
12991 /* Set the visible flags for all frames. Do this before checking for
12992 resized or garbaged frames; they want to know if their frames are
12993 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
12994 number_of_visible_frames = 0;
12995
12996 FOR_EACH_FRAME (tail, frame)
12997 {
12998 struct frame *f = XFRAME (frame);
12999
13000 if (FRAME_VISIBLE_P (f))
13001 {
13002 ++number_of_visible_frames;
13003 /* Adjust matrices for visible frames only. */
13004 if (f->fonts_changed)
13005 {
13006 adjust_frame_glyphs (f);
13007 f->fonts_changed = 0;
13008 }
13009 /* If cursor type has been changed on the frame
13010 other than selected, consider all frames. */
13011 if (f != sf && f->cursor_type_changed)
13012 update_mode_lines++;
13013 }
13014 clear_desired_matrices (f);
13015 }
13016
13017 /* Notice any pending interrupt request to change frame size. */
13018 do_pending_window_change (1);
13019
13020 /* do_pending_window_change could change the selected_window due to
13021 frame resizing which makes the selected window too small. */
13022 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13023 sw = w;
13024
13025 /* Clear frames marked as garbaged. */
13026 clear_garbaged_frames ();
13027
13028 /* Build menubar and tool-bar items. */
13029 if (NILP (Vmemory_full))
13030 prepare_menu_bars ();
13031
13032 if (windows_or_buffers_changed)
13033 update_mode_lines++;
13034
13035 reconsider_clip_changes (w);
13036
13037 /* In most cases selected window displays current buffer. */
13038 match_p = XBUFFER (w->contents) == current_buffer;
13039 if (match_p)
13040 {
13041 ptrdiff_t count1;
13042
13043 /* Detect case that we need to write or remove a star in the mode line. */
13044 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13045 {
13046 w->update_mode_line = 1;
13047 if (buffer_shared_and_changed ())
13048 update_mode_lines++;
13049 }
13050
13051 /* Avoid invocation of point motion hooks by `current_column' below. */
13052 count1 = SPECPDL_INDEX ();
13053 specbind (Qinhibit_point_motion_hooks, Qt);
13054
13055 if (mode_line_update_needed (w))
13056 w->update_mode_line = 1;
13057
13058 unbind_to (count1, Qnil);
13059 }
13060
13061 consider_all_windows_p = (update_mode_lines
13062 || buffer_shared_and_changed ());
13063
13064 /* If specs for an arrow have changed, do thorough redisplay
13065 to ensure we remove any arrow that should no longer exist. */
13066 if (overlay_arrows_changed_p ())
13067 consider_all_windows_p = windows_or_buffers_changed = 1;
13068
13069 /* Normally the message* functions will have already displayed and
13070 updated the echo area, but the frame may have been trashed, or
13071 the update may have been preempted, so display the echo area
13072 again here. Checking message_cleared_p captures the case that
13073 the echo area should be cleared. */
13074 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13075 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13076 || (message_cleared_p
13077 && minibuf_level == 0
13078 /* If the mini-window is currently selected, this means the
13079 echo-area doesn't show through. */
13080 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13081 {
13082 int window_height_changed_p = echo_area_display (0);
13083
13084 if (message_cleared_p)
13085 update_miniwindow_p = 1;
13086
13087 must_finish = 1;
13088
13089 /* If we don't display the current message, don't clear the
13090 message_cleared_p flag, because, if we did, we wouldn't clear
13091 the echo area in the next redisplay which doesn't preserve
13092 the echo area. */
13093 if (!display_last_displayed_message_p)
13094 message_cleared_p = 0;
13095
13096 if (window_height_changed_p)
13097 {
13098 consider_all_windows_p = 1;
13099 ++update_mode_lines;
13100 ++windows_or_buffers_changed;
13101
13102 /* If window configuration was changed, frames may have been
13103 marked garbaged. Clear them or we will experience
13104 surprises wrt scrolling. */
13105 clear_garbaged_frames ();
13106 }
13107 }
13108 else if (EQ (selected_window, minibuf_window)
13109 && (current_buffer->clip_changed || window_outdated (w))
13110 && resize_mini_window (w, 0))
13111 {
13112 /* Resized active mini-window to fit the size of what it is
13113 showing if its contents might have changed. */
13114 must_finish = 1;
13115 /* FIXME: this causes all frames to be updated, which seems unnecessary
13116 since only the current frame needs to be considered. This function
13117 needs to be rewritten with two variables, consider_all_windows and
13118 consider_all_frames. */
13119 consider_all_windows_p = 1;
13120 ++windows_or_buffers_changed;
13121 ++update_mode_lines;
13122
13123 /* If window configuration was changed, frames may have been
13124 marked garbaged. Clear them or we will experience
13125 surprises wrt scrolling. */
13126 clear_garbaged_frames ();
13127 }
13128
13129 /* If showing the region, and mark has changed, we must redisplay
13130 the whole window. The assignment to this_line_start_pos prevents
13131 the optimization directly below this if-statement. */
13132 if (((!NILP (Vtransient_mark_mode)
13133 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13134 != (w->region_showing > 0))
13135 || (w->region_showing
13136 && w->region_showing
13137 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13138 CHARPOS (this_line_start_pos) = 0;
13139
13140 /* Optimize the case that only the line containing the cursor in the
13141 selected window has changed. Variables starting with this_ are
13142 set in display_line and record information about the line
13143 containing the cursor. */
13144 tlbufpos = this_line_start_pos;
13145 tlendpos = this_line_end_pos;
13146 if (!consider_all_windows_p
13147 && CHARPOS (tlbufpos) > 0
13148 && !w->update_mode_line
13149 && !current_buffer->clip_changed
13150 && !current_buffer->prevent_redisplay_optimizations_p
13151 && FRAME_VISIBLE_P (XFRAME (w->frame))
13152 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13153 && !XFRAME (w->frame)->cursor_type_changed
13154 /* Make sure recorded data applies to current buffer, etc. */
13155 && this_line_buffer == current_buffer
13156 && match_p
13157 && !w->force_start
13158 && !w->optional_new_start
13159 /* Point must be on the line that we have info recorded about. */
13160 && PT >= CHARPOS (tlbufpos)
13161 && PT <= Z - CHARPOS (tlendpos)
13162 /* All text outside that line, including its final newline,
13163 must be unchanged. */
13164 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13165 CHARPOS (tlendpos)))
13166 {
13167 if (CHARPOS (tlbufpos) > BEGV
13168 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13169 && (CHARPOS (tlbufpos) == ZV
13170 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13171 /* Former continuation line has disappeared by becoming empty. */
13172 goto cancel;
13173 else if (window_outdated (w) || MINI_WINDOW_P (w))
13174 {
13175 /* We have to handle the case of continuation around a
13176 wide-column character (see the comment in indent.c around
13177 line 1340).
13178
13179 For instance, in the following case:
13180
13181 -------- Insert --------
13182 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13183 J_I_ ==> J_I_ `^^' are cursors.
13184 ^^ ^^
13185 -------- --------
13186
13187 As we have to redraw the line above, we cannot use this
13188 optimization. */
13189
13190 struct it it;
13191 int line_height_before = this_line_pixel_height;
13192
13193 /* Note that start_display will handle the case that the
13194 line starting at tlbufpos is a continuation line. */
13195 start_display (&it, w, tlbufpos);
13196
13197 /* Implementation note: It this still necessary? */
13198 if (it.current_x != this_line_start_x)
13199 goto cancel;
13200
13201 TRACE ((stderr, "trying display optimization 1\n"));
13202 w->cursor.vpos = -1;
13203 overlay_arrow_seen = 0;
13204 it.vpos = this_line_vpos;
13205 it.current_y = this_line_y;
13206 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13207 display_line (&it);
13208
13209 /* If line contains point, is not continued,
13210 and ends at same distance from eob as before, we win. */
13211 if (w->cursor.vpos >= 0
13212 /* Line is not continued, otherwise this_line_start_pos
13213 would have been set to 0 in display_line. */
13214 && CHARPOS (this_line_start_pos)
13215 /* Line ends as before. */
13216 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13217 /* Line has same height as before. Otherwise other lines
13218 would have to be shifted up or down. */
13219 && this_line_pixel_height == line_height_before)
13220 {
13221 /* If this is not the window's last line, we must adjust
13222 the charstarts of the lines below. */
13223 if (it.current_y < it.last_visible_y)
13224 {
13225 struct glyph_row *row
13226 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13227 ptrdiff_t delta, delta_bytes;
13228
13229 /* We used to distinguish between two cases here,
13230 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13231 when the line ends in a newline or the end of the
13232 buffer's accessible portion. But both cases did
13233 the same, so they were collapsed. */
13234 delta = (Z
13235 - CHARPOS (tlendpos)
13236 - MATRIX_ROW_START_CHARPOS (row));
13237 delta_bytes = (Z_BYTE
13238 - BYTEPOS (tlendpos)
13239 - MATRIX_ROW_START_BYTEPOS (row));
13240
13241 increment_matrix_positions (w->current_matrix,
13242 this_line_vpos + 1,
13243 w->current_matrix->nrows,
13244 delta, delta_bytes);
13245 }
13246
13247 /* If this row displays text now but previously didn't,
13248 or vice versa, w->window_end_vpos may have to be
13249 adjusted. */
13250 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13251 {
13252 if (w->window_end_vpos < this_line_vpos)
13253 w->window_end_vpos = this_line_vpos;
13254 }
13255 else if (w->window_end_vpos == this_line_vpos
13256 && this_line_vpos > 0)
13257 w->window_end_vpos = this_line_vpos - 1;
13258 w->window_end_valid = 0;
13259
13260 /* Update hint: No need to try to scroll in update_window. */
13261 w->desired_matrix->no_scrolling_p = 1;
13262
13263 #ifdef GLYPH_DEBUG
13264 *w->desired_matrix->method = 0;
13265 debug_method_add (w, "optimization 1");
13266 #endif
13267 #ifdef HAVE_WINDOW_SYSTEM
13268 update_window_fringes (w, 0);
13269 #endif
13270 goto update;
13271 }
13272 else
13273 goto cancel;
13274 }
13275 else if (/* Cursor position hasn't changed. */
13276 PT == w->last_point
13277 /* Make sure the cursor was last displayed
13278 in this window. Otherwise we have to reposition it. */
13279 && 0 <= w->cursor.vpos
13280 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13281 {
13282 if (!must_finish)
13283 {
13284 do_pending_window_change (1);
13285 /* If selected_window changed, redisplay again. */
13286 if (WINDOWP (selected_window)
13287 && (w = XWINDOW (selected_window)) != sw)
13288 goto retry;
13289
13290 /* We used to always goto end_of_redisplay here, but this
13291 isn't enough if we have a blinking cursor. */
13292 if (w->cursor_off_p == w->last_cursor_off_p)
13293 goto end_of_redisplay;
13294 }
13295 goto update;
13296 }
13297 /* If highlighting the region, or if the cursor is in the echo area,
13298 then we can't just move the cursor. */
13299 else if (! (!NILP (Vtransient_mark_mode)
13300 && !NILP (BVAR (current_buffer, mark_active)))
13301 && (EQ (selected_window,
13302 BVAR (current_buffer, last_selected_window))
13303 || highlight_nonselected_windows)
13304 && !w->region_showing
13305 && NILP (Vshow_trailing_whitespace)
13306 && !cursor_in_echo_area)
13307 {
13308 struct it it;
13309 struct glyph_row *row;
13310
13311 /* Skip from tlbufpos to PT and see where it is. Note that
13312 PT may be in invisible text. If so, we will end at the
13313 next visible position. */
13314 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13315 NULL, DEFAULT_FACE_ID);
13316 it.current_x = this_line_start_x;
13317 it.current_y = this_line_y;
13318 it.vpos = this_line_vpos;
13319
13320 /* The call to move_it_to stops in front of PT, but
13321 moves over before-strings. */
13322 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13323
13324 if (it.vpos == this_line_vpos
13325 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13326 row->enabled_p))
13327 {
13328 eassert (this_line_vpos == it.vpos);
13329 eassert (this_line_y == it.current_y);
13330 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13331 #ifdef GLYPH_DEBUG
13332 *w->desired_matrix->method = 0;
13333 debug_method_add (w, "optimization 3");
13334 #endif
13335 goto update;
13336 }
13337 else
13338 goto cancel;
13339 }
13340
13341 cancel:
13342 /* Text changed drastically or point moved off of line. */
13343 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13344 }
13345
13346 CHARPOS (this_line_start_pos) = 0;
13347 consider_all_windows_p |= buffer_shared_and_changed ();
13348 ++clear_face_cache_count;
13349 #ifdef HAVE_WINDOW_SYSTEM
13350 ++clear_image_cache_count;
13351 #endif
13352
13353 /* Build desired matrices, and update the display. If
13354 consider_all_windows_p is non-zero, do it for all windows on all
13355 frames. Otherwise do it for selected_window, only. */
13356
13357 if (consider_all_windows_p)
13358 {
13359 FOR_EACH_FRAME (tail, frame)
13360 XFRAME (frame)->updated_p = 0;
13361
13362 FOR_EACH_FRAME (tail, frame)
13363 {
13364 struct frame *f = XFRAME (frame);
13365
13366 /* We don't have to do anything for unselected terminal
13367 frames. */
13368 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13369 && !EQ (FRAME_TTY (f)->top_frame, frame))
13370 continue;
13371
13372 retry_frame:
13373
13374 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13375 {
13376 /* Mark all the scroll bars to be removed; we'll redeem
13377 the ones we want when we redisplay their windows. */
13378 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13379 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13380
13381 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13382 redisplay_windows (FRAME_ROOT_WINDOW (f));
13383
13384 /* The X error handler may have deleted that frame. */
13385 if (!FRAME_LIVE_P (f))
13386 continue;
13387
13388 /* Any scroll bars which redisplay_windows should have
13389 nuked should now go away. */
13390 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13391 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13392
13393 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13394 {
13395 /* If fonts changed on visible frame, display again. */
13396 if (f->fonts_changed)
13397 {
13398 adjust_frame_glyphs (f);
13399 f->fonts_changed = 0;
13400 goto retry_frame;
13401 }
13402
13403 /* See if we have to hscroll. */
13404 if (!f->already_hscrolled_p)
13405 {
13406 f->already_hscrolled_p = 1;
13407 if (hscroll_windows (f->root_window))
13408 goto retry_frame;
13409 }
13410
13411 /* Prevent various kinds of signals during display
13412 update. stdio is not robust about handling
13413 signals, which can cause an apparent I/O
13414 error. */
13415 if (interrupt_input)
13416 unrequest_sigio ();
13417 STOP_POLLING;
13418
13419 /* Update the display. */
13420 set_window_update_flags (XWINDOW (f->root_window), 1);
13421 pending |= update_frame (f, 0, 0);
13422 f->cursor_type_changed = 0;
13423 f->updated_p = 1;
13424 }
13425 }
13426 }
13427
13428 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13429
13430 if (!pending)
13431 {
13432 /* Do the mark_window_display_accurate after all windows have
13433 been redisplayed because this call resets flags in buffers
13434 which are needed for proper redisplay. */
13435 FOR_EACH_FRAME (tail, frame)
13436 {
13437 struct frame *f = XFRAME (frame);
13438 if (f->updated_p)
13439 {
13440 mark_window_display_accurate (f->root_window, 1);
13441 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13442 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13443 }
13444 }
13445 }
13446 }
13447 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13448 {
13449 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13450 struct frame *mini_frame;
13451
13452 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13453 /* Use list_of_error, not Qerror, so that
13454 we catch only errors and don't run the debugger. */
13455 internal_condition_case_1 (redisplay_window_1, selected_window,
13456 list_of_error,
13457 redisplay_window_error);
13458 if (update_miniwindow_p)
13459 internal_condition_case_1 (redisplay_window_1, mini_window,
13460 list_of_error,
13461 redisplay_window_error);
13462
13463 /* Compare desired and current matrices, perform output. */
13464
13465 update:
13466 /* If fonts changed, display again. */
13467 if (sf->fonts_changed)
13468 goto retry;
13469
13470 /* Prevent various kinds of signals during display update.
13471 stdio is not robust about handling signals,
13472 which can cause an apparent I/O error. */
13473 if (interrupt_input)
13474 unrequest_sigio ();
13475 STOP_POLLING;
13476
13477 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13478 {
13479 if (hscroll_windows (selected_window))
13480 goto retry;
13481
13482 XWINDOW (selected_window)->must_be_updated_p = 1;
13483 pending = update_frame (sf, 0, 0);
13484 sf->cursor_type_changed = 0;
13485 }
13486
13487 /* We may have called echo_area_display at the top of this
13488 function. If the echo area is on another frame, that may
13489 have put text on a frame other than the selected one, so the
13490 above call to update_frame would not have caught it. Catch
13491 it here. */
13492 mini_window = FRAME_MINIBUF_WINDOW (sf);
13493 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13494
13495 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13496 {
13497 XWINDOW (mini_window)->must_be_updated_p = 1;
13498 pending |= update_frame (mini_frame, 0, 0);
13499 mini_frame->cursor_type_changed = 0;
13500 if (!pending && hscroll_windows (mini_window))
13501 goto retry;
13502 }
13503 }
13504
13505 /* If display was paused because of pending input, make sure we do a
13506 thorough update the next time. */
13507 if (pending)
13508 {
13509 /* Prevent the optimization at the beginning of
13510 redisplay_internal that tries a single-line update of the
13511 line containing the cursor in the selected window. */
13512 CHARPOS (this_line_start_pos) = 0;
13513
13514 /* Let the overlay arrow be updated the next time. */
13515 update_overlay_arrows (0);
13516
13517 /* If we pause after scrolling, some rows in the current
13518 matrices of some windows are not valid. */
13519 if (!WINDOW_FULL_WIDTH_P (w)
13520 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13521 update_mode_lines = 1;
13522 }
13523 else
13524 {
13525 if (!consider_all_windows_p)
13526 {
13527 /* This has already been done above if
13528 consider_all_windows_p is set. */
13529 mark_window_display_accurate_1 (w, 1);
13530
13531 /* Say overlay arrows are up to date. */
13532 update_overlay_arrows (1);
13533
13534 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13535 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13536 }
13537
13538 update_mode_lines = 0;
13539 windows_or_buffers_changed = 0;
13540 }
13541
13542 /* Start SIGIO interrupts coming again. Having them off during the
13543 code above makes it less likely one will discard output, but not
13544 impossible, since there might be stuff in the system buffer here.
13545 But it is much hairier to try to do anything about that. */
13546 if (interrupt_input)
13547 request_sigio ();
13548 RESUME_POLLING;
13549
13550 /* If a frame has become visible which was not before, redisplay
13551 again, so that we display it. Expose events for such a frame
13552 (which it gets when becoming visible) don't call the parts of
13553 redisplay constructing glyphs, so simply exposing a frame won't
13554 display anything in this case. So, we have to display these
13555 frames here explicitly. */
13556 if (!pending)
13557 {
13558 int new_count = 0;
13559
13560 FOR_EACH_FRAME (tail, frame)
13561 {
13562 int this_is_visible = 0;
13563
13564 if (XFRAME (frame)->visible)
13565 this_is_visible = 1;
13566
13567 if (this_is_visible)
13568 new_count++;
13569 }
13570
13571 if (new_count != number_of_visible_frames)
13572 windows_or_buffers_changed++;
13573 }
13574
13575 /* Change frame size now if a change is pending. */
13576 do_pending_window_change (1);
13577
13578 /* If we just did a pending size change, or have additional
13579 visible frames, or selected_window changed, redisplay again. */
13580 if ((windows_or_buffers_changed && !pending)
13581 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13582 goto retry;
13583
13584 /* Clear the face and image caches.
13585
13586 We used to do this only if consider_all_windows_p. But the cache
13587 needs to be cleared if a timer creates images in the current
13588 buffer (e.g. the test case in Bug#6230). */
13589
13590 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13591 {
13592 clear_face_cache (0);
13593 clear_face_cache_count = 0;
13594 }
13595
13596 #ifdef HAVE_WINDOW_SYSTEM
13597 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13598 {
13599 clear_image_caches (Qnil);
13600 clear_image_cache_count = 0;
13601 }
13602 #endif /* HAVE_WINDOW_SYSTEM */
13603
13604 end_of_redisplay:
13605 unbind_to (count, Qnil);
13606 RESUME_POLLING;
13607 }
13608
13609
13610 /* Redisplay, but leave alone any recent echo area message unless
13611 another message has been requested in its place.
13612
13613 This is useful in situations where you need to redisplay but no
13614 user action has occurred, making it inappropriate for the message
13615 area to be cleared. See tracking_off and
13616 wait_reading_process_output for examples of these situations.
13617
13618 FROM_WHERE is an integer saying from where this function was
13619 called. This is useful for debugging. */
13620
13621 void
13622 redisplay_preserve_echo_area (int from_where)
13623 {
13624 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13625
13626 if (!NILP (echo_area_buffer[1]))
13627 {
13628 /* We have a previously displayed message, but no current
13629 message. Redisplay the previous message. */
13630 display_last_displayed_message_p = 1;
13631 redisplay_internal ();
13632 display_last_displayed_message_p = 0;
13633 }
13634 else
13635 redisplay_internal ();
13636
13637 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13638 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13639 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13640 }
13641
13642
13643 /* Function registered with record_unwind_protect in redisplay_internal. */
13644
13645 static void
13646 unwind_redisplay (void)
13647 {
13648 redisplaying_p = 0;
13649 }
13650
13651
13652 /* Mark the display of leaf window W as accurate or inaccurate.
13653 If ACCURATE_P is non-zero mark display of W as accurate. If
13654 ACCURATE_P is zero, arrange for W to be redisplayed the next
13655 time redisplay_internal is called. */
13656
13657 static void
13658 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13659 {
13660 struct buffer *b = XBUFFER (w->contents);
13661
13662 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13663 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13664 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13665
13666 if (accurate_p)
13667 {
13668 b->clip_changed = 0;
13669 b->prevent_redisplay_optimizations_p = 0;
13670
13671 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13672 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13673 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13674 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13675
13676 w->current_matrix->buffer = b;
13677 w->current_matrix->begv = BUF_BEGV (b);
13678 w->current_matrix->zv = BUF_ZV (b);
13679
13680 w->last_cursor_vpos = w->cursor.vpos;
13681 w->last_cursor_off_p = w->cursor_off_p;
13682
13683 if (w == XWINDOW (selected_window))
13684 w->last_point = BUF_PT (b);
13685 else
13686 w->last_point = marker_position (w->pointm);
13687
13688 w->window_end_valid = 1;
13689 w->update_mode_line = 0;
13690 }
13691 }
13692
13693
13694 /* Mark the display of windows in the window tree rooted at WINDOW as
13695 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13696 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13697 be redisplayed the next time redisplay_internal is called. */
13698
13699 void
13700 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13701 {
13702 struct window *w;
13703
13704 for (; !NILP (window); window = w->next)
13705 {
13706 w = XWINDOW (window);
13707 if (WINDOWP (w->contents))
13708 mark_window_display_accurate (w->contents, accurate_p);
13709 else
13710 mark_window_display_accurate_1 (w, accurate_p);
13711 }
13712
13713 if (accurate_p)
13714 update_overlay_arrows (1);
13715 else
13716 /* Force a thorough redisplay the next time by setting
13717 last_arrow_position and last_arrow_string to t, which is
13718 unequal to any useful value of Voverlay_arrow_... */
13719 update_overlay_arrows (-1);
13720 }
13721
13722
13723 /* Return value in display table DP (Lisp_Char_Table *) for character
13724 C. Since a display table doesn't have any parent, we don't have to
13725 follow parent. Do not call this function directly but use the
13726 macro DISP_CHAR_VECTOR. */
13727
13728 Lisp_Object
13729 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13730 {
13731 Lisp_Object val;
13732
13733 if (ASCII_CHAR_P (c))
13734 {
13735 val = dp->ascii;
13736 if (SUB_CHAR_TABLE_P (val))
13737 val = XSUB_CHAR_TABLE (val)->contents[c];
13738 }
13739 else
13740 {
13741 Lisp_Object table;
13742
13743 XSETCHAR_TABLE (table, dp);
13744 val = char_table_ref (table, c);
13745 }
13746 if (NILP (val))
13747 val = dp->defalt;
13748 return val;
13749 }
13750
13751
13752 \f
13753 /***********************************************************************
13754 Window Redisplay
13755 ***********************************************************************/
13756
13757 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13758
13759 static void
13760 redisplay_windows (Lisp_Object window)
13761 {
13762 while (!NILP (window))
13763 {
13764 struct window *w = XWINDOW (window);
13765
13766 if (WINDOWP (w->contents))
13767 redisplay_windows (w->contents);
13768 else if (BUFFERP (w->contents))
13769 {
13770 displayed_buffer = XBUFFER (w->contents);
13771 /* Use list_of_error, not Qerror, so that
13772 we catch only errors and don't run the debugger. */
13773 internal_condition_case_1 (redisplay_window_0, window,
13774 list_of_error,
13775 redisplay_window_error);
13776 }
13777
13778 window = w->next;
13779 }
13780 }
13781
13782 static Lisp_Object
13783 redisplay_window_error (Lisp_Object ignore)
13784 {
13785 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13786 return Qnil;
13787 }
13788
13789 static Lisp_Object
13790 redisplay_window_0 (Lisp_Object window)
13791 {
13792 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13793 redisplay_window (window, 0);
13794 return Qnil;
13795 }
13796
13797 static Lisp_Object
13798 redisplay_window_1 (Lisp_Object window)
13799 {
13800 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13801 redisplay_window (window, 1);
13802 return Qnil;
13803 }
13804 \f
13805
13806 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13807 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13808 which positions recorded in ROW differ from current buffer
13809 positions.
13810
13811 Return 0 if cursor is not on this row, 1 otherwise. */
13812
13813 static int
13814 set_cursor_from_row (struct window *w, struct glyph_row *row,
13815 struct glyph_matrix *matrix,
13816 ptrdiff_t delta, ptrdiff_t delta_bytes,
13817 int dy, int dvpos)
13818 {
13819 struct glyph *glyph = row->glyphs[TEXT_AREA];
13820 struct glyph *end = glyph + row->used[TEXT_AREA];
13821 struct glyph *cursor = NULL;
13822 /* The last known character position in row. */
13823 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13824 int x = row->x;
13825 ptrdiff_t pt_old = PT - delta;
13826 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13827 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13828 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13829 /* A glyph beyond the edge of TEXT_AREA which we should never
13830 touch. */
13831 struct glyph *glyphs_end = end;
13832 /* Non-zero means we've found a match for cursor position, but that
13833 glyph has the avoid_cursor_p flag set. */
13834 int match_with_avoid_cursor = 0;
13835 /* Non-zero means we've seen at least one glyph that came from a
13836 display string. */
13837 int string_seen = 0;
13838 /* Largest and smallest buffer positions seen so far during scan of
13839 glyph row. */
13840 ptrdiff_t bpos_max = pos_before;
13841 ptrdiff_t bpos_min = pos_after;
13842 /* Last buffer position covered by an overlay string with an integer
13843 `cursor' property. */
13844 ptrdiff_t bpos_covered = 0;
13845 /* Non-zero means the display string on which to display the cursor
13846 comes from a text property, not from an overlay. */
13847 int string_from_text_prop = 0;
13848
13849 /* Don't even try doing anything if called for a mode-line or
13850 header-line row, since the rest of the code isn't prepared to
13851 deal with such calamities. */
13852 eassert (!row->mode_line_p);
13853 if (row->mode_line_p)
13854 return 0;
13855
13856 /* Skip over glyphs not having an object at the start and the end of
13857 the row. These are special glyphs like truncation marks on
13858 terminal frames. */
13859 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13860 {
13861 if (!row->reversed_p)
13862 {
13863 while (glyph < end
13864 && INTEGERP (glyph->object)
13865 && glyph->charpos < 0)
13866 {
13867 x += glyph->pixel_width;
13868 ++glyph;
13869 }
13870 while (end > glyph
13871 && INTEGERP ((end - 1)->object)
13872 /* CHARPOS is zero for blanks and stretch glyphs
13873 inserted by extend_face_to_end_of_line. */
13874 && (end - 1)->charpos <= 0)
13875 --end;
13876 glyph_before = glyph - 1;
13877 glyph_after = end;
13878 }
13879 else
13880 {
13881 struct glyph *g;
13882
13883 /* If the glyph row is reversed, we need to process it from back
13884 to front, so swap the edge pointers. */
13885 glyphs_end = end = glyph - 1;
13886 glyph += row->used[TEXT_AREA] - 1;
13887
13888 while (glyph > end + 1
13889 && INTEGERP (glyph->object)
13890 && glyph->charpos < 0)
13891 {
13892 --glyph;
13893 x -= glyph->pixel_width;
13894 }
13895 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13896 --glyph;
13897 /* By default, in reversed rows we put the cursor on the
13898 rightmost (first in the reading order) glyph. */
13899 for (g = end + 1; g < glyph; g++)
13900 x += g->pixel_width;
13901 while (end < glyph
13902 && INTEGERP ((end + 1)->object)
13903 && (end + 1)->charpos <= 0)
13904 ++end;
13905 glyph_before = glyph + 1;
13906 glyph_after = end;
13907 }
13908 }
13909 else if (row->reversed_p)
13910 {
13911 /* In R2L rows that don't display text, put the cursor on the
13912 rightmost glyph. Case in point: an empty last line that is
13913 part of an R2L paragraph. */
13914 cursor = end - 1;
13915 /* Avoid placing the cursor on the last glyph of the row, where
13916 on terminal frames we hold the vertical border between
13917 adjacent windows. */
13918 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13919 && !WINDOW_RIGHTMOST_P (w)
13920 && cursor == row->glyphs[LAST_AREA] - 1)
13921 cursor--;
13922 x = -1; /* will be computed below, at label compute_x */
13923 }
13924
13925 /* Step 1: Try to find the glyph whose character position
13926 corresponds to point. If that's not possible, find 2 glyphs
13927 whose character positions are the closest to point, one before
13928 point, the other after it. */
13929 if (!row->reversed_p)
13930 while (/* not marched to end of glyph row */
13931 glyph < end
13932 /* glyph was not inserted by redisplay for internal purposes */
13933 && !INTEGERP (glyph->object))
13934 {
13935 if (BUFFERP (glyph->object))
13936 {
13937 ptrdiff_t dpos = glyph->charpos - pt_old;
13938
13939 if (glyph->charpos > bpos_max)
13940 bpos_max = glyph->charpos;
13941 if (glyph->charpos < bpos_min)
13942 bpos_min = glyph->charpos;
13943 if (!glyph->avoid_cursor_p)
13944 {
13945 /* If we hit point, we've found the glyph on which to
13946 display the cursor. */
13947 if (dpos == 0)
13948 {
13949 match_with_avoid_cursor = 0;
13950 break;
13951 }
13952 /* See if we've found a better approximation to
13953 POS_BEFORE or to POS_AFTER. */
13954 if (0 > dpos && dpos > pos_before - pt_old)
13955 {
13956 pos_before = glyph->charpos;
13957 glyph_before = glyph;
13958 }
13959 else if (0 < dpos && dpos < pos_after - pt_old)
13960 {
13961 pos_after = glyph->charpos;
13962 glyph_after = glyph;
13963 }
13964 }
13965 else if (dpos == 0)
13966 match_with_avoid_cursor = 1;
13967 }
13968 else if (STRINGP (glyph->object))
13969 {
13970 Lisp_Object chprop;
13971 ptrdiff_t glyph_pos = glyph->charpos;
13972
13973 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13974 glyph->object);
13975 if (!NILP (chprop))
13976 {
13977 /* If the string came from a `display' text property,
13978 look up the buffer position of that property and
13979 use that position to update bpos_max, as if we
13980 actually saw such a position in one of the row's
13981 glyphs. This helps with supporting integer values
13982 of `cursor' property on the display string in
13983 situations where most or all of the row's buffer
13984 text is completely covered by display properties,
13985 so that no glyph with valid buffer positions is
13986 ever seen in the row. */
13987 ptrdiff_t prop_pos =
13988 string_buffer_position_lim (glyph->object, pos_before,
13989 pos_after, 0);
13990
13991 if (prop_pos >= pos_before)
13992 bpos_max = prop_pos - 1;
13993 }
13994 if (INTEGERP (chprop))
13995 {
13996 bpos_covered = bpos_max + XINT (chprop);
13997 /* If the `cursor' property covers buffer positions up
13998 to and including point, we should display cursor on
13999 this glyph. Note that, if a `cursor' property on one
14000 of the string's characters has an integer value, we
14001 will break out of the loop below _before_ we get to
14002 the position match above. IOW, integer values of
14003 the `cursor' property override the "exact match for
14004 point" strategy of positioning the cursor. */
14005 /* Implementation note: bpos_max == pt_old when, e.g.,
14006 we are in an empty line, where bpos_max is set to
14007 MATRIX_ROW_START_CHARPOS, see above. */
14008 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14009 {
14010 cursor = glyph;
14011 break;
14012 }
14013 }
14014
14015 string_seen = 1;
14016 }
14017 x += glyph->pixel_width;
14018 ++glyph;
14019 }
14020 else if (glyph > end) /* row is reversed */
14021 while (!INTEGERP (glyph->object))
14022 {
14023 if (BUFFERP (glyph->object))
14024 {
14025 ptrdiff_t dpos = glyph->charpos - pt_old;
14026
14027 if (glyph->charpos > bpos_max)
14028 bpos_max = glyph->charpos;
14029 if (glyph->charpos < bpos_min)
14030 bpos_min = glyph->charpos;
14031 if (!glyph->avoid_cursor_p)
14032 {
14033 if (dpos == 0)
14034 {
14035 match_with_avoid_cursor = 0;
14036 break;
14037 }
14038 if (0 > dpos && dpos > pos_before - pt_old)
14039 {
14040 pos_before = glyph->charpos;
14041 glyph_before = glyph;
14042 }
14043 else if (0 < dpos && dpos < pos_after - pt_old)
14044 {
14045 pos_after = glyph->charpos;
14046 glyph_after = glyph;
14047 }
14048 }
14049 else if (dpos == 0)
14050 match_with_avoid_cursor = 1;
14051 }
14052 else if (STRINGP (glyph->object))
14053 {
14054 Lisp_Object chprop;
14055 ptrdiff_t glyph_pos = glyph->charpos;
14056
14057 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14058 glyph->object);
14059 if (!NILP (chprop))
14060 {
14061 ptrdiff_t prop_pos =
14062 string_buffer_position_lim (glyph->object, pos_before,
14063 pos_after, 0);
14064
14065 if (prop_pos >= pos_before)
14066 bpos_max = prop_pos - 1;
14067 }
14068 if (INTEGERP (chprop))
14069 {
14070 bpos_covered = bpos_max + XINT (chprop);
14071 /* If the `cursor' property covers buffer positions up
14072 to and including point, we should display cursor on
14073 this glyph. */
14074 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14075 {
14076 cursor = glyph;
14077 break;
14078 }
14079 }
14080 string_seen = 1;
14081 }
14082 --glyph;
14083 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14084 {
14085 x--; /* can't use any pixel_width */
14086 break;
14087 }
14088 x -= glyph->pixel_width;
14089 }
14090
14091 /* Step 2: If we didn't find an exact match for point, we need to
14092 look for a proper place to put the cursor among glyphs between
14093 GLYPH_BEFORE and GLYPH_AFTER. */
14094 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14095 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14096 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14097 {
14098 /* An empty line has a single glyph whose OBJECT is zero and
14099 whose CHARPOS is the position of a newline on that line.
14100 Note that on a TTY, there are more glyphs after that, which
14101 were produced by extend_face_to_end_of_line, but their
14102 CHARPOS is zero or negative. */
14103 int empty_line_p =
14104 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14105 && INTEGERP (glyph->object) && glyph->charpos > 0
14106 /* On a TTY, continued and truncated rows also have a glyph at
14107 their end whose OBJECT is zero and whose CHARPOS is
14108 positive (the continuation and truncation glyphs), but such
14109 rows are obviously not "empty". */
14110 && !(row->continued_p || row->truncated_on_right_p);
14111
14112 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14113 {
14114 ptrdiff_t ellipsis_pos;
14115
14116 /* Scan back over the ellipsis glyphs. */
14117 if (!row->reversed_p)
14118 {
14119 ellipsis_pos = (glyph - 1)->charpos;
14120 while (glyph > row->glyphs[TEXT_AREA]
14121 && (glyph - 1)->charpos == ellipsis_pos)
14122 glyph--, x -= glyph->pixel_width;
14123 /* That loop always goes one position too far, including
14124 the glyph before the ellipsis. So scan forward over
14125 that one. */
14126 x += glyph->pixel_width;
14127 glyph++;
14128 }
14129 else /* row is reversed */
14130 {
14131 ellipsis_pos = (glyph + 1)->charpos;
14132 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14133 && (glyph + 1)->charpos == ellipsis_pos)
14134 glyph++, x += glyph->pixel_width;
14135 x -= glyph->pixel_width;
14136 glyph--;
14137 }
14138 }
14139 else if (match_with_avoid_cursor)
14140 {
14141 cursor = glyph_after;
14142 x = -1;
14143 }
14144 else if (string_seen)
14145 {
14146 int incr = row->reversed_p ? -1 : +1;
14147
14148 /* Need to find the glyph that came out of a string which is
14149 present at point. That glyph is somewhere between
14150 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14151 positioned between POS_BEFORE and POS_AFTER in the
14152 buffer. */
14153 struct glyph *start, *stop;
14154 ptrdiff_t pos = pos_before;
14155
14156 x = -1;
14157
14158 /* If the row ends in a newline from a display string,
14159 reordering could have moved the glyphs belonging to the
14160 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14161 in this case we extend the search to the last glyph in
14162 the row that was not inserted by redisplay. */
14163 if (row->ends_in_newline_from_string_p)
14164 {
14165 glyph_after = end;
14166 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14167 }
14168
14169 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14170 correspond to POS_BEFORE and POS_AFTER, respectively. We
14171 need START and STOP in the order that corresponds to the
14172 row's direction as given by its reversed_p flag. If the
14173 directionality of characters between POS_BEFORE and
14174 POS_AFTER is the opposite of the row's base direction,
14175 these characters will have been reordered for display,
14176 and we need to reverse START and STOP. */
14177 if (!row->reversed_p)
14178 {
14179 start = min (glyph_before, glyph_after);
14180 stop = max (glyph_before, glyph_after);
14181 }
14182 else
14183 {
14184 start = max (glyph_before, glyph_after);
14185 stop = min (glyph_before, glyph_after);
14186 }
14187 for (glyph = start + incr;
14188 row->reversed_p ? glyph > stop : glyph < stop; )
14189 {
14190
14191 /* Any glyphs that come from the buffer are here because
14192 of bidi reordering. Skip them, and only pay
14193 attention to glyphs that came from some string. */
14194 if (STRINGP (glyph->object))
14195 {
14196 Lisp_Object str;
14197 ptrdiff_t tem;
14198 /* If the display property covers the newline, we
14199 need to search for it one position farther. */
14200 ptrdiff_t lim = pos_after
14201 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14202
14203 string_from_text_prop = 0;
14204 str = glyph->object;
14205 tem = string_buffer_position_lim (str, pos, lim, 0);
14206 if (tem == 0 /* from overlay */
14207 || pos <= tem)
14208 {
14209 /* If the string from which this glyph came is
14210 found in the buffer at point, or at position
14211 that is closer to point than pos_after, then
14212 we've found the glyph we've been looking for.
14213 If it comes from an overlay (tem == 0), and
14214 it has the `cursor' property on one of its
14215 glyphs, record that glyph as a candidate for
14216 displaying the cursor. (As in the
14217 unidirectional version, we will display the
14218 cursor on the last candidate we find.) */
14219 if (tem == 0
14220 || tem == pt_old
14221 || (tem - pt_old > 0 && tem < pos_after))
14222 {
14223 /* The glyphs from this string could have
14224 been reordered. Find the one with the
14225 smallest string position. Or there could
14226 be a character in the string with the
14227 `cursor' property, which means display
14228 cursor on that character's glyph. */
14229 ptrdiff_t strpos = glyph->charpos;
14230
14231 if (tem)
14232 {
14233 cursor = glyph;
14234 string_from_text_prop = 1;
14235 }
14236 for ( ;
14237 (row->reversed_p ? glyph > stop : glyph < stop)
14238 && EQ (glyph->object, str);
14239 glyph += incr)
14240 {
14241 Lisp_Object cprop;
14242 ptrdiff_t gpos = glyph->charpos;
14243
14244 cprop = Fget_char_property (make_number (gpos),
14245 Qcursor,
14246 glyph->object);
14247 if (!NILP (cprop))
14248 {
14249 cursor = glyph;
14250 break;
14251 }
14252 if (tem && glyph->charpos < strpos)
14253 {
14254 strpos = glyph->charpos;
14255 cursor = glyph;
14256 }
14257 }
14258
14259 if (tem == pt_old
14260 || (tem - pt_old > 0 && tem < pos_after))
14261 goto compute_x;
14262 }
14263 if (tem)
14264 pos = tem + 1; /* don't find previous instances */
14265 }
14266 /* This string is not what we want; skip all of the
14267 glyphs that came from it. */
14268 while ((row->reversed_p ? glyph > stop : glyph < stop)
14269 && EQ (glyph->object, str))
14270 glyph += incr;
14271 }
14272 else
14273 glyph += incr;
14274 }
14275
14276 /* If we reached the end of the line, and END was from a string,
14277 the cursor is not on this line. */
14278 if (cursor == NULL
14279 && (row->reversed_p ? glyph <= end : glyph >= end)
14280 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14281 && STRINGP (end->object)
14282 && row->continued_p)
14283 return 0;
14284 }
14285 /* A truncated row may not include PT among its character positions.
14286 Setting the cursor inside the scroll margin will trigger
14287 recalculation of hscroll in hscroll_window_tree. But if a
14288 display string covers point, defer to the string-handling
14289 code below to figure this out. */
14290 else if (row->truncated_on_left_p && pt_old < bpos_min)
14291 {
14292 cursor = glyph_before;
14293 x = -1;
14294 }
14295 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14296 /* Zero-width characters produce no glyphs. */
14297 || (!empty_line_p
14298 && (row->reversed_p
14299 ? glyph_after > glyphs_end
14300 : glyph_after < glyphs_end)))
14301 {
14302 cursor = glyph_after;
14303 x = -1;
14304 }
14305 }
14306
14307 compute_x:
14308 if (cursor != NULL)
14309 glyph = cursor;
14310 else if (glyph == glyphs_end
14311 && pos_before == pos_after
14312 && STRINGP ((row->reversed_p
14313 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14314 : row->glyphs[TEXT_AREA])->object))
14315 {
14316 /* If all the glyphs of this row came from strings, put the
14317 cursor on the first glyph of the row. This avoids having the
14318 cursor outside of the text area in this very rare and hard
14319 use case. */
14320 glyph =
14321 row->reversed_p
14322 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14323 : row->glyphs[TEXT_AREA];
14324 }
14325 if (x < 0)
14326 {
14327 struct glyph *g;
14328
14329 /* Need to compute x that corresponds to GLYPH. */
14330 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14331 {
14332 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14333 emacs_abort ();
14334 x += g->pixel_width;
14335 }
14336 }
14337
14338 /* ROW could be part of a continued line, which, under bidi
14339 reordering, might have other rows whose start and end charpos
14340 occlude point. Only set w->cursor if we found a better
14341 approximation to the cursor position than we have from previously
14342 examined candidate rows belonging to the same continued line. */
14343 if (/* we already have a candidate row */
14344 w->cursor.vpos >= 0
14345 /* that candidate is not the row we are processing */
14346 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14347 /* Make sure cursor.vpos specifies a row whose start and end
14348 charpos occlude point, and it is valid candidate for being a
14349 cursor-row. This is because some callers of this function
14350 leave cursor.vpos at the row where the cursor was displayed
14351 during the last redisplay cycle. */
14352 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14353 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14354 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14355 {
14356 struct glyph *g1 =
14357 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14358
14359 /* Don't consider glyphs that are outside TEXT_AREA. */
14360 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14361 return 0;
14362 /* Keep the candidate whose buffer position is the closest to
14363 point or has the `cursor' property. */
14364 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14365 w->cursor.hpos >= 0
14366 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14367 && ((BUFFERP (g1->object)
14368 && (g1->charpos == pt_old /* an exact match always wins */
14369 || (BUFFERP (glyph->object)
14370 && eabs (g1->charpos - pt_old)
14371 < eabs (glyph->charpos - pt_old))))
14372 /* previous candidate is a glyph from a string that has
14373 a non-nil `cursor' property */
14374 || (STRINGP (g1->object)
14375 && (!NILP (Fget_char_property (make_number (g1->charpos),
14376 Qcursor, g1->object))
14377 /* previous candidate is from the same display
14378 string as this one, and the display string
14379 came from a text property */
14380 || (EQ (g1->object, glyph->object)
14381 && string_from_text_prop)
14382 /* this candidate is from newline and its
14383 position is not an exact match */
14384 || (INTEGERP (glyph->object)
14385 && glyph->charpos != pt_old)))))
14386 return 0;
14387 /* If this candidate gives an exact match, use that. */
14388 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14389 /* If this candidate is a glyph created for the
14390 terminating newline of a line, and point is on that
14391 newline, it wins because it's an exact match. */
14392 || (!row->continued_p
14393 && INTEGERP (glyph->object)
14394 && glyph->charpos == 0
14395 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14396 /* Otherwise, keep the candidate that comes from a row
14397 spanning less buffer positions. This may win when one or
14398 both candidate positions are on glyphs that came from
14399 display strings, for which we cannot compare buffer
14400 positions. */
14401 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14402 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14403 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14404 return 0;
14405 }
14406 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14407 w->cursor.x = x;
14408 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14409 w->cursor.y = row->y + dy;
14410
14411 if (w == XWINDOW (selected_window))
14412 {
14413 if (!row->continued_p
14414 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14415 && row->x == 0)
14416 {
14417 this_line_buffer = XBUFFER (w->contents);
14418
14419 CHARPOS (this_line_start_pos)
14420 = MATRIX_ROW_START_CHARPOS (row) + delta;
14421 BYTEPOS (this_line_start_pos)
14422 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14423
14424 CHARPOS (this_line_end_pos)
14425 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14426 BYTEPOS (this_line_end_pos)
14427 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14428
14429 this_line_y = w->cursor.y;
14430 this_line_pixel_height = row->height;
14431 this_line_vpos = w->cursor.vpos;
14432 this_line_start_x = row->x;
14433 }
14434 else
14435 CHARPOS (this_line_start_pos) = 0;
14436 }
14437
14438 return 1;
14439 }
14440
14441
14442 /* Run window scroll functions, if any, for WINDOW with new window
14443 start STARTP. Sets the window start of WINDOW to that position.
14444
14445 We assume that the window's buffer is really current. */
14446
14447 static struct text_pos
14448 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14449 {
14450 struct window *w = XWINDOW (window);
14451 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14452
14453 eassert (current_buffer == XBUFFER (w->contents));
14454
14455 if (!NILP (Vwindow_scroll_functions))
14456 {
14457 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14458 make_number (CHARPOS (startp)));
14459 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14460 /* In case the hook functions switch buffers. */
14461 set_buffer_internal (XBUFFER (w->contents));
14462 }
14463
14464 return startp;
14465 }
14466
14467
14468 /* Make sure the line containing the cursor is fully visible.
14469 A value of 1 means there is nothing to be done.
14470 (Either the line is fully visible, or it cannot be made so,
14471 or we cannot tell.)
14472
14473 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14474 is higher than window.
14475
14476 A value of 0 means the caller should do scrolling
14477 as if point had gone off the screen. */
14478
14479 static int
14480 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14481 {
14482 struct glyph_matrix *matrix;
14483 struct glyph_row *row;
14484 int window_height;
14485
14486 if (!make_cursor_line_fully_visible_p)
14487 return 1;
14488
14489 /* It's not always possible to find the cursor, e.g, when a window
14490 is full of overlay strings. Don't do anything in that case. */
14491 if (w->cursor.vpos < 0)
14492 return 1;
14493
14494 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14495 row = MATRIX_ROW (matrix, w->cursor.vpos);
14496
14497 /* If the cursor row is not partially visible, there's nothing to do. */
14498 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14499 return 1;
14500
14501 /* If the row the cursor is in is taller than the window's height,
14502 it's not clear what to do, so do nothing. */
14503 window_height = window_box_height (w);
14504 if (row->height >= window_height)
14505 {
14506 if (!force_p || MINI_WINDOW_P (w)
14507 || w->vscroll || w->cursor.vpos == 0)
14508 return 1;
14509 }
14510 return 0;
14511 }
14512
14513
14514 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14515 non-zero means only WINDOW is redisplayed in redisplay_internal.
14516 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14517 in redisplay_window to bring a partially visible line into view in
14518 the case that only the cursor has moved.
14519
14520 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14521 last screen line's vertical height extends past the end of the screen.
14522
14523 Value is
14524
14525 1 if scrolling succeeded
14526
14527 0 if scrolling didn't find point.
14528
14529 -1 if new fonts have been loaded so that we must interrupt
14530 redisplay, adjust glyph matrices, and try again. */
14531
14532 enum
14533 {
14534 SCROLLING_SUCCESS,
14535 SCROLLING_FAILED,
14536 SCROLLING_NEED_LARGER_MATRICES
14537 };
14538
14539 /* If scroll-conservatively is more than this, never recenter.
14540
14541 If you change this, don't forget to update the doc string of
14542 `scroll-conservatively' and the Emacs manual. */
14543 #define SCROLL_LIMIT 100
14544
14545 static int
14546 try_scrolling (Lisp_Object window, int just_this_one_p,
14547 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14548 int temp_scroll_step, int last_line_misfit)
14549 {
14550 struct window *w = XWINDOW (window);
14551 struct frame *f = XFRAME (w->frame);
14552 struct text_pos pos, startp;
14553 struct it it;
14554 int this_scroll_margin, scroll_max, rc, height;
14555 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14556 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14557 Lisp_Object aggressive;
14558 /* We will never try scrolling more than this number of lines. */
14559 int scroll_limit = SCROLL_LIMIT;
14560 int frame_line_height = default_line_pixel_height (w);
14561 int window_total_lines
14562 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
14563
14564 #ifdef GLYPH_DEBUG
14565 debug_method_add (w, "try_scrolling");
14566 #endif
14567
14568 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14569
14570 /* Compute scroll margin height in pixels. We scroll when point is
14571 within this distance from the top or bottom of the window. */
14572 if (scroll_margin > 0)
14573 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
14574 * frame_line_height;
14575 else
14576 this_scroll_margin = 0;
14577
14578 /* Force arg_scroll_conservatively to have a reasonable value, to
14579 avoid scrolling too far away with slow move_it_* functions. Note
14580 that the user can supply scroll-conservatively equal to
14581 `most-positive-fixnum', which can be larger than INT_MAX. */
14582 if (arg_scroll_conservatively > scroll_limit)
14583 {
14584 arg_scroll_conservatively = scroll_limit + 1;
14585 scroll_max = scroll_limit * frame_line_height;
14586 }
14587 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14588 /* Compute how much we should try to scroll maximally to bring
14589 point into view. */
14590 scroll_max = (max (scroll_step,
14591 max (arg_scroll_conservatively, temp_scroll_step))
14592 * frame_line_height);
14593 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14594 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14595 /* We're trying to scroll because of aggressive scrolling but no
14596 scroll_step is set. Choose an arbitrary one. */
14597 scroll_max = 10 * frame_line_height;
14598 else
14599 scroll_max = 0;
14600
14601 too_near_end:
14602
14603 /* Decide whether to scroll down. */
14604 if (PT > CHARPOS (startp))
14605 {
14606 int scroll_margin_y;
14607
14608 /* Compute the pixel ypos of the scroll margin, then move IT to
14609 either that ypos or PT, whichever comes first. */
14610 start_display (&it, w, startp);
14611 scroll_margin_y = it.last_visible_y - this_scroll_margin
14612 - frame_line_height * extra_scroll_margin_lines;
14613 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14614 (MOVE_TO_POS | MOVE_TO_Y));
14615
14616 if (PT > CHARPOS (it.current.pos))
14617 {
14618 int y0 = line_bottom_y (&it);
14619 /* Compute how many pixels below window bottom to stop searching
14620 for PT. This avoids costly search for PT that is far away if
14621 the user limited scrolling by a small number of lines, but
14622 always finds PT if scroll_conservatively is set to a large
14623 number, such as most-positive-fixnum. */
14624 int slack = max (scroll_max, 10 * frame_line_height);
14625 int y_to_move = it.last_visible_y + slack;
14626
14627 /* Compute the distance from the scroll margin to PT or to
14628 the scroll limit, whichever comes first. This should
14629 include the height of the cursor line, to make that line
14630 fully visible. */
14631 move_it_to (&it, PT, -1, y_to_move,
14632 -1, MOVE_TO_POS | MOVE_TO_Y);
14633 dy = line_bottom_y (&it) - y0;
14634
14635 if (dy > scroll_max)
14636 return SCROLLING_FAILED;
14637
14638 if (dy > 0)
14639 scroll_down_p = 1;
14640 }
14641 }
14642
14643 if (scroll_down_p)
14644 {
14645 /* Point is in or below the bottom scroll margin, so move the
14646 window start down. If scrolling conservatively, move it just
14647 enough down to make point visible. If scroll_step is set,
14648 move it down by scroll_step. */
14649 if (arg_scroll_conservatively)
14650 amount_to_scroll
14651 = min (max (dy, frame_line_height),
14652 frame_line_height * arg_scroll_conservatively);
14653 else if (scroll_step || temp_scroll_step)
14654 amount_to_scroll = scroll_max;
14655 else
14656 {
14657 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14658 height = WINDOW_BOX_TEXT_HEIGHT (w);
14659 if (NUMBERP (aggressive))
14660 {
14661 double float_amount = XFLOATINT (aggressive) * height;
14662 int aggressive_scroll = float_amount;
14663 if (aggressive_scroll == 0 && float_amount > 0)
14664 aggressive_scroll = 1;
14665 /* Don't let point enter the scroll margin near top of
14666 the window. This could happen if the value of
14667 scroll_up_aggressively is too large and there are
14668 non-zero margins, because scroll_up_aggressively
14669 means put point that fraction of window height
14670 _from_the_bottom_margin_. */
14671 if (aggressive_scroll + 2*this_scroll_margin > height)
14672 aggressive_scroll = height - 2*this_scroll_margin;
14673 amount_to_scroll = dy + aggressive_scroll;
14674 }
14675 }
14676
14677 if (amount_to_scroll <= 0)
14678 return SCROLLING_FAILED;
14679
14680 start_display (&it, w, startp);
14681 if (arg_scroll_conservatively <= scroll_limit)
14682 move_it_vertically (&it, amount_to_scroll);
14683 else
14684 {
14685 /* Extra precision for users who set scroll-conservatively
14686 to a large number: make sure the amount we scroll
14687 the window start is never less than amount_to_scroll,
14688 which was computed as distance from window bottom to
14689 point. This matters when lines at window top and lines
14690 below window bottom have different height. */
14691 struct it it1;
14692 void *it1data = NULL;
14693 /* We use a temporary it1 because line_bottom_y can modify
14694 its argument, if it moves one line down; see there. */
14695 int start_y;
14696
14697 SAVE_IT (it1, it, it1data);
14698 start_y = line_bottom_y (&it1);
14699 do {
14700 RESTORE_IT (&it, &it, it1data);
14701 move_it_by_lines (&it, 1);
14702 SAVE_IT (it1, it, it1data);
14703 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14704 }
14705
14706 /* If STARTP is unchanged, move it down another screen line. */
14707 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14708 move_it_by_lines (&it, 1);
14709 startp = it.current.pos;
14710 }
14711 else
14712 {
14713 struct text_pos scroll_margin_pos = startp;
14714 int y_offset = 0;
14715
14716 /* See if point is inside the scroll margin at the top of the
14717 window. */
14718 if (this_scroll_margin)
14719 {
14720 int y_start;
14721
14722 start_display (&it, w, startp);
14723 y_start = it.current_y;
14724 move_it_vertically (&it, this_scroll_margin);
14725 scroll_margin_pos = it.current.pos;
14726 /* If we didn't move enough before hitting ZV, request
14727 additional amount of scroll, to move point out of the
14728 scroll margin. */
14729 if (IT_CHARPOS (it) == ZV
14730 && it.current_y - y_start < this_scroll_margin)
14731 y_offset = this_scroll_margin - (it.current_y - y_start);
14732 }
14733
14734 if (PT < CHARPOS (scroll_margin_pos))
14735 {
14736 /* Point is in the scroll margin at the top of the window or
14737 above what is displayed in the window. */
14738 int y0, y_to_move;
14739
14740 /* Compute the vertical distance from PT to the scroll
14741 margin position. Move as far as scroll_max allows, or
14742 one screenful, or 10 screen lines, whichever is largest.
14743 Give up if distance is greater than scroll_max or if we
14744 didn't reach the scroll margin position. */
14745 SET_TEXT_POS (pos, PT, PT_BYTE);
14746 start_display (&it, w, pos);
14747 y0 = it.current_y;
14748 y_to_move = max (it.last_visible_y,
14749 max (scroll_max, 10 * frame_line_height));
14750 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14751 y_to_move, -1,
14752 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14753 dy = it.current_y - y0;
14754 if (dy > scroll_max
14755 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14756 return SCROLLING_FAILED;
14757
14758 /* Additional scroll for when ZV was too close to point. */
14759 dy += y_offset;
14760
14761 /* Compute new window start. */
14762 start_display (&it, w, startp);
14763
14764 if (arg_scroll_conservatively)
14765 amount_to_scroll = max (dy, frame_line_height *
14766 max (scroll_step, temp_scroll_step));
14767 else if (scroll_step || temp_scroll_step)
14768 amount_to_scroll = scroll_max;
14769 else
14770 {
14771 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14772 height = WINDOW_BOX_TEXT_HEIGHT (w);
14773 if (NUMBERP (aggressive))
14774 {
14775 double float_amount = XFLOATINT (aggressive) * height;
14776 int aggressive_scroll = float_amount;
14777 if (aggressive_scroll == 0 && float_amount > 0)
14778 aggressive_scroll = 1;
14779 /* Don't let point enter the scroll margin near
14780 bottom of the window, if the value of
14781 scroll_down_aggressively happens to be too
14782 large. */
14783 if (aggressive_scroll + 2*this_scroll_margin > height)
14784 aggressive_scroll = height - 2*this_scroll_margin;
14785 amount_to_scroll = dy + aggressive_scroll;
14786 }
14787 }
14788
14789 if (amount_to_scroll <= 0)
14790 return SCROLLING_FAILED;
14791
14792 move_it_vertically_backward (&it, amount_to_scroll);
14793 startp = it.current.pos;
14794 }
14795 }
14796
14797 /* Run window scroll functions. */
14798 startp = run_window_scroll_functions (window, startp);
14799
14800 /* Display the window. Give up if new fonts are loaded, or if point
14801 doesn't appear. */
14802 if (!try_window (window, startp, 0))
14803 rc = SCROLLING_NEED_LARGER_MATRICES;
14804 else if (w->cursor.vpos < 0)
14805 {
14806 clear_glyph_matrix (w->desired_matrix);
14807 rc = SCROLLING_FAILED;
14808 }
14809 else
14810 {
14811 /* Maybe forget recorded base line for line number display. */
14812 if (!just_this_one_p
14813 || current_buffer->clip_changed
14814 || BEG_UNCHANGED < CHARPOS (startp))
14815 w->base_line_number = 0;
14816
14817 /* If cursor ends up on a partially visible line,
14818 treat that as being off the bottom of the screen. */
14819 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14820 /* It's possible that the cursor is on the first line of the
14821 buffer, which is partially obscured due to a vscroll
14822 (Bug#7537). In that case, avoid looping forever . */
14823 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14824 {
14825 clear_glyph_matrix (w->desired_matrix);
14826 ++extra_scroll_margin_lines;
14827 goto too_near_end;
14828 }
14829 rc = SCROLLING_SUCCESS;
14830 }
14831
14832 return rc;
14833 }
14834
14835
14836 /* Compute a suitable window start for window W if display of W starts
14837 on a continuation line. Value is non-zero if a new window start
14838 was computed.
14839
14840 The new window start will be computed, based on W's width, starting
14841 from the start of the continued line. It is the start of the
14842 screen line with the minimum distance from the old start W->start. */
14843
14844 static int
14845 compute_window_start_on_continuation_line (struct window *w)
14846 {
14847 struct text_pos pos, start_pos;
14848 int window_start_changed_p = 0;
14849
14850 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14851
14852 /* If window start is on a continuation line... Window start may be
14853 < BEGV in case there's invisible text at the start of the
14854 buffer (M-x rmail, for example). */
14855 if (CHARPOS (start_pos) > BEGV
14856 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14857 {
14858 struct it it;
14859 struct glyph_row *row;
14860
14861 /* Handle the case that the window start is out of range. */
14862 if (CHARPOS (start_pos) < BEGV)
14863 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14864 else if (CHARPOS (start_pos) > ZV)
14865 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14866
14867 /* Find the start of the continued line. This should be fast
14868 because find_newline is fast (newline cache). */
14869 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14870 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14871 row, DEFAULT_FACE_ID);
14872 reseat_at_previous_visible_line_start (&it);
14873
14874 /* If the line start is "too far" away from the window start,
14875 say it takes too much time to compute a new window start. */
14876 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14877 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14878 {
14879 int min_distance, distance;
14880
14881 /* Move forward by display lines to find the new window
14882 start. If window width was enlarged, the new start can
14883 be expected to be > the old start. If window width was
14884 decreased, the new window start will be < the old start.
14885 So, we're looking for the display line start with the
14886 minimum distance from the old window start. */
14887 pos = it.current.pos;
14888 min_distance = INFINITY;
14889 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14890 distance < min_distance)
14891 {
14892 min_distance = distance;
14893 pos = it.current.pos;
14894 if (it.line_wrap == WORD_WRAP)
14895 {
14896 /* Under WORD_WRAP, move_it_by_lines is likely to
14897 overshoot and stop not at the first, but the
14898 second character from the left margin. So in
14899 that case, we need a more tight control on the X
14900 coordinate of the iterator than move_it_by_lines
14901 promises in its contract. The method is to first
14902 go to the last (rightmost) visible character of a
14903 line, then move to the leftmost character on the
14904 next line in a separate call. */
14905 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
14906 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14907 move_it_to (&it, ZV, 0,
14908 it.current_y + it.max_ascent + it.max_descent, -1,
14909 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14910 }
14911 else
14912 move_it_by_lines (&it, 1);
14913 }
14914
14915 /* Set the window start there. */
14916 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14917 window_start_changed_p = 1;
14918 }
14919 }
14920
14921 return window_start_changed_p;
14922 }
14923
14924
14925 /* Try cursor movement in case text has not changed in window WINDOW,
14926 with window start STARTP. Value is
14927
14928 CURSOR_MOVEMENT_SUCCESS if successful
14929
14930 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14931
14932 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14933 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14934 we want to scroll as if scroll-step were set to 1. See the code.
14935
14936 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14937 which case we have to abort this redisplay, and adjust matrices
14938 first. */
14939
14940 enum
14941 {
14942 CURSOR_MOVEMENT_SUCCESS,
14943 CURSOR_MOVEMENT_CANNOT_BE_USED,
14944 CURSOR_MOVEMENT_MUST_SCROLL,
14945 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14946 };
14947
14948 static int
14949 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14950 {
14951 struct window *w = XWINDOW (window);
14952 struct frame *f = XFRAME (w->frame);
14953 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14954
14955 #ifdef GLYPH_DEBUG
14956 if (inhibit_try_cursor_movement)
14957 return rc;
14958 #endif
14959
14960 /* Previously, there was a check for Lisp integer in the
14961 if-statement below. Now, this field is converted to
14962 ptrdiff_t, thus zero means invalid position in a buffer. */
14963 eassert (w->last_point > 0);
14964 /* Likewise there was a check whether window_end_vpos is nil or larger
14965 than the window. Now window_end_vpos is int and so never nil, but
14966 let's leave eassert to check whether it fits in the window. */
14967 eassert (w->window_end_vpos < w->current_matrix->nrows);
14968
14969 /* Handle case where text has not changed, only point, and it has
14970 not moved off the frame. */
14971 if (/* Point may be in this window. */
14972 PT >= CHARPOS (startp)
14973 /* Selective display hasn't changed. */
14974 && !current_buffer->clip_changed
14975 /* Function force-mode-line-update is used to force a thorough
14976 redisplay. It sets either windows_or_buffers_changed or
14977 update_mode_lines. So don't take a shortcut here for these
14978 cases. */
14979 && !update_mode_lines
14980 && !windows_or_buffers_changed
14981 && !f->cursor_type_changed
14982 /* Can't use this case if highlighting a region. When a
14983 region exists, cursor movement has to do more than just
14984 set the cursor. */
14985 && markpos_of_region () < 0
14986 && !w->region_showing
14987 && NILP (Vshow_trailing_whitespace)
14988 /* This code is not used for mini-buffer for the sake of the case
14989 of redisplaying to replace an echo area message; since in
14990 that case the mini-buffer contents per se are usually
14991 unchanged. This code is of no real use in the mini-buffer
14992 since the handling of this_line_start_pos, etc., in redisplay
14993 handles the same cases. */
14994 && !EQ (window, minibuf_window)
14995 && (FRAME_WINDOW_P (f)
14996 || !overlay_arrow_in_current_buffer_p ()))
14997 {
14998 int this_scroll_margin, top_scroll_margin;
14999 struct glyph_row *row = NULL;
15000 int frame_line_height = default_line_pixel_height (w);
15001 int window_total_lines
15002 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15003
15004 #ifdef GLYPH_DEBUG
15005 debug_method_add (w, "cursor movement");
15006 #endif
15007
15008 /* Scroll if point within this distance from the top or bottom
15009 of the window. This is a pixel value. */
15010 if (scroll_margin > 0)
15011 {
15012 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15013 this_scroll_margin *= frame_line_height;
15014 }
15015 else
15016 this_scroll_margin = 0;
15017
15018 top_scroll_margin = this_scroll_margin;
15019 if (WINDOW_WANTS_HEADER_LINE_P (w))
15020 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15021
15022 /* Start with the row the cursor was displayed during the last
15023 not paused redisplay. Give up if that row is not valid. */
15024 if (w->last_cursor_vpos < 0
15025 || w->last_cursor_vpos >= w->current_matrix->nrows)
15026 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15027 else
15028 {
15029 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15030 if (row->mode_line_p)
15031 ++row;
15032 if (!row->enabled_p)
15033 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15034 }
15035
15036 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15037 {
15038 int scroll_p = 0, must_scroll = 0;
15039 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15040
15041 if (PT > w->last_point)
15042 {
15043 /* Point has moved forward. */
15044 while (MATRIX_ROW_END_CHARPOS (row) < PT
15045 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15046 {
15047 eassert (row->enabled_p);
15048 ++row;
15049 }
15050
15051 /* If the end position of a row equals the start
15052 position of the next row, and PT is at that position,
15053 we would rather display cursor in the next line. */
15054 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15055 && MATRIX_ROW_END_CHARPOS (row) == PT
15056 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15057 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15058 && !cursor_row_p (row))
15059 ++row;
15060
15061 /* If within the scroll margin, scroll. Note that
15062 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15063 the next line would be drawn, and that
15064 this_scroll_margin can be zero. */
15065 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15066 || PT > MATRIX_ROW_END_CHARPOS (row)
15067 /* Line is completely visible last line in window
15068 and PT is to be set in the next line. */
15069 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15070 && PT == MATRIX_ROW_END_CHARPOS (row)
15071 && !row->ends_at_zv_p
15072 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15073 scroll_p = 1;
15074 }
15075 else if (PT < w->last_point)
15076 {
15077 /* Cursor has to be moved backward. Note that PT >=
15078 CHARPOS (startp) because of the outer if-statement. */
15079 while (!row->mode_line_p
15080 && (MATRIX_ROW_START_CHARPOS (row) > PT
15081 || (MATRIX_ROW_START_CHARPOS (row) == PT
15082 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15083 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15084 row > w->current_matrix->rows
15085 && (row-1)->ends_in_newline_from_string_p))))
15086 && (row->y > top_scroll_margin
15087 || CHARPOS (startp) == BEGV))
15088 {
15089 eassert (row->enabled_p);
15090 --row;
15091 }
15092
15093 /* Consider the following case: Window starts at BEGV,
15094 there is invisible, intangible text at BEGV, so that
15095 display starts at some point START > BEGV. It can
15096 happen that we are called with PT somewhere between
15097 BEGV and START. Try to handle that case. */
15098 if (row < w->current_matrix->rows
15099 || row->mode_line_p)
15100 {
15101 row = w->current_matrix->rows;
15102 if (row->mode_line_p)
15103 ++row;
15104 }
15105
15106 /* Due to newlines in overlay strings, we may have to
15107 skip forward over overlay strings. */
15108 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15109 && MATRIX_ROW_END_CHARPOS (row) == PT
15110 && !cursor_row_p (row))
15111 ++row;
15112
15113 /* If within the scroll margin, scroll. */
15114 if (row->y < top_scroll_margin
15115 && CHARPOS (startp) != BEGV)
15116 scroll_p = 1;
15117 }
15118 else
15119 {
15120 /* Cursor did not move. So don't scroll even if cursor line
15121 is partially visible, as it was so before. */
15122 rc = CURSOR_MOVEMENT_SUCCESS;
15123 }
15124
15125 if (PT < MATRIX_ROW_START_CHARPOS (row)
15126 || PT > MATRIX_ROW_END_CHARPOS (row))
15127 {
15128 /* if PT is not in the glyph row, give up. */
15129 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15130 must_scroll = 1;
15131 }
15132 else if (rc != CURSOR_MOVEMENT_SUCCESS
15133 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15134 {
15135 struct glyph_row *row1;
15136
15137 /* If rows are bidi-reordered and point moved, back up
15138 until we find a row that does not belong to a
15139 continuation line. This is because we must consider
15140 all rows of a continued line as candidates for the
15141 new cursor positioning, since row start and end
15142 positions change non-linearly with vertical position
15143 in such rows. */
15144 /* FIXME: Revisit this when glyph ``spilling'' in
15145 continuation lines' rows is implemented for
15146 bidi-reordered rows. */
15147 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15148 MATRIX_ROW_CONTINUATION_LINE_P (row);
15149 --row)
15150 {
15151 /* If we hit the beginning of the displayed portion
15152 without finding the first row of a continued
15153 line, give up. */
15154 if (row <= row1)
15155 {
15156 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15157 break;
15158 }
15159 eassert (row->enabled_p);
15160 }
15161 }
15162 if (must_scroll)
15163 ;
15164 else if (rc != CURSOR_MOVEMENT_SUCCESS
15165 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15166 /* Make sure this isn't a header line by any chance, since
15167 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15168 && !row->mode_line_p
15169 && make_cursor_line_fully_visible_p)
15170 {
15171 if (PT == MATRIX_ROW_END_CHARPOS (row)
15172 && !row->ends_at_zv_p
15173 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15174 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15175 else if (row->height > window_box_height (w))
15176 {
15177 /* If we end up in a partially visible line, let's
15178 make it fully visible, except when it's taller
15179 than the window, in which case we can't do much
15180 about it. */
15181 *scroll_step = 1;
15182 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15183 }
15184 else
15185 {
15186 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15187 if (!cursor_row_fully_visible_p (w, 0, 1))
15188 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15189 else
15190 rc = CURSOR_MOVEMENT_SUCCESS;
15191 }
15192 }
15193 else if (scroll_p)
15194 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15195 else if (rc != CURSOR_MOVEMENT_SUCCESS
15196 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15197 {
15198 /* With bidi-reordered rows, there could be more than
15199 one candidate row whose start and end positions
15200 occlude point. We need to let set_cursor_from_row
15201 find the best candidate. */
15202 /* FIXME: Revisit this when glyph ``spilling'' in
15203 continuation lines' rows is implemented for
15204 bidi-reordered rows. */
15205 int rv = 0;
15206
15207 do
15208 {
15209 int at_zv_p = 0, exact_match_p = 0;
15210
15211 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15212 && PT <= MATRIX_ROW_END_CHARPOS (row)
15213 && cursor_row_p (row))
15214 rv |= set_cursor_from_row (w, row, w->current_matrix,
15215 0, 0, 0, 0);
15216 /* As soon as we've found the exact match for point,
15217 or the first suitable row whose ends_at_zv_p flag
15218 is set, we are done. */
15219 at_zv_p =
15220 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15221 if (rv && !at_zv_p
15222 && w->cursor.hpos >= 0
15223 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15224 w->cursor.vpos))
15225 {
15226 struct glyph_row *candidate =
15227 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15228 struct glyph *g =
15229 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15230 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15231
15232 exact_match_p =
15233 (BUFFERP (g->object) && g->charpos == PT)
15234 || (INTEGERP (g->object)
15235 && (g->charpos == PT
15236 || (g->charpos == 0 && endpos - 1 == PT)));
15237 }
15238 if (rv && (at_zv_p || exact_match_p))
15239 {
15240 rc = CURSOR_MOVEMENT_SUCCESS;
15241 break;
15242 }
15243 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15244 break;
15245 ++row;
15246 }
15247 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15248 || row->continued_p)
15249 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15250 || (MATRIX_ROW_START_CHARPOS (row) == PT
15251 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15252 /* If we didn't find any candidate rows, or exited the
15253 loop before all the candidates were examined, signal
15254 to the caller that this method failed. */
15255 if (rc != CURSOR_MOVEMENT_SUCCESS
15256 && !(rv
15257 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15258 && !row->continued_p))
15259 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15260 else if (rv)
15261 rc = CURSOR_MOVEMENT_SUCCESS;
15262 }
15263 else
15264 {
15265 do
15266 {
15267 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15268 {
15269 rc = CURSOR_MOVEMENT_SUCCESS;
15270 break;
15271 }
15272 ++row;
15273 }
15274 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15275 && MATRIX_ROW_START_CHARPOS (row) == PT
15276 && cursor_row_p (row));
15277 }
15278 }
15279 }
15280
15281 return rc;
15282 }
15283
15284 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15285 static
15286 #endif
15287 void
15288 set_vertical_scroll_bar (struct window *w)
15289 {
15290 ptrdiff_t start, end, whole;
15291
15292 /* Calculate the start and end positions for the current window.
15293 At some point, it would be nice to choose between scrollbars
15294 which reflect the whole buffer size, with special markers
15295 indicating narrowing, and scrollbars which reflect only the
15296 visible region.
15297
15298 Note that mini-buffers sometimes aren't displaying any text. */
15299 if (!MINI_WINDOW_P (w)
15300 || (w == XWINDOW (minibuf_window)
15301 && NILP (echo_area_buffer[0])))
15302 {
15303 struct buffer *buf = XBUFFER (w->contents);
15304 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15305 start = marker_position (w->start) - BUF_BEGV (buf);
15306 /* I don't think this is guaranteed to be right. For the
15307 moment, we'll pretend it is. */
15308 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15309
15310 if (end < start)
15311 end = start;
15312 if (whole < (end - start))
15313 whole = end - start;
15314 }
15315 else
15316 start = end = whole = 0;
15317
15318 /* Indicate what this scroll bar ought to be displaying now. */
15319 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15320 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15321 (w, end - start, whole, start);
15322 }
15323
15324
15325 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15326 selected_window is redisplayed.
15327
15328 We can return without actually redisplaying the window if fonts has been
15329 changed on window's frame. In that case, redisplay_internal will retry. */
15330
15331 static void
15332 redisplay_window (Lisp_Object window, int just_this_one_p)
15333 {
15334 struct window *w = XWINDOW (window);
15335 struct frame *f = XFRAME (w->frame);
15336 struct buffer *buffer = XBUFFER (w->contents);
15337 struct buffer *old = current_buffer;
15338 struct text_pos lpoint, opoint, startp;
15339 int update_mode_line;
15340 int tem;
15341 struct it it;
15342 /* Record it now because it's overwritten. */
15343 int current_matrix_up_to_date_p = 0;
15344 int used_current_matrix_p = 0;
15345 /* This is less strict than current_matrix_up_to_date_p.
15346 It indicates that the buffer contents and narrowing are unchanged. */
15347 int buffer_unchanged_p = 0;
15348 int temp_scroll_step = 0;
15349 ptrdiff_t count = SPECPDL_INDEX ();
15350 int rc;
15351 int centering_position = -1;
15352 int last_line_misfit = 0;
15353 ptrdiff_t beg_unchanged, end_unchanged;
15354 int frame_line_height;
15355
15356 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15357 opoint = lpoint;
15358
15359 #ifdef GLYPH_DEBUG
15360 *w->desired_matrix->method = 0;
15361 #endif
15362
15363 /* Make sure that both W's markers are valid. */
15364 eassert (XMARKER (w->start)->buffer == buffer);
15365 eassert (XMARKER (w->pointm)->buffer == buffer);
15366
15367 restart:
15368 reconsider_clip_changes (w);
15369 frame_line_height = default_line_pixel_height (w);
15370
15371 /* Has the mode line to be updated? */
15372 update_mode_line = (w->update_mode_line
15373 || update_mode_lines
15374 || buffer->clip_changed
15375 || buffer->prevent_redisplay_optimizations_p);
15376
15377 if (MINI_WINDOW_P (w))
15378 {
15379 if (w == XWINDOW (echo_area_window)
15380 && !NILP (echo_area_buffer[0]))
15381 {
15382 if (update_mode_line)
15383 /* We may have to update a tty frame's menu bar or a
15384 tool-bar. Example `M-x C-h C-h C-g'. */
15385 goto finish_menu_bars;
15386 else
15387 /* We've already displayed the echo area glyphs in this window. */
15388 goto finish_scroll_bars;
15389 }
15390 else if ((w != XWINDOW (minibuf_window)
15391 || minibuf_level == 0)
15392 /* When buffer is nonempty, redisplay window normally. */
15393 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15394 /* Quail displays non-mini buffers in minibuffer window.
15395 In that case, redisplay the window normally. */
15396 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15397 {
15398 /* W is a mini-buffer window, but it's not active, so clear
15399 it. */
15400 int yb = window_text_bottom_y (w);
15401 struct glyph_row *row;
15402 int y;
15403
15404 for (y = 0, row = w->desired_matrix->rows;
15405 y < yb;
15406 y += row->height, ++row)
15407 blank_row (w, row, y);
15408 goto finish_scroll_bars;
15409 }
15410
15411 clear_glyph_matrix (w->desired_matrix);
15412 }
15413
15414 /* Otherwise set up data on this window; select its buffer and point
15415 value. */
15416 /* Really select the buffer, for the sake of buffer-local
15417 variables. */
15418 set_buffer_internal_1 (XBUFFER (w->contents));
15419
15420 current_matrix_up_to_date_p
15421 = (w->window_end_valid
15422 && !current_buffer->clip_changed
15423 && !current_buffer->prevent_redisplay_optimizations_p
15424 && !window_outdated (w));
15425
15426 /* Run the window-bottom-change-functions
15427 if it is possible that the text on the screen has changed
15428 (either due to modification of the text, or any other reason). */
15429 if (!current_matrix_up_to_date_p
15430 && !NILP (Vwindow_text_change_functions))
15431 {
15432 safe_run_hooks (Qwindow_text_change_functions);
15433 goto restart;
15434 }
15435
15436 beg_unchanged = BEG_UNCHANGED;
15437 end_unchanged = END_UNCHANGED;
15438
15439 SET_TEXT_POS (opoint, PT, PT_BYTE);
15440
15441 specbind (Qinhibit_point_motion_hooks, Qt);
15442
15443 buffer_unchanged_p
15444 = (w->window_end_valid
15445 && !current_buffer->clip_changed
15446 && !window_outdated (w));
15447
15448 /* When windows_or_buffers_changed is non-zero, we can't rely
15449 on the window end being valid, so set it to zero there. */
15450 if (windows_or_buffers_changed)
15451 {
15452 /* If window starts on a continuation line, maybe adjust the
15453 window start in case the window's width changed. */
15454 if (XMARKER (w->start)->buffer == current_buffer)
15455 compute_window_start_on_continuation_line (w);
15456
15457 w->window_end_valid = 0;
15458 /* If so, we also can't rely on current matrix
15459 and should not fool try_cursor_movement below. */
15460 current_matrix_up_to_date_p = 0;
15461 }
15462
15463 /* Some sanity checks. */
15464 CHECK_WINDOW_END (w);
15465 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15466 emacs_abort ();
15467 if (BYTEPOS (opoint) < CHARPOS (opoint))
15468 emacs_abort ();
15469
15470 if (mode_line_update_needed (w))
15471 update_mode_line = 1;
15472
15473 /* Point refers normally to the selected window. For any other
15474 window, set up appropriate value. */
15475 if (!EQ (window, selected_window))
15476 {
15477 ptrdiff_t new_pt = marker_position (w->pointm);
15478 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15479 if (new_pt < BEGV)
15480 {
15481 new_pt = BEGV;
15482 new_pt_byte = BEGV_BYTE;
15483 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15484 }
15485 else if (new_pt > (ZV - 1))
15486 {
15487 new_pt = ZV;
15488 new_pt_byte = ZV_BYTE;
15489 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15490 }
15491
15492 /* We don't use SET_PT so that the point-motion hooks don't run. */
15493 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15494 }
15495
15496 /* If any of the character widths specified in the display table
15497 have changed, invalidate the width run cache. It's true that
15498 this may be a bit late to catch such changes, but the rest of
15499 redisplay goes (non-fatally) haywire when the display table is
15500 changed, so why should we worry about doing any better? */
15501 if (current_buffer->width_run_cache)
15502 {
15503 struct Lisp_Char_Table *disptab = buffer_display_table ();
15504
15505 if (! disptab_matches_widthtab
15506 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15507 {
15508 invalidate_region_cache (current_buffer,
15509 current_buffer->width_run_cache,
15510 BEG, Z);
15511 recompute_width_table (current_buffer, disptab);
15512 }
15513 }
15514
15515 /* If window-start is screwed up, choose a new one. */
15516 if (XMARKER (w->start)->buffer != current_buffer)
15517 goto recenter;
15518
15519 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15520
15521 /* If someone specified a new starting point but did not insist,
15522 check whether it can be used. */
15523 if (w->optional_new_start
15524 && CHARPOS (startp) >= BEGV
15525 && CHARPOS (startp) <= ZV)
15526 {
15527 w->optional_new_start = 0;
15528 start_display (&it, w, startp);
15529 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15530 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15531 if (IT_CHARPOS (it) == PT)
15532 w->force_start = 1;
15533 /* IT may overshoot PT if text at PT is invisible. */
15534 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15535 w->force_start = 1;
15536 }
15537
15538 force_start:
15539
15540 /* Handle case where place to start displaying has been specified,
15541 unless the specified location is outside the accessible range. */
15542 if (w->force_start || window_frozen_p (w))
15543 {
15544 /* We set this later on if we have to adjust point. */
15545 int new_vpos = -1;
15546
15547 w->force_start = 0;
15548 w->vscroll = 0;
15549 w->window_end_valid = 0;
15550
15551 /* Forget any recorded base line for line number display. */
15552 if (!buffer_unchanged_p)
15553 w->base_line_number = 0;
15554
15555 /* Redisplay the mode line. Select the buffer properly for that.
15556 Also, run the hook window-scroll-functions
15557 because we have scrolled. */
15558 /* Note, we do this after clearing force_start because
15559 if there's an error, it is better to forget about force_start
15560 than to get into an infinite loop calling the hook functions
15561 and having them get more errors. */
15562 if (!update_mode_line
15563 || ! NILP (Vwindow_scroll_functions))
15564 {
15565 update_mode_line = 1;
15566 w->update_mode_line = 1;
15567 startp = run_window_scroll_functions (window, startp);
15568 }
15569
15570 if (CHARPOS (startp) < BEGV)
15571 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15572 else if (CHARPOS (startp) > ZV)
15573 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15574
15575 /* Redisplay, then check if cursor has been set during the
15576 redisplay. Give up if new fonts were loaded. */
15577 /* We used to issue a CHECK_MARGINS argument to try_window here,
15578 but this causes scrolling to fail when point begins inside
15579 the scroll margin (bug#148) -- cyd */
15580 if (!try_window (window, startp, 0))
15581 {
15582 w->force_start = 1;
15583 clear_glyph_matrix (w->desired_matrix);
15584 goto need_larger_matrices;
15585 }
15586
15587 if (w->cursor.vpos < 0 && !window_frozen_p (w))
15588 {
15589 /* If point does not appear, try to move point so it does
15590 appear. The desired matrix has been built above, so we
15591 can use it here. */
15592 new_vpos = window_box_height (w) / 2;
15593 }
15594
15595 if (!cursor_row_fully_visible_p (w, 0, 0))
15596 {
15597 /* Point does appear, but on a line partly visible at end of window.
15598 Move it back to a fully-visible line. */
15599 new_vpos = window_box_height (w);
15600 }
15601 else if (w->cursor.vpos >=0)
15602 {
15603 /* Some people insist on not letting point enter the scroll
15604 margin, even though this part handles windows that didn't
15605 scroll at all. */
15606 int window_total_lines
15607 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15608 int margin = min (scroll_margin, window_total_lines / 4);
15609 int pixel_margin = margin * frame_line_height;
15610 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15611
15612 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15613 below, which finds the row to move point to, advances by
15614 the Y coordinate of the _next_ row, see the definition of
15615 MATRIX_ROW_BOTTOM_Y. */
15616 if (w->cursor.vpos < margin + header_line)
15617 {
15618 w->cursor.vpos = -1;
15619 clear_glyph_matrix (w->desired_matrix);
15620 goto try_to_scroll;
15621 }
15622 else
15623 {
15624 int window_height = window_box_height (w);
15625
15626 if (header_line)
15627 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15628 if (w->cursor.y >= window_height - pixel_margin)
15629 {
15630 w->cursor.vpos = -1;
15631 clear_glyph_matrix (w->desired_matrix);
15632 goto try_to_scroll;
15633 }
15634 }
15635 }
15636
15637 /* If we need to move point for either of the above reasons,
15638 now actually do it. */
15639 if (new_vpos >= 0)
15640 {
15641 struct glyph_row *row;
15642
15643 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15644 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15645 ++row;
15646
15647 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15648 MATRIX_ROW_START_BYTEPOS (row));
15649
15650 if (w != XWINDOW (selected_window))
15651 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15652 else if (current_buffer == old)
15653 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15654
15655 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15656
15657 /* If we are highlighting the region, then we just changed
15658 the region, so redisplay to show it. */
15659 if (markpos_of_region () >= 0)
15660 {
15661 clear_glyph_matrix (w->desired_matrix);
15662 if (!try_window (window, startp, 0))
15663 goto need_larger_matrices;
15664 }
15665 }
15666
15667 #ifdef GLYPH_DEBUG
15668 debug_method_add (w, "forced window start");
15669 #endif
15670 goto done;
15671 }
15672
15673 /* Handle case where text has not changed, only point, and it has
15674 not moved off the frame, and we are not retrying after hscroll.
15675 (current_matrix_up_to_date_p is nonzero when retrying.) */
15676 if (current_matrix_up_to_date_p
15677 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15678 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15679 {
15680 switch (rc)
15681 {
15682 case CURSOR_MOVEMENT_SUCCESS:
15683 used_current_matrix_p = 1;
15684 goto done;
15685
15686 case CURSOR_MOVEMENT_MUST_SCROLL:
15687 goto try_to_scroll;
15688
15689 default:
15690 emacs_abort ();
15691 }
15692 }
15693 /* If current starting point was originally the beginning of a line
15694 but no longer is, find a new starting point. */
15695 else if (w->start_at_line_beg
15696 && !(CHARPOS (startp) <= BEGV
15697 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15698 {
15699 #ifdef GLYPH_DEBUG
15700 debug_method_add (w, "recenter 1");
15701 #endif
15702 goto recenter;
15703 }
15704
15705 /* Try scrolling with try_window_id. Value is > 0 if update has
15706 been done, it is -1 if we know that the same window start will
15707 not work. It is 0 if unsuccessful for some other reason. */
15708 else if ((tem = try_window_id (w)) != 0)
15709 {
15710 #ifdef GLYPH_DEBUG
15711 debug_method_add (w, "try_window_id %d", tem);
15712 #endif
15713
15714 if (f->fonts_changed)
15715 goto need_larger_matrices;
15716 if (tem > 0)
15717 goto done;
15718
15719 /* Otherwise try_window_id has returned -1 which means that we
15720 don't want the alternative below this comment to execute. */
15721 }
15722 else if (CHARPOS (startp) >= BEGV
15723 && CHARPOS (startp) <= ZV
15724 && PT >= CHARPOS (startp)
15725 && (CHARPOS (startp) < ZV
15726 /* Avoid starting at end of buffer. */
15727 || CHARPOS (startp) == BEGV
15728 || !window_outdated (w)))
15729 {
15730 int d1, d2, d3, d4, d5, d6;
15731
15732 /* If first window line is a continuation line, and window start
15733 is inside the modified region, but the first change is before
15734 current window start, we must select a new window start.
15735
15736 However, if this is the result of a down-mouse event (e.g. by
15737 extending the mouse-drag-overlay), we don't want to select a
15738 new window start, since that would change the position under
15739 the mouse, resulting in an unwanted mouse-movement rather
15740 than a simple mouse-click. */
15741 if (!w->start_at_line_beg
15742 && NILP (do_mouse_tracking)
15743 && CHARPOS (startp) > BEGV
15744 && CHARPOS (startp) > BEG + beg_unchanged
15745 && CHARPOS (startp) <= Z - end_unchanged
15746 /* Even if w->start_at_line_beg is nil, a new window may
15747 start at a line_beg, since that's how set_buffer_window
15748 sets it. So, we need to check the return value of
15749 compute_window_start_on_continuation_line. (See also
15750 bug#197). */
15751 && XMARKER (w->start)->buffer == current_buffer
15752 && compute_window_start_on_continuation_line (w)
15753 /* It doesn't make sense to force the window start like we
15754 do at label force_start if it is already known that point
15755 will not be visible in the resulting window, because
15756 doing so will move point from its correct position
15757 instead of scrolling the window to bring point into view.
15758 See bug#9324. */
15759 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15760 {
15761 w->force_start = 1;
15762 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15763 goto force_start;
15764 }
15765
15766 #ifdef GLYPH_DEBUG
15767 debug_method_add (w, "same window start");
15768 #endif
15769
15770 /* Try to redisplay starting at same place as before.
15771 If point has not moved off frame, accept the results. */
15772 if (!current_matrix_up_to_date_p
15773 /* Don't use try_window_reusing_current_matrix in this case
15774 because a window scroll function can have changed the
15775 buffer. */
15776 || !NILP (Vwindow_scroll_functions)
15777 || MINI_WINDOW_P (w)
15778 || !(used_current_matrix_p
15779 = try_window_reusing_current_matrix (w)))
15780 {
15781 IF_DEBUG (debug_method_add (w, "1"));
15782 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15783 /* -1 means we need to scroll.
15784 0 means we need new matrices, but fonts_changed
15785 is set in that case, so we will detect it below. */
15786 goto try_to_scroll;
15787 }
15788
15789 if (f->fonts_changed)
15790 goto need_larger_matrices;
15791
15792 if (w->cursor.vpos >= 0)
15793 {
15794 if (!just_this_one_p
15795 || current_buffer->clip_changed
15796 || BEG_UNCHANGED < CHARPOS (startp))
15797 /* Forget any recorded base line for line number display. */
15798 w->base_line_number = 0;
15799
15800 if (!cursor_row_fully_visible_p (w, 1, 0))
15801 {
15802 clear_glyph_matrix (w->desired_matrix);
15803 last_line_misfit = 1;
15804 }
15805 /* Drop through and scroll. */
15806 else
15807 goto done;
15808 }
15809 else
15810 clear_glyph_matrix (w->desired_matrix);
15811 }
15812
15813 try_to_scroll:
15814
15815 /* Redisplay the mode line. Select the buffer properly for that. */
15816 if (!update_mode_line)
15817 {
15818 update_mode_line = 1;
15819 w->update_mode_line = 1;
15820 }
15821
15822 /* Try to scroll by specified few lines. */
15823 if ((scroll_conservatively
15824 || emacs_scroll_step
15825 || temp_scroll_step
15826 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15827 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15828 && CHARPOS (startp) >= BEGV
15829 && CHARPOS (startp) <= ZV)
15830 {
15831 /* The function returns -1 if new fonts were loaded, 1 if
15832 successful, 0 if not successful. */
15833 int ss = try_scrolling (window, just_this_one_p,
15834 scroll_conservatively,
15835 emacs_scroll_step,
15836 temp_scroll_step, last_line_misfit);
15837 switch (ss)
15838 {
15839 case SCROLLING_SUCCESS:
15840 goto done;
15841
15842 case SCROLLING_NEED_LARGER_MATRICES:
15843 goto need_larger_matrices;
15844
15845 case SCROLLING_FAILED:
15846 break;
15847
15848 default:
15849 emacs_abort ();
15850 }
15851 }
15852
15853 /* Finally, just choose a place to start which positions point
15854 according to user preferences. */
15855
15856 recenter:
15857
15858 #ifdef GLYPH_DEBUG
15859 debug_method_add (w, "recenter");
15860 #endif
15861
15862 /* Forget any previously recorded base line for line number display. */
15863 if (!buffer_unchanged_p)
15864 w->base_line_number = 0;
15865
15866 /* Determine the window start relative to point. */
15867 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15868 it.current_y = it.last_visible_y;
15869 if (centering_position < 0)
15870 {
15871 int window_total_lines
15872 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15873 int margin =
15874 scroll_margin > 0
15875 ? min (scroll_margin, window_total_lines / 4)
15876 : 0;
15877 ptrdiff_t margin_pos = CHARPOS (startp);
15878 Lisp_Object aggressive;
15879 int scrolling_up;
15880
15881 /* If there is a scroll margin at the top of the window, find
15882 its character position. */
15883 if (margin
15884 /* Cannot call start_display if startp is not in the
15885 accessible region of the buffer. This can happen when we
15886 have just switched to a different buffer and/or changed
15887 its restriction. In that case, startp is initialized to
15888 the character position 1 (BEGV) because we did not yet
15889 have chance to display the buffer even once. */
15890 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15891 {
15892 struct it it1;
15893 void *it1data = NULL;
15894
15895 SAVE_IT (it1, it, it1data);
15896 start_display (&it1, w, startp);
15897 move_it_vertically (&it1, margin * frame_line_height);
15898 margin_pos = IT_CHARPOS (it1);
15899 RESTORE_IT (&it, &it, it1data);
15900 }
15901 scrolling_up = PT > margin_pos;
15902 aggressive =
15903 scrolling_up
15904 ? BVAR (current_buffer, scroll_up_aggressively)
15905 : BVAR (current_buffer, scroll_down_aggressively);
15906
15907 if (!MINI_WINDOW_P (w)
15908 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15909 {
15910 int pt_offset = 0;
15911
15912 /* Setting scroll-conservatively overrides
15913 scroll-*-aggressively. */
15914 if (!scroll_conservatively && NUMBERP (aggressive))
15915 {
15916 double float_amount = XFLOATINT (aggressive);
15917
15918 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15919 if (pt_offset == 0 && float_amount > 0)
15920 pt_offset = 1;
15921 if (pt_offset && margin > 0)
15922 margin -= 1;
15923 }
15924 /* Compute how much to move the window start backward from
15925 point so that point will be displayed where the user
15926 wants it. */
15927 if (scrolling_up)
15928 {
15929 centering_position = it.last_visible_y;
15930 if (pt_offset)
15931 centering_position -= pt_offset;
15932 centering_position -=
15933 frame_line_height * (1 + margin + (last_line_misfit != 0))
15934 + WINDOW_HEADER_LINE_HEIGHT (w);
15935 /* Don't let point enter the scroll margin near top of
15936 the window. */
15937 if (centering_position < margin * frame_line_height)
15938 centering_position = margin * frame_line_height;
15939 }
15940 else
15941 centering_position = margin * frame_line_height + pt_offset;
15942 }
15943 else
15944 /* Set the window start half the height of the window backward
15945 from point. */
15946 centering_position = window_box_height (w) / 2;
15947 }
15948 move_it_vertically_backward (&it, centering_position);
15949
15950 eassert (IT_CHARPOS (it) >= BEGV);
15951
15952 /* The function move_it_vertically_backward may move over more
15953 than the specified y-distance. If it->w is small, e.g. a
15954 mini-buffer window, we may end up in front of the window's
15955 display area. Start displaying at the start of the line
15956 containing PT in this case. */
15957 if (it.current_y <= 0)
15958 {
15959 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15960 move_it_vertically_backward (&it, 0);
15961 it.current_y = 0;
15962 }
15963
15964 it.current_x = it.hpos = 0;
15965
15966 /* Set the window start position here explicitly, to avoid an
15967 infinite loop in case the functions in window-scroll-functions
15968 get errors. */
15969 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15970
15971 /* Run scroll hooks. */
15972 startp = run_window_scroll_functions (window, it.current.pos);
15973
15974 /* Redisplay the window. */
15975 if (!current_matrix_up_to_date_p
15976 || windows_or_buffers_changed
15977 || f->cursor_type_changed
15978 /* Don't use try_window_reusing_current_matrix in this case
15979 because it can have changed the buffer. */
15980 || !NILP (Vwindow_scroll_functions)
15981 || !just_this_one_p
15982 || MINI_WINDOW_P (w)
15983 || !(used_current_matrix_p
15984 = try_window_reusing_current_matrix (w)))
15985 try_window (window, startp, 0);
15986
15987 /* If new fonts have been loaded (due to fontsets), give up. We
15988 have to start a new redisplay since we need to re-adjust glyph
15989 matrices. */
15990 if (f->fonts_changed)
15991 goto need_larger_matrices;
15992
15993 /* If cursor did not appear assume that the middle of the window is
15994 in the first line of the window. Do it again with the next line.
15995 (Imagine a window of height 100, displaying two lines of height
15996 60. Moving back 50 from it->last_visible_y will end in the first
15997 line.) */
15998 if (w->cursor.vpos < 0)
15999 {
16000 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16001 {
16002 clear_glyph_matrix (w->desired_matrix);
16003 move_it_by_lines (&it, 1);
16004 try_window (window, it.current.pos, 0);
16005 }
16006 else if (PT < IT_CHARPOS (it))
16007 {
16008 clear_glyph_matrix (w->desired_matrix);
16009 move_it_by_lines (&it, -1);
16010 try_window (window, it.current.pos, 0);
16011 }
16012 else
16013 {
16014 /* Not much we can do about it. */
16015 }
16016 }
16017
16018 /* Consider the following case: Window starts at BEGV, there is
16019 invisible, intangible text at BEGV, so that display starts at
16020 some point START > BEGV. It can happen that we are called with
16021 PT somewhere between BEGV and START. Try to handle that case. */
16022 if (w->cursor.vpos < 0)
16023 {
16024 struct glyph_row *row = w->current_matrix->rows;
16025 if (row->mode_line_p)
16026 ++row;
16027 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16028 }
16029
16030 if (!cursor_row_fully_visible_p (w, 0, 0))
16031 {
16032 /* If vscroll is enabled, disable it and try again. */
16033 if (w->vscroll)
16034 {
16035 w->vscroll = 0;
16036 clear_glyph_matrix (w->desired_matrix);
16037 goto recenter;
16038 }
16039
16040 /* Users who set scroll-conservatively to a large number want
16041 point just above/below the scroll margin. If we ended up
16042 with point's row partially visible, move the window start to
16043 make that row fully visible and out of the margin. */
16044 if (scroll_conservatively > SCROLL_LIMIT)
16045 {
16046 int window_total_lines
16047 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16048 int margin =
16049 scroll_margin > 0
16050 ? min (scroll_margin, window_total_lines / 4)
16051 : 0;
16052 int move_down = w->cursor.vpos >= window_total_lines / 2;
16053
16054 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16055 clear_glyph_matrix (w->desired_matrix);
16056 if (1 == try_window (window, it.current.pos,
16057 TRY_WINDOW_CHECK_MARGINS))
16058 goto done;
16059 }
16060
16061 /* If centering point failed to make the whole line visible,
16062 put point at the top instead. That has to make the whole line
16063 visible, if it can be done. */
16064 if (centering_position == 0)
16065 goto done;
16066
16067 clear_glyph_matrix (w->desired_matrix);
16068 centering_position = 0;
16069 goto recenter;
16070 }
16071
16072 done:
16073
16074 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16075 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16076 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16077
16078 /* Display the mode line, if we must. */
16079 if ((update_mode_line
16080 /* If window not full width, must redo its mode line
16081 if (a) the window to its side is being redone and
16082 (b) we do a frame-based redisplay. This is a consequence
16083 of how inverted lines are drawn in frame-based redisplay. */
16084 || (!just_this_one_p
16085 && !FRAME_WINDOW_P (f)
16086 && !WINDOW_FULL_WIDTH_P (w))
16087 /* Line number to display. */
16088 || w->base_line_pos > 0
16089 /* Column number is displayed and different from the one displayed. */
16090 || (w->column_number_displayed != -1
16091 && (w->column_number_displayed != current_column ())))
16092 /* This means that the window has a mode line. */
16093 && (WINDOW_WANTS_MODELINE_P (w)
16094 || WINDOW_WANTS_HEADER_LINE_P (w)))
16095 {
16096 display_mode_lines (w);
16097
16098 /* If mode line height has changed, arrange for a thorough
16099 immediate redisplay using the correct mode line height. */
16100 if (WINDOW_WANTS_MODELINE_P (w)
16101 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16102 {
16103 f->fonts_changed = 1;
16104 w->mode_line_height = -1;
16105 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16106 = DESIRED_MODE_LINE_HEIGHT (w);
16107 }
16108
16109 /* If header line height has changed, arrange for a thorough
16110 immediate redisplay using the correct header line height. */
16111 if (WINDOW_WANTS_HEADER_LINE_P (w)
16112 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16113 {
16114 f->fonts_changed = 1;
16115 w->header_line_height = -1;
16116 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16117 = DESIRED_HEADER_LINE_HEIGHT (w);
16118 }
16119
16120 if (f->fonts_changed)
16121 goto need_larger_matrices;
16122 }
16123
16124 if (!line_number_displayed && w->base_line_pos != -1)
16125 {
16126 w->base_line_pos = 0;
16127 w->base_line_number = 0;
16128 }
16129
16130 finish_menu_bars:
16131
16132 /* When we reach a frame's selected window, redo the frame's menu bar. */
16133 if (update_mode_line
16134 && EQ (FRAME_SELECTED_WINDOW (f), window))
16135 {
16136 int redisplay_menu_p = 0;
16137
16138 if (FRAME_WINDOW_P (f))
16139 {
16140 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16141 || defined (HAVE_NS) || defined (USE_GTK)
16142 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16143 #else
16144 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16145 #endif
16146 }
16147 else
16148 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16149
16150 if (redisplay_menu_p)
16151 display_menu_bar (w);
16152
16153 #ifdef HAVE_WINDOW_SYSTEM
16154 if (FRAME_WINDOW_P (f))
16155 {
16156 #if defined (USE_GTK) || defined (HAVE_NS)
16157 if (FRAME_EXTERNAL_TOOL_BAR (f))
16158 redisplay_tool_bar (f);
16159 #else
16160 if (WINDOWP (f->tool_bar_window)
16161 && (FRAME_TOOL_BAR_LINES (f) > 0
16162 || !NILP (Vauto_resize_tool_bars))
16163 && redisplay_tool_bar (f))
16164 ignore_mouse_drag_p = 1;
16165 #endif
16166 }
16167 #endif
16168 }
16169
16170 #ifdef HAVE_WINDOW_SYSTEM
16171 if (FRAME_WINDOW_P (f)
16172 && update_window_fringes (w, (just_this_one_p
16173 || (!used_current_matrix_p && !overlay_arrow_seen)
16174 || w->pseudo_window_p)))
16175 {
16176 update_begin (f);
16177 block_input ();
16178 if (draw_window_fringes (w, 1))
16179 x_draw_vertical_border (w);
16180 unblock_input ();
16181 update_end (f);
16182 }
16183 #endif /* HAVE_WINDOW_SYSTEM */
16184
16185 /* We go to this label, with fonts_changed set, if it is
16186 necessary to try again using larger glyph matrices.
16187 We have to redeem the scroll bar even in this case,
16188 because the loop in redisplay_internal expects that. */
16189 need_larger_matrices:
16190 ;
16191 finish_scroll_bars:
16192
16193 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16194 {
16195 /* Set the thumb's position and size. */
16196 set_vertical_scroll_bar (w);
16197
16198 /* Note that we actually used the scroll bar attached to this
16199 window, so it shouldn't be deleted at the end of redisplay. */
16200 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16201 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16202 }
16203
16204 /* Restore current_buffer and value of point in it. The window
16205 update may have changed the buffer, so first make sure `opoint'
16206 is still valid (Bug#6177). */
16207 if (CHARPOS (opoint) < BEGV)
16208 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16209 else if (CHARPOS (opoint) > ZV)
16210 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16211 else
16212 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16213
16214 set_buffer_internal_1 (old);
16215 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16216 shorter. This can be caused by log truncation in *Messages*. */
16217 if (CHARPOS (lpoint) <= ZV)
16218 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16219
16220 unbind_to (count, Qnil);
16221 }
16222
16223
16224 /* Build the complete desired matrix of WINDOW with a window start
16225 buffer position POS.
16226
16227 Value is 1 if successful. It is zero if fonts were loaded during
16228 redisplay which makes re-adjusting glyph matrices necessary, and -1
16229 if point would appear in the scroll margins.
16230 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16231 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16232 set in FLAGS.) */
16233
16234 int
16235 try_window (Lisp_Object window, struct text_pos pos, int flags)
16236 {
16237 struct window *w = XWINDOW (window);
16238 struct it it;
16239 struct glyph_row *last_text_row = NULL;
16240 struct frame *f = XFRAME (w->frame);
16241 int frame_line_height = default_line_pixel_height (w);
16242
16243 /* Make POS the new window start. */
16244 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16245
16246 /* Mark cursor position as unknown. No overlay arrow seen. */
16247 w->cursor.vpos = -1;
16248 overlay_arrow_seen = 0;
16249
16250 /* Initialize iterator and info to start at POS. */
16251 start_display (&it, w, pos);
16252
16253 /* Display all lines of W. */
16254 while (it.current_y < it.last_visible_y)
16255 {
16256 if (display_line (&it))
16257 last_text_row = it.glyph_row - 1;
16258 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16259 return 0;
16260 }
16261
16262 /* Don't let the cursor end in the scroll margins. */
16263 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16264 && !MINI_WINDOW_P (w))
16265 {
16266 int this_scroll_margin;
16267 int window_total_lines
16268 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16269
16270 if (scroll_margin > 0)
16271 {
16272 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16273 this_scroll_margin *= frame_line_height;
16274 }
16275 else
16276 this_scroll_margin = 0;
16277
16278 if ((w->cursor.y >= 0 /* not vscrolled */
16279 && w->cursor.y < this_scroll_margin
16280 && CHARPOS (pos) > BEGV
16281 && IT_CHARPOS (it) < ZV)
16282 /* rms: considering make_cursor_line_fully_visible_p here
16283 seems to give wrong results. We don't want to recenter
16284 when the last line is partly visible, we want to allow
16285 that case to be handled in the usual way. */
16286 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16287 {
16288 w->cursor.vpos = -1;
16289 clear_glyph_matrix (w->desired_matrix);
16290 return -1;
16291 }
16292 }
16293
16294 /* If bottom moved off end of frame, change mode line percentage. */
16295 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
16296 w->update_mode_line = 1;
16297
16298 /* Set window_end_pos to the offset of the last character displayed
16299 on the window from the end of current_buffer. Set
16300 window_end_vpos to its row number. */
16301 if (last_text_row)
16302 {
16303 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16304 adjust_window_ends (w, last_text_row, 0);
16305 eassert
16306 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16307 w->window_end_vpos)));
16308 }
16309 else
16310 {
16311 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16312 w->window_end_pos = Z - ZV;
16313 w->window_end_vpos = 0;
16314 }
16315
16316 /* But that is not valid info until redisplay finishes. */
16317 w->window_end_valid = 0;
16318 return 1;
16319 }
16320
16321
16322 \f
16323 /************************************************************************
16324 Window redisplay reusing current matrix when buffer has not changed
16325 ************************************************************************/
16326
16327 /* Try redisplay of window W showing an unchanged buffer with a
16328 different window start than the last time it was displayed by
16329 reusing its current matrix. Value is non-zero if successful.
16330 W->start is the new window start. */
16331
16332 static int
16333 try_window_reusing_current_matrix (struct window *w)
16334 {
16335 struct frame *f = XFRAME (w->frame);
16336 struct glyph_row *bottom_row;
16337 struct it it;
16338 struct run run;
16339 struct text_pos start, new_start;
16340 int nrows_scrolled, i;
16341 struct glyph_row *last_text_row;
16342 struct glyph_row *last_reused_text_row;
16343 struct glyph_row *start_row;
16344 int start_vpos, min_y, max_y;
16345
16346 #ifdef GLYPH_DEBUG
16347 if (inhibit_try_window_reusing)
16348 return 0;
16349 #endif
16350
16351 if (/* This function doesn't handle terminal frames. */
16352 !FRAME_WINDOW_P (f)
16353 /* Don't try to reuse the display if windows have been split
16354 or such. */
16355 || windows_or_buffers_changed
16356 || f->cursor_type_changed)
16357 return 0;
16358
16359 /* Can't do this if region may have changed. */
16360 if (markpos_of_region () >= 0
16361 || w->region_showing
16362 || !NILP (Vshow_trailing_whitespace))
16363 return 0;
16364
16365 /* If top-line visibility has changed, give up. */
16366 if (WINDOW_WANTS_HEADER_LINE_P (w)
16367 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16368 return 0;
16369
16370 /* Give up if old or new display is scrolled vertically. We could
16371 make this function handle this, but right now it doesn't. */
16372 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16373 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16374 return 0;
16375
16376 /* The variable new_start now holds the new window start. The old
16377 start `start' can be determined from the current matrix. */
16378 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16379 start = start_row->minpos;
16380 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16381
16382 /* Clear the desired matrix for the display below. */
16383 clear_glyph_matrix (w->desired_matrix);
16384
16385 if (CHARPOS (new_start) <= CHARPOS (start))
16386 {
16387 /* Don't use this method if the display starts with an ellipsis
16388 displayed for invisible text. It's not easy to handle that case
16389 below, and it's certainly not worth the effort since this is
16390 not a frequent case. */
16391 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16392 return 0;
16393
16394 IF_DEBUG (debug_method_add (w, "twu1"));
16395
16396 /* Display up to a row that can be reused. The variable
16397 last_text_row is set to the last row displayed that displays
16398 text. Note that it.vpos == 0 if or if not there is a
16399 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16400 start_display (&it, w, new_start);
16401 w->cursor.vpos = -1;
16402 last_text_row = last_reused_text_row = NULL;
16403
16404 while (it.current_y < it.last_visible_y && !f->fonts_changed)
16405 {
16406 /* If we have reached into the characters in the START row,
16407 that means the line boundaries have changed. So we
16408 can't start copying with the row START. Maybe it will
16409 work to start copying with the following row. */
16410 while (IT_CHARPOS (it) > CHARPOS (start))
16411 {
16412 /* Advance to the next row as the "start". */
16413 start_row++;
16414 start = start_row->minpos;
16415 /* If there are no more rows to try, or just one, give up. */
16416 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16417 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16418 || CHARPOS (start) == ZV)
16419 {
16420 clear_glyph_matrix (w->desired_matrix);
16421 return 0;
16422 }
16423
16424 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16425 }
16426 /* If we have reached alignment, we can copy the rest of the
16427 rows. */
16428 if (IT_CHARPOS (it) == CHARPOS (start)
16429 /* Don't accept "alignment" inside a display vector,
16430 since start_row could have started in the middle of
16431 that same display vector (thus their character
16432 positions match), and we have no way of telling if
16433 that is the case. */
16434 && it.current.dpvec_index < 0)
16435 break;
16436
16437 if (display_line (&it))
16438 last_text_row = it.glyph_row - 1;
16439
16440 }
16441
16442 /* A value of current_y < last_visible_y means that we stopped
16443 at the previous window start, which in turn means that we
16444 have at least one reusable row. */
16445 if (it.current_y < it.last_visible_y)
16446 {
16447 struct glyph_row *row;
16448
16449 /* IT.vpos always starts from 0; it counts text lines. */
16450 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16451
16452 /* Find PT if not already found in the lines displayed. */
16453 if (w->cursor.vpos < 0)
16454 {
16455 int dy = it.current_y - start_row->y;
16456
16457 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16458 row = row_containing_pos (w, PT, row, NULL, dy);
16459 if (row)
16460 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16461 dy, nrows_scrolled);
16462 else
16463 {
16464 clear_glyph_matrix (w->desired_matrix);
16465 return 0;
16466 }
16467 }
16468
16469 /* Scroll the display. Do it before the current matrix is
16470 changed. The problem here is that update has not yet
16471 run, i.e. part of the current matrix is not up to date.
16472 scroll_run_hook will clear the cursor, and use the
16473 current matrix to get the height of the row the cursor is
16474 in. */
16475 run.current_y = start_row->y;
16476 run.desired_y = it.current_y;
16477 run.height = it.last_visible_y - it.current_y;
16478
16479 if (run.height > 0 && run.current_y != run.desired_y)
16480 {
16481 update_begin (f);
16482 FRAME_RIF (f)->update_window_begin_hook (w);
16483 FRAME_RIF (f)->clear_window_mouse_face (w);
16484 FRAME_RIF (f)->scroll_run_hook (w, &run);
16485 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16486 update_end (f);
16487 }
16488
16489 /* Shift current matrix down by nrows_scrolled lines. */
16490 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16491 rotate_matrix (w->current_matrix,
16492 start_vpos,
16493 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16494 nrows_scrolled);
16495
16496 /* Disable lines that must be updated. */
16497 for (i = 0; i < nrows_scrolled; ++i)
16498 (start_row + i)->enabled_p = 0;
16499
16500 /* Re-compute Y positions. */
16501 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16502 max_y = it.last_visible_y;
16503 for (row = start_row + nrows_scrolled;
16504 row < bottom_row;
16505 ++row)
16506 {
16507 row->y = it.current_y;
16508 row->visible_height = row->height;
16509
16510 if (row->y < min_y)
16511 row->visible_height -= min_y - row->y;
16512 if (row->y + row->height > max_y)
16513 row->visible_height -= row->y + row->height - max_y;
16514 if (row->fringe_bitmap_periodic_p)
16515 row->redraw_fringe_bitmaps_p = 1;
16516
16517 it.current_y += row->height;
16518
16519 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16520 last_reused_text_row = row;
16521 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16522 break;
16523 }
16524
16525 /* Disable lines in the current matrix which are now
16526 below the window. */
16527 for (++row; row < bottom_row; ++row)
16528 row->enabled_p = row->mode_line_p = 0;
16529 }
16530
16531 /* Update window_end_pos etc.; last_reused_text_row is the last
16532 reused row from the current matrix containing text, if any.
16533 The value of last_text_row is the last displayed line
16534 containing text. */
16535 if (last_reused_text_row)
16536 adjust_window_ends (w, last_reused_text_row, 1);
16537 else if (last_text_row)
16538 adjust_window_ends (w, last_text_row, 0);
16539 else
16540 {
16541 /* This window must be completely empty. */
16542 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16543 w->window_end_pos = Z - ZV;
16544 w->window_end_vpos = 0;
16545 }
16546 w->window_end_valid = 0;
16547
16548 /* Update hint: don't try scrolling again in update_window. */
16549 w->desired_matrix->no_scrolling_p = 1;
16550
16551 #ifdef GLYPH_DEBUG
16552 debug_method_add (w, "try_window_reusing_current_matrix 1");
16553 #endif
16554 return 1;
16555 }
16556 else if (CHARPOS (new_start) > CHARPOS (start))
16557 {
16558 struct glyph_row *pt_row, *row;
16559 struct glyph_row *first_reusable_row;
16560 struct glyph_row *first_row_to_display;
16561 int dy;
16562 int yb = window_text_bottom_y (w);
16563
16564 /* Find the row starting at new_start, if there is one. Don't
16565 reuse a partially visible line at the end. */
16566 first_reusable_row = start_row;
16567 while (first_reusable_row->enabled_p
16568 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16569 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16570 < CHARPOS (new_start)))
16571 ++first_reusable_row;
16572
16573 /* Give up if there is no row to reuse. */
16574 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16575 || !first_reusable_row->enabled_p
16576 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16577 != CHARPOS (new_start)))
16578 return 0;
16579
16580 /* We can reuse fully visible rows beginning with
16581 first_reusable_row to the end of the window. Set
16582 first_row_to_display to the first row that cannot be reused.
16583 Set pt_row to the row containing point, if there is any. */
16584 pt_row = NULL;
16585 for (first_row_to_display = first_reusable_row;
16586 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16587 ++first_row_to_display)
16588 {
16589 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16590 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16591 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16592 && first_row_to_display->ends_at_zv_p
16593 && pt_row == NULL)))
16594 pt_row = first_row_to_display;
16595 }
16596
16597 /* Start displaying at the start of first_row_to_display. */
16598 eassert (first_row_to_display->y < yb);
16599 init_to_row_start (&it, w, first_row_to_display);
16600
16601 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16602 - start_vpos);
16603 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16604 - nrows_scrolled);
16605 it.current_y = (first_row_to_display->y - first_reusable_row->y
16606 + WINDOW_HEADER_LINE_HEIGHT (w));
16607
16608 /* Display lines beginning with first_row_to_display in the
16609 desired matrix. Set last_text_row to the last row displayed
16610 that displays text. */
16611 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16612 if (pt_row == NULL)
16613 w->cursor.vpos = -1;
16614 last_text_row = NULL;
16615 while (it.current_y < it.last_visible_y && !f->fonts_changed)
16616 if (display_line (&it))
16617 last_text_row = it.glyph_row - 1;
16618
16619 /* If point is in a reused row, adjust y and vpos of the cursor
16620 position. */
16621 if (pt_row)
16622 {
16623 w->cursor.vpos -= nrows_scrolled;
16624 w->cursor.y -= first_reusable_row->y - start_row->y;
16625 }
16626
16627 /* Give up if point isn't in a row displayed or reused. (This
16628 also handles the case where w->cursor.vpos < nrows_scrolled
16629 after the calls to display_line, which can happen with scroll
16630 margins. See bug#1295.) */
16631 if (w->cursor.vpos < 0)
16632 {
16633 clear_glyph_matrix (w->desired_matrix);
16634 return 0;
16635 }
16636
16637 /* Scroll the display. */
16638 run.current_y = first_reusable_row->y;
16639 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16640 run.height = it.last_visible_y - run.current_y;
16641 dy = run.current_y - run.desired_y;
16642
16643 if (run.height)
16644 {
16645 update_begin (f);
16646 FRAME_RIF (f)->update_window_begin_hook (w);
16647 FRAME_RIF (f)->clear_window_mouse_face (w);
16648 FRAME_RIF (f)->scroll_run_hook (w, &run);
16649 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16650 update_end (f);
16651 }
16652
16653 /* Adjust Y positions of reused rows. */
16654 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16655 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16656 max_y = it.last_visible_y;
16657 for (row = first_reusable_row; row < first_row_to_display; ++row)
16658 {
16659 row->y -= dy;
16660 row->visible_height = row->height;
16661 if (row->y < min_y)
16662 row->visible_height -= min_y - row->y;
16663 if (row->y + row->height > max_y)
16664 row->visible_height -= row->y + row->height - max_y;
16665 if (row->fringe_bitmap_periodic_p)
16666 row->redraw_fringe_bitmaps_p = 1;
16667 }
16668
16669 /* Scroll the current matrix. */
16670 eassert (nrows_scrolled > 0);
16671 rotate_matrix (w->current_matrix,
16672 start_vpos,
16673 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16674 -nrows_scrolled);
16675
16676 /* Disable rows not reused. */
16677 for (row -= nrows_scrolled; row < bottom_row; ++row)
16678 row->enabled_p = 0;
16679
16680 /* Point may have moved to a different line, so we cannot assume that
16681 the previous cursor position is valid; locate the correct row. */
16682 if (pt_row)
16683 {
16684 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16685 row < bottom_row
16686 && PT >= MATRIX_ROW_END_CHARPOS (row)
16687 && !row->ends_at_zv_p;
16688 row++)
16689 {
16690 w->cursor.vpos++;
16691 w->cursor.y = row->y;
16692 }
16693 if (row < bottom_row)
16694 {
16695 /* Can't simply scan the row for point with
16696 bidi-reordered glyph rows. Let set_cursor_from_row
16697 figure out where to put the cursor, and if it fails,
16698 give up. */
16699 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16700 {
16701 if (!set_cursor_from_row (w, row, w->current_matrix,
16702 0, 0, 0, 0))
16703 {
16704 clear_glyph_matrix (w->desired_matrix);
16705 return 0;
16706 }
16707 }
16708 else
16709 {
16710 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16711 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16712
16713 for (; glyph < end
16714 && (!BUFFERP (glyph->object)
16715 || glyph->charpos < PT);
16716 glyph++)
16717 {
16718 w->cursor.hpos++;
16719 w->cursor.x += glyph->pixel_width;
16720 }
16721 }
16722 }
16723 }
16724
16725 /* Adjust window end. A null value of last_text_row means that
16726 the window end is in reused rows which in turn means that
16727 only its vpos can have changed. */
16728 if (last_text_row)
16729 adjust_window_ends (w, last_text_row, 0);
16730 else
16731 w->window_end_vpos -= nrows_scrolled;
16732
16733 w->window_end_valid = 0;
16734 w->desired_matrix->no_scrolling_p = 1;
16735
16736 #ifdef GLYPH_DEBUG
16737 debug_method_add (w, "try_window_reusing_current_matrix 2");
16738 #endif
16739 return 1;
16740 }
16741
16742 return 0;
16743 }
16744
16745
16746 \f
16747 /************************************************************************
16748 Window redisplay reusing current matrix when buffer has changed
16749 ************************************************************************/
16750
16751 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16752 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16753 ptrdiff_t *, ptrdiff_t *);
16754 static struct glyph_row *
16755 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16756 struct glyph_row *);
16757
16758
16759 /* Return the last row in MATRIX displaying text. If row START is
16760 non-null, start searching with that row. IT gives the dimensions
16761 of the display. Value is null if matrix is empty; otherwise it is
16762 a pointer to the row found. */
16763
16764 static struct glyph_row *
16765 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16766 struct glyph_row *start)
16767 {
16768 struct glyph_row *row, *row_found;
16769
16770 /* Set row_found to the last row in IT->w's current matrix
16771 displaying text. The loop looks funny but think of partially
16772 visible lines. */
16773 row_found = NULL;
16774 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16775 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16776 {
16777 eassert (row->enabled_p);
16778 row_found = row;
16779 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16780 break;
16781 ++row;
16782 }
16783
16784 return row_found;
16785 }
16786
16787
16788 /* Return the last row in the current matrix of W that is not affected
16789 by changes at the start of current_buffer that occurred since W's
16790 current matrix was built. Value is null if no such row exists.
16791
16792 BEG_UNCHANGED us the number of characters unchanged at the start of
16793 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16794 first changed character in current_buffer. Characters at positions <
16795 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16796 when the current matrix was built. */
16797
16798 static struct glyph_row *
16799 find_last_unchanged_at_beg_row (struct window *w)
16800 {
16801 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16802 struct glyph_row *row;
16803 struct glyph_row *row_found = NULL;
16804 int yb = window_text_bottom_y (w);
16805
16806 /* Find the last row displaying unchanged text. */
16807 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16808 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16809 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16810 ++row)
16811 {
16812 if (/* If row ends before first_changed_pos, it is unchanged,
16813 except in some case. */
16814 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16815 /* When row ends in ZV and we write at ZV it is not
16816 unchanged. */
16817 && !row->ends_at_zv_p
16818 /* When first_changed_pos is the end of a continued line,
16819 row is not unchanged because it may be no longer
16820 continued. */
16821 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16822 && (row->continued_p
16823 || row->exact_window_width_line_p))
16824 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16825 needs to be recomputed, so don't consider this row as
16826 unchanged. This happens when the last line was
16827 bidi-reordered and was killed immediately before this
16828 redisplay cycle. In that case, ROW->end stores the
16829 buffer position of the first visual-order character of
16830 the killed text, which is now beyond ZV. */
16831 && CHARPOS (row->end.pos) <= ZV)
16832 row_found = row;
16833
16834 /* Stop if last visible row. */
16835 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16836 break;
16837 }
16838
16839 return row_found;
16840 }
16841
16842
16843 /* Find the first glyph row in the current matrix of W that is not
16844 affected by changes at the end of current_buffer since the
16845 time W's current matrix was built.
16846
16847 Return in *DELTA the number of chars by which buffer positions in
16848 unchanged text at the end of current_buffer must be adjusted.
16849
16850 Return in *DELTA_BYTES the corresponding number of bytes.
16851
16852 Value is null if no such row exists, i.e. all rows are affected by
16853 changes. */
16854
16855 static struct glyph_row *
16856 find_first_unchanged_at_end_row (struct window *w,
16857 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16858 {
16859 struct glyph_row *row;
16860 struct glyph_row *row_found = NULL;
16861
16862 *delta = *delta_bytes = 0;
16863
16864 /* Display must not have been paused, otherwise the current matrix
16865 is not up to date. */
16866 eassert (w->window_end_valid);
16867
16868 /* A value of window_end_pos >= END_UNCHANGED means that the window
16869 end is in the range of changed text. If so, there is no
16870 unchanged row at the end of W's current matrix. */
16871 if (w->window_end_pos >= END_UNCHANGED)
16872 return NULL;
16873
16874 /* Set row to the last row in W's current matrix displaying text. */
16875 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
16876
16877 /* If matrix is entirely empty, no unchanged row exists. */
16878 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16879 {
16880 /* The value of row is the last glyph row in the matrix having a
16881 meaningful buffer position in it. The end position of row
16882 corresponds to window_end_pos. This allows us to translate
16883 buffer positions in the current matrix to current buffer
16884 positions for characters not in changed text. */
16885 ptrdiff_t Z_old =
16886 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
16887 ptrdiff_t Z_BYTE_old =
16888 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16889 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16890 struct glyph_row *first_text_row
16891 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16892
16893 *delta = Z - Z_old;
16894 *delta_bytes = Z_BYTE - Z_BYTE_old;
16895
16896 /* Set last_unchanged_pos to the buffer position of the last
16897 character in the buffer that has not been changed. Z is the
16898 index + 1 of the last character in current_buffer, i.e. by
16899 subtracting END_UNCHANGED we get the index of the last
16900 unchanged character, and we have to add BEG to get its buffer
16901 position. */
16902 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16903 last_unchanged_pos_old = last_unchanged_pos - *delta;
16904
16905 /* Search backward from ROW for a row displaying a line that
16906 starts at a minimum position >= last_unchanged_pos_old. */
16907 for (; row > first_text_row; --row)
16908 {
16909 /* This used to abort, but it can happen.
16910 It is ok to just stop the search instead here. KFS. */
16911 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16912 break;
16913
16914 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16915 row_found = row;
16916 }
16917 }
16918
16919 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16920
16921 return row_found;
16922 }
16923
16924
16925 /* Make sure that glyph rows in the current matrix of window W
16926 reference the same glyph memory as corresponding rows in the
16927 frame's frame matrix. This function is called after scrolling W's
16928 current matrix on a terminal frame in try_window_id and
16929 try_window_reusing_current_matrix. */
16930
16931 static void
16932 sync_frame_with_window_matrix_rows (struct window *w)
16933 {
16934 struct frame *f = XFRAME (w->frame);
16935 struct glyph_row *window_row, *window_row_end, *frame_row;
16936
16937 /* Preconditions: W must be a leaf window and full-width. Its frame
16938 must have a frame matrix. */
16939 eassert (BUFFERP (w->contents));
16940 eassert (WINDOW_FULL_WIDTH_P (w));
16941 eassert (!FRAME_WINDOW_P (f));
16942
16943 /* If W is a full-width window, glyph pointers in W's current matrix
16944 have, by definition, to be the same as glyph pointers in the
16945 corresponding frame matrix. Note that frame matrices have no
16946 marginal areas (see build_frame_matrix). */
16947 window_row = w->current_matrix->rows;
16948 window_row_end = window_row + w->current_matrix->nrows;
16949 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16950 while (window_row < window_row_end)
16951 {
16952 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16953 struct glyph *end = window_row->glyphs[LAST_AREA];
16954
16955 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16956 frame_row->glyphs[TEXT_AREA] = start;
16957 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16958 frame_row->glyphs[LAST_AREA] = end;
16959
16960 /* Disable frame rows whose corresponding window rows have
16961 been disabled in try_window_id. */
16962 if (!window_row->enabled_p)
16963 frame_row->enabled_p = 0;
16964
16965 ++window_row, ++frame_row;
16966 }
16967 }
16968
16969
16970 /* Find the glyph row in window W containing CHARPOS. Consider all
16971 rows between START and END (not inclusive). END null means search
16972 all rows to the end of the display area of W. Value is the row
16973 containing CHARPOS or null. */
16974
16975 struct glyph_row *
16976 row_containing_pos (struct window *w, ptrdiff_t charpos,
16977 struct glyph_row *start, struct glyph_row *end, int dy)
16978 {
16979 struct glyph_row *row = start;
16980 struct glyph_row *best_row = NULL;
16981 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
16982 int last_y;
16983
16984 /* If we happen to start on a header-line, skip that. */
16985 if (row->mode_line_p)
16986 ++row;
16987
16988 if ((end && row >= end) || !row->enabled_p)
16989 return NULL;
16990
16991 last_y = window_text_bottom_y (w) - dy;
16992
16993 while (1)
16994 {
16995 /* Give up if we have gone too far. */
16996 if (end && row >= end)
16997 return NULL;
16998 /* This formerly returned if they were equal.
16999 I think that both quantities are of a "last plus one" type;
17000 if so, when they are equal, the row is within the screen. -- rms. */
17001 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17002 return NULL;
17003
17004 /* If it is in this row, return this row. */
17005 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17006 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17007 /* The end position of a row equals the start
17008 position of the next row. If CHARPOS is there, we
17009 would rather consider it displayed in the next
17010 line, except when this line ends in ZV. */
17011 && !row_for_charpos_p (row, charpos)))
17012 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17013 {
17014 struct glyph *g;
17015
17016 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17017 || (!best_row && !row->continued_p))
17018 return row;
17019 /* In bidi-reordered rows, there could be several rows whose
17020 edges surround CHARPOS, all of these rows belonging to
17021 the same continued line. We need to find the row which
17022 fits CHARPOS the best. */
17023 for (g = row->glyphs[TEXT_AREA];
17024 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17025 g++)
17026 {
17027 if (!STRINGP (g->object))
17028 {
17029 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17030 {
17031 mindif = eabs (g->charpos - charpos);
17032 best_row = row;
17033 /* Exact match always wins. */
17034 if (mindif == 0)
17035 return best_row;
17036 }
17037 }
17038 }
17039 }
17040 else if (best_row && !row->continued_p)
17041 return best_row;
17042 ++row;
17043 }
17044 }
17045
17046
17047 /* Try to redisplay window W by reusing its existing display. W's
17048 current matrix must be up to date when this function is called,
17049 i.e. window_end_valid must be nonzero.
17050
17051 Value is
17052
17053 1 if display has been updated
17054 0 if otherwise unsuccessful
17055 -1 if redisplay with same window start is known not to succeed
17056
17057 The following steps are performed:
17058
17059 1. Find the last row in the current matrix of W that is not
17060 affected by changes at the start of current_buffer. If no such row
17061 is found, give up.
17062
17063 2. Find the first row in W's current matrix that is not affected by
17064 changes at the end of current_buffer. Maybe there is no such row.
17065
17066 3. Display lines beginning with the row + 1 found in step 1 to the
17067 row found in step 2 or, if step 2 didn't find a row, to the end of
17068 the window.
17069
17070 4. If cursor is not known to appear on the window, give up.
17071
17072 5. If display stopped at the row found in step 2, scroll the
17073 display and current matrix as needed.
17074
17075 6. Maybe display some lines at the end of W, if we must. This can
17076 happen under various circumstances, like a partially visible line
17077 becoming fully visible, or because newly displayed lines are displayed
17078 in smaller font sizes.
17079
17080 7. Update W's window end information. */
17081
17082 static int
17083 try_window_id (struct window *w)
17084 {
17085 struct frame *f = XFRAME (w->frame);
17086 struct glyph_matrix *current_matrix = w->current_matrix;
17087 struct glyph_matrix *desired_matrix = w->desired_matrix;
17088 struct glyph_row *last_unchanged_at_beg_row;
17089 struct glyph_row *first_unchanged_at_end_row;
17090 struct glyph_row *row;
17091 struct glyph_row *bottom_row;
17092 int bottom_vpos;
17093 struct it it;
17094 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17095 int dvpos, dy;
17096 struct text_pos start_pos;
17097 struct run run;
17098 int first_unchanged_at_end_vpos = 0;
17099 struct glyph_row *last_text_row, *last_text_row_at_end;
17100 struct text_pos start;
17101 ptrdiff_t first_changed_charpos, last_changed_charpos;
17102
17103 #ifdef GLYPH_DEBUG
17104 if (inhibit_try_window_id)
17105 return 0;
17106 #endif
17107
17108 /* This is handy for debugging. */
17109 #if 0
17110 #define GIVE_UP(X) \
17111 do { \
17112 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17113 return 0; \
17114 } while (0)
17115 #else
17116 #define GIVE_UP(X) return 0
17117 #endif
17118
17119 SET_TEXT_POS_FROM_MARKER (start, w->start);
17120
17121 /* Don't use this for mini-windows because these can show
17122 messages and mini-buffers, and we don't handle that here. */
17123 if (MINI_WINDOW_P (w))
17124 GIVE_UP (1);
17125
17126 /* This flag is used to prevent redisplay optimizations. */
17127 if (windows_or_buffers_changed || f->cursor_type_changed)
17128 GIVE_UP (2);
17129
17130 /* Verify that narrowing has not changed.
17131 Also verify that we were not told to prevent redisplay optimizations.
17132 It would be nice to further
17133 reduce the number of cases where this prevents try_window_id. */
17134 if (current_buffer->clip_changed
17135 || current_buffer->prevent_redisplay_optimizations_p)
17136 GIVE_UP (3);
17137
17138 /* Window must either use window-based redisplay or be full width. */
17139 if (!FRAME_WINDOW_P (f)
17140 && (!FRAME_LINE_INS_DEL_OK (f)
17141 || !WINDOW_FULL_WIDTH_P (w)))
17142 GIVE_UP (4);
17143
17144 /* Give up if point is known NOT to appear in W. */
17145 if (PT < CHARPOS (start))
17146 GIVE_UP (5);
17147
17148 /* Another way to prevent redisplay optimizations. */
17149 if (w->last_modified == 0)
17150 GIVE_UP (6);
17151
17152 /* Verify that window is not hscrolled. */
17153 if (w->hscroll != 0)
17154 GIVE_UP (7);
17155
17156 /* Verify that display wasn't paused. */
17157 if (!w->window_end_valid)
17158 GIVE_UP (8);
17159
17160 /* Can't use this if highlighting a region because a cursor movement
17161 will do more than just set the cursor. */
17162 if (markpos_of_region () >= 0)
17163 GIVE_UP (9);
17164
17165 /* Likewise if highlighting trailing whitespace. */
17166 if (!NILP (Vshow_trailing_whitespace))
17167 GIVE_UP (11);
17168
17169 /* Likewise if showing a region. */
17170 if (w->region_showing)
17171 GIVE_UP (10);
17172
17173 /* Can't use this if overlay arrow position and/or string have
17174 changed. */
17175 if (overlay_arrows_changed_p ())
17176 GIVE_UP (12);
17177
17178 /* When word-wrap is on, adding a space to the first word of a
17179 wrapped line can change the wrap position, altering the line
17180 above it. It might be worthwhile to handle this more
17181 intelligently, but for now just redisplay from scratch. */
17182 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17183 GIVE_UP (21);
17184
17185 /* Under bidi reordering, adding or deleting a character in the
17186 beginning of a paragraph, before the first strong directional
17187 character, can change the base direction of the paragraph (unless
17188 the buffer specifies a fixed paragraph direction), which will
17189 require to redisplay the whole paragraph. It might be worthwhile
17190 to find the paragraph limits and widen the range of redisplayed
17191 lines to that, but for now just give up this optimization and
17192 redisplay from scratch. */
17193 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17194 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17195 GIVE_UP (22);
17196
17197 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17198 only if buffer has really changed. The reason is that the gap is
17199 initially at Z for freshly visited files. The code below would
17200 set end_unchanged to 0 in that case. */
17201 if (MODIFF > SAVE_MODIFF
17202 /* This seems to happen sometimes after saving a buffer. */
17203 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17204 {
17205 if (GPT - BEG < BEG_UNCHANGED)
17206 BEG_UNCHANGED = GPT - BEG;
17207 if (Z - GPT < END_UNCHANGED)
17208 END_UNCHANGED = Z - GPT;
17209 }
17210
17211 /* The position of the first and last character that has been changed. */
17212 first_changed_charpos = BEG + BEG_UNCHANGED;
17213 last_changed_charpos = Z - END_UNCHANGED;
17214
17215 /* If window starts after a line end, and the last change is in
17216 front of that newline, then changes don't affect the display.
17217 This case happens with stealth-fontification. Note that although
17218 the display is unchanged, glyph positions in the matrix have to
17219 be adjusted, of course. */
17220 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17221 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17222 && ((last_changed_charpos < CHARPOS (start)
17223 && CHARPOS (start) == BEGV)
17224 || (last_changed_charpos < CHARPOS (start) - 1
17225 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17226 {
17227 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17228 struct glyph_row *r0;
17229
17230 /* Compute how many chars/bytes have been added to or removed
17231 from the buffer. */
17232 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17233 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17234 Z_delta = Z - Z_old;
17235 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17236
17237 /* Give up if PT is not in the window. Note that it already has
17238 been checked at the start of try_window_id that PT is not in
17239 front of the window start. */
17240 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17241 GIVE_UP (13);
17242
17243 /* If window start is unchanged, we can reuse the whole matrix
17244 as is, after adjusting glyph positions. No need to compute
17245 the window end again, since its offset from Z hasn't changed. */
17246 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17247 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17248 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17249 /* PT must not be in a partially visible line. */
17250 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17251 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17252 {
17253 /* Adjust positions in the glyph matrix. */
17254 if (Z_delta || Z_delta_bytes)
17255 {
17256 struct glyph_row *r1
17257 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17258 increment_matrix_positions (w->current_matrix,
17259 MATRIX_ROW_VPOS (r0, current_matrix),
17260 MATRIX_ROW_VPOS (r1, current_matrix),
17261 Z_delta, Z_delta_bytes);
17262 }
17263
17264 /* Set the cursor. */
17265 row = row_containing_pos (w, PT, r0, NULL, 0);
17266 if (row)
17267 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17268 else
17269 emacs_abort ();
17270 return 1;
17271 }
17272 }
17273
17274 /* Handle the case that changes are all below what is displayed in
17275 the window, and that PT is in the window. This shortcut cannot
17276 be taken if ZV is visible in the window, and text has been added
17277 there that is visible in the window. */
17278 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17279 /* ZV is not visible in the window, or there are no
17280 changes at ZV, actually. */
17281 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17282 || first_changed_charpos == last_changed_charpos))
17283 {
17284 struct glyph_row *r0;
17285
17286 /* Give up if PT is not in the window. Note that it already has
17287 been checked at the start of try_window_id that PT is not in
17288 front of the window start. */
17289 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17290 GIVE_UP (14);
17291
17292 /* If window start is unchanged, we can reuse the whole matrix
17293 as is, without changing glyph positions since no text has
17294 been added/removed in front of the window end. */
17295 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17296 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17297 /* PT must not be in a partially visible line. */
17298 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17299 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17300 {
17301 /* We have to compute the window end anew since text
17302 could have been added/removed after it. */
17303 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17304 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17305
17306 /* Set the cursor. */
17307 row = row_containing_pos (w, PT, r0, NULL, 0);
17308 if (row)
17309 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17310 else
17311 emacs_abort ();
17312 return 2;
17313 }
17314 }
17315
17316 /* Give up if window start is in the changed area.
17317
17318 The condition used to read
17319
17320 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17321
17322 but why that was tested escapes me at the moment. */
17323 if (CHARPOS (start) >= first_changed_charpos
17324 && CHARPOS (start) <= last_changed_charpos)
17325 GIVE_UP (15);
17326
17327 /* Check that window start agrees with the start of the first glyph
17328 row in its current matrix. Check this after we know the window
17329 start is not in changed text, otherwise positions would not be
17330 comparable. */
17331 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17332 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17333 GIVE_UP (16);
17334
17335 /* Give up if the window ends in strings. Overlay strings
17336 at the end are difficult to handle, so don't try. */
17337 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
17338 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17339 GIVE_UP (20);
17340
17341 /* Compute the position at which we have to start displaying new
17342 lines. Some of the lines at the top of the window might be
17343 reusable because they are not displaying changed text. Find the
17344 last row in W's current matrix not affected by changes at the
17345 start of current_buffer. Value is null if changes start in the
17346 first line of window. */
17347 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17348 if (last_unchanged_at_beg_row)
17349 {
17350 /* Avoid starting to display in the middle of a character, a TAB
17351 for instance. This is easier than to set up the iterator
17352 exactly, and it's not a frequent case, so the additional
17353 effort wouldn't really pay off. */
17354 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17355 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17356 && last_unchanged_at_beg_row > w->current_matrix->rows)
17357 --last_unchanged_at_beg_row;
17358
17359 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17360 GIVE_UP (17);
17361
17362 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17363 GIVE_UP (18);
17364 start_pos = it.current.pos;
17365
17366 /* Start displaying new lines in the desired matrix at the same
17367 vpos we would use in the current matrix, i.e. below
17368 last_unchanged_at_beg_row. */
17369 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17370 current_matrix);
17371 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17372 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17373
17374 eassert (it.hpos == 0 && it.current_x == 0);
17375 }
17376 else
17377 {
17378 /* There are no reusable lines at the start of the window.
17379 Start displaying in the first text line. */
17380 start_display (&it, w, start);
17381 it.vpos = it.first_vpos;
17382 start_pos = it.current.pos;
17383 }
17384
17385 /* Find the first row that is not affected by changes at the end of
17386 the buffer. Value will be null if there is no unchanged row, in
17387 which case we must redisplay to the end of the window. delta
17388 will be set to the value by which buffer positions beginning with
17389 first_unchanged_at_end_row have to be adjusted due to text
17390 changes. */
17391 first_unchanged_at_end_row
17392 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17393 IF_DEBUG (debug_delta = delta);
17394 IF_DEBUG (debug_delta_bytes = delta_bytes);
17395
17396 /* Set stop_pos to the buffer position up to which we will have to
17397 display new lines. If first_unchanged_at_end_row != NULL, this
17398 is the buffer position of the start of the line displayed in that
17399 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17400 that we don't stop at a buffer position. */
17401 stop_pos = 0;
17402 if (first_unchanged_at_end_row)
17403 {
17404 eassert (last_unchanged_at_beg_row == NULL
17405 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17406
17407 /* If this is a continuation line, move forward to the next one
17408 that isn't. Changes in lines above affect this line.
17409 Caution: this may move first_unchanged_at_end_row to a row
17410 not displaying text. */
17411 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17412 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17413 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17414 < it.last_visible_y))
17415 ++first_unchanged_at_end_row;
17416
17417 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17418 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17419 >= it.last_visible_y))
17420 first_unchanged_at_end_row = NULL;
17421 else
17422 {
17423 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17424 + delta);
17425 first_unchanged_at_end_vpos
17426 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17427 eassert (stop_pos >= Z - END_UNCHANGED);
17428 }
17429 }
17430 else if (last_unchanged_at_beg_row == NULL)
17431 GIVE_UP (19);
17432
17433
17434 #ifdef GLYPH_DEBUG
17435
17436 /* Either there is no unchanged row at the end, or the one we have
17437 now displays text. This is a necessary condition for the window
17438 end pos calculation at the end of this function. */
17439 eassert (first_unchanged_at_end_row == NULL
17440 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17441
17442 debug_last_unchanged_at_beg_vpos
17443 = (last_unchanged_at_beg_row
17444 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17445 : -1);
17446 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17447
17448 #endif /* GLYPH_DEBUG */
17449
17450
17451 /* Display new lines. Set last_text_row to the last new line
17452 displayed which has text on it, i.e. might end up as being the
17453 line where the window_end_vpos is. */
17454 w->cursor.vpos = -1;
17455 last_text_row = NULL;
17456 overlay_arrow_seen = 0;
17457 while (it.current_y < it.last_visible_y
17458 && !f->fonts_changed
17459 && (first_unchanged_at_end_row == NULL
17460 || IT_CHARPOS (it) < stop_pos))
17461 {
17462 if (display_line (&it))
17463 last_text_row = it.glyph_row - 1;
17464 }
17465
17466 if (f->fonts_changed)
17467 return -1;
17468
17469
17470 /* Compute differences in buffer positions, y-positions etc. for
17471 lines reused at the bottom of the window. Compute what we can
17472 scroll. */
17473 if (first_unchanged_at_end_row
17474 /* No lines reused because we displayed everything up to the
17475 bottom of the window. */
17476 && it.current_y < it.last_visible_y)
17477 {
17478 dvpos = (it.vpos
17479 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17480 current_matrix));
17481 dy = it.current_y - first_unchanged_at_end_row->y;
17482 run.current_y = first_unchanged_at_end_row->y;
17483 run.desired_y = run.current_y + dy;
17484 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17485 }
17486 else
17487 {
17488 delta = delta_bytes = dvpos = dy
17489 = run.current_y = run.desired_y = run.height = 0;
17490 first_unchanged_at_end_row = NULL;
17491 }
17492 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17493
17494
17495 /* Find the cursor if not already found. We have to decide whether
17496 PT will appear on this window (it sometimes doesn't, but this is
17497 not a very frequent case.) This decision has to be made before
17498 the current matrix is altered. A value of cursor.vpos < 0 means
17499 that PT is either in one of the lines beginning at
17500 first_unchanged_at_end_row or below the window. Don't care for
17501 lines that might be displayed later at the window end; as
17502 mentioned, this is not a frequent case. */
17503 if (w->cursor.vpos < 0)
17504 {
17505 /* Cursor in unchanged rows at the top? */
17506 if (PT < CHARPOS (start_pos)
17507 && last_unchanged_at_beg_row)
17508 {
17509 row = row_containing_pos (w, PT,
17510 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17511 last_unchanged_at_beg_row + 1, 0);
17512 if (row)
17513 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17514 }
17515
17516 /* Start from first_unchanged_at_end_row looking for PT. */
17517 else if (first_unchanged_at_end_row)
17518 {
17519 row = row_containing_pos (w, PT - delta,
17520 first_unchanged_at_end_row, NULL, 0);
17521 if (row)
17522 set_cursor_from_row (w, row, w->current_matrix, delta,
17523 delta_bytes, dy, dvpos);
17524 }
17525
17526 /* Give up if cursor was not found. */
17527 if (w->cursor.vpos < 0)
17528 {
17529 clear_glyph_matrix (w->desired_matrix);
17530 return -1;
17531 }
17532 }
17533
17534 /* Don't let the cursor end in the scroll margins. */
17535 {
17536 int this_scroll_margin, cursor_height;
17537 int frame_line_height = default_line_pixel_height (w);
17538 int window_total_lines
17539 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
17540
17541 this_scroll_margin =
17542 max (0, min (scroll_margin, window_total_lines / 4));
17543 this_scroll_margin *= frame_line_height;
17544 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17545
17546 if ((w->cursor.y < this_scroll_margin
17547 && CHARPOS (start) > BEGV)
17548 /* Old redisplay didn't take scroll margin into account at the bottom,
17549 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17550 || (w->cursor.y + (make_cursor_line_fully_visible_p
17551 ? cursor_height + this_scroll_margin
17552 : 1)) > it.last_visible_y)
17553 {
17554 w->cursor.vpos = -1;
17555 clear_glyph_matrix (w->desired_matrix);
17556 return -1;
17557 }
17558 }
17559
17560 /* Scroll the display. Do it before changing the current matrix so
17561 that xterm.c doesn't get confused about where the cursor glyph is
17562 found. */
17563 if (dy && run.height)
17564 {
17565 update_begin (f);
17566
17567 if (FRAME_WINDOW_P (f))
17568 {
17569 FRAME_RIF (f)->update_window_begin_hook (w);
17570 FRAME_RIF (f)->clear_window_mouse_face (w);
17571 FRAME_RIF (f)->scroll_run_hook (w, &run);
17572 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17573 }
17574 else
17575 {
17576 /* Terminal frame. In this case, dvpos gives the number of
17577 lines to scroll by; dvpos < 0 means scroll up. */
17578 int from_vpos
17579 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17580 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17581 int end = (WINDOW_TOP_EDGE_LINE (w)
17582 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17583 + window_internal_height (w));
17584
17585 #if defined (HAVE_GPM) || defined (MSDOS)
17586 x_clear_window_mouse_face (w);
17587 #endif
17588 /* Perform the operation on the screen. */
17589 if (dvpos > 0)
17590 {
17591 /* Scroll last_unchanged_at_beg_row to the end of the
17592 window down dvpos lines. */
17593 set_terminal_window (f, end);
17594
17595 /* On dumb terminals delete dvpos lines at the end
17596 before inserting dvpos empty lines. */
17597 if (!FRAME_SCROLL_REGION_OK (f))
17598 ins_del_lines (f, end - dvpos, -dvpos);
17599
17600 /* Insert dvpos empty lines in front of
17601 last_unchanged_at_beg_row. */
17602 ins_del_lines (f, from, dvpos);
17603 }
17604 else if (dvpos < 0)
17605 {
17606 /* Scroll up last_unchanged_at_beg_vpos to the end of
17607 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17608 set_terminal_window (f, end);
17609
17610 /* Delete dvpos lines in front of
17611 last_unchanged_at_beg_vpos. ins_del_lines will set
17612 the cursor to the given vpos and emit |dvpos| delete
17613 line sequences. */
17614 ins_del_lines (f, from + dvpos, dvpos);
17615
17616 /* On a dumb terminal insert dvpos empty lines at the
17617 end. */
17618 if (!FRAME_SCROLL_REGION_OK (f))
17619 ins_del_lines (f, end + dvpos, -dvpos);
17620 }
17621
17622 set_terminal_window (f, 0);
17623 }
17624
17625 update_end (f);
17626 }
17627
17628 /* Shift reused rows of the current matrix to the right position.
17629 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17630 text. */
17631 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17632 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17633 if (dvpos < 0)
17634 {
17635 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17636 bottom_vpos, dvpos);
17637 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17638 bottom_vpos);
17639 }
17640 else if (dvpos > 0)
17641 {
17642 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17643 bottom_vpos, dvpos);
17644 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17645 first_unchanged_at_end_vpos + dvpos);
17646 }
17647
17648 /* For frame-based redisplay, make sure that current frame and window
17649 matrix are in sync with respect to glyph memory. */
17650 if (!FRAME_WINDOW_P (f))
17651 sync_frame_with_window_matrix_rows (w);
17652
17653 /* Adjust buffer positions in reused rows. */
17654 if (delta || delta_bytes)
17655 increment_matrix_positions (current_matrix,
17656 first_unchanged_at_end_vpos + dvpos,
17657 bottom_vpos, delta, delta_bytes);
17658
17659 /* Adjust Y positions. */
17660 if (dy)
17661 shift_glyph_matrix (w, current_matrix,
17662 first_unchanged_at_end_vpos + dvpos,
17663 bottom_vpos, dy);
17664
17665 if (first_unchanged_at_end_row)
17666 {
17667 first_unchanged_at_end_row += dvpos;
17668 if (first_unchanged_at_end_row->y >= it.last_visible_y
17669 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17670 first_unchanged_at_end_row = NULL;
17671 }
17672
17673 /* If scrolling up, there may be some lines to display at the end of
17674 the window. */
17675 last_text_row_at_end = NULL;
17676 if (dy < 0)
17677 {
17678 /* Scrolling up can leave for example a partially visible line
17679 at the end of the window to be redisplayed. */
17680 /* Set last_row to the glyph row in the current matrix where the
17681 window end line is found. It has been moved up or down in
17682 the matrix by dvpos. */
17683 int last_vpos = w->window_end_vpos + dvpos;
17684 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17685
17686 /* If last_row is the window end line, it should display text. */
17687 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17688
17689 /* If window end line was partially visible before, begin
17690 displaying at that line. Otherwise begin displaying with the
17691 line following it. */
17692 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17693 {
17694 init_to_row_start (&it, w, last_row);
17695 it.vpos = last_vpos;
17696 it.current_y = last_row->y;
17697 }
17698 else
17699 {
17700 init_to_row_end (&it, w, last_row);
17701 it.vpos = 1 + last_vpos;
17702 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17703 ++last_row;
17704 }
17705
17706 /* We may start in a continuation line. If so, we have to
17707 get the right continuation_lines_width and current_x. */
17708 it.continuation_lines_width = last_row->continuation_lines_width;
17709 it.hpos = it.current_x = 0;
17710
17711 /* Display the rest of the lines at the window end. */
17712 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17713 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17714 {
17715 /* Is it always sure that the display agrees with lines in
17716 the current matrix? I don't think so, so we mark rows
17717 displayed invalid in the current matrix by setting their
17718 enabled_p flag to zero. */
17719 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17720 if (display_line (&it))
17721 last_text_row_at_end = it.glyph_row - 1;
17722 }
17723 }
17724
17725 /* Update window_end_pos and window_end_vpos. */
17726 if (first_unchanged_at_end_row && !last_text_row_at_end)
17727 {
17728 /* Window end line if one of the preserved rows from the current
17729 matrix. Set row to the last row displaying text in current
17730 matrix starting at first_unchanged_at_end_row, after
17731 scrolling. */
17732 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17733 row = find_last_row_displaying_text (w->current_matrix, &it,
17734 first_unchanged_at_end_row);
17735 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17736 adjust_window_ends (w, row, 1);
17737 eassert (w->window_end_bytepos >= 0);
17738 IF_DEBUG (debug_method_add (w, "A"));
17739 }
17740 else if (last_text_row_at_end)
17741 {
17742 adjust_window_ends (w, last_text_row_at_end, 0);
17743 eassert (w->window_end_bytepos >= 0);
17744 IF_DEBUG (debug_method_add (w, "B"));
17745 }
17746 else if (last_text_row)
17747 {
17748 /* We have displayed either to the end of the window or at the
17749 end of the window, i.e. the last row with text is to be found
17750 in the desired matrix. */
17751 adjust_window_ends (w, last_text_row, 0);
17752 eassert (w->window_end_bytepos >= 0);
17753 }
17754 else if (first_unchanged_at_end_row == NULL
17755 && last_text_row == NULL
17756 && last_text_row_at_end == NULL)
17757 {
17758 /* Displayed to end of window, but no line containing text was
17759 displayed. Lines were deleted at the end of the window. */
17760 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17761 int vpos = w->window_end_vpos;
17762 struct glyph_row *current_row = current_matrix->rows + vpos;
17763 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17764
17765 for (row = NULL;
17766 row == NULL && vpos >= first_vpos;
17767 --vpos, --current_row, --desired_row)
17768 {
17769 if (desired_row->enabled_p)
17770 {
17771 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17772 row = desired_row;
17773 }
17774 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17775 row = current_row;
17776 }
17777
17778 eassert (row != NULL);
17779 w->window_end_vpos = vpos + 1;
17780 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17781 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17782 eassert (w->window_end_bytepos >= 0);
17783 IF_DEBUG (debug_method_add (w, "C"));
17784 }
17785 else
17786 emacs_abort ();
17787
17788 IF_DEBUG (debug_end_pos = w->window_end_pos;
17789 debug_end_vpos = w->window_end_vpos);
17790
17791 /* Record that display has not been completed. */
17792 w->window_end_valid = 0;
17793 w->desired_matrix->no_scrolling_p = 1;
17794 return 3;
17795
17796 #undef GIVE_UP
17797 }
17798
17799
17800 \f
17801 /***********************************************************************
17802 More debugging support
17803 ***********************************************************************/
17804
17805 #ifdef GLYPH_DEBUG
17806
17807 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17808 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17809 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17810
17811
17812 /* Dump the contents of glyph matrix MATRIX on stderr.
17813
17814 GLYPHS 0 means don't show glyph contents.
17815 GLYPHS 1 means show glyphs in short form
17816 GLYPHS > 1 means show glyphs in long form. */
17817
17818 void
17819 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17820 {
17821 int i;
17822 for (i = 0; i < matrix->nrows; ++i)
17823 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17824 }
17825
17826
17827 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17828 the glyph row and area where the glyph comes from. */
17829
17830 void
17831 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17832 {
17833 if (glyph->type == CHAR_GLYPH
17834 || glyph->type == GLYPHLESS_GLYPH)
17835 {
17836 fprintf (stderr,
17837 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17838 glyph - row->glyphs[TEXT_AREA],
17839 (glyph->type == CHAR_GLYPH
17840 ? 'C'
17841 : 'G'),
17842 glyph->charpos,
17843 (BUFFERP (glyph->object)
17844 ? 'B'
17845 : (STRINGP (glyph->object)
17846 ? 'S'
17847 : (INTEGERP (glyph->object)
17848 ? '0'
17849 : '-'))),
17850 glyph->pixel_width,
17851 glyph->u.ch,
17852 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17853 ? glyph->u.ch
17854 : '.'),
17855 glyph->face_id,
17856 glyph->left_box_line_p,
17857 glyph->right_box_line_p);
17858 }
17859 else if (glyph->type == STRETCH_GLYPH)
17860 {
17861 fprintf (stderr,
17862 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17863 glyph - row->glyphs[TEXT_AREA],
17864 'S',
17865 glyph->charpos,
17866 (BUFFERP (glyph->object)
17867 ? 'B'
17868 : (STRINGP (glyph->object)
17869 ? 'S'
17870 : (INTEGERP (glyph->object)
17871 ? '0'
17872 : '-'))),
17873 glyph->pixel_width,
17874 0,
17875 ' ',
17876 glyph->face_id,
17877 glyph->left_box_line_p,
17878 glyph->right_box_line_p);
17879 }
17880 else if (glyph->type == IMAGE_GLYPH)
17881 {
17882 fprintf (stderr,
17883 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17884 glyph - row->glyphs[TEXT_AREA],
17885 'I',
17886 glyph->charpos,
17887 (BUFFERP (glyph->object)
17888 ? 'B'
17889 : (STRINGP (glyph->object)
17890 ? 'S'
17891 : (INTEGERP (glyph->object)
17892 ? '0'
17893 : '-'))),
17894 glyph->pixel_width,
17895 glyph->u.img_id,
17896 '.',
17897 glyph->face_id,
17898 glyph->left_box_line_p,
17899 glyph->right_box_line_p);
17900 }
17901 else if (glyph->type == COMPOSITE_GLYPH)
17902 {
17903 fprintf (stderr,
17904 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17905 glyph - row->glyphs[TEXT_AREA],
17906 '+',
17907 glyph->charpos,
17908 (BUFFERP (glyph->object)
17909 ? 'B'
17910 : (STRINGP (glyph->object)
17911 ? 'S'
17912 : (INTEGERP (glyph->object)
17913 ? '0'
17914 : '-'))),
17915 glyph->pixel_width,
17916 glyph->u.cmp.id);
17917 if (glyph->u.cmp.automatic)
17918 fprintf (stderr,
17919 "[%d-%d]",
17920 glyph->slice.cmp.from, glyph->slice.cmp.to);
17921 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17922 glyph->face_id,
17923 glyph->left_box_line_p,
17924 glyph->right_box_line_p);
17925 }
17926 }
17927
17928
17929 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17930 GLYPHS 0 means don't show glyph contents.
17931 GLYPHS 1 means show glyphs in short form
17932 GLYPHS > 1 means show glyphs in long form. */
17933
17934 void
17935 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17936 {
17937 if (glyphs != 1)
17938 {
17939 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17940 fprintf (stderr, "==============================================================================\n");
17941
17942 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17943 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17944 vpos,
17945 MATRIX_ROW_START_CHARPOS (row),
17946 MATRIX_ROW_END_CHARPOS (row),
17947 row->used[TEXT_AREA],
17948 row->contains_overlapping_glyphs_p,
17949 row->enabled_p,
17950 row->truncated_on_left_p,
17951 row->truncated_on_right_p,
17952 row->continued_p,
17953 MATRIX_ROW_CONTINUATION_LINE_P (row),
17954 MATRIX_ROW_DISPLAYS_TEXT_P (row),
17955 row->ends_at_zv_p,
17956 row->fill_line_p,
17957 row->ends_in_middle_of_char_p,
17958 row->starts_in_middle_of_char_p,
17959 row->mouse_face_p,
17960 row->x,
17961 row->y,
17962 row->pixel_width,
17963 row->height,
17964 row->visible_height,
17965 row->ascent,
17966 row->phys_ascent);
17967 /* The next 3 lines should align to "Start" in the header. */
17968 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
17969 row->end.overlay_string_index,
17970 row->continuation_lines_width);
17971 fprintf (stderr, " %9"pI"d %9"pI"d\n",
17972 CHARPOS (row->start.string_pos),
17973 CHARPOS (row->end.string_pos));
17974 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
17975 row->end.dpvec_index);
17976 }
17977
17978 if (glyphs > 1)
17979 {
17980 int area;
17981
17982 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17983 {
17984 struct glyph *glyph = row->glyphs[area];
17985 struct glyph *glyph_end = glyph + row->used[area];
17986
17987 /* Glyph for a line end in text. */
17988 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
17989 ++glyph_end;
17990
17991 if (glyph < glyph_end)
17992 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
17993
17994 for (; glyph < glyph_end; ++glyph)
17995 dump_glyph (row, glyph, area);
17996 }
17997 }
17998 else if (glyphs == 1)
17999 {
18000 int area;
18001
18002 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18003 {
18004 char *s = alloca (row->used[area] + 4);
18005 int i;
18006
18007 for (i = 0; i < row->used[area]; ++i)
18008 {
18009 struct glyph *glyph = row->glyphs[area] + i;
18010 if (i == row->used[area] - 1
18011 && area == TEXT_AREA
18012 && INTEGERP (glyph->object)
18013 && glyph->type == CHAR_GLYPH
18014 && glyph->u.ch == ' ')
18015 {
18016 strcpy (&s[i], "[\\n]");
18017 i += 4;
18018 }
18019 else if (glyph->type == CHAR_GLYPH
18020 && glyph->u.ch < 0x80
18021 && glyph->u.ch >= ' ')
18022 s[i] = glyph->u.ch;
18023 else
18024 s[i] = '.';
18025 }
18026
18027 s[i] = '\0';
18028 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18029 }
18030 }
18031 }
18032
18033
18034 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18035 Sdump_glyph_matrix, 0, 1, "p",
18036 doc: /* Dump the current matrix of the selected window to stderr.
18037 Shows contents of glyph row structures. With non-nil
18038 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18039 glyphs in short form, otherwise show glyphs in long form. */)
18040 (Lisp_Object glyphs)
18041 {
18042 struct window *w = XWINDOW (selected_window);
18043 struct buffer *buffer = XBUFFER (w->contents);
18044
18045 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18046 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18047 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18048 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18049 fprintf (stderr, "=============================================\n");
18050 dump_glyph_matrix (w->current_matrix,
18051 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18052 return Qnil;
18053 }
18054
18055
18056 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18057 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18058 (void)
18059 {
18060 struct frame *f = XFRAME (selected_frame);
18061 dump_glyph_matrix (f->current_matrix, 1);
18062 return Qnil;
18063 }
18064
18065
18066 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18067 doc: /* Dump glyph row ROW to stderr.
18068 GLYPH 0 means don't dump glyphs.
18069 GLYPH 1 means dump glyphs in short form.
18070 GLYPH > 1 or omitted means dump glyphs in long form. */)
18071 (Lisp_Object row, Lisp_Object glyphs)
18072 {
18073 struct glyph_matrix *matrix;
18074 EMACS_INT vpos;
18075
18076 CHECK_NUMBER (row);
18077 matrix = XWINDOW (selected_window)->current_matrix;
18078 vpos = XINT (row);
18079 if (vpos >= 0 && vpos < matrix->nrows)
18080 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18081 vpos,
18082 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18083 return Qnil;
18084 }
18085
18086
18087 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18088 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18089 GLYPH 0 means don't dump glyphs.
18090 GLYPH 1 means dump glyphs in short form.
18091 GLYPH > 1 or omitted means dump glyphs in long form. */)
18092 (Lisp_Object row, Lisp_Object glyphs)
18093 {
18094 struct frame *sf = SELECTED_FRAME ();
18095 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18096 EMACS_INT vpos;
18097
18098 CHECK_NUMBER (row);
18099 vpos = XINT (row);
18100 if (vpos >= 0 && vpos < m->nrows)
18101 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18102 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18103 return Qnil;
18104 }
18105
18106
18107 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18108 doc: /* Toggle tracing of redisplay.
18109 With ARG, turn tracing on if and only if ARG is positive. */)
18110 (Lisp_Object arg)
18111 {
18112 if (NILP (arg))
18113 trace_redisplay_p = !trace_redisplay_p;
18114 else
18115 {
18116 arg = Fprefix_numeric_value (arg);
18117 trace_redisplay_p = XINT (arg) > 0;
18118 }
18119
18120 return Qnil;
18121 }
18122
18123
18124 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18125 doc: /* Like `format', but print result to stderr.
18126 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18127 (ptrdiff_t nargs, Lisp_Object *args)
18128 {
18129 Lisp_Object s = Fformat (nargs, args);
18130 fprintf (stderr, "%s", SDATA (s));
18131 return Qnil;
18132 }
18133
18134 #endif /* GLYPH_DEBUG */
18135
18136
18137 \f
18138 /***********************************************************************
18139 Building Desired Matrix Rows
18140 ***********************************************************************/
18141
18142 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18143 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18144
18145 static struct glyph_row *
18146 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18147 {
18148 struct frame *f = XFRAME (WINDOW_FRAME (w));
18149 struct buffer *buffer = XBUFFER (w->contents);
18150 struct buffer *old = current_buffer;
18151 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18152 int arrow_len = SCHARS (overlay_arrow_string);
18153 const unsigned char *arrow_end = arrow_string + arrow_len;
18154 const unsigned char *p;
18155 struct it it;
18156 bool multibyte_p;
18157 int n_glyphs_before;
18158
18159 set_buffer_temp (buffer);
18160 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18161 it.glyph_row->used[TEXT_AREA] = 0;
18162 SET_TEXT_POS (it.position, 0, 0);
18163
18164 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18165 p = arrow_string;
18166 while (p < arrow_end)
18167 {
18168 Lisp_Object face, ilisp;
18169
18170 /* Get the next character. */
18171 if (multibyte_p)
18172 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18173 else
18174 {
18175 it.c = it.char_to_display = *p, it.len = 1;
18176 if (! ASCII_CHAR_P (it.c))
18177 it.char_to_display = BYTE8_TO_CHAR (it.c);
18178 }
18179 p += it.len;
18180
18181 /* Get its face. */
18182 ilisp = make_number (p - arrow_string);
18183 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18184 it.face_id = compute_char_face (f, it.char_to_display, face);
18185
18186 /* Compute its width, get its glyphs. */
18187 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18188 SET_TEXT_POS (it.position, -1, -1);
18189 PRODUCE_GLYPHS (&it);
18190
18191 /* If this character doesn't fit any more in the line, we have
18192 to remove some glyphs. */
18193 if (it.current_x > it.last_visible_x)
18194 {
18195 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18196 break;
18197 }
18198 }
18199
18200 set_buffer_temp (old);
18201 return it.glyph_row;
18202 }
18203
18204
18205 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18206 glyphs to insert is determined by produce_special_glyphs. */
18207
18208 static void
18209 insert_left_trunc_glyphs (struct it *it)
18210 {
18211 struct it truncate_it;
18212 struct glyph *from, *end, *to, *toend;
18213
18214 eassert (!FRAME_WINDOW_P (it->f)
18215 || (!it->glyph_row->reversed_p
18216 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18217 || (it->glyph_row->reversed_p
18218 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18219
18220 /* Get the truncation glyphs. */
18221 truncate_it = *it;
18222 truncate_it.current_x = 0;
18223 truncate_it.face_id = DEFAULT_FACE_ID;
18224 truncate_it.glyph_row = &scratch_glyph_row;
18225 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18226 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18227 truncate_it.object = make_number (0);
18228 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18229
18230 /* Overwrite glyphs from IT with truncation glyphs. */
18231 if (!it->glyph_row->reversed_p)
18232 {
18233 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18234
18235 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18236 end = from + tused;
18237 to = it->glyph_row->glyphs[TEXT_AREA];
18238 toend = to + it->glyph_row->used[TEXT_AREA];
18239 if (FRAME_WINDOW_P (it->f))
18240 {
18241 /* On GUI frames, when variable-size fonts are displayed,
18242 the truncation glyphs may need more pixels than the row's
18243 glyphs they overwrite. We overwrite more glyphs to free
18244 enough screen real estate, and enlarge the stretch glyph
18245 on the right (see display_line), if there is one, to
18246 preserve the screen position of the truncation glyphs on
18247 the right. */
18248 int w = 0;
18249 struct glyph *g = to;
18250 short used;
18251
18252 /* The first glyph could be partially visible, in which case
18253 it->glyph_row->x will be negative. But we want the left
18254 truncation glyphs to be aligned at the left margin of the
18255 window, so we override the x coordinate at which the row
18256 will begin. */
18257 it->glyph_row->x = 0;
18258 while (g < toend && w < it->truncation_pixel_width)
18259 {
18260 w += g->pixel_width;
18261 ++g;
18262 }
18263 if (g - to - tused > 0)
18264 {
18265 memmove (to + tused, g, (toend - g) * sizeof(*g));
18266 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18267 }
18268 used = it->glyph_row->used[TEXT_AREA];
18269 if (it->glyph_row->truncated_on_right_p
18270 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18271 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18272 == STRETCH_GLYPH)
18273 {
18274 int extra = w - it->truncation_pixel_width;
18275
18276 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18277 }
18278 }
18279
18280 while (from < end)
18281 *to++ = *from++;
18282
18283 /* There may be padding glyphs left over. Overwrite them too. */
18284 if (!FRAME_WINDOW_P (it->f))
18285 {
18286 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18287 {
18288 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18289 while (from < end)
18290 *to++ = *from++;
18291 }
18292 }
18293
18294 if (to > toend)
18295 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18296 }
18297 else
18298 {
18299 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18300
18301 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18302 that back to front. */
18303 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18304 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18305 toend = it->glyph_row->glyphs[TEXT_AREA];
18306 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18307 if (FRAME_WINDOW_P (it->f))
18308 {
18309 int w = 0;
18310 struct glyph *g = to;
18311
18312 while (g >= toend && w < it->truncation_pixel_width)
18313 {
18314 w += g->pixel_width;
18315 --g;
18316 }
18317 if (to - g - tused > 0)
18318 to = g + tused;
18319 if (it->glyph_row->truncated_on_right_p
18320 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18321 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18322 {
18323 int extra = w - it->truncation_pixel_width;
18324
18325 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18326 }
18327 }
18328
18329 while (from >= end && to >= toend)
18330 *to-- = *from--;
18331 if (!FRAME_WINDOW_P (it->f))
18332 {
18333 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18334 {
18335 from =
18336 truncate_it.glyph_row->glyphs[TEXT_AREA]
18337 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18338 while (from >= end && to >= toend)
18339 *to-- = *from--;
18340 }
18341 }
18342 if (from >= end)
18343 {
18344 /* Need to free some room before prepending additional
18345 glyphs. */
18346 int move_by = from - end + 1;
18347 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18348 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18349
18350 for ( ; g >= g0; g--)
18351 g[move_by] = *g;
18352 while (from >= end)
18353 *to-- = *from--;
18354 it->glyph_row->used[TEXT_AREA] += move_by;
18355 }
18356 }
18357 }
18358
18359 /* Compute the hash code for ROW. */
18360 unsigned
18361 row_hash (struct glyph_row *row)
18362 {
18363 int area, k;
18364 unsigned hashval = 0;
18365
18366 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18367 for (k = 0; k < row->used[area]; ++k)
18368 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18369 + row->glyphs[area][k].u.val
18370 + row->glyphs[area][k].face_id
18371 + row->glyphs[area][k].padding_p
18372 + (row->glyphs[area][k].type << 2));
18373
18374 return hashval;
18375 }
18376
18377 /* Compute the pixel height and width of IT->glyph_row.
18378
18379 Most of the time, ascent and height of a display line will be equal
18380 to the max_ascent and max_height values of the display iterator
18381 structure. This is not the case if
18382
18383 1. We hit ZV without displaying anything. In this case, max_ascent
18384 and max_height will be zero.
18385
18386 2. We have some glyphs that don't contribute to the line height.
18387 (The glyph row flag contributes_to_line_height_p is for future
18388 pixmap extensions).
18389
18390 The first case is easily covered by using default values because in
18391 these cases, the line height does not really matter, except that it
18392 must not be zero. */
18393
18394 static void
18395 compute_line_metrics (struct it *it)
18396 {
18397 struct glyph_row *row = it->glyph_row;
18398
18399 if (FRAME_WINDOW_P (it->f))
18400 {
18401 int i, min_y, max_y;
18402
18403 /* The line may consist of one space only, that was added to
18404 place the cursor on it. If so, the row's height hasn't been
18405 computed yet. */
18406 if (row->height == 0)
18407 {
18408 if (it->max_ascent + it->max_descent == 0)
18409 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18410 row->ascent = it->max_ascent;
18411 row->height = it->max_ascent + it->max_descent;
18412 row->phys_ascent = it->max_phys_ascent;
18413 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18414 row->extra_line_spacing = it->max_extra_line_spacing;
18415 }
18416
18417 /* Compute the width of this line. */
18418 row->pixel_width = row->x;
18419 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18420 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18421
18422 eassert (row->pixel_width >= 0);
18423 eassert (row->ascent >= 0 && row->height > 0);
18424
18425 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18426 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18427
18428 /* If first line's physical ascent is larger than its logical
18429 ascent, use the physical ascent, and make the row taller.
18430 This makes accented characters fully visible. */
18431 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18432 && row->phys_ascent > row->ascent)
18433 {
18434 row->height += row->phys_ascent - row->ascent;
18435 row->ascent = row->phys_ascent;
18436 }
18437
18438 /* Compute how much of the line is visible. */
18439 row->visible_height = row->height;
18440
18441 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18442 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18443
18444 if (row->y < min_y)
18445 row->visible_height -= min_y - row->y;
18446 if (row->y + row->height > max_y)
18447 row->visible_height -= row->y + row->height - max_y;
18448 }
18449 else
18450 {
18451 row->pixel_width = row->used[TEXT_AREA];
18452 if (row->continued_p)
18453 row->pixel_width -= it->continuation_pixel_width;
18454 else if (row->truncated_on_right_p)
18455 row->pixel_width -= it->truncation_pixel_width;
18456 row->ascent = row->phys_ascent = 0;
18457 row->height = row->phys_height = row->visible_height = 1;
18458 row->extra_line_spacing = 0;
18459 }
18460
18461 /* Compute a hash code for this row. */
18462 row->hash = row_hash (row);
18463
18464 it->max_ascent = it->max_descent = 0;
18465 it->max_phys_ascent = it->max_phys_descent = 0;
18466 }
18467
18468
18469 /* Append one space to the glyph row of iterator IT if doing a
18470 window-based redisplay. The space has the same face as
18471 IT->face_id. Value is non-zero if a space was added.
18472
18473 This function is called to make sure that there is always one glyph
18474 at the end of a glyph row that the cursor can be set on under
18475 window-systems. (If there weren't such a glyph we would not know
18476 how wide and tall a box cursor should be displayed).
18477
18478 At the same time this space let's a nicely handle clearing to the
18479 end of the line if the row ends in italic text. */
18480
18481 static int
18482 append_space_for_newline (struct it *it, int default_face_p)
18483 {
18484 if (FRAME_WINDOW_P (it->f))
18485 {
18486 int n = it->glyph_row->used[TEXT_AREA];
18487
18488 if (it->glyph_row->glyphs[TEXT_AREA] + n
18489 < it->glyph_row->glyphs[1 + TEXT_AREA])
18490 {
18491 /* Save some values that must not be changed.
18492 Must save IT->c and IT->len because otherwise
18493 ITERATOR_AT_END_P wouldn't work anymore after
18494 append_space_for_newline has been called. */
18495 enum display_element_type saved_what = it->what;
18496 int saved_c = it->c, saved_len = it->len;
18497 int saved_char_to_display = it->char_to_display;
18498 int saved_x = it->current_x;
18499 int saved_face_id = it->face_id;
18500 int saved_box_end = it->end_of_box_run_p;
18501 struct text_pos saved_pos;
18502 Lisp_Object saved_object;
18503 struct face *face;
18504
18505 saved_object = it->object;
18506 saved_pos = it->position;
18507
18508 it->what = IT_CHARACTER;
18509 memset (&it->position, 0, sizeof it->position);
18510 it->object = make_number (0);
18511 it->c = it->char_to_display = ' ';
18512 it->len = 1;
18513
18514 /* If the default face was remapped, be sure to use the
18515 remapped face for the appended newline. */
18516 if (default_face_p)
18517 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18518 else if (it->face_before_selective_p)
18519 it->face_id = it->saved_face_id;
18520 face = FACE_FROM_ID (it->f, it->face_id);
18521 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18522 /* In R2L rows, we will prepend a stretch glyph that will
18523 have the end_of_box_run_p flag set for it, so there's no
18524 need for the appended newline glyph to have that flag
18525 set. */
18526 if (it->glyph_row->reversed_p
18527 /* But if the appended newline glyph goes all the way to
18528 the end of the row, there will be no stretch glyph,
18529 so leave the box flag set. */
18530 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18531 it->end_of_box_run_p = 0;
18532
18533 PRODUCE_GLYPHS (it);
18534
18535 it->override_ascent = -1;
18536 it->constrain_row_ascent_descent_p = 0;
18537 it->current_x = saved_x;
18538 it->object = saved_object;
18539 it->position = saved_pos;
18540 it->what = saved_what;
18541 it->face_id = saved_face_id;
18542 it->len = saved_len;
18543 it->c = saved_c;
18544 it->char_to_display = saved_char_to_display;
18545 it->end_of_box_run_p = saved_box_end;
18546 return 1;
18547 }
18548 }
18549
18550 return 0;
18551 }
18552
18553
18554 /* Extend the face of the last glyph in the text area of IT->glyph_row
18555 to the end of the display line. Called from display_line. If the
18556 glyph row is empty, add a space glyph to it so that we know the
18557 face to draw. Set the glyph row flag fill_line_p. If the glyph
18558 row is R2L, prepend a stretch glyph to cover the empty space to the
18559 left of the leftmost glyph. */
18560
18561 static void
18562 extend_face_to_end_of_line (struct it *it)
18563 {
18564 struct face *face, *default_face;
18565 struct frame *f = it->f;
18566
18567 /* If line is already filled, do nothing. Non window-system frames
18568 get a grace of one more ``pixel'' because their characters are
18569 1-``pixel'' wide, so they hit the equality too early. This grace
18570 is needed only for R2L rows that are not continued, to produce
18571 one extra blank where we could display the cursor. */
18572 if (it->current_x >= it->last_visible_x
18573 + (!FRAME_WINDOW_P (f)
18574 && it->glyph_row->reversed_p
18575 && !it->glyph_row->continued_p))
18576 return;
18577
18578 /* The default face, possibly remapped. */
18579 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18580
18581 /* Face extension extends the background and box of IT->face_id
18582 to the end of the line. If the background equals the background
18583 of the frame, we don't have to do anything. */
18584 if (it->face_before_selective_p)
18585 face = FACE_FROM_ID (f, it->saved_face_id);
18586 else
18587 face = FACE_FROM_ID (f, it->face_id);
18588
18589 if (FRAME_WINDOW_P (f)
18590 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18591 && face->box == FACE_NO_BOX
18592 && face->background == FRAME_BACKGROUND_PIXEL (f)
18593 && !face->stipple
18594 && !it->glyph_row->reversed_p)
18595 return;
18596
18597 /* Set the glyph row flag indicating that the face of the last glyph
18598 in the text area has to be drawn to the end of the text area. */
18599 it->glyph_row->fill_line_p = 1;
18600
18601 /* If current character of IT is not ASCII, make sure we have the
18602 ASCII face. This will be automatically undone the next time
18603 get_next_display_element returns a multibyte character. Note
18604 that the character will always be single byte in unibyte
18605 text. */
18606 if (!ASCII_CHAR_P (it->c))
18607 {
18608 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18609 }
18610
18611 if (FRAME_WINDOW_P (f))
18612 {
18613 /* If the row is empty, add a space with the current face of IT,
18614 so that we know which face to draw. */
18615 if (it->glyph_row->used[TEXT_AREA] == 0)
18616 {
18617 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18618 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18619 it->glyph_row->used[TEXT_AREA] = 1;
18620 }
18621 #ifdef HAVE_WINDOW_SYSTEM
18622 if (it->glyph_row->reversed_p)
18623 {
18624 /* Prepend a stretch glyph to the row, such that the
18625 rightmost glyph will be drawn flushed all the way to the
18626 right margin of the window. The stretch glyph that will
18627 occupy the empty space, if any, to the left of the
18628 glyphs. */
18629 struct font *font = face->font ? face->font : FRAME_FONT (f);
18630 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18631 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18632 struct glyph *g;
18633 int row_width, stretch_ascent, stretch_width;
18634 struct text_pos saved_pos;
18635 int saved_face_id, saved_avoid_cursor, saved_box_start;
18636
18637 for (row_width = 0, g = row_start; g < row_end; g++)
18638 row_width += g->pixel_width;
18639 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18640 if (stretch_width > 0)
18641 {
18642 stretch_ascent =
18643 (((it->ascent + it->descent)
18644 * FONT_BASE (font)) / FONT_HEIGHT (font));
18645 saved_pos = it->position;
18646 memset (&it->position, 0, sizeof it->position);
18647 saved_avoid_cursor = it->avoid_cursor_p;
18648 it->avoid_cursor_p = 1;
18649 saved_face_id = it->face_id;
18650 saved_box_start = it->start_of_box_run_p;
18651 /* The last row's stretch glyph should get the default
18652 face, to avoid painting the rest of the window with
18653 the region face, if the region ends at ZV. */
18654 if (it->glyph_row->ends_at_zv_p)
18655 it->face_id = default_face->id;
18656 else
18657 it->face_id = face->id;
18658 it->start_of_box_run_p = 0;
18659 append_stretch_glyph (it, make_number (0), stretch_width,
18660 it->ascent + it->descent, stretch_ascent);
18661 it->position = saved_pos;
18662 it->avoid_cursor_p = saved_avoid_cursor;
18663 it->face_id = saved_face_id;
18664 it->start_of_box_run_p = saved_box_start;
18665 }
18666 }
18667 #endif /* HAVE_WINDOW_SYSTEM */
18668 }
18669 else
18670 {
18671 /* Save some values that must not be changed. */
18672 int saved_x = it->current_x;
18673 struct text_pos saved_pos;
18674 Lisp_Object saved_object;
18675 enum display_element_type saved_what = it->what;
18676 int saved_face_id = it->face_id;
18677
18678 saved_object = it->object;
18679 saved_pos = it->position;
18680
18681 it->what = IT_CHARACTER;
18682 memset (&it->position, 0, sizeof it->position);
18683 it->object = make_number (0);
18684 it->c = it->char_to_display = ' ';
18685 it->len = 1;
18686 /* The last row's blank glyphs should get the default face, to
18687 avoid painting the rest of the window with the region face,
18688 if the region ends at ZV. */
18689 if (it->glyph_row->ends_at_zv_p)
18690 it->face_id = default_face->id;
18691 else
18692 it->face_id = face->id;
18693
18694 PRODUCE_GLYPHS (it);
18695
18696 while (it->current_x <= it->last_visible_x)
18697 PRODUCE_GLYPHS (it);
18698
18699 /* Don't count these blanks really. It would let us insert a left
18700 truncation glyph below and make us set the cursor on them, maybe. */
18701 it->current_x = saved_x;
18702 it->object = saved_object;
18703 it->position = saved_pos;
18704 it->what = saved_what;
18705 it->face_id = saved_face_id;
18706 }
18707 }
18708
18709
18710 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18711 trailing whitespace. */
18712
18713 static int
18714 trailing_whitespace_p (ptrdiff_t charpos)
18715 {
18716 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18717 int c = 0;
18718
18719 while (bytepos < ZV_BYTE
18720 && (c = FETCH_CHAR (bytepos),
18721 c == ' ' || c == '\t'))
18722 ++bytepos;
18723
18724 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18725 {
18726 if (bytepos != PT_BYTE)
18727 return 1;
18728 }
18729 return 0;
18730 }
18731
18732
18733 /* Highlight trailing whitespace, if any, in ROW. */
18734
18735 static void
18736 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18737 {
18738 int used = row->used[TEXT_AREA];
18739
18740 if (used)
18741 {
18742 struct glyph *start = row->glyphs[TEXT_AREA];
18743 struct glyph *glyph = start + used - 1;
18744
18745 if (row->reversed_p)
18746 {
18747 /* Right-to-left rows need to be processed in the opposite
18748 direction, so swap the edge pointers. */
18749 glyph = start;
18750 start = row->glyphs[TEXT_AREA] + used - 1;
18751 }
18752
18753 /* Skip over glyphs inserted to display the cursor at the
18754 end of a line, for extending the face of the last glyph
18755 to the end of the line on terminals, and for truncation
18756 and continuation glyphs. */
18757 if (!row->reversed_p)
18758 {
18759 while (glyph >= start
18760 && glyph->type == CHAR_GLYPH
18761 && INTEGERP (glyph->object))
18762 --glyph;
18763 }
18764 else
18765 {
18766 while (glyph <= start
18767 && glyph->type == CHAR_GLYPH
18768 && INTEGERP (glyph->object))
18769 ++glyph;
18770 }
18771
18772 /* If last glyph is a space or stretch, and it's trailing
18773 whitespace, set the face of all trailing whitespace glyphs in
18774 IT->glyph_row to `trailing-whitespace'. */
18775 if ((row->reversed_p ? glyph <= start : glyph >= start)
18776 && BUFFERP (glyph->object)
18777 && (glyph->type == STRETCH_GLYPH
18778 || (glyph->type == CHAR_GLYPH
18779 && glyph->u.ch == ' '))
18780 && trailing_whitespace_p (glyph->charpos))
18781 {
18782 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18783 if (face_id < 0)
18784 return;
18785
18786 if (!row->reversed_p)
18787 {
18788 while (glyph >= start
18789 && BUFFERP (glyph->object)
18790 && (glyph->type == STRETCH_GLYPH
18791 || (glyph->type == CHAR_GLYPH
18792 && glyph->u.ch == ' ')))
18793 (glyph--)->face_id = face_id;
18794 }
18795 else
18796 {
18797 while (glyph <= start
18798 && BUFFERP (glyph->object)
18799 && (glyph->type == STRETCH_GLYPH
18800 || (glyph->type == CHAR_GLYPH
18801 && glyph->u.ch == ' ')))
18802 (glyph++)->face_id = face_id;
18803 }
18804 }
18805 }
18806 }
18807
18808
18809 /* Value is non-zero if glyph row ROW should be
18810 considered to hold the buffer position CHARPOS. */
18811
18812 static int
18813 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18814 {
18815 int result = 1;
18816
18817 if (charpos == CHARPOS (row->end.pos)
18818 || charpos == MATRIX_ROW_END_CHARPOS (row))
18819 {
18820 /* Suppose the row ends on a string.
18821 Unless the row is continued, that means it ends on a newline
18822 in the string. If it's anything other than a display string
18823 (e.g., a before-string from an overlay), we don't want the
18824 cursor there. (This heuristic seems to give the optimal
18825 behavior for the various types of multi-line strings.)
18826 One exception: if the string has `cursor' property on one of
18827 its characters, we _do_ want the cursor there. */
18828 if (CHARPOS (row->end.string_pos) >= 0)
18829 {
18830 if (row->continued_p)
18831 result = 1;
18832 else
18833 {
18834 /* Check for `display' property. */
18835 struct glyph *beg = row->glyphs[TEXT_AREA];
18836 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18837 struct glyph *glyph;
18838
18839 result = 0;
18840 for (glyph = end; glyph >= beg; --glyph)
18841 if (STRINGP (glyph->object))
18842 {
18843 Lisp_Object prop
18844 = Fget_char_property (make_number (charpos),
18845 Qdisplay, Qnil);
18846 result =
18847 (!NILP (prop)
18848 && display_prop_string_p (prop, glyph->object));
18849 /* If there's a `cursor' property on one of the
18850 string's characters, this row is a cursor row,
18851 even though this is not a display string. */
18852 if (!result)
18853 {
18854 Lisp_Object s = glyph->object;
18855
18856 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18857 {
18858 ptrdiff_t gpos = glyph->charpos;
18859
18860 if (!NILP (Fget_char_property (make_number (gpos),
18861 Qcursor, s)))
18862 {
18863 result = 1;
18864 break;
18865 }
18866 }
18867 }
18868 break;
18869 }
18870 }
18871 }
18872 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18873 {
18874 /* If the row ends in middle of a real character,
18875 and the line is continued, we want the cursor here.
18876 That's because CHARPOS (ROW->end.pos) would equal
18877 PT if PT is before the character. */
18878 if (!row->ends_in_ellipsis_p)
18879 result = row->continued_p;
18880 else
18881 /* If the row ends in an ellipsis, then
18882 CHARPOS (ROW->end.pos) will equal point after the
18883 invisible text. We want that position to be displayed
18884 after the ellipsis. */
18885 result = 0;
18886 }
18887 /* If the row ends at ZV, display the cursor at the end of that
18888 row instead of at the start of the row below. */
18889 else if (row->ends_at_zv_p)
18890 result = 1;
18891 else
18892 result = 0;
18893 }
18894
18895 return result;
18896 }
18897
18898 /* Value is non-zero if glyph row ROW should be
18899 used to hold the cursor. */
18900
18901 static int
18902 cursor_row_p (struct glyph_row *row)
18903 {
18904 return row_for_charpos_p (row, PT);
18905 }
18906
18907 \f
18908
18909 /* Push the property PROP so that it will be rendered at the current
18910 position in IT. Return 1 if PROP was successfully pushed, 0
18911 otherwise. Called from handle_line_prefix to handle the
18912 `line-prefix' and `wrap-prefix' properties. */
18913
18914 static int
18915 push_prefix_prop (struct it *it, Lisp_Object prop)
18916 {
18917 struct text_pos pos =
18918 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18919
18920 eassert (it->method == GET_FROM_BUFFER
18921 || it->method == GET_FROM_DISPLAY_VECTOR
18922 || it->method == GET_FROM_STRING);
18923
18924 /* We need to save the current buffer/string position, so it will be
18925 restored by pop_it, because iterate_out_of_display_property
18926 depends on that being set correctly, but some situations leave
18927 it->position not yet set when this function is called. */
18928 push_it (it, &pos);
18929
18930 if (STRINGP (prop))
18931 {
18932 if (SCHARS (prop) == 0)
18933 {
18934 pop_it (it);
18935 return 0;
18936 }
18937
18938 it->string = prop;
18939 it->string_from_prefix_prop_p = 1;
18940 it->multibyte_p = STRING_MULTIBYTE (it->string);
18941 it->current.overlay_string_index = -1;
18942 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18943 it->end_charpos = it->string_nchars = SCHARS (it->string);
18944 it->method = GET_FROM_STRING;
18945 it->stop_charpos = 0;
18946 it->prev_stop = 0;
18947 it->base_level_stop = 0;
18948
18949 /* Force paragraph direction to be that of the parent
18950 buffer/string. */
18951 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18952 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18953 else
18954 it->paragraph_embedding = L2R;
18955
18956 /* Set up the bidi iterator for this display string. */
18957 if (it->bidi_p)
18958 {
18959 it->bidi_it.string.lstring = it->string;
18960 it->bidi_it.string.s = NULL;
18961 it->bidi_it.string.schars = it->end_charpos;
18962 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18963 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18964 it->bidi_it.string.unibyte = !it->multibyte_p;
18965 it->bidi_it.w = it->w;
18966 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18967 }
18968 }
18969 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18970 {
18971 it->method = GET_FROM_STRETCH;
18972 it->object = prop;
18973 }
18974 #ifdef HAVE_WINDOW_SYSTEM
18975 else if (IMAGEP (prop))
18976 {
18977 it->what = IT_IMAGE;
18978 it->image_id = lookup_image (it->f, prop);
18979 it->method = GET_FROM_IMAGE;
18980 }
18981 #endif /* HAVE_WINDOW_SYSTEM */
18982 else
18983 {
18984 pop_it (it); /* bogus display property, give up */
18985 return 0;
18986 }
18987
18988 return 1;
18989 }
18990
18991 /* Return the character-property PROP at the current position in IT. */
18992
18993 static Lisp_Object
18994 get_it_property (struct it *it, Lisp_Object prop)
18995 {
18996 Lisp_Object position, object = it->object;
18997
18998 if (STRINGP (object))
18999 position = make_number (IT_STRING_CHARPOS (*it));
19000 else if (BUFFERP (object))
19001 {
19002 position = make_number (IT_CHARPOS (*it));
19003 object = it->window;
19004 }
19005 else
19006 return Qnil;
19007
19008 return Fget_char_property (position, prop, object);
19009 }
19010
19011 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19012
19013 static void
19014 handle_line_prefix (struct it *it)
19015 {
19016 Lisp_Object prefix;
19017
19018 if (it->continuation_lines_width > 0)
19019 {
19020 prefix = get_it_property (it, Qwrap_prefix);
19021 if (NILP (prefix))
19022 prefix = Vwrap_prefix;
19023 }
19024 else
19025 {
19026 prefix = get_it_property (it, Qline_prefix);
19027 if (NILP (prefix))
19028 prefix = Vline_prefix;
19029 }
19030 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19031 {
19032 /* If the prefix is wider than the window, and we try to wrap
19033 it, it would acquire its own wrap prefix, and so on till the
19034 iterator stack overflows. So, don't wrap the prefix. */
19035 it->line_wrap = TRUNCATE;
19036 it->avoid_cursor_p = 1;
19037 }
19038 }
19039
19040 \f
19041
19042 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19043 only for R2L lines from display_line and display_string, when they
19044 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19045 the line/string needs to be continued on the next glyph row. */
19046 static void
19047 unproduce_glyphs (struct it *it, int n)
19048 {
19049 struct glyph *glyph, *end;
19050
19051 eassert (it->glyph_row);
19052 eassert (it->glyph_row->reversed_p);
19053 eassert (it->area == TEXT_AREA);
19054 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19055
19056 if (n > it->glyph_row->used[TEXT_AREA])
19057 n = it->glyph_row->used[TEXT_AREA];
19058 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19059 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19060 for ( ; glyph < end; glyph++)
19061 glyph[-n] = *glyph;
19062 }
19063
19064 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19065 and ROW->maxpos. */
19066 static void
19067 find_row_edges (struct it *it, struct glyph_row *row,
19068 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19069 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19070 {
19071 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19072 lines' rows is implemented for bidi-reordered rows. */
19073
19074 /* ROW->minpos is the value of min_pos, the minimal buffer position
19075 we have in ROW, or ROW->start.pos if that is smaller. */
19076 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19077 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19078 else
19079 /* We didn't find buffer positions smaller than ROW->start, or
19080 didn't find _any_ valid buffer positions in any of the glyphs,
19081 so we must trust the iterator's computed positions. */
19082 row->minpos = row->start.pos;
19083 if (max_pos <= 0)
19084 {
19085 max_pos = CHARPOS (it->current.pos);
19086 max_bpos = BYTEPOS (it->current.pos);
19087 }
19088
19089 /* Here are the various use-cases for ending the row, and the
19090 corresponding values for ROW->maxpos:
19091
19092 Line ends in a newline from buffer eol_pos + 1
19093 Line is continued from buffer max_pos + 1
19094 Line is truncated on right it->current.pos
19095 Line ends in a newline from string max_pos + 1(*)
19096 (*) + 1 only when line ends in a forward scan
19097 Line is continued from string max_pos
19098 Line is continued from display vector max_pos
19099 Line is entirely from a string min_pos == max_pos
19100 Line is entirely from a display vector min_pos == max_pos
19101 Line that ends at ZV ZV
19102
19103 If you discover other use-cases, please add them here as
19104 appropriate. */
19105 if (row->ends_at_zv_p)
19106 row->maxpos = it->current.pos;
19107 else if (row->used[TEXT_AREA])
19108 {
19109 int seen_this_string = 0;
19110 struct glyph_row *r1 = row - 1;
19111
19112 /* Did we see the same display string on the previous row? */
19113 if (STRINGP (it->object)
19114 /* this is not the first row */
19115 && row > it->w->desired_matrix->rows
19116 /* previous row is not the header line */
19117 && !r1->mode_line_p
19118 /* previous row also ends in a newline from a string */
19119 && r1->ends_in_newline_from_string_p)
19120 {
19121 struct glyph *start, *end;
19122
19123 /* Search for the last glyph of the previous row that came
19124 from buffer or string. Depending on whether the row is
19125 L2R or R2L, we need to process it front to back or the
19126 other way round. */
19127 if (!r1->reversed_p)
19128 {
19129 start = r1->glyphs[TEXT_AREA];
19130 end = start + r1->used[TEXT_AREA];
19131 /* Glyphs inserted by redisplay have an integer (zero)
19132 as their object. */
19133 while (end > start
19134 && INTEGERP ((end - 1)->object)
19135 && (end - 1)->charpos <= 0)
19136 --end;
19137 if (end > start)
19138 {
19139 if (EQ ((end - 1)->object, it->object))
19140 seen_this_string = 1;
19141 }
19142 else
19143 /* If all the glyphs of the previous row were inserted
19144 by redisplay, it means the previous row was
19145 produced from a single newline, which is only
19146 possible if that newline came from the same string
19147 as the one which produced this ROW. */
19148 seen_this_string = 1;
19149 }
19150 else
19151 {
19152 end = r1->glyphs[TEXT_AREA] - 1;
19153 start = end + r1->used[TEXT_AREA];
19154 while (end < start
19155 && INTEGERP ((end + 1)->object)
19156 && (end + 1)->charpos <= 0)
19157 ++end;
19158 if (end < start)
19159 {
19160 if (EQ ((end + 1)->object, it->object))
19161 seen_this_string = 1;
19162 }
19163 else
19164 seen_this_string = 1;
19165 }
19166 }
19167 /* Take note of each display string that covers a newline only
19168 once, the first time we see it. This is for when a display
19169 string includes more than one newline in it. */
19170 if (row->ends_in_newline_from_string_p && !seen_this_string)
19171 {
19172 /* If we were scanning the buffer forward when we displayed
19173 the string, we want to account for at least one buffer
19174 position that belongs to this row (position covered by
19175 the display string), so that cursor positioning will
19176 consider this row as a candidate when point is at the end
19177 of the visual line represented by this row. This is not
19178 required when scanning back, because max_pos will already
19179 have a much larger value. */
19180 if (CHARPOS (row->end.pos) > max_pos)
19181 INC_BOTH (max_pos, max_bpos);
19182 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19183 }
19184 else if (CHARPOS (it->eol_pos) > 0)
19185 SET_TEXT_POS (row->maxpos,
19186 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19187 else if (row->continued_p)
19188 {
19189 /* If max_pos is different from IT's current position, it
19190 means IT->method does not belong to the display element
19191 at max_pos. However, it also means that the display
19192 element at max_pos was displayed in its entirety on this
19193 line, which is equivalent to saying that the next line
19194 starts at the next buffer position. */
19195 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19196 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19197 else
19198 {
19199 INC_BOTH (max_pos, max_bpos);
19200 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19201 }
19202 }
19203 else if (row->truncated_on_right_p)
19204 /* display_line already called reseat_at_next_visible_line_start,
19205 which puts the iterator at the beginning of the next line, in
19206 the logical order. */
19207 row->maxpos = it->current.pos;
19208 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19209 /* A line that is entirely from a string/image/stretch... */
19210 row->maxpos = row->minpos;
19211 else
19212 emacs_abort ();
19213 }
19214 else
19215 row->maxpos = it->current.pos;
19216 }
19217
19218 /* Construct the glyph row IT->glyph_row in the desired matrix of
19219 IT->w from text at the current position of IT. See dispextern.h
19220 for an overview of struct it. Value is non-zero if
19221 IT->glyph_row displays text, as opposed to a line displaying ZV
19222 only. */
19223
19224 static int
19225 display_line (struct it *it)
19226 {
19227 struct glyph_row *row = it->glyph_row;
19228 Lisp_Object overlay_arrow_string;
19229 struct it wrap_it;
19230 void *wrap_data = NULL;
19231 int may_wrap = 0, wrap_x IF_LINT (= 0);
19232 int wrap_row_used = -1;
19233 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19234 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19235 int wrap_row_extra_line_spacing IF_LINT (= 0);
19236 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19237 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19238 int cvpos;
19239 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19240 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19241
19242 /* We always start displaying at hpos zero even if hscrolled. */
19243 eassert (it->hpos == 0 && it->current_x == 0);
19244
19245 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19246 >= it->w->desired_matrix->nrows)
19247 {
19248 it->w->nrows_scale_factor++;
19249 it->f->fonts_changed = 1;
19250 return 0;
19251 }
19252
19253 /* Is IT->w showing the region? */
19254 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19255
19256 /* Clear the result glyph row and enable it. */
19257 prepare_desired_row (row);
19258
19259 row->y = it->current_y;
19260 row->start = it->start;
19261 row->continuation_lines_width = it->continuation_lines_width;
19262 row->displays_text_p = 1;
19263 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19264 it->starts_in_middle_of_char_p = 0;
19265
19266 /* Arrange the overlays nicely for our purposes. Usually, we call
19267 display_line on only one line at a time, in which case this
19268 can't really hurt too much, or we call it on lines which appear
19269 one after another in the buffer, in which case all calls to
19270 recenter_overlay_lists but the first will be pretty cheap. */
19271 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19272
19273 /* Move over display elements that are not visible because we are
19274 hscrolled. This may stop at an x-position < IT->first_visible_x
19275 if the first glyph is partially visible or if we hit a line end. */
19276 if (it->current_x < it->first_visible_x)
19277 {
19278 enum move_it_result move_result;
19279
19280 this_line_min_pos = row->start.pos;
19281 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19282 MOVE_TO_POS | MOVE_TO_X);
19283 /* If we are under a large hscroll, move_it_in_display_line_to
19284 could hit the end of the line without reaching
19285 it->first_visible_x. Pretend that we did reach it. This is
19286 especially important on a TTY, where we will call
19287 extend_face_to_end_of_line, which needs to know how many
19288 blank glyphs to produce. */
19289 if (it->current_x < it->first_visible_x
19290 && (move_result == MOVE_NEWLINE_OR_CR
19291 || move_result == MOVE_POS_MATCH_OR_ZV))
19292 it->current_x = it->first_visible_x;
19293
19294 /* Record the smallest positions seen while we moved over
19295 display elements that are not visible. This is needed by
19296 redisplay_internal for optimizing the case where the cursor
19297 stays inside the same line. The rest of this function only
19298 considers positions that are actually displayed, so
19299 RECORD_MAX_MIN_POS will not otherwise record positions that
19300 are hscrolled to the left of the left edge of the window. */
19301 min_pos = CHARPOS (this_line_min_pos);
19302 min_bpos = BYTEPOS (this_line_min_pos);
19303 }
19304 else
19305 {
19306 /* We only do this when not calling `move_it_in_display_line_to'
19307 above, because move_it_in_display_line_to calls
19308 handle_line_prefix itself. */
19309 handle_line_prefix (it);
19310 }
19311
19312 /* Get the initial row height. This is either the height of the
19313 text hscrolled, if there is any, or zero. */
19314 row->ascent = it->max_ascent;
19315 row->height = it->max_ascent + it->max_descent;
19316 row->phys_ascent = it->max_phys_ascent;
19317 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19318 row->extra_line_spacing = it->max_extra_line_spacing;
19319
19320 /* Utility macro to record max and min buffer positions seen until now. */
19321 #define RECORD_MAX_MIN_POS(IT) \
19322 do \
19323 { \
19324 int composition_p = !STRINGP ((IT)->string) \
19325 && ((IT)->what == IT_COMPOSITION); \
19326 ptrdiff_t current_pos = \
19327 composition_p ? (IT)->cmp_it.charpos \
19328 : IT_CHARPOS (*(IT)); \
19329 ptrdiff_t current_bpos = \
19330 composition_p ? CHAR_TO_BYTE (current_pos) \
19331 : IT_BYTEPOS (*(IT)); \
19332 if (current_pos < min_pos) \
19333 { \
19334 min_pos = current_pos; \
19335 min_bpos = current_bpos; \
19336 } \
19337 if (IT_CHARPOS (*it) > max_pos) \
19338 { \
19339 max_pos = IT_CHARPOS (*it); \
19340 max_bpos = IT_BYTEPOS (*it); \
19341 } \
19342 } \
19343 while (0)
19344
19345 /* Loop generating characters. The loop is left with IT on the next
19346 character to display. */
19347 while (1)
19348 {
19349 int n_glyphs_before, hpos_before, x_before;
19350 int x, nglyphs;
19351 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19352
19353 /* Retrieve the next thing to display. Value is zero if end of
19354 buffer reached. */
19355 if (!get_next_display_element (it))
19356 {
19357 /* Maybe add a space at the end of this line that is used to
19358 display the cursor there under X. Set the charpos of the
19359 first glyph of blank lines not corresponding to any text
19360 to -1. */
19361 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19362 row->exact_window_width_line_p = 1;
19363 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19364 || row->used[TEXT_AREA] == 0)
19365 {
19366 row->glyphs[TEXT_AREA]->charpos = -1;
19367 row->displays_text_p = 0;
19368
19369 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19370 && (!MINI_WINDOW_P (it->w)
19371 || (minibuf_level && EQ (it->window, minibuf_window))))
19372 row->indicate_empty_line_p = 1;
19373 }
19374
19375 it->continuation_lines_width = 0;
19376 row->ends_at_zv_p = 1;
19377 /* A row that displays right-to-left text must always have
19378 its last face extended all the way to the end of line,
19379 even if this row ends in ZV, because we still write to
19380 the screen left to right. We also need to extend the
19381 last face if the default face is remapped to some
19382 different face, otherwise the functions that clear
19383 portions of the screen will clear with the default face's
19384 background color. */
19385 if (row->reversed_p
19386 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19387 extend_face_to_end_of_line (it);
19388 break;
19389 }
19390
19391 /* Now, get the metrics of what we want to display. This also
19392 generates glyphs in `row' (which is IT->glyph_row). */
19393 n_glyphs_before = row->used[TEXT_AREA];
19394 x = it->current_x;
19395
19396 /* Remember the line height so far in case the next element doesn't
19397 fit on the line. */
19398 if (it->line_wrap != TRUNCATE)
19399 {
19400 ascent = it->max_ascent;
19401 descent = it->max_descent;
19402 phys_ascent = it->max_phys_ascent;
19403 phys_descent = it->max_phys_descent;
19404
19405 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19406 {
19407 if (IT_DISPLAYING_WHITESPACE (it))
19408 may_wrap = 1;
19409 else if (may_wrap)
19410 {
19411 SAVE_IT (wrap_it, *it, wrap_data);
19412 wrap_x = x;
19413 wrap_row_used = row->used[TEXT_AREA];
19414 wrap_row_ascent = row->ascent;
19415 wrap_row_height = row->height;
19416 wrap_row_phys_ascent = row->phys_ascent;
19417 wrap_row_phys_height = row->phys_height;
19418 wrap_row_extra_line_spacing = row->extra_line_spacing;
19419 wrap_row_min_pos = min_pos;
19420 wrap_row_min_bpos = min_bpos;
19421 wrap_row_max_pos = max_pos;
19422 wrap_row_max_bpos = max_bpos;
19423 may_wrap = 0;
19424 }
19425 }
19426 }
19427
19428 PRODUCE_GLYPHS (it);
19429
19430 /* If this display element was in marginal areas, continue with
19431 the next one. */
19432 if (it->area != TEXT_AREA)
19433 {
19434 row->ascent = max (row->ascent, it->max_ascent);
19435 row->height = max (row->height, it->max_ascent + it->max_descent);
19436 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19437 row->phys_height = max (row->phys_height,
19438 it->max_phys_ascent + it->max_phys_descent);
19439 row->extra_line_spacing = max (row->extra_line_spacing,
19440 it->max_extra_line_spacing);
19441 set_iterator_to_next (it, 1);
19442 continue;
19443 }
19444
19445 /* Does the display element fit on the line? If we truncate
19446 lines, we should draw past the right edge of the window. If
19447 we don't truncate, we want to stop so that we can display the
19448 continuation glyph before the right margin. If lines are
19449 continued, there are two possible strategies for characters
19450 resulting in more than 1 glyph (e.g. tabs): Display as many
19451 glyphs as possible in this line and leave the rest for the
19452 continuation line, or display the whole element in the next
19453 line. Original redisplay did the former, so we do it also. */
19454 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19455 hpos_before = it->hpos;
19456 x_before = x;
19457
19458 if (/* Not a newline. */
19459 nglyphs > 0
19460 /* Glyphs produced fit entirely in the line. */
19461 && it->current_x < it->last_visible_x)
19462 {
19463 it->hpos += nglyphs;
19464 row->ascent = max (row->ascent, it->max_ascent);
19465 row->height = max (row->height, it->max_ascent + it->max_descent);
19466 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19467 row->phys_height = max (row->phys_height,
19468 it->max_phys_ascent + it->max_phys_descent);
19469 row->extra_line_spacing = max (row->extra_line_spacing,
19470 it->max_extra_line_spacing);
19471 if (it->current_x - it->pixel_width < it->first_visible_x)
19472 row->x = x - it->first_visible_x;
19473 /* Record the maximum and minimum buffer positions seen so
19474 far in glyphs that will be displayed by this row. */
19475 if (it->bidi_p)
19476 RECORD_MAX_MIN_POS (it);
19477 }
19478 else
19479 {
19480 int i, new_x;
19481 struct glyph *glyph;
19482
19483 for (i = 0; i < nglyphs; ++i, x = new_x)
19484 {
19485 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19486 new_x = x + glyph->pixel_width;
19487
19488 if (/* Lines are continued. */
19489 it->line_wrap != TRUNCATE
19490 && (/* Glyph doesn't fit on the line. */
19491 new_x > it->last_visible_x
19492 /* Or it fits exactly on a window system frame. */
19493 || (new_x == it->last_visible_x
19494 && FRAME_WINDOW_P (it->f)
19495 && (row->reversed_p
19496 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19497 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19498 {
19499 /* End of a continued line. */
19500
19501 if (it->hpos == 0
19502 || (new_x == it->last_visible_x
19503 && FRAME_WINDOW_P (it->f)
19504 && (row->reversed_p
19505 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19506 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19507 {
19508 /* Current glyph is the only one on the line or
19509 fits exactly on the line. We must continue
19510 the line because we can't draw the cursor
19511 after the glyph. */
19512 row->continued_p = 1;
19513 it->current_x = new_x;
19514 it->continuation_lines_width += new_x;
19515 ++it->hpos;
19516 if (i == nglyphs - 1)
19517 {
19518 /* If line-wrap is on, check if a previous
19519 wrap point was found. */
19520 if (wrap_row_used > 0
19521 /* Even if there is a previous wrap
19522 point, continue the line here as
19523 usual, if (i) the previous character
19524 was a space or tab AND (ii) the
19525 current character is not. */
19526 && (!may_wrap
19527 || IT_DISPLAYING_WHITESPACE (it)))
19528 goto back_to_wrap;
19529
19530 /* Record the maximum and minimum buffer
19531 positions seen so far in glyphs that will be
19532 displayed by this row. */
19533 if (it->bidi_p)
19534 RECORD_MAX_MIN_POS (it);
19535 set_iterator_to_next (it, 1);
19536 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19537 {
19538 if (!get_next_display_element (it))
19539 {
19540 row->exact_window_width_line_p = 1;
19541 it->continuation_lines_width = 0;
19542 row->continued_p = 0;
19543 row->ends_at_zv_p = 1;
19544 }
19545 else if (ITERATOR_AT_END_OF_LINE_P (it))
19546 {
19547 row->continued_p = 0;
19548 row->exact_window_width_line_p = 1;
19549 }
19550 }
19551 }
19552 else if (it->bidi_p)
19553 RECORD_MAX_MIN_POS (it);
19554 }
19555 else if (CHAR_GLYPH_PADDING_P (*glyph)
19556 && !FRAME_WINDOW_P (it->f))
19557 {
19558 /* A padding glyph that doesn't fit on this line.
19559 This means the whole character doesn't fit
19560 on the line. */
19561 if (row->reversed_p)
19562 unproduce_glyphs (it, row->used[TEXT_AREA]
19563 - n_glyphs_before);
19564 row->used[TEXT_AREA] = n_glyphs_before;
19565
19566 /* Fill the rest of the row with continuation
19567 glyphs like in 20.x. */
19568 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19569 < row->glyphs[1 + TEXT_AREA])
19570 produce_special_glyphs (it, IT_CONTINUATION);
19571
19572 row->continued_p = 1;
19573 it->current_x = x_before;
19574 it->continuation_lines_width += x_before;
19575
19576 /* Restore the height to what it was before the
19577 element not fitting on the line. */
19578 it->max_ascent = ascent;
19579 it->max_descent = descent;
19580 it->max_phys_ascent = phys_ascent;
19581 it->max_phys_descent = phys_descent;
19582 }
19583 else if (wrap_row_used > 0)
19584 {
19585 back_to_wrap:
19586 if (row->reversed_p)
19587 unproduce_glyphs (it,
19588 row->used[TEXT_AREA] - wrap_row_used);
19589 RESTORE_IT (it, &wrap_it, wrap_data);
19590 it->continuation_lines_width += wrap_x;
19591 row->used[TEXT_AREA] = wrap_row_used;
19592 row->ascent = wrap_row_ascent;
19593 row->height = wrap_row_height;
19594 row->phys_ascent = wrap_row_phys_ascent;
19595 row->phys_height = wrap_row_phys_height;
19596 row->extra_line_spacing = wrap_row_extra_line_spacing;
19597 min_pos = wrap_row_min_pos;
19598 min_bpos = wrap_row_min_bpos;
19599 max_pos = wrap_row_max_pos;
19600 max_bpos = wrap_row_max_bpos;
19601 row->continued_p = 1;
19602 row->ends_at_zv_p = 0;
19603 row->exact_window_width_line_p = 0;
19604 it->continuation_lines_width += x;
19605
19606 /* Make sure that a non-default face is extended
19607 up to the right margin of the window. */
19608 extend_face_to_end_of_line (it);
19609 }
19610 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19611 {
19612 /* A TAB that extends past the right edge of the
19613 window. This produces a single glyph on
19614 window system frames. We leave the glyph in
19615 this row and let it fill the row, but don't
19616 consume the TAB. */
19617 if ((row->reversed_p
19618 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19619 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19620 produce_special_glyphs (it, IT_CONTINUATION);
19621 it->continuation_lines_width += it->last_visible_x;
19622 row->ends_in_middle_of_char_p = 1;
19623 row->continued_p = 1;
19624 glyph->pixel_width = it->last_visible_x - x;
19625 it->starts_in_middle_of_char_p = 1;
19626 }
19627 else
19628 {
19629 /* Something other than a TAB that draws past
19630 the right edge of the window. Restore
19631 positions to values before the element. */
19632 if (row->reversed_p)
19633 unproduce_glyphs (it, row->used[TEXT_AREA]
19634 - (n_glyphs_before + i));
19635 row->used[TEXT_AREA] = n_glyphs_before + i;
19636
19637 /* Display continuation glyphs. */
19638 it->current_x = x_before;
19639 it->continuation_lines_width += x;
19640 if (!FRAME_WINDOW_P (it->f)
19641 || (row->reversed_p
19642 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19643 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19644 produce_special_glyphs (it, IT_CONTINUATION);
19645 row->continued_p = 1;
19646
19647 extend_face_to_end_of_line (it);
19648
19649 if (nglyphs > 1 && i > 0)
19650 {
19651 row->ends_in_middle_of_char_p = 1;
19652 it->starts_in_middle_of_char_p = 1;
19653 }
19654
19655 /* Restore the height to what it was before the
19656 element not fitting on the line. */
19657 it->max_ascent = ascent;
19658 it->max_descent = descent;
19659 it->max_phys_ascent = phys_ascent;
19660 it->max_phys_descent = phys_descent;
19661 }
19662
19663 break;
19664 }
19665 else if (new_x > it->first_visible_x)
19666 {
19667 /* Increment number of glyphs actually displayed. */
19668 ++it->hpos;
19669
19670 /* Record the maximum and minimum buffer positions
19671 seen so far in glyphs that will be displayed by
19672 this row. */
19673 if (it->bidi_p)
19674 RECORD_MAX_MIN_POS (it);
19675
19676 if (x < it->first_visible_x)
19677 /* Glyph is partially visible, i.e. row starts at
19678 negative X position. */
19679 row->x = x - it->first_visible_x;
19680 }
19681 else
19682 {
19683 /* Glyph is completely off the left margin of the
19684 window. This should not happen because of the
19685 move_it_in_display_line at the start of this
19686 function, unless the text display area of the
19687 window is empty. */
19688 eassert (it->first_visible_x <= it->last_visible_x);
19689 }
19690 }
19691 /* Even if this display element produced no glyphs at all,
19692 we want to record its position. */
19693 if (it->bidi_p && nglyphs == 0)
19694 RECORD_MAX_MIN_POS (it);
19695
19696 row->ascent = max (row->ascent, it->max_ascent);
19697 row->height = max (row->height, it->max_ascent + it->max_descent);
19698 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19699 row->phys_height = max (row->phys_height,
19700 it->max_phys_ascent + it->max_phys_descent);
19701 row->extra_line_spacing = max (row->extra_line_spacing,
19702 it->max_extra_line_spacing);
19703
19704 /* End of this display line if row is continued. */
19705 if (row->continued_p || row->ends_at_zv_p)
19706 break;
19707 }
19708
19709 at_end_of_line:
19710 /* Is this a line end? If yes, we're also done, after making
19711 sure that a non-default face is extended up to the right
19712 margin of the window. */
19713 if (ITERATOR_AT_END_OF_LINE_P (it))
19714 {
19715 int used_before = row->used[TEXT_AREA];
19716
19717 row->ends_in_newline_from_string_p = STRINGP (it->object);
19718
19719 /* Add a space at the end of the line that is used to
19720 display the cursor there. */
19721 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19722 append_space_for_newline (it, 0);
19723
19724 /* Extend the face to the end of the line. */
19725 extend_face_to_end_of_line (it);
19726
19727 /* Make sure we have the position. */
19728 if (used_before == 0)
19729 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19730
19731 /* Record the position of the newline, for use in
19732 find_row_edges. */
19733 it->eol_pos = it->current.pos;
19734
19735 /* Consume the line end. This skips over invisible lines. */
19736 set_iterator_to_next (it, 1);
19737 it->continuation_lines_width = 0;
19738 break;
19739 }
19740
19741 /* Proceed with next display element. Note that this skips
19742 over lines invisible because of selective display. */
19743 set_iterator_to_next (it, 1);
19744
19745 /* If we truncate lines, we are done when the last displayed
19746 glyphs reach past the right margin of the window. */
19747 if (it->line_wrap == TRUNCATE
19748 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19749 ? (it->current_x >= it->last_visible_x)
19750 : (it->current_x > it->last_visible_x)))
19751 {
19752 /* Maybe add truncation glyphs. */
19753 if (!FRAME_WINDOW_P (it->f)
19754 || (row->reversed_p
19755 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19756 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19757 {
19758 int i, n;
19759
19760 if (!row->reversed_p)
19761 {
19762 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19763 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19764 break;
19765 }
19766 else
19767 {
19768 for (i = 0; i < row->used[TEXT_AREA]; i++)
19769 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19770 break;
19771 /* Remove any padding glyphs at the front of ROW, to
19772 make room for the truncation glyphs we will be
19773 adding below. The loop below always inserts at
19774 least one truncation glyph, so also remove the
19775 last glyph added to ROW. */
19776 unproduce_glyphs (it, i + 1);
19777 /* Adjust i for the loop below. */
19778 i = row->used[TEXT_AREA] - (i + 1);
19779 }
19780
19781 it->current_x = x_before;
19782 if (!FRAME_WINDOW_P (it->f))
19783 {
19784 for (n = row->used[TEXT_AREA]; i < n; ++i)
19785 {
19786 row->used[TEXT_AREA] = i;
19787 produce_special_glyphs (it, IT_TRUNCATION);
19788 }
19789 }
19790 else
19791 {
19792 row->used[TEXT_AREA] = i;
19793 produce_special_glyphs (it, IT_TRUNCATION);
19794 }
19795 }
19796 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19797 {
19798 /* Don't truncate if we can overflow newline into fringe. */
19799 if (!get_next_display_element (it))
19800 {
19801 it->continuation_lines_width = 0;
19802 row->ends_at_zv_p = 1;
19803 row->exact_window_width_line_p = 1;
19804 break;
19805 }
19806 if (ITERATOR_AT_END_OF_LINE_P (it))
19807 {
19808 row->exact_window_width_line_p = 1;
19809 goto at_end_of_line;
19810 }
19811 it->current_x = x_before;
19812 }
19813
19814 row->truncated_on_right_p = 1;
19815 it->continuation_lines_width = 0;
19816 reseat_at_next_visible_line_start (it, 0);
19817 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19818 it->hpos = hpos_before;
19819 break;
19820 }
19821 }
19822
19823 if (wrap_data)
19824 bidi_unshelve_cache (wrap_data, 1);
19825
19826 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19827 at the left window margin. */
19828 if (it->first_visible_x
19829 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19830 {
19831 if (!FRAME_WINDOW_P (it->f)
19832 || (row->reversed_p
19833 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19834 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19835 insert_left_trunc_glyphs (it);
19836 row->truncated_on_left_p = 1;
19837 }
19838
19839 /* Remember the position at which this line ends.
19840
19841 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19842 cannot be before the call to find_row_edges below, since that is
19843 where these positions are determined. */
19844 row->end = it->current;
19845 if (!it->bidi_p)
19846 {
19847 row->minpos = row->start.pos;
19848 row->maxpos = row->end.pos;
19849 }
19850 else
19851 {
19852 /* ROW->minpos and ROW->maxpos must be the smallest and
19853 `1 + the largest' buffer positions in ROW. But if ROW was
19854 bidi-reordered, these two positions can be anywhere in the
19855 row, so we must determine them now. */
19856 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19857 }
19858
19859 /* If the start of this line is the overlay arrow-position, then
19860 mark this glyph row as the one containing the overlay arrow.
19861 This is clearly a mess with variable size fonts. It would be
19862 better to let it be displayed like cursors under X. */
19863 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19864 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19865 !NILP (overlay_arrow_string)))
19866 {
19867 /* Overlay arrow in window redisplay is a fringe bitmap. */
19868 if (STRINGP (overlay_arrow_string))
19869 {
19870 struct glyph_row *arrow_row
19871 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19872 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19873 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19874 struct glyph *p = row->glyphs[TEXT_AREA];
19875 struct glyph *p2, *end;
19876
19877 /* Copy the arrow glyphs. */
19878 while (glyph < arrow_end)
19879 *p++ = *glyph++;
19880
19881 /* Throw away padding glyphs. */
19882 p2 = p;
19883 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19884 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19885 ++p2;
19886 if (p2 > p)
19887 {
19888 while (p2 < end)
19889 *p++ = *p2++;
19890 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19891 }
19892 }
19893 else
19894 {
19895 eassert (INTEGERP (overlay_arrow_string));
19896 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19897 }
19898 overlay_arrow_seen = 1;
19899 }
19900
19901 /* Highlight trailing whitespace. */
19902 if (!NILP (Vshow_trailing_whitespace))
19903 highlight_trailing_whitespace (it->f, it->glyph_row);
19904
19905 /* Compute pixel dimensions of this line. */
19906 compute_line_metrics (it);
19907
19908 /* Implementation note: No changes in the glyphs of ROW or in their
19909 faces can be done past this point, because compute_line_metrics
19910 computes ROW's hash value and stores it within the glyph_row
19911 structure. */
19912
19913 /* Record whether this row ends inside an ellipsis. */
19914 row->ends_in_ellipsis_p
19915 = (it->method == GET_FROM_DISPLAY_VECTOR
19916 && it->ellipsis_p);
19917
19918 /* Save fringe bitmaps in this row. */
19919 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19920 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19921 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19922 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19923
19924 it->left_user_fringe_bitmap = 0;
19925 it->left_user_fringe_face_id = 0;
19926 it->right_user_fringe_bitmap = 0;
19927 it->right_user_fringe_face_id = 0;
19928
19929 /* Maybe set the cursor. */
19930 cvpos = it->w->cursor.vpos;
19931 if ((cvpos < 0
19932 /* In bidi-reordered rows, keep checking for proper cursor
19933 position even if one has been found already, because buffer
19934 positions in such rows change non-linearly with ROW->VPOS,
19935 when a line is continued. One exception: when we are at ZV,
19936 display cursor on the first suitable glyph row, since all
19937 the empty rows after that also have their position set to ZV. */
19938 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19939 lines' rows is implemented for bidi-reordered rows. */
19940 || (it->bidi_p
19941 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19942 && PT >= MATRIX_ROW_START_CHARPOS (row)
19943 && PT <= MATRIX_ROW_END_CHARPOS (row)
19944 && cursor_row_p (row))
19945 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19946
19947 /* Prepare for the next line. This line starts horizontally at (X
19948 HPOS) = (0 0). Vertical positions are incremented. As a
19949 convenience for the caller, IT->glyph_row is set to the next
19950 row to be used. */
19951 it->current_x = it->hpos = 0;
19952 it->current_y += row->height;
19953 SET_TEXT_POS (it->eol_pos, 0, 0);
19954 ++it->vpos;
19955 ++it->glyph_row;
19956 /* The next row should by default use the same value of the
19957 reversed_p flag as this one. set_iterator_to_next decides when
19958 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19959 the flag accordingly. */
19960 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19961 it->glyph_row->reversed_p = row->reversed_p;
19962 it->start = row->end;
19963 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
19964
19965 #undef RECORD_MAX_MIN_POS
19966 }
19967
19968 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19969 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19970 doc: /* Return paragraph direction at point in BUFFER.
19971 Value is either `left-to-right' or `right-to-left'.
19972 If BUFFER is omitted or nil, it defaults to the current buffer.
19973
19974 Paragraph direction determines how the text in the paragraph is displayed.
19975 In left-to-right paragraphs, text begins at the left margin of the window
19976 and the reading direction is generally left to right. In right-to-left
19977 paragraphs, text begins at the right margin and is read from right to left.
19978
19979 See also `bidi-paragraph-direction'. */)
19980 (Lisp_Object buffer)
19981 {
19982 struct buffer *buf = current_buffer;
19983 struct buffer *old = buf;
19984
19985 if (! NILP (buffer))
19986 {
19987 CHECK_BUFFER (buffer);
19988 buf = XBUFFER (buffer);
19989 }
19990
19991 if (NILP (BVAR (buf, bidi_display_reordering))
19992 || NILP (BVAR (buf, enable_multibyte_characters))
19993 /* When we are loading loadup.el, the character property tables
19994 needed for bidi iteration are not yet available. */
19995 || !NILP (Vpurify_flag))
19996 return Qleft_to_right;
19997 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19998 return BVAR (buf, bidi_paragraph_direction);
19999 else
20000 {
20001 /* Determine the direction from buffer text. We could try to
20002 use current_matrix if it is up to date, but this seems fast
20003 enough as it is. */
20004 struct bidi_it itb;
20005 ptrdiff_t pos = BUF_PT (buf);
20006 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20007 int c;
20008 void *itb_data = bidi_shelve_cache ();
20009
20010 set_buffer_temp (buf);
20011 /* bidi_paragraph_init finds the base direction of the paragraph
20012 by searching forward from paragraph start. We need the base
20013 direction of the current or _previous_ paragraph, so we need
20014 to make sure we are within that paragraph. To that end, find
20015 the previous non-empty line. */
20016 if (pos >= ZV && pos > BEGV)
20017 DEC_BOTH (pos, bytepos);
20018 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20019 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20020 {
20021 while ((c = FETCH_BYTE (bytepos)) == '\n'
20022 || c == ' ' || c == '\t' || c == '\f')
20023 {
20024 if (bytepos <= BEGV_BYTE)
20025 break;
20026 bytepos--;
20027 pos--;
20028 }
20029 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20030 bytepos--;
20031 }
20032 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20033 itb.paragraph_dir = NEUTRAL_DIR;
20034 itb.string.s = NULL;
20035 itb.string.lstring = Qnil;
20036 itb.string.bufpos = 0;
20037 itb.string.unibyte = 0;
20038 /* We have no window to use here for ignoring window-specific
20039 overlays. Using NULL for window pointer will cause
20040 compute_display_string_pos to use the current buffer. */
20041 itb.w = NULL;
20042 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20043 bidi_unshelve_cache (itb_data, 0);
20044 set_buffer_temp (old);
20045 switch (itb.paragraph_dir)
20046 {
20047 case L2R:
20048 return Qleft_to_right;
20049 break;
20050 case R2L:
20051 return Qright_to_left;
20052 break;
20053 default:
20054 emacs_abort ();
20055 }
20056 }
20057 }
20058
20059 DEFUN ("move-point-visually", Fmove_point_visually,
20060 Smove_point_visually, 1, 1, 0,
20061 doc: /* Move point in the visual order in the specified DIRECTION.
20062 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20063 left.
20064
20065 Value is the new character position of point. */)
20066 (Lisp_Object direction)
20067 {
20068 struct window *w = XWINDOW (selected_window);
20069 struct buffer *b = XBUFFER (w->contents);
20070 struct glyph_row *row;
20071 int dir;
20072 Lisp_Object paragraph_dir;
20073
20074 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20075 (!(ROW)->continued_p \
20076 && INTEGERP ((GLYPH)->object) \
20077 && (GLYPH)->type == CHAR_GLYPH \
20078 && (GLYPH)->u.ch == ' ' \
20079 && (GLYPH)->charpos >= 0 \
20080 && !(GLYPH)->avoid_cursor_p)
20081
20082 CHECK_NUMBER (direction);
20083 dir = XINT (direction);
20084 if (dir > 0)
20085 dir = 1;
20086 else
20087 dir = -1;
20088
20089 /* If current matrix is up-to-date, we can use the information
20090 recorded in the glyphs, at least as long as the goal is on the
20091 screen. */
20092 if (w->window_end_valid
20093 && !windows_or_buffers_changed
20094 && b
20095 && !b->clip_changed
20096 && !b->prevent_redisplay_optimizations_p
20097 && !window_outdated (w)
20098 && w->cursor.vpos >= 0
20099 && w->cursor.vpos < w->current_matrix->nrows
20100 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20101 {
20102 struct glyph *g = row->glyphs[TEXT_AREA];
20103 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20104 struct glyph *gpt = g + w->cursor.hpos;
20105
20106 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20107 {
20108 if (BUFFERP (g->object) && g->charpos != PT)
20109 {
20110 SET_PT (g->charpos);
20111 w->cursor.vpos = -1;
20112 return make_number (PT);
20113 }
20114 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20115 {
20116 ptrdiff_t new_pos;
20117
20118 if (BUFFERP (gpt->object))
20119 {
20120 new_pos = PT;
20121 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20122 new_pos += (row->reversed_p ? -dir : dir);
20123 else
20124 new_pos -= (row->reversed_p ? -dir : dir);;
20125 }
20126 else if (BUFFERP (g->object))
20127 new_pos = g->charpos;
20128 else
20129 break;
20130 SET_PT (new_pos);
20131 w->cursor.vpos = -1;
20132 return make_number (PT);
20133 }
20134 else if (ROW_GLYPH_NEWLINE_P (row, g))
20135 {
20136 /* Glyphs inserted at the end of a non-empty line for
20137 positioning the cursor have zero charpos, so we must
20138 deduce the value of point by other means. */
20139 if (g->charpos > 0)
20140 SET_PT (g->charpos);
20141 else if (row->ends_at_zv_p && PT != ZV)
20142 SET_PT (ZV);
20143 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20144 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20145 else
20146 break;
20147 w->cursor.vpos = -1;
20148 return make_number (PT);
20149 }
20150 }
20151 if (g == e || INTEGERP (g->object))
20152 {
20153 if (row->truncated_on_left_p || row->truncated_on_right_p)
20154 goto simulate_display;
20155 if (!row->reversed_p)
20156 row += dir;
20157 else
20158 row -= dir;
20159 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20160 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20161 goto simulate_display;
20162
20163 if (dir > 0)
20164 {
20165 if (row->reversed_p && !row->continued_p)
20166 {
20167 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20168 w->cursor.vpos = -1;
20169 return make_number (PT);
20170 }
20171 g = row->glyphs[TEXT_AREA];
20172 e = g + row->used[TEXT_AREA];
20173 for ( ; g < e; g++)
20174 {
20175 if (BUFFERP (g->object)
20176 /* Empty lines have only one glyph, which stands
20177 for the newline, and whose charpos is the
20178 buffer position of the newline. */
20179 || ROW_GLYPH_NEWLINE_P (row, g)
20180 /* When the buffer ends in a newline, the line at
20181 EOB also has one glyph, but its charpos is -1. */
20182 || (row->ends_at_zv_p
20183 && !row->reversed_p
20184 && INTEGERP (g->object)
20185 && g->type == CHAR_GLYPH
20186 && g->u.ch == ' '))
20187 {
20188 if (g->charpos > 0)
20189 SET_PT (g->charpos);
20190 else if (!row->reversed_p
20191 && row->ends_at_zv_p
20192 && PT != ZV)
20193 SET_PT (ZV);
20194 else
20195 continue;
20196 w->cursor.vpos = -1;
20197 return make_number (PT);
20198 }
20199 }
20200 }
20201 else
20202 {
20203 if (!row->reversed_p && !row->continued_p)
20204 {
20205 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20206 w->cursor.vpos = -1;
20207 return make_number (PT);
20208 }
20209 e = row->glyphs[TEXT_AREA];
20210 g = e + row->used[TEXT_AREA] - 1;
20211 for ( ; g >= e; g--)
20212 {
20213 if (BUFFERP (g->object)
20214 || (ROW_GLYPH_NEWLINE_P (row, g)
20215 && g->charpos > 0)
20216 /* Empty R2L lines on GUI frames have the buffer
20217 position of the newline stored in the stretch
20218 glyph. */
20219 || g->type == STRETCH_GLYPH
20220 || (row->ends_at_zv_p
20221 && row->reversed_p
20222 && INTEGERP (g->object)
20223 && g->type == CHAR_GLYPH
20224 && g->u.ch == ' '))
20225 {
20226 if (g->charpos > 0)
20227 SET_PT (g->charpos);
20228 else if (row->reversed_p
20229 && row->ends_at_zv_p
20230 && PT != ZV)
20231 SET_PT (ZV);
20232 else
20233 continue;
20234 w->cursor.vpos = -1;
20235 return make_number (PT);
20236 }
20237 }
20238 }
20239 }
20240 }
20241
20242 simulate_display:
20243
20244 /* If we wind up here, we failed to move by using the glyphs, so we
20245 need to simulate display instead. */
20246
20247 if (b)
20248 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
20249 else
20250 paragraph_dir = Qleft_to_right;
20251 if (EQ (paragraph_dir, Qright_to_left))
20252 dir = -dir;
20253 if (PT <= BEGV && dir < 0)
20254 xsignal0 (Qbeginning_of_buffer);
20255 else if (PT >= ZV && dir > 0)
20256 xsignal0 (Qend_of_buffer);
20257 else
20258 {
20259 struct text_pos pt;
20260 struct it it;
20261 int pt_x, target_x, pixel_width, pt_vpos;
20262 bool at_eol_p;
20263 bool overshoot_expected = false;
20264 bool target_is_eol_p = false;
20265
20266 /* Setup the arena. */
20267 SET_TEXT_POS (pt, PT, PT_BYTE);
20268 start_display (&it, w, pt);
20269
20270 if (it.cmp_it.id < 0
20271 && it.method == GET_FROM_STRING
20272 && it.area == TEXT_AREA
20273 && it.string_from_display_prop_p
20274 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
20275 overshoot_expected = true;
20276
20277 /* Find the X coordinate of point. We start from the beginning
20278 of this or previous line to make sure we are before point in
20279 the logical order (since the move_it_* functions can only
20280 move forward). */
20281 reseat_at_previous_visible_line_start (&it);
20282 it.current_x = it.hpos = it.current_y = it.vpos = 0;
20283 if (IT_CHARPOS (it) != PT)
20284 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
20285 -1, -1, -1, MOVE_TO_POS);
20286 pt_x = it.current_x;
20287 pt_vpos = it.vpos;
20288 if (dir > 0 || overshoot_expected)
20289 {
20290 struct glyph_row *row = it.glyph_row;
20291
20292 /* When point is at beginning of line, we don't have
20293 information about the glyph there loaded into struct
20294 it. Calling get_next_display_element fixes that. */
20295 if (pt_x == 0)
20296 get_next_display_element (&it);
20297 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20298 it.glyph_row = NULL;
20299 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
20300 it.glyph_row = row;
20301 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20302 it, lest it will become out of sync with it's buffer
20303 position. */
20304 it.current_x = pt_x;
20305 }
20306 else
20307 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20308 pixel_width = it.pixel_width;
20309 if (overshoot_expected && at_eol_p)
20310 pixel_width = 0;
20311 else if (pixel_width <= 0)
20312 pixel_width = 1;
20313
20314 /* If there's a display string at point, we are actually at the
20315 glyph to the left of point, so we need to correct the X
20316 coordinate. */
20317 if (overshoot_expected)
20318 pt_x += pixel_width;
20319
20320 /* Compute target X coordinate, either to the left or to the
20321 right of point. On TTY frames, all characters have the same
20322 pixel width of 1, so we can use that. On GUI frames we don't
20323 have an easy way of getting at the pixel width of the
20324 character to the left of point, so we use a different method
20325 of getting to that place. */
20326 if (dir > 0)
20327 target_x = pt_x + pixel_width;
20328 else
20329 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
20330
20331 /* Target X coordinate could be one line above or below the line
20332 of point, in which case we need to adjust the target X
20333 coordinate. Also, if moving to the left, we need to begin at
20334 the left edge of the point's screen line. */
20335 if (dir < 0)
20336 {
20337 if (pt_x > 0)
20338 {
20339 start_display (&it, w, pt);
20340 reseat_at_previous_visible_line_start (&it);
20341 it.current_x = it.current_y = it.hpos = 0;
20342 if (pt_vpos != 0)
20343 move_it_by_lines (&it, pt_vpos);
20344 }
20345 else
20346 {
20347 move_it_by_lines (&it, -1);
20348 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
20349 target_is_eol_p = true;
20350 }
20351 }
20352 else
20353 {
20354 if (at_eol_p
20355 || (target_x >= it.last_visible_x
20356 && it.line_wrap != TRUNCATE))
20357 {
20358 if (pt_x > 0)
20359 move_it_by_lines (&it, 0);
20360 move_it_by_lines (&it, 1);
20361 target_x = 0;
20362 }
20363 }
20364
20365 /* Move to the target X coordinate. */
20366 #ifdef HAVE_WINDOW_SYSTEM
20367 /* On GUI frames, as we don't know the X coordinate of the
20368 character to the left of point, moving point to the left
20369 requires walking, one grapheme cluster at a time, until we
20370 find ourself at a place immediately to the left of the
20371 character at point. */
20372 if (FRAME_WINDOW_P (it.f) && dir < 0)
20373 {
20374 struct text_pos new_pos = it.current.pos;
20375 enum move_it_result rc = MOVE_X_REACHED;
20376
20377 while (it.current_x + it.pixel_width <= target_x
20378 && rc == MOVE_X_REACHED)
20379 {
20380 int new_x = it.current_x + it.pixel_width;
20381
20382 new_pos = it.current.pos;
20383 if (new_x == it.current_x)
20384 new_x++;
20385 rc = move_it_in_display_line_to (&it, ZV, new_x,
20386 MOVE_TO_POS | MOVE_TO_X);
20387 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
20388 break;
20389 }
20390 /* If we ended up on a composed character inside
20391 bidi-reordered text (e.g., Hebrew text with diacritics),
20392 the iterator gives us the buffer position of the last (in
20393 logical order) character of the composed grapheme cluster,
20394 which is not what we want. So we cheat: we compute the
20395 character position of the character that follows (in the
20396 logical order) the one where the above loop stopped. That
20397 character will appear on display to the left of point. */
20398 if (it.bidi_p
20399 && it.bidi_it.scan_dir == -1
20400 && new_pos.charpos - IT_CHARPOS (it) > 1)
20401 {
20402 new_pos.charpos = IT_CHARPOS (it) + 1;
20403 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
20404 }
20405 it.current.pos = new_pos;
20406 }
20407 else
20408 #endif
20409 if (it.current_x != target_x)
20410 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
20411
20412 /* When lines are truncated, the above loop will stop at the
20413 window edge. But we want to get to the end of line, even if
20414 it is beyond the window edge; automatic hscroll will then
20415 scroll the window to show point as appropriate. */
20416 if (target_is_eol_p && it.line_wrap == TRUNCATE
20417 && get_next_display_element (&it))
20418 {
20419 struct text_pos new_pos = it.current.pos;
20420
20421 while (!ITERATOR_AT_END_OF_LINE_P (&it))
20422 {
20423 set_iterator_to_next (&it, 0);
20424 if (it.method == GET_FROM_BUFFER)
20425 new_pos = it.current.pos;
20426 if (!get_next_display_element (&it))
20427 break;
20428 }
20429
20430 it.current.pos = new_pos;
20431 }
20432
20433 /* If we ended up in a display string that covers point, move to
20434 buffer position to the right in the visual order. */
20435 if (dir > 0)
20436 {
20437 while (IT_CHARPOS (it) == PT)
20438 {
20439 set_iterator_to_next (&it, 0);
20440 if (!get_next_display_element (&it))
20441 break;
20442 }
20443 }
20444
20445 /* Move point to that position. */
20446 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
20447 }
20448
20449 return make_number (PT);
20450
20451 #undef ROW_GLYPH_NEWLINE_P
20452 }
20453
20454 \f
20455 /***********************************************************************
20456 Menu Bar
20457 ***********************************************************************/
20458
20459 /* Redisplay the menu bar in the frame for window W.
20460
20461 The menu bar of X frames that don't have X toolkit support is
20462 displayed in a special window W->frame->menu_bar_window.
20463
20464 The menu bar of terminal frames is treated specially as far as
20465 glyph matrices are concerned. Menu bar lines are not part of
20466 windows, so the update is done directly on the frame matrix rows
20467 for the menu bar. */
20468
20469 static void
20470 display_menu_bar (struct window *w)
20471 {
20472 struct frame *f = XFRAME (WINDOW_FRAME (w));
20473 struct it it;
20474 Lisp_Object items;
20475 int i;
20476
20477 /* Don't do all this for graphical frames. */
20478 #ifdef HAVE_NTGUI
20479 if (FRAME_W32_P (f))
20480 return;
20481 #endif
20482 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20483 if (FRAME_X_P (f))
20484 return;
20485 #endif
20486
20487 #ifdef HAVE_NS
20488 if (FRAME_NS_P (f))
20489 return;
20490 #endif /* HAVE_NS */
20491
20492 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20493 eassert (!FRAME_WINDOW_P (f));
20494 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20495 it.first_visible_x = 0;
20496 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20497 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20498 if (FRAME_WINDOW_P (f))
20499 {
20500 /* Menu bar lines are displayed in the desired matrix of the
20501 dummy window menu_bar_window. */
20502 struct window *menu_w;
20503 menu_w = XWINDOW (f->menu_bar_window);
20504 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20505 MENU_FACE_ID);
20506 it.first_visible_x = 0;
20507 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20508 }
20509 else
20510 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20511 {
20512 /* This is a TTY frame, i.e. character hpos/vpos are used as
20513 pixel x/y. */
20514 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20515 MENU_FACE_ID);
20516 it.first_visible_x = 0;
20517 it.last_visible_x = FRAME_COLS (f);
20518 }
20519
20520 /* FIXME: This should be controlled by a user option. See the
20521 comments in redisplay_tool_bar and display_mode_line about
20522 this. */
20523 it.paragraph_embedding = L2R;
20524
20525 /* Clear all rows of the menu bar. */
20526 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20527 {
20528 struct glyph_row *row = it.glyph_row + i;
20529 clear_glyph_row (row);
20530 row->enabled_p = 1;
20531 row->full_width_p = 1;
20532 }
20533
20534 /* Display all items of the menu bar. */
20535 items = FRAME_MENU_BAR_ITEMS (it.f);
20536 for (i = 0; i < ASIZE (items); i += 4)
20537 {
20538 Lisp_Object string;
20539
20540 /* Stop at nil string. */
20541 string = AREF (items, i + 1);
20542 if (NILP (string))
20543 break;
20544
20545 /* Remember where item was displayed. */
20546 ASET (items, i + 3, make_number (it.hpos));
20547
20548 /* Display the item, pad with one space. */
20549 if (it.current_x < it.last_visible_x)
20550 display_string (NULL, string, Qnil, 0, 0, &it,
20551 SCHARS (string) + 1, 0, 0, -1);
20552 }
20553
20554 /* Fill out the line with spaces. */
20555 if (it.current_x < it.last_visible_x)
20556 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20557
20558 /* Compute the total height of the lines. */
20559 compute_line_metrics (&it);
20560 }
20561
20562
20563 \f
20564 /***********************************************************************
20565 Mode Line
20566 ***********************************************************************/
20567
20568 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20569 FORCE is non-zero, redisplay mode lines unconditionally.
20570 Otherwise, redisplay only mode lines that are garbaged. Value is
20571 the number of windows whose mode lines were redisplayed. */
20572
20573 static int
20574 redisplay_mode_lines (Lisp_Object window, int force)
20575 {
20576 int nwindows = 0;
20577
20578 while (!NILP (window))
20579 {
20580 struct window *w = XWINDOW (window);
20581
20582 if (WINDOWP (w->contents))
20583 nwindows += redisplay_mode_lines (w->contents, force);
20584 else if (force
20585 || FRAME_GARBAGED_P (XFRAME (w->frame))
20586 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20587 {
20588 struct text_pos lpoint;
20589 struct buffer *old = current_buffer;
20590
20591 /* Set the window's buffer for the mode line display. */
20592 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20593 set_buffer_internal_1 (XBUFFER (w->contents));
20594
20595 /* Point refers normally to the selected window. For any
20596 other window, set up appropriate value. */
20597 if (!EQ (window, selected_window))
20598 {
20599 struct text_pos pt;
20600
20601 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
20602 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20603 }
20604
20605 /* Display mode lines. */
20606 clear_glyph_matrix (w->desired_matrix);
20607 if (display_mode_lines (w))
20608 {
20609 ++nwindows;
20610 w->must_be_updated_p = 1;
20611 }
20612
20613 /* Restore old settings. */
20614 set_buffer_internal_1 (old);
20615 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20616 }
20617
20618 window = w->next;
20619 }
20620
20621 return nwindows;
20622 }
20623
20624
20625 /* Display the mode and/or header line of window W. Value is the
20626 sum number of mode lines and header lines displayed. */
20627
20628 static int
20629 display_mode_lines (struct window *w)
20630 {
20631 Lisp_Object old_selected_window = selected_window;
20632 Lisp_Object old_selected_frame = selected_frame;
20633 Lisp_Object new_frame = w->frame;
20634 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20635 int n = 0;
20636
20637 selected_frame = new_frame;
20638 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20639 or window's point, then we'd need select_window_1 here as well. */
20640 XSETWINDOW (selected_window, w);
20641 XFRAME (new_frame)->selected_window = selected_window;
20642
20643 /* These will be set while the mode line specs are processed. */
20644 line_number_displayed = 0;
20645 w->column_number_displayed = -1;
20646
20647 if (WINDOW_WANTS_MODELINE_P (w))
20648 {
20649 struct window *sel_w = XWINDOW (old_selected_window);
20650
20651 /* Select mode line face based on the real selected window. */
20652 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20653 BVAR (current_buffer, mode_line_format));
20654 ++n;
20655 }
20656
20657 if (WINDOW_WANTS_HEADER_LINE_P (w))
20658 {
20659 display_mode_line (w, HEADER_LINE_FACE_ID,
20660 BVAR (current_buffer, header_line_format));
20661 ++n;
20662 }
20663
20664 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20665 selected_frame = old_selected_frame;
20666 selected_window = old_selected_window;
20667 return n;
20668 }
20669
20670
20671 /* Display mode or header line of window W. FACE_ID specifies which
20672 line to display; it is either MODE_LINE_FACE_ID or
20673 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20674 display. Value is the pixel height of the mode/header line
20675 displayed. */
20676
20677 static int
20678 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20679 {
20680 struct it it;
20681 struct face *face;
20682 ptrdiff_t count = SPECPDL_INDEX ();
20683
20684 init_iterator (&it, w, -1, -1, NULL, face_id);
20685 /* Don't extend on a previously drawn mode-line.
20686 This may happen if called from pos_visible_p. */
20687 it.glyph_row->enabled_p = 0;
20688 prepare_desired_row (it.glyph_row);
20689
20690 it.glyph_row->mode_line_p = 1;
20691
20692 /* FIXME: This should be controlled by a user option. But
20693 supporting such an option is not trivial, since the mode line is
20694 made up of many separate strings. */
20695 it.paragraph_embedding = L2R;
20696
20697 record_unwind_protect (unwind_format_mode_line,
20698 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20699
20700 mode_line_target = MODE_LINE_DISPLAY;
20701
20702 /* Temporarily make frame's keyboard the current kboard so that
20703 kboard-local variables in the mode_line_format will get the right
20704 values. */
20705 push_kboard (FRAME_KBOARD (it.f));
20706 record_unwind_save_match_data ();
20707 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20708 pop_kboard ();
20709
20710 unbind_to (count, Qnil);
20711
20712 /* Fill up with spaces. */
20713 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20714
20715 compute_line_metrics (&it);
20716 it.glyph_row->full_width_p = 1;
20717 it.glyph_row->continued_p = 0;
20718 it.glyph_row->truncated_on_left_p = 0;
20719 it.glyph_row->truncated_on_right_p = 0;
20720
20721 /* Make a 3D mode-line have a shadow at its right end. */
20722 face = FACE_FROM_ID (it.f, face_id);
20723 extend_face_to_end_of_line (&it);
20724 if (face->box != FACE_NO_BOX)
20725 {
20726 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20727 + it.glyph_row->used[TEXT_AREA] - 1);
20728 last->right_box_line_p = 1;
20729 }
20730
20731 return it.glyph_row->height;
20732 }
20733
20734 /* Move element ELT in LIST to the front of LIST.
20735 Return the updated list. */
20736
20737 static Lisp_Object
20738 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20739 {
20740 register Lisp_Object tail, prev;
20741 register Lisp_Object tem;
20742
20743 tail = list;
20744 prev = Qnil;
20745 while (CONSP (tail))
20746 {
20747 tem = XCAR (tail);
20748
20749 if (EQ (elt, tem))
20750 {
20751 /* Splice out the link TAIL. */
20752 if (NILP (prev))
20753 list = XCDR (tail);
20754 else
20755 Fsetcdr (prev, XCDR (tail));
20756
20757 /* Now make it the first. */
20758 Fsetcdr (tail, list);
20759 return tail;
20760 }
20761 else
20762 prev = tail;
20763 tail = XCDR (tail);
20764 QUIT;
20765 }
20766
20767 /* Not found--return unchanged LIST. */
20768 return list;
20769 }
20770
20771 /* Contribute ELT to the mode line for window IT->w. How it
20772 translates into text depends on its data type.
20773
20774 IT describes the display environment in which we display, as usual.
20775
20776 DEPTH is the depth in recursion. It is used to prevent
20777 infinite recursion here.
20778
20779 FIELD_WIDTH is the number of characters the display of ELT should
20780 occupy in the mode line, and PRECISION is the maximum number of
20781 characters to display from ELT's representation. See
20782 display_string for details.
20783
20784 Returns the hpos of the end of the text generated by ELT.
20785
20786 PROPS is a property list to add to any string we encounter.
20787
20788 If RISKY is nonzero, remove (disregard) any properties in any string
20789 we encounter, and ignore :eval and :propertize.
20790
20791 The global variable `mode_line_target' determines whether the
20792 output is passed to `store_mode_line_noprop',
20793 `store_mode_line_string', or `display_string'. */
20794
20795 static int
20796 display_mode_element (struct it *it, int depth, int field_width, int precision,
20797 Lisp_Object elt, Lisp_Object props, int risky)
20798 {
20799 int n = 0, field, prec;
20800 int literal = 0;
20801
20802 tail_recurse:
20803 if (depth > 100)
20804 elt = build_string ("*too-deep*");
20805
20806 depth++;
20807
20808 switch (XTYPE (elt))
20809 {
20810 case Lisp_String:
20811 {
20812 /* A string: output it and check for %-constructs within it. */
20813 unsigned char c;
20814 ptrdiff_t offset = 0;
20815
20816 if (SCHARS (elt) > 0
20817 && (!NILP (props) || risky))
20818 {
20819 Lisp_Object oprops, aelt;
20820 oprops = Ftext_properties_at (make_number (0), elt);
20821
20822 /* If the starting string's properties are not what
20823 we want, translate the string. Also, if the string
20824 is risky, do that anyway. */
20825
20826 if (NILP (Fequal (props, oprops)) || risky)
20827 {
20828 /* If the starting string has properties,
20829 merge the specified ones onto the existing ones. */
20830 if (! NILP (oprops) && !risky)
20831 {
20832 Lisp_Object tem;
20833
20834 oprops = Fcopy_sequence (oprops);
20835 tem = props;
20836 while (CONSP (tem))
20837 {
20838 oprops = Fplist_put (oprops, XCAR (tem),
20839 XCAR (XCDR (tem)));
20840 tem = XCDR (XCDR (tem));
20841 }
20842 props = oprops;
20843 }
20844
20845 aelt = Fassoc (elt, mode_line_proptrans_alist);
20846 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20847 {
20848 /* AELT is what we want. Move it to the front
20849 without consing. */
20850 elt = XCAR (aelt);
20851 mode_line_proptrans_alist
20852 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20853 }
20854 else
20855 {
20856 Lisp_Object tem;
20857
20858 /* If AELT has the wrong props, it is useless.
20859 so get rid of it. */
20860 if (! NILP (aelt))
20861 mode_line_proptrans_alist
20862 = Fdelq (aelt, mode_line_proptrans_alist);
20863
20864 elt = Fcopy_sequence (elt);
20865 Fset_text_properties (make_number (0), Flength (elt),
20866 props, elt);
20867 /* Add this item to mode_line_proptrans_alist. */
20868 mode_line_proptrans_alist
20869 = Fcons (Fcons (elt, props),
20870 mode_line_proptrans_alist);
20871 /* Truncate mode_line_proptrans_alist
20872 to at most 50 elements. */
20873 tem = Fnthcdr (make_number (50),
20874 mode_line_proptrans_alist);
20875 if (! NILP (tem))
20876 XSETCDR (tem, Qnil);
20877 }
20878 }
20879 }
20880
20881 offset = 0;
20882
20883 if (literal)
20884 {
20885 prec = precision - n;
20886 switch (mode_line_target)
20887 {
20888 case MODE_LINE_NOPROP:
20889 case MODE_LINE_TITLE:
20890 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20891 break;
20892 case MODE_LINE_STRING:
20893 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20894 break;
20895 case MODE_LINE_DISPLAY:
20896 n += display_string (NULL, elt, Qnil, 0, 0, it,
20897 0, prec, 0, STRING_MULTIBYTE (elt));
20898 break;
20899 }
20900
20901 break;
20902 }
20903
20904 /* Handle the non-literal case. */
20905
20906 while ((precision <= 0 || n < precision)
20907 && SREF (elt, offset) != 0
20908 && (mode_line_target != MODE_LINE_DISPLAY
20909 || it->current_x < it->last_visible_x))
20910 {
20911 ptrdiff_t last_offset = offset;
20912
20913 /* Advance to end of string or next format specifier. */
20914 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20915 ;
20916
20917 if (offset - 1 != last_offset)
20918 {
20919 ptrdiff_t nchars, nbytes;
20920
20921 /* Output to end of string or up to '%'. Field width
20922 is length of string. Don't output more than
20923 PRECISION allows us. */
20924 offset--;
20925
20926 prec = c_string_width (SDATA (elt) + last_offset,
20927 offset - last_offset, precision - n,
20928 &nchars, &nbytes);
20929
20930 switch (mode_line_target)
20931 {
20932 case MODE_LINE_NOPROP:
20933 case MODE_LINE_TITLE:
20934 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20935 break;
20936 case MODE_LINE_STRING:
20937 {
20938 ptrdiff_t bytepos = last_offset;
20939 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20940 ptrdiff_t endpos = (precision <= 0
20941 ? string_byte_to_char (elt, offset)
20942 : charpos + nchars);
20943
20944 n += store_mode_line_string (NULL,
20945 Fsubstring (elt, make_number (charpos),
20946 make_number (endpos)),
20947 0, 0, 0, Qnil);
20948 }
20949 break;
20950 case MODE_LINE_DISPLAY:
20951 {
20952 ptrdiff_t bytepos = last_offset;
20953 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20954
20955 if (precision <= 0)
20956 nchars = string_byte_to_char (elt, offset) - charpos;
20957 n += display_string (NULL, elt, Qnil, 0, charpos,
20958 it, 0, nchars, 0,
20959 STRING_MULTIBYTE (elt));
20960 }
20961 break;
20962 }
20963 }
20964 else /* c == '%' */
20965 {
20966 ptrdiff_t percent_position = offset;
20967
20968 /* Get the specified minimum width. Zero means
20969 don't pad. */
20970 field = 0;
20971 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20972 field = field * 10 + c - '0';
20973
20974 /* Don't pad beyond the total padding allowed. */
20975 if (field_width - n > 0 && field > field_width - n)
20976 field = field_width - n;
20977
20978 /* Note that either PRECISION <= 0 or N < PRECISION. */
20979 prec = precision - n;
20980
20981 if (c == 'M')
20982 n += display_mode_element (it, depth, field, prec,
20983 Vglobal_mode_string, props,
20984 risky);
20985 else if (c != 0)
20986 {
20987 bool multibyte;
20988 ptrdiff_t bytepos, charpos;
20989 const char *spec;
20990 Lisp_Object string;
20991
20992 bytepos = percent_position;
20993 charpos = (STRING_MULTIBYTE (elt)
20994 ? string_byte_to_char (elt, bytepos)
20995 : bytepos);
20996 spec = decode_mode_spec (it->w, c, field, &string);
20997 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20998
20999 switch (mode_line_target)
21000 {
21001 case MODE_LINE_NOPROP:
21002 case MODE_LINE_TITLE:
21003 n += store_mode_line_noprop (spec, field, prec);
21004 break;
21005 case MODE_LINE_STRING:
21006 {
21007 Lisp_Object tem = build_string (spec);
21008 props = Ftext_properties_at (make_number (charpos), elt);
21009 /* Should only keep face property in props */
21010 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21011 }
21012 break;
21013 case MODE_LINE_DISPLAY:
21014 {
21015 int nglyphs_before, nwritten;
21016
21017 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21018 nwritten = display_string (spec, string, elt,
21019 charpos, 0, it,
21020 field, prec, 0,
21021 multibyte);
21022
21023 /* Assign to the glyphs written above the
21024 string where the `%x' came from, position
21025 of the `%'. */
21026 if (nwritten > 0)
21027 {
21028 struct glyph *glyph
21029 = (it->glyph_row->glyphs[TEXT_AREA]
21030 + nglyphs_before);
21031 int i;
21032
21033 for (i = 0; i < nwritten; ++i)
21034 {
21035 glyph[i].object = elt;
21036 glyph[i].charpos = charpos;
21037 }
21038
21039 n += nwritten;
21040 }
21041 }
21042 break;
21043 }
21044 }
21045 else /* c == 0 */
21046 break;
21047 }
21048 }
21049 }
21050 break;
21051
21052 case Lisp_Symbol:
21053 /* A symbol: process the value of the symbol recursively
21054 as if it appeared here directly. Avoid error if symbol void.
21055 Special case: if value of symbol is a string, output the string
21056 literally. */
21057 {
21058 register Lisp_Object tem;
21059
21060 /* If the variable is not marked as risky to set
21061 then its contents are risky to use. */
21062 if (NILP (Fget (elt, Qrisky_local_variable)))
21063 risky = 1;
21064
21065 tem = Fboundp (elt);
21066 if (!NILP (tem))
21067 {
21068 tem = Fsymbol_value (elt);
21069 /* If value is a string, output that string literally:
21070 don't check for % within it. */
21071 if (STRINGP (tem))
21072 literal = 1;
21073
21074 if (!EQ (tem, elt))
21075 {
21076 /* Give up right away for nil or t. */
21077 elt = tem;
21078 goto tail_recurse;
21079 }
21080 }
21081 }
21082 break;
21083
21084 case Lisp_Cons:
21085 {
21086 register Lisp_Object car, tem;
21087
21088 /* A cons cell: five distinct cases.
21089 If first element is :eval or :propertize, do something special.
21090 If first element is a string or a cons, process all the elements
21091 and effectively concatenate them.
21092 If first element is a negative number, truncate displaying cdr to
21093 at most that many characters. If positive, pad (with spaces)
21094 to at least that many characters.
21095 If first element is a symbol, process the cadr or caddr recursively
21096 according to whether the symbol's value is non-nil or nil. */
21097 car = XCAR (elt);
21098 if (EQ (car, QCeval))
21099 {
21100 /* An element of the form (:eval FORM) means evaluate FORM
21101 and use the result as mode line elements. */
21102
21103 if (risky)
21104 break;
21105
21106 if (CONSP (XCDR (elt)))
21107 {
21108 Lisp_Object spec;
21109 spec = safe_eval (XCAR (XCDR (elt)));
21110 n += display_mode_element (it, depth, field_width - n,
21111 precision - n, spec, props,
21112 risky);
21113 }
21114 }
21115 else if (EQ (car, QCpropertize))
21116 {
21117 /* An element of the form (:propertize ELT PROPS...)
21118 means display ELT but applying properties PROPS. */
21119
21120 if (risky)
21121 break;
21122
21123 if (CONSP (XCDR (elt)))
21124 n += display_mode_element (it, depth, field_width - n,
21125 precision - n, XCAR (XCDR (elt)),
21126 XCDR (XCDR (elt)), risky);
21127 }
21128 else if (SYMBOLP (car))
21129 {
21130 tem = Fboundp (car);
21131 elt = XCDR (elt);
21132 if (!CONSP (elt))
21133 goto invalid;
21134 /* elt is now the cdr, and we know it is a cons cell.
21135 Use its car if CAR has a non-nil value. */
21136 if (!NILP (tem))
21137 {
21138 tem = Fsymbol_value (car);
21139 if (!NILP (tem))
21140 {
21141 elt = XCAR (elt);
21142 goto tail_recurse;
21143 }
21144 }
21145 /* Symbol's value is nil (or symbol is unbound)
21146 Get the cddr of the original list
21147 and if possible find the caddr and use that. */
21148 elt = XCDR (elt);
21149 if (NILP (elt))
21150 break;
21151 else if (!CONSP (elt))
21152 goto invalid;
21153 elt = XCAR (elt);
21154 goto tail_recurse;
21155 }
21156 else if (INTEGERP (car))
21157 {
21158 register int lim = XINT (car);
21159 elt = XCDR (elt);
21160 if (lim < 0)
21161 {
21162 /* Negative int means reduce maximum width. */
21163 if (precision <= 0)
21164 precision = -lim;
21165 else
21166 precision = min (precision, -lim);
21167 }
21168 else if (lim > 0)
21169 {
21170 /* Padding specified. Don't let it be more than
21171 current maximum. */
21172 if (precision > 0)
21173 lim = min (precision, lim);
21174
21175 /* If that's more padding than already wanted, queue it.
21176 But don't reduce padding already specified even if
21177 that is beyond the current truncation point. */
21178 field_width = max (lim, field_width);
21179 }
21180 goto tail_recurse;
21181 }
21182 else if (STRINGP (car) || CONSP (car))
21183 {
21184 Lisp_Object halftail = elt;
21185 int len = 0;
21186
21187 while (CONSP (elt)
21188 && (precision <= 0 || n < precision))
21189 {
21190 n += display_mode_element (it, depth,
21191 /* Do padding only after the last
21192 element in the list. */
21193 (! CONSP (XCDR (elt))
21194 ? field_width - n
21195 : 0),
21196 precision - n, XCAR (elt),
21197 props, risky);
21198 elt = XCDR (elt);
21199 len++;
21200 if ((len & 1) == 0)
21201 halftail = XCDR (halftail);
21202 /* Check for cycle. */
21203 if (EQ (halftail, elt))
21204 break;
21205 }
21206 }
21207 }
21208 break;
21209
21210 default:
21211 invalid:
21212 elt = build_string ("*invalid*");
21213 goto tail_recurse;
21214 }
21215
21216 /* Pad to FIELD_WIDTH. */
21217 if (field_width > 0 && n < field_width)
21218 {
21219 switch (mode_line_target)
21220 {
21221 case MODE_LINE_NOPROP:
21222 case MODE_LINE_TITLE:
21223 n += store_mode_line_noprop ("", field_width - n, 0);
21224 break;
21225 case MODE_LINE_STRING:
21226 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
21227 break;
21228 case MODE_LINE_DISPLAY:
21229 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
21230 0, 0, 0);
21231 break;
21232 }
21233 }
21234
21235 return n;
21236 }
21237
21238 /* Store a mode-line string element in mode_line_string_list.
21239
21240 If STRING is non-null, display that C string. Otherwise, the Lisp
21241 string LISP_STRING is displayed.
21242
21243 FIELD_WIDTH is the minimum number of output glyphs to produce.
21244 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21245 with spaces. FIELD_WIDTH <= 0 means don't pad.
21246
21247 PRECISION is the maximum number of characters to output from
21248 STRING. PRECISION <= 0 means don't truncate the string.
21249
21250 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21251 properties to the string.
21252
21253 PROPS are the properties to add to the string.
21254 The mode_line_string_face face property is always added to the string.
21255 */
21256
21257 static int
21258 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21259 int field_width, int precision, Lisp_Object props)
21260 {
21261 ptrdiff_t len;
21262 int n = 0;
21263
21264 if (string != NULL)
21265 {
21266 len = strlen (string);
21267 if (precision > 0 && len > precision)
21268 len = precision;
21269 lisp_string = make_string (string, len);
21270 if (NILP (props))
21271 props = mode_line_string_face_prop;
21272 else if (!NILP (mode_line_string_face))
21273 {
21274 Lisp_Object face = Fplist_get (props, Qface);
21275 props = Fcopy_sequence (props);
21276 if (NILP (face))
21277 face = mode_line_string_face;
21278 else
21279 face = list2 (face, mode_line_string_face);
21280 props = Fplist_put (props, Qface, face);
21281 }
21282 Fadd_text_properties (make_number (0), make_number (len),
21283 props, lisp_string);
21284 }
21285 else
21286 {
21287 len = XFASTINT (Flength (lisp_string));
21288 if (precision > 0 && len > precision)
21289 {
21290 len = precision;
21291 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21292 precision = -1;
21293 }
21294 if (!NILP (mode_line_string_face))
21295 {
21296 Lisp_Object face;
21297 if (NILP (props))
21298 props = Ftext_properties_at (make_number (0), lisp_string);
21299 face = Fplist_get (props, Qface);
21300 if (NILP (face))
21301 face = mode_line_string_face;
21302 else
21303 face = list2 (face, mode_line_string_face);
21304 props = list2 (Qface, face);
21305 if (copy_string)
21306 lisp_string = Fcopy_sequence (lisp_string);
21307 }
21308 if (!NILP (props))
21309 Fadd_text_properties (make_number (0), make_number (len),
21310 props, lisp_string);
21311 }
21312
21313 if (len > 0)
21314 {
21315 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21316 n += len;
21317 }
21318
21319 if (field_width > len)
21320 {
21321 field_width -= len;
21322 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21323 if (!NILP (props))
21324 Fadd_text_properties (make_number (0), make_number (field_width),
21325 props, lisp_string);
21326 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21327 n += field_width;
21328 }
21329
21330 return n;
21331 }
21332
21333
21334 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21335 1, 4, 0,
21336 doc: /* Format a string out of a mode line format specification.
21337 First arg FORMAT specifies the mode line format (see `mode-line-format'
21338 for details) to use.
21339
21340 By default, the format is evaluated for the currently selected window.
21341
21342 Optional second arg FACE specifies the face property to put on all
21343 characters for which no face is specified. The value nil means the
21344 default face. The value t means whatever face the window's mode line
21345 currently uses (either `mode-line' or `mode-line-inactive',
21346 depending on whether the window is the selected window or not).
21347 An integer value means the value string has no text
21348 properties.
21349
21350 Optional third and fourth args WINDOW and BUFFER specify the window
21351 and buffer to use as the context for the formatting (defaults
21352 are the selected window and the WINDOW's buffer). */)
21353 (Lisp_Object format, Lisp_Object face,
21354 Lisp_Object window, Lisp_Object buffer)
21355 {
21356 struct it it;
21357 int len;
21358 struct window *w;
21359 struct buffer *old_buffer = NULL;
21360 int face_id;
21361 int no_props = INTEGERP (face);
21362 ptrdiff_t count = SPECPDL_INDEX ();
21363 Lisp_Object str;
21364 int string_start = 0;
21365
21366 w = decode_any_window (window);
21367 XSETWINDOW (window, w);
21368
21369 if (NILP (buffer))
21370 buffer = w->contents;
21371 CHECK_BUFFER (buffer);
21372
21373 /* Make formatting the modeline a non-op when noninteractive, otherwise
21374 there will be problems later caused by a partially initialized frame. */
21375 if (NILP (format) || noninteractive)
21376 return empty_unibyte_string;
21377
21378 if (no_props)
21379 face = Qnil;
21380
21381 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21382 : EQ (face, Qt) ? (EQ (window, selected_window)
21383 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21384 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21385 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21386 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21387 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21388 : DEFAULT_FACE_ID;
21389
21390 old_buffer = current_buffer;
21391
21392 /* Save things including mode_line_proptrans_alist,
21393 and set that to nil so that we don't alter the outer value. */
21394 record_unwind_protect (unwind_format_mode_line,
21395 format_mode_line_unwind_data
21396 (XFRAME (WINDOW_FRAME (w)),
21397 old_buffer, selected_window, 1));
21398 mode_line_proptrans_alist = Qnil;
21399
21400 Fselect_window (window, Qt);
21401 set_buffer_internal_1 (XBUFFER (buffer));
21402
21403 init_iterator (&it, w, -1, -1, NULL, face_id);
21404
21405 if (no_props)
21406 {
21407 mode_line_target = MODE_LINE_NOPROP;
21408 mode_line_string_face_prop = Qnil;
21409 mode_line_string_list = Qnil;
21410 string_start = MODE_LINE_NOPROP_LEN (0);
21411 }
21412 else
21413 {
21414 mode_line_target = MODE_LINE_STRING;
21415 mode_line_string_list = Qnil;
21416 mode_line_string_face = face;
21417 mode_line_string_face_prop
21418 = NILP (face) ? Qnil : list2 (Qface, face);
21419 }
21420
21421 push_kboard (FRAME_KBOARD (it.f));
21422 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21423 pop_kboard ();
21424
21425 if (no_props)
21426 {
21427 len = MODE_LINE_NOPROP_LEN (string_start);
21428 str = make_string (mode_line_noprop_buf + string_start, len);
21429 }
21430 else
21431 {
21432 mode_line_string_list = Fnreverse (mode_line_string_list);
21433 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21434 empty_unibyte_string);
21435 }
21436
21437 unbind_to (count, Qnil);
21438 return str;
21439 }
21440
21441 /* Write a null-terminated, right justified decimal representation of
21442 the positive integer D to BUF using a minimal field width WIDTH. */
21443
21444 static void
21445 pint2str (register char *buf, register int width, register ptrdiff_t d)
21446 {
21447 register char *p = buf;
21448
21449 if (d <= 0)
21450 *p++ = '0';
21451 else
21452 {
21453 while (d > 0)
21454 {
21455 *p++ = d % 10 + '0';
21456 d /= 10;
21457 }
21458 }
21459
21460 for (width -= (int) (p - buf); width > 0; --width)
21461 *p++ = ' ';
21462 *p-- = '\0';
21463 while (p > buf)
21464 {
21465 d = *buf;
21466 *buf++ = *p;
21467 *p-- = d;
21468 }
21469 }
21470
21471 /* Write a null-terminated, right justified decimal and "human
21472 readable" representation of the nonnegative integer D to BUF using
21473 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21474
21475 static const char power_letter[] =
21476 {
21477 0, /* no letter */
21478 'k', /* kilo */
21479 'M', /* mega */
21480 'G', /* giga */
21481 'T', /* tera */
21482 'P', /* peta */
21483 'E', /* exa */
21484 'Z', /* zetta */
21485 'Y' /* yotta */
21486 };
21487
21488 static void
21489 pint2hrstr (char *buf, int width, ptrdiff_t d)
21490 {
21491 /* We aim to represent the nonnegative integer D as
21492 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21493 ptrdiff_t quotient = d;
21494 int remainder = 0;
21495 /* -1 means: do not use TENTHS. */
21496 int tenths = -1;
21497 int exponent = 0;
21498
21499 /* Length of QUOTIENT.TENTHS as a string. */
21500 int length;
21501
21502 char * psuffix;
21503 char * p;
21504
21505 if (quotient >= 1000)
21506 {
21507 /* Scale to the appropriate EXPONENT. */
21508 do
21509 {
21510 remainder = quotient % 1000;
21511 quotient /= 1000;
21512 exponent++;
21513 }
21514 while (quotient >= 1000);
21515
21516 /* Round to nearest and decide whether to use TENTHS or not. */
21517 if (quotient <= 9)
21518 {
21519 tenths = remainder / 100;
21520 if (remainder % 100 >= 50)
21521 {
21522 if (tenths < 9)
21523 tenths++;
21524 else
21525 {
21526 quotient++;
21527 if (quotient == 10)
21528 tenths = -1;
21529 else
21530 tenths = 0;
21531 }
21532 }
21533 }
21534 else
21535 if (remainder >= 500)
21536 {
21537 if (quotient < 999)
21538 quotient++;
21539 else
21540 {
21541 quotient = 1;
21542 exponent++;
21543 tenths = 0;
21544 }
21545 }
21546 }
21547
21548 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21549 if (tenths == -1 && quotient <= 99)
21550 if (quotient <= 9)
21551 length = 1;
21552 else
21553 length = 2;
21554 else
21555 length = 3;
21556 p = psuffix = buf + max (width, length);
21557
21558 /* Print EXPONENT. */
21559 *psuffix++ = power_letter[exponent];
21560 *psuffix = '\0';
21561
21562 /* Print TENTHS. */
21563 if (tenths >= 0)
21564 {
21565 *--p = '0' + tenths;
21566 *--p = '.';
21567 }
21568
21569 /* Print QUOTIENT. */
21570 do
21571 {
21572 int digit = quotient % 10;
21573 *--p = '0' + digit;
21574 }
21575 while ((quotient /= 10) != 0);
21576
21577 /* Print leading spaces. */
21578 while (buf < p)
21579 *--p = ' ';
21580 }
21581
21582 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21583 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21584 type of CODING_SYSTEM. Return updated pointer into BUF. */
21585
21586 static unsigned char invalid_eol_type[] = "(*invalid*)";
21587
21588 static char *
21589 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21590 {
21591 Lisp_Object val;
21592 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21593 const unsigned char *eol_str;
21594 int eol_str_len;
21595 /* The EOL conversion we are using. */
21596 Lisp_Object eoltype;
21597
21598 val = CODING_SYSTEM_SPEC (coding_system);
21599 eoltype = Qnil;
21600
21601 if (!VECTORP (val)) /* Not yet decided. */
21602 {
21603 *buf++ = multibyte ? '-' : ' ';
21604 if (eol_flag)
21605 eoltype = eol_mnemonic_undecided;
21606 /* Don't mention EOL conversion if it isn't decided. */
21607 }
21608 else
21609 {
21610 Lisp_Object attrs;
21611 Lisp_Object eolvalue;
21612
21613 attrs = AREF (val, 0);
21614 eolvalue = AREF (val, 2);
21615
21616 *buf++ = multibyte
21617 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21618 : ' ';
21619
21620 if (eol_flag)
21621 {
21622 /* The EOL conversion that is normal on this system. */
21623
21624 if (NILP (eolvalue)) /* Not yet decided. */
21625 eoltype = eol_mnemonic_undecided;
21626 else if (VECTORP (eolvalue)) /* Not yet decided. */
21627 eoltype = eol_mnemonic_undecided;
21628 else /* eolvalue is Qunix, Qdos, or Qmac. */
21629 eoltype = (EQ (eolvalue, Qunix)
21630 ? eol_mnemonic_unix
21631 : (EQ (eolvalue, Qdos) == 1
21632 ? eol_mnemonic_dos : eol_mnemonic_mac));
21633 }
21634 }
21635
21636 if (eol_flag)
21637 {
21638 /* Mention the EOL conversion if it is not the usual one. */
21639 if (STRINGP (eoltype))
21640 {
21641 eol_str = SDATA (eoltype);
21642 eol_str_len = SBYTES (eoltype);
21643 }
21644 else if (CHARACTERP (eoltype))
21645 {
21646 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21647 int c = XFASTINT (eoltype);
21648 eol_str_len = CHAR_STRING (c, tmp);
21649 eol_str = tmp;
21650 }
21651 else
21652 {
21653 eol_str = invalid_eol_type;
21654 eol_str_len = sizeof (invalid_eol_type) - 1;
21655 }
21656 memcpy (buf, eol_str, eol_str_len);
21657 buf += eol_str_len;
21658 }
21659
21660 return buf;
21661 }
21662
21663 /* Return a string for the output of a mode line %-spec for window W,
21664 generated by character C. FIELD_WIDTH > 0 means pad the string
21665 returned with spaces to that value. Return a Lisp string in
21666 *STRING if the resulting string is taken from that Lisp string.
21667
21668 Note we operate on the current buffer for most purposes. */
21669
21670 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21671
21672 static const char *
21673 decode_mode_spec (struct window *w, register int c, int field_width,
21674 Lisp_Object *string)
21675 {
21676 Lisp_Object obj;
21677 struct frame *f = XFRAME (WINDOW_FRAME (w));
21678 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21679 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21680 produce strings from numerical values, so limit preposterously
21681 large values of FIELD_WIDTH to avoid overrunning the buffer's
21682 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21683 bytes plus the terminating null. */
21684 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21685 struct buffer *b = current_buffer;
21686
21687 obj = Qnil;
21688 *string = Qnil;
21689
21690 switch (c)
21691 {
21692 case '*':
21693 if (!NILP (BVAR (b, read_only)))
21694 return "%";
21695 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21696 return "*";
21697 return "-";
21698
21699 case '+':
21700 /* This differs from %* only for a modified read-only buffer. */
21701 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21702 return "*";
21703 if (!NILP (BVAR (b, read_only)))
21704 return "%";
21705 return "-";
21706
21707 case '&':
21708 /* This differs from %* in ignoring read-only-ness. */
21709 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21710 return "*";
21711 return "-";
21712
21713 case '%':
21714 return "%";
21715
21716 case '[':
21717 {
21718 int i;
21719 char *p;
21720
21721 if (command_loop_level > 5)
21722 return "[[[... ";
21723 p = decode_mode_spec_buf;
21724 for (i = 0; i < command_loop_level; i++)
21725 *p++ = '[';
21726 *p = 0;
21727 return decode_mode_spec_buf;
21728 }
21729
21730 case ']':
21731 {
21732 int i;
21733 char *p;
21734
21735 if (command_loop_level > 5)
21736 return " ...]]]";
21737 p = decode_mode_spec_buf;
21738 for (i = 0; i < command_loop_level; i++)
21739 *p++ = ']';
21740 *p = 0;
21741 return decode_mode_spec_buf;
21742 }
21743
21744 case '-':
21745 {
21746 register int i;
21747
21748 /* Let lots_of_dashes be a string of infinite length. */
21749 if (mode_line_target == MODE_LINE_NOPROP
21750 || mode_line_target == MODE_LINE_STRING)
21751 return "--";
21752 if (field_width <= 0
21753 || field_width > sizeof (lots_of_dashes))
21754 {
21755 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21756 decode_mode_spec_buf[i] = '-';
21757 decode_mode_spec_buf[i] = '\0';
21758 return decode_mode_spec_buf;
21759 }
21760 else
21761 return lots_of_dashes;
21762 }
21763
21764 case 'b':
21765 obj = BVAR (b, name);
21766 break;
21767
21768 case 'c':
21769 /* %c and %l are ignored in `frame-title-format'.
21770 (In redisplay_internal, the frame title is drawn _before_ the
21771 windows are updated, so the stuff which depends on actual
21772 window contents (such as %l) may fail to render properly, or
21773 even crash emacs.) */
21774 if (mode_line_target == MODE_LINE_TITLE)
21775 return "";
21776 else
21777 {
21778 ptrdiff_t col = current_column ();
21779 w->column_number_displayed = col;
21780 pint2str (decode_mode_spec_buf, width, col);
21781 return decode_mode_spec_buf;
21782 }
21783
21784 case 'e':
21785 #ifndef SYSTEM_MALLOC
21786 {
21787 if (NILP (Vmemory_full))
21788 return "";
21789 else
21790 return "!MEM FULL! ";
21791 }
21792 #else
21793 return "";
21794 #endif
21795
21796 case 'F':
21797 /* %F displays the frame name. */
21798 if (!NILP (f->title))
21799 return SSDATA (f->title);
21800 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21801 return SSDATA (f->name);
21802 return "Emacs";
21803
21804 case 'f':
21805 obj = BVAR (b, filename);
21806 break;
21807
21808 case 'i':
21809 {
21810 ptrdiff_t size = ZV - BEGV;
21811 pint2str (decode_mode_spec_buf, width, size);
21812 return decode_mode_spec_buf;
21813 }
21814
21815 case 'I':
21816 {
21817 ptrdiff_t size = ZV - BEGV;
21818 pint2hrstr (decode_mode_spec_buf, width, size);
21819 return decode_mode_spec_buf;
21820 }
21821
21822 case 'l':
21823 {
21824 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21825 ptrdiff_t topline, nlines, height;
21826 ptrdiff_t junk;
21827
21828 /* %c and %l are ignored in `frame-title-format'. */
21829 if (mode_line_target == MODE_LINE_TITLE)
21830 return "";
21831
21832 startpos = marker_position (w->start);
21833 startpos_byte = marker_byte_position (w->start);
21834 height = WINDOW_TOTAL_LINES (w);
21835
21836 /* If we decided that this buffer isn't suitable for line numbers,
21837 don't forget that too fast. */
21838 if (w->base_line_pos == -1)
21839 goto no_value;
21840
21841 /* If the buffer is very big, don't waste time. */
21842 if (INTEGERP (Vline_number_display_limit)
21843 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21844 {
21845 w->base_line_pos = 0;
21846 w->base_line_number = 0;
21847 goto no_value;
21848 }
21849
21850 if (w->base_line_number > 0
21851 && w->base_line_pos > 0
21852 && w->base_line_pos <= startpos)
21853 {
21854 line = w->base_line_number;
21855 linepos = w->base_line_pos;
21856 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21857 }
21858 else
21859 {
21860 line = 1;
21861 linepos = BUF_BEGV (b);
21862 linepos_byte = BUF_BEGV_BYTE (b);
21863 }
21864
21865 /* Count lines from base line to window start position. */
21866 nlines = display_count_lines (linepos_byte,
21867 startpos_byte,
21868 startpos, &junk);
21869
21870 topline = nlines + line;
21871
21872 /* Determine a new base line, if the old one is too close
21873 or too far away, or if we did not have one.
21874 "Too close" means it's plausible a scroll-down would
21875 go back past it. */
21876 if (startpos == BUF_BEGV (b))
21877 {
21878 w->base_line_number = topline;
21879 w->base_line_pos = BUF_BEGV (b);
21880 }
21881 else if (nlines < height + 25 || nlines > height * 3 + 50
21882 || linepos == BUF_BEGV (b))
21883 {
21884 ptrdiff_t limit = BUF_BEGV (b);
21885 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21886 ptrdiff_t position;
21887 ptrdiff_t distance =
21888 (height * 2 + 30) * line_number_display_limit_width;
21889
21890 if (startpos - distance > limit)
21891 {
21892 limit = startpos - distance;
21893 limit_byte = CHAR_TO_BYTE (limit);
21894 }
21895
21896 nlines = display_count_lines (startpos_byte,
21897 limit_byte,
21898 - (height * 2 + 30),
21899 &position);
21900 /* If we couldn't find the lines we wanted within
21901 line_number_display_limit_width chars per line,
21902 give up on line numbers for this window. */
21903 if (position == limit_byte && limit == startpos - distance)
21904 {
21905 w->base_line_pos = -1;
21906 w->base_line_number = 0;
21907 goto no_value;
21908 }
21909
21910 w->base_line_number = topline - nlines;
21911 w->base_line_pos = BYTE_TO_CHAR (position);
21912 }
21913
21914 /* Now count lines from the start pos to point. */
21915 nlines = display_count_lines (startpos_byte,
21916 PT_BYTE, PT, &junk);
21917
21918 /* Record that we did display the line number. */
21919 line_number_displayed = 1;
21920
21921 /* Make the string to show. */
21922 pint2str (decode_mode_spec_buf, width, topline + nlines);
21923 return decode_mode_spec_buf;
21924 no_value:
21925 {
21926 char* p = decode_mode_spec_buf;
21927 int pad = width - 2;
21928 while (pad-- > 0)
21929 *p++ = ' ';
21930 *p++ = '?';
21931 *p++ = '?';
21932 *p = '\0';
21933 return decode_mode_spec_buf;
21934 }
21935 }
21936 break;
21937
21938 case 'm':
21939 obj = BVAR (b, mode_name);
21940 break;
21941
21942 case 'n':
21943 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21944 return " Narrow";
21945 break;
21946
21947 case 'p':
21948 {
21949 ptrdiff_t pos = marker_position (w->start);
21950 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21951
21952 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
21953 {
21954 if (pos <= BUF_BEGV (b))
21955 return "All";
21956 else
21957 return "Bottom";
21958 }
21959 else if (pos <= BUF_BEGV (b))
21960 return "Top";
21961 else
21962 {
21963 if (total > 1000000)
21964 /* Do it differently for a large value, to avoid overflow. */
21965 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21966 else
21967 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21968 /* We can't normally display a 3-digit number,
21969 so get us a 2-digit number that is close. */
21970 if (total == 100)
21971 total = 99;
21972 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21973 return decode_mode_spec_buf;
21974 }
21975 }
21976
21977 /* Display percentage of size above the bottom of the screen. */
21978 case 'P':
21979 {
21980 ptrdiff_t toppos = marker_position (w->start);
21981 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
21982 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21983
21984 if (botpos >= BUF_ZV (b))
21985 {
21986 if (toppos <= BUF_BEGV (b))
21987 return "All";
21988 else
21989 return "Bottom";
21990 }
21991 else
21992 {
21993 if (total > 1000000)
21994 /* Do it differently for a large value, to avoid overflow. */
21995 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21996 else
21997 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21998 /* We can't normally display a 3-digit number,
21999 so get us a 2-digit number that is close. */
22000 if (total == 100)
22001 total = 99;
22002 if (toppos <= BUF_BEGV (b))
22003 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22004 else
22005 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22006 return decode_mode_spec_buf;
22007 }
22008 }
22009
22010 case 's':
22011 /* status of process */
22012 obj = Fget_buffer_process (Fcurrent_buffer ());
22013 if (NILP (obj))
22014 return "no process";
22015 #ifndef MSDOS
22016 obj = Fsymbol_name (Fprocess_status (obj));
22017 #endif
22018 break;
22019
22020 case '@':
22021 {
22022 ptrdiff_t count = inhibit_garbage_collection ();
22023 Lisp_Object val = call1 (intern ("file-remote-p"),
22024 BVAR (current_buffer, directory));
22025 unbind_to (count, Qnil);
22026
22027 if (NILP (val))
22028 return "-";
22029 else
22030 return "@";
22031 }
22032
22033 case 'z':
22034 /* coding-system (not including end-of-line format) */
22035 case 'Z':
22036 /* coding-system (including end-of-line type) */
22037 {
22038 int eol_flag = (c == 'Z');
22039 char *p = decode_mode_spec_buf;
22040
22041 if (! FRAME_WINDOW_P (f))
22042 {
22043 /* No need to mention EOL here--the terminal never needs
22044 to do EOL conversion. */
22045 p = decode_mode_spec_coding (CODING_ID_NAME
22046 (FRAME_KEYBOARD_CODING (f)->id),
22047 p, 0);
22048 p = decode_mode_spec_coding (CODING_ID_NAME
22049 (FRAME_TERMINAL_CODING (f)->id),
22050 p, 0);
22051 }
22052 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
22053 p, eol_flag);
22054
22055 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22056 #ifdef subprocesses
22057 obj = Fget_buffer_process (Fcurrent_buffer ());
22058 if (PROCESSP (obj))
22059 {
22060 p = decode_mode_spec_coding
22061 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
22062 p = decode_mode_spec_coding
22063 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
22064 }
22065 #endif /* subprocesses */
22066 #endif /* 0 */
22067 *p = 0;
22068 return decode_mode_spec_buf;
22069 }
22070 }
22071
22072 if (STRINGP (obj))
22073 {
22074 *string = obj;
22075 return SSDATA (obj);
22076 }
22077 else
22078 return "";
22079 }
22080
22081
22082 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22083 means count lines back from START_BYTE. But don't go beyond
22084 LIMIT_BYTE. Return the number of lines thus found (always
22085 nonnegative).
22086
22087 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22088 either the position COUNT lines after/before START_BYTE, if we
22089 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22090 COUNT lines. */
22091
22092 static ptrdiff_t
22093 display_count_lines (ptrdiff_t start_byte,
22094 ptrdiff_t limit_byte, ptrdiff_t count,
22095 ptrdiff_t *byte_pos_ptr)
22096 {
22097 register unsigned char *cursor;
22098 unsigned char *base;
22099
22100 register ptrdiff_t ceiling;
22101 register unsigned char *ceiling_addr;
22102 ptrdiff_t orig_count = count;
22103
22104 /* If we are not in selective display mode,
22105 check only for newlines. */
22106 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
22107 && !INTEGERP (BVAR (current_buffer, selective_display)));
22108
22109 if (count > 0)
22110 {
22111 while (start_byte < limit_byte)
22112 {
22113 ceiling = BUFFER_CEILING_OF (start_byte);
22114 ceiling = min (limit_byte - 1, ceiling);
22115 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
22116 base = (cursor = BYTE_POS_ADDR (start_byte));
22117
22118 do
22119 {
22120 if (selective_display)
22121 {
22122 while (*cursor != '\n' && *cursor != 015
22123 && ++cursor != ceiling_addr)
22124 continue;
22125 if (cursor == ceiling_addr)
22126 break;
22127 }
22128 else
22129 {
22130 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
22131 if (! cursor)
22132 break;
22133 }
22134
22135 cursor++;
22136
22137 if (--count == 0)
22138 {
22139 start_byte += cursor - base;
22140 *byte_pos_ptr = start_byte;
22141 return orig_count;
22142 }
22143 }
22144 while (cursor < ceiling_addr);
22145
22146 start_byte += ceiling_addr - base;
22147 }
22148 }
22149 else
22150 {
22151 while (start_byte > limit_byte)
22152 {
22153 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
22154 ceiling = max (limit_byte, ceiling);
22155 ceiling_addr = BYTE_POS_ADDR (ceiling);
22156 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
22157 while (1)
22158 {
22159 if (selective_display)
22160 {
22161 while (--cursor >= ceiling_addr
22162 && *cursor != '\n' && *cursor != 015)
22163 continue;
22164 if (cursor < ceiling_addr)
22165 break;
22166 }
22167 else
22168 {
22169 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
22170 if (! cursor)
22171 break;
22172 }
22173
22174 if (++count == 0)
22175 {
22176 start_byte += cursor - base + 1;
22177 *byte_pos_ptr = start_byte;
22178 /* When scanning backwards, we should
22179 not count the newline posterior to which we stop. */
22180 return - orig_count - 1;
22181 }
22182 }
22183 start_byte += ceiling_addr - base;
22184 }
22185 }
22186
22187 *byte_pos_ptr = limit_byte;
22188
22189 if (count < 0)
22190 return - orig_count + count;
22191 return orig_count - count;
22192
22193 }
22194
22195
22196 \f
22197 /***********************************************************************
22198 Displaying strings
22199 ***********************************************************************/
22200
22201 /* Display a NUL-terminated string, starting with index START.
22202
22203 If STRING is non-null, display that C string. Otherwise, the Lisp
22204 string LISP_STRING is displayed. There's a case that STRING is
22205 non-null and LISP_STRING is not nil. It means STRING is a string
22206 data of LISP_STRING. In that case, we display LISP_STRING while
22207 ignoring its text properties.
22208
22209 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22210 FACE_STRING. Display STRING or LISP_STRING with the face at
22211 FACE_STRING_POS in FACE_STRING:
22212
22213 Display the string in the environment given by IT, but use the
22214 standard display table, temporarily.
22215
22216 FIELD_WIDTH is the minimum number of output glyphs to produce.
22217 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22218 with spaces. If STRING has more characters, more than FIELD_WIDTH
22219 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22220
22221 PRECISION is the maximum number of characters to output from
22222 STRING. PRECISION < 0 means don't truncate the string.
22223
22224 This is roughly equivalent to printf format specifiers:
22225
22226 FIELD_WIDTH PRECISION PRINTF
22227 ----------------------------------------
22228 -1 -1 %s
22229 -1 10 %.10s
22230 10 -1 %10s
22231 20 10 %20.10s
22232
22233 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22234 display them, and < 0 means obey the current buffer's value of
22235 enable_multibyte_characters.
22236
22237 Value is the number of columns displayed. */
22238
22239 static int
22240 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
22241 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
22242 int field_width, int precision, int max_x, int multibyte)
22243 {
22244 int hpos_at_start = it->hpos;
22245 int saved_face_id = it->face_id;
22246 struct glyph_row *row = it->glyph_row;
22247 ptrdiff_t it_charpos;
22248
22249 /* Initialize the iterator IT for iteration over STRING beginning
22250 with index START. */
22251 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22252 precision, field_width, multibyte);
22253 if (string && STRINGP (lisp_string))
22254 /* LISP_STRING is the one returned by decode_mode_spec. We should
22255 ignore its text properties. */
22256 it->stop_charpos = it->end_charpos;
22257
22258 /* If displaying STRING, set up the face of the iterator from
22259 FACE_STRING, if that's given. */
22260 if (STRINGP (face_string))
22261 {
22262 ptrdiff_t endptr;
22263 struct face *face;
22264
22265 it->face_id
22266 = face_at_string_position (it->w, face_string, face_string_pos,
22267 0, it->region_beg_charpos,
22268 it->region_end_charpos,
22269 &endptr, it->base_face_id, 0);
22270 face = FACE_FROM_ID (it->f, it->face_id);
22271 it->face_box_p = face->box != FACE_NO_BOX;
22272 }
22273
22274 /* Set max_x to the maximum allowed X position. Don't let it go
22275 beyond the right edge of the window. */
22276 if (max_x <= 0)
22277 max_x = it->last_visible_x;
22278 else
22279 max_x = min (max_x, it->last_visible_x);
22280
22281 /* Skip over display elements that are not visible. because IT->w is
22282 hscrolled. */
22283 if (it->current_x < it->first_visible_x)
22284 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22285 MOVE_TO_POS | MOVE_TO_X);
22286
22287 row->ascent = it->max_ascent;
22288 row->height = it->max_ascent + it->max_descent;
22289 row->phys_ascent = it->max_phys_ascent;
22290 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22291 row->extra_line_spacing = it->max_extra_line_spacing;
22292
22293 if (STRINGP (it->string))
22294 it_charpos = IT_STRING_CHARPOS (*it);
22295 else
22296 it_charpos = IT_CHARPOS (*it);
22297
22298 /* This condition is for the case that we are called with current_x
22299 past last_visible_x. */
22300 while (it->current_x < max_x)
22301 {
22302 int x_before, x, n_glyphs_before, i, nglyphs;
22303
22304 /* Get the next display element. */
22305 if (!get_next_display_element (it))
22306 break;
22307
22308 /* Produce glyphs. */
22309 x_before = it->current_x;
22310 n_glyphs_before = row->used[TEXT_AREA];
22311 PRODUCE_GLYPHS (it);
22312
22313 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22314 i = 0;
22315 x = x_before;
22316 while (i < nglyphs)
22317 {
22318 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22319
22320 if (it->line_wrap != TRUNCATE
22321 && x + glyph->pixel_width > max_x)
22322 {
22323 /* End of continued line or max_x reached. */
22324 if (CHAR_GLYPH_PADDING_P (*glyph))
22325 {
22326 /* A wide character is unbreakable. */
22327 if (row->reversed_p)
22328 unproduce_glyphs (it, row->used[TEXT_AREA]
22329 - n_glyphs_before);
22330 row->used[TEXT_AREA] = n_glyphs_before;
22331 it->current_x = x_before;
22332 }
22333 else
22334 {
22335 if (row->reversed_p)
22336 unproduce_glyphs (it, row->used[TEXT_AREA]
22337 - (n_glyphs_before + i));
22338 row->used[TEXT_AREA] = n_glyphs_before + i;
22339 it->current_x = x;
22340 }
22341 break;
22342 }
22343 else if (x + glyph->pixel_width >= it->first_visible_x)
22344 {
22345 /* Glyph is at least partially visible. */
22346 ++it->hpos;
22347 if (x < it->first_visible_x)
22348 row->x = x - it->first_visible_x;
22349 }
22350 else
22351 {
22352 /* Glyph is off the left margin of the display area.
22353 Should not happen. */
22354 emacs_abort ();
22355 }
22356
22357 row->ascent = max (row->ascent, it->max_ascent);
22358 row->height = max (row->height, it->max_ascent + it->max_descent);
22359 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22360 row->phys_height = max (row->phys_height,
22361 it->max_phys_ascent + it->max_phys_descent);
22362 row->extra_line_spacing = max (row->extra_line_spacing,
22363 it->max_extra_line_spacing);
22364 x += glyph->pixel_width;
22365 ++i;
22366 }
22367
22368 /* Stop if max_x reached. */
22369 if (i < nglyphs)
22370 break;
22371
22372 /* Stop at line ends. */
22373 if (ITERATOR_AT_END_OF_LINE_P (it))
22374 {
22375 it->continuation_lines_width = 0;
22376 break;
22377 }
22378
22379 set_iterator_to_next (it, 1);
22380 if (STRINGP (it->string))
22381 it_charpos = IT_STRING_CHARPOS (*it);
22382 else
22383 it_charpos = IT_CHARPOS (*it);
22384
22385 /* Stop if truncating at the right edge. */
22386 if (it->line_wrap == TRUNCATE
22387 && it->current_x >= it->last_visible_x)
22388 {
22389 /* Add truncation mark, but don't do it if the line is
22390 truncated at a padding space. */
22391 if (it_charpos < it->string_nchars)
22392 {
22393 if (!FRAME_WINDOW_P (it->f))
22394 {
22395 int ii, n;
22396
22397 if (it->current_x > it->last_visible_x)
22398 {
22399 if (!row->reversed_p)
22400 {
22401 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22402 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22403 break;
22404 }
22405 else
22406 {
22407 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22408 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22409 break;
22410 unproduce_glyphs (it, ii + 1);
22411 ii = row->used[TEXT_AREA] - (ii + 1);
22412 }
22413 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22414 {
22415 row->used[TEXT_AREA] = ii;
22416 produce_special_glyphs (it, IT_TRUNCATION);
22417 }
22418 }
22419 produce_special_glyphs (it, IT_TRUNCATION);
22420 }
22421 row->truncated_on_right_p = 1;
22422 }
22423 break;
22424 }
22425 }
22426
22427 /* Maybe insert a truncation at the left. */
22428 if (it->first_visible_x
22429 && it_charpos > 0)
22430 {
22431 if (!FRAME_WINDOW_P (it->f)
22432 || (row->reversed_p
22433 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22434 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22435 insert_left_trunc_glyphs (it);
22436 row->truncated_on_left_p = 1;
22437 }
22438
22439 it->face_id = saved_face_id;
22440
22441 /* Value is number of columns displayed. */
22442 return it->hpos - hpos_at_start;
22443 }
22444
22445
22446 \f
22447 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22448 appears as an element of LIST or as the car of an element of LIST.
22449 If PROPVAL is a list, compare each element against LIST in that
22450 way, and return 1/2 if any element of PROPVAL is found in LIST.
22451 Otherwise return 0. This function cannot quit.
22452 The return value is 2 if the text is invisible but with an ellipsis
22453 and 1 if it's invisible and without an ellipsis. */
22454
22455 int
22456 invisible_p (register Lisp_Object propval, Lisp_Object list)
22457 {
22458 register Lisp_Object tail, proptail;
22459
22460 for (tail = list; CONSP (tail); tail = XCDR (tail))
22461 {
22462 register Lisp_Object tem;
22463 tem = XCAR (tail);
22464 if (EQ (propval, tem))
22465 return 1;
22466 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22467 return NILP (XCDR (tem)) ? 1 : 2;
22468 }
22469
22470 if (CONSP (propval))
22471 {
22472 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22473 {
22474 Lisp_Object propelt;
22475 propelt = XCAR (proptail);
22476 for (tail = list; CONSP (tail); tail = XCDR (tail))
22477 {
22478 register Lisp_Object tem;
22479 tem = XCAR (tail);
22480 if (EQ (propelt, tem))
22481 return 1;
22482 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22483 return NILP (XCDR (tem)) ? 1 : 2;
22484 }
22485 }
22486 }
22487
22488 return 0;
22489 }
22490
22491 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22492 doc: /* Non-nil if the property makes the text invisible.
22493 POS-OR-PROP can be a marker or number, in which case it is taken to be
22494 a position in the current buffer and the value of the `invisible' property
22495 is checked; or it can be some other value, which is then presumed to be the
22496 value of the `invisible' property of the text of interest.
22497 The non-nil value returned can be t for truly invisible text or something
22498 else if the text is replaced by an ellipsis. */)
22499 (Lisp_Object pos_or_prop)
22500 {
22501 Lisp_Object prop
22502 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22503 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22504 : pos_or_prop);
22505 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22506 return (invis == 0 ? Qnil
22507 : invis == 1 ? Qt
22508 : make_number (invis));
22509 }
22510
22511 /* Calculate a width or height in pixels from a specification using
22512 the following elements:
22513
22514 SPEC ::=
22515 NUM - a (fractional) multiple of the default font width/height
22516 (NUM) - specifies exactly NUM pixels
22517 UNIT - a fixed number of pixels, see below.
22518 ELEMENT - size of a display element in pixels, see below.
22519 (NUM . SPEC) - equals NUM * SPEC
22520 (+ SPEC SPEC ...) - add pixel values
22521 (- SPEC SPEC ...) - subtract pixel values
22522 (- SPEC) - negate pixel value
22523
22524 NUM ::=
22525 INT or FLOAT - a number constant
22526 SYMBOL - use symbol's (buffer local) variable binding.
22527
22528 UNIT ::=
22529 in - pixels per inch *)
22530 mm - pixels per 1/1000 meter *)
22531 cm - pixels per 1/100 meter *)
22532 width - width of current font in pixels.
22533 height - height of current font in pixels.
22534
22535 *) using the ratio(s) defined in display-pixels-per-inch.
22536
22537 ELEMENT ::=
22538
22539 left-fringe - left fringe width in pixels
22540 right-fringe - right fringe width in pixels
22541
22542 left-margin - left margin width in pixels
22543 right-margin - right margin width in pixels
22544
22545 scroll-bar - scroll-bar area width in pixels
22546
22547 Examples:
22548
22549 Pixels corresponding to 5 inches:
22550 (5 . in)
22551
22552 Total width of non-text areas on left side of window (if scroll-bar is on left):
22553 '(space :width (+ left-fringe left-margin scroll-bar))
22554
22555 Align to first text column (in header line):
22556 '(space :align-to 0)
22557
22558 Align to middle of text area minus half the width of variable `my-image'
22559 containing a loaded image:
22560 '(space :align-to (0.5 . (- text my-image)))
22561
22562 Width of left margin minus width of 1 character in the default font:
22563 '(space :width (- left-margin 1))
22564
22565 Width of left margin minus width of 2 characters in the current font:
22566 '(space :width (- left-margin (2 . width)))
22567
22568 Center 1 character over left-margin (in header line):
22569 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22570
22571 Different ways to express width of left fringe plus left margin minus one pixel:
22572 '(space :width (- (+ left-fringe left-margin) (1)))
22573 '(space :width (+ left-fringe left-margin (- (1))))
22574 '(space :width (+ left-fringe left-margin (-1)))
22575
22576 */
22577
22578 static int
22579 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22580 struct font *font, int width_p, int *align_to)
22581 {
22582 double pixels;
22583
22584 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22585 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22586
22587 if (NILP (prop))
22588 return OK_PIXELS (0);
22589
22590 eassert (FRAME_LIVE_P (it->f));
22591
22592 if (SYMBOLP (prop))
22593 {
22594 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22595 {
22596 char *unit = SSDATA (SYMBOL_NAME (prop));
22597
22598 if (unit[0] == 'i' && unit[1] == 'n')
22599 pixels = 1.0;
22600 else if (unit[0] == 'm' && unit[1] == 'm')
22601 pixels = 25.4;
22602 else if (unit[0] == 'c' && unit[1] == 'm')
22603 pixels = 2.54;
22604 else
22605 pixels = 0;
22606 if (pixels > 0)
22607 {
22608 double ppi = (width_p ? FRAME_RES_X (it->f)
22609 : FRAME_RES_Y (it->f));
22610
22611 if (ppi > 0)
22612 return OK_PIXELS (ppi / pixels);
22613 return 0;
22614 }
22615 }
22616
22617 #ifdef HAVE_WINDOW_SYSTEM
22618 if (EQ (prop, Qheight))
22619 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22620 if (EQ (prop, Qwidth))
22621 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22622 #else
22623 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22624 return OK_PIXELS (1);
22625 #endif
22626
22627 if (EQ (prop, Qtext))
22628 return OK_PIXELS (width_p
22629 ? window_box_width (it->w, TEXT_AREA)
22630 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22631
22632 if (align_to && *align_to < 0)
22633 {
22634 *res = 0;
22635 if (EQ (prop, Qleft))
22636 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22637 if (EQ (prop, Qright))
22638 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22639 if (EQ (prop, Qcenter))
22640 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22641 + window_box_width (it->w, TEXT_AREA) / 2);
22642 if (EQ (prop, Qleft_fringe))
22643 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22644 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22645 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22646 if (EQ (prop, Qright_fringe))
22647 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22648 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22649 : window_box_right_offset (it->w, TEXT_AREA));
22650 if (EQ (prop, Qleft_margin))
22651 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22652 if (EQ (prop, Qright_margin))
22653 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22654 if (EQ (prop, Qscroll_bar))
22655 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22656 ? 0
22657 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22658 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22659 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22660 : 0)));
22661 }
22662 else
22663 {
22664 if (EQ (prop, Qleft_fringe))
22665 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22666 if (EQ (prop, Qright_fringe))
22667 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22668 if (EQ (prop, Qleft_margin))
22669 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22670 if (EQ (prop, Qright_margin))
22671 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22672 if (EQ (prop, Qscroll_bar))
22673 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22674 }
22675
22676 prop = buffer_local_value_1 (prop, it->w->contents);
22677 if (EQ (prop, Qunbound))
22678 prop = Qnil;
22679 }
22680
22681 if (INTEGERP (prop) || FLOATP (prop))
22682 {
22683 int base_unit = (width_p
22684 ? FRAME_COLUMN_WIDTH (it->f)
22685 : FRAME_LINE_HEIGHT (it->f));
22686 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22687 }
22688
22689 if (CONSP (prop))
22690 {
22691 Lisp_Object car = XCAR (prop);
22692 Lisp_Object cdr = XCDR (prop);
22693
22694 if (SYMBOLP (car))
22695 {
22696 #ifdef HAVE_WINDOW_SYSTEM
22697 if (FRAME_WINDOW_P (it->f)
22698 && valid_image_p (prop))
22699 {
22700 ptrdiff_t id = lookup_image (it->f, prop);
22701 struct image *img = IMAGE_FROM_ID (it->f, id);
22702
22703 return OK_PIXELS (width_p ? img->width : img->height);
22704 }
22705 #endif
22706 if (EQ (car, Qplus) || EQ (car, Qminus))
22707 {
22708 int first = 1;
22709 double px;
22710
22711 pixels = 0;
22712 while (CONSP (cdr))
22713 {
22714 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22715 font, width_p, align_to))
22716 return 0;
22717 if (first)
22718 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22719 else
22720 pixels += px;
22721 cdr = XCDR (cdr);
22722 }
22723 if (EQ (car, Qminus))
22724 pixels = -pixels;
22725 return OK_PIXELS (pixels);
22726 }
22727
22728 car = buffer_local_value_1 (car, it->w->contents);
22729 if (EQ (car, Qunbound))
22730 car = Qnil;
22731 }
22732
22733 if (INTEGERP (car) || FLOATP (car))
22734 {
22735 double fact;
22736 pixels = XFLOATINT (car);
22737 if (NILP (cdr))
22738 return OK_PIXELS (pixels);
22739 if (calc_pixel_width_or_height (&fact, it, cdr,
22740 font, width_p, align_to))
22741 return OK_PIXELS (pixels * fact);
22742 return 0;
22743 }
22744
22745 return 0;
22746 }
22747
22748 return 0;
22749 }
22750
22751 \f
22752 /***********************************************************************
22753 Glyph Display
22754 ***********************************************************************/
22755
22756 #ifdef HAVE_WINDOW_SYSTEM
22757
22758 #ifdef GLYPH_DEBUG
22759
22760 void
22761 dump_glyph_string (struct glyph_string *s)
22762 {
22763 fprintf (stderr, "glyph string\n");
22764 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22765 s->x, s->y, s->width, s->height);
22766 fprintf (stderr, " ybase = %d\n", s->ybase);
22767 fprintf (stderr, " hl = %d\n", s->hl);
22768 fprintf (stderr, " left overhang = %d, right = %d\n",
22769 s->left_overhang, s->right_overhang);
22770 fprintf (stderr, " nchars = %d\n", s->nchars);
22771 fprintf (stderr, " extends to end of line = %d\n",
22772 s->extends_to_end_of_line_p);
22773 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22774 fprintf (stderr, " bg width = %d\n", s->background_width);
22775 }
22776
22777 #endif /* GLYPH_DEBUG */
22778
22779 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22780 of XChar2b structures for S; it can't be allocated in
22781 init_glyph_string because it must be allocated via `alloca'. W
22782 is the window on which S is drawn. ROW and AREA are the glyph row
22783 and area within the row from which S is constructed. START is the
22784 index of the first glyph structure covered by S. HL is a
22785 face-override for drawing S. */
22786
22787 #ifdef HAVE_NTGUI
22788 #define OPTIONAL_HDC(hdc) HDC hdc,
22789 #define DECLARE_HDC(hdc) HDC hdc;
22790 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22791 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22792 #endif
22793
22794 #ifndef OPTIONAL_HDC
22795 #define OPTIONAL_HDC(hdc)
22796 #define DECLARE_HDC(hdc)
22797 #define ALLOCATE_HDC(hdc, f)
22798 #define RELEASE_HDC(hdc, f)
22799 #endif
22800
22801 static void
22802 init_glyph_string (struct glyph_string *s,
22803 OPTIONAL_HDC (hdc)
22804 XChar2b *char2b, struct window *w, struct glyph_row *row,
22805 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22806 {
22807 memset (s, 0, sizeof *s);
22808 s->w = w;
22809 s->f = XFRAME (w->frame);
22810 #ifdef HAVE_NTGUI
22811 s->hdc = hdc;
22812 #endif
22813 s->display = FRAME_X_DISPLAY (s->f);
22814 s->window = FRAME_X_WINDOW (s->f);
22815 s->char2b = char2b;
22816 s->hl = hl;
22817 s->row = row;
22818 s->area = area;
22819 s->first_glyph = row->glyphs[area] + start;
22820 s->height = row->height;
22821 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22822 s->ybase = s->y + row->ascent;
22823 }
22824
22825
22826 /* Append the list of glyph strings with head H and tail T to the list
22827 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22828
22829 static void
22830 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22831 struct glyph_string *h, struct glyph_string *t)
22832 {
22833 if (h)
22834 {
22835 if (*head)
22836 (*tail)->next = h;
22837 else
22838 *head = h;
22839 h->prev = *tail;
22840 *tail = t;
22841 }
22842 }
22843
22844
22845 /* Prepend the list of glyph strings with head H and tail T to the
22846 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22847 result. */
22848
22849 static void
22850 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22851 struct glyph_string *h, struct glyph_string *t)
22852 {
22853 if (h)
22854 {
22855 if (*head)
22856 (*head)->prev = t;
22857 else
22858 *tail = t;
22859 t->next = *head;
22860 *head = h;
22861 }
22862 }
22863
22864
22865 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22866 Set *HEAD and *TAIL to the resulting list. */
22867
22868 static void
22869 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22870 struct glyph_string *s)
22871 {
22872 s->next = s->prev = NULL;
22873 append_glyph_string_lists (head, tail, s, s);
22874 }
22875
22876
22877 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22878 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22879 make sure that X resources for the face returned are allocated.
22880 Value is a pointer to a realized face that is ready for display if
22881 DISPLAY_P is non-zero. */
22882
22883 static struct face *
22884 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22885 XChar2b *char2b, int display_p)
22886 {
22887 struct face *face = FACE_FROM_ID (f, face_id);
22888 unsigned code = 0;
22889
22890 if (face->font)
22891 {
22892 code = face->font->driver->encode_char (face->font, c);
22893
22894 if (code == FONT_INVALID_CODE)
22895 code = 0;
22896 }
22897 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22898
22899 /* Make sure X resources of the face are allocated. */
22900 #ifdef HAVE_X_WINDOWS
22901 if (display_p)
22902 #endif
22903 {
22904 eassert (face != NULL);
22905 PREPARE_FACE_FOR_DISPLAY (f, face);
22906 }
22907
22908 return face;
22909 }
22910
22911
22912 /* Get face and two-byte form of character glyph GLYPH on frame F.
22913 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22914 a pointer to a realized face that is ready for display. */
22915
22916 static struct face *
22917 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22918 XChar2b *char2b, int *two_byte_p)
22919 {
22920 struct face *face;
22921 unsigned code = 0;
22922
22923 eassert (glyph->type == CHAR_GLYPH);
22924 face = FACE_FROM_ID (f, glyph->face_id);
22925
22926 /* Make sure X resources of the face are allocated. */
22927 eassert (face != NULL);
22928 PREPARE_FACE_FOR_DISPLAY (f, face);
22929
22930 if (two_byte_p)
22931 *two_byte_p = 0;
22932
22933 if (face->font)
22934 {
22935 if (CHAR_BYTE8_P (glyph->u.ch))
22936 code = CHAR_TO_BYTE8 (glyph->u.ch);
22937 else
22938 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22939
22940 if (code == FONT_INVALID_CODE)
22941 code = 0;
22942 }
22943
22944 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22945 return face;
22946 }
22947
22948
22949 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22950 Return 1 if FONT has a glyph for C, otherwise return 0. */
22951
22952 static int
22953 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22954 {
22955 unsigned code;
22956
22957 if (CHAR_BYTE8_P (c))
22958 code = CHAR_TO_BYTE8 (c);
22959 else
22960 code = font->driver->encode_char (font, c);
22961
22962 if (code == FONT_INVALID_CODE)
22963 return 0;
22964 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22965 return 1;
22966 }
22967
22968
22969 /* Fill glyph string S with composition components specified by S->cmp.
22970
22971 BASE_FACE is the base face of the composition.
22972 S->cmp_from is the index of the first component for S.
22973
22974 OVERLAPS non-zero means S should draw the foreground only, and use
22975 its physical height for clipping. See also draw_glyphs.
22976
22977 Value is the index of a component not in S. */
22978
22979 static int
22980 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22981 int overlaps)
22982 {
22983 int i;
22984 /* For all glyphs of this composition, starting at the offset
22985 S->cmp_from, until we reach the end of the definition or encounter a
22986 glyph that requires the different face, add it to S. */
22987 struct face *face;
22988
22989 eassert (s);
22990
22991 s->for_overlaps = overlaps;
22992 s->face = NULL;
22993 s->font = NULL;
22994 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22995 {
22996 int c = COMPOSITION_GLYPH (s->cmp, i);
22997
22998 /* TAB in a composition means display glyphs with padding space
22999 on the left or right. */
23000 if (c != '\t')
23001 {
23002 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23003 -1, Qnil);
23004
23005 face = get_char_face_and_encoding (s->f, c, face_id,
23006 s->char2b + i, 1);
23007 if (face)
23008 {
23009 if (! s->face)
23010 {
23011 s->face = face;
23012 s->font = s->face->font;
23013 }
23014 else if (s->face != face)
23015 break;
23016 }
23017 }
23018 ++s->nchars;
23019 }
23020 s->cmp_to = i;
23021
23022 if (s->face == NULL)
23023 {
23024 s->face = base_face->ascii_face;
23025 s->font = s->face->font;
23026 }
23027
23028 /* All glyph strings for the same composition has the same width,
23029 i.e. the width set for the first component of the composition. */
23030 s->width = s->first_glyph->pixel_width;
23031
23032 /* If the specified font could not be loaded, use the frame's
23033 default font, but record the fact that we couldn't load it in
23034 the glyph string so that we can draw rectangles for the
23035 characters of the glyph string. */
23036 if (s->font == NULL)
23037 {
23038 s->font_not_found_p = 1;
23039 s->font = FRAME_FONT (s->f);
23040 }
23041
23042 /* Adjust base line for subscript/superscript text. */
23043 s->ybase += s->first_glyph->voffset;
23044
23045 /* This glyph string must always be drawn with 16-bit functions. */
23046 s->two_byte_p = 1;
23047
23048 return s->cmp_to;
23049 }
23050
23051 static int
23052 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
23053 int start, int end, int overlaps)
23054 {
23055 struct glyph *glyph, *last;
23056 Lisp_Object lgstring;
23057 int i;
23058
23059 s->for_overlaps = overlaps;
23060 glyph = s->row->glyphs[s->area] + start;
23061 last = s->row->glyphs[s->area] + end;
23062 s->cmp_id = glyph->u.cmp.id;
23063 s->cmp_from = glyph->slice.cmp.from;
23064 s->cmp_to = glyph->slice.cmp.to + 1;
23065 s->face = FACE_FROM_ID (s->f, face_id);
23066 lgstring = composition_gstring_from_id (s->cmp_id);
23067 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
23068 glyph++;
23069 while (glyph < last
23070 && glyph->u.cmp.automatic
23071 && glyph->u.cmp.id == s->cmp_id
23072 && s->cmp_to == glyph->slice.cmp.from)
23073 s->cmp_to = (glyph++)->slice.cmp.to + 1;
23074
23075 for (i = s->cmp_from; i < s->cmp_to; i++)
23076 {
23077 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
23078 unsigned code = LGLYPH_CODE (lglyph);
23079
23080 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
23081 }
23082 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
23083 return glyph - s->row->glyphs[s->area];
23084 }
23085
23086
23087 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23088 See the comment of fill_glyph_string for arguments.
23089 Value is the index of the first glyph not in S. */
23090
23091
23092 static int
23093 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
23094 int start, int end, int overlaps)
23095 {
23096 struct glyph *glyph, *last;
23097 int voffset;
23098
23099 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
23100 s->for_overlaps = overlaps;
23101 glyph = s->row->glyphs[s->area] + start;
23102 last = s->row->glyphs[s->area] + end;
23103 voffset = glyph->voffset;
23104 s->face = FACE_FROM_ID (s->f, face_id);
23105 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
23106 s->nchars = 1;
23107 s->width = glyph->pixel_width;
23108 glyph++;
23109 while (glyph < last
23110 && glyph->type == GLYPHLESS_GLYPH
23111 && glyph->voffset == voffset
23112 && glyph->face_id == face_id)
23113 {
23114 s->nchars++;
23115 s->width += glyph->pixel_width;
23116 glyph++;
23117 }
23118 s->ybase += voffset;
23119 return glyph - s->row->glyphs[s->area];
23120 }
23121
23122
23123 /* Fill glyph string S from a sequence of character glyphs.
23124
23125 FACE_ID is the face id of the string. START is the index of the
23126 first glyph to consider, END is the index of the last + 1.
23127 OVERLAPS non-zero means S should draw the foreground only, and use
23128 its physical height for clipping. See also draw_glyphs.
23129
23130 Value is the index of the first glyph not in S. */
23131
23132 static int
23133 fill_glyph_string (struct glyph_string *s, int face_id,
23134 int start, int end, int overlaps)
23135 {
23136 struct glyph *glyph, *last;
23137 int voffset;
23138 int glyph_not_available_p;
23139
23140 eassert (s->f == XFRAME (s->w->frame));
23141 eassert (s->nchars == 0);
23142 eassert (start >= 0 && end > start);
23143
23144 s->for_overlaps = overlaps;
23145 glyph = s->row->glyphs[s->area] + start;
23146 last = s->row->glyphs[s->area] + end;
23147 voffset = glyph->voffset;
23148 s->padding_p = glyph->padding_p;
23149 glyph_not_available_p = glyph->glyph_not_available_p;
23150
23151 while (glyph < last
23152 && glyph->type == CHAR_GLYPH
23153 && glyph->voffset == voffset
23154 /* Same face id implies same font, nowadays. */
23155 && glyph->face_id == face_id
23156 && glyph->glyph_not_available_p == glyph_not_available_p)
23157 {
23158 int two_byte_p;
23159
23160 s->face = get_glyph_face_and_encoding (s->f, glyph,
23161 s->char2b + s->nchars,
23162 &two_byte_p);
23163 s->two_byte_p = two_byte_p;
23164 ++s->nchars;
23165 eassert (s->nchars <= end - start);
23166 s->width += glyph->pixel_width;
23167 if (glyph++->padding_p != s->padding_p)
23168 break;
23169 }
23170
23171 s->font = s->face->font;
23172
23173 /* If the specified font could not be loaded, use the frame's font,
23174 but record the fact that we couldn't load it in
23175 S->font_not_found_p so that we can draw rectangles for the
23176 characters of the glyph string. */
23177 if (s->font == NULL || glyph_not_available_p)
23178 {
23179 s->font_not_found_p = 1;
23180 s->font = FRAME_FONT (s->f);
23181 }
23182
23183 /* Adjust base line for subscript/superscript text. */
23184 s->ybase += voffset;
23185
23186 eassert (s->face && s->face->gc);
23187 return glyph - s->row->glyphs[s->area];
23188 }
23189
23190
23191 /* Fill glyph string S from image glyph S->first_glyph. */
23192
23193 static void
23194 fill_image_glyph_string (struct glyph_string *s)
23195 {
23196 eassert (s->first_glyph->type == IMAGE_GLYPH);
23197 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
23198 eassert (s->img);
23199 s->slice = s->first_glyph->slice.img;
23200 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
23201 s->font = s->face->font;
23202 s->width = s->first_glyph->pixel_width;
23203
23204 /* Adjust base line for subscript/superscript text. */
23205 s->ybase += s->first_glyph->voffset;
23206 }
23207
23208
23209 /* Fill glyph string S from a sequence of stretch glyphs.
23210
23211 START is the index of the first glyph to consider,
23212 END is the index of the last + 1.
23213
23214 Value is the index of the first glyph not in S. */
23215
23216 static int
23217 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23218 {
23219 struct glyph *glyph, *last;
23220 int voffset, face_id;
23221
23222 eassert (s->first_glyph->type == STRETCH_GLYPH);
23223
23224 glyph = s->row->glyphs[s->area] + start;
23225 last = s->row->glyphs[s->area] + end;
23226 face_id = glyph->face_id;
23227 s->face = FACE_FROM_ID (s->f, face_id);
23228 s->font = s->face->font;
23229 s->width = glyph->pixel_width;
23230 s->nchars = 1;
23231 voffset = glyph->voffset;
23232
23233 for (++glyph;
23234 (glyph < last
23235 && glyph->type == STRETCH_GLYPH
23236 && glyph->voffset == voffset
23237 && glyph->face_id == face_id);
23238 ++glyph)
23239 s->width += glyph->pixel_width;
23240
23241 /* Adjust base line for subscript/superscript text. */
23242 s->ybase += voffset;
23243
23244 /* The case that face->gc == 0 is handled when drawing the glyph
23245 string by calling PREPARE_FACE_FOR_DISPLAY. */
23246 eassert (s->face);
23247 return glyph - s->row->glyphs[s->area];
23248 }
23249
23250 static struct font_metrics *
23251 get_per_char_metric (struct font *font, XChar2b *char2b)
23252 {
23253 static struct font_metrics metrics;
23254 unsigned code;
23255
23256 if (! font)
23257 return NULL;
23258 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23259 if (code == FONT_INVALID_CODE)
23260 return NULL;
23261 font->driver->text_extents (font, &code, 1, &metrics);
23262 return &metrics;
23263 }
23264
23265 /* EXPORT for RIF:
23266 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23267 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23268 assumed to be zero. */
23269
23270 void
23271 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23272 {
23273 *left = *right = 0;
23274
23275 if (glyph->type == CHAR_GLYPH)
23276 {
23277 struct face *face;
23278 XChar2b char2b;
23279 struct font_metrics *pcm;
23280
23281 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23282 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23283 {
23284 if (pcm->rbearing > pcm->width)
23285 *right = pcm->rbearing - pcm->width;
23286 if (pcm->lbearing < 0)
23287 *left = -pcm->lbearing;
23288 }
23289 }
23290 else if (glyph->type == COMPOSITE_GLYPH)
23291 {
23292 if (! glyph->u.cmp.automatic)
23293 {
23294 struct composition *cmp = composition_table[glyph->u.cmp.id];
23295
23296 if (cmp->rbearing > cmp->pixel_width)
23297 *right = cmp->rbearing - cmp->pixel_width;
23298 if (cmp->lbearing < 0)
23299 *left = - cmp->lbearing;
23300 }
23301 else
23302 {
23303 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23304 struct font_metrics metrics;
23305
23306 composition_gstring_width (gstring, glyph->slice.cmp.from,
23307 glyph->slice.cmp.to + 1, &metrics);
23308 if (metrics.rbearing > metrics.width)
23309 *right = metrics.rbearing - metrics.width;
23310 if (metrics.lbearing < 0)
23311 *left = - metrics.lbearing;
23312 }
23313 }
23314 }
23315
23316
23317 /* Return the index of the first glyph preceding glyph string S that
23318 is overwritten by S because of S's left overhang. Value is -1
23319 if no glyphs are overwritten. */
23320
23321 static int
23322 left_overwritten (struct glyph_string *s)
23323 {
23324 int k;
23325
23326 if (s->left_overhang)
23327 {
23328 int x = 0, i;
23329 struct glyph *glyphs = s->row->glyphs[s->area];
23330 int first = s->first_glyph - glyphs;
23331
23332 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23333 x -= glyphs[i].pixel_width;
23334
23335 k = i + 1;
23336 }
23337 else
23338 k = -1;
23339
23340 return k;
23341 }
23342
23343
23344 /* Return the index of the first glyph preceding glyph string S that
23345 is overwriting S because of its right overhang. Value is -1 if no
23346 glyph in front of S overwrites S. */
23347
23348 static int
23349 left_overwriting (struct glyph_string *s)
23350 {
23351 int i, k, x;
23352 struct glyph *glyphs = s->row->glyphs[s->area];
23353 int first = s->first_glyph - glyphs;
23354
23355 k = -1;
23356 x = 0;
23357 for (i = first - 1; i >= 0; --i)
23358 {
23359 int left, right;
23360 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23361 if (x + right > 0)
23362 k = i;
23363 x -= glyphs[i].pixel_width;
23364 }
23365
23366 return k;
23367 }
23368
23369
23370 /* Return the index of the last glyph following glyph string S that is
23371 overwritten by S because of S's right overhang. Value is -1 if
23372 no such glyph is found. */
23373
23374 static int
23375 right_overwritten (struct glyph_string *s)
23376 {
23377 int k = -1;
23378
23379 if (s->right_overhang)
23380 {
23381 int x = 0, i;
23382 struct glyph *glyphs = s->row->glyphs[s->area];
23383 int first = (s->first_glyph - glyphs
23384 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23385 int end = s->row->used[s->area];
23386
23387 for (i = first; i < end && s->right_overhang > x; ++i)
23388 x += glyphs[i].pixel_width;
23389
23390 k = i;
23391 }
23392
23393 return k;
23394 }
23395
23396
23397 /* Return the index of the last glyph following glyph string S that
23398 overwrites S because of its left overhang. Value is negative
23399 if no such glyph is found. */
23400
23401 static int
23402 right_overwriting (struct glyph_string *s)
23403 {
23404 int i, k, x;
23405 int end = s->row->used[s->area];
23406 struct glyph *glyphs = s->row->glyphs[s->area];
23407 int first = (s->first_glyph - glyphs
23408 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23409
23410 k = -1;
23411 x = 0;
23412 for (i = first; i < end; ++i)
23413 {
23414 int left, right;
23415 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23416 if (x - left < 0)
23417 k = i;
23418 x += glyphs[i].pixel_width;
23419 }
23420
23421 return k;
23422 }
23423
23424
23425 /* Set background width of glyph string S. START is the index of the
23426 first glyph following S. LAST_X is the right-most x-position + 1
23427 in the drawing area. */
23428
23429 static void
23430 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23431 {
23432 /* If the face of this glyph string has to be drawn to the end of
23433 the drawing area, set S->extends_to_end_of_line_p. */
23434
23435 if (start == s->row->used[s->area]
23436 && s->area == TEXT_AREA
23437 && ((s->row->fill_line_p
23438 && (s->hl == DRAW_NORMAL_TEXT
23439 || s->hl == DRAW_IMAGE_RAISED
23440 || s->hl == DRAW_IMAGE_SUNKEN))
23441 || s->hl == DRAW_MOUSE_FACE))
23442 s->extends_to_end_of_line_p = 1;
23443
23444 /* If S extends its face to the end of the line, set its
23445 background_width to the distance to the right edge of the drawing
23446 area. */
23447 if (s->extends_to_end_of_line_p)
23448 s->background_width = last_x - s->x + 1;
23449 else
23450 s->background_width = s->width;
23451 }
23452
23453
23454 /* Compute overhangs and x-positions for glyph string S and its
23455 predecessors, or successors. X is the starting x-position for S.
23456 BACKWARD_P non-zero means process predecessors. */
23457
23458 static void
23459 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23460 {
23461 if (backward_p)
23462 {
23463 while (s)
23464 {
23465 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23466 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23467 x -= s->width;
23468 s->x = x;
23469 s = s->prev;
23470 }
23471 }
23472 else
23473 {
23474 while (s)
23475 {
23476 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23477 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23478 s->x = x;
23479 x += s->width;
23480 s = s->next;
23481 }
23482 }
23483 }
23484
23485
23486
23487 /* The following macros are only called from draw_glyphs below.
23488 They reference the following parameters of that function directly:
23489 `w', `row', `area', and `overlap_p'
23490 as well as the following local variables:
23491 `s', `f', and `hdc' (in W32) */
23492
23493 #ifdef HAVE_NTGUI
23494 /* On W32, silently add local `hdc' variable to argument list of
23495 init_glyph_string. */
23496 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23497 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23498 #else
23499 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23500 init_glyph_string (s, char2b, w, row, area, start, hl)
23501 #endif
23502
23503 /* Add a glyph string for a stretch glyph to the list of strings
23504 between HEAD and TAIL. START is the index of the stretch glyph in
23505 row area AREA of glyph row ROW. END is the index of the last glyph
23506 in that glyph row area. X is the current output position assigned
23507 to the new glyph string constructed. HL overrides that face of the
23508 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23509 is the right-most x-position of the drawing area. */
23510
23511 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23512 and below -- keep them on one line. */
23513 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23514 do \
23515 { \
23516 s = alloca (sizeof *s); \
23517 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23518 START = fill_stretch_glyph_string (s, START, END); \
23519 append_glyph_string (&HEAD, &TAIL, s); \
23520 s->x = (X); \
23521 } \
23522 while (0)
23523
23524
23525 /* Add a glyph string for an image glyph to the list of strings
23526 between HEAD and TAIL. START is the index of the image glyph in
23527 row area AREA of glyph row ROW. END is the index of the last glyph
23528 in that glyph row area. X is the current output position assigned
23529 to the new glyph string constructed. HL overrides that face of the
23530 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23531 is the right-most x-position of the drawing area. */
23532
23533 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23534 do \
23535 { \
23536 s = alloca (sizeof *s); \
23537 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23538 fill_image_glyph_string (s); \
23539 append_glyph_string (&HEAD, &TAIL, s); \
23540 ++START; \
23541 s->x = (X); \
23542 } \
23543 while (0)
23544
23545
23546 /* Add a glyph string for a sequence of character glyphs to the list
23547 of strings between HEAD and TAIL. START is the index of the first
23548 glyph in row area AREA of glyph row ROW that is part of the new
23549 glyph string. END is the index of the last glyph in that glyph row
23550 area. X is the current output position assigned to the new glyph
23551 string constructed. HL overrides that face of the glyph; e.g. it
23552 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23553 right-most x-position of the drawing area. */
23554
23555 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23556 do \
23557 { \
23558 int face_id; \
23559 XChar2b *char2b; \
23560 \
23561 face_id = (row)->glyphs[area][START].face_id; \
23562 \
23563 s = alloca (sizeof *s); \
23564 char2b = alloca ((END - START) * sizeof *char2b); \
23565 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23566 append_glyph_string (&HEAD, &TAIL, s); \
23567 s->x = (X); \
23568 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23569 } \
23570 while (0)
23571
23572
23573 /* Add a glyph string for a composite sequence to the list of strings
23574 between HEAD and TAIL. START is the index of the first glyph in
23575 row area AREA of glyph row ROW that is part of the new glyph
23576 string. END is the index of the last glyph in that glyph row area.
23577 X is the current output position assigned to the new glyph string
23578 constructed. HL overrides that face of the glyph; e.g. it is
23579 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23580 x-position of the drawing area. */
23581
23582 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23583 do { \
23584 int face_id = (row)->glyphs[area][START].face_id; \
23585 struct face *base_face = FACE_FROM_ID (f, face_id); \
23586 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23587 struct composition *cmp = composition_table[cmp_id]; \
23588 XChar2b *char2b; \
23589 struct glyph_string *first_s = NULL; \
23590 int n; \
23591 \
23592 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23593 \
23594 /* Make glyph_strings for each glyph sequence that is drawable by \
23595 the same face, and append them to HEAD/TAIL. */ \
23596 for (n = 0; n < cmp->glyph_len;) \
23597 { \
23598 s = alloca (sizeof *s); \
23599 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23600 append_glyph_string (&(HEAD), &(TAIL), s); \
23601 s->cmp = cmp; \
23602 s->cmp_from = n; \
23603 s->x = (X); \
23604 if (n == 0) \
23605 first_s = s; \
23606 n = fill_composite_glyph_string (s, base_face, overlaps); \
23607 } \
23608 \
23609 ++START; \
23610 s = first_s; \
23611 } while (0)
23612
23613
23614 /* Add a glyph string for a glyph-string sequence to the list of strings
23615 between HEAD and TAIL. */
23616
23617 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23618 do { \
23619 int face_id; \
23620 XChar2b *char2b; \
23621 Lisp_Object gstring; \
23622 \
23623 face_id = (row)->glyphs[area][START].face_id; \
23624 gstring = (composition_gstring_from_id \
23625 ((row)->glyphs[area][START].u.cmp.id)); \
23626 s = alloca (sizeof *s); \
23627 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23628 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23629 append_glyph_string (&(HEAD), &(TAIL), s); \
23630 s->x = (X); \
23631 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23632 } while (0)
23633
23634
23635 /* Add a glyph string for a sequence of glyphless character's glyphs
23636 to the list of strings between HEAD and TAIL. The meanings of
23637 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23638
23639 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23640 do \
23641 { \
23642 int face_id; \
23643 \
23644 face_id = (row)->glyphs[area][START].face_id; \
23645 \
23646 s = alloca (sizeof *s); \
23647 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23648 append_glyph_string (&HEAD, &TAIL, s); \
23649 s->x = (X); \
23650 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23651 overlaps); \
23652 } \
23653 while (0)
23654
23655
23656 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23657 of AREA of glyph row ROW on window W between indices START and END.
23658 HL overrides the face for drawing glyph strings, e.g. it is
23659 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23660 x-positions of the drawing area.
23661
23662 This is an ugly monster macro construct because we must use alloca
23663 to allocate glyph strings (because draw_glyphs can be called
23664 asynchronously). */
23665
23666 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23667 do \
23668 { \
23669 HEAD = TAIL = NULL; \
23670 while (START < END) \
23671 { \
23672 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23673 switch (first_glyph->type) \
23674 { \
23675 case CHAR_GLYPH: \
23676 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23677 HL, X, LAST_X); \
23678 break; \
23679 \
23680 case COMPOSITE_GLYPH: \
23681 if (first_glyph->u.cmp.automatic) \
23682 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23683 HL, X, LAST_X); \
23684 else \
23685 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23686 HL, X, LAST_X); \
23687 break; \
23688 \
23689 case STRETCH_GLYPH: \
23690 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23691 HL, X, LAST_X); \
23692 break; \
23693 \
23694 case IMAGE_GLYPH: \
23695 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23696 HL, X, LAST_X); \
23697 break; \
23698 \
23699 case GLYPHLESS_GLYPH: \
23700 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23701 HL, X, LAST_X); \
23702 break; \
23703 \
23704 default: \
23705 emacs_abort (); \
23706 } \
23707 \
23708 if (s) \
23709 { \
23710 set_glyph_string_background_width (s, START, LAST_X); \
23711 (X) += s->width; \
23712 } \
23713 } \
23714 } while (0)
23715
23716
23717 /* Draw glyphs between START and END in AREA of ROW on window W,
23718 starting at x-position X. X is relative to AREA in W. HL is a
23719 face-override with the following meaning:
23720
23721 DRAW_NORMAL_TEXT draw normally
23722 DRAW_CURSOR draw in cursor face
23723 DRAW_MOUSE_FACE draw in mouse face.
23724 DRAW_INVERSE_VIDEO draw in mode line face
23725 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23726 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23727
23728 If OVERLAPS is non-zero, draw only the foreground of characters and
23729 clip to the physical height of ROW. Non-zero value also defines
23730 the overlapping part to be drawn:
23731
23732 OVERLAPS_PRED overlap with preceding rows
23733 OVERLAPS_SUCC overlap with succeeding rows
23734 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23735 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23736
23737 Value is the x-position reached, relative to AREA of W. */
23738
23739 static int
23740 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23741 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23742 enum draw_glyphs_face hl, int overlaps)
23743 {
23744 struct glyph_string *head, *tail;
23745 struct glyph_string *s;
23746 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23747 int i, j, x_reached, last_x, area_left = 0;
23748 struct frame *f = XFRAME (WINDOW_FRAME (w));
23749 DECLARE_HDC (hdc);
23750
23751 ALLOCATE_HDC (hdc, f);
23752
23753 /* Let's rather be paranoid than getting a SEGV. */
23754 end = min (end, row->used[area]);
23755 start = clip_to_bounds (0, start, end);
23756
23757 /* Translate X to frame coordinates. Set last_x to the right
23758 end of the drawing area. */
23759 if (row->full_width_p)
23760 {
23761 /* X is relative to the left edge of W, without scroll bars
23762 or fringes. */
23763 area_left = WINDOW_LEFT_EDGE_X (w);
23764 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23765 }
23766 else
23767 {
23768 area_left = window_box_left (w, area);
23769 last_x = area_left + window_box_width (w, area);
23770 }
23771 x += area_left;
23772
23773 /* Build a doubly-linked list of glyph_string structures between
23774 head and tail from what we have to draw. Note that the macro
23775 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23776 the reason we use a separate variable `i'. */
23777 i = start;
23778 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23779 if (tail)
23780 x_reached = tail->x + tail->background_width;
23781 else
23782 x_reached = x;
23783
23784 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23785 the row, redraw some glyphs in front or following the glyph
23786 strings built above. */
23787 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23788 {
23789 struct glyph_string *h, *t;
23790 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23791 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23792 int check_mouse_face = 0;
23793 int dummy_x = 0;
23794
23795 /* If mouse highlighting is on, we may need to draw adjacent
23796 glyphs using mouse-face highlighting. */
23797 if (area == TEXT_AREA && row->mouse_face_p
23798 && hlinfo->mouse_face_beg_row >= 0
23799 && hlinfo->mouse_face_end_row >= 0)
23800 {
23801 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
23802
23803 if (row_vpos >= hlinfo->mouse_face_beg_row
23804 && row_vpos <= hlinfo->mouse_face_end_row)
23805 {
23806 check_mouse_face = 1;
23807 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
23808 ? hlinfo->mouse_face_beg_col : 0;
23809 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
23810 ? hlinfo->mouse_face_end_col
23811 : row->used[TEXT_AREA];
23812 }
23813 }
23814
23815 /* Compute overhangs for all glyph strings. */
23816 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23817 for (s = head; s; s = s->next)
23818 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23819
23820 /* Prepend glyph strings for glyphs in front of the first glyph
23821 string that are overwritten because of the first glyph
23822 string's left overhang. The background of all strings
23823 prepended must be drawn because the first glyph string
23824 draws over it. */
23825 i = left_overwritten (head);
23826 if (i >= 0)
23827 {
23828 enum draw_glyphs_face overlap_hl;
23829
23830 /* If this row contains mouse highlighting, attempt to draw
23831 the overlapped glyphs with the correct highlight. This
23832 code fails if the overlap encompasses more than one glyph
23833 and mouse-highlight spans only some of these glyphs.
23834 However, making it work perfectly involves a lot more
23835 code, and I don't know if the pathological case occurs in
23836 practice, so we'll stick to this for now. --- cyd */
23837 if (check_mouse_face
23838 && mouse_beg_col < start && mouse_end_col > i)
23839 overlap_hl = DRAW_MOUSE_FACE;
23840 else
23841 overlap_hl = DRAW_NORMAL_TEXT;
23842
23843 j = i;
23844 BUILD_GLYPH_STRINGS (j, start, h, t,
23845 overlap_hl, dummy_x, last_x);
23846 start = i;
23847 compute_overhangs_and_x (t, head->x, 1);
23848 prepend_glyph_string_lists (&head, &tail, h, t);
23849 clip_head = head;
23850 }
23851
23852 /* Prepend glyph strings for glyphs in front of the first glyph
23853 string that overwrite that glyph string because of their
23854 right overhang. For these strings, only the foreground must
23855 be drawn, because it draws over the glyph string at `head'.
23856 The background must not be drawn because this would overwrite
23857 right overhangs of preceding glyphs for which no glyph
23858 strings exist. */
23859 i = left_overwriting (head);
23860 if (i >= 0)
23861 {
23862 enum draw_glyphs_face overlap_hl;
23863
23864 if (check_mouse_face
23865 && mouse_beg_col < start && mouse_end_col > i)
23866 overlap_hl = DRAW_MOUSE_FACE;
23867 else
23868 overlap_hl = DRAW_NORMAL_TEXT;
23869
23870 clip_head = head;
23871 BUILD_GLYPH_STRINGS (i, start, h, t,
23872 overlap_hl, dummy_x, last_x);
23873 for (s = h; s; s = s->next)
23874 s->background_filled_p = 1;
23875 compute_overhangs_and_x (t, head->x, 1);
23876 prepend_glyph_string_lists (&head, &tail, h, t);
23877 }
23878
23879 /* Append glyphs strings for glyphs following the last glyph
23880 string tail that are overwritten by tail. The background of
23881 these strings has to be drawn because tail's foreground draws
23882 over it. */
23883 i = right_overwritten (tail);
23884 if (i >= 0)
23885 {
23886 enum draw_glyphs_face overlap_hl;
23887
23888 if (check_mouse_face
23889 && mouse_beg_col < i && mouse_end_col > end)
23890 overlap_hl = DRAW_MOUSE_FACE;
23891 else
23892 overlap_hl = DRAW_NORMAL_TEXT;
23893
23894 BUILD_GLYPH_STRINGS (end, i, h, t,
23895 overlap_hl, x, last_x);
23896 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23897 we don't have `end = i;' here. */
23898 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23899 append_glyph_string_lists (&head, &tail, h, t);
23900 clip_tail = tail;
23901 }
23902
23903 /* Append glyph strings for glyphs following the last glyph
23904 string tail that overwrite tail. The foreground of such
23905 glyphs has to be drawn because it writes into the background
23906 of tail. The background must not be drawn because it could
23907 paint over the foreground of following glyphs. */
23908 i = right_overwriting (tail);
23909 if (i >= 0)
23910 {
23911 enum draw_glyphs_face overlap_hl;
23912 if (check_mouse_face
23913 && mouse_beg_col < i && mouse_end_col > end)
23914 overlap_hl = DRAW_MOUSE_FACE;
23915 else
23916 overlap_hl = DRAW_NORMAL_TEXT;
23917
23918 clip_tail = tail;
23919 i++; /* We must include the Ith glyph. */
23920 BUILD_GLYPH_STRINGS (end, i, h, t,
23921 overlap_hl, x, last_x);
23922 for (s = h; s; s = s->next)
23923 s->background_filled_p = 1;
23924 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23925 append_glyph_string_lists (&head, &tail, h, t);
23926 }
23927 if (clip_head || clip_tail)
23928 for (s = head; s; s = s->next)
23929 {
23930 s->clip_head = clip_head;
23931 s->clip_tail = clip_tail;
23932 }
23933 }
23934
23935 /* Draw all strings. */
23936 for (s = head; s; s = s->next)
23937 FRAME_RIF (f)->draw_glyph_string (s);
23938
23939 #ifndef HAVE_NS
23940 /* When focus a sole frame and move horizontally, this sets on_p to 0
23941 causing a failure to erase prev cursor position. */
23942 if (area == TEXT_AREA
23943 && !row->full_width_p
23944 /* When drawing overlapping rows, only the glyph strings'
23945 foreground is drawn, which doesn't erase a cursor
23946 completely. */
23947 && !overlaps)
23948 {
23949 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23950 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23951 : (tail ? tail->x + tail->background_width : x));
23952 x0 -= area_left;
23953 x1 -= area_left;
23954
23955 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23956 row->y, MATRIX_ROW_BOTTOM_Y (row));
23957 }
23958 #endif
23959
23960 /* Value is the x-position up to which drawn, relative to AREA of W.
23961 This doesn't include parts drawn because of overhangs. */
23962 if (row->full_width_p)
23963 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23964 else
23965 x_reached -= area_left;
23966
23967 RELEASE_HDC (hdc, f);
23968
23969 return x_reached;
23970 }
23971
23972 /* Expand row matrix if too narrow. Don't expand if area
23973 is not present. */
23974
23975 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23976 { \
23977 if (!it->f->fonts_changed \
23978 && (it->glyph_row->glyphs[area] \
23979 < it->glyph_row->glyphs[area + 1])) \
23980 { \
23981 it->w->ncols_scale_factor++; \
23982 it->f->fonts_changed = 1; \
23983 } \
23984 }
23985
23986 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23987 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23988
23989 static void
23990 append_glyph (struct it *it)
23991 {
23992 struct glyph *glyph;
23993 enum glyph_row_area area = it->area;
23994
23995 eassert (it->glyph_row);
23996 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23997
23998 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23999 if (glyph < it->glyph_row->glyphs[area + 1])
24000 {
24001 /* If the glyph row is reversed, we need to prepend the glyph
24002 rather than append it. */
24003 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24004 {
24005 struct glyph *g;
24006
24007 /* Make room for the additional glyph. */
24008 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24009 g[1] = *g;
24010 glyph = it->glyph_row->glyphs[area];
24011 }
24012 glyph->charpos = CHARPOS (it->position);
24013 glyph->object = it->object;
24014 if (it->pixel_width > 0)
24015 {
24016 glyph->pixel_width = it->pixel_width;
24017 glyph->padding_p = 0;
24018 }
24019 else
24020 {
24021 /* Assure at least 1-pixel width. Otherwise, cursor can't
24022 be displayed correctly. */
24023 glyph->pixel_width = 1;
24024 glyph->padding_p = 1;
24025 }
24026 glyph->ascent = it->ascent;
24027 glyph->descent = it->descent;
24028 glyph->voffset = it->voffset;
24029 glyph->type = CHAR_GLYPH;
24030 glyph->avoid_cursor_p = it->avoid_cursor_p;
24031 glyph->multibyte_p = it->multibyte_p;
24032 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24033 {
24034 /* In R2L rows, the left and the right box edges need to be
24035 drawn in reverse direction. */
24036 glyph->right_box_line_p = it->start_of_box_run_p;
24037 glyph->left_box_line_p = it->end_of_box_run_p;
24038 }
24039 else
24040 {
24041 glyph->left_box_line_p = it->start_of_box_run_p;
24042 glyph->right_box_line_p = it->end_of_box_run_p;
24043 }
24044 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24045 || it->phys_descent > it->descent);
24046 glyph->glyph_not_available_p = it->glyph_not_available_p;
24047 glyph->face_id = it->face_id;
24048 glyph->u.ch = it->char_to_display;
24049 glyph->slice.img = null_glyph_slice;
24050 glyph->font_type = FONT_TYPE_UNKNOWN;
24051 if (it->bidi_p)
24052 {
24053 glyph->resolved_level = it->bidi_it.resolved_level;
24054 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24055 emacs_abort ();
24056 glyph->bidi_type = it->bidi_it.type;
24057 }
24058 else
24059 {
24060 glyph->resolved_level = 0;
24061 glyph->bidi_type = UNKNOWN_BT;
24062 }
24063 ++it->glyph_row->used[area];
24064 }
24065 else
24066 IT_EXPAND_MATRIX_WIDTH (it, area);
24067 }
24068
24069 /* Store one glyph for the composition IT->cmp_it.id in
24070 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24071 non-null. */
24072
24073 static void
24074 append_composite_glyph (struct it *it)
24075 {
24076 struct glyph *glyph;
24077 enum glyph_row_area area = it->area;
24078
24079 eassert (it->glyph_row);
24080
24081 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24082 if (glyph < it->glyph_row->glyphs[area + 1])
24083 {
24084 /* If the glyph row is reversed, we need to prepend the glyph
24085 rather than append it. */
24086 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
24087 {
24088 struct glyph *g;
24089
24090 /* Make room for the new glyph. */
24091 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
24092 g[1] = *g;
24093 glyph = it->glyph_row->glyphs[it->area];
24094 }
24095 glyph->charpos = it->cmp_it.charpos;
24096 glyph->object = it->object;
24097 glyph->pixel_width = it->pixel_width;
24098 glyph->ascent = it->ascent;
24099 glyph->descent = it->descent;
24100 glyph->voffset = it->voffset;
24101 glyph->type = COMPOSITE_GLYPH;
24102 if (it->cmp_it.ch < 0)
24103 {
24104 glyph->u.cmp.automatic = 0;
24105 glyph->u.cmp.id = it->cmp_it.id;
24106 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
24107 }
24108 else
24109 {
24110 glyph->u.cmp.automatic = 1;
24111 glyph->u.cmp.id = it->cmp_it.id;
24112 glyph->slice.cmp.from = it->cmp_it.from;
24113 glyph->slice.cmp.to = it->cmp_it.to - 1;
24114 }
24115 glyph->avoid_cursor_p = it->avoid_cursor_p;
24116 glyph->multibyte_p = it->multibyte_p;
24117 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24118 {
24119 /* In R2L rows, the left and the right box edges need to be
24120 drawn in reverse direction. */
24121 glyph->right_box_line_p = it->start_of_box_run_p;
24122 glyph->left_box_line_p = it->end_of_box_run_p;
24123 }
24124 else
24125 {
24126 glyph->left_box_line_p = it->start_of_box_run_p;
24127 glyph->right_box_line_p = it->end_of_box_run_p;
24128 }
24129 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24130 || it->phys_descent > it->descent);
24131 glyph->padding_p = 0;
24132 glyph->glyph_not_available_p = 0;
24133 glyph->face_id = it->face_id;
24134 glyph->font_type = FONT_TYPE_UNKNOWN;
24135 if (it->bidi_p)
24136 {
24137 glyph->resolved_level = it->bidi_it.resolved_level;
24138 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24139 emacs_abort ();
24140 glyph->bidi_type = it->bidi_it.type;
24141 }
24142 ++it->glyph_row->used[area];
24143 }
24144 else
24145 IT_EXPAND_MATRIX_WIDTH (it, area);
24146 }
24147
24148
24149 /* Change IT->ascent and IT->height according to the setting of
24150 IT->voffset. */
24151
24152 static void
24153 take_vertical_position_into_account (struct it *it)
24154 {
24155 if (it->voffset)
24156 {
24157 if (it->voffset < 0)
24158 /* Increase the ascent so that we can display the text higher
24159 in the line. */
24160 it->ascent -= it->voffset;
24161 else
24162 /* Increase the descent so that we can display the text lower
24163 in the line. */
24164 it->descent += it->voffset;
24165 }
24166 }
24167
24168
24169 /* Produce glyphs/get display metrics for the image IT is loaded with.
24170 See the description of struct display_iterator in dispextern.h for
24171 an overview of struct display_iterator. */
24172
24173 static void
24174 produce_image_glyph (struct it *it)
24175 {
24176 struct image *img;
24177 struct face *face;
24178 int glyph_ascent, crop;
24179 struct glyph_slice slice;
24180
24181 eassert (it->what == IT_IMAGE);
24182
24183 face = FACE_FROM_ID (it->f, it->face_id);
24184 eassert (face);
24185 /* Make sure X resources of the face is loaded. */
24186 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24187
24188 if (it->image_id < 0)
24189 {
24190 /* Fringe bitmap. */
24191 it->ascent = it->phys_ascent = 0;
24192 it->descent = it->phys_descent = 0;
24193 it->pixel_width = 0;
24194 it->nglyphs = 0;
24195 return;
24196 }
24197
24198 img = IMAGE_FROM_ID (it->f, it->image_id);
24199 eassert (img);
24200 /* Make sure X resources of the image is loaded. */
24201 prepare_image_for_display (it->f, img);
24202
24203 slice.x = slice.y = 0;
24204 slice.width = img->width;
24205 slice.height = img->height;
24206
24207 if (INTEGERP (it->slice.x))
24208 slice.x = XINT (it->slice.x);
24209 else if (FLOATP (it->slice.x))
24210 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24211
24212 if (INTEGERP (it->slice.y))
24213 slice.y = XINT (it->slice.y);
24214 else if (FLOATP (it->slice.y))
24215 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24216
24217 if (INTEGERP (it->slice.width))
24218 slice.width = XINT (it->slice.width);
24219 else if (FLOATP (it->slice.width))
24220 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24221
24222 if (INTEGERP (it->slice.height))
24223 slice.height = XINT (it->slice.height);
24224 else if (FLOATP (it->slice.height))
24225 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24226
24227 if (slice.x >= img->width)
24228 slice.x = img->width;
24229 if (slice.y >= img->height)
24230 slice.y = img->height;
24231 if (slice.x + slice.width >= img->width)
24232 slice.width = img->width - slice.x;
24233 if (slice.y + slice.height > img->height)
24234 slice.height = img->height - slice.y;
24235
24236 if (slice.width == 0 || slice.height == 0)
24237 return;
24238
24239 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24240
24241 it->descent = slice.height - glyph_ascent;
24242 if (slice.y == 0)
24243 it->descent += img->vmargin;
24244 if (slice.y + slice.height == img->height)
24245 it->descent += img->vmargin;
24246 it->phys_descent = it->descent;
24247
24248 it->pixel_width = slice.width;
24249 if (slice.x == 0)
24250 it->pixel_width += img->hmargin;
24251 if (slice.x + slice.width == img->width)
24252 it->pixel_width += img->hmargin;
24253
24254 /* It's quite possible for images to have an ascent greater than
24255 their height, so don't get confused in that case. */
24256 if (it->descent < 0)
24257 it->descent = 0;
24258
24259 it->nglyphs = 1;
24260
24261 if (face->box != FACE_NO_BOX)
24262 {
24263 if (face->box_line_width > 0)
24264 {
24265 if (slice.y == 0)
24266 it->ascent += face->box_line_width;
24267 if (slice.y + slice.height == img->height)
24268 it->descent += face->box_line_width;
24269 }
24270
24271 if (it->start_of_box_run_p && slice.x == 0)
24272 it->pixel_width += eabs (face->box_line_width);
24273 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24274 it->pixel_width += eabs (face->box_line_width);
24275 }
24276
24277 take_vertical_position_into_account (it);
24278
24279 /* Automatically crop wide image glyphs at right edge so we can
24280 draw the cursor on same display row. */
24281 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24282 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24283 {
24284 it->pixel_width -= crop;
24285 slice.width -= crop;
24286 }
24287
24288 if (it->glyph_row)
24289 {
24290 struct glyph *glyph;
24291 enum glyph_row_area area = it->area;
24292
24293 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24294 if (glyph < it->glyph_row->glyphs[area + 1])
24295 {
24296 glyph->charpos = CHARPOS (it->position);
24297 glyph->object = it->object;
24298 glyph->pixel_width = it->pixel_width;
24299 glyph->ascent = glyph_ascent;
24300 glyph->descent = it->descent;
24301 glyph->voffset = it->voffset;
24302 glyph->type = IMAGE_GLYPH;
24303 glyph->avoid_cursor_p = it->avoid_cursor_p;
24304 glyph->multibyte_p = it->multibyte_p;
24305 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24306 {
24307 /* In R2L rows, the left and the right box edges need to be
24308 drawn in reverse direction. */
24309 glyph->right_box_line_p = it->start_of_box_run_p;
24310 glyph->left_box_line_p = it->end_of_box_run_p;
24311 }
24312 else
24313 {
24314 glyph->left_box_line_p = it->start_of_box_run_p;
24315 glyph->right_box_line_p = it->end_of_box_run_p;
24316 }
24317 glyph->overlaps_vertically_p = 0;
24318 glyph->padding_p = 0;
24319 glyph->glyph_not_available_p = 0;
24320 glyph->face_id = it->face_id;
24321 glyph->u.img_id = img->id;
24322 glyph->slice.img = slice;
24323 glyph->font_type = FONT_TYPE_UNKNOWN;
24324 if (it->bidi_p)
24325 {
24326 glyph->resolved_level = it->bidi_it.resolved_level;
24327 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24328 emacs_abort ();
24329 glyph->bidi_type = it->bidi_it.type;
24330 }
24331 ++it->glyph_row->used[area];
24332 }
24333 else
24334 IT_EXPAND_MATRIX_WIDTH (it, area);
24335 }
24336 }
24337
24338
24339 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24340 of the glyph, WIDTH and HEIGHT are the width and height of the
24341 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24342
24343 static void
24344 append_stretch_glyph (struct it *it, Lisp_Object object,
24345 int width, int height, int ascent)
24346 {
24347 struct glyph *glyph;
24348 enum glyph_row_area area = it->area;
24349
24350 eassert (ascent >= 0 && ascent <= height);
24351
24352 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24353 if (glyph < it->glyph_row->glyphs[area + 1])
24354 {
24355 /* If the glyph row is reversed, we need to prepend the glyph
24356 rather than append it. */
24357 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24358 {
24359 struct glyph *g;
24360
24361 /* Make room for the additional glyph. */
24362 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24363 g[1] = *g;
24364 glyph = it->glyph_row->glyphs[area];
24365 }
24366 glyph->charpos = CHARPOS (it->position);
24367 glyph->object = object;
24368 glyph->pixel_width = width;
24369 glyph->ascent = ascent;
24370 glyph->descent = height - ascent;
24371 glyph->voffset = it->voffset;
24372 glyph->type = STRETCH_GLYPH;
24373 glyph->avoid_cursor_p = it->avoid_cursor_p;
24374 glyph->multibyte_p = it->multibyte_p;
24375 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24376 {
24377 /* In R2L rows, the left and the right box edges need to be
24378 drawn in reverse direction. */
24379 glyph->right_box_line_p = it->start_of_box_run_p;
24380 glyph->left_box_line_p = it->end_of_box_run_p;
24381 }
24382 else
24383 {
24384 glyph->left_box_line_p = it->start_of_box_run_p;
24385 glyph->right_box_line_p = it->end_of_box_run_p;
24386 }
24387 glyph->overlaps_vertically_p = 0;
24388 glyph->padding_p = 0;
24389 glyph->glyph_not_available_p = 0;
24390 glyph->face_id = it->face_id;
24391 glyph->u.stretch.ascent = ascent;
24392 glyph->u.stretch.height = height;
24393 glyph->slice.img = null_glyph_slice;
24394 glyph->font_type = FONT_TYPE_UNKNOWN;
24395 if (it->bidi_p)
24396 {
24397 glyph->resolved_level = it->bidi_it.resolved_level;
24398 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24399 emacs_abort ();
24400 glyph->bidi_type = it->bidi_it.type;
24401 }
24402 else
24403 {
24404 glyph->resolved_level = 0;
24405 glyph->bidi_type = UNKNOWN_BT;
24406 }
24407 ++it->glyph_row->used[area];
24408 }
24409 else
24410 IT_EXPAND_MATRIX_WIDTH (it, area);
24411 }
24412
24413 #endif /* HAVE_WINDOW_SYSTEM */
24414
24415 /* Produce a stretch glyph for iterator IT. IT->object is the value
24416 of the glyph property displayed. The value must be a list
24417 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24418 being recognized:
24419
24420 1. `:width WIDTH' specifies that the space should be WIDTH *
24421 canonical char width wide. WIDTH may be an integer or floating
24422 point number.
24423
24424 2. `:relative-width FACTOR' specifies that the width of the stretch
24425 should be computed from the width of the first character having the
24426 `glyph' property, and should be FACTOR times that width.
24427
24428 3. `:align-to HPOS' specifies that the space should be wide enough
24429 to reach HPOS, a value in canonical character units.
24430
24431 Exactly one of the above pairs must be present.
24432
24433 4. `:height HEIGHT' specifies that the height of the stretch produced
24434 should be HEIGHT, measured in canonical character units.
24435
24436 5. `:relative-height FACTOR' specifies that the height of the
24437 stretch should be FACTOR times the height of the characters having
24438 the glyph property.
24439
24440 Either none or exactly one of 4 or 5 must be present.
24441
24442 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24443 of the stretch should be used for the ascent of the stretch.
24444 ASCENT must be in the range 0 <= ASCENT <= 100. */
24445
24446 void
24447 produce_stretch_glyph (struct it *it)
24448 {
24449 /* (space :width WIDTH :height HEIGHT ...) */
24450 Lisp_Object prop, plist;
24451 int width = 0, height = 0, align_to = -1;
24452 int zero_width_ok_p = 0;
24453 double tem;
24454 struct font *font = NULL;
24455
24456 #ifdef HAVE_WINDOW_SYSTEM
24457 int ascent = 0;
24458 int zero_height_ok_p = 0;
24459
24460 if (FRAME_WINDOW_P (it->f))
24461 {
24462 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24463 font = face->font ? face->font : FRAME_FONT (it->f);
24464 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24465 }
24466 #endif
24467
24468 /* List should start with `space'. */
24469 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24470 plist = XCDR (it->object);
24471
24472 /* Compute the width of the stretch. */
24473 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24474 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24475 {
24476 /* Absolute width `:width WIDTH' specified and valid. */
24477 zero_width_ok_p = 1;
24478 width = (int)tem;
24479 }
24480 #ifdef HAVE_WINDOW_SYSTEM
24481 else if (FRAME_WINDOW_P (it->f)
24482 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24483 {
24484 /* Relative width `:relative-width FACTOR' specified and valid.
24485 Compute the width of the characters having the `glyph'
24486 property. */
24487 struct it it2;
24488 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24489
24490 it2 = *it;
24491 if (it->multibyte_p)
24492 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24493 else
24494 {
24495 it2.c = it2.char_to_display = *p, it2.len = 1;
24496 if (! ASCII_CHAR_P (it2.c))
24497 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24498 }
24499
24500 it2.glyph_row = NULL;
24501 it2.what = IT_CHARACTER;
24502 x_produce_glyphs (&it2);
24503 width = NUMVAL (prop) * it2.pixel_width;
24504 }
24505 #endif /* HAVE_WINDOW_SYSTEM */
24506 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24507 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24508 {
24509 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24510 align_to = (align_to < 0
24511 ? 0
24512 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24513 else if (align_to < 0)
24514 align_to = window_box_left_offset (it->w, TEXT_AREA);
24515 width = max (0, (int)tem + align_to - it->current_x);
24516 zero_width_ok_p = 1;
24517 }
24518 else
24519 /* Nothing specified -> width defaults to canonical char width. */
24520 width = FRAME_COLUMN_WIDTH (it->f);
24521
24522 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24523 width = 1;
24524
24525 #ifdef HAVE_WINDOW_SYSTEM
24526 /* Compute height. */
24527 if (FRAME_WINDOW_P (it->f))
24528 {
24529 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24530 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24531 {
24532 height = (int)tem;
24533 zero_height_ok_p = 1;
24534 }
24535 else if (prop = Fplist_get (plist, QCrelative_height),
24536 NUMVAL (prop) > 0)
24537 height = FONT_HEIGHT (font) * NUMVAL (prop);
24538 else
24539 height = FONT_HEIGHT (font);
24540
24541 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24542 height = 1;
24543
24544 /* Compute percentage of height used for ascent. If
24545 `:ascent ASCENT' is present and valid, use that. Otherwise,
24546 derive the ascent from the font in use. */
24547 if (prop = Fplist_get (plist, QCascent),
24548 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24549 ascent = height * NUMVAL (prop) / 100.0;
24550 else if (!NILP (prop)
24551 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24552 ascent = min (max (0, (int)tem), height);
24553 else
24554 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24555 }
24556 else
24557 #endif /* HAVE_WINDOW_SYSTEM */
24558 height = 1;
24559
24560 if (width > 0 && it->line_wrap != TRUNCATE
24561 && it->current_x + width > it->last_visible_x)
24562 {
24563 width = it->last_visible_x - it->current_x;
24564 #ifdef HAVE_WINDOW_SYSTEM
24565 /* Subtract one more pixel from the stretch width, but only on
24566 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24567 width -= FRAME_WINDOW_P (it->f);
24568 #endif
24569 }
24570
24571 if (width > 0 && height > 0 && it->glyph_row)
24572 {
24573 Lisp_Object o_object = it->object;
24574 Lisp_Object object = it->stack[it->sp - 1].string;
24575 int n = width;
24576
24577 if (!STRINGP (object))
24578 object = it->w->contents;
24579 #ifdef HAVE_WINDOW_SYSTEM
24580 if (FRAME_WINDOW_P (it->f))
24581 append_stretch_glyph (it, object, width, height, ascent);
24582 else
24583 #endif
24584 {
24585 it->object = object;
24586 it->char_to_display = ' ';
24587 it->pixel_width = it->len = 1;
24588 while (n--)
24589 tty_append_glyph (it);
24590 it->object = o_object;
24591 }
24592 }
24593
24594 it->pixel_width = width;
24595 #ifdef HAVE_WINDOW_SYSTEM
24596 if (FRAME_WINDOW_P (it->f))
24597 {
24598 it->ascent = it->phys_ascent = ascent;
24599 it->descent = it->phys_descent = height - it->ascent;
24600 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24601 take_vertical_position_into_account (it);
24602 }
24603 else
24604 #endif
24605 it->nglyphs = width;
24606 }
24607
24608 /* Get information about special display element WHAT in an
24609 environment described by IT. WHAT is one of IT_TRUNCATION or
24610 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24611 non-null glyph_row member. This function ensures that fields like
24612 face_id, c, len of IT are left untouched. */
24613
24614 static void
24615 produce_special_glyphs (struct it *it, enum display_element_type what)
24616 {
24617 struct it temp_it;
24618 Lisp_Object gc;
24619 GLYPH glyph;
24620
24621 temp_it = *it;
24622 temp_it.object = make_number (0);
24623 memset (&temp_it.current, 0, sizeof temp_it.current);
24624
24625 if (what == IT_CONTINUATION)
24626 {
24627 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24628 if (it->bidi_it.paragraph_dir == R2L)
24629 SET_GLYPH_FROM_CHAR (glyph, '/');
24630 else
24631 SET_GLYPH_FROM_CHAR (glyph, '\\');
24632 if (it->dp
24633 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24634 {
24635 /* FIXME: Should we mirror GC for R2L lines? */
24636 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24637 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24638 }
24639 }
24640 else if (what == IT_TRUNCATION)
24641 {
24642 /* Truncation glyph. */
24643 SET_GLYPH_FROM_CHAR (glyph, '$');
24644 if (it->dp
24645 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24646 {
24647 /* FIXME: Should we mirror GC for R2L lines? */
24648 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24649 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24650 }
24651 }
24652 else
24653 emacs_abort ();
24654
24655 #ifdef HAVE_WINDOW_SYSTEM
24656 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24657 is turned off, we precede the truncation/continuation glyphs by a
24658 stretch glyph whose width is computed such that these special
24659 glyphs are aligned at the window margin, even when very different
24660 fonts are used in different glyph rows. */
24661 if (FRAME_WINDOW_P (temp_it.f)
24662 /* init_iterator calls this with it->glyph_row == NULL, and it
24663 wants only the pixel width of the truncation/continuation
24664 glyphs. */
24665 && temp_it.glyph_row
24666 /* insert_left_trunc_glyphs calls us at the beginning of the
24667 row, and it has its own calculation of the stretch glyph
24668 width. */
24669 && temp_it.glyph_row->used[TEXT_AREA] > 0
24670 && (temp_it.glyph_row->reversed_p
24671 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24672 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24673 {
24674 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24675
24676 if (stretch_width > 0)
24677 {
24678 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24679 struct font *font =
24680 face->font ? face->font : FRAME_FONT (temp_it.f);
24681 int stretch_ascent =
24682 (((temp_it.ascent + temp_it.descent)
24683 * FONT_BASE (font)) / FONT_HEIGHT (font));
24684
24685 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24686 temp_it.ascent + temp_it.descent,
24687 stretch_ascent);
24688 }
24689 }
24690 #endif
24691
24692 temp_it.dp = NULL;
24693 temp_it.what = IT_CHARACTER;
24694 temp_it.len = 1;
24695 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24696 temp_it.face_id = GLYPH_FACE (glyph);
24697 temp_it.len = CHAR_BYTES (temp_it.c);
24698
24699 PRODUCE_GLYPHS (&temp_it);
24700 it->pixel_width = temp_it.pixel_width;
24701 it->nglyphs = temp_it.pixel_width;
24702 }
24703
24704 #ifdef HAVE_WINDOW_SYSTEM
24705
24706 /* Calculate line-height and line-spacing properties.
24707 An integer value specifies explicit pixel value.
24708 A float value specifies relative value to current face height.
24709 A cons (float . face-name) specifies relative value to
24710 height of specified face font.
24711
24712 Returns height in pixels, or nil. */
24713
24714
24715 static Lisp_Object
24716 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24717 int boff, int override)
24718 {
24719 Lisp_Object face_name = Qnil;
24720 int ascent, descent, height;
24721
24722 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24723 return val;
24724
24725 if (CONSP (val))
24726 {
24727 face_name = XCAR (val);
24728 val = XCDR (val);
24729 if (!NUMBERP (val))
24730 val = make_number (1);
24731 if (NILP (face_name))
24732 {
24733 height = it->ascent + it->descent;
24734 goto scale;
24735 }
24736 }
24737
24738 if (NILP (face_name))
24739 {
24740 font = FRAME_FONT (it->f);
24741 boff = FRAME_BASELINE_OFFSET (it->f);
24742 }
24743 else if (EQ (face_name, Qt))
24744 {
24745 override = 0;
24746 }
24747 else
24748 {
24749 int face_id;
24750 struct face *face;
24751
24752 face_id = lookup_named_face (it->f, face_name, 0);
24753 if (face_id < 0)
24754 return make_number (-1);
24755
24756 face = FACE_FROM_ID (it->f, face_id);
24757 font = face->font;
24758 if (font == NULL)
24759 return make_number (-1);
24760 boff = font->baseline_offset;
24761 if (font->vertical_centering)
24762 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24763 }
24764
24765 ascent = FONT_BASE (font) + boff;
24766 descent = FONT_DESCENT (font) - boff;
24767
24768 if (override)
24769 {
24770 it->override_ascent = ascent;
24771 it->override_descent = descent;
24772 it->override_boff = boff;
24773 }
24774
24775 height = ascent + descent;
24776
24777 scale:
24778 if (FLOATP (val))
24779 height = (int)(XFLOAT_DATA (val) * height);
24780 else if (INTEGERP (val))
24781 height *= XINT (val);
24782
24783 return make_number (height);
24784 }
24785
24786
24787 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24788 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24789 and only if this is for a character for which no font was found.
24790
24791 If the display method (it->glyphless_method) is
24792 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24793 length of the acronym or the hexadecimal string, UPPER_XOFF and
24794 UPPER_YOFF are pixel offsets for the upper part of the string,
24795 LOWER_XOFF and LOWER_YOFF are for the lower part.
24796
24797 For the other display methods, LEN through LOWER_YOFF are zero. */
24798
24799 static void
24800 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24801 short upper_xoff, short upper_yoff,
24802 short lower_xoff, short lower_yoff)
24803 {
24804 struct glyph *glyph;
24805 enum glyph_row_area area = it->area;
24806
24807 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24808 if (glyph < it->glyph_row->glyphs[area + 1])
24809 {
24810 /* If the glyph row is reversed, we need to prepend the glyph
24811 rather than append it. */
24812 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24813 {
24814 struct glyph *g;
24815
24816 /* Make room for the additional glyph. */
24817 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24818 g[1] = *g;
24819 glyph = it->glyph_row->glyphs[area];
24820 }
24821 glyph->charpos = CHARPOS (it->position);
24822 glyph->object = it->object;
24823 glyph->pixel_width = it->pixel_width;
24824 glyph->ascent = it->ascent;
24825 glyph->descent = it->descent;
24826 glyph->voffset = it->voffset;
24827 glyph->type = GLYPHLESS_GLYPH;
24828 glyph->u.glyphless.method = it->glyphless_method;
24829 glyph->u.glyphless.for_no_font = for_no_font;
24830 glyph->u.glyphless.len = len;
24831 glyph->u.glyphless.ch = it->c;
24832 glyph->slice.glyphless.upper_xoff = upper_xoff;
24833 glyph->slice.glyphless.upper_yoff = upper_yoff;
24834 glyph->slice.glyphless.lower_xoff = lower_xoff;
24835 glyph->slice.glyphless.lower_yoff = lower_yoff;
24836 glyph->avoid_cursor_p = it->avoid_cursor_p;
24837 glyph->multibyte_p = it->multibyte_p;
24838 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24839 {
24840 /* In R2L rows, the left and the right box edges need to be
24841 drawn in reverse direction. */
24842 glyph->right_box_line_p = it->start_of_box_run_p;
24843 glyph->left_box_line_p = it->end_of_box_run_p;
24844 }
24845 else
24846 {
24847 glyph->left_box_line_p = it->start_of_box_run_p;
24848 glyph->right_box_line_p = it->end_of_box_run_p;
24849 }
24850 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24851 || it->phys_descent > it->descent);
24852 glyph->padding_p = 0;
24853 glyph->glyph_not_available_p = 0;
24854 glyph->face_id = face_id;
24855 glyph->font_type = FONT_TYPE_UNKNOWN;
24856 if (it->bidi_p)
24857 {
24858 glyph->resolved_level = it->bidi_it.resolved_level;
24859 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24860 emacs_abort ();
24861 glyph->bidi_type = it->bidi_it.type;
24862 }
24863 ++it->glyph_row->used[area];
24864 }
24865 else
24866 IT_EXPAND_MATRIX_WIDTH (it, area);
24867 }
24868
24869
24870 /* Produce a glyph for a glyphless character for iterator IT.
24871 IT->glyphless_method specifies which method to use for displaying
24872 the character. See the description of enum
24873 glyphless_display_method in dispextern.h for the detail.
24874
24875 FOR_NO_FONT is nonzero if and only if this is for a character for
24876 which no font was found. ACRONYM, if non-nil, is an acronym string
24877 for the character. */
24878
24879 static void
24880 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24881 {
24882 int face_id;
24883 struct face *face;
24884 struct font *font;
24885 int base_width, base_height, width, height;
24886 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24887 int len;
24888
24889 /* Get the metrics of the base font. We always refer to the current
24890 ASCII face. */
24891 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24892 font = face->font ? face->font : FRAME_FONT (it->f);
24893 it->ascent = FONT_BASE (font) + font->baseline_offset;
24894 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24895 base_height = it->ascent + it->descent;
24896 base_width = font->average_width;
24897
24898 /* Get a face ID for the glyph by utilizing a cache (the same way as
24899 done for `escape-glyph' in get_next_display_element). */
24900 if (it->f == last_glyphless_glyph_frame
24901 && it->face_id == last_glyphless_glyph_face_id)
24902 {
24903 face_id = last_glyphless_glyph_merged_face_id;
24904 }
24905 else
24906 {
24907 /* Merge the `glyphless-char' face into the current face. */
24908 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24909 last_glyphless_glyph_frame = it->f;
24910 last_glyphless_glyph_face_id = it->face_id;
24911 last_glyphless_glyph_merged_face_id = face_id;
24912 }
24913
24914 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24915 {
24916 it->pixel_width = THIN_SPACE_WIDTH;
24917 len = 0;
24918 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24919 }
24920 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24921 {
24922 width = CHAR_WIDTH (it->c);
24923 if (width == 0)
24924 width = 1;
24925 else if (width > 4)
24926 width = 4;
24927 it->pixel_width = base_width * width;
24928 len = 0;
24929 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24930 }
24931 else
24932 {
24933 char buf[7];
24934 const char *str;
24935 unsigned int code[6];
24936 int upper_len;
24937 int ascent, descent;
24938 struct font_metrics metrics_upper, metrics_lower;
24939
24940 face = FACE_FROM_ID (it->f, face_id);
24941 font = face->font ? face->font : FRAME_FONT (it->f);
24942 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24943
24944 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24945 {
24946 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24947 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24948 if (CONSP (acronym))
24949 acronym = XCAR (acronym);
24950 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24951 }
24952 else
24953 {
24954 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24955 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24956 str = buf;
24957 }
24958 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24959 code[len] = font->driver->encode_char (font, str[len]);
24960 upper_len = (len + 1) / 2;
24961 font->driver->text_extents (font, code, upper_len,
24962 &metrics_upper);
24963 font->driver->text_extents (font, code + upper_len, len - upper_len,
24964 &metrics_lower);
24965
24966
24967
24968 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24969 width = max (metrics_upper.width, metrics_lower.width) + 4;
24970 upper_xoff = upper_yoff = 2; /* the typical case */
24971 if (base_width >= width)
24972 {
24973 /* Align the upper to the left, the lower to the right. */
24974 it->pixel_width = base_width;
24975 lower_xoff = base_width - 2 - metrics_lower.width;
24976 }
24977 else
24978 {
24979 /* Center the shorter one. */
24980 it->pixel_width = width;
24981 if (metrics_upper.width >= metrics_lower.width)
24982 lower_xoff = (width - metrics_lower.width) / 2;
24983 else
24984 {
24985 /* FIXME: This code doesn't look right. It formerly was
24986 missing the "lower_xoff = 0;", which couldn't have
24987 been right since it left lower_xoff uninitialized. */
24988 lower_xoff = 0;
24989 upper_xoff = (width - metrics_upper.width) / 2;
24990 }
24991 }
24992
24993 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24994 top, bottom, and between upper and lower strings. */
24995 height = (metrics_upper.ascent + metrics_upper.descent
24996 + metrics_lower.ascent + metrics_lower.descent) + 5;
24997 /* Center vertically.
24998 H:base_height, D:base_descent
24999 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25000
25001 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25002 descent = D - H/2 + h/2;
25003 lower_yoff = descent - 2 - ld;
25004 upper_yoff = lower_yoff - la - 1 - ud; */
25005 ascent = - (it->descent - (base_height + height + 1) / 2);
25006 descent = it->descent - (base_height - height) / 2;
25007 lower_yoff = descent - 2 - metrics_lower.descent;
25008 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
25009 - metrics_upper.descent);
25010 /* Don't make the height shorter than the base height. */
25011 if (height > base_height)
25012 {
25013 it->ascent = ascent;
25014 it->descent = descent;
25015 }
25016 }
25017
25018 it->phys_ascent = it->ascent;
25019 it->phys_descent = it->descent;
25020 if (it->glyph_row)
25021 append_glyphless_glyph (it, face_id, for_no_font, len,
25022 upper_xoff, upper_yoff,
25023 lower_xoff, lower_yoff);
25024 it->nglyphs = 1;
25025 take_vertical_position_into_account (it);
25026 }
25027
25028
25029 /* RIF:
25030 Produce glyphs/get display metrics for the display element IT is
25031 loaded with. See the description of struct it in dispextern.h
25032 for an overview of struct it. */
25033
25034 void
25035 x_produce_glyphs (struct it *it)
25036 {
25037 int extra_line_spacing = it->extra_line_spacing;
25038
25039 it->glyph_not_available_p = 0;
25040
25041 if (it->what == IT_CHARACTER)
25042 {
25043 XChar2b char2b;
25044 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25045 struct font *font = face->font;
25046 struct font_metrics *pcm = NULL;
25047 int boff; /* baseline offset */
25048
25049 if (font == NULL)
25050 {
25051 /* When no suitable font is found, display this character by
25052 the method specified in the first extra slot of
25053 Vglyphless_char_display. */
25054 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
25055
25056 eassert (it->what == IT_GLYPHLESS);
25057 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
25058 goto done;
25059 }
25060
25061 boff = font->baseline_offset;
25062 if (font->vertical_centering)
25063 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25064
25065 if (it->char_to_display != '\n' && it->char_to_display != '\t')
25066 {
25067 int stretched_p;
25068
25069 it->nglyphs = 1;
25070
25071 if (it->override_ascent >= 0)
25072 {
25073 it->ascent = it->override_ascent;
25074 it->descent = it->override_descent;
25075 boff = it->override_boff;
25076 }
25077 else
25078 {
25079 it->ascent = FONT_BASE (font) + boff;
25080 it->descent = FONT_DESCENT (font) - boff;
25081 }
25082
25083 if (get_char_glyph_code (it->char_to_display, font, &char2b))
25084 {
25085 pcm = get_per_char_metric (font, &char2b);
25086 if (pcm->width == 0
25087 && pcm->rbearing == 0 && pcm->lbearing == 0)
25088 pcm = NULL;
25089 }
25090
25091 if (pcm)
25092 {
25093 it->phys_ascent = pcm->ascent + boff;
25094 it->phys_descent = pcm->descent - boff;
25095 it->pixel_width = pcm->width;
25096 }
25097 else
25098 {
25099 it->glyph_not_available_p = 1;
25100 it->phys_ascent = it->ascent;
25101 it->phys_descent = it->descent;
25102 it->pixel_width = font->space_width;
25103 }
25104
25105 if (it->constrain_row_ascent_descent_p)
25106 {
25107 if (it->descent > it->max_descent)
25108 {
25109 it->ascent += it->descent - it->max_descent;
25110 it->descent = it->max_descent;
25111 }
25112 if (it->ascent > it->max_ascent)
25113 {
25114 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25115 it->ascent = it->max_ascent;
25116 }
25117 it->phys_ascent = min (it->phys_ascent, it->ascent);
25118 it->phys_descent = min (it->phys_descent, it->descent);
25119 extra_line_spacing = 0;
25120 }
25121
25122 /* If this is a space inside a region of text with
25123 `space-width' property, change its width. */
25124 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
25125 if (stretched_p)
25126 it->pixel_width *= XFLOATINT (it->space_width);
25127
25128 /* If face has a box, add the box thickness to the character
25129 height. If character has a box line to the left and/or
25130 right, add the box line width to the character's width. */
25131 if (face->box != FACE_NO_BOX)
25132 {
25133 int thick = face->box_line_width;
25134
25135 if (thick > 0)
25136 {
25137 it->ascent += thick;
25138 it->descent += thick;
25139 }
25140 else
25141 thick = -thick;
25142
25143 if (it->start_of_box_run_p)
25144 it->pixel_width += thick;
25145 if (it->end_of_box_run_p)
25146 it->pixel_width += thick;
25147 }
25148
25149 /* If face has an overline, add the height of the overline
25150 (1 pixel) and a 1 pixel margin to the character height. */
25151 if (face->overline_p)
25152 it->ascent += overline_margin;
25153
25154 if (it->constrain_row_ascent_descent_p)
25155 {
25156 if (it->ascent > it->max_ascent)
25157 it->ascent = it->max_ascent;
25158 if (it->descent > it->max_descent)
25159 it->descent = it->max_descent;
25160 }
25161
25162 take_vertical_position_into_account (it);
25163
25164 /* If we have to actually produce glyphs, do it. */
25165 if (it->glyph_row)
25166 {
25167 if (stretched_p)
25168 {
25169 /* Translate a space with a `space-width' property
25170 into a stretch glyph. */
25171 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25172 / FONT_HEIGHT (font));
25173 append_stretch_glyph (it, it->object, it->pixel_width,
25174 it->ascent + it->descent, ascent);
25175 }
25176 else
25177 append_glyph (it);
25178
25179 /* If characters with lbearing or rbearing are displayed
25180 in this line, record that fact in a flag of the
25181 glyph row. This is used to optimize X output code. */
25182 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25183 it->glyph_row->contains_overlapping_glyphs_p = 1;
25184 }
25185 if (! stretched_p && it->pixel_width == 0)
25186 /* We assure that all visible glyphs have at least 1-pixel
25187 width. */
25188 it->pixel_width = 1;
25189 }
25190 else if (it->char_to_display == '\n')
25191 {
25192 /* A newline has no width, but we need the height of the
25193 line. But if previous part of the line sets a height,
25194 don't increase that height */
25195
25196 Lisp_Object height;
25197 Lisp_Object total_height = Qnil;
25198
25199 it->override_ascent = -1;
25200 it->pixel_width = 0;
25201 it->nglyphs = 0;
25202
25203 height = get_it_property (it, Qline_height);
25204 /* Split (line-height total-height) list */
25205 if (CONSP (height)
25206 && CONSP (XCDR (height))
25207 && NILP (XCDR (XCDR (height))))
25208 {
25209 total_height = XCAR (XCDR (height));
25210 height = XCAR (height);
25211 }
25212 height = calc_line_height_property (it, height, font, boff, 1);
25213
25214 if (it->override_ascent >= 0)
25215 {
25216 it->ascent = it->override_ascent;
25217 it->descent = it->override_descent;
25218 boff = it->override_boff;
25219 }
25220 else
25221 {
25222 it->ascent = FONT_BASE (font) + boff;
25223 it->descent = FONT_DESCENT (font) - boff;
25224 }
25225
25226 if (EQ (height, Qt))
25227 {
25228 if (it->descent > it->max_descent)
25229 {
25230 it->ascent += it->descent - it->max_descent;
25231 it->descent = it->max_descent;
25232 }
25233 if (it->ascent > it->max_ascent)
25234 {
25235 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25236 it->ascent = it->max_ascent;
25237 }
25238 it->phys_ascent = min (it->phys_ascent, it->ascent);
25239 it->phys_descent = min (it->phys_descent, it->descent);
25240 it->constrain_row_ascent_descent_p = 1;
25241 extra_line_spacing = 0;
25242 }
25243 else
25244 {
25245 Lisp_Object spacing;
25246
25247 it->phys_ascent = it->ascent;
25248 it->phys_descent = it->descent;
25249
25250 if ((it->max_ascent > 0 || it->max_descent > 0)
25251 && face->box != FACE_NO_BOX
25252 && face->box_line_width > 0)
25253 {
25254 it->ascent += face->box_line_width;
25255 it->descent += face->box_line_width;
25256 }
25257 if (!NILP (height)
25258 && XINT (height) > it->ascent + it->descent)
25259 it->ascent = XINT (height) - it->descent;
25260
25261 if (!NILP (total_height))
25262 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25263 else
25264 {
25265 spacing = get_it_property (it, Qline_spacing);
25266 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25267 }
25268 if (INTEGERP (spacing))
25269 {
25270 extra_line_spacing = XINT (spacing);
25271 if (!NILP (total_height))
25272 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25273 }
25274 }
25275 }
25276 else /* i.e. (it->char_to_display == '\t') */
25277 {
25278 if (font->space_width > 0)
25279 {
25280 int tab_width = it->tab_width * font->space_width;
25281 int x = it->current_x + it->continuation_lines_width;
25282 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25283
25284 /* If the distance from the current position to the next tab
25285 stop is less than a space character width, use the
25286 tab stop after that. */
25287 if (next_tab_x - x < font->space_width)
25288 next_tab_x += tab_width;
25289
25290 it->pixel_width = next_tab_x - x;
25291 it->nglyphs = 1;
25292 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25293 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25294
25295 if (it->glyph_row)
25296 {
25297 append_stretch_glyph (it, it->object, it->pixel_width,
25298 it->ascent + it->descent, it->ascent);
25299 }
25300 }
25301 else
25302 {
25303 it->pixel_width = 0;
25304 it->nglyphs = 1;
25305 }
25306 }
25307 }
25308 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25309 {
25310 /* A static composition.
25311
25312 Note: A composition is represented as one glyph in the
25313 glyph matrix. There are no padding glyphs.
25314
25315 Important note: pixel_width, ascent, and descent are the
25316 values of what is drawn by draw_glyphs (i.e. the values of
25317 the overall glyphs composed). */
25318 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25319 int boff; /* baseline offset */
25320 struct composition *cmp = composition_table[it->cmp_it.id];
25321 int glyph_len = cmp->glyph_len;
25322 struct font *font = face->font;
25323
25324 it->nglyphs = 1;
25325
25326 /* If we have not yet calculated pixel size data of glyphs of
25327 the composition for the current face font, calculate them
25328 now. Theoretically, we have to check all fonts for the
25329 glyphs, but that requires much time and memory space. So,
25330 here we check only the font of the first glyph. This may
25331 lead to incorrect display, but it's very rare, and C-l
25332 (recenter-top-bottom) can correct the display anyway. */
25333 if (! cmp->font || cmp->font != font)
25334 {
25335 /* Ascent and descent of the font of the first character
25336 of this composition (adjusted by baseline offset).
25337 Ascent and descent of overall glyphs should not be less
25338 than these, respectively. */
25339 int font_ascent, font_descent, font_height;
25340 /* Bounding box of the overall glyphs. */
25341 int leftmost, rightmost, lowest, highest;
25342 int lbearing, rbearing;
25343 int i, width, ascent, descent;
25344 int left_padded = 0, right_padded = 0;
25345 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25346 XChar2b char2b;
25347 struct font_metrics *pcm;
25348 int font_not_found_p;
25349 ptrdiff_t pos;
25350
25351 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25352 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25353 break;
25354 if (glyph_len < cmp->glyph_len)
25355 right_padded = 1;
25356 for (i = 0; i < glyph_len; i++)
25357 {
25358 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25359 break;
25360 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25361 }
25362 if (i > 0)
25363 left_padded = 1;
25364
25365 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25366 : IT_CHARPOS (*it));
25367 /* If no suitable font is found, use the default font. */
25368 font_not_found_p = font == NULL;
25369 if (font_not_found_p)
25370 {
25371 face = face->ascii_face;
25372 font = face->font;
25373 }
25374 boff = font->baseline_offset;
25375 if (font->vertical_centering)
25376 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25377 font_ascent = FONT_BASE (font) + boff;
25378 font_descent = FONT_DESCENT (font) - boff;
25379 font_height = FONT_HEIGHT (font);
25380
25381 cmp->font = font;
25382
25383 pcm = NULL;
25384 if (! font_not_found_p)
25385 {
25386 get_char_face_and_encoding (it->f, c, it->face_id,
25387 &char2b, 0);
25388 pcm = get_per_char_metric (font, &char2b);
25389 }
25390
25391 /* Initialize the bounding box. */
25392 if (pcm)
25393 {
25394 width = cmp->glyph_len > 0 ? pcm->width : 0;
25395 ascent = pcm->ascent;
25396 descent = pcm->descent;
25397 lbearing = pcm->lbearing;
25398 rbearing = pcm->rbearing;
25399 }
25400 else
25401 {
25402 width = cmp->glyph_len > 0 ? font->space_width : 0;
25403 ascent = FONT_BASE (font);
25404 descent = FONT_DESCENT (font);
25405 lbearing = 0;
25406 rbearing = width;
25407 }
25408
25409 rightmost = width;
25410 leftmost = 0;
25411 lowest = - descent + boff;
25412 highest = ascent + boff;
25413
25414 if (! font_not_found_p
25415 && font->default_ascent
25416 && CHAR_TABLE_P (Vuse_default_ascent)
25417 && !NILP (Faref (Vuse_default_ascent,
25418 make_number (it->char_to_display))))
25419 highest = font->default_ascent + boff;
25420
25421 /* Draw the first glyph at the normal position. It may be
25422 shifted to right later if some other glyphs are drawn
25423 at the left. */
25424 cmp->offsets[i * 2] = 0;
25425 cmp->offsets[i * 2 + 1] = boff;
25426 cmp->lbearing = lbearing;
25427 cmp->rbearing = rbearing;
25428
25429 /* Set cmp->offsets for the remaining glyphs. */
25430 for (i++; i < glyph_len; i++)
25431 {
25432 int left, right, btm, top;
25433 int ch = COMPOSITION_GLYPH (cmp, i);
25434 int face_id;
25435 struct face *this_face;
25436
25437 if (ch == '\t')
25438 ch = ' ';
25439 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25440 this_face = FACE_FROM_ID (it->f, face_id);
25441 font = this_face->font;
25442
25443 if (font == NULL)
25444 pcm = NULL;
25445 else
25446 {
25447 get_char_face_and_encoding (it->f, ch, face_id,
25448 &char2b, 0);
25449 pcm = get_per_char_metric (font, &char2b);
25450 }
25451 if (! pcm)
25452 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25453 else
25454 {
25455 width = pcm->width;
25456 ascent = pcm->ascent;
25457 descent = pcm->descent;
25458 lbearing = pcm->lbearing;
25459 rbearing = pcm->rbearing;
25460 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25461 {
25462 /* Relative composition with or without
25463 alternate chars. */
25464 left = (leftmost + rightmost - width) / 2;
25465 btm = - descent + boff;
25466 if (font->relative_compose
25467 && (! CHAR_TABLE_P (Vignore_relative_composition)
25468 || NILP (Faref (Vignore_relative_composition,
25469 make_number (ch)))))
25470 {
25471
25472 if (- descent >= font->relative_compose)
25473 /* One extra pixel between two glyphs. */
25474 btm = highest + 1;
25475 else if (ascent <= 0)
25476 /* One extra pixel between two glyphs. */
25477 btm = lowest - 1 - ascent - descent;
25478 }
25479 }
25480 else
25481 {
25482 /* A composition rule is specified by an integer
25483 value that encodes global and new reference
25484 points (GREF and NREF). GREF and NREF are
25485 specified by numbers as below:
25486
25487 0---1---2 -- ascent
25488 | |
25489 | |
25490 | |
25491 9--10--11 -- center
25492 | |
25493 ---3---4---5--- baseline
25494 | |
25495 6---7---8 -- descent
25496 */
25497 int rule = COMPOSITION_RULE (cmp, i);
25498 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25499
25500 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25501 grefx = gref % 3, nrefx = nref % 3;
25502 grefy = gref / 3, nrefy = nref / 3;
25503 if (xoff)
25504 xoff = font_height * (xoff - 128) / 256;
25505 if (yoff)
25506 yoff = font_height * (yoff - 128) / 256;
25507
25508 left = (leftmost
25509 + grefx * (rightmost - leftmost) / 2
25510 - nrefx * width / 2
25511 + xoff);
25512
25513 btm = ((grefy == 0 ? highest
25514 : grefy == 1 ? 0
25515 : grefy == 2 ? lowest
25516 : (highest + lowest) / 2)
25517 - (nrefy == 0 ? ascent + descent
25518 : nrefy == 1 ? descent - boff
25519 : nrefy == 2 ? 0
25520 : (ascent + descent) / 2)
25521 + yoff);
25522 }
25523
25524 cmp->offsets[i * 2] = left;
25525 cmp->offsets[i * 2 + 1] = btm + descent;
25526
25527 /* Update the bounding box of the overall glyphs. */
25528 if (width > 0)
25529 {
25530 right = left + width;
25531 if (left < leftmost)
25532 leftmost = left;
25533 if (right > rightmost)
25534 rightmost = right;
25535 }
25536 top = btm + descent + ascent;
25537 if (top > highest)
25538 highest = top;
25539 if (btm < lowest)
25540 lowest = btm;
25541
25542 if (cmp->lbearing > left + lbearing)
25543 cmp->lbearing = left + lbearing;
25544 if (cmp->rbearing < left + rbearing)
25545 cmp->rbearing = left + rbearing;
25546 }
25547 }
25548
25549 /* If there are glyphs whose x-offsets are negative,
25550 shift all glyphs to the right and make all x-offsets
25551 non-negative. */
25552 if (leftmost < 0)
25553 {
25554 for (i = 0; i < cmp->glyph_len; i++)
25555 cmp->offsets[i * 2] -= leftmost;
25556 rightmost -= leftmost;
25557 cmp->lbearing -= leftmost;
25558 cmp->rbearing -= leftmost;
25559 }
25560
25561 if (left_padded && cmp->lbearing < 0)
25562 {
25563 for (i = 0; i < cmp->glyph_len; i++)
25564 cmp->offsets[i * 2] -= cmp->lbearing;
25565 rightmost -= cmp->lbearing;
25566 cmp->rbearing -= cmp->lbearing;
25567 cmp->lbearing = 0;
25568 }
25569 if (right_padded && rightmost < cmp->rbearing)
25570 {
25571 rightmost = cmp->rbearing;
25572 }
25573
25574 cmp->pixel_width = rightmost;
25575 cmp->ascent = highest;
25576 cmp->descent = - lowest;
25577 if (cmp->ascent < font_ascent)
25578 cmp->ascent = font_ascent;
25579 if (cmp->descent < font_descent)
25580 cmp->descent = font_descent;
25581 }
25582
25583 if (it->glyph_row
25584 && (cmp->lbearing < 0
25585 || cmp->rbearing > cmp->pixel_width))
25586 it->glyph_row->contains_overlapping_glyphs_p = 1;
25587
25588 it->pixel_width = cmp->pixel_width;
25589 it->ascent = it->phys_ascent = cmp->ascent;
25590 it->descent = it->phys_descent = cmp->descent;
25591 if (face->box != FACE_NO_BOX)
25592 {
25593 int thick = face->box_line_width;
25594
25595 if (thick > 0)
25596 {
25597 it->ascent += thick;
25598 it->descent += thick;
25599 }
25600 else
25601 thick = - thick;
25602
25603 if (it->start_of_box_run_p)
25604 it->pixel_width += thick;
25605 if (it->end_of_box_run_p)
25606 it->pixel_width += thick;
25607 }
25608
25609 /* If face has an overline, add the height of the overline
25610 (1 pixel) and a 1 pixel margin to the character height. */
25611 if (face->overline_p)
25612 it->ascent += overline_margin;
25613
25614 take_vertical_position_into_account (it);
25615 if (it->ascent < 0)
25616 it->ascent = 0;
25617 if (it->descent < 0)
25618 it->descent = 0;
25619
25620 if (it->glyph_row && cmp->glyph_len > 0)
25621 append_composite_glyph (it);
25622 }
25623 else if (it->what == IT_COMPOSITION)
25624 {
25625 /* A dynamic (automatic) composition. */
25626 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25627 Lisp_Object gstring;
25628 struct font_metrics metrics;
25629
25630 it->nglyphs = 1;
25631
25632 gstring = composition_gstring_from_id (it->cmp_it.id);
25633 it->pixel_width
25634 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25635 &metrics);
25636 if (it->glyph_row
25637 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25638 it->glyph_row->contains_overlapping_glyphs_p = 1;
25639 it->ascent = it->phys_ascent = metrics.ascent;
25640 it->descent = it->phys_descent = metrics.descent;
25641 if (face->box != FACE_NO_BOX)
25642 {
25643 int thick = face->box_line_width;
25644
25645 if (thick > 0)
25646 {
25647 it->ascent += thick;
25648 it->descent += thick;
25649 }
25650 else
25651 thick = - thick;
25652
25653 if (it->start_of_box_run_p)
25654 it->pixel_width += thick;
25655 if (it->end_of_box_run_p)
25656 it->pixel_width += thick;
25657 }
25658 /* If face has an overline, add the height of the overline
25659 (1 pixel) and a 1 pixel margin to the character height. */
25660 if (face->overline_p)
25661 it->ascent += overline_margin;
25662 take_vertical_position_into_account (it);
25663 if (it->ascent < 0)
25664 it->ascent = 0;
25665 if (it->descent < 0)
25666 it->descent = 0;
25667
25668 if (it->glyph_row)
25669 append_composite_glyph (it);
25670 }
25671 else if (it->what == IT_GLYPHLESS)
25672 produce_glyphless_glyph (it, 0, Qnil);
25673 else if (it->what == IT_IMAGE)
25674 produce_image_glyph (it);
25675 else if (it->what == IT_STRETCH)
25676 produce_stretch_glyph (it);
25677
25678 done:
25679 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25680 because this isn't true for images with `:ascent 100'. */
25681 eassert (it->ascent >= 0 && it->descent >= 0);
25682 if (it->area == TEXT_AREA)
25683 it->current_x += it->pixel_width;
25684
25685 if (extra_line_spacing > 0)
25686 {
25687 it->descent += extra_line_spacing;
25688 if (extra_line_spacing > it->max_extra_line_spacing)
25689 it->max_extra_line_spacing = extra_line_spacing;
25690 }
25691
25692 it->max_ascent = max (it->max_ascent, it->ascent);
25693 it->max_descent = max (it->max_descent, it->descent);
25694 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25695 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25696 }
25697
25698 /* EXPORT for RIF:
25699 Output LEN glyphs starting at START at the nominal cursor position.
25700 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
25701 being updated, and UPDATED_AREA is the area of that row being updated. */
25702
25703 void
25704 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
25705 struct glyph *start, enum glyph_row_area updated_area, int len)
25706 {
25707 int x, hpos, chpos = w->phys_cursor.hpos;
25708
25709 eassert (updated_row);
25710 /* When the window is hscrolled, cursor hpos can legitimately be out
25711 of bounds, but we draw the cursor at the corresponding window
25712 margin in that case. */
25713 if (!updated_row->reversed_p && chpos < 0)
25714 chpos = 0;
25715 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25716 chpos = updated_row->used[TEXT_AREA] - 1;
25717
25718 block_input ();
25719
25720 /* Write glyphs. */
25721
25722 hpos = start - updated_row->glyphs[updated_area];
25723 x = draw_glyphs (w, w->output_cursor.x,
25724 updated_row, updated_area,
25725 hpos, hpos + len,
25726 DRAW_NORMAL_TEXT, 0);
25727
25728 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25729 if (updated_area == TEXT_AREA
25730 && w->phys_cursor_on_p
25731 && w->phys_cursor.vpos == w->output_cursor.vpos
25732 && chpos >= hpos
25733 && chpos < hpos + len)
25734 w->phys_cursor_on_p = 0;
25735
25736 unblock_input ();
25737
25738 /* Advance the output cursor. */
25739 w->output_cursor.hpos += len;
25740 w->output_cursor.x = x;
25741 }
25742
25743
25744 /* EXPORT for RIF:
25745 Insert LEN glyphs from START at the nominal cursor position. */
25746
25747 void
25748 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
25749 struct glyph *start, enum glyph_row_area updated_area, int len)
25750 {
25751 struct frame *f;
25752 int line_height, shift_by_width, shifted_region_width;
25753 struct glyph_row *row;
25754 struct glyph *glyph;
25755 int frame_x, frame_y;
25756 ptrdiff_t hpos;
25757
25758 eassert (updated_row);
25759 block_input ();
25760 f = XFRAME (WINDOW_FRAME (w));
25761
25762 /* Get the height of the line we are in. */
25763 row = updated_row;
25764 line_height = row->height;
25765
25766 /* Get the width of the glyphs to insert. */
25767 shift_by_width = 0;
25768 for (glyph = start; glyph < start + len; ++glyph)
25769 shift_by_width += glyph->pixel_width;
25770
25771 /* Get the width of the region to shift right. */
25772 shifted_region_width = (window_box_width (w, updated_area)
25773 - w->output_cursor.x
25774 - shift_by_width);
25775
25776 /* Shift right. */
25777 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
25778 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
25779
25780 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25781 line_height, shift_by_width);
25782
25783 /* Write the glyphs. */
25784 hpos = start - row->glyphs[updated_area];
25785 draw_glyphs (w, w->output_cursor.x, row, updated_area,
25786 hpos, hpos + len,
25787 DRAW_NORMAL_TEXT, 0);
25788
25789 /* Advance the output cursor. */
25790 w->output_cursor.hpos += len;
25791 w->output_cursor.x += shift_by_width;
25792 unblock_input ();
25793 }
25794
25795
25796 /* EXPORT for RIF:
25797 Erase the current text line from the nominal cursor position
25798 (inclusive) to pixel column TO_X (exclusive). The idea is that
25799 everything from TO_X onward is already erased.
25800
25801 TO_X is a pixel position relative to UPDATED_AREA of currently
25802 updated window W. TO_X == -1 means clear to the end of this area. */
25803
25804 void
25805 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
25806 enum glyph_row_area updated_area, int to_x)
25807 {
25808 struct frame *f;
25809 int max_x, min_y, max_y;
25810 int from_x, from_y, to_y;
25811
25812 eassert (updated_row);
25813 f = XFRAME (w->frame);
25814
25815 if (updated_row->full_width_p)
25816 max_x = WINDOW_TOTAL_WIDTH (w);
25817 else
25818 max_x = window_box_width (w, updated_area);
25819 max_y = window_text_bottom_y (w);
25820
25821 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25822 of window. For TO_X > 0, truncate to end of drawing area. */
25823 if (to_x == 0)
25824 return;
25825 else if (to_x < 0)
25826 to_x = max_x;
25827 else
25828 to_x = min (to_x, max_x);
25829
25830 to_y = min (max_y, w->output_cursor.y + updated_row->height);
25831
25832 /* Notice if the cursor will be cleared by this operation. */
25833 if (!updated_row->full_width_p)
25834 notice_overwritten_cursor (w, updated_area,
25835 w->output_cursor.x, -1,
25836 updated_row->y,
25837 MATRIX_ROW_BOTTOM_Y (updated_row));
25838
25839 from_x = w->output_cursor.x;
25840
25841 /* Translate to frame coordinates. */
25842 if (updated_row->full_width_p)
25843 {
25844 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25845 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25846 }
25847 else
25848 {
25849 int area_left = window_box_left (w, updated_area);
25850 from_x += area_left;
25851 to_x += area_left;
25852 }
25853
25854 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25855 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
25856 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25857
25858 /* Prevent inadvertently clearing to end of the X window. */
25859 if (to_x > from_x && to_y > from_y)
25860 {
25861 block_input ();
25862 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25863 to_x - from_x, to_y - from_y);
25864 unblock_input ();
25865 }
25866 }
25867
25868 #endif /* HAVE_WINDOW_SYSTEM */
25869
25870
25871 \f
25872 /***********************************************************************
25873 Cursor types
25874 ***********************************************************************/
25875
25876 /* Value is the internal representation of the specified cursor type
25877 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25878 of the bar cursor. */
25879
25880 static enum text_cursor_kinds
25881 get_specified_cursor_type (Lisp_Object arg, int *width)
25882 {
25883 enum text_cursor_kinds type;
25884
25885 if (NILP (arg))
25886 return NO_CURSOR;
25887
25888 if (EQ (arg, Qbox))
25889 return FILLED_BOX_CURSOR;
25890
25891 if (EQ (arg, Qhollow))
25892 return HOLLOW_BOX_CURSOR;
25893
25894 if (EQ (arg, Qbar))
25895 {
25896 *width = 2;
25897 return BAR_CURSOR;
25898 }
25899
25900 if (CONSP (arg)
25901 && EQ (XCAR (arg), Qbar)
25902 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25903 {
25904 *width = XINT (XCDR (arg));
25905 return BAR_CURSOR;
25906 }
25907
25908 if (EQ (arg, Qhbar))
25909 {
25910 *width = 2;
25911 return HBAR_CURSOR;
25912 }
25913
25914 if (CONSP (arg)
25915 && EQ (XCAR (arg), Qhbar)
25916 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25917 {
25918 *width = XINT (XCDR (arg));
25919 return HBAR_CURSOR;
25920 }
25921
25922 /* Treat anything unknown as "hollow box cursor".
25923 It was bad to signal an error; people have trouble fixing
25924 .Xdefaults with Emacs, when it has something bad in it. */
25925 type = HOLLOW_BOX_CURSOR;
25926
25927 return type;
25928 }
25929
25930 /* Set the default cursor types for specified frame. */
25931 void
25932 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25933 {
25934 int width = 1;
25935 Lisp_Object tem;
25936
25937 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25938 FRAME_CURSOR_WIDTH (f) = width;
25939
25940 /* By default, set up the blink-off state depending on the on-state. */
25941
25942 tem = Fassoc (arg, Vblink_cursor_alist);
25943 if (!NILP (tem))
25944 {
25945 FRAME_BLINK_OFF_CURSOR (f)
25946 = get_specified_cursor_type (XCDR (tem), &width);
25947 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25948 }
25949 else
25950 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25951
25952 /* Make sure the cursor gets redrawn. */
25953 f->cursor_type_changed = 1;
25954 }
25955
25956
25957 #ifdef HAVE_WINDOW_SYSTEM
25958
25959 /* Return the cursor we want to be displayed in window W. Return
25960 width of bar/hbar cursor through WIDTH arg. Return with
25961 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25962 (i.e. if the `system caret' should track this cursor).
25963
25964 In a mini-buffer window, we want the cursor only to appear if we
25965 are reading input from this window. For the selected window, we
25966 want the cursor type given by the frame parameter or buffer local
25967 setting of cursor-type. If explicitly marked off, draw no cursor.
25968 In all other cases, we want a hollow box cursor. */
25969
25970 static enum text_cursor_kinds
25971 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25972 int *active_cursor)
25973 {
25974 struct frame *f = XFRAME (w->frame);
25975 struct buffer *b = XBUFFER (w->contents);
25976 int cursor_type = DEFAULT_CURSOR;
25977 Lisp_Object alt_cursor;
25978 int non_selected = 0;
25979
25980 *active_cursor = 1;
25981
25982 /* Echo area */
25983 if (cursor_in_echo_area
25984 && FRAME_HAS_MINIBUF_P (f)
25985 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25986 {
25987 if (w == XWINDOW (echo_area_window))
25988 {
25989 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25990 {
25991 *width = FRAME_CURSOR_WIDTH (f);
25992 return FRAME_DESIRED_CURSOR (f);
25993 }
25994 else
25995 return get_specified_cursor_type (BVAR (b, cursor_type), width);
25996 }
25997
25998 *active_cursor = 0;
25999 non_selected = 1;
26000 }
26001
26002 /* Detect a nonselected window or nonselected frame. */
26003 else if (w != XWINDOW (f->selected_window)
26004 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
26005 {
26006 *active_cursor = 0;
26007
26008 if (MINI_WINDOW_P (w) && minibuf_level == 0)
26009 return NO_CURSOR;
26010
26011 non_selected = 1;
26012 }
26013
26014 /* Never display a cursor in a window in which cursor-type is nil. */
26015 if (NILP (BVAR (b, cursor_type)))
26016 return NO_CURSOR;
26017
26018 /* Get the normal cursor type for this window. */
26019 if (EQ (BVAR (b, cursor_type), Qt))
26020 {
26021 cursor_type = FRAME_DESIRED_CURSOR (f);
26022 *width = FRAME_CURSOR_WIDTH (f);
26023 }
26024 else
26025 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
26026
26027 /* Use cursor-in-non-selected-windows instead
26028 for non-selected window or frame. */
26029 if (non_selected)
26030 {
26031 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
26032 if (!EQ (Qt, alt_cursor))
26033 return get_specified_cursor_type (alt_cursor, width);
26034 /* t means modify the normal cursor type. */
26035 if (cursor_type == FILLED_BOX_CURSOR)
26036 cursor_type = HOLLOW_BOX_CURSOR;
26037 else if (cursor_type == BAR_CURSOR && *width > 1)
26038 --*width;
26039 return cursor_type;
26040 }
26041
26042 /* Use normal cursor if not blinked off. */
26043 if (!w->cursor_off_p)
26044 {
26045 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26046 {
26047 if (cursor_type == FILLED_BOX_CURSOR)
26048 {
26049 /* Using a block cursor on large images can be very annoying.
26050 So use a hollow cursor for "large" images.
26051 If image is not transparent (no mask), also use hollow cursor. */
26052 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26053 if (img != NULL && IMAGEP (img->spec))
26054 {
26055 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26056 where N = size of default frame font size.
26057 This should cover most of the "tiny" icons people may use. */
26058 if (!img->mask
26059 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
26060 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
26061 cursor_type = HOLLOW_BOX_CURSOR;
26062 }
26063 }
26064 else if (cursor_type != NO_CURSOR)
26065 {
26066 /* Display current only supports BOX and HOLLOW cursors for images.
26067 So for now, unconditionally use a HOLLOW cursor when cursor is
26068 not a solid box cursor. */
26069 cursor_type = HOLLOW_BOX_CURSOR;
26070 }
26071 }
26072 return cursor_type;
26073 }
26074
26075 /* Cursor is blinked off, so determine how to "toggle" it. */
26076
26077 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26078 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
26079 return get_specified_cursor_type (XCDR (alt_cursor), width);
26080
26081 /* Then see if frame has specified a specific blink off cursor type. */
26082 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
26083 {
26084 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
26085 return FRAME_BLINK_OFF_CURSOR (f);
26086 }
26087
26088 #if 0
26089 /* Some people liked having a permanently visible blinking cursor,
26090 while others had very strong opinions against it. So it was
26091 decided to remove it. KFS 2003-09-03 */
26092
26093 /* Finally perform built-in cursor blinking:
26094 filled box <-> hollow box
26095 wide [h]bar <-> narrow [h]bar
26096 narrow [h]bar <-> no cursor
26097 other type <-> no cursor */
26098
26099 if (cursor_type == FILLED_BOX_CURSOR)
26100 return HOLLOW_BOX_CURSOR;
26101
26102 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
26103 {
26104 *width = 1;
26105 return cursor_type;
26106 }
26107 #endif
26108
26109 return NO_CURSOR;
26110 }
26111
26112
26113 /* Notice when the text cursor of window W has been completely
26114 overwritten by a drawing operation that outputs glyphs in AREA
26115 starting at X0 and ending at X1 in the line starting at Y0 and
26116 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26117 the rest of the line after X0 has been written. Y coordinates
26118 are window-relative. */
26119
26120 static void
26121 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
26122 int x0, int x1, int y0, int y1)
26123 {
26124 int cx0, cx1, cy0, cy1;
26125 struct glyph_row *row;
26126
26127 if (!w->phys_cursor_on_p)
26128 return;
26129 if (area != TEXT_AREA)
26130 return;
26131
26132 if (w->phys_cursor.vpos < 0
26133 || w->phys_cursor.vpos >= w->current_matrix->nrows
26134 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
26135 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
26136 return;
26137
26138 if (row->cursor_in_fringe_p)
26139 {
26140 row->cursor_in_fringe_p = 0;
26141 draw_fringe_bitmap (w, row, row->reversed_p);
26142 w->phys_cursor_on_p = 0;
26143 return;
26144 }
26145
26146 cx0 = w->phys_cursor.x;
26147 cx1 = cx0 + w->phys_cursor_width;
26148 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26149 return;
26150
26151 /* The cursor image will be completely removed from the
26152 screen if the output area intersects the cursor area in
26153 y-direction. When we draw in [y0 y1[, and some part of
26154 the cursor is at y < y0, that part must have been drawn
26155 before. When scrolling, the cursor is erased before
26156 actually scrolling, so we don't come here. When not
26157 scrolling, the rows above the old cursor row must have
26158 changed, and in this case these rows must have written
26159 over the cursor image.
26160
26161 Likewise if part of the cursor is below y1, with the
26162 exception of the cursor being in the first blank row at
26163 the buffer and window end because update_text_area
26164 doesn't draw that row. (Except when it does, but
26165 that's handled in update_text_area.) */
26166
26167 cy0 = w->phys_cursor.y;
26168 cy1 = cy0 + w->phys_cursor_height;
26169 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26170 return;
26171
26172 w->phys_cursor_on_p = 0;
26173 }
26174
26175 #endif /* HAVE_WINDOW_SYSTEM */
26176
26177 \f
26178 /************************************************************************
26179 Mouse Face
26180 ************************************************************************/
26181
26182 #ifdef HAVE_WINDOW_SYSTEM
26183
26184 /* EXPORT for RIF:
26185 Fix the display of area AREA of overlapping row ROW in window W
26186 with respect to the overlapping part OVERLAPS. */
26187
26188 void
26189 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26190 enum glyph_row_area area, int overlaps)
26191 {
26192 int i, x;
26193
26194 block_input ();
26195
26196 x = 0;
26197 for (i = 0; i < row->used[area];)
26198 {
26199 if (row->glyphs[area][i].overlaps_vertically_p)
26200 {
26201 int start = i, start_x = x;
26202
26203 do
26204 {
26205 x += row->glyphs[area][i].pixel_width;
26206 ++i;
26207 }
26208 while (i < row->used[area]
26209 && row->glyphs[area][i].overlaps_vertically_p);
26210
26211 draw_glyphs (w, start_x, row, area,
26212 start, i,
26213 DRAW_NORMAL_TEXT, overlaps);
26214 }
26215 else
26216 {
26217 x += row->glyphs[area][i].pixel_width;
26218 ++i;
26219 }
26220 }
26221
26222 unblock_input ();
26223 }
26224
26225
26226 /* EXPORT:
26227 Draw the cursor glyph of window W in glyph row ROW. See the
26228 comment of draw_glyphs for the meaning of HL. */
26229
26230 void
26231 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26232 enum draw_glyphs_face hl)
26233 {
26234 /* If cursor hpos is out of bounds, don't draw garbage. This can
26235 happen in mini-buffer windows when switching between echo area
26236 glyphs and mini-buffer. */
26237 if ((row->reversed_p
26238 ? (w->phys_cursor.hpos >= 0)
26239 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26240 {
26241 int on_p = w->phys_cursor_on_p;
26242 int x1;
26243 int hpos = w->phys_cursor.hpos;
26244
26245 /* When the window is hscrolled, cursor hpos can legitimately be
26246 out of bounds, but we draw the cursor at the corresponding
26247 window margin in that case. */
26248 if (!row->reversed_p && hpos < 0)
26249 hpos = 0;
26250 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26251 hpos = row->used[TEXT_AREA] - 1;
26252
26253 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26254 hl, 0);
26255 w->phys_cursor_on_p = on_p;
26256
26257 if (hl == DRAW_CURSOR)
26258 w->phys_cursor_width = x1 - w->phys_cursor.x;
26259 /* When we erase the cursor, and ROW is overlapped by other
26260 rows, make sure that these overlapping parts of other rows
26261 are redrawn. */
26262 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26263 {
26264 w->phys_cursor_width = x1 - w->phys_cursor.x;
26265
26266 if (row > w->current_matrix->rows
26267 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26268 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26269 OVERLAPS_ERASED_CURSOR);
26270
26271 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26272 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26273 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26274 OVERLAPS_ERASED_CURSOR);
26275 }
26276 }
26277 }
26278
26279
26280 /* EXPORT:
26281 Erase the image of a cursor of window W from the screen. */
26282
26283 void
26284 erase_phys_cursor (struct window *w)
26285 {
26286 struct frame *f = XFRAME (w->frame);
26287 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26288 int hpos = w->phys_cursor.hpos;
26289 int vpos = w->phys_cursor.vpos;
26290 int mouse_face_here_p = 0;
26291 struct glyph_matrix *active_glyphs = w->current_matrix;
26292 struct glyph_row *cursor_row;
26293 struct glyph *cursor_glyph;
26294 enum draw_glyphs_face hl;
26295
26296 /* No cursor displayed or row invalidated => nothing to do on the
26297 screen. */
26298 if (w->phys_cursor_type == NO_CURSOR)
26299 goto mark_cursor_off;
26300
26301 /* VPOS >= active_glyphs->nrows means that window has been resized.
26302 Don't bother to erase the cursor. */
26303 if (vpos >= active_glyphs->nrows)
26304 goto mark_cursor_off;
26305
26306 /* If row containing cursor is marked invalid, there is nothing we
26307 can do. */
26308 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26309 if (!cursor_row->enabled_p)
26310 goto mark_cursor_off;
26311
26312 /* If line spacing is > 0, old cursor may only be partially visible in
26313 window after split-window. So adjust visible height. */
26314 cursor_row->visible_height = min (cursor_row->visible_height,
26315 window_text_bottom_y (w) - cursor_row->y);
26316
26317 /* If row is completely invisible, don't attempt to delete a cursor which
26318 isn't there. This can happen if cursor is at top of a window, and
26319 we switch to a buffer with a header line in that window. */
26320 if (cursor_row->visible_height <= 0)
26321 goto mark_cursor_off;
26322
26323 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26324 if (cursor_row->cursor_in_fringe_p)
26325 {
26326 cursor_row->cursor_in_fringe_p = 0;
26327 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26328 goto mark_cursor_off;
26329 }
26330
26331 /* This can happen when the new row is shorter than the old one.
26332 In this case, either draw_glyphs or clear_end_of_line
26333 should have cleared the cursor. Note that we wouldn't be
26334 able to erase the cursor in this case because we don't have a
26335 cursor glyph at hand. */
26336 if ((cursor_row->reversed_p
26337 ? (w->phys_cursor.hpos < 0)
26338 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26339 goto mark_cursor_off;
26340
26341 /* When the window is hscrolled, cursor hpos can legitimately be out
26342 of bounds, but we draw the cursor at the corresponding window
26343 margin in that case. */
26344 if (!cursor_row->reversed_p && hpos < 0)
26345 hpos = 0;
26346 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26347 hpos = cursor_row->used[TEXT_AREA] - 1;
26348
26349 /* If the cursor is in the mouse face area, redisplay that when
26350 we clear the cursor. */
26351 if (! NILP (hlinfo->mouse_face_window)
26352 && coords_in_mouse_face_p (w, hpos, vpos)
26353 /* Don't redraw the cursor's spot in mouse face if it is at the
26354 end of a line (on a newline). The cursor appears there, but
26355 mouse highlighting does not. */
26356 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26357 mouse_face_here_p = 1;
26358
26359 /* Maybe clear the display under the cursor. */
26360 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26361 {
26362 int x, y, left_x;
26363 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26364 int width;
26365
26366 cursor_glyph = get_phys_cursor_glyph (w);
26367 if (cursor_glyph == NULL)
26368 goto mark_cursor_off;
26369
26370 width = cursor_glyph->pixel_width;
26371 left_x = window_box_left_offset (w, TEXT_AREA);
26372 x = w->phys_cursor.x;
26373 if (x < left_x)
26374 width -= left_x - x;
26375 width = min (width, window_box_width (w, TEXT_AREA) - x);
26376 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26377 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26378
26379 if (width > 0)
26380 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26381 }
26382
26383 /* Erase the cursor by redrawing the character underneath it. */
26384 if (mouse_face_here_p)
26385 hl = DRAW_MOUSE_FACE;
26386 else
26387 hl = DRAW_NORMAL_TEXT;
26388 draw_phys_cursor_glyph (w, cursor_row, hl);
26389
26390 mark_cursor_off:
26391 w->phys_cursor_on_p = 0;
26392 w->phys_cursor_type = NO_CURSOR;
26393 }
26394
26395
26396 /* EXPORT:
26397 Display or clear cursor of window W. If ON is zero, clear the
26398 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26399 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26400
26401 void
26402 display_and_set_cursor (struct window *w, bool on,
26403 int hpos, int vpos, int x, int y)
26404 {
26405 struct frame *f = XFRAME (w->frame);
26406 int new_cursor_type;
26407 int new_cursor_width;
26408 int active_cursor;
26409 struct glyph_row *glyph_row;
26410 struct glyph *glyph;
26411
26412 /* This is pointless on invisible frames, and dangerous on garbaged
26413 windows and frames; in the latter case, the frame or window may
26414 be in the midst of changing its size, and x and y may be off the
26415 window. */
26416 if (! FRAME_VISIBLE_P (f)
26417 || FRAME_GARBAGED_P (f)
26418 || vpos >= w->current_matrix->nrows
26419 || hpos >= w->current_matrix->matrix_w)
26420 return;
26421
26422 /* If cursor is off and we want it off, return quickly. */
26423 if (!on && !w->phys_cursor_on_p)
26424 return;
26425
26426 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26427 /* If cursor row is not enabled, we don't really know where to
26428 display the cursor. */
26429 if (!glyph_row->enabled_p)
26430 {
26431 w->phys_cursor_on_p = 0;
26432 return;
26433 }
26434
26435 glyph = NULL;
26436 if (!glyph_row->exact_window_width_line_p
26437 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26438 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26439
26440 eassert (input_blocked_p ());
26441
26442 /* Set new_cursor_type to the cursor we want to be displayed. */
26443 new_cursor_type = get_window_cursor_type (w, glyph,
26444 &new_cursor_width, &active_cursor);
26445
26446 /* If cursor is currently being shown and we don't want it to be or
26447 it is in the wrong place, or the cursor type is not what we want,
26448 erase it. */
26449 if (w->phys_cursor_on_p
26450 && (!on
26451 || w->phys_cursor.x != x
26452 || w->phys_cursor.y != y
26453 || new_cursor_type != w->phys_cursor_type
26454 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26455 && new_cursor_width != w->phys_cursor_width)))
26456 erase_phys_cursor (w);
26457
26458 /* Don't check phys_cursor_on_p here because that flag is only set
26459 to zero in some cases where we know that the cursor has been
26460 completely erased, to avoid the extra work of erasing the cursor
26461 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26462 still not be visible, or it has only been partly erased. */
26463 if (on)
26464 {
26465 w->phys_cursor_ascent = glyph_row->ascent;
26466 w->phys_cursor_height = glyph_row->height;
26467
26468 /* Set phys_cursor_.* before x_draw_.* is called because some
26469 of them may need the information. */
26470 w->phys_cursor.x = x;
26471 w->phys_cursor.y = glyph_row->y;
26472 w->phys_cursor.hpos = hpos;
26473 w->phys_cursor.vpos = vpos;
26474 }
26475
26476 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26477 new_cursor_type, new_cursor_width,
26478 on, active_cursor);
26479 }
26480
26481
26482 /* Switch the display of W's cursor on or off, according to the value
26483 of ON. */
26484
26485 static void
26486 update_window_cursor (struct window *w, bool on)
26487 {
26488 /* Don't update cursor in windows whose frame is in the process
26489 of being deleted. */
26490 if (w->current_matrix)
26491 {
26492 int hpos = w->phys_cursor.hpos;
26493 int vpos = w->phys_cursor.vpos;
26494 struct glyph_row *row;
26495
26496 if (vpos >= w->current_matrix->nrows
26497 || hpos >= w->current_matrix->matrix_w)
26498 return;
26499
26500 row = MATRIX_ROW (w->current_matrix, vpos);
26501
26502 /* When the window is hscrolled, cursor hpos can legitimately be
26503 out of bounds, but we draw the cursor at the corresponding
26504 window margin in that case. */
26505 if (!row->reversed_p && hpos < 0)
26506 hpos = 0;
26507 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26508 hpos = row->used[TEXT_AREA] - 1;
26509
26510 block_input ();
26511 display_and_set_cursor (w, on, hpos, vpos,
26512 w->phys_cursor.x, w->phys_cursor.y);
26513 unblock_input ();
26514 }
26515 }
26516
26517
26518 /* Call update_window_cursor with parameter ON_P on all leaf windows
26519 in the window tree rooted at W. */
26520
26521 static void
26522 update_cursor_in_window_tree (struct window *w, bool on_p)
26523 {
26524 while (w)
26525 {
26526 if (WINDOWP (w->contents))
26527 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26528 else
26529 update_window_cursor (w, on_p);
26530
26531 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26532 }
26533 }
26534
26535
26536 /* EXPORT:
26537 Display the cursor on window W, or clear it, according to ON_P.
26538 Don't change the cursor's position. */
26539
26540 void
26541 x_update_cursor (struct frame *f, bool on_p)
26542 {
26543 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26544 }
26545
26546
26547 /* EXPORT:
26548 Clear the cursor of window W to background color, and mark the
26549 cursor as not shown. This is used when the text where the cursor
26550 is about to be rewritten. */
26551
26552 void
26553 x_clear_cursor (struct window *w)
26554 {
26555 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26556 update_window_cursor (w, 0);
26557 }
26558
26559 #endif /* HAVE_WINDOW_SYSTEM */
26560
26561 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26562 and MSDOS. */
26563 static void
26564 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26565 int start_hpos, int end_hpos,
26566 enum draw_glyphs_face draw)
26567 {
26568 #ifdef HAVE_WINDOW_SYSTEM
26569 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26570 {
26571 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26572 return;
26573 }
26574 #endif
26575 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26576 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26577 #endif
26578 }
26579
26580 /* Display the active region described by mouse_face_* according to DRAW. */
26581
26582 static void
26583 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26584 {
26585 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26586 struct frame *f = XFRAME (WINDOW_FRAME (w));
26587
26588 if (/* If window is in the process of being destroyed, don't bother
26589 to do anything. */
26590 w->current_matrix != NULL
26591 /* Don't update mouse highlight if hidden */
26592 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26593 /* Recognize when we are called to operate on rows that don't exist
26594 anymore. This can happen when a window is split. */
26595 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26596 {
26597 int phys_cursor_on_p = w->phys_cursor_on_p;
26598 struct glyph_row *row, *first, *last;
26599
26600 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26601 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26602
26603 for (row = first; row <= last && row->enabled_p; ++row)
26604 {
26605 int start_hpos, end_hpos, start_x;
26606
26607 /* For all but the first row, the highlight starts at column 0. */
26608 if (row == first)
26609 {
26610 /* R2L rows have BEG and END in reversed order, but the
26611 screen drawing geometry is always left to right. So
26612 we need to mirror the beginning and end of the
26613 highlighted area in R2L rows. */
26614 if (!row->reversed_p)
26615 {
26616 start_hpos = hlinfo->mouse_face_beg_col;
26617 start_x = hlinfo->mouse_face_beg_x;
26618 }
26619 else if (row == last)
26620 {
26621 start_hpos = hlinfo->mouse_face_end_col;
26622 start_x = hlinfo->mouse_face_end_x;
26623 }
26624 else
26625 {
26626 start_hpos = 0;
26627 start_x = 0;
26628 }
26629 }
26630 else if (row->reversed_p && row == last)
26631 {
26632 start_hpos = hlinfo->mouse_face_end_col;
26633 start_x = hlinfo->mouse_face_end_x;
26634 }
26635 else
26636 {
26637 start_hpos = 0;
26638 start_x = 0;
26639 }
26640
26641 if (row == last)
26642 {
26643 if (!row->reversed_p)
26644 end_hpos = hlinfo->mouse_face_end_col;
26645 else if (row == first)
26646 end_hpos = hlinfo->mouse_face_beg_col;
26647 else
26648 {
26649 end_hpos = row->used[TEXT_AREA];
26650 if (draw == DRAW_NORMAL_TEXT)
26651 row->fill_line_p = 1; /* Clear to end of line */
26652 }
26653 }
26654 else if (row->reversed_p && row == first)
26655 end_hpos = hlinfo->mouse_face_beg_col;
26656 else
26657 {
26658 end_hpos = row->used[TEXT_AREA];
26659 if (draw == DRAW_NORMAL_TEXT)
26660 row->fill_line_p = 1; /* Clear to end of line */
26661 }
26662
26663 if (end_hpos > start_hpos)
26664 {
26665 draw_row_with_mouse_face (w, start_x, row,
26666 start_hpos, end_hpos, draw);
26667
26668 row->mouse_face_p
26669 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26670 }
26671 }
26672
26673 #ifdef HAVE_WINDOW_SYSTEM
26674 /* When we've written over the cursor, arrange for it to
26675 be displayed again. */
26676 if (FRAME_WINDOW_P (f)
26677 && phys_cursor_on_p && !w->phys_cursor_on_p)
26678 {
26679 int hpos = w->phys_cursor.hpos;
26680
26681 /* When the window is hscrolled, cursor hpos can legitimately be
26682 out of bounds, but we draw the cursor at the corresponding
26683 window margin in that case. */
26684 if (!row->reversed_p && hpos < 0)
26685 hpos = 0;
26686 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26687 hpos = row->used[TEXT_AREA] - 1;
26688
26689 block_input ();
26690 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26691 w->phys_cursor.x, w->phys_cursor.y);
26692 unblock_input ();
26693 }
26694 #endif /* HAVE_WINDOW_SYSTEM */
26695 }
26696
26697 #ifdef HAVE_WINDOW_SYSTEM
26698 /* Change the mouse cursor. */
26699 if (FRAME_WINDOW_P (f))
26700 {
26701 if (draw == DRAW_NORMAL_TEXT
26702 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26703 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26704 else if (draw == DRAW_MOUSE_FACE)
26705 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26706 else
26707 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26708 }
26709 #endif /* HAVE_WINDOW_SYSTEM */
26710 }
26711
26712 /* EXPORT:
26713 Clear out the mouse-highlighted active region.
26714 Redraw it un-highlighted first. Value is non-zero if mouse
26715 face was actually drawn unhighlighted. */
26716
26717 int
26718 clear_mouse_face (Mouse_HLInfo *hlinfo)
26719 {
26720 int cleared = 0;
26721
26722 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26723 {
26724 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26725 cleared = 1;
26726 }
26727
26728 reset_mouse_highlight (hlinfo);
26729 return cleared;
26730 }
26731
26732 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26733 within the mouse face on that window. */
26734 static int
26735 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26736 {
26737 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26738
26739 /* Quickly resolve the easy cases. */
26740 if (!(WINDOWP (hlinfo->mouse_face_window)
26741 && XWINDOW (hlinfo->mouse_face_window) == w))
26742 return 0;
26743 if (vpos < hlinfo->mouse_face_beg_row
26744 || vpos > hlinfo->mouse_face_end_row)
26745 return 0;
26746 if (vpos > hlinfo->mouse_face_beg_row
26747 && vpos < hlinfo->mouse_face_end_row)
26748 return 1;
26749
26750 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26751 {
26752 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26753 {
26754 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26755 return 1;
26756 }
26757 else if ((vpos == hlinfo->mouse_face_beg_row
26758 && hpos >= hlinfo->mouse_face_beg_col)
26759 || (vpos == hlinfo->mouse_face_end_row
26760 && hpos < hlinfo->mouse_face_end_col))
26761 return 1;
26762 }
26763 else
26764 {
26765 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26766 {
26767 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26768 return 1;
26769 }
26770 else if ((vpos == hlinfo->mouse_face_beg_row
26771 && hpos <= hlinfo->mouse_face_beg_col)
26772 || (vpos == hlinfo->mouse_face_end_row
26773 && hpos > hlinfo->mouse_face_end_col))
26774 return 1;
26775 }
26776 return 0;
26777 }
26778
26779
26780 /* EXPORT:
26781 Non-zero if physical cursor of window W is within mouse face. */
26782
26783 int
26784 cursor_in_mouse_face_p (struct window *w)
26785 {
26786 int hpos = w->phys_cursor.hpos;
26787 int vpos = w->phys_cursor.vpos;
26788 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26789
26790 /* When the window is hscrolled, cursor hpos can legitimately be out
26791 of bounds, but we draw the cursor at the corresponding window
26792 margin in that case. */
26793 if (!row->reversed_p && hpos < 0)
26794 hpos = 0;
26795 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26796 hpos = row->used[TEXT_AREA] - 1;
26797
26798 return coords_in_mouse_face_p (w, hpos, vpos);
26799 }
26800
26801
26802 \f
26803 /* Find the glyph rows START_ROW and END_ROW of window W that display
26804 characters between buffer positions START_CHARPOS and END_CHARPOS
26805 (excluding END_CHARPOS). DISP_STRING is a display string that
26806 covers these buffer positions. This is similar to
26807 row_containing_pos, but is more accurate when bidi reordering makes
26808 buffer positions change non-linearly with glyph rows. */
26809 static void
26810 rows_from_pos_range (struct window *w,
26811 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26812 Lisp_Object disp_string,
26813 struct glyph_row **start, struct glyph_row **end)
26814 {
26815 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26816 int last_y = window_text_bottom_y (w);
26817 struct glyph_row *row;
26818
26819 *start = NULL;
26820 *end = NULL;
26821
26822 while (!first->enabled_p
26823 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26824 first++;
26825
26826 /* Find the START row. */
26827 for (row = first;
26828 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26829 row++)
26830 {
26831 /* A row can potentially be the START row if the range of the
26832 characters it displays intersects the range
26833 [START_CHARPOS..END_CHARPOS). */
26834 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26835 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26836 /* See the commentary in row_containing_pos, for the
26837 explanation of the complicated way to check whether
26838 some position is beyond the end of the characters
26839 displayed by a row. */
26840 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26841 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26842 && !row->ends_at_zv_p
26843 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26844 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26845 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26846 && !row->ends_at_zv_p
26847 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26848 {
26849 /* Found a candidate row. Now make sure at least one of the
26850 glyphs it displays has a charpos from the range
26851 [START_CHARPOS..END_CHARPOS).
26852
26853 This is not obvious because bidi reordering could make
26854 buffer positions of a row be 1,2,3,102,101,100, and if we
26855 want to highlight characters in [50..60), we don't want
26856 this row, even though [50..60) does intersect [1..103),
26857 the range of character positions given by the row's start
26858 and end positions. */
26859 struct glyph *g = row->glyphs[TEXT_AREA];
26860 struct glyph *e = g + row->used[TEXT_AREA];
26861
26862 while (g < e)
26863 {
26864 if (((BUFFERP (g->object) || INTEGERP (g->object))
26865 && start_charpos <= g->charpos && g->charpos < end_charpos)
26866 /* A glyph that comes from DISP_STRING is by
26867 definition to be highlighted. */
26868 || EQ (g->object, disp_string))
26869 *start = row;
26870 g++;
26871 }
26872 if (*start)
26873 break;
26874 }
26875 }
26876
26877 /* Find the END row. */
26878 if (!*start
26879 /* If the last row is partially visible, start looking for END
26880 from that row, instead of starting from FIRST. */
26881 && !(row->enabled_p
26882 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26883 row = first;
26884 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26885 {
26886 struct glyph_row *next = row + 1;
26887 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26888
26889 if (!next->enabled_p
26890 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26891 /* The first row >= START whose range of displayed characters
26892 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26893 is the row END + 1. */
26894 || (start_charpos < next_start
26895 && end_charpos < next_start)
26896 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26897 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26898 && !next->ends_at_zv_p
26899 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26900 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26901 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26902 && !next->ends_at_zv_p
26903 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26904 {
26905 *end = row;
26906 break;
26907 }
26908 else
26909 {
26910 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26911 but none of the characters it displays are in the range, it is
26912 also END + 1. */
26913 struct glyph *g = next->glyphs[TEXT_AREA];
26914 struct glyph *s = g;
26915 struct glyph *e = g + next->used[TEXT_AREA];
26916
26917 while (g < e)
26918 {
26919 if (((BUFFERP (g->object) || INTEGERP (g->object))
26920 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26921 /* If the buffer position of the first glyph in
26922 the row is equal to END_CHARPOS, it means
26923 the last character to be highlighted is the
26924 newline of ROW, and we must consider NEXT as
26925 END, not END+1. */
26926 || (((!next->reversed_p && g == s)
26927 || (next->reversed_p && g == e - 1))
26928 && (g->charpos == end_charpos
26929 /* Special case for when NEXT is an
26930 empty line at ZV. */
26931 || (g->charpos == -1
26932 && !row->ends_at_zv_p
26933 && next_start == end_charpos)))))
26934 /* A glyph that comes from DISP_STRING is by
26935 definition to be highlighted. */
26936 || EQ (g->object, disp_string))
26937 break;
26938 g++;
26939 }
26940 if (g == e)
26941 {
26942 *end = row;
26943 break;
26944 }
26945 /* The first row that ends at ZV must be the last to be
26946 highlighted. */
26947 else if (next->ends_at_zv_p)
26948 {
26949 *end = next;
26950 break;
26951 }
26952 }
26953 }
26954 }
26955
26956 /* This function sets the mouse_face_* elements of HLINFO, assuming
26957 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26958 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26959 for the overlay or run of text properties specifying the mouse
26960 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26961 before-string and after-string that must also be highlighted.
26962 DISP_STRING, if non-nil, is a display string that may cover some
26963 or all of the highlighted text. */
26964
26965 static void
26966 mouse_face_from_buffer_pos (Lisp_Object window,
26967 Mouse_HLInfo *hlinfo,
26968 ptrdiff_t mouse_charpos,
26969 ptrdiff_t start_charpos,
26970 ptrdiff_t end_charpos,
26971 Lisp_Object before_string,
26972 Lisp_Object after_string,
26973 Lisp_Object disp_string)
26974 {
26975 struct window *w = XWINDOW (window);
26976 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26977 struct glyph_row *r1, *r2;
26978 struct glyph *glyph, *end;
26979 ptrdiff_t ignore, pos;
26980 int x;
26981
26982 eassert (NILP (disp_string) || STRINGP (disp_string));
26983 eassert (NILP (before_string) || STRINGP (before_string));
26984 eassert (NILP (after_string) || STRINGP (after_string));
26985
26986 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26987 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26988 if (r1 == NULL)
26989 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
26990 /* If the before-string or display-string contains newlines,
26991 rows_from_pos_range skips to its last row. Move back. */
26992 if (!NILP (before_string) || !NILP (disp_string))
26993 {
26994 struct glyph_row *prev;
26995 while ((prev = r1 - 1, prev >= first)
26996 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
26997 && prev->used[TEXT_AREA] > 0)
26998 {
26999 struct glyph *beg = prev->glyphs[TEXT_AREA];
27000 glyph = beg + prev->used[TEXT_AREA];
27001 while (--glyph >= beg && INTEGERP (glyph->object));
27002 if (glyph < beg
27003 || !(EQ (glyph->object, before_string)
27004 || EQ (glyph->object, disp_string)))
27005 break;
27006 r1 = prev;
27007 }
27008 }
27009 if (r2 == NULL)
27010 {
27011 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27012 hlinfo->mouse_face_past_end = 1;
27013 }
27014 else if (!NILP (after_string))
27015 {
27016 /* If the after-string has newlines, advance to its last row. */
27017 struct glyph_row *next;
27018 struct glyph_row *last
27019 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27020
27021 for (next = r2 + 1;
27022 next <= last
27023 && next->used[TEXT_AREA] > 0
27024 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
27025 ++next)
27026 r2 = next;
27027 }
27028 /* The rest of the display engine assumes that mouse_face_beg_row is
27029 either above mouse_face_end_row or identical to it. But with
27030 bidi-reordered continued lines, the row for START_CHARPOS could
27031 be below the row for END_CHARPOS. If so, swap the rows and store
27032 them in correct order. */
27033 if (r1->y > r2->y)
27034 {
27035 struct glyph_row *tem = r2;
27036
27037 r2 = r1;
27038 r1 = tem;
27039 }
27040
27041 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27042 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27043
27044 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27045 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27046 could be anywhere in the row and in any order. The strategy
27047 below is to find the leftmost and the rightmost glyph that
27048 belongs to either of these 3 strings, or whose position is
27049 between START_CHARPOS and END_CHARPOS, and highlight all the
27050 glyphs between those two. This may cover more than just the text
27051 between START_CHARPOS and END_CHARPOS if the range of characters
27052 strides the bidi level boundary, e.g. if the beginning is in R2L
27053 text while the end is in L2R text or vice versa. */
27054 if (!r1->reversed_p)
27055 {
27056 /* This row is in a left to right paragraph. Scan it left to
27057 right. */
27058 glyph = r1->glyphs[TEXT_AREA];
27059 end = glyph + r1->used[TEXT_AREA];
27060 x = r1->x;
27061
27062 /* Skip truncation glyphs at the start of the glyph row. */
27063 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27064 for (; glyph < end
27065 && INTEGERP (glyph->object)
27066 && glyph->charpos < 0;
27067 ++glyph)
27068 x += glyph->pixel_width;
27069
27070 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27071 or DISP_STRING, and the first glyph from buffer whose
27072 position is between START_CHARPOS and END_CHARPOS. */
27073 for (; glyph < end
27074 && !INTEGERP (glyph->object)
27075 && !EQ (glyph->object, disp_string)
27076 && !(BUFFERP (glyph->object)
27077 && (glyph->charpos >= start_charpos
27078 && glyph->charpos < end_charpos));
27079 ++glyph)
27080 {
27081 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27082 are present at buffer positions between START_CHARPOS and
27083 END_CHARPOS, or if they come from an overlay. */
27084 if (EQ (glyph->object, before_string))
27085 {
27086 pos = string_buffer_position (before_string,
27087 start_charpos);
27088 /* If pos == 0, it means before_string came from an
27089 overlay, not from a buffer position. */
27090 if (!pos || (pos >= start_charpos && pos < end_charpos))
27091 break;
27092 }
27093 else if (EQ (glyph->object, after_string))
27094 {
27095 pos = string_buffer_position (after_string, end_charpos);
27096 if (!pos || (pos >= start_charpos && pos < end_charpos))
27097 break;
27098 }
27099 x += glyph->pixel_width;
27100 }
27101 hlinfo->mouse_face_beg_x = x;
27102 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27103 }
27104 else
27105 {
27106 /* This row is in a right to left paragraph. Scan it right to
27107 left. */
27108 struct glyph *g;
27109
27110 end = r1->glyphs[TEXT_AREA] - 1;
27111 glyph = end + r1->used[TEXT_AREA];
27112
27113 /* Skip truncation glyphs at the start of the glyph row. */
27114 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27115 for (; glyph > end
27116 && INTEGERP (glyph->object)
27117 && glyph->charpos < 0;
27118 --glyph)
27119 ;
27120
27121 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27122 or DISP_STRING, and the first glyph from buffer whose
27123 position is between START_CHARPOS and END_CHARPOS. */
27124 for (; glyph > end
27125 && !INTEGERP (glyph->object)
27126 && !EQ (glyph->object, disp_string)
27127 && !(BUFFERP (glyph->object)
27128 && (glyph->charpos >= start_charpos
27129 && glyph->charpos < end_charpos));
27130 --glyph)
27131 {
27132 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27133 are present at buffer positions between START_CHARPOS and
27134 END_CHARPOS, or if they come from an overlay. */
27135 if (EQ (glyph->object, before_string))
27136 {
27137 pos = string_buffer_position (before_string, start_charpos);
27138 /* If pos == 0, it means before_string came from an
27139 overlay, not from a buffer position. */
27140 if (!pos || (pos >= start_charpos && pos < end_charpos))
27141 break;
27142 }
27143 else if (EQ (glyph->object, after_string))
27144 {
27145 pos = string_buffer_position (after_string, end_charpos);
27146 if (!pos || (pos >= start_charpos && pos < end_charpos))
27147 break;
27148 }
27149 }
27150
27151 glyph++; /* first glyph to the right of the highlighted area */
27152 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27153 x += g->pixel_width;
27154 hlinfo->mouse_face_beg_x = x;
27155 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27156 }
27157
27158 /* If the highlight ends in a different row, compute GLYPH and END
27159 for the end row. Otherwise, reuse the values computed above for
27160 the row where the highlight begins. */
27161 if (r2 != r1)
27162 {
27163 if (!r2->reversed_p)
27164 {
27165 glyph = r2->glyphs[TEXT_AREA];
27166 end = glyph + r2->used[TEXT_AREA];
27167 x = r2->x;
27168 }
27169 else
27170 {
27171 end = r2->glyphs[TEXT_AREA] - 1;
27172 glyph = end + r2->used[TEXT_AREA];
27173 }
27174 }
27175
27176 if (!r2->reversed_p)
27177 {
27178 /* Skip truncation and continuation glyphs near the end of the
27179 row, and also blanks and stretch glyphs inserted by
27180 extend_face_to_end_of_line. */
27181 while (end > glyph
27182 && INTEGERP ((end - 1)->object))
27183 --end;
27184 /* Scan the rest of the glyph row from the end, looking for the
27185 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27186 DISP_STRING, or whose position is between START_CHARPOS
27187 and END_CHARPOS */
27188 for (--end;
27189 end > glyph
27190 && !INTEGERP (end->object)
27191 && !EQ (end->object, disp_string)
27192 && !(BUFFERP (end->object)
27193 && (end->charpos >= start_charpos
27194 && end->charpos < end_charpos));
27195 --end)
27196 {
27197 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27198 are present at buffer positions between START_CHARPOS and
27199 END_CHARPOS, or if they come from an overlay. */
27200 if (EQ (end->object, before_string))
27201 {
27202 pos = string_buffer_position (before_string, start_charpos);
27203 if (!pos || (pos >= start_charpos && pos < end_charpos))
27204 break;
27205 }
27206 else if (EQ (end->object, after_string))
27207 {
27208 pos = string_buffer_position (after_string, end_charpos);
27209 if (!pos || (pos >= start_charpos && pos < end_charpos))
27210 break;
27211 }
27212 }
27213 /* Find the X coordinate of the last glyph to be highlighted. */
27214 for (; glyph <= end; ++glyph)
27215 x += glyph->pixel_width;
27216
27217 hlinfo->mouse_face_end_x = x;
27218 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27219 }
27220 else
27221 {
27222 /* Skip truncation and continuation glyphs near the end of the
27223 row, and also blanks and stretch glyphs inserted by
27224 extend_face_to_end_of_line. */
27225 x = r2->x;
27226 end++;
27227 while (end < glyph
27228 && INTEGERP (end->object))
27229 {
27230 x += end->pixel_width;
27231 ++end;
27232 }
27233 /* Scan the rest of the glyph row from the end, looking for the
27234 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27235 DISP_STRING, or whose position is between START_CHARPOS
27236 and END_CHARPOS */
27237 for ( ;
27238 end < glyph
27239 && !INTEGERP (end->object)
27240 && !EQ (end->object, disp_string)
27241 && !(BUFFERP (end->object)
27242 && (end->charpos >= start_charpos
27243 && end->charpos < end_charpos));
27244 ++end)
27245 {
27246 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27247 are present at buffer positions between START_CHARPOS and
27248 END_CHARPOS, or if they come from an overlay. */
27249 if (EQ (end->object, before_string))
27250 {
27251 pos = string_buffer_position (before_string, start_charpos);
27252 if (!pos || (pos >= start_charpos && pos < end_charpos))
27253 break;
27254 }
27255 else if (EQ (end->object, after_string))
27256 {
27257 pos = string_buffer_position (after_string, end_charpos);
27258 if (!pos || (pos >= start_charpos && pos < end_charpos))
27259 break;
27260 }
27261 x += end->pixel_width;
27262 }
27263 /* If we exited the above loop because we arrived at the last
27264 glyph of the row, and its buffer position is still not in
27265 range, it means the last character in range is the preceding
27266 newline. Bump the end column and x values to get past the
27267 last glyph. */
27268 if (end == glyph
27269 && BUFFERP (end->object)
27270 && (end->charpos < start_charpos
27271 || end->charpos >= end_charpos))
27272 {
27273 x += end->pixel_width;
27274 ++end;
27275 }
27276 hlinfo->mouse_face_end_x = x;
27277 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27278 }
27279
27280 hlinfo->mouse_face_window = window;
27281 hlinfo->mouse_face_face_id
27282 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
27283 mouse_charpos + 1,
27284 !hlinfo->mouse_face_hidden, -1);
27285 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27286 }
27287
27288 /* The following function is not used anymore (replaced with
27289 mouse_face_from_string_pos), but I leave it here for the time
27290 being, in case someone would. */
27291
27292 #if 0 /* not used */
27293
27294 /* Find the position of the glyph for position POS in OBJECT in
27295 window W's current matrix, and return in *X, *Y the pixel
27296 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27297
27298 RIGHT_P non-zero means return the position of the right edge of the
27299 glyph, RIGHT_P zero means return the left edge position.
27300
27301 If no glyph for POS exists in the matrix, return the position of
27302 the glyph with the next smaller position that is in the matrix, if
27303 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27304 exists in the matrix, return the position of the glyph with the
27305 next larger position in OBJECT.
27306
27307 Value is non-zero if a glyph was found. */
27308
27309 static int
27310 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27311 int *hpos, int *vpos, int *x, int *y, int right_p)
27312 {
27313 int yb = window_text_bottom_y (w);
27314 struct glyph_row *r;
27315 struct glyph *best_glyph = NULL;
27316 struct glyph_row *best_row = NULL;
27317 int best_x = 0;
27318
27319 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27320 r->enabled_p && r->y < yb;
27321 ++r)
27322 {
27323 struct glyph *g = r->glyphs[TEXT_AREA];
27324 struct glyph *e = g + r->used[TEXT_AREA];
27325 int gx;
27326
27327 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27328 if (EQ (g->object, object))
27329 {
27330 if (g->charpos == pos)
27331 {
27332 best_glyph = g;
27333 best_x = gx;
27334 best_row = r;
27335 goto found;
27336 }
27337 else if (best_glyph == NULL
27338 || ((eabs (g->charpos - pos)
27339 < eabs (best_glyph->charpos - pos))
27340 && (right_p
27341 ? g->charpos < pos
27342 : g->charpos > pos)))
27343 {
27344 best_glyph = g;
27345 best_x = gx;
27346 best_row = r;
27347 }
27348 }
27349 }
27350
27351 found:
27352
27353 if (best_glyph)
27354 {
27355 *x = best_x;
27356 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27357
27358 if (right_p)
27359 {
27360 *x += best_glyph->pixel_width;
27361 ++*hpos;
27362 }
27363
27364 *y = best_row->y;
27365 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
27366 }
27367
27368 return best_glyph != NULL;
27369 }
27370 #endif /* not used */
27371
27372 /* Find the positions of the first and the last glyphs in window W's
27373 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27374 (assumed to be a string), and return in HLINFO's mouse_face_*
27375 members the pixel and column/row coordinates of those glyphs. */
27376
27377 static void
27378 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27379 Lisp_Object object,
27380 ptrdiff_t startpos, ptrdiff_t endpos)
27381 {
27382 int yb = window_text_bottom_y (w);
27383 struct glyph_row *r;
27384 struct glyph *g, *e;
27385 int gx;
27386 int found = 0;
27387
27388 /* Find the glyph row with at least one position in the range
27389 [STARTPOS..ENDPOS], and the first glyph in that row whose
27390 position belongs to that range. */
27391 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27392 r->enabled_p && r->y < yb;
27393 ++r)
27394 {
27395 if (!r->reversed_p)
27396 {
27397 g = r->glyphs[TEXT_AREA];
27398 e = g + r->used[TEXT_AREA];
27399 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27400 if (EQ (g->object, object)
27401 && startpos <= g->charpos && g->charpos <= endpos)
27402 {
27403 hlinfo->mouse_face_beg_row
27404 = MATRIX_ROW_VPOS (r, w->current_matrix);
27405 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27406 hlinfo->mouse_face_beg_x = gx;
27407 found = 1;
27408 break;
27409 }
27410 }
27411 else
27412 {
27413 struct glyph *g1;
27414
27415 e = r->glyphs[TEXT_AREA];
27416 g = e + r->used[TEXT_AREA];
27417 for ( ; g > e; --g)
27418 if (EQ ((g-1)->object, object)
27419 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27420 {
27421 hlinfo->mouse_face_beg_row
27422 = MATRIX_ROW_VPOS (r, w->current_matrix);
27423 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27424 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27425 gx += g1->pixel_width;
27426 hlinfo->mouse_face_beg_x = gx;
27427 found = 1;
27428 break;
27429 }
27430 }
27431 if (found)
27432 break;
27433 }
27434
27435 if (!found)
27436 return;
27437
27438 /* Starting with the next row, look for the first row which does NOT
27439 include any glyphs whose positions are in the range. */
27440 for (++r; r->enabled_p && r->y < yb; ++r)
27441 {
27442 g = r->glyphs[TEXT_AREA];
27443 e = g + r->used[TEXT_AREA];
27444 found = 0;
27445 for ( ; g < e; ++g)
27446 if (EQ (g->object, object)
27447 && startpos <= g->charpos && g->charpos <= endpos)
27448 {
27449 found = 1;
27450 break;
27451 }
27452 if (!found)
27453 break;
27454 }
27455
27456 /* The highlighted region ends on the previous row. */
27457 r--;
27458
27459 /* Set the end row. */
27460 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27461
27462 /* Compute and set the end column and the end column's horizontal
27463 pixel coordinate. */
27464 if (!r->reversed_p)
27465 {
27466 g = r->glyphs[TEXT_AREA];
27467 e = g + r->used[TEXT_AREA];
27468 for ( ; e > g; --e)
27469 if (EQ ((e-1)->object, object)
27470 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27471 break;
27472 hlinfo->mouse_face_end_col = e - g;
27473
27474 for (gx = r->x; g < e; ++g)
27475 gx += g->pixel_width;
27476 hlinfo->mouse_face_end_x = gx;
27477 }
27478 else
27479 {
27480 e = r->glyphs[TEXT_AREA];
27481 g = e + r->used[TEXT_AREA];
27482 for (gx = r->x ; e < g; ++e)
27483 {
27484 if (EQ (e->object, object)
27485 && startpos <= e->charpos && e->charpos <= endpos)
27486 break;
27487 gx += e->pixel_width;
27488 }
27489 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27490 hlinfo->mouse_face_end_x = gx;
27491 }
27492 }
27493
27494 #ifdef HAVE_WINDOW_SYSTEM
27495
27496 /* See if position X, Y is within a hot-spot of an image. */
27497
27498 static int
27499 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27500 {
27501 if (!CONSP (hot_spot))
27502 return 0;
27503
27504 if (EQ (XCAR (hot_spot), Qrect))
27505 {
27506 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27507 Lisp_Object rect = XCDR (hot_spot);
27508 Lisp_Object tem;
27509 if (!CONSP (rect))
27510 return 0;
27511 if (!CONSP (XCAR (rect)))
27512 return 0;
27513 if (!CONSP (XCDR (rect)))
27514 return 0;
27515 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27516 return 0;
27517 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27518 return 0;
27519 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27520 return 0;
27521 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27522 return 0;
27523 return 1;
27524 }
27525 else if (EQ (XCAR (hot_spot), Qcircle))
27526 {
27527 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27528 Lisp_Object circ = XCDR (hot_spot);
27529 Lisp_Object lr, lx0, ly0;
27530 if (CONSP (circ)
27531 && CONSP (XCAR (circ))
27532 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27533 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27534 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27535 {
27536 double r = XFLOATINT (lr);
27537 double dx = XINT (lx0) - x;
27538 double dy = XINT (ly0) - y;
27539 return (dx * dx + dy * dy <= r * r);
27540 }
27541 }
27542 else if (EQ (XCAR (hot_spot), Qpoly))
27543 {
27544 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27545 if (VECTORP (XCDR (hot_spot)))
27546 {
27547 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27548 Lisp_Object *poly = v->contents;
27549 ptrdiff_t n = v->header.size;
27550 ptrdiff_t i;
27551 int inside = 0;
27552 Lisp_Object lx, ly;
27553 int x0, y0;
27554
27555 /* Need an even number of coordinates, and at least 3 edges. */
27556 if (n < 6 || n & 1)
27557 return 0;
27558
27559 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27560 If count is odd, we are inside polygon. Pixels on edges
27561 may or may not be included depending on actual geometry of the
27562 polygon. */
27563 if ((lx = poly[n-2], !INTEGERP (lx))
27564 || (ly = poly[n-1], !INTEGERP (lx)))
27565 return 0;
27566 x0 = XINT (lx), y0 = XINT (ly);
27567 for (i = 0; i < n; i += 2)
27568 {
27569 int x1 = x0, y1 = y0;
27570 if ((lx = poly[i], !INTEGERP (lx))
27571 || (ly = poly[i+1], !INTEGERP (ly)))
27572 return 0;
27573 x0 = XINT (lx), y0 = XINT (ly);
27574
27575 /* Does this segment cross the X line? */
27576 if (x0 >= x)
27577 {
27578 if (x1 >= x)
27579 continue;
27580 }
27581 else if (x1 < x)
27582 continue;
27583 if (y > y0 && y > y1)
27584 continue;
27585 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27586 inside = !inside;
27587 }
27588 return inside;
27589 }
27590 }
27591 return 0;
27592 }
27593
27594 Lisp_Object
27595 find_hot_spot (Lisp_Object map, int x, int y)
27596 {
27597 while (CONSP (map))
27598 {
27599 if (CONSP (XCAR (map))
27600 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27601 return XCAR (map);
27602 map = XCDR (map);
27603 }
27604
27605 return Qnil;
27606 }
27607
27608 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27609 3, 3, 0,
27610 doc: /* Lookup in image map MAP coordinates X and Y.
27611 An image map is an alist where each element has the format (AREA ID PLIST).
27612 An AREA is specified as either a rectangle, a circle, or a polygon:
27613 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27614 pixel coordinates of the upper left and bottom right corners.
27615 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27616 and the radius of the circle; r may be a float or integer.
27617 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27618 vector describes one corner in the polygon.
27619 Returns the alist element for the first matching AREA in MAP. */)
27620 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27621 {
27622 if (NILP (map))
27623 return Qnil;
27624
27625 CHECK_NUMBER (x);
27626 CHECK_NUMBER (y);
27627
27628 return find_hot_spot (map,
27629 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27630 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27631 }
27632
27633
27634 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27635 static void
27636 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27637 {
27638 /* Do not change cursor shape while dragging mouse. */
27639 if (!NILP (do_mouse_tracking))
27640 return;
27641
27642 if (!NILP (pointer))
27643 {
27644 if (EQ (pointer, Qarrow))
27645 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27646 else if (EQ (pointer, Qhand))
27647 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27648 else if (EQ (pointer, Qtext))
27649 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27650 else if (EQ (pointer, intern ("hdrag")))
27651 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27652 #ifdef HAVE_X_WINDOWS
27653 else if (EQ (pointer, intern ("vdrag")))
27654 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27655 #endif
27656 else if (EQ (pointer, intern ("hourglass")))
27657 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27658 else if (EQ (pointer, Qmodeline))
27659 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27660 else
27661 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27662 }
27663
27664 if (cursor != No_Cursor)
27665 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27666 }
27667
27668 #endif /* HAVE_WINDOW_SYSTEM */
27669
27670 /* Take proper action when mouse has moved to the mode or header line
27671 or marginal area AREA of window W, x-position X and y-position Y.
27672 X is relative to the start of the text display area of W, so the
27673 width of bitmap areas and scroll bars must be subtracted to get a
27674 position relative to the start of the mode line. */
27675
27676 static void
27677 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27678 enum window_part area)
27679 {
27680 struct window *w = XWINDOW (window);
27681 struct frame *f = XFRAME (w->frame);
27682 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27683 #ifdef HAVE_WINDOW_SYSTEM
27684 Display_Info *dpyinfo;
27685 #endif
27686 Cursor cursor = No_Cursor;
27687 Lisp_Object pointer = Qnil;
27688 int dx, dy, width, height;
27689 ptrdiff_t charpos;
27690 Lisp_Object string, object = Qnil;
27691 Lisp_Object pos IF_LINT (= Qnil), help;
27692
27693 Lisp_Object mouse_face;
27694 int original_x_pixel = x;
27695 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27696 struct glyph_row *row IF_LINT (= 0);
27697
27698 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27699 {
27700 int x0;
27701 struct glyph *end;
27702
27703 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27704 returns them in row/column units! */
27705 string = mode_line_string (w, area, &x, &y, &charpos,
27706 &object, &dx, &dy, &width, &height);
27707
27708 row = (area == ON_MODE_LINE
27709 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27710 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27711
27712 /* Find the glyph under the mouse pointer. */
27713 if (row->mode_line_p && row->enabled_p)
27714 {
27715 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27716 end = glyph + row->used[TEXT_AREA];
27717
27718 for (x0 = original_x_pixel;
27719 glyph < end && x0 >= glyph->pixel_width;
27720 ++glyph)
27721 x0 -= glyph->pixel_width;
27722
27723 if (glyph >= end)
27724 glyph = NULL;
27725 }
27726 }
27727 else
27728 {
27729 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27730 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27731 returns them in row/column units! */
27732 string = marginal_area_string (w, area, &x, &y, &charpos,
27733 &object, &dx, &dy, &width, &height);
27734 }
27735
27736 help = Qnil;
27737
27738 #ifdef HAVE_WINDOW_SYSTEM
27739 if (IMAGEP (object))
27740 {
27741 Lisp_Object image_map, hotspot;
27742 if ((image_map = Fplist_get (XCDR (object), QCmap),
27743 !NILP (image_map))
27744 && (hotspot = find_hot_spot (image_map, dx, dy),
27745 CONSP (hotspot))
27746 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27747 {
27748 Lisp_Object plist;
27749
27750 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27751 If so, we could look for mouse-enter, mouse-leave
27752 properties in PLIST (and do something...). */
27753 hotspot = XCDR (hotspot);
27754 if (CONSP (hotspot)
27755 && (plist = XCAR (hotspot), CONSP (plist)))
27756 {
27757 pointer = Fplist_get (plist, Qpointer);
27758 if (NILP (pointer))
27759 pointer = Qhand;
27760 help = Fplist_get (plist, Qhelp_echo);
27761 if (!NILP (help))
27762 {
27763 help_echo_string = help;
27764 XSETWINDOW (help_echo_window, w);
27765 help_echo_object = w->contents;
27766 help_echo_pos = charpos;
27767 }
27768 }
27769 }
27770 if (NILP (pointer))
27771 pointer = Fplist_get (XCDR (object), QCpointer);
27772 }
27773 #endif /* HAVE_WINDOW_SYSTEM */
27774
27775 if (STRINGP (string))
27776 pos = make_number (charpos);
27777
27778 /* Set the help text and mouse pointer. If the mouse is on a part
27779 of the mode line without any text (e.g. past the right edge of
27780 the mode line text), use the default help text and pointer. */
27781 if (STRINGP (string) || area == ON_MODE_LINE)
27782 {
27783 /* Arrange to display the help by setting the global variables
27784 help_echo_string, help_echo_object, and help_echo_pos. */
27785 if (NILP (help))
27786 {
27787 if (STRINGP (string))
27788 help = Fget_text_property (pos, Qhelp_echo, string);
27789
27790 if (!NILP (help))
27791 {
27792 help_echo_string = help;
27793 XSETWINDOW (help_echo_window, w);
27794 help_echo_object = string;
27795 help_echo_pos = charpos;
27796 }
27797 else if (area == ON_MODE_LINE)
27798 {
27799 Lisp_Object default_help
27800 = buffer_local_value_1 (Qmode_line_default_help_echo,
27801 w->contents);
27802
27803 if (STRINGP (default_help))
27804 {
27805 help_echo_string = default_help;
27806 XSETWINDOW (help_echo_window, w);
27807 help_echo_object = Qnil;
27808 help_echo_pos = -1;
27809 }
27810 }
27811 }
27812
27813 #ifdef HAVE_WINDOW_SYSTEM
27814 /* Change the mouse pointer according to what is under it. */
27815 if (FRAME_WINDOW_P (f))
27816 {
27817 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27818 if (STRINGP (string))
27819 {
27820 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27821
27822 if (NILP (pointer))
27823 pointer = Fget_text_property (pos, Qpointer, string);
27824
27825 /* Change the mouse pointer according to what is under X/Y. */
27826 if (NILP (pointer)
27827 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27828 {
27829 Lisp_Object map;
27830 map = Fget_text_property (pos, Qlocal_map, string);
27831 if (!KEYMAPP (map))
27832 map = Fget_text_property (pos, Qkeymap, string);
27833 if (!KEYMAPP (map))
27834 cursor = dpyinfo->vertical_scroll_bar_cursor;
27835 }
27836 }
27837 else
27838 /* Default mode-line pointer. */
27839 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27840 }
27841 #endif
27842 }
27843
27844 /* Change the mouse face according to what is under X/Y. */
27845 if (STRINGP (string))
27846 {
27847 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27848 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27849 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27850 && glyph)
27851 {
27852 Lisp_Object b, e;
27853
27854 struct glyph * tmp_glyph;
27855
27856 int gpos;
27857 int gseq_length;
27858 int total_pixel_width;
27859 ptrdiff_t begpos, endpos, ignore;
27860
27861 int vpos, hpos;
27862
27863 b = Fprevious_single_property_change (make_number (charpos + 1),
27864 Qmouse_face, string, Qnil);
27865 if (NILP (b))
27866 begpos = 0;
27867 else
27868 begpos = XINT (b);
27869
27870 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27871 if (NILP (e))
27872 endpos = SCHARS (string);
27873 else
27874 endpos = XINT (e);
27875
27876 /* Calculate the glyph position GPOS of GLYPH in the
27877 displayed string, relative to the beginning of the
27878 highlighted part of the string.
27879
27880 Note: GPOS is different from CHARPOS. CHARPOS is the
27881 position of GLYPH in the internal string object. A mode
27882 line string format has structures which are converted to
27883 a flattened string by the Emacs Lisp interpreter. The
27884 internal string is an element of those structures. The
27885 displayed string is the flattened string. */
27886 tmp_glyph = row_start_glyph;
27887 while (tmp_glyph < glyph
27888 && (!(EQ (tmp_glyph->object, glyph->object)
27889 && begpos <= tmp_glyph->charpos
27890 && tmp_glyph->charpos < endpos)))
27891 tmp_glyph++;
27892 gpos = glyph - tmp_glyph;
27893
27894 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27895 the highlighted part of the displayed string to which
27896 GLYPH belongs. Note: GSEQ_LENGTH is different from
27897 SCHARS (STRING), because the latter returns the length of
27898 the internal string. */
27899 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27900 tmp_glyph > glyph
27901 && (!(EQ (tmp_glyph->object, glyph->object)
27902 && begpos <= tmp_glyph->charpos
27903 && tmp_glyph->charpos < endpos));
27904 tmp_glyph--)
27905 ;
27906 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27907
27908 /* Calculate the total pixel width of all the glyphs between
27909 the beginning of the highlighted area and GLYPH. */
27910 total_pixel_width = 0;
27911 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27912 total_pixel_width += tmp_glyph->pixel_width;
27913
27914 /* Pre calculation of re-rendering position. Note: X is in
27915 column units here, after the call to mode_line_string or
27916 marginal_area_string. */
27917 hpos = x - gpos;
27918 vpos = (area == ON_MODE_LINE
27919 ? (w->current_matrix)->nrows - 1
27920 : 0);
27921
27922 /* If GLYPH's position is included in the region that is
27923 already drawn in mouse face, we have nothing to do. */
27924 if ( EQ (window, hlinfo->mouse_face_window)
27925 && (!row->reversed_p
27926 ? (hlinfo->mouse_face_beg_col <= hpos
27927 && hpos < hlinfo->mouse_face_end_col)
27928 /* In R2L rows we swap BEG and END, see below. */
27929 : (hlinfo->mouse_face_end_col <= hpos
27930 && hpos < hlinfo->mouse_face_beg_col))
27931 && hlinfo->mouse_face_beg_row == vpos )
27932 return;
27933
27934 if (clear_mouse_face (hlinfo))
27935 cursor = No_Cursor;
27936
27937 if (!row->reversed_p)
27938 {
27939 hlinfo->mouse_face_beg_col = hpos;
27940 hlinfo->mouse_face_beg_x = original_x_pixel
27941 - (total_pixel_width + dx);
27942 hlinfo->mouse_face_end_col = hpos + gseq_length;
27943 hlinfo->mouse_face_end_x = 0;
27944 }
27945 else
27946 {
27947 /* In R2L rows, show_mouse_face expects BEG and END
27948 coordinates to be swapped. */
27949 hlinfo->mouse_face_end_col = hpos;
27950 hlinfo->mouse_face_end_x = original_x_pixel
27951 - (total_pixel_width + dx);
27952 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27953 hlinfo->mouse_face_beg_x = 0;
27954 }
27955
27956 hlinfo->mouse_face_beg_row = vpos;
27957 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27958 hlinfo->mouse_face_past_end = 0;
27959 hlinfo->mouse_face_window = window;
27960
27961 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27962 charpos,
27963 0, 0, 0,
27964 &ignore,
27965 glyph->face_id,
27966 1);
27967 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27968
27969 if (NILP (pointer))
27970 pointer = Qhand;
27971 }
27972 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27973 clear_mouse_face (hlinfo);
27974 }
27975 #ifdef HAVE_WINDOW_SYSTEM
27976 if (FRAME_WINDOW_P (f))
27977 define_frame_cursor1 (f, cursor, pointer);
27978 #endif
27979 }
27980
27981
27982 /* EXPORT:
27983 Take proper action when the mouse has moved to position X, Y on
27984 frame F with regards to highlighting portions of display that have
27985 mouse-face properties. Also de-highlight portions of display where
27986 the mouse was before, set the mouse pointer shape as appropriate
27987 for the mouse coordinates, and activate help echo (tooltips).
27988 X and Y can be negative or out of range. */
27989
27990 void
27991 note_mouse_highlight (struct frame *f, int x, int y)
27992 {
27993 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27994 enum window_part part = ON_NOTHING;
27995 Lisp_Object window;
27996 struct window *w;
27997 Cursor cursor = No_Cursor;
27998 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
27999 struct buffer *b;
28000
28001 /* When a menu is active, don't highlight because this looks odd. */
28002 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28003 if (popup_activated ())
28004 return;
28005 #endif
28006
28007 if (!f->glyphs_initialized_p
28008 || f->pointer_invisible)
28009 return;
28010
28011 hlinfo->mouse_face_mouse_x = x;
28012 hlinfo->mouse_face_mouse_y = y;
28013 hlinfo->mouse_face_mouse_frame = f;
28014
28015 if (hlinfo->mouse_face_defer)
28016 return;
28017
28018 /* Which window is that in? */
28019 window = window_from_coordinates (f, x, y, &part, 1);
28020
28021 /* If displaying active text in another window, clear that. */
28022 if (! EQ (window, hlinfo->mouse_face_window)
28023 /* Also clear if we move out of text area in same window. */
28024 || (!NILP (hlinfo->mouse_face_window)
28025 && !NILP (window)
28026 && part != ON_TEXT
28027 && part != ON_MODE_LINE
28028 && part != ON_HEADER_LINE))
28029 clear_mouse_face (hlinfo);
28030
28031 /* Not on a window -> return. */
28032 if (!WINDOWP (window))
28033 return;
28034
28035 /* Reset help_echo_string. It will get recomputed below. */
28036 help_echo_string = Qnil;
28037
28038 /* Convert to window-relative pixel coordinates. */
28039 w = XWINDOW (window);
28040 frame_to_window_pixel_xy (w, &x, &y);
28041
28042 #ifdef HAVE_WINDOW_SYSTEM
28043 /* Handle tool-bar window differently since it doesn't display a
28044 buffer. */
28045 if (EQ (window, f->tool_bar_window))
28046 {
28047 note_tool_bar_highlight (f, x, y);
28048 return;
28049 }
28050 #endif
28051
28052 /* Mouse is on the mode, header line or margin? */
28053 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
28054 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
28055 {
28056 note_mode_line_or_margin_highlight (window, x, y, part);
28057 return;
28058 }
28059
28060 #ifdef HAVE_WINDOW_SYSTEM
28061 if (part == ON_VERTICAL_BORDER)
28062 {
28063 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28064 help_echo_string = build_string ("drag-mouse-1: resize");
28065 }
28066 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28067 || part == ON_SCROLL_BAR)
28068 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28069 else
28070 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28071 #endif
28072
28073 /* Are we in a window whose display is up to date?
28074 And verify the buffer's text has not changed. */
28075 b = XBUFFER (w->contents);
28076 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28077 {
28078 int hpos, vpos, dx, dy, area = LAST_AREA;
28079 ptrdiff_t pos;
28080 struct glyph *glyph;
28081 Lisp_Object object;
28082 Lisp_Object mouse_face = Qnil, position;
28083 Lisp_Object *overlay_vec = NULL;
28084 ptrdiff_t i, noverlays;
28085 struct buffer *obuf;
28086 ptrdiff_t obegv, ozv;
28087 int same_region;
28088
28089 /* Find the glyph under X/Y. */
28090 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
28091
28092 #ifdef HAVE_WINDOW_SYSTEM
28093 /* Look for :pointer property on image. */
28094 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28095 {
28096 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
28097 if (img != NULL && IMAGEP (img->spec))
28098 {
28099 Lisp_Object image_map, hotspot;
28100 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
28101 !NILP (image_map))
28102 && (hotspot = find_hot_spot (image_map,
28103 glyph->slice.img.x + dx,
28104 glyph->slice.img.y + dy),
28105 CONSP (hotspot))
28106 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28107 {
28108 Lisp_Object plist;
28109
28110 /* Could check XCAR (hotspot) to see if we enter/leave
28111 this hot-spot.
28112 If so, we could look for mouse-enter, mouse-leave
28113 properties in PLIST (and do something...). */
28114 hotspot = XCDR (hotspot);
28115 if (CONSP (hotspot)
28116 && (plist = XCAR (hotspot), CONSP (plist)))
28117 {
28118 pointer = Fplist_get (plist, Qpointer);
28119 if (NILP (pointer))
28120 pointer = Qhand;
28121 help_echo_string = Fplist_get (plist, Qhelp_echo);
28122 if (!NILP (help_echo_string))
28123 {
28124 help_echo_window = window;
28125 help_echo_object = glyph->object;
28126 help_echo_pos = glyph->charpos;
28127 }
28128 }
28129 }
28130 if (NILP (pointer))
28131 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28132 }
28133 }
28134 #endif /* HAVE_WINDOW_SYSTEM */
28135
28136 /* Clear mouse face if X/Y not over text. */
28137 if (glyph == NULL
28138 || area != TEXT_AREA
28139 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
28140 /* Glyph's OBJECT is an integer for glyphs inserted by the
28141 display engine for its internal purposes, like truncation
28142 and continuation glyphs and blanks beyond the end of
28143 line's text on text terminals. If we are over such a
28144 glyph, we are not over any text. */
28145 || INTEGERP (glyph->object)
28146 /* R2L rows have a stretch glyph at their front, which
28147 stands for no text, whereas L2R rows have no glyphs at
28148 all beyond the end of text. Treat such stretch glyphs
28149 like we do with NULL glyphs in L2R rows. */
28150 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28151 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
28152 && glyph->type == STRETCH_GLYPH
28153 && glyph->avoid_cursor_p))
28154 {
28155 if (clear_mouse_face (hlinfo))
28156 cursor = No_Cursor;
28157 #ifdef HAVE_WINDOW_SYSTEM
28158 if (FRAME_WINDOW_P (f) && NILP (pointer))
28159 {
28160 if (area != TEXT_AREA)
28161 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28162 else
28163 pointer = Vvoid_text_area_pointer;
28164 }
28165 #endif
28166 goto set_cursor;
28167 }
28168
28169 pos = glyph->charpos;
28170 object = glyph->object;
28171 if (!STRINGP (object) && !BUFFERP (object))
28172 goto set_cursor;
28173
28174 /* If we get an out-of-range value, return now; avoid an error. */
28175 if (BUFFERP (object) && pos > BUF_Z (b))
28176 goto set_cursor;
28177
28178 /* Make the window's buffer temporarily current for
28179 overlays_at and compute_char_face. */
28180 obuf = current_buffer;
28181 current_buffer = b;
28182 obegv = BEGV;
28183 ozv = ZV;
28184 BEGV = BEG;
28185 ZV = Z;
28186
28187 /* Is this char mouse-active or does it have help-echo? */
28188 position = make_number (pos);
28189
28190 if (BUFFERP (object))
28191 {
28192 /* Put all the overlays we want in a vector in overlay_vec. */
28193 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28194 /* Sort overlays into increasing priority order. */
28195 noverlays = sort_overlays (overlay_vec, noverlays, w);
28196 }
28197 else
28198 noverlays = 0;
28199
28200 if (NILP (Vmouse_highlight))
28201 {
28202 clear_mouse_face (hlinfo);
28203 goto check_help_echo;
28204 }
28205
28206 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28207
28208 if (same_region)
28209 cursor = No_Cursor;
28210
28211 /* Check mouse-face highlighting. */
28212 if (! same_region
28213 /* If there exists an overlay with mouse-face overlapping
28214 the one we are currently highlighting, we have to
28215 check if we enter the overlapping overlay, and then
28216 highlight only that. */
28217 || (OVERLAYP (hlinfo->mouse_face_overlay)
28218 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28219 {
28220 /* Find the highest priority overlay with a mouse-face. */
28221 Lisp_Object overlay = Qnil;
28222 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28223 {
28224 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28225 if (!NILP (mouse_face))
28226 overlay = overlay_vec[i];
28227 }
28228
28229 /* If we're highlighting the same overlay as before, there's
28230 no need to do that again. */
28231 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28232 goto check_help_echo;
28233 hlinfo->mouse_face_overlay = overlay;
28234
28235 /* Clear the display of the old active region, if any. */
28236 if (clear_mouse_face (hlinfo))
28237 cursor = No_Cursor;
28238
28239 /* If no overlay applies, get a text property. */
28240 if (NILP (overlay))
28241 mouse_face = Fget_text_property (position, Qmouse_face, object);
28242
28243 /* Next, compute the bounds of the mouse highlighting and
28244 display it. */
28245 if (!NILP (mouse_face) && STRINGP (object))
28246 {
28247 /* The mouse-highlighting comes from a display string
28248 with a mouse-face. */
28249 Lisp_Object s, e;
28250 ptrdiff_t ignore;
28251
28252 s = Fprevious_single_property_change
28253 (make_number (pos + 1), Qmouse_face, object, Qnil);
28254 e = Fnext_single_property_change
28255 (position, Qmouse_face, object, Qnil);
28256 if (NILP (s))
28257 s = make_number (0);
28258 if (NILP (e))
28259 e = make_number (SCHARS (object) - 1);
28260 mouse_face_from_string_pos (w, hlinfo, object,
28261 XINT (s), XINT (e));
28262 hlinfo->mouse_face_past_end = 0;
28263 hlinfo->mouse_face_window = window;
28264 hlinfo->mouse_face_face_id
28265 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
28266 glyph->face_id, 1);
28267 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28268 cursor = No_Cursor;
28269 }
28270 else
28271 {
28272 /* The mouse-highlighting, if any, comes from an overlay
28273 or text property in the buffer. */
28274 Lisp_Object buffer IF_LINT (= Qnil);
28275 Lisp_Object disp_string IF_LINT (= Qnil);
28276
28277 if (STRINGP (object))
28278 {
28279 /* If we are on a display string with no mouse-face,
28280 check if the text under it has one. */
28281 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28282 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28283 pos = string_buffer_position (object, start);
28284 if (pos > 0)
28285 {
28286 mouse_face = get_char_property_and_overlay
28287 (make_number (pos), Qmouse_face, w->contents, &overlay);
28288 buffer = w->contents;
28289 disp_string = object;
28290 }
28291 }
28292 else
28293 {
28294 buffer = object;
28295 disp_string = Qnil;
28296 }
28297
28298 if (!NILP (mouse_face))
28299 {
28300 Lisp_Object before, after;
28301 Lisp_Object before_string, after_string;
28302 /* To correctly find the limits of mouse highlight
28303 in a bidi-reordered buffer, we must not use the
28304 optimization of limiting the search in
28305 previous-single-property-change and
28306 next-single-property-change, because
28307 rows_from_pos_range needs the real start and end
28308 positions to DTRT in this case. That's because
28309 the first row visible in a window does not
28310 necessarily display the character whose position
28311 is the smallest. */
28312 Lisp_Object lim1 =
28313 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28314 ? Fmarker_position (w->start)
28315 : Qnil;
28316 Lisp_Object lim2 =
28317 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28318 ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos)
28319 : Qnil;
28320
28321 if (NILP (overlay))
28322 {
28323 /* Handle the text property case. */
28324 before = Fprevious_single_property_change
28325 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28326 after = Fnext_single_property_change
28327 (make_number (pos), Qmouse_face, buffer, lim2);
28328 before_string = after_string = Qnil;
28329 }
28330 else
28331 {
28332 /* Handle the overlay case. */
28333 before = Foverlay_start (overlay);
28334 after = Foverlay_end (overlay);
28335 before_string = Foverlay_get (overlay, Qbefore_string);
28336 after_string = Foverlay_get (overlay, Qafter_string);
28337
28338 if (!STRINGP (before_string)) before_string = Qnil;
28339 if (!STRINGP (after_string)) after_string = Qnil;
28340 }
28341
28342 mouse_face_from_buffer_pos (window, hlinfo, pos,
28343 NILP (before)
28344 ? 1
28345 : XFASTINT (before),
28346 NILP (after)
28347 ? BUF_Z (XBUFFER (buffer))
28348 : XFASTINT (after),
28349 before_string, after_string,
28350 disp_string);
28351 cursor = No_Cursor;
28352 }
28353 }
28354 }
28355
28356 check_help_echo:
28357
28358 /* Look for a `help-echo' property. */
28359 if (NILP (help_echo_string)) {
28360 Lisp_Object help, overlay;
28361
28362 /* Check overlays first. */
28363 help = overlay = Qnil;
28364 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28365 {
28366 overlay = overlay_vec[i];
28367 help = Foverlay_get (overlay, Qhelp_echo);
28368 }
28369
28370 if (!NILP (help))
28371 {
28372 help_echo_string = help;
28373 help_echo_window = window;
28374 help_echo_object = overlay;
28375 help_echo_pos = pos;
28376 }
28377 else
28378 {
28379 Lisp_Object obj = glyph->object;
28380 ptrdiff_t charpos = glyph->charpos;
28381
28382 /* Try text properties. */
28383 if (STRINGP (obj)
28384 && charpos >= 0
28385 && charpos < SCHARS (obj))
28386 {
28387 help = Fget_text_property (make_number (charpos),
28388 Qhelp_echo, obj);
28389 if (NILP (help))
28390 {
28391 /* If the string itself doesn't specify a help-echo,
28392 see if the buffer text ``under'' it does. */
28393 struct glyph_row *r
28394 = MATRIX_ROW (w->current_matrix, vpos);
28395 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28396 ptrdiff_t p = string_buffer_position (obj, start);
28397 if (p > 0)
28398 {
28399 help = Fget_char_property (make_number (p),
28400 Qhelp_echo, w->contents);
28401 if (!NILP (help))
28402 {
28403 charpos = p;
28404 obj = w->contents;
28405 }
28406 }
28407 }
28408 }
28409 else if (BUFFERP (obj)
28410 && charpos >= BEGV
28411 && charpos < ZV)
28412 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28413 obj);
28414
28415 if (!NILP (help))
28416 {
28417 help_echo_string = help;
28418 help_echo_window = window;
28419 help_echo_object = obj;
28420 help_echo_pos = charpos;
28421 }
28422 }
28423 }
28424
28425 #ifdef HAVE_WINDOW_SYSTEM
28426 /* Look for a `pointer' property. */
28427 if (FRAME_WINDOW_P (f) && NILP (pointer))
28428 {
28429 /* Check overlays first. */
28430 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28431 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28432
28433 if (NILP (pointer))
28434 {
28435 Lisp_Object obj = glyph->object;
28436 ptrdiff_t charpos = glyph->charpos;
28437
28438 /* Try text properties. */
28439 if (STRINGP (obj)
28440 && charpos >= 0
28441 && charpos < SCHARS (obj))
28442 {
28443 pointer = Fget_text_property (make_number (charpos),
28444 Qpointer, obj);
28445 if (NILP (pointer))
28446 {
28447 /* If the string itself doesn't specify a pointer,
28448 see if the buffer text ``under'' it does. */
28449 struct glyph_row *r
28450 = MATRIX_ROW (w->current_matrix, vpos);
28451 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28452 ptrdiff_t p = string_buffer_position (obj, start);
28453 if (p > 0)
28454 pointer = Fget_char_property (make_number (p),
28455 Qpointer, w->contents);
28456 }
28457 }
28458 else if (BUFFERP (obj)
28459 && charpos >= BEGV
28460 && charpos < ZV)
28461 pointer = Fget_text_property (make_number (charpos),
28462 Qpointer, obj);
28463 }
28464 }
28465 #endif /* HAVE_WINDOW_SYSTEM */
28466
28467 BEGV = obegv;
28468 ZV = ozv;
28469 current_buffer = obuf;
28470 }
28471
28472 set_cursor:
28473
28474 #ifdef HAVE_WINDOW_SYSTEM
28475 if (FRAME_WINDOW_P (f))
28476 define_frame_cursor1 (f, cursor, pointer);
28477 #else
28478 /* This is here to prevent a compiler error, about "label at end of
28479 compound statement". */
28480 return;
28481 #endif
28482 }
28483
28484
28485 /* EXPORT for RIF:
28486 Clear any mouse-face on window W. This function is part of the
28487 redisplay interface, and is called from try_window_id and similar
28488 functions to ensure the mouse-highlight is off. */
28489
28490 void
28491 x_clear_window_mouse_face (struct window *w)
28492 {
28493 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28494 Lisp_Object window;
28495
28496 block_input ();
28497 XSETWINDOW (window, w);
28498 if (EQ (window, hlinfo->mouse_face_window))
28499 clear_mouse_face (hlinfo);
28500 unblock_input ();
28501 }
28502
28503
28504 /* EXPORT:
28505 Just discard the mouse face information for frame F, if any.
28506 This is used when the size of F is changed. */
28507
28508 void
28509 cancel_mouse_face (struct frame *f)
28510 {
28511 Lisp_Object window;
28512 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28513
28514 window = hlinfo->mouse_face_window;
28515 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28516 reset_mouse_highlight (hlinfo);
28517 }
28518
28519
28520 \f
28521 /***********************************************************************
28522 Exposure Events
28523 ***********************************************************************/
28524
28525 #ifdef HAVE_WINDOW_SYSTEM
28526
28527 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28528 which intersects rectangle R. R is in window-relative coordinates. */
28529
28530 static void
28531 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28532 enum glyph_row_area area)
28533 {
28534 struct glyph *first = row->glyphs[area];
28535 struct glyph *end = row->glyphs[area] + row->used[area];
28536 struct glyph *last;
28537 int first_x, start_x, x;
28538
28539 if (area == TEXT_AREA && row->fill_line_p)
28540 /* If row extends face to end of line write the whole line. */
28541 draw_glyphs (w, 0, row, area,
28542 0, row->used[area],
28543 DRAW_NORMAL_TEXT, 0);
28544 else
28545 {
28546 /* Set START_X to the window-relative start position for drawing glyphs of
28547 AREA. The first glyph of the text area can be partially visible.
28548 The first glyphs of other areas cannot. */
28549 start_x = window_box_left_offset (w, area);
28550 x = start_x;
28551 if (area == TEXT_AREA)
28552 x += row->x;
28553
28554 /* Find the first glyph that must be redrawn. */
28555 while (first < end
28556 && x + first->pixel_width < r->x)
28557 {
28558 x += first->pixel_width;
28559 ++first;
28560 }
28561
28562 /* Find the last one. */
28563 last = first;
28564 first_x = x;
28565 while (last < end
28566 && x < r->x + r->width)
28567 {
28568 x += last->pixel_width;
28569 ++last;
28570 }
28571
28572 /* Repaint. */
28573 if (last > first)
28574 draw_glyphs (w, first_x - start_x, row, area,
28575 first - row->glyphs[area], last - row->glyphs[area],
28576 DRAW_NORMAL_TEXT, 0);
28577 }
28578 }
28579
28580
28581 /* Redraw the parts of the glyph row ROW on window W intersecting
28582 rectangle R. R is in window-relative coordinates. Value is
28583 non-zero if mouse-face was overwritten. */
28584
28585 static int
28586 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28587 {
28588 eassert (row->enabled_p);
28589
28590 if (row->mode_line_p || w->pseudo_window_p)
28591 draw_glyphs (w, 0, row, TEXT_AREA,
28592 0, row->used[TEXT_AREA],
28593 DRAW_NORMAL_TEXT, 0);
28594 else
28595 {
28596 if (row->used[LEFT_MARGIN_AREA])
28597 expose_area (w, row, r, LEFT_MARGIN_AREA);
28598 if (row->used[TEXT_AREA])
28599 expose_area (w, row, r, TEXT_AREA);
28600 if (row->used[RIGHT_MARGIN_AREA])
28601 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28602 draw_row_fringe_bitmaps (w, row);
28603 }
28604
28605 return row->mouse_face_p;
28606 }
28607
28608
28609 /* Redraw those parts of glyphs rows during expose event handling that
28610 overlap other rows. Redrawing of an exposed line writes over parts
28611 of lines overlapping that exposed line; this function fixes that.
28612
28613 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28614 row in W's current matrix that is exposed and overlaps other rows.
28615 LAST_OVERLAPPING_ROW is the last such row. */
28616
28617 static void
28618 expose_overlaps (struct window *w,
28619 struct glyph_row *first_overlapping_row,
28620 struct glyph_row *last_overlapping_row,
28621 XRectangle *r)
28622 {
28623 struct glyph_row *row;
28624
28625 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28626 if (row->overlapping_p)
28627 {
28628 eassert (row->enabled_p && !row->mode_line_p);
28629
28630 row->clip = r;
28631 if (row->used[LEFT_MARGIN_AREA])
28632 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28633
28634 if (row->used[TEXT_AREA])
28635 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28636
28637 if (row->used[RIGHT_MARGIN_AREA])
28638 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28639 row->clip = NULL;
28640 }
28641 }
28642
28643
28644 /* Return non-zero if W's cursor intersects rectangle R. */
28645
28646 static int
28647 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28648 {
28649 XRectangle cr, result;
28650 struct glyph *cursor_glyph;
28651 struct glyph_row *row;
28652
28653 if (w->phys_cursor.vpos >= 0
28654 && w->phys_cursor.vpos < w->current_matrix->nrows
28655 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28656 row->enabled_p)
28657 && row->cursor_in_fringe_p)
28658 {
28659 /* Cursor is in the fringe. */
28660 cr.x = window_box_right_offset (w,
28661 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28662 ? RIGHT_MARGIN_AREA
28663 : TEXT_AREA));
28664 cr.y = row->y;
28665 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28666 cr.height = row->height;
28667 return x_intersect_rectangles (&cr, r, &result);
28668 }
28669
28670 cursor_glyph = get_phys_cursor_glyph (w);
28671 if (cursor_glyph)
28672 {
28673 /* r is relative to W's box, but w->phys_cursor.x is relative
28674 to left edge of W's TEXT area. Adjust it. */
28675 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28676 cr.y = w->phys_cursor.y;
28677 cr.width = cursor_glyph->pixel_width;
28678 cr.height = w->phys_cursor_height;
28679 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28680 I assume the effect is the same -- and this is portable. */
28681 return x_intersect_rectangles (&cr, r, &result);
28682 }
28683 /* If we don't understand the format, pretend we're not in the hot-spot. */
28684 return 0;
28685 }
28686
28687
28688 /* EXPORT:
28689 Draw a vertical window border to the right of window W if W doesn't
28690 have vertical scroll bars. */
28691
28692 void
28693 x_draw_vertical_border (struct window *w)
28694 {
28695 struct frame *f = XFRAME (WINDOW_FRAME (w));
28696
28697 /* We could do better, if we knew what type of scroll-bar the adjacent
28698 windows (on either side) have... But we don't :-(
28699 However, I think this works ok. ++KFS 2003-04-25 */
28700
28701 /* Redraw borders between horizontally adjacent windows. Don't
28702 do it for frames with vertical scroll bars because either the
28703 right scroll bar of a window, or the left scroll bar of its
28704 neighbor will suffice as a border. */
28705 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28706 return;
28707
28708 /* Note: It is necessary to redraw both the left and the right
28709 borders, for when only this single window W is being
28710 redisplayed. */
28711 if (!WINDOW_RIGHTMOST_P (w)
28712 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28713 {
28714 int x0, x1, y0, y1;
28715
28716 window_box_edges (w, &x0, &y0, &x1, &y1);
28717 y1 -= 1;
28718
28719 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28720 x1 -= 1;
28721
28722 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28723 }
28724 if (!WINDOW_LEFTMOST_P (w)
28725 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28726 {
28727 int x0, x1, y0, y1;
28728
28729 window_box_edges (w, &x0, &y0, &x1, &y1);
28730 y1 -= 1;
28731
28732 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28733 x0 -= 1;
28734
28735 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28736 }
28737 }
28738
28739
28740 /* Redraw the part of window W intersection rectangle FR. Pixel
28741 coordinates in FR are frame-relative. Call this function with
28742 input blocked. Value is non-zero if the exposure overwrites
28743 mouse-face. */
28744
28745 static int
28746 expose_window (struct window *w, XRectangle *fr)
28747 {
28748 struct frame *f = XFRAME (w->frame);
28749 XRectangle wr, r;
28750 int mouse_face_overwritten_p = 0;
28751
28752 /* If window is not yet fully initialized, do nothing. This can
28753 happen when toolkit scroll bars are used and a window is split.
28754 Reconfiguring the scroll bar will generate an expose for a newly
28755 created window. */
28756 if (w->current_matrix == NULL)
28757 return 0;
28758
28759 /* When we're currently updating the window, display and current
28760 matrix usually don't agree. Arrange for a thorough display
28761 later. */
28762 if (w->must_be_updated_p)
28763 {
28764 SET_FRAME_GARBAGED (f);
28765 return 0;
28766 }
28767
28768 /* Frame-relative pixel rectangle of W. */
28769 wr.x = WINDOW_LEFT_EDGE_X (w);
28770 wr.y = WINDOW_TOP_EDGE_Y (w);
28771 wr.width = WINDOW_TOTAL_WIDTH (w);
28772 wr.height = WINDOW_TOTAL_HEIGHT (w);
28773
28774 if (x_intersect_rectangles (fr, &wr, &r))
28775 {
28776 int yb = window_text_bottom_y (w);
28777 struct glyph_row *row;
28778 int cursor_cleared_p, phys_cursor_on_p;
28779 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28780
28781 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28782 r.x, r.y, r.width, r.height));
28783
28784 /* Convert to window coordinates. */
28785 r.x -= WINDOW_LEFT_EDGE_X (w);
28786 r.y -= WINDOW_TOP_EDGE_Y (w);
28787
28788 /* Turn off the cursor. */
28789 if (!w->pseudo_window_p
28790 && phys_cursor_in_rect_p (w, &r))
28791 {
28792 x_clear_cursor (w);
28793 cursor_cleared_p = 1;
28794 }
28795 else
28796 cursor_cleared_p = 0;
28797
28798 /* If the row containing the cursor extends face to end of line,
28799 then expose_area might overwrite the cursor outside the
28800 rectangle and thus notice_overwritten_cursor might clear
28801 w->phys_cursor_on_p. We remember the original value and
28802 check later if it is changed. */
28803 phys_cursor_on_p = w->phys_cursor_on_p;
28804
28805 /* Update lines intersecting rectangle R. */
28806 first_overlapping_row = last_overlapping_row = NULL;
28807 for (row = w->current_matrix->rows;
28808 row->enabled_p;
28809 ++row)
28810 {
28811 int y0 = row->y;
28812 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28813
28814 if ((y0 >= r.y && y0 < r.y + r.height)
28815 || (y1 > r.y && y1 < r.y + r.height)
28816 || (r.y >= y0 && r.y < y1)
28817 || (r.y + r.height > y0 && r.y + r.height < y1))
28818 {
28819 /* A header line may be overlapping, but there is no need
28820 to fix overlapping areas for them. KFS 2005-02-12 */
28821 if (row->overlapping_p && !row->mode_line_p)
28822 {
28823 if (first_overlapping_row == NULL)
28824 first_overlapping_row = row;
28825 last_overlapping_row = row;
28826 }
28827
28828 row->clip = fr;
28829 if (expose_line (w, row, &r))
28830 mouse_face_overwritten_p = 1;
28831 row->clip = NULL;
28832 }
28833 else if (row->overlapping_p)
28834 {
28835 /* We must redraw a row overlapping the exposed area. */
28836 if (y0 < r.y
28837 ? y0 + row->phys_height > r.y
28838 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28839 {
28840 if (first_overlapping_row == NULL)
28841 first_overlapping_row = row;
28842 last_overlapping_row = row;
28843 }
28844 }
28845
28846 if (y1 >= yb)
28847 break;
28848 }
28849
28850 /* Display the mode line if there is one. */
28851 if (WINDOW_WANTS_MODELINE_P (w)
28852 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28853 row->enabled_p)
28854 && row->y < r.y + r.height)
28855 {
28856 if (expose_line (w, row, &r))
28857 mouse_face_overwritten_p = 1;
28858 }
28859
28860 if (!w->pseudo_window_p)
28861 {
28862 /* Fix the display of overlapping rows. */
28863 if (first_overlapping_row)
28864 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28865 fr);
28866
28867 /* Draw border between windows. */
28868 x_draw_vertical_border (w);
28869
28870 /* Turn the cursor on again. */
28871 if (cursor_cleared_p
28872 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28873 update_window_cursor (w, 1);
28874 }
28875 }
28876
28877 return mouse_face_overwritten_p;
28878 }
28879
28880
28881
28882 /* Redraw (parts) of all windows in the window tree rooted at W that
28883 intersect R. R contains frame pixel coordinates. Value is
28884 non-zero if the exposure overwrites mouse-face. */
28885
28886 static int
28887 expose_window_tree (struct window *w, XRectangle *r)
28888 {
28889 struct frame *f = XFRAME (w->frame);
28890 int mouse_face_overwritten_p = 0;
28891
28892 while (w && !FRAME_GARBAGED_P (f))
28893 {
28894 if (WINDOWP (w->contents))
28895 mouse_face_overwritten_p
28896 |= expose_window_tree (XWINDOW (w->contents), r);
28897 else
28898 mouse_face_overwritten_p |= expose_window (w, r);
28899
28900 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28901 }
28902
28903 return mouse_face_overwritten_p;
28904 }
28905
28906
28907 /* EXPORT:
28908 Redisplay an exposed area of frame F. X and Y are the upper-left
28909 corner of the exposed rectangle. W and H are width and height of
28910 the exposed area. All are pixel values. W or H zero means redraw
28911 the entire frame. */
28912
28913 void
28914 expose_frame (struct frame *f, int x, int y, int w, int h)
28915 {
28916 XRectangle r;
28917 int mouse_face_overwritten_p = 0;
28918
28919 TRACE ((stderr, "expose_frame "));
28920
28921 /* No need to redraw if frame will be redrawn soon. */
28922 if (FRAME_GARBAGED_P (f))
28923 {
28924 TRACE ((stderr, " garbaged\n"));
28925 return;
28926 }
28927
28928 /* If basic faces haven't been realized yet, there is no point in
28929 trying to redraw anything. This can happen when we get an expose
28930 event while Emacs is starting, e.g. by moving another window. */
28931 if (FRAME_FACE_CACHE (f) == NULL
28932 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28933 {
28934 TRACE ((stderr, " no faces\n"));
28935 return;
28936 }
28937
28938 if (w == 0 || h == 0)
28939 {
28940 r.x = r.y = 0;
28941 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28942 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28943 }
28944 else
28945 {
28946 r.x = x;
28947 r.y = y;
28948 r.width = w;
28949 r.height = h;
28950 }
28951
28952 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28953 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28954
28955 if (WINDOWP (f->tool_bar_window))
28956 mouse_face_overwritten_p
28957 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28958
28959 #ifdef HAVE_X_WINDOWS
28960 #ifndef MSDOS
28961 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28962 if (WINDOWP (f->menu_bar_window))
28963 mouse_face_overwritten_p
28964 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28965 #endif /* not USE_X_TOOLKIT and not USE_GTK */
28966 #endif
28967 #endif
28968
28969 /* Some window managers support a focus-follows-mouse style with
28970 delayed raising of frames. Imagine a partially obscured frame,
28971 and moving the mouse into partially obscured mouse-face on that
28972 frame. The visible part of the mouse-face will be highlighted,
28973 then the WM raises the obscured frame. With at least one WM, KDE
28974 2.1, Emacs is not getting any event for the raising of the frame
28975 (even tried with SubstructureRedirectMask), only Expose events.
28976 These expose events will draw text normally, i.e. not
28977 highlighted. Which means we must redo the highlight here.
28978 Subsume it under ``we love X''. --gerd 2001-08-15 */
28979 /* Included in Windows version because Windows most likely does not
28980 do the right thing if any third party tool offers
28981 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28982 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
28983 {
28984 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28985 if (f == hlinfo->mouse_face_mouse_frame)
28986 {
28987 int mouse_x = hlinfo->mouse_face_mouse_x;
28988 int mouse_y = hlinfo->mouse_face_mouse_y;
28989 clear_mouse_face (hlinfo);
28990 note_mouse_highlight (f, mouse_x, mouse_y);
28991 }
28992 }
28993 }
28994
28995
28996 /* EXPORT:
28997 Determine the intersection of two rectangles R1 and R2. Return
28998 the intersection in *RESULT. Value is non-zero if RESULT is not
28999 empty. */
29000
29001 int
29002 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
29003 {
29004 XRectangle *left, *right;
29005 XRectangle *upper, *lower;
29006 int intersection_p = 0;
29007
29008 /* Rearrange so that R1 is the left-most rectangle. */
29009 if (r1->x < r2->x)
29010 left = r1, right = r2;
29011 else
29012 left = r2, right = r1;
29013
29014 /* X0 of the intersection is right.x0, if this is inside R1,
29015 otherwise there is no intersection. */
29016 if (right->x <= left->x + left->width)
29017 {
29018 result->x = right->x;
29019
29020 /* The right end of the intersection is the minimum of
29021 the right ends of left and right. */
29022 result->width = (min (left->x + left->width, right->x + right->width)
29023 - result->x);
29024
29025 /* Same game for Y. */
29026 if (r1->y < r2->y)
29027 upper = r1, lower = r2;
29028 else
29029 upper = r2, lower = r1;
29030
29031 /* The upper end of the intersection is lower.y0, if this is inside
29032 of upper. Otherwise, there is no intersection. */
29033 if (lower->y <= upper->y + upper->height)
29034 {
29035 result->y = lower->y;
29036
29037 /* The lower end of the intersection is the minimum of the lower
29038 ends of upper and lower. */
29039 result->height = (min (lower->y + lower->height,
29040 upper->y + upper->height)
29041 - result->y);
29042 intersection_p = 1;
29043 }
29044 }
29045
29046 return intersection_p;
29047 }
29048
29049 #endif /* HAVE_WINDOW_SYSTEM */
29050
29051 \f
29052 /***********************************************************************
29053 Initialization
29054 ***********************************************************************/
29055
29056 void
29057 syms_of_xdisp (void)
29058 {
29059 Vwith_echo_area_save_vector = Qnil;
29060 staticpro (&Vwith_echo_area_save_vector);
29061
29062 Vmessage_stack = Qnil;
29063 staticpro (&Vmessage_stack);
29064
29065 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
29066 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
29067
29068 message_dolog_marker1 = Fmake_marker ();
29069 staticpro (&message_dolog_marker1);
29070 message_dolog_marker2 = Fmake_marker ();
29071 staticpro (&message_dolog_marker2);
29072 message_dolog_marker3 = Fmake_marker ();
29073 staticpro (&message_dolog_marker3);
29074
29075 #ifdef GLYPH_DEBUG
29076 defsubr (&Sdump_frame_glyph_matrix);
29077 defsubr (&Sdump_glyph_matrix);
29078 defsubr (&Sdump_glyph_row);
29079 defsubr (&Sdump_tool_bar_row);
29080 defsubr (&Strace_redisplay);
29081 defsubr (&Strace_to_stderr);
29082 #endif
29083 #ifdef HAVE_WINDOW_SYSTEM
29084 defsubr (&Stool_bar_lines_needed);
29085 defsubr (&Slookup_image_map);
29086 #endif
29087 defsubr (&Sline_pixel_height);
29088 defsubr (&Sformat_mode_line);
29089 defsubr (&Sinvisible_p);
29090 defsubr (&Scurrent_bidi_paragraph_direction);
29091 defsubr (&Smove_point_visually);
29092
29093 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
29094 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
29095 DEFSYM (Qoverriding_local_map, "overriding-local-map");
29096 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
29097 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
29098 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
29099 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
29100 DEFSYM (Qeval, "eval");
29101 DEFSYM (QCdata, ":data");
29102 DEFSYM (Qdisplay, "display");
29103 DEFSYM (Qspace_width, "space-width");
29104 DEFSYM (Qraise, "raise");
29105 DEFSYM (Qslice, "slice");
29106 DEFSYM (Qspace, "space");
29107 DEFSYM (Qmargin, "margin");
29108 DEFSYM (Qpointer, "pointer");
29109 DEFSYM (Qleft_margin, "left-margin");
29110 DEFSYM (Qright_margin, "right-margin");
29111 DEFSYM (Qcenter, "center");
29112 DEFSYM (Qline_height, "line-height");
29113 DEFSYM (QCalign_to, ":align-to");
29114 DEFSYM (QCrelative_width, ":relative-width");
29115 DEFSYM (QCrelative_height, ":relative-height");
29116 DEFSYM (QCeval, ":eval");
29117 DEFSYM (QCpropertize, ":propertize");
29118 DEFSYM (QCfile, ":file");
29119 DEFSYM (Qfontified, "fontified");
29120 DEFSYM (Qfontification_functions, "fontification-functions");
29121 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
29122 DEFSYM (Qescape_glyph, "escape-glyph");
29123 DEFSYM (Qnobreak_space, "nobreak-space");
29124 DEFSYM (Qimage, "image");
29125 DEFSYM (Qtext, "text");
29126 DEFSYM (Qboth, "both");
29127 DEFSYM (Qboth_horiz, "both-horiz");
29128 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29129 DEFSYM (QCmap, ":map");
29130 DEFSYM (QCpointer, ":pointer");
29131 DEFSYM (Qrect, "rect");
29132 DEFSYM (Qcircle, "circle");
29133 DEFSYM (Qpoly, "poly");
29134 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29135 DEFSYM (Qgrow_only, "grow-only");
29136 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29137 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29138 DEFSYM (Qposition, "position");
29139 DEFSYM (Qbuffer_position, "buffer-position");
29140 DEFSYM (Qobject, "object");
29141 DEFSYM (Qbar, "bar");
29142 DEFSYM (Qhbar, "hbar");
29143 DEFSYM (Qbox, "box");
29144 DEFSYM (Qhollow, "hollow");
29145 DEFSYM (Qhand, "hand");
29146 DEFSYM (Qarrow, "arrow");
29147 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29148
29149 list_of_error = list1 (list2 (intern_c_string ("error"),
29150 intern_c_string ("void-variable")));
29151 staticpro (&list_of_error);
29152
29153 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29154 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29155 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29156 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29157
29158 echo_buffer[0] = echo_buffer[1] = Qnil;
29159 staticpro (&echo_buffer[0]);
29160 staticpro (&echo_buffer[1]);
29161
29162 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29163 staticpro (&echo_area_buffer[0]);
29164 staticpro (&echo_area_buffer[1]);
29165
29166 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29167 staticpro (&Vmessages_buffer_name);
29168
29169 mode_line_proptrans_alist = Qnil;
29170 staticpro (&mode_line_proptrans_alist);
29171 mode_line_string_list = Qnil;
29172 staticpro (&mode_line_string_list);
29173 mode_line_string_face = Qnil;
29174 staticpro (&mode_line_string_face);
29175 mode_line_string_face_prop = Qnil;
29176 staticpro (&mode_line_string_face_prop);
29177 Vmode_line_unwind_vector = Qnil;
29178 staticpro (&Vmode_line_unwind_vector);
29179
29180 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29181
29182 help_echo_string = Qnil;
29183 staticpro (&help_echo_string);
29184 help_echo_object = Qnil;
29185 staticpro (&help_echo_object);
29186 help_echo_window = Qnil;
29187 staticpro (&help_echo_window);
29188 previous_help_echo_string = Qnil;
29189 staticpro (&previous_help_echo_string);
29190 help_echo_pos = -1;
29191
29192 DEFSYM (Qright_to_left, "right-to-left");
29193 DEFSYM (Qleft_to_right, "left-to-right");
29194
29195 #ifdef HAVE_WINDOW_SYSTEM
29196 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29197 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29198 For example, if a block cursor is over a tab, it will be drawn as
29199 wide as that tab on the display. */);
29200 x_stretch_cursor_p = 0;
29201 #endif
29202
29203 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29204 doc: /* Non-nil means highlight trailing whitespace.
29205 The face used for trailing whitespace is `trailing-whitespace'. */);
29206 Vshow_trailing_whitespace = Qnil;
29207
29208 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29209 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29210 If the value is t, Emacs highlights non-ASCII chars which have the
29211 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29212 or `escape-glyph' face respectively.
29213
29214 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29215 U+2011 (non-breaking hyphen) are affected.
29216
29217 Any other non-nil value means to display these characters as a escape
29218 glyph followed by an ordinary space or hyphen.
29219
29220 A value of nil means no special handling of these characters. */);
29221 Vnobreak_char_display = Qt;
29222
29223 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29224 doc: /* The pointer shape to show in void text areas.
29225 A value of nil means to show the text pointer. Other options are `arrow',
29226 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29227 Vvoid_text_area_pointer = Qarrow;
29228
29229 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29230 doc: /* Non-nil means don't actually do any redisplay.
29231 This is used for internal purposes. */);
29232 Vinhibit_redisplay = Qnil;
29233
29234 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29235 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29236 Vglobal_mode_string = Qnil;
29237
29238 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29239 doc: /* Marker for where to display an arrow on top of the buffer text.
29240 This must be the beginning of a line in order to work.
29241 See also `overlay-arrow-string'. */);
29242 Voverlay_arrow_position = Qnil;
29243
29244 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29245 doc: /* String to display as an arrow in non-window frames.
29246 See also `overlay-arrow-position'. */);
29247 Voverlay_arrow_string = build_pure_c_string ("=>");
29248
29249 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29250 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29251 The symbols on this list are examined during redisplay to determine
29252 where to display overlay arrows. */);
29253 Voverlay_arrow_variable_list
29254 = list1 (intern_c_string ("overlay-arrow-position"));
29255
29256 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29257 doc: /* The number of lines to try scrolling a window by when point moves out.
29258 If that fails to bring point back on frame, point is centered instead.
29259 If this is zero, point is always centered after it moves off frame.
29260 If you want scrolling to always be a line at a time, you should set
29261 `scroll-conservatively' to a large value rather than set this to 1. */);
29262
29263 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29264 doc: /* Scroll up to this many lines, to bring point back on screen.
29265 If point moves off-screen, redisplay will scroll by up to
29266 `scroll-conservatively' lines in order to bring point just barely
29267 onto the screen again. If that cannot be done, then redisplay
29268 recenters point as usual.
29269
29270 If the value is greater than 100, redisplay will never recenter point,
29271 but will always scroll just enough text to bring point into view, even
29272 if you move far away.
29273
29274 A value of zero means always recenter point if it moves off screen. */);
29275 scroll_conservatively = 0;
29276
29277 DEFVAR_INT ("scroll-margin", scroll_margin,
29278 doc: /* Number of lines of margin at the top and bottom of a window.
29279 Recenter the window whenever point gets within this many lines
29280 of the top or bottom of the window. */);
29281 scroll_margin = 0;
29282
29283 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29284 doc: /* Pixels per inch value for non-window system displays.
29285 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29286 Vdisplay_pixels_per_inch = make_float (72.0);
29287
29288 #ifdef GLYPH_DEBUG
29289 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29290 #endif
29291
29292 DEFVAR_LISP ("truncate-partial-width-windows",
29293 Vtruncate_partial_width_windows,
29294 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29295 For an integer value, truncate lines in each window narrower than the
29296 full frame width, provided the window width is less than that integer;
29297 otherwise, respect the value of `truncate-lines'.
29298
29299 For any other non-nil value, truncate lines in all windows that do
29300 not span the full frame width.
29301
29302 A value of nil means to respect the value of `truncate-lines'.
29303
29304 If `word-wrap' is enabled, you might want to reduce this. */);
29305 Vtruncate_partial_width_windows = make_number (50);
29306
29307 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29308 doc: /* Maximum buffer size for which line number should be displayed.
29309 If the buffer is bigger than this, the line number does not appear
29310 in the mode line. A value of nil means no limit. */);
29311 Vline_number_display_limit = Qnil;
29312
29313 DEFVAR_INT ("line-number-display-limit-width",
29314 line_number_display_limit_width,
29315 doc: /* Maximum line width (in characters) for line number display.
29316 If the average length of the lines near point is bigger than this, then the
29317 line number may be omitted from the mode line. */);
29318 line_number_display_limit_width = 200;
29319
29320 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29321 doc: /* Non-nil means highlight region even in nonselected windows. */);
29322 highlight_nonselected_windows = 0;
29323
29324 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29325 doc: /* Non-nil if more than one frame is visible on this display.
29326 Minibuffer-only frames don't count, but iconified frames do.
29327 This variable is not guaranteed to be accurate except while processing
29328 `frame-title-format' and `icon-title-format'. */);
29329
29330 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29331 doc: /* Template for displaying the title bar of visible frames.
29332 \(Assuming the window manager supports this feature.)
29333
29334 This variable has the same structure as `mode-line-format', except that
29335 the %c and %l constructs are ignored. It is used only on frames for
29336 which no explicit name has been set \(see `modify-frame-parameters'). */);
29337
29338 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29339 doc: /* Template for displaying the title bar of an iconified frame.
29340 \(Assuming the window manager supports this feature.)
29341 This variable has the same structure as `mode-line-format' (which see),
29342 and is used only on frames for which no explicit name has been set
29343 \(see `modify-frame-parameters'). */);
29344 Vicon_title_format
29345 = Vframe_title_format
29346 = listn (CONSTYPE_PURE, 3,
29347 intern_c_string ("multiple-frames"),
29348 build_pure_c_string ("%b"),
29349 listn (CONSTYPE_PURE, 4,
29350 empty_unibyte_string,
29351 intern_c_string ("invocation-name"),
29352 build_pure_c_string ("@"),
29353 intern_c_string ("system-name")));
29354
29355 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29356 doc: /* Maximum number of lines to keep in the message log buffer.
29357 If nil, disable message logging. If t, log messages but don't truncate
29358 the buffer when it becomes large. */);
29359 Vmessage_log_max = make_number (1000);
29360
29361 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29362 doc: /* Functions called before redisplay, if window sizes have changed.
29363 The value should be a list of functions that take one argument.
29364 Just before redisplay, for each frame, if any of its windows have changed
29365 size since the last redisplay, or have been split or deleted,
29366 all the functions in the list are called, with the frame as argument. */);
29367 Vwindow_size_change_functions = Qnil;
29368
29369 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29370 doc: /* List of functions to call before redisplaying a window with scrolling.
29371 Each function is called with two arguments, the window and its new
29372 display-start position. Note that these functions are also called by
29373 `set-window-buffer'. Also note that the value of `window-end' is not
29374 valid when these functions are called.
29375
29376 Warning: Do not use this feature to alter the way the window
29377 is scrolled. It is not designed for that, and such use probably won't
29378 work. */);
29379 Vwindow_scroll_functions = Qnil;
29380
29381 DEFVAR_LISP ("window-text-change-functions",
29382 Vwindow_text_change_functions,
29383 doc: /* Functions to call in redisplay when text in the window might change. */);
29384 Vwindow_text_change_functions = Qnil;
29385
29386 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29387 doc: /* Functions called when redisplay of a window reaches the end trigger.
29388 Each function is called with two arguments, the window and the end trigger value.
29389 See `set-window-redisplay-end-trigger'. */);
29390 Vredisplay_end_trigger_functions = Qnil;
29391
29392 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29393 doc: /* Non-nil means autoselect window with mouse pointer.
29394 If nil, do not autoselect windows.
29395 A positive number means delay autoselection by that many seconds: a
29396 window is autoselected only after the mouse has remained in that
29397 window for the duration of the delay.
29398 A negative number has a similar effect, but causes windows to be
29399 autoselected only after the mouse has stopped moving. \(Because of
29400 the way Emacs compares mouse events, you will occasionally wait twice
29401 that time before the window gets selected.\)
29402 Any other value means to autoselect window instantaneously when the
29403 mouse pointer enters it.
29404
29405 Autoselection selects the minibuffer only if it is active, and never
29406 unselects the minibuffer if it is active.
29407
29408 When customizing this variable make sure that the actual value of
29409 `focus-follows-mouse' matches the behavior of your window manager. */);
29410 Vmouse_autoselect_window = Qnil;
29411
29412 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29413 doc: /* Non-nil means automatically resize tool-bars.
29414 This dynamically changes the tool-bar's height to the minimum height
29415 that is needed to make all tool-bar items visible.
29416 If value is `grow-only', the tool-bar's height is only increased
29417 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29418 Vauto_resize_tool_bars = Qt;
29419
29420 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29421 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29422 auto_raise_tool_bar_buttons_p = 1;
29423
29424 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29425 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29426 make_cursor_line_fully_visible_p = 1;
29427
29428 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29429 doc: /* Border below tool-bar in pixels.
29430 If an integer, use it as the height of the border.
29431 If it is one of `internal-border-width' or `border-width', use the
29432 value of the corresponding frame parameter.
29433 Otherwise, no border is added below the tool-bar. */);
29434 Vtool_bar_border = Qinternal_border_width;
29435
29436 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29437 doc: /* Margin around tool-bar buttons in pixels.
29438 If an integer, use that for both horizontal and vertical margins.
29439 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29440 HORZ specifying the horizontal margin, and VERT specifying the
29441 vertical margin. */);
29442 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29443
29444 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29445 doc: /* Relief thickness of tool-bar buttons. */);
29446 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29447
29448 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29449 doc: /* Tool bar style to use.
29450 It can be one of
29451 image - show images only
29452 text - show text only
29453 both - show both, text below image
29454 both-horiz - show text to the right of the image
29455 text-image-horiz - show text to the left of the image
29456 any other - use system default or image if no system default.
29457
29458 This variable only affects the GTK+ toolkit version of Emacs. */);
29459 Vtool_bar_style = Qnil;
29460
29461 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29462 doc: /* Maximum number of characters a label can have to be shown.
29463 The tool bar style must also show labels for this to have any effect, see
29464 `tool-bar-style'. */);
29465 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29466
29467 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29468 doc: /* List of functions to call to fontify regions of text.
29469 Each function is called with one argument POS. Functions must
29470 fontify a region starting at POS in the current buffer, and give
29471 fontified regions the property `fontified'. */);
29472 Vfontification_functions = Qnil;
29473 Fmake_variable_buffer_local (Qfontification_functions);
29474
29475 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29476 unibyte_display_via_language_environment,
29477 doc: /* Non-nil means display unibyte text according to language environment.
29478 Specifically, this means that raw bytes in the range 160-255 decimal
29479 are displayed by converting them to the equivalent multibyte characters
29480 according to the current language environment. As a result, they are
29481 displayed according to the current fontset.
29482
29483 Note that this variable affects only how these bytes are displayed,
29484 but does not change the fact they are interpreted as raw bytes. */);
29485 unibyte_display_via_language_environment = 0;
29486
29487 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29488 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29489 If a float, it specifies a fraction of the mini-window frame's height.
29490 If an integer, it specifies a number of lines. */);
29491 Vmax_mini_window_height = make_float (0.25);
29492
29493 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29494 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29495 A value of nil means don't automatically resize mini-windows.
29496 A value of t means resize them to fit the text displayed in them.
29497 A value of `grow-only', the default, means let mini-windows grow only;
29498 they return to their normal size when the minibuffer is closed, or the
29499 echo area becomes empty. */);
29500 Vresize_mini_windows = Qgrow_only;
29501
29502 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29503 doc: /* Alist specifying how to blink the cursor off.
29504 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29505 `cursor-type' frame-parameter or variable equals ON-STATE,
29506 comparing using `equal', Emacs uses OFF-STATE to specify
29507 how to blink it off. ON-STATE and OFF-STATE are values for
29508 the `cursor-type' frame parameter.
29509
29510 If a frame's ON-STATE has no entry in this list,
29511 the frame's other specifications determine how to blink the cursor off. */);
29512 Vblink_cursor_alist = Qnil;
29513
29514 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29515 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29516 If non-nil, windows are automatically scrolled horizontally to make
29517 point visible. */);
29518 automatic_hscrolling_p = 1;
29519 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29520
29521 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29522 doc: /* How many columns away from the window edge point is allowed to get
29523 before automatic hscrolling will horizontally scroll the window. */);
29524 hscroll_margin = 5;
29525
29526 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29527 doc: /* How many columns to scroll the window when point gets too close to the edge.
29528 When point is less than `hscroll-margin' columns from the window
29529 edge, automatic hscrolling will scroll the window by the amount of columns
29530 determined by this variable. If its value is a positive integer, scroll that
29531 many columns. If it's a positive floating-point number, it specifies the
29532 fraction of the window's width to scroll. If it's nil or zero, point will be
29533 centered horizontally after the scroll. Any other value, including negative
29534 numbers, are treated as if the value were zero.
29535
29536 Automatic hscrolling always moves point outside the scroll margin, so if
29537 point was more than scroll step columns inside the margin, the window will
29538 scroll more than the value given by the scroll step.
29539
29540 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29541 and `scroll-right' overrides this variable's effect. */);
29542 Vhscroll_step = make_number (0);
29543
29544 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29545 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29546 Bind this around calls to `message' to let it take effect. */);
29547 message_truncate_lines = 0;
29548
29549 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29550 doc: /* Normal hook run to update the menu bar definitions.
29551 Redisplay runs this hook before it redisplays the menu bar.
29552 This is used to update submenus such as Buffers,
29553 whose contents depend on various data. */);
29554 Vmenu_bar_update_hook = Qnil;
29555
29556 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29557 doc: /* Frame for which we are updating a menu.
29558 The enable predicate for a menu binding should check this variable. */);
29559 Vmenu_updating_frame = Qnil;
29560
29561 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29562 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29563 inhibit_menubar_update = 0;
29564
29565 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29566 doc: /* Prefix prepended to all continuation lines at display time.
29567 The value may be a string, an image, or a stretch-glyph; it is
29568 interpreted in the same way as the value of a `display' text property.
29569
29570 This variable is overridden by any `wrap-prefix' text or overlay
29571 property.
29572
29573 To add a prefix to non-continuation lines, use `line-prefix'. */);
29574 Vwrap_prefix = Qnil;
29575 DEFSYM (Qwrap_prefix, "wrap-prefix");
29576 Fmake_variable_buffer_local (Qwrap_prefix);
29577
29578 DEFVAR_LISP ("line-prefix", Vline_prefix,
29579 doc: /* Prefix prepended to all non-continuation lines at display time.
29580 The value may be a string, an image, or a stretch-glyph; it is
29581 interpreted in the same way as the value of a `display' text property.
29582
29583 This variable is overridden by any `line-prefix' text or overlay
29584 property.
29585
29586 To add a prefix to continuation lines, use `wrap-prefix'. */);
29587 Vline_prefix = Qnil;
29588 DEFSYM (Qline_prefix, "line-prefix");
29589 Fmake_variable_buffer_local (Qline_prefix);
29590
29591 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29592 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29593 inhibit_eval_during_redisplay = 0;
29594
29595 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29596 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29597 inhibit_free_realized_faces = 0;
29598
29599 #ifdef GLYPH_DEBUG
29600 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29601 doc: /* Inhibit try_window_id display optimization. */);
29602 inhibit_try_window_id = 0;
29603
29604 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29605 doc: /* Inhibit try_window_reusing display optimization. */);
29606 inhibit_try_window_reusing = 0;
29607
29608 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29609 doc: /* Inhibit try_cursor_movement display optimization. */);
29610 inhibit_try_cursor_movement = 0;
29611 #endif /* GLYPH_DEBUG */
29612
29613 DEFVAR_INT ("overline-margin", overline_margin,
29614 doc: /* Space between overline and text, in pixels.
29615 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29616 margin to the character height. */);
29617 overline_margin = 2;
29618
29619 DEFVAR_INT ("underline-minimum-offset",
29620 underline_minimum_offset,
29621 doc: /* Minimum distance between baseline and underline.
29622 This can improve legibility of underlined text at small font sizes,
29623 particularly when using variable `x-use-underline-position-properties'
29624 with fonts that specify an UNDERLINE_POSITION relatively close to the
29625 baseline. The default value is 1. */);
29626 underline_minimum_offset = 1;
29627
29628 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29629 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29630 This feature only works when on a window system that can change
29631 cursor shapes. */);
29632 display_hourglass_p = 1;
29633
29634 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29635 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29636 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29637
29638 #ifdef HAVE_WINDOW_SYSTEM
29639 hourglass_atimer = NULL;
29640 hourglass_shown_p = 0;
29641 #endif /* HAVE_WINDOW_SYSTEM */
29642
29643 DEFSYM (Qglyphless_char, "glyphless-char");
29644 DEFSYM (Qhex_code, "hex-code");
29645 DEFSYM (Qempty_box, "empty-box");
29646 DEFSYM (Qthin_space, "thin-space");
29647 DEFSYM (Qzero_width, "zero-width");
29648
29649 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29650 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29651
29652 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29653 doc: /* Char-table defining glyphless characters.
29654 Each element, if non-nil, should be one of the following:
29655 an ASCII acronym string: display this string in a box
29656 `hex-code': display the hexadecimal code of a character in a box
29657 `empty-box': display as an empty box
29658 `thin-space': display as 1-pixel width space
29659 `zero-width': don't display
29660 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29661 display method for graphical terminals and text terminals respectively.
29662 GRAPHICAL and TEXT should each have one of the values listed above.
29663
29664 The char-table has one extra slot to control the display of a character for
29665 which no font is found. This slot only takes effect on graphical terminals.
29666 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29667 `thin-space'. The default is `empty-box'. */);
29668 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29669 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29670 Qempty_box);
29671
29672 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29673 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29674 Vdebug_on_message = Qnil;
29675 }
29676
29677
29678 /* Initialize this module when Emacs starts. */
29679
29680 void
29681 init_xdisp (void)
29682 {
29683 CHARPOS (this_line_start_pos) = 0;
29684
29685 if (!noninteractive)
29686 {
29687 struct window *m = XWINDOW (minibuf_window);
29688 Lisp_Object frame = m->frame;
29689 struct frame *f = XFRAME (frame);
29690 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29691 struct window *r = XWINDOW (root);
29692 int i;
29693
29694 echo_area_window = minibuf_window;
29695
29696 r->top_line = FRAME_TOP_MARGIN (f);
29697 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29698 r->total_cols = FRAME_COLS (f);
29699
29700 m->top_line = FRAME_LINES (f) - 1;
29701 m->total_lines = 1;
29702 m->total_cols = FRAME_COLS (f);
29703
29704 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29705 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29706 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29707
29708 /* The default ellipsis glyphs `...'. */
29709 for (i = 0; i < 3; ++i)
29710 default_invis_vector[i] = make_number ('.');
29711 }
29712
29713 {
29714 /* Allocate the buffer for frame titles.
29715 Also used for `format-mode-line'. */
29716 int size = 100;
29717 mode_line_noprop_buf = xmalloc (size);
29718 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29719 mode_line_noprop_ptr = mode_line_noprop_buf;
29720 mode_line_target = MODE_LINE_DISPLAY;
29721 }
29722
29723 help_echo_showing_p = 0;
29724 }
29725
29726 #ifdef HAVE_WINDOW_SYSTEM
29727
29728 /* Platform-independent portion of hourglass implementation. */
29729
29730 /* Cancel a currently active hourglass timer, and start a new one. */
29731 void
29732 start_hourglass (void)
29733 {
29734 struct timespec delay;
29735
29736 cancel_hourglass ();
29737
29738 if (INTEGERP (Vhourglass_delay)
29739 && XINT (Vhourglass_delay) > 0)
29740 delay = make_timespec (min (XINT (Vhourglass_delay),
29741 TYPE_MAXIMUM (time_t)),
29742 0);
29743 else if (FLOATP (Vhourglass_delay)
29744 && XFLOAT_DATA (Vhourglass_delay) > 0)
29745 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
29746 else
29747 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
29748
29749 #ifdef HAVE_NTGUI
29750 {
29751 extern void w32_note_current_window (void);
29752 w32_note_current_window ();
29753 }
29754 #endif /* HAVE_NTGUI */
29755
29756 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29757 show_hourglass, NULL);
29758 }
29759
29760
29761 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29762 shown. */
29763 void
29764 cancel_hourglass (void)
29765 {
29766 if (hourglass_atimer)
29767 {
29768 cancel_atimer (hourglass_atimer);
29769 hourglass_atimer = NULL;
29770 }
29771
29772 if (hourglass_shown_p)
29773 hide_hourglass ();
29774 }
29775
29776 #endif /* HAVE_WINDOW_SYSTEM */