]> code.delx.au - gnu-emacs/blob - src/xdisp.c
Merge from emacs-24; up to 2012-12-12T22:29:54Z!yamaoka@jpl.org
[gnu-emacs] / 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
303 #ifdef HAVE_X_WINDOWS
304 #include "xterm.h"
305 #endif
306 #ifdef HAVE_NTGUI
307 #include "w32term.h"
308 #endif
309 #ifdef HAVE_NS
310 #include "nsterm.h"
311 #endif
312 #ifdef USE_GTK
313 #include "gtkutil.h"
314 #endif
315
316 #include "font.h"
317
318 #ifndef FRAME_X_OUTPUT
319 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
320 #endif
321
322 #define INFINITY 10000000
323
324 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
325 Lisp_Object Qwindow_scroll_functions;
326 static Lisp_Object Qwindow_text_change_functions;
327 static Lisp_Object Qredisplay_end_trigger_functions;
328 Lisp_Object Qinhibit_point_motion_hooks;
329 static Lisp_Object QCeval, QCpropertize;
330 Lisp_Object QCfile, QCdata;
331 static Lisp_Object Qfontified;
332 static Lisp_Object Qgrow_only;
333 static Lisp_Object Qinhibit_eval_during_redisplay;
334 static Lisp_Object Qbuffer_position, Qposition, Qobject;
335 static Lisp_Object Qright_to_left, Qleft_to_right;
336
337 /* Cursor shapes. */
338 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
339
340 /* Pointer shapes. */
341 static Lisp_Object Qarrow, Qhand;
342 Lisp_Object Qtext;
343
344 /* Holds the list (error). */
345 static Lisp_Object list_of_error;
346
347 static Lisp_Object Qfontification_functions;
348
349 static Lisp_Object Qwrap_prefix;
350 static Lisp_Object Qline_prefix;
351 static Lisp_Object Qredisplay_internal;
352
353 /* Non-nil means don't actually do any redisplay. */
354
355 Lisp_Object Qinhibit_redisplay;
356
357 /* Names of text properties relevant for redisplay. */
358
359 Lisp_Object Qdisplay;
360
361 Lisp_Object Qspace, QCalign_to;
362 static Lisp_Object QCrelative_width, QCrelative_height;
363 Lisp_Object Qleft_margin, Qright_margin;
364 static Lisp_Object Qspace_width, Qraise;
365 static Lisp_Object Qslice;
366 Lisp_Object Qcenter;
367 static Lisp_Object Qmargin, Qpointer;
368 static Lisp_Object Qline_height;
369
370 /* These setters are used only in this file, so they can be private. */
371 static void
372 wset_base_line_number (struct window *w, Lisp_Object val)
373 {
374 w->base_line_number = val;
375 }
376 static void
377 wset_base_line_pos (struct window *w, Lisp_Object val)
378 {
379 w->base_line_pos = val;
380 }
381 static void
382 wset_column_number_displayed (struct window *w, Lisp_Object val)
383 {
384 w->column_number_displayed = val;
385 }
386 static void
387 wset_region_showing (struct window *w, Lisp_Object val)
388 {
389 w->region_showing = val;
390 }
391
392 #ifdef HAVE_WINDOW_SYSTEM
393
394 /* Test if overflow newline into fringe. Called with iterator IT
395 at or past right window margin, and with IT->current_x set. */
396
397 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
398 (!NILP (Voverflow_newline_into_fringe) \
399 && FRAME_WINDOW_P ((IT)->f) \
400 && ((IT)->bidi_it.paragraph_dir == R2L \
401 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
402 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
403 && (IT)->current_x == (IT)->last_visible_x \
404 && (IT)->line_wrap != WORD_WRAP)
405
406 #else /* !HAVE_WINDOW_SYSTEM */
407 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
408 #endif /* HAVE_WINDOW_SYSTEM */
409
410 /* Test if the display element loaded in IT, or the underlying buffer
411 or string character, is a space or a TAB character. This is used
412 to determine where word wrapping can occur. */
413
414 #define IT_DISPLAYING_WHITESPACE(it) \
415 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
416 || ((STRINGP (it->string) \
417 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
418 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
419 || (it->s \
420 && (it->s[IT_BYTEPOS (*it)] == ' ' \
421 || it->s[IT_BYTEPOS (*it)] == '\t')) \
422 || (IT_BYTEPOS (*it) < ZV_BYTE \
423 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
424 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
425
426 /* Name of the face used to highlight trailing whitespace. */
427
428 static Lisp_Object Qtrailing_whitespace;
429
430 /* Name and number of the face used to highlight escape glyphs. */
431
432 static Lisp_Object Qescape_glyph;
433
434 /* Name and number of the face used to highlight non-breaking spaces. */
435
436 static Lisp_Object Qnobreak_space;
437
438 /* The symbol `image' which is the car of the lists used to represent
439 images in Lisp. Also a tool bar style. */
440
441 Lisp_Object Qimage;
442
443 /* The image map types. */
444 Lisp_Object QCmap;
445 static Lisp_Object QCpointer;
446 static Lisp_Object Qrect, Qcircle, Qpoly;
447
448 /* Tool bar styles */
449 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
450
451 /* Non-zero means print newline to stdout before next mini-buffer
452 message. */
453
454 int noninteractive_need_newline;
455
456 /* Non-zero means print newline to message log before next message. */
457
458 static int message_log_need_newline;
459
460 /* Three markers that message_dolog uses.
461 It could allocate them itself, but that causes trouble
462 in handling memory-full errors. */
463 static Lisp_Object message_dolog_marker1;
464 static Lisp_Object message_dolog_marker2;
465 static Lisp_Object message_dolog_marker3;
466 \f
467 /* The buffer position of the first character appearing entirely or
468 partially on the line of the selected window which contains the
469 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
470 redisplay optimization in redisplay_internal. */
471
472 static struct text_pos this_line_start_pos;
473
474 /* Number of characters past the end of the line above, including the
475 terminating newline. */
476
477 static struct text_pos this_line_end_pos;
478
479 /* The vertical positions and the height of this line. */
480
481 static int this_line_vpos;
482 static int this_line_y;
483 static int this_line_pixel_height;
484
485 /* X position at which this display line starts. Usually zero;
486 negative if first character is partially visible. */
487
488 static int this_line_start_x;
489
490 /* The smallest character position seen by move_it_* functions as they
491 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
492 hscrolled lines, see display_line. */
493
494 static struct text_pos this_line_min_pos;
495
496 /* Buffer that this_line_.* variables are referring to. */
497
498 static struct buffer *this_line_buffer;
499
500
501 /* Values of those variables at last redisplay are stored as
502 properties on `overlay-arrow-position' symbol. However, if
503 Voverlay_arrow_position is a marker, last-arrow-position is its
504 numerical position. */
505
506 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
507
508 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
509 properties on a symbol in overlay-arrow-variable-list. */
510
511 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
512
513 Lisp_Object Qmenu_bar_update_hook;
514
515 /* Nonzero if an overlay arrow has been displayed in this window. */
516
517 static int overlay_arrow_seen;
518
519 /* Vector containing glyphs for an ellipsis `...'. */
520
521 static Lisp_Object default_invis_vector[3];
522
523 /* This is the window where the echo area message was displayed. It
524 is always a mini-buffer window, but it may not be the same window
525 currently active as a mini-buffer. */
526
527 Lisp_Object echo_area_window;
528
529 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
530 pushes the current message and the value of
531 message_enable_multibyte on the stack, the function restore_message
532 pops the stack and displays MESSAGE again. */
533
534 static Lisp_Object Vmessage_stack;
535
536 /* Nonzero means multibyte characters were enabled when the echo area
537 message was specified. */
538
539 static int message_enable_multibyte;
540
541 /* Nonzero if we should redraw the mode lines on the next redisplay. */
542
543 int update_mode_lines;
544
545 /* Nonzero if window sizes or contents have changed since last
546 redisplay that finished. */
547
548 int windows_or_buffers_changed;
549
550 /* Nonzero means a frame's cursor type has been changed. */
551
552 int cursor_type_changed;
553
554 /* Nonzero after display_mode_line if %l was used and it displayed a
555 line number. */
556
557 static int line_number_displayed;
558
559 /* The name of the *Messages* buffer, a string. */
560
561 static Lisp_Object Vmessages_buffer_name;
562
563 /* Current, index 0, and last displayed echo area message. Either
564 buffers from echo_buffers, or nil to indicate no message. */
565
566 Lisp_Object echo_area_buffer[2];
567
568 /* The buffers referenced from echo_area_buffer. */
569
570 static Lisp_Object echo_buffer[2];
571
572 /* A vector saved used in with_area_buffer to reduce consing. */
573
574 static Lisp_Object Vwith_echo_area_save_vector;
575
576 /* Non-zero means display_echo_area should display the last echo area
577 message again. Set by redisplay_preserve_echo_area. */
578
579 static int display_last_displayed_message_p;
580
581 /* Nonzero if echo area is being used by print; zero if being used by
582 message. */
583
584 static int message_buf_print;
585
586 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
587
588 static Lisp_Object Qinhibit_menubar_update;
589 static Lisp_Object Qmessage_truncate_lines;
590
591 /* Set to 1 in clear_message to make redisplay_internal aware
592 of an emptied echo area. */
593
594 static int message_cleared_p;
595
596 /* A scratch glyph row with contents used for generating truncation
597 glyphs. Also used in direct_output_for_insert. */
598
599 #define MAX_SCRATCH_GLYPHS 100
600 static struct glyph_row scratch_glyph_row;
601 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
602
603 /* Ascent and height of the last line processed by move_it_to. */
604
605 static int last_max_ascent, last_height;
606
607 /* Non-zero if there's a help-echo in the echo area. */
608
609 int help_echo_showing_p;
610
611 /* If >= 0, computed, exact values of mode-line and header-line height
612 to use in the macros CURRENT_MODE_LINE_HEIGHT and
613 CURRENT_HEADER_LINE_HEIGHT. */
614
615 int current_mode_line_height, current_header_line_height;
616
617 /* The maximum distance to look ahead for text properties. Values
618 that are too small let us call compute_char_face and similar
619 functions too often which is expensive. Values that are too large
620 let us call compute_char_face and alike too often because we
621 might not be interested in text properties that far away. */
622
623 #define TEXT_PROP_DISTANCE_LIMIT 100
624
625 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
626 iterator state and later restore it. This is needed because the
627 bidi iterator on bidi.c keeps a stacked cache of its states, which
628 is really a singleton. When we use scratch iterator objects to
629 move around the buffer, we can cause the bidi cache to be pushed or
630 popped, and therefore we need to restore the cache state when we
631 return to the original iterator. */
632 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
633 do { \
634 if (CACHE) \
635 bidi_unshelve_cache (CACHE, 1); \
636 ITCOPY = ITORIG; \
637 CACHE = bidi_shelve_cache (); \
638 } while (0)
639
640 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
641 do { \
642 if (pITORIG != pITCOPY) \
643 *(pITORIG) = *(pITCOPY); \
644 bidi_unshelve_cache (CACHE, 0); \
645 CACHE = NULL; \
646 } while (0)
647
648 #ifdef GLYPH_DEBUG
649
650 /* Non-zero means print traces of redisplay if compiled with
651 GLYPH_DEBUG defined. */
652
653 int trace_redisplay_p;
654
655 #endif /* GLYPH_DEBUG */
656
657 #ifdef DEBUG_TRACE_MOVE
658 /* Non-zero means trace with TRACE_MOVE to stderr. */
659 int trace_move;
660
661 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
662 #else
663 #define TRACE_MOVE(x) (void) 0
664 #endif
665
666 static Lisp_Object Qauto_hscroll_mode;
667
668 /* Buffer being redisplayed -- for redisplay_window_error. */
669
670 static struct buffer *displayed_buffer;
671
672 /* Value returned from text property handlers (see below). */
673
674 enum prop_handled
675 {
676 HANDLED_NORMALLY,
677 HANDLED_RECOMPUTE_PROPS,
678 HANDLED_OVERLAY_STRING_CONSUMED,
679 HANDLED_RETURN
680 };
681
682 /* A description of text properties that redisplay is interested
683 in. */
684
685 struct props
686 {
687 /* The name of the property. */
688 Lisp_Object *name;
689
690 /* A unique index for the property. */
691 enum prop_idx idx;
692
693 /* A handler function called to set up iterator IT from the property
694 at IT's current position. Value is used to steer handle_stop. */
695 enum prop_handled (*handler) (struct it *it);
696 };
697
698 static enum prop_handled handle_face_prop (struct it *);
699 static enum prop_handled handle_invisible_prop (struct it *);
700 static enum prop_handled handle_display_prop (struct it *);
701 static enum prop_handled handle_composition_prop (struct it *);
702 static enum prop_handled handle_overlay_change (struct it *);
703 static enum prop_handled handle_fontified_prop (struct it *);
704
705 /* Properties handled by iterators. */
706
707 static struct props it_props[] =
708 {
709 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
710 /* Handle `face' before `display' because some sub-properties of
711 `display' need to know the face. */
712 {&Qface, FACE_PROP_IDX, handle_face_prop},
713 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
714 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
715 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
716 {NULL, 0, NULL}
717 };
718
719 /* Value is the position described by X. If X is a marker, value is
720 the marker_position of X. Otherwise, value is X. */
721
722 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
723
724 /* Enumeration returned by some move_it_.* functions internally. */
725
726 enum move_it_result
727 {
728 /* Not used. Undefined value. */
729 MOVE_UNDEFINED,
730
731 /* Move ended at the requested buffer position or ZV. */
732 MOVE_POS_MATCH_OR_ZV,
733
734 /* Move ended at the requested X pixel position. */
735 MOVE_X_REACHED,
736
737 /* Move within a line ended at the end of a line that must be
738 continued. */
739 MOVE_LINE_CONTINUED,
740
741 /* Move within a line ended at the end of a line that would
742 be displayed truncated. */
743 MOVE_LINE_TRUNCATED,
744
745 /* Move within a line ended at a line end. */
746 MOVE_NEWLINE_OR_CR
747 };
748
749 /* This counter is used to clear the face cache every once in a while
750 in redisplay_internal. It is incremented for each redisplay.
751 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
752 cleared. */
753
754 #define CLEAR_FACE_CACHE_COUNT 500
755 static int clear_face_cache_count;
756
757 /* Similarly for the image cache. */
758
759 #ifdef HAVE_WINDOW_SYSTEM
760 #define CLEAR_IMAGE_CACHE_COUNT 101
761 static int clear_image_cache_count;
762
763 /* Null glyph slice */
764 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
765 #endif
766
767 /* True while redisplay_internal is in progress. */
768
769 bool redisplaying_p;
770
771 static Lisp_Object Qinhibit_free_realized_faces;
772 static Lisp_Object Qmode_line_default_help_echo;
773
774 /* If a string, XTread_socket generates an event to display that string.
775 (The display is done in read_char.) */
776
777 Lisp_Object help_echo_string;
778 Lisp_Object help_echo_window;
779 Lisp_Object help_echo_object;
780 ptrdiff_t help_echo_pos;
781
782 /* Temporary variable for XTread_socket. */
783
784 Lisp_Object previous_help_echo_string;
785
786 /* Platform-independent portion of hourglass implementation. */
787
788 /* Non-zero means an hourglass cursor is currently shown. */
789 int hourglass_shown_p;
790
791 /* If non-null, an asynchronous timer that, when it expires, displays
792 an hourglass cursor on all frames. */
793 struct atimer *hourglass_atimer;
794
795 /* Name of the face used to display glyphless characters. */
796 Lisp_Object Qglyphless_char;
797
798 /* Symbol for the purpose of Vglyphless_char_display. */
799 static Lisp_Object Qglyphless_char_display;
800
801 /* Method symbols for Vglyphless_char_display. */
802 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
803
804 /* Default pixel width of `thin-space' display method. */
805 #define THIN_SPACE_WIDTH 1
806
807 /* Default number of seconds to wait before displaying an hourglass
808 cursor. */
809 #define DEFAULT_HOURGLASS_DELAY 1
810
811 \f
812 /* Function prototypes. */
813
814 static void setup_for_ellipsis (struct it *, int);
815 static void set_iterator_to_next (struct it *, int);
816 static void mark_window_display_accurate_1 (struct window *, int);
817 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
818 static int display_prop_string_p (Lisp_Object, Lisp_Object);
819 static int cursor_row_p (struct glyph_row *);
820 static int redisplay_mode_lines (Lisp_Object, int);
821 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
822
823 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
824
825 static void handle_line_prefix (struct it *);
826
827 static void pint2str (char *, int, ptrdiff_t);
828 static void pint2hrstr (char *, int, ptrdiff_t);
829 static struct text_pos run_window_scroll_functions (Lisp_Object,
830 struct text_pos);
831 static void reconsider_clip_changes (struct window *, struct buffer *);
832 static int text_outside_line_unchanged_p (struct window *,
833 ptrdiff_t, ptrdiff_t);
834 static void store_mode_line_noprop_char (char);
835 static int store_mode_line_noprop (const char *, int, int);
836 static void handle_stop (struct it *);
837 static void handle_stop_backwards (struct it *, ptrdiff_t);
838 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
839 static void ensure_echo_area_buffers (void);
840 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
841 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
842 static int with_echo_area_buffer (struct window *, int,
843 int (*) (ptrdiff_t, Lisp_Object),
844 ptrdiff_t, Lisp_Object);
845 static void clear_garbaged_frames (void);
846 static int current_message_1 (ptrdiff_t, Lisp_Object);
847 static void pop_message (void);
848 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
849 static void set_message (Lisp_Object);
850 static int set_message_1 (ptrdiff_t, Lisp_Object);
851 static int display_echo_area (struct window *);
852 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
853 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
854 static Lisp_Object unwind_redisplay (Lisp_Object);
855 static int string_char_and_length (const unsigned char *, int *);
856 static struct text_pos display_prop_end (struct it *, Lisp_Object,
857 struct text_pos);
858 static int compute_window_start_on_continuation_line (struct window *);
859 static void insert_left_trunc_glyphs (struct it *);
860 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
861 Lisp_Object);
862 static void extend_face_to_end_of_line (struct it *);
863 static int append_space_for_newline (struct it *, int);
864 static int cursor_row_fully_visible_p (struct window *, int, int);
865 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
866 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
867 static int trailing_whitespace_p (ptrdiff_t);
868 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
869 static void push_it (struct it *, struct text_pos *);
870 static void iterate_out_of_display_property (struct it *);
871 static void pop_it (struct it *);
872 static void sync_frame_with_window_matrix_rows (struct window *);
873 static void redisplay_internal (void);
874 static int echo_area_display (int);
875 static void redisplay_windows (Lisp_Object);
876 static void redisplay_window (Lisp_Object, int);
877 static Lisp_Object redisplay_window_error (Lisp_Object);
878 static Lisp_Object redisplay_window_0 (Lisp_Object);
879 static Lisp_Object redisplay_window_1 (Lisp_Object);
880 static int set_cursor_from_row (struct window *, struct glyph_row *,
881 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
882 int, int);
883 static int update_menu_bar (struct frame *, int, int);
884 static int try_window_reusing_current_matrix (struct window *);
885 static int try_window_id (struct window *);
886 static int display_line (struct it *);
887 static int display_mode_lines (struct window *);
888 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
889 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
890 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
891 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
892 static void display_menu_bar (struct window *);
893 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
894 ptrdiff_t *);
895 static int display_string (const char *, Lisp_Object, Lisp_Object,
896 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
897 static void compute_line_metrics (struct it *);
898 static void run_redisplay_end_trigger_hook (struct it *);
899 static int get_overlay_strings (struct it *, ptrdiff_t);
900 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
901 static void next_overlay_string (struct it *);
902 static void reseat (struct it *, struct text_pos, int);
903 static void reseat_1 (struct it *, struct text_pos, int);
904 static void back_to_previous_visible_line_start (struct it *);
905 void reseat_at_previous_visible_line_start (struct it *);
906 static void reseat_at_next_visible_line_start (struct it *, int);
907 static int next_element_from_ellipsis (struct it *);
908 static int next_element_from_display_vector (struct it *);
909 static int next_element_from_string (struct it *);
910 static int next_element_from_c_string (struct it *);
911 static int next_element_from_buffer (struct it *);
912 static int next_element_from_composition (struct it *);
913 static int next_element_from_image (struct it *);
914 static int next_element_from_stretch (struct it *);
915 static void load_overlay_strings (struct it *, ptrdiff_t);
916 static int init_from_display_pos (struct it *, struct window *,
917 struct display_pos *);
918 static void reseat_to_string (struct it *, const char *,
919 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
920 static int get_next_display_element (struct it *);
921 static enum move_it_result
922 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
923 enum move_operation_enum);
924 void move_it_vertically_backward (struct it *, int);
925 static void get_visually_first_element (struct it *);
926 static void init_to_row_start (struct it *, struct window *,
927 struct glyph_row *);
928 static int init_to_row_end (struct it *, struct window *,
929 struct glyph_row *);
930 static void back_to_previous_line_start (struct it *);
931 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
932 static struct text_pos string_pos_nchars_ahead (struct text_pos,
933 Lisp_Object, ptrdiff_t);
934 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
935 static struct text_pos c_string_pos (ptrdiff_t, const char *, int);
936 static ptrdiff_t number_of_chars (const char *, int);
937 static void compute_stop_pos (struct it *);
938 static void compute_string_pos (struct text_pos *, struct text_pos,
939 Lisp_Object);
940 static int face_before_or_after_it_pos (struct it *, int);
941 static ptrdiff_t next_overlay_change (ptrdiff_t);
942 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
943 Lisp_Object, struct text_pos *, ptrdiff_t, int);
944 static int handle_single_display_spec (struct it *, Lisp_Object,
945 Lisp_Object, Lisp_Object,
946 struct text_pos *, ptrdiff_t, int, int);
947 static int underlying_face_id (struct it *);
948 static int in_ellipses_for_invisible_text_p (struct display_pos *,
949 struct window *);
950
951 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
952 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
953
954 #ifdef HAVE_WINDOW_SYSTEM
955
956 static void x_consider_frame_title (Lisp_Object);
957 static int tool_bar_lines_needed (struct frame *, int *);
958 static void update_tool_bar (struct frame *, int);
959 static void build_desired_tool_bar_string (struct frame *f);
960 static int redisplay_tool_bar (struct frame *);
961 static void display_tool_bar_line (struct it *, int);
962 static void notice_overwritten_cursor (struct window *,
963 enum glyph_row_area,
964 int, int, int, int);
965 static void append_stretch_glyph (struct it *, Lisp_Object,
966 int, int, int);
967
968
969 #endif /* HAVE_WINDOW_SYSTEM */
970
971 static void produce_special_glyphs (struct it *, enum display_element_type);
972 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
973 static int coords_in_mouse_face_p (struct window *, int, int);
974
975
976 \f
977 /***********************************************************************
978 Window display dimensions
979 ***********************************************************************/
980
981 /* Return the bottom boundary y-position for text lines in window W.
982 This is the first y position at which a line cannot start.
983 It is relative to the top of the window.
984
985 This is the height of W minus the height of a mode line, if any. */
986
987 int
988 window_text_bottom_y (struct window *w)
989 {
990 int height = WINDOW_TOTAL_HEIGHT (w);
991
992 if (WINDOW_WANTS_MODELINE_P (w))
993 height -= CURRENT_MODE_LINE_HEIGHT (w);
994 return height;
995 }
996
997 /* Return the pixel width of display area AREA of window W. AREA < 0
998 means return the total width of W, not including fringes to
999 the left and right of the window. */
1000
1001 int
1002 window_box_width (struct window *w, int area)
1003 {
1004 int cols = XFASTINT (w->total_cols);
1005 int pixels = 0;
1006
1007 if (!w->pseudo_window_p)
1008 {
1009 cols -= WINDOW_SCROLL_BAR_COLS (w);
1010
1011 if (area == TEXT_AREA)
1012 {
1013 if (INTEGERP (w->left_margin_cols))
1014 cols -= XFASTINT (w->left_margin_cols);
1015 if (INTEGERP (w->right_margin_cols))
1016 cols -= XFASTINT (w->right_margin_cols);
1017 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1018 }
1019 else if (area == LEFT_MARGIN_AREA)
1020 {
1021 cols = (INTEGERP (w->left_margin_cols)
1022 ? XFASTINT (w->left_margin_cols) : 0);
1023 pixels = 0;
1024 }
1025 else if (area == RIGHT_MARGIN_AREA)
1026 {
1027 cols = (INTEGERP (w->right_margin_cols)
1028 ? XFASTINT (w->right_margin_cols) : 0);
1029 pixels = 0;
1030 }
1031 }
1032
1033 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1034 }
1035
1036
1037 /* Return the pixel height of the display area of window W, not
1038 including mode lines of W, if any. */
1039
1040 int
1041 window_box_height (struct window *w)
1042 {
1043 struct frame *f = XFRAME (w->frame);
1044 int height = WINDOW_TOTAL_HEIGHT (w);
1045
1046 eassert (height >= 0);
1047
1048 /* Note: the code below that determines the mode-line/header-line
1049 height is essentially the same as that contained in the macro
1050 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1051 the appropriate glyph row has its `mode_line_p' flag set,
1052 and if it doesn't, uses estimate_mode_line_height instead. */
1053
1054 if (WINDOW_WANTS_MODELINE_P (w))
1055 {
1056 struct glyph_row *ml_row
1057 = (w->current_matrix && w->current_matrix->rows
1058 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1059 : 0);
1060 if (ml_row && ml_row->mode_line_p)
1061 height -= ml_row->height;
1062 else
1063 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1064 }
1065
1066 if (WINDOW_WANTS_HEADER_LINE_P (w))
1067 {
1068 struct glyph_row *hl_row
1069 = (w->current_matrix && w->current_matrix->rows
1070 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1071 : 0);
1072 if (hl_row && hl_row->mode_line_p)
1073 height -= hl_row->height;
1074 else
1075 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1076 }
1077
1078 /* With a very small font and a mode-line that's taller than
1079 default, we might end up with a negative height. */
1080 return max (0, height);
1081 }
1082
1083 /* Return the window-relative coordinate of the left edge of display
1084 area AREA of window W. AREA < 0 means return the left edge of the
1085 whole window, to the right of the left fringe of W. */
1086
1087 int
1088 window_box_left_offset (struct window *w, int area)
1089 {
1090 int x;
1091
1092 if (w->pseudo_window_p)
1093 return 0;
1094
1095 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1096
1097 if (area == TEXT_AREA)
1098 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1099 + window_box_width (w, LEFT_MARGIN_AREA));
1100 else if (area == RIGHT_MARGIN_AREA)
1101 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1102 + window_box_width (w, LEFT_MARGIN_AREA)
1103 + window_box_width (w, TEXT_AREA)
1104 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1105 ? 0
1106 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1107 else if (area == LEFT_MARGIN_AREA
1108 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1109 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1110
1111 return x;
1112 }
1113
1114
1115 /* Return the window-relative coordinate of the right edge of display
1116 area AREA of window W. AREA < 0 means return the right edge of the
1117 whole window, to the left of the right fringe of W. */
1118
1119 int
1120 window_box_right_offset (struct window *w, int area)
1121 {
1122 return window_box_left_offset (w, area) + window_box_width (w, area);
1123 }
1124
1125 /* Return the frame-relative coordinate of the left edge of display
1126 area AREA of window W. AREA < 0 means return the left edge of the
1127 whole window, to the right of the left fringe of W. */
1128
1129 int
1130 window_box_left (struct window *w, int area)
1131 {
1132 struct frame *f = XFRAME (w->frame);
1133 int x;
1134
1135 if (w->pseudo_window_p)
1136 return FRAME_INTERNAL_BORDER_WIDTH (f);
1137
1138 x = (WINDOW_LEFT_EDGE_X (w)
1139 + window_box_left_offset (w, area));
1140
1141 return x;
1142 }
1143
1144
1145 /* Return the frame-relative coordinate of the right edge of display
1146 area AREA of window W. AREA < 0 means return the right edge of the
1147 whole window, to the left of the right fringe of W. */
1148
1149 int
1150 window_box_right (struct window *w, int area)
1151 {
1152 return window_box_left (w, area) + window_box_width (w, area);
1153 }
1154
1155 /* Get the bounding box of the display area AREA of window W, without
1156 mode lines, in frame-relative coordinates. AREA < 0 means the
1157 whole window, not including the left and right fringes of
1158 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1159 coordinates of the upper-left corner of the box. Return in
1160 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1161
1162 void
1163 window_box (struct window *w, int area, int *box_x, int *box_y,
1164 int *box_width, int *box_height)
1165 {
1166 if (box_width)
1167 *box_width = window_box_width (w, area);
1168 if (box_height)
1169 *box_height = window_box_height (w);
1170 if (box_x)
1171 *box_x = window_box_left (w, area);
1172 if (box_y)
1173 {
1174 *box_y = WINDOW_TOP_EDGE_Y (w);
1175 if (WINDOW_WANTS_HEADER_LINE_P (w))
1176 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1177 }
1178 }
1179
1180
1181 /* Get the bounding box of the display area AREA of window W, without
1182 mode lines. AREA < 0 means the whole window, not including the
1183 left and right fringe of the window. Return in *TOP_LEFT_X
1184 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1185 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1186 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1187 box. */
1188
1189 static void
1190 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1191 int *bottom_right_x, int *bottom_right_y)
1192 {
1193 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1194 bottom_right_y);
1195 *bottom_right_x += *top_left_x;
1196 *bottom_right_y += *top_left_y;
1197 }
1198
1199
1200 \f
1201 /***********************************************************************
1202 Utilities
1203 ***********************************************************************/
1204
1205 /* Return the bottom y-position of the line the iterator IT is in.
1206 This can modify IT's settings. */
1207
1208 int
1209 line_bottom_y (struct it *it)
1210 {
1211 int line_height = it->max_ascent + it->max_descent;
1212 int line_top_y = it->current_y;
1213
1214 if (line_height == 0)
1215 {
1216 if (last_height)
1217 line_height = last_height;
1218 else if (IT_CHARPOS (*it) < ZV)
1219 {
1220 move_it_by_lines (it, 1);
1221 line_height = (it->max_ascent || it->max_descent
1222 ? it->max_ascent + it->max_descent
1223 : last_height);
1224 }
1225 else
1226 {
1227 struct glyph_row *row = it->glyph_row;
1228
1229 /* Use the default character height. */
1230 it->glyph_row = NULL;
1231 it->what = IT_CHARACTER;
1232 it->c = ' ';
1233 it->len = 1;
1234 PRODUCE_GLYPHS (it);
1235 line_height = it->ascent + it->descent;
1236 it->glyph_row = row;
1237 }
1238 }
1239
1240 return line_top_y + line_height;
1241 }
1242
1243 /* Subroutine of pos_visible_p below. Extracts a display string, if
1244 any, from the display spec given as its argument. */
1245 static Lisp_Object
1246 string_from_display_spec (Lisp_Object spec)
1247 {
1248 if (CONSP (spec))
1249 {
1250 while (CONSP (spec))
1251 {
1252 if (STRINGP (XCAR (spec)))
1253 return XCAR (spec);
1254 spec = XCDR (spec);
1255 }
1256 }
1257 else if (VECTORP (spec))
1258 {
1259 ptrdiff_t i;
1260
1261 for (i = 0; i < ASIZE (spec); i++)
1262 {
1263 if (STRINGP (AREF (spec, i)))
1264 return AREF (spec, i);
1265 }
1266 return Qnil;
1267 }
1268
1269 return spec;
1270 }
1271
1272
1273 /* Limit insanely large values of W->hscroll on frame F to the largest
1274 value that will still prevent first_visible_x and last_visible_x of
1275 'struct it' from overflowing an int. */
1276 static int
1277 window_hscroll_limited (struct window *w, struct frame *f)
1278 {
1279 ptrdiff_t window_hscroll = w->hscroll;
1280 int window_text_width = window_box_width (w, TEXT_AREA);
1281 int colwidth = FRAME_COLUMN_WIDTH (f);
1282
1283 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1284 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1285
1286 return window_hscroll;
1287 }
1288
1289 /* Return 1 if position CHARPOS is visible in window W.
1290 CHARPOS < 0 means return info about WINDOW_END position.
1291 If visible, set *X and *Y to pixel coordinates of top left corner.
1292 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1293 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1294
1295 int
1296 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1297 int *rtop, int *rbot, int *rowh, int *vpos)
1298 {
1299 struct it it;
1300 void *itdata = bidi_shelve_cache ();
1301 struct text_pos top;
1302 int visible_p = 0;
1303 struct buffer *old_buffer = NULL;
1304
1305 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1306 return visible_p;
1307
1308 if (XBUFFER (w->buffer) != current_buffer)
1309 {
1310 old_buffer = current_buffer;
1311 set_buffer_internal_1 (XBUFFER (w->buffer));
1312 }
1313
1314 SET_TEXT_POS_FROM_MARKER (top, w->start);
1315 /* Scrolling a minibuffer window via scroll bar when the echo area
1316 shows long text sometimes resets the minibuffer contents behind
1317 our backs. */
1318 if (CHARPOS (top) > ZV)
1319 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1320
1321 /* Compute exact mode line heights. */
1322 if (WINDOW_WANTS_MODELINE_P (w))
1323 current_mode_line_height
1324 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1325 BVAR (current_buffer, mode_line_format));
1326
1327 if (WINDOW_WANTS_HEADER_LINE_P (w))
1328 current_header_line_height
1329 = display_mode_line (w, HEADER_LINE_FACE_ID,
1330 BVAR (current_buffer, header_line_format));
1331
1332 start_display (&it, w, top);
1333 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1334 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1335
1336 if (charpos >= 0
1337 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1338 && IT_CHARPOS (it) >= charpos)
1339 /* When scanning backwards under bidi iteration, move_it_to
1340 stops at or _before_ CHARPOS, because it stops at or to
1341 the _right_ of the character at CHARPOS. */
1342 || (it.bidi_p && it.bidi_it.scan_dir == -1
1343 && IT_CHARPOS (it) <= charpos)))
1344 {
1345 /* We have reached CHARPOS, or passed it. How the call to
1346 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1347 or covered by a display property, move_it_to stops at the end
1348 of the invisible text, to the right of CHARPOS. (ii) If
1349 CHARPOS is in a display vector, move_it_to stops on its last
1350 glyph. */
1351 int top_x = it.current_x;
1352 int top_y = it.current_y;
1353 /* Calling line_bottom_y may change it.method, it.position, etc. */
1354 enum it_method it_method = it.method;
1355 int bottom_y = (last_height = 0, line_bottom_y (&it));
1356 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1357
1358 if (top_y < window_top_y)
1359 visible_p = bottom_y > window_top_y;
1360 else if (top_y < it.last_visible_y)
1361 visible_p = 1;
1362 if (bottom_y >= it.last_visible_y
1363 && it.bidi_p && it.bidi_it.scan_dir == -1
1364 && IT_CHARPOS (it) < charpos)
1365 {
1366 /* When the last line of the window is scanned backwards
1367 under bidi iteration, we could be duped into thinking
1368 that we have passed CHARPOS, when in fact move_it_to
1369 simply stopped short of CHARPOS because it reached
1370 last_visible_y. To see if that's what happened, we call
1371 move_it_to again with a slightly larger vertical limit,
1372 and see if it actually moved vertically; if it did, we
1373 didn't really reach CHARPOS, which is beyond window end. */
1374 struct it save_it = it;
1375 /* Why 10? because we don't know how many canonical lines
1376 will the height of the next line(s) be. So we guess. */
1377 int ten_more_lines =
1378 10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w)));
1379
1380 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1381 MOVE_TO_POS | MOVE_TO_Y);
1382 if (it.current_y > top_y)
1383 visible_p = 0;
1384
1385 it = save_it;
1386 }
1387 if (visible_p)
1388 {
1389 if (it_method == GET_FROM_DISPLAY_VECTOR)
1390 {
1391 /* We stopped on the last glyph of a display vector.
1392 Try and recompute. Hack alert! */
1393 if (charpos < 2 || top.charpos >= charpos)
1394 top_x = it.glyph_row->x;
1395 else
1396 {
1397 struct it it2;
1398 start_display (&it2, w, top);
1399 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1400 get_next_display_element (&it2);
1401 PRODUCE_GLYPHS (&it2);
1402 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1403 || it2.current_x > it2.last_visible_x)
1404 top_x = it.glyph_row->x;
1405 else
1406 {
1407 top_x = it2.current_x;
1408 top_y = it2.current_y;
1409 }
1410 }
1411 }
1412 else if (IT_CHARPOS (it) != charpos)
1413 {
1414 Lisp_Object cpos = make_number (charpos);
1415 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1416 Lisp_Object string = string_from_display_spec (spec);
1417 int newline_in_string = 0;
1418
1419 if (STRINGP (string))
1420 {
1421 const char *s = SSDATA (string);
1422 const char *e = s + SBYTES (string);
1423 while (s < e)
1424 {
1425 if (*s++ == '\n')
1426 {
1427 newline_in_string = 1;
1428 break;
1429 }
1430 }
1431 }
1432 /* The tricky code below is needed because there's a
1433 discrepancy between move_it_to and how we set cursor
1434 when the display line ends in a newline from a
1435 display string. move_it_to will stop _after_ such
1436 display strings, whereas set_cursor_from_row
1437 conspires with cursor_row_p to place the cursor on
1438 the first glyph produced from the display string. */
1439
1440 /* We have overshoot PT because it is covered by a
1441 display property whose value is a string. If the
1442 string includes embedded newlines, we are also in the
1443 wrong display line. Backtrack to the correct line,
1444 where the display string begins. */
1445 if (newline_in_string)
1446 {
1447 Lisp_Object startpos, endpos;
1448 EMACS_INT start, end;
1449 struct it it3;
1450 int it3_moved;
1451
1452 /* Find the first and the last buffer positions
1453 covered by the display string. */
1454 endpos =
1455 Fnext_single_char_property_change (cpos, Qdisplay,
1456 Qnil, Qnil);
1457 startpos =
1458 Fprevious_single_char_property_change (endpos, Qdisplay,
1459 Qnil, Qnil);
1460 start = XFASTINT (startpos);
1461 end = XFASTINT (endpos);
1462 /* Move to the last buffer position before the
1463 display property. */
1464 start_display (&it3, w, top);
1465 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1466 /* Move forward one more line if the position before
1467 the display string is a newline or if it is the
1468 rightmost character on a line that is
1469 continued or word-wrapped. */
1470 if (it3.method == GET_FROM_BUFFER
1471 && it3.c == '\n')
1472 move_it_by_lines (&it3, 1);
1473 else if (move_it_in_display_line_to (&it3, -1,
1474 it3.current_x
1475 + it3.pixel_width,
1476 MOVE_TO_X)
1477 == MOVE_LINE_CONTINUED)
1478 {
1479 move_it_by_lines (&it3, 1);
1480 /* When we are under word-wrap, the #$@%!
1481 move_it_by_lines moves 2 lines, so we need to
1482 fix that up. */
1483 if (it3.line_wrap == WORD_WRAP)
1484 move_it_by_lines (&it3, -1);
1485 }
1486
1487 /* Record the vertical coordinate of the display
1488 line where we wound up. */
1489 top_y = it3.current_y;
1490 if (it3.bidi_p)
1491 {
1492 /* When characters are reordered for display,
1493 the character displayed to the left of the
1494 display string could be _after_ the display
1495 property in the logical order. Use the
1496 smallest vertical position of these two. */
1497 start_display (&it3, w, top);
1498 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1499 if (it3.current_y < top_y)
1500 top_y = it3.current_y;
1501 }
1502 /* Move from the top of the window to the beginning
1503 of the display line where the display string
1504 begins. */
1505 start_display (&it3, w, top);
1506 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1507 /* If it3_moved stays zero after the 'while' loop
1508 below, that means we already were at a newline
1509 before the loop (e.g., the display string begins
1510 with a newline), so we don't need to (and cannot)
1511 inspect the glyphs of it3.glyph_row, because
1512 PRODUCE_GLYPHS will not produce anything for a
1513 newline, and thus it3.glyph_row stays at its
1514 stale content it got at top of the window. */
1515 it3_moved = 0;
1516 /* Finally, advance the iterator until we hit the
1517 first display element whose character position is
1518 CHARPOS, or until the first newline from the
1519 display string, which signals the end of the
1520 display line. */
1521 while (get_next_display_element (&it3))
1522 {
1523 PRODUCE_GLYPHS (&it3);
1524 if (IT_CHARPOS (it3) == charpos
1525 || ITERATOR_AT_END_OF_LINE_P (&it3))
1526 break;
1527 it3_moved = 1;
1528 set_iterator_to_next (&it3, 0);
1529 }
1530 top_x = it3.current_x - it3.pixel_width;
1531 /* Normally, we would exit the above loop because we
1532 found the display element whose character
1533 position is CHARPOS. For the contingency that we
1534 didn't, and stopped at the first newline from the
1535 display string, move back over the glyphs
1536 produced from the string, until we find the
1537 rightmost glyph not from the string. */
1538 if (it3_moved
1539 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1540 {
1541 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1542 + it3.glyph_row->used[TEXT_AREA];
1543
1544 while (EQ ((g - 1)->object, string))
1545 {
1546 --g;
1547 top_x -= g->pixel_width;
1548 }
1549 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1550 + it3.glyph_row->used[TEXT_AREA]);
1551 }
1552 }
1553 }
1554
1555 *x = top_x;
1556 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1557 *rtop = max (0, window_top_y - top_y);
1558 *rbot = max (0, bottom_y - it.last_visible_y);
1559 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1560 - max (top_y, window_top_y)));
1561 *vpos = it.vpos;
1562 }
1563 }
1564 else
1565 {
1566 /* We were asked to provide info about WINDOW_END. */
1567 struct it it2;
1568 void *it2data = NULL;
1569
1570 SAVE_IT (it2, it, it2data);
1571 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1572 move_it_by_lines (&it, 1);
1573 if (charpos < IT_CHARPOS (it)
1574 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1575 {
1576 visible_p = 1;
1577 RESTORE_IT (&it2, &it2, it2data);
1578 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1579 *x = it2.current_x;
1580 *y = it2.current_y + it2.max_ascent - it2.ascent;
1581 *rtop = max (0, -it2.current_y);
1582 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1583 - it.last_visible_y));
1584 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1585 it.last_visible_y)
1586 - max (it2.current_y,
1587 WINDOW_HEADER_LINE_HEIGHT (w))));
1588 *vpos = it2.vpos;
1589 }
1590 else
1591 bidi_unshelve_cache (it2data, 1);
1592 }
1593 bidi_unshelve_cache (itdata, 0);
1594
1595 if (old_buffer)
1596 set_buffer_internal_1 (old_buffer);
1597
1598 current_header_line_height = current_mode_line_height = -1;
1599
1600 if (visible_p && w->hscroll > 0)
1601 *x -=
1602 window_hscroll_limited (w, WINDOW_XFRAME (w))
1603 * WINDOW_FRAME_COLUMN_WIDTH (w);
1604
1605 #if 0
1606 /* Debugging code. */
1607 if (visible_p)
1608 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1609 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1610 else
1611 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1612 #endif
1613
1614 return visible_p;
1615 }
1616
1617
1618 /* Return the next character from STR. Return in *LEN the length of
1619 the character. This is like STRING_CHAR_AND_LENGTH but never
1620 returns an invalid character. If we find one, we return a `?', but
1621 with the length of the invalid character. */
1622
1623 static int
1624 string_char_and_length (const unsigned char *str, int *len)
1625 {
1626 int c;
1627
1628 c = STRING_CHAR_AND_LENGTH (str, *len);
1629 if (!CHAR_VALID_P (c))
1630 /* We may not change the length here because other places in Emacs
1631 don't use this function, i.e. they silently accept invalid
1632 characters. */
1633 c = '?';
1634
1635 return c;
1636 }
1637
1638
1639
1640 /* Given a position POS containing a valid character and byte position
1641 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1642
1643 static struct text_pos
1644 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1645 {
1646 eassert (STRINGP (string) && nchars >= 0);
1647
1648 if (STRING_MULTIBYTE (string))
1649 {
1650 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1651 int len;
1652
1653 while (nchars--)
1654 {
1655 string_char_and_length (p, &len);
1656 p += len;
1657 CHARPOS (pos) += 1;
1658 BYTEPOS (pos) += len;
1659 }
1660 }
1661 else
1662 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1663
1664 return pos;
1665 }
1666
1667
1668 /* Value is the text position, i.e. character and byte position,
1669 for character position CHARPOS in STRING. */
1670
1671 static struct text_pos
1672 string_pos (ptrdiff_t charpos, Lisp_Object string)
1673 {
1674 struct text_pos pos;
1675 eassert (STRINGP (string));
1676 eassert (charpos >= 0);
1677 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1678 return pos;
1679 }
1680
1681
1682 /* Value is a text position, i.e. character and byte position, for
1683 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1684 means recognize multibyte characters. */
1685
1686 static struct text_pos
1687 c_string_pos (ptrdiff_t charpos, const char *s, int multibyte_p)
1688 {
1689 struct text_pos pos;
1690
1691 eassert (s != NULL);
1692 eassert (charpos >= 0);
1693
1694 if (multibyte_p)
1695 {
1696 int len;
1697
1698 SET_TEXT_POS (pos, 0, 0);
1699 while (charpos--)
1700 {
1701 string_char_and_length ((const unsigned char *) s, &len);
1702 s += len;
1703 CHARPOS (pos) += 1;
1704 BYTEPOS (pos) += len;
1705 }
1706 }
1707 else
1708 SET_TEXT_POS (pos, charpos, charpos);
1709
1710 return pos;
1711 }
1712
1713
1714 /* Value is the number of characters in C string S. MULTIBYTE_P
1715 non-zero means recognize multibyte characters. */
1716
1717 static ptrdiff_t
1718 number_of_chars (const char *s, int multibyte_p)
1719 {
1720 ptrdiff_t nchars;
1721
1722 if (multibyte_p)
1723 {
1724 ptrdiff_t rest = strlen (s);
1725 int len;
1726 const unsigned char *p = (const unsigned char *) s;
1727
1728 for (nchars = 0; rest > 0; ++nchars)
1729 {
1730 string_char_and_length (p, &len);
1731 rest -= len, p += len;
1732 }
1733 }
1734 else
1735 nchars = strlen (s);
1736
1737 return nchars;
1738 }
1739
1740
1741 /* Compute byte position NEWPOS->bytepos corresponding to
1742 NEWPOS->charpos. POS is a known position in string STRING.
1743 NEWPOS->charpos must be >= POS.charpos. */
1744
1745 static void
1746 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1747 {
1748 eassert (STRINGP (string));
1749 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1750
1751 if (STRING_MULTIBYTE (string))
1752 *newpos = string_pos_nchars_ahead (pos, string,
1753 CHARPOS (*newpos) - CHARPOS (pos));
1754 else
1755 BYTEPOS (*newpos) = CHARPOS (*newpos);
1756 }
1757
1758 /* EXPORT:
1759 Return an estimation of the pixel height of mode or header lines on
1760 frame F. FACE_ID specifies what line's height to estimate. */
1761
1762 int
1763 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1764 {
1765 #ifdef HAVE_WINDOW_SYSTEM
1766 if (FRAME_WINDOW_P (f))
1767 {
1768 int height = FONT_HEIGHT (FRAME_FONT (f));
1769
1770 /* This function is called so early when Emacs starts that the face
1771 cache and mode line face are not yet initialized. */
1772 if (FRAME_FACE_CACHE (f))
1773 {
1774 struct face *face = FACE_FROM_ID (f, face_id);
1775 if (face)
1776 {
1777 if (face->font)
1778 height = FONT_HEIGHT (face->font);
1779 if (face->box_line_width > 0)
1780 height += 2 * face->box_line_width;
1781 }
1782 }
1783
1784 return height;
1785 }
1786 #endif
1787
1788 return 1;
1789 }
1790
1791 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1792 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1793 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1794 not force the value into range. */
1795
1796 void
1797 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1798 int *x, int *y, NativeRectangle *bounds, int noclip)
1799 {
1800
1801 #ifdef HAVE_WINDOW_SYSTEM
1802 if (FRAME_WINDOW_P (f))
1803 {
1804 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1805 even for negative values. */
1806 if (pix_x < 0)
1807 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1808 if (pix_y < 0)
1809 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1810
1811 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1812 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1813
1814 if (bounds)
1815 STORE_NATIVE_RECT (*bounds,
1816 FRAME_COL_TO_PIXEL_X (f, pix_x),
1817 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1818 FRAME_COLUMN_WIDTH (f) - 1,
1819 FRAME_LINE_HEIGHT (f) - 1);
1820
1821 if (!noclip)
1822 {
1823 if (pix_x < 0)
1824 pix_x = 0;
1825 else if (pix_x > FRAME_TOTAL_COLS (f))
1826 pix_x = FRAME_TOTAL_COLS (f);
1827
1828 if (pix_y < 0)
1829 pix_y = 0;
1830 else if (pix_y > FRAME_LINES (f))
1831 pix_y = FRAME_LINES (f);
1832 }
1833 }
1834 #endif
1835
1836 *x = pix_x;
1837 *y = pix_y;
1838 }
1839
1840
1841 /* Find the glyph under window-relative coordinates X/Y in window W.
1842 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1843 strings. Return in *HPOS and *VPOS the row and column number of
1844 the glyph found. Return in *AREA the glyph area containing X.
1845 Value is a pointer to the glyph found or null if X/Y is not on
1846 text, or we can't tell because W's current matrix is not up to
1847 date. */
1848
1849 static
1850 struct glyph *
1851 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1852 int *dx, int *dy, int *area)
1853 {
1854 struct glyph *glyph, *end;
1855 struct glyph_row *row = NULL;
1856 int x0, i;
1857
1858 /* Find row containing Y. Give up if some row is not enabled. */
1859 for (i = 0; i < w->current_matrix->nrows; ++i)
1860 {
1861 row = MATRIX_ROW (w->current_matrix, i);
1862 if (!row->enabled_p)
1863 return NULL;
1864 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1865 break;
1866 }
1867
1868 *vpos = i;
1869 *hpos = 0;
1870
1871 /* Give up if Y is not in the window. */
1872 if (i == w->current_matrix->nrows)
1873 return NULL;
1874
1875 /* Get the glyph area containing X. */
1876 if (w->pseudo_window_p)
1877 {
1878 *area = TEXT_AREA;
1879 x0 = 0;
1880 }
1881 else
1882 {
1883 if (x < window_box_left_offset (w, TEXT_AREA))
1884 {
1885 *area = LEFT_MARGIN_AREA;
1886 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1887 }
1888 else if (x < window_box_right_offset (w, TEXT_AREA))
1889 {
1890 *area = TEXT_AREA;
1891 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1892 }
1893 else
1894 {
1895 *area = RIGHT_MARGIN_AREA;
1896 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1897 }
1898 }
1899
1900 /* Find glyph containing X. */
1901 glyph = row->glyphs[*area];
1902 end = glyph + row->used[*area];
1903 x -= x0;
1904 while (glyph < end && x >= glyph->pixel_width)
1905 {
1906 x -= glyph->pixel_width;
1907 ++glyph;
1908 }
1909
1910 if (glyph == end)
1911 return NULL;
1912
1913 if (dx)
1914 {
1915 *dx = x;
1916 *dy = y - (row->y + row->ascent - glyph->ascent);
1917 }
1918
1919 *hpos = glyph - row->glyphs[*area];
1920 return glyph;
1921 }
1922
1923 /* Convert frame-relative x/y to coordinates relative to window W.
1924 Takes pseudo-windows into account. */
1925
1926 static void
1927 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1928 {
1929 if (w->pseudo_window_p)
1930 {
1931 /* A pseudo-window is always full-width, and starts at the
1932 left edge of the frame, plus a frame border. */
1933 struct frame *f = XFRAME (w->frame);
1934 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1935 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1936 }
1937 else
1938 {
1939 *x -= WINDOW_LEFT_EDGE_X (w);
1940 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1941 }
1942 }
1943
1944 #ifdef HAVE_WINDOW_SYSTEM
1945
1946 /* EXPORT:
1947 Return in RECTS[] at most N clipping rectangles for glyph string S.
1948 Return the number of stored rectangles. */
1949
1950 int
1951 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1952 {
1953 XRectangle r;
1954
1955 if (n <= 0)
1956 return 0;
1957
1958 if (s->row->full_width_p)
1959 {
1960 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1961 r.x = WINDOW_LEFT_EDGE_X (s->w);
1962 r.width = WINDOW_TOTAL_WIDTH (s->w);
1963
1964 /* Unless displaying a mode or menu bar line, which are always
1965 fully visible, clip to the visible part of the row. */
1966 if (s->w->pseudo_window_p)
1967 r.height = s->row->visible_height;
1968 else
1969 r.height = s->height;
1970 }
1971 else
1972 {
1973 /* This is a text line that may be partially visible. */
1974 r.x = window_box_left (s->w, s->area);
1975 r.width = window_box_width (s->w, s->area);
1976 r.height = s->row->visible_height;
1977 }
1978
1979 if (s->clip_head)
1980 if (r.x < s->clip_head->x)
1981 {
1982 if (r.width >= s->clip_head->x - r.x)
1983 r.width -= s->clip_head->x - r.x;
1984 else
1985 r.width = 0;
1986 r.x = s->clip_head->x;
1987 }
1988 if (s->clip_tail)
1989 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1990 {
1991 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1992 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1993 else
1994 r.width = 0;
1995 }
1996
1997 /* If S draws overlapping rows, it's sufficient to use the top and
1998 bottom of the window for clipping because this glyph string
1999 intentionally draws over other lines. */
2000 if (s->for_overlaps)
2001 {
2002 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2003 r.height = window_text_bottom_y (s->w) - r.y;
2004
2005 /* Alas, the above simple strategy does not work for the
2006 environments with anti-aliased text: if the same text is
2007 drawn onto the same place multiple times, it gets thicker.
2008 If the overlap we are processing is for the erased cursor, we
2009 take the intersection with the rectangle of the cursor. */
2010 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2011 {
2012 XRectangle rc, r_save = r;
2013
2014 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2015 rc.y = s->w->phys_cursor.y;
2016 rc.width = s->w->phys_cursor_width;
2017 rc.height = s->w->phys_cursor_height;
2018
2019 x_intersect_rectangles (&r_save, &rc, &r);
2020 }
2021 }
2022 else
2023 {
2024 /* Don't use S->y for clipping because it doesn't take partially
2025 visible lines into account. For example, it can be negative for
2026 partially visible lines at the top of a window. */
2027 if (!s->row->full_width_p
2028 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2029 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2030 else
2031 r.y = max (0, s->row->y);
2032 }
2033
2034 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2035
2036 /* If drawing the cursor, don't let glyph draw outside its
2037 advertised boundaries. Cleartype does this under some circumstances. */
2038 if (s->hl == DRAW_CURSOR)
2039 {
2040 struct glyph *glyph = s->first_glyph;
2041 int height, max_y;
2042
2043 if (s->x > r.x)
2044 {
2045 r.width -= s->x - r.x;
2046 r.x = s->x;
2047 }
2048 r.width = min (r.width, glyph->pixel_width);
2049
2050 /* If r.y is below window bottom, ensure that we still see a cursor. */
2051 height = min (glyph->ascent + glyph->descent,
2052 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2053 max_y = window_text_bottom_y (s->w) - height;
2054 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2055 if (s->ybase - glyph->ascent > max_y)
2056 {
2057 r.y = max_y;
2058 r.height = height;
2059 }
2060 else
2061 {
2062 /* Don't draw cursor glyph taller than our actual glyph. */
2063 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2064 if (height < r.height)
2065 {
2066 max_y = r.y + r.height;
2067 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2068 r.height = min (max_y - r.y, height);
2069 }
2070 }
2071 }
2072
2073 if (s->row->clip)
2074 {
2075 XRectangle r_save = r;
2076
2077 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2078 r.width = 0;
2079 }
2080
2081 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2082 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2083 {
2084 #ifdef CONVERT_FROM_XRECT
2085 CONVERT_FROM_XRECT (r, *rects);
2086 #else
2087 *rects = r;
2088 #endif
2089 return 1;
2090 }
2091 else
2092 {
2093 /* If we are processing overlapping and allowed to return
2094 multiple clipping rectangles, we exclude the row of the glyph
2095 string from the clipping rectangle. This is to avoid drawing
2096 the same text on the environment with anti-aliasing. */
2097 #ifdef CONVERT_FROM_XRECT
2098 XRectangle rs[2];
2099 #else
2100 XRectangle *rs = rects;
2101 #endif
2102 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2103
2104 if (s->for_overlaps & OVERLAPS_PRED)
2105 {
2106 rs[i] = r;
2107 if (r.y + r.height > row_y)
2108 {
2109 if (r.y < row_y)
2110 rs[i].height = row_y - r.y;
2111 else
2112 rs[i].height = 0;
2113 }
2114 i++;
2115 }
2116 if (s->for_overlaps & OVERLAPS_SUCC)
2117 {
2118 rs[i] = r;
2119 if (r.y < row_y + s->row->visible_height)
2120 {
2121 if (r.y + r.height > row_y + s->row->visible_height)
2122 {
2123 rs[i].y = row_y + s->row->visible_height;
2124 rs[i].height = r.y + r.height - rs[i].y;
2125 }
2126 else
2127 rs[i].height = 0;
2128 }
2129 i++;
2130 }
2131
2132 n = i;
2133 #ifdef CONVERT_FROM_XRECT
2134 for (i = 0; i < n; i++)
2135 CONVERT_FROM_XRECT (rs[i], rects[i]);
2136 #endif
2137 return n;
2138 }
2139 }
2140
2141 /* EXPORT:
2142 Return in *NR the clipping rectangle for glyph string S. */
2143
2144 void
2145 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2146 {
2147 get_glyph_string_clip_rects (s, nr, 1);
2148 }
2149
2150
2151 /* EXPORT:
2152 Return the position and height of the phys cursor in window W.
2153 Set w->phys_cursor_width to width of phys cursor.
2154 */
2155
2156 void
2157 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2158 struct glyph *glyph, int *xp, int *yp, int *heightp)
2159 {
2160 struct frame *f = XFRAME (WINDOW_FRAME (w));
2161 int x, y, wd, h, h0, y0;
2162
2163 /* Compute the width of the rectangle to draw. If on a stretch
2164 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2165 rectangle as wide as the glyph, but use a canonical character
2166 width instead. */
2167 wd = glyph->pixel_width - 1;
2168 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2169 wd++; /* Why? */
2170 #endif
2171
2172 x = w->phys_cursor.x;
2173 if (x < 0)
2174 {
2175 wd += x;
2176 x = 0;
2177 }
2178
2179 if (glyph->type == STRETCH_GLYPH
2180 && !x_stretch_cursor_p)
2181 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2182 w->phys_cursor_width = wd;
2183
2184 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2185
2186 /* If y is below window bottom, ensure that we still see a cursor. */
2187 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2188
2189 h = max (h0, glyph->ascent + glyph->descent);
2190 h0 = min (h0, glyph->ascent + glyph->descent);
2191
2192 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2193 if (y < y0)
2194 {
2195 h = max (h - (y0 - y) + 1, h0);
2196 y = y0 - 1;
2197 }
2198 else
2199 {
2200 y0 = window_text_bottom_y (w) - h0;
2201 if (y > y0)
2202 {
2203 h += y - y0;
2204 y = y0;
2205 }
2206 }
2207
2208 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2209 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2210 *heightp = h;
2211 }
2212
2213 /*
2214 * Remember which glyph the mouse is over.
2215 */
2216
2217 void
2218 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2219 {
2220 Lisp_Object window;
2221 struct window *w;
2222 struct glyph_row *r, *gr, *end_row;
2223 enum window_part part;
2224 enum glyph_row_area area;
2225 int x, y, width, height;
2226
2227 /* Try to determine frame pixel position and size of the glyph under
2228 frame pixel coordinates X/Y on frame F. */
2229
2230 if (!f->glyphs_initialized_p
2231 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2232 NILP (window)))
2233 {
2234 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2235 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2236 goto virtual_glyph;
2237 }
2238
2239 w = XWINDOW (window);
2240 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2241 height = WINDOW_FRAME_LINE_HEIGHT (w);
2242
2243 x = window_relative_x_coord (w, part, gx);
2244 y = gy - WINDOW_TOP_EDGE_Y (w);
2245
2246 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2247 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2248
2249 if (w->pseudo_window_p)
2250 {
2251 area = TEXT_AREA;
2252 part = ON_MODE_LINE; /* Don't adjust margin. */
2253 goto text_glyph;
2254 }
2255
2256 switch (part)
2257 {
2258 case ON_LEFT_MARGIN:
2259 area = LEFT_MARGIN_AREA;
2260 goto text_glyph;
2261
2262 case ON_RIGHT_MARGIN:
2263 area = RIGHT_MARGIN_AREA;
2264 goto text_glyph;
2265
2266 case ON_HEADER_LINE:
2267 case ON_MODE_LINE:
2268 gr = (part == ON_HEADER_LINE
2269 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2270 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2271 gy = gr->y;
2272 area = TEXT_AREA;
2273 goto text_glyph_row_found;
2274
2275 case ON_TEXT:
2276 area = TEXT_AREA;
2277
2278 text_glyph:
2279 gr = 0; gy = 0;
2280 for (; r <= end_row && r->enabled_p; ++r)
2281 if (r->y + r->height > y)
2282 {
2283 gr = r; gy = r->y;
2284 break;
2285 }
2286
2287 text_glyph_row_found:
2288 if (gr && gy <= y)
2289 {
2290 struct glyph *g = gr->glyphs[area];
2291 struct glyph *end = g + gr->used[area];
2292
2293 height = gr->height;
2294 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2295 if (gx + g->pixel_width > x)
2296 break;
2297
2298 if (g < end)
2299 {
2300 if (g->type == IMAGE_GLYPH)
2301 {
2302 /* Don't remember when mouse is over image, as
2303 image may have hot-spots. */
2304 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2305 return;
2306 }
2307 width = g->pixel_width;
2308 }
2309 else
2310 {
2311 /* Use nominal char spacing at end of line. */
2312 x -= gx;
2313 gx += (x / width) * width;
2314 }
2315
2316 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2317 gx += window_box_left_offset (w, area);
2318 }
2319 else
2320 {
2321 /* Use nominal line height at end of window. */
2322 gx = (x / width) * width;
2323 y -= gy;
2324 gy += (y / height) * height;
2325 }
2326 break;
2327
2328 case ON_LEFT_FRINGE:
2329 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2330 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2331 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2332 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2333 goto row_glyph;
2334
2335 case ON_RIGHT_FRINGE:
2336 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2337 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2338 : window_box_right_offset (w, TEXT_AREA));
2339 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2340 goto row_glyph;
2341
2342 case ON_SCROLL_BAR:
2343 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2344 ? 0
2345 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2346 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2347 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2348 : 0)));
2349 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2350
2351 row_glyph:
2352 gr = 0, gy = 0;
2353 for (; r <= end_row && r->enabled_p; ++r)
2354 if (r->y + r->height > y)
2355 {
2356 gr = r; gy = r->y;
2357 break;
2358 }
2359
2360 if (gr && gy <= y)
2361 height = gr->height;
2362 else
2363 {
2364 /* Use nominal line height at end of window. */
2365 y -= gy;
2366 gy += (y / height) * height;
2367 }
2368 break;
2369
2370 default:
2371 ;
2372 virtual_glyph:
2373 /* If there is no glyph under the mouse, then we divide the screen
2374 into a grid of the smallest glyph in the frame, and use that
2375 as our "glyph". */
2376
2377 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2378 round down even for negative values. */
2379 if (gx < 0)
2380 gx -= width - 1;
2381 if (gy < 0)
2382 gy -= height - 1;
2383
2384 gx = (gx / width) * width;
2385 gy = (gy / height) * height;
2386
2387 goto store_rect;
2388 }
2389
2390 gx += WINDOW_LEFT_EDGE_X (w);
2391 gy += WINDOW_TOP_EDGE_Y (w);
2392
2393 store_rect:
2394 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2395
2396 /* Visible feedback for debugging. */
2397 #if 0
2398 #if HAVE_X_WINDOWS
2399 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2400 f->output_data.x->normal_gc,
2401 gx, gy, width, height);
2402 #endif
2403 #endif
2404 }
2405
2406
2407 #endif /* HAVE_WINDOW_SYSTEM */
2408
2409 \f
2410 /***********************************************************************
2411 Lisp form evaluation
2412 ***********************************************************************/
2413
2414 /* Error handler for safe_eval and safe_call. */
2415
2416 static Lisp_Object
2417 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2418 {
2419 add_to_log ("Error during redisplay: %S signaled %S",
2420 Flist (nargs, args), arg);
2421 return Qnil;
2422 }
2423
2424 /* Call function FUNC with the rest of NARGS - 1 arguments
2425 following. Return the result, or nil if something went
2426 wrong. Prevent redisplay during the evaluation. */
2427
2428 Lisp_Object
2429 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2430 {
2431 Lisp_Object val;
2432
2433 if (inhibit_eval_during_redisplay)
2434 val = Qnil;
2435 else
2436 {
2437 va_list ap;
2438 ptrdiff_t i;
2439 ptrdiff_t count = SPECPDL_INDEX ();
2440 struct gcpro gcpro1;
2441 Lisp_Object *args = alloca (nargs * word_size);
2442
2443 args[0] = func;
2444 va_start (ap, func);
2445 for (i = 1; i < nargs; i++)
2446 args[i] = va_arg (ap, Lisp_Object);
2447 va_end (ap);
2448
2449 GCPRO1 (args[0]);
2450 gcpro1.nvars = nargs;
2451 specbind (Qinhibit_redisplay, Qt);
2452 /* Use Qt to ensure debugger does not run,
2453 so there is no possibility of wanting to redisplay. */
2454 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2455 safe_eval_handler);
2456 UNGCPRO;
2457 val = unbind_to (count, val);
2458 }
2459
2460 return val;
2461 }
2462
2463
2464 /* Call function FN with one argument ARG.
2465 Return the result, or nil if something went wrong. */
2466
2467 Lisp_Object
2468 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2469 {
2470 return safe_call (2, fn, arg);
2471 }
2472
2473 static Lisp_Object Qeval;
2474
2475 Lisp_Object
2476 safe_eval (Lisp_Object sexpr)
2477 {
2478 return safe_call1 (Qeval, sexpr);
2479 }
2480
2481 /* Call function FN with two arguments ARG1 and ARG2.
2482 Return the result, or nil if something went wrong. */
2483
2484 Lisp_Object
2485 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2486 {
2487 return safe_call (3, fn, arg1, arg2);
2488 }
2489
2490
2491 \f
2492 /***********************************************************************
2493 Debugging
2494 ***********************************************************************/
2495
2496 #if 0
2497
2498 /* Define CHECK_IT to perform sanity checks on iterators.
2499 This is for debugging. It is too slow to do unconditionally. */
2500
2501 static void
2502 check_it (struct it *it)
2503 {
2504 if (it->method == GET_FROM_STRING)
2505 {
2506 eassert (STRINGP (it->string));
2507 eassert (IT_STRING_CHARPOS (*it) >= 0);
2508 }
2509 else
2510 {
2511 eassert (IT_STRING_CHARPOS (*it) < 0);
2512 if (it->method == GET_FROM_BUFFER)
2513 {
2514 /* Check that character and byte positions agree. */
2515 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2516 }
2517 }
2518
2519 if (it->dpvec)
2520 eassert (it->current.dpvec_index >= 0);
2521 else
2522 eassert (it->current.dpvec_index < 0);
2523 }
2524
2525 #define CHECK_IT(IT) check_it ((IT))
2526
2527 #else /* not 0 */
2528
2529 #define CHECK_IT(IT) (void) 0
2530
2531 #endif /* not 0 */
2532
2533
2534 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2535
2536 /* Check that the window end of window W is what we expect it
2537 to be---the last row in the current matrix displaying text. */
2538
2539 static void
2540 check_window_end (struct window *w)
2541 {
2542 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2543 {
2544 struct glyph_row *row;
2545 eassert ((row = MATRIX_ROW (w->current_matrix,
2546 XFASTINT (w->window_end_vpos)),
2547 !row->enabled_p
2548 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2549 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2550 }
2551 }
2552
2553 #define CHECK_WINDOW_END(W) check_window_end ((W))
2554
2555 #else
2556
2557 #define CHECK_WINDOW_END(W) (void) 0
2558
2559 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2560
2561 /* Return mark position if current buffer has the region of non-zero length,
2562 or -1 otherwise. */
2563
2564 static ptrdiff_t
2565 markpos_of_region (void)
2566 {
2567 if (!NILP (Vtransient_mark_mode)
2568 && !NILP (BVAR (current_buffer, mark_active))
2569 && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
2570 {
2571 ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
2572
2573 if (markpos != PT)
2574 return markpos;
2575 }
2576 return -1;
2577 }
2578
2579 /***********************************************************************
2580 Iterator initialization
2581 ***********************************************************************/
2582
2583 /* Initialize IT for displaying current_buffer in window W, starting
2584 at character position CHARPOS. CHARPOS < 0 means that no buffer
2585 position is specified which is useful when the iterator is assigned
2586 a position later. BYTEPOS is the byte position corresponding to
2587 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2588
2589 If ROW is not null, calls to produce_glyphs with IT as parameter
2590 will produce glyphs in that row.
2591
2592 BASE_FACE_ID is the id of a base face to use. It must be one of
2593 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2594 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2595 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2596
2597 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2598 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2599 will be initialized to use the corresponding mode line glyph row of
2600 the desired matrix of W. */
2601
2602 void
2603 init_iterator (struct it *it, struct window *w,
2604 ptrdiff_t charpos, ptrdiff_t bytepos,
2605 struct glyph_row *row, enum face_id base_face_id)
2606 {
2607 ptrdiff_t markpos;
2608 enum face_id remapped_base_face_id = base_face_id;
2609
2610 /* Some precondition checks. */
2611 eassert (w != NULL && it != NULL);
2612 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2613 && charpos <= ZV));
2614
2615 /* If face attributes have been changed since the last redisplay,
2616 free realized faces now because they depend on face definitions
2617 that might have changed. Don't free faces while there might be
2618 desired matrices pending which reference these faces. */
2619 if (face_change_count && !inhibit_free_realized_faces)
2620 {
2621 face_change_count = 0;
2622 free_all_realized_faces (Qnil);
2623 }
2624
2625 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2626 if (! NILP (Vface_remapping_alist))
2627 remapped_base_face_id
2628 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2629
2630 /* Use one of the mode line rows of W's desired matrix if
2631 appropriate. */
2632 if (row == NULL)
2633 {
2634 if (base_face_id == MODE_LINE_FACE_ID
2635 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2636 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2637 else if (base_face_id == HEADER_LINE_FACE_ID)
2638 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2639 }
2640
2641 /* Clear IT. */
2642 memset (it, 0, sizeof *it);
2643 it->current.overlay_string_index = -1;
2644 it->current.dpvec_index = -1;
2645 it->base_face_id = remapped_base_face_id;
2646 it->string = Qnil;
2647 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2648 it->paragraph_embedding = L2R;
2649 it->bidi_it.string.lstring = Qnil;
2650 it->bidi_it.string.s = NULL;
2651 it->bidi_it.string.bufpos = 0;
2652
2653 /* The window in which we iterate over current_buffer: */
2654 XSETWINDOW (it->window, w);
2655 it->w = w;
2656 it->f = XFRAME (w->frame);
2657
2658 it->cmp_it.id = -1;
2659
2660 /* Extra space between lines (on window systems only). */
2661 if (base_face_id == DEFAULT_FACE_ID
2662 && FRAME_WINDOW_P (it->f))
2663 {
2664 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2665 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2666 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2667 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2668 * FRAME_LINE_HEIGHT (it->f));
2669 else if (it->f->extra_line_spacing > 0)
2670 it->extra_line_spacing = it->f->extra_line_spacing;
2671 it->max_extra_line_spacing = 0;
2672 }
2673
2674 /* If realized faces have been removed, e.g. because of face
2675 attribute changes of named faces, recompute them. When running
2676 in batch mode, the face cache of the initial frame is null. If
2677 we happen to get called, make a dummy face cache. */
2678 if (FRAME_FACE_CACHE (it->f) == NULL)
2679 init_frame_faces (it->f);
2680 if (FRAME_FACE_CACHE (it->f)->used == 0)
2681 recompute_basic_faces (it->f);
2682
2683 /* Current value of the `slice', `space-width', and 'height' properties. */
2684 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2685 it->space_width = Qnil;
2686 it->font_height = Qnil;
2687 it->override_ascent = -1;
2688
2689 /* Are control characters displayed as `^C'? */
2690 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2691
2692 /* -1 means everything between a CR and the following line end
2693 is invisible. >0 means lines indented more than this value are
2694 invisible. */
2695 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2696 ? (clip_to_bounds
2697 (-1, XINT (BVAR (current_buffer, selective_display)),
2698 PTRDIFF_MAX))
2699 : (!NILP (BVAR (current_buffer, selective_display))
2700 ? -1 : 0));
2701 it->selective_display_ellipsis_p
2702 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2703
2704 /* Display table to use. */
2705 it->dp = window_display_table (w);
2706
2707 /* Are multibyte characters enabled in current_buffer? */
2708 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2709
2710 /* If visible region is of non-zero length, set IT->region_beg_charpos
2711 and IT->region_end_charpos to the start and end of a visible region
2712 in window IT->w. Set both to -1 to indicate no region. */
2713 markpos = markpos_of_region ();
2714 if (0 <= markpos
2715 /* Maybe highlight only in selected window. */
2716 && (/* Either show region everywhere. */
2717 highlight_nonselected_windows
2718 /* Or show region in the selected window. */
2719 || w == XWINDOW (selected_window)
2720 /* Or show the region if we are in the mini-buffer and W is
2721 the window the mini-buffer refers to. */
2722 || (MINI_WINDOW_P (XWINDOW (selected_window))
2723 && WINDOWP (minibuf_selected_window)
2724 && w == XWINDOW (minibuf_selected_window))))
2725 {
2726 it->region_beg_charpos = min (PT, markpos);
2727 it->region_end_charpos = max (PT, markpos);
2728 }
2729 else
2730 it->region_beg_charpos = it->region_end_charpos = -1;
2731
2732 /* Get the position at which the redisplay_end_trigger hook should
2733 be run, if it is to be run at all. */
2734 if (MARKERP (w->redisplay_end_trigger)
2735 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2736 it->redisplay_end_trigger_charpos
2737 = marker_position (w->redisplay_end_trigger);
2738 else if (INTEGERP (w->redisplay_end_trigger))
2739 it->redisplay_end_trigger_charpos =
2740 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2741
2742 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2743
2744 /* Are lines in the display truncated? */
2745 if (base_face_id != DEFAULT_FACE_ID
2746 || it->w->hscroll
2747 || (! WINDOW_FULL_WIDTH_P (it->w)
2748 && ((!NILP (Vtruncate_partial_width_windows)
2749 && !INTEGERP (Vtruncate_partial_width_windows))
2750 || (INTEGERP (Vtruncate_partial_width_windows)
2751 && (WINDOW_TOTAL_COLS (it->w)
2752 < XINT (Vtruncate_partial_width_windows))))))
2753 it->line_wrap = TRUNCATE;
2754 else if (NILP (BVAR (current_buffer, truncate_lines)))
2755 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2756 ? WINDOW_WRAP : WORD_WRAP;
2757 else
2758 it->line_wrap = TRUNCATE;
2759
2760 /* Get dimensions of truncation and continuation glyphs. These are
2761 displayed as fringe bitmaps under X, but we need them for such
2762 frames when the fringes are turned off. But leave the dimensions
2763 zero for tooltip frames, as these glyphs look ugly there and also
2764 sabotage calculations of tooltip dimensions in x-show-tip. */
2765 #ifdef HAVE_WINDOW_SYSTEM
2766 if (!(FRAME_WINDOW_P (it->f)
2767 && FRAMEP (tip_frame)
2768 && it->f == XFRAME (tip_frame)))
2769 #endif
2770 {
2771 if (it->line_wrap == TRUNCATE)
2772 {
2773 /* We will need the truncation glyph. */
2774 eassert (it->glyph_row == NULL);
2775 produce_special_glyphs (it, IT_TRUNCATION);
2776 it->truncation_pixel_width = it->pixel_width;
2777 }
2778 else
2779 {
2780 /* We will need the continuation glyph. */
2781 eassert (it->glyph_row == NULL);
2782 produce_special_glyphs (it, IT_CONTINUATION);
2783 it->continuation_pixel_width = it->pixel_width;
2784 }
2785 }
2786
2787 /* Reset these values to zero because the produce_special_glyphs
2788 above has changed them. */
2789 it->pixel_width = it->ascent = it->descent = 0;
2790 it->phys_ascent = it->phys_descent = 0;
2791
2792 /* Set this after getting the dimensions of truncation and
2793 continuation glyphs, so that we don't produce glyphs when calling
2794 produce_special_glyphs, above. */
2795 it->glyph_row = row;
2796 it->area = TEXT_AREA;
2797
2798 /* Forget any previous info about this row being reversed. */
2799 if (it->glyph_row)
2800 it->glyph_row->reversed_p = 0;
2801
2802 /* Get the dimensions of the display area. The display area
2803 consists of the visible window area plus a horizontally scrolled
2804 part to the left of the window. All x-values are relative to the
2805 start of this total display area. */
2806 if (base_face_id != DEFAULT_FACE_ID)
2807 {
2808 /* Mode lines, menu bar in terminal frames. */
2809 it->first_visible_x = 0;
2810 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2811 }
2812 else
2813 {
2814 it->first_visible_x =
2815 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2816 it->last_visible_x = (it->first_visible_x
2817 + window_box_width (w, TEXT_AREA));
2818
2819 /* If we truncate lines, leave room for the truncation glyph(s) at
2820 the right margin. Otherwise, leave room for the continuation
2821 glyph(s). Done only if the window has no fringes. Since we
2822 don't know at this point whether there will be any R2L lines in
2823 the window, we reserve space for truncation/continuation glyphs
2824 even if only one of the fringes is absent. */
2825 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2826 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2827 {
2828 if (it->line_wrap == TRUNCATE)
2829 it->last_visible_x -= it->truncation_pixel_width;
2830 else
2831 it->last_visible_x -= it->continuation_pixel_width;
2832 }
2833
2834 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2835 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2836 }
2837
2838 /* Leave room for a border glyph. */
2839 if (!FRAME_WINDOW_P (it->f)
2840 && !WINDOW_RIGHTMOST_P (it->w))
2841 it->last_visible_x -= 1;
2842
2843 it->last_visible_y = window_text_bottom_y (w);
2844
2845 /* For mode lines and alike, arrange for the first glyph having a
2846 left box line if the face specifies a box. */
2847 if (base_face_id != DEFAULT_FACE_ID)
2848 {
2849 struct face *face;
2850
2851 it->face_id = remapped_base_face_id;
2852
2853 /* If we have a boxed mode line, make the first character appear
2854 with a left box line. */
2855 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2856 if (face->box != FACE_NO_BOX)
2857 it->start_of_box_run_p = 1;
2858 }
2859
2860 /* If a buffer position was specified, set the iterator there,
2861 getting overlays and face properties from that position. */
2862 if (charpos >= BUF_BEG (current_buffer))
2863 {
2864 it->end_charpos = ZV;
2865 IT_CHARPOS (*it) = charpos;
2866
2867 /* We will rely on `reseat' to set this up properly, via
2868 handle_face_prop. */
2869 it->face_id = it->base_face_id;
2870
2871 /* Compute byte position if not specified. */
2872 if (bytepos < charpos)
2873 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2874 else
2875 IT_BYTEPOS (*it) = bytepos;
2876
2877 it->start = it->current;
2878 /* Do we need to reorder bidirectional text? Not if this is a
2879 unibyte buffer: by definition, none of the single-byte
2880 characters are strong R2L, so no reordering is needed. And
2881 bidi.c doesn't support unibyte buffers anyway. Also, don't
2882 reorder while we are loading loadup.el, since the tables of
2883 character properties needed for reordering are not yet
2884 available. */
2885 it->bidi_p =
2886 NILP (Vpurify_flag)
2887 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2888 && it->multibyte_p;
2889
2890 /* If we are to reorder bidirectional text, init the bidi
2891 iterator. */
2892 if (it->bidi_p)
2893 {
2894 /* Note the paragraph direction that this buffer wants to
2895 use. */
2896 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2897 Qleft_to_right))
2898 it->paragraph_embedding = L2R;
2899 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2900 Qright_to_left))
2901 it->paragraph_embedding = R2L;
2902 else
2903 it->paragraph_embedding = NEUTRAL_DIR;
2904 bidi_unshelve_cache (NULL, 0);
2905 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2906 &it->bidi_it);
2907 }
2908
2909 /* Compute faces etc. */
2910 reseat (it, it->current.pos, 1);
2911 }
2912
2913 CHECK_IT (it);
2914 }
2915
2916
2917 /* Initialize IT for the display of window W with window start POS. */
2918
2919 void
2920 start_display (struct it *it, struct window *w, struct text_pos pos)
2921 {
2922 struct glyph_row *row;
2923 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2924
2925 row = w->desired_matrix->rows + first_vpos;
2926 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2927 it->first_vpos = first_vpos;
2928
2929 /* Don't reseat to previous visible line start if current start
2930 position is in a string or image. */
2931 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2932 {
2933 int start_at_line_beg_p;
2934 int first_y = it->current_y;
2935
2936 /* If window start is not at a line start, skip forward to POS to
2937 get the correct continuation lines width. */
2938 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2939 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2940 if (!start_at_line_beg_p)
2941 {
2942 int new_x;
2943
2944 reseat_at_previous_visible_line_start (it);
2945 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2946
2947 new_x = it->current_x + it->pixel_width;
2948
2949 /* If lines are continued, this line may end in the middle
2950 of a multi-glyph character (e.g. a control character
2951 displayed as \003, or in the middle of an overlay
2952 string). In this case move_it_to above will not have
2953 taken us to the start of the continuation line but to the
2954 end of the continued line. */
2955 if (it->current_x > 0
2956 && it->line_wrap != TRUNCATE /* Lines are continued. */
2957 && (/* And glyph doesn't fit on the line. */
2958 new_x > it->last_visible_x
2959 /* Or it fits exactly and we're on a window
2960 system frame. */
2961 || (new_x == it->last_visible_x
2962 && FRAME_WINDOW_P (it->f)
2963 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
2964 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
2965 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
2966 {
2967 if ((it->current.dpvec_index >= 0
2968 || it->current.overlay_string_index >= 0)
2969 /* If we are on a newline from a display vector or
2970 overlay string, then we are already at the end of
2971 a screen line; no need to go to the next line in
2972 that case, as this line is not really continued.
2973 (If we do go to the next line, C-e will not DTRT.) */
2974 && it->c != '\n')
2975 {
2976 set_iterator_to_next (it, 1);
2977 move_it_in_display_line_to (it, -1, -1, 0);
2978 }
2979
2980 it->continuation_lines_width += it->current_x;
2981 }
2982 /* If the character at POS is displayed via a display
2983 vector, move_it_to above stops at the final glyph of
2984 IT->dpvec. To make the caller redisplay that character
2985 again (a.k.a. start at POS), we need to reset the
2986 dpvec_index to the beginning of IT->dpvec. */
2987 else if (it->current.dpvec_index >= 0)
2988 it->current.dpvec_index = 0;
2989
2990 /* We're starting a new display line, not affected by the
2991 height of the continued line, so clear the appropriate
2992 fields in the iterator structure. */
2993 it->max_ascent = it->max_descent = 0;
2994 it->max_phys_ascent = it->max_phys_descent = 0;
2995
2996 it->current_y = first_y;
2997 it->vpos = 0;
2998 it->current_x = it->hpos = 0;
2999 }
3000 }
3001 }
3002
3003
3004 /* Return 1 if POS is a position in ellipses displayed for invisible
3005 text. W is the window we display, for text property lookup. */
3006
3007 static int
3008 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3009 {
3010 Lisp_Object prop, window;
3011 int ellipses_p = 0;
3012 ptrdiff_t charpos = CHARPOS (pos->pos);
3013
3014 /* If POS specifies a position in a display vector, this might
3015 be for an ellipsis displayed for invisible text. We won't
3016 get the iterator set up for delivering that ellipsis unless
3017 we make sure that it gets aware of the invisible text. */
3018 if (pos->dpvec_index >= 0
3019 && pos->overlay_string_index < 0
3020 && CHARPOS (pos->string_pos) < 0
3021 && charpos > BEGV
3022 && (XSETWINDOW (window, w),
3023 prop = Fget_char_property (make_number (charpos),
3024 Qinvisible, window),
3025 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3026 {
3027 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3028 window);
3029 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3030 }
3031
3032 return ellipses_p;
3033 }
3034
3035
3036 /* Initialize IT for stepping through current_buffer in window W,
3037 starting at position POS that includes overlay string and display
3038 vector/ control character translation position information. Value
3039 is zero if there are overlay strings with newlines at POS. */
3040
3041 static int
3042 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3043 {
3044 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3045 int i, overlay_strings_with_newlines = 0;
3046
3047 /* If POS specifies a position in a display vector, this might
3048 be for an ellipsis displayed for invisible text. We won't
3049 get the iterator set up for delivering that ellipsis unless
3050 we make sure that it gets aware of the invisible text. */
3051 if (in_ellipses_for_invisible_text_p (pos, w))
3052 {
3053 --charpos;
3054 bytepos = 0;
3055 }
3056
3057 /* Keep in mind: the call to reseat in init_iterator skips invisible
3058 text, so we might end up at a position different from POS. This
3059 is only a problem when POS is a row start after a newline and an
3060 overlay starts there with an after-string, and the overlay has an
3061 invisible property. Since we don't skip invisible text in
3062 display_line and elsewhere immediately after consuming the
3063 newline before the row start, such a POS will not be in a string,
3064 but the call to init_iterator below will move us to the
3065 after-string. */
3066 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3067
3068 /* This only scans the current chunk -- it should scan all chunks.
3069 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3070 to 16 in 22.1 to make this a lesser problem. */
3071 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3072 {
3073 const char *s = SSDATA (it->overlay_strings[i]);
3074 const char *e = s + SBYTES (it->overlay_strings[i]);
3075
3076 while (s < e && *s != '\n')
3077 ++s;
3078
3079 if (s < e)
3080 {
3081 overlay_strings_with_newlines = 1;
3082 break;
3083 }
3084 }
3085
3086 /* If position is within an overlay string, set up IT to the right
3087 overlay string. */
3088 if (pos->overlay_string_index >= 0)
3089 {
3090 int relative_index;
3091
3092 /* If the first overlay string happens to have a `display'
3093 property for an image, the iterator will be set up for that
3094 image, and we have to undo that setup first before we can
3095 correct the overlay string index. */
3096 if (it->method == GET_FROM_IMAGE)
3097 pop_it (it);
3098
3099 /* We already have the first chunk of overlay strings in
3100 IT->overlay_strings. Load more until the one for
3101 pos->overlay_string_index is in IT->overlay_strings. */
3102 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3103 {
3104 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3105 it->current.overlay_string_index = 0;
3106 while (n--)
3107 {
3108 load_overlay_strings (it, 0);
3109 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3110 }
3111 }
3112
3113 it->current.overlay_string_index = pos->overlay_string_index;
3114 relative_index = (it->current.overlay_string_index
3115 % OVERLAY_STRING_CHUNK_SIZE);
3116 it->string = it->overlay_strings[relative_index];
3117 eassert (STRINGP (it->string));
3118 it->current.string_pos = pos->string_pos;
3119 it->method = GET_FROM_STRING;
3120 it->end_charpos = SCHARS (it->string);
3121 /* Set up the bidi iterator for this overlay string. */
3122 if (it->bidi_p)
3123 {
3124 it->bidi_it.string.lstring = it->string;
3125 it->bidi_it.string.s = NULL;
3126 it->bidi_it.string.schars = SCHARS (it->string);
3127 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3128 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3129 it->bidi_it.string.unibyte = !it->multibyte_p;
3130 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3131 FRAME_WINDOW_P (it->f), &it->bidi_it);
3132
3133 /* Synchronize the state of the bidi iterator with
3134 pos->string_pos. For any string position other than
3135 zero, this will be done automagically when we resume
3136 iteration over the string and get_visually_first_element
3137 is called. But if string_pos is zero, and the string is
3138 to be reordered for display, we need to resync manually,
3139 since it could be that the iteration state recorded in
3140 pos ended at string_pos of 0 moving backwards in string. */
3141 if (CHARPOS (pos->string_pos) == 0)
3142 {
3143 get_visually_first_element (it);
3144 if (IT_STRING_CHARPOS (*it) != 0)
3145 do {
3146 /* Paranoia. */
3147 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3148 bidi_move_to_visually_next (&it->bidi_it);
3149 } while (it->bidi_it.charpos != 0);
3150 }
3151 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3152 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3153 }
3154 }
3155
3156 if (CHARPOS (pos->string_pos) >= 0)
3157 {
3158 /* Recorded position is not in an overlay string, but in another
3159 string. This can only be a string from a `display' property.
3160 IT should already be filled with that string. */
3161 it->current.string_pos = pos->string_pos;
3162 eassert (STRINGP (it->string));
3163 if (it->bidi_p)
3164 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3165 FRAME_WINDOW_P (it->f), &it->bidi_it);
3166 }
3167
3168 /* Restore position in display vector translations, control
3169 character translations or ellipses. */
3170 if (pos->dpvec_index >= 0)
3171 {
3172 if (it->dpvec == NULL)
3173 get_next_display_element (it);
3174 eassert (it->dpvec && it->current.dpvec_index == 0);
3175 it->current.dpvec_index = pos->dpvec_index;
3176 }
3177
3178 CHECK_IT (it);
3179 return !overlay_strings_with_newlines;
3180 }
3181
3182
3183 /* Initialize IT for stepping through current_buffer in window W
3184 starting at ROW->start. */
3185
3186 static void
3187 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3188 {
3189 init_from_display_pos (it, w, &row->start);
3190 it->start = row->start;
3191 it->continuation_lines_width = row->continuation_lines_width;
3192 CHECK_IT (it);
3193 }
3194
3195
3196 /* Initialize IT for stepping through current_buffer in window W
3197 starting in the line following ROW, i.e. starting at ROW->end.
3198 Value is zero if there are overlay strings with newlines at ROW's
3199 end position. */
3200
3201 static int
3202 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3203 {
3204 int success = 0;
3205
3206 if (init_from_display_pos (it, w, &row->end))
3207 {
3208 if (row->continued_p)
3209 it->continuation_lines_width
3210 = row->continuation_lines_width + row->pixel_width;
3211 CHECK_IT (it);
3212 success = 1;
3213 }
3214
3215 return success;
3216 }
3217
3218
3219
3220 \f
3221 /***********************************************************************
3222 Text properties
3223 ***********************************************************************/
3224
3225 /* Called when IT reaches IT->stop_charpos. Handle text property and
3226 overlay changes. Set IT->stop_charpos to the next position where
3227 to stop. */
3228
3229 static void
3230 handle_stop (struct it *it)
3231 {
3232 enum prop_handled handled;
3233 int handle_overlay_change_p;
3234 struct props *p;
3235
3236 it->dpvec = NULL;
3237 it->current.dpvec_index = -1;
3238 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3239 it->ignore_overlay_strings_at_pos_p = 0;
3240 it->ellipsis_p = 0;
3241
3242 /* Use face of preceding text for ellipsis (if invisible) */
3243 if (it->selective_display_ellipsis_p)
3244 it->saved_face_id = it->face_id;
3245
3246 do
3247 {
3248 handled = HANDLED_NORMALLY;
3249
3250 /* Call text property handlers. */
3251 for (p = it_props; p->handler; ++p)
3252 {
3253 handled = p->handler (it);
3254
3255 if (handled == HANDLED_RECOMPUTE_PROPS)
3256 break;
3257 else if (handled == HANDLED_RETURN)
3258 {
3259 /* We still want to show before and after strings from
3260 overlays even if the actual buffer text is replaced. */
3261 if (!handle_overlay_change_p
3262 || it->sp > 1
3263 /* Don't call get_overlay_strings_1 if we already
3264 have overlay strings loaded, because doing so
3265 will load them again and push the iterator state
3266 onto the stack one more time, which is not
3267 expected by the rest of the code that processes
3268 overlay strings. */
3269 || (it->current.overlay_string_index < 0
3270 ? !get_overlay_strings_1 (it, 0, 0)
3271 : 0))
3272 {
3273 if (it->ellipsis_p)
3274 setup_for_ellipsis (it, 0);
3275 /* When handling a display spec, we might load an
3276 empty string. In that case, discard it here. We
3277 used to discard it in handle_single_display_spec,
3278 but that causes get_overlay_strings_1, above, to
3279 ignore overlay strings that we must check. */
3280 if (STRINGP (it->string) && !SCHARS (it->string))
3281 pop_it (it);
3282 return;
3283 }
3284 else if (STRINGP (it->string) && !SCHARS (it->string))
3285 pop_it (it);
3286 else
3287 {
3288 it->ignore_overlay_strings_at_pos_p = 1;
3289 it->string_from_display_prop_p = 0;
3290 it->from_disp_prop_p = 0;
3291 handle_overlay_change_p = 0;
3292 }
3293 handled = HANDLED_RECOMPUTE_PROPS;
3294 break;
3295 }
3296 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3297 handle_overlay_change_p = 0;
3298 }
3299
3300 if (handled != HANDLED_RECOMPUTE_PROPS)
3301 {
3302 /* Don't check for overlay strings below when set to deliver
3303 characters from a display vector. */
3304 if (it->method == GET_FROM_DISPLAY_VECTOR)
3305 handle_overlay_change_p = 0;
3306
3307 /* Handle overlay changes.
3308 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3309 if it finds overlays. */
3310 if (handle_overlay_change_p)
3311 handled = handle_overlay_change (it);
3312 }
3313
3314 if (it->ellipsis_p)
3315 {
3316 setup_for_ellipsis (it, 0);
3317 break;
3318 }
3319 }
3320 while (handled == HANDLED_RECOMPUTE_PROPS);
3321
3322 /* Determine where to stop next. */
3323 if (handled == HANDLED_NORMALLY)
3324 compute_stop_pos (it);
3325 }
3326
3327
3328 /* Compute IT->stop_charpos from text property and overlay change
3329 information for IT's current position. */
3330
3331 static void
3332 compute_stop_pos (struct it *it)
3333 {
3334 register INTERVAL iv, next_iv;
3335 Lisp_Object object, limit, position;
3336 ptrdiff_t charpos, bytepos;
3337
3338 if (STRINGP (it->string))
3339 {
3340 /* Strings are usually short, so don't limit the search for
3341 properties. */
3342 it->stop_charpos = it->end_charpos;
3343 object = it->string;
3344 limit = Qnil;
3345 charpos = IT_STRING_CHARPOS (*it);
3346 bytepos = IT_STRING_BYTEPOS (*it);
3347 }
3348 else
3349 {
3350 ptrdiff_t pos;
3351
3352 /* If end_charpos is out of range for some reason, such as a
3353 misbehaving display function, rationalize it (Bug#5984). */
3354 if (it->end_charpos > ZV)
3355 it->end_charpos = ZV;
3356 it->stop_charpos = it->end_charpos;
3357
3358 /* If next overlay change is in front of the current stop pos
3359 (which is IT->end_charpos), stop there. Note: value of
3360 next_overlay_change is point-max if no overlay change
3361 follows. */
3362 charpos = IT_CHARPOS (*it);
3363 bytepos = IT_BYTEPOS (*it);
3364 pos = next_overlay_change (charpos);
3365 if (pos < it->stop_charpos)
3366 it->stop_charpos = pos;
3367
3368 /* If showing the region, we have to stop at the region
3369 start or end because the face might change there. */
3370 if (it->region_beg_charpos > 0)
3371 {
3372 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3373 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3374 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3375 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3376 }
3377
3378 /* Set up variables for computing the stop position from text
3379 property changes. */
3380 XSETBUFFER (object, current_buffer);
3381 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3382 }
3383
3384 /* Get the interval containing IT's position. Value is a null
3385 interval if there isn't such an interval. */
3386 position = make_number (charpos);
3387 iv = validate_interval_range (object, &position, &position, 0);
3388 if (iv)
3389 {
3390 Lisp_Object values_here[LAST_PROP_IDX];
3391 struct props *p;
3392
3393 /* Get properties here. */
3394 for (p = it_props; p->handler; ++p)
3395 values_here[p->idx] = textget (iv->plist, *p->name);
3396
3397 /* Look for an interval following iv that has different
3398 properties. */
3399 for (next_iv = next_interval (iv);
3400 (next_iv
3401 && (NILP (limit)
3402 || XFASTINT (limit) > next_iv->position));
3403 next_iv = next_interval (next_iv))
3404 {
3405 for (p = it_props; p->handler; ++p)
3406 {
3407 Lisp_Object new_value;
3408
3409 new_value = textget (next_iv->plist, *p->name);
3410 if (!EQ (values_here[p->idx], new_value))
3411 break;
3412 }
3413
3414 if (p->handler)
3415 break;
3416 }
3417
3418 if (next_iv)
3419 {
3420 if (INTEGERP (limit)
3421 && next_iv->position >= XFASTINT (limit))
3422 /* No text property change up to limit. */
3423 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3424 else
3425 /* Text properties change in next_iv. */
3426 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3427 }
3428 }
3429
3430 if (it->cmp_it.id < 0)
3431 {
3432 ptrdiff_t stoppos = it->end_charpos;
3433
3434 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3435 stoppos = -1;
3436 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3437 stoppos, it->string);
3438 }
3439
3440 eassert (STRINGP (it->string)
3441 || (it->stop_charpos >= BEGV
3442 && it->stop_charpos >= IT_CHARPOS (*it)));
3443 }
3444
3445
3446 /* Return the position of the next overlay change after POS in
3447 current_buffer. Value is point-max if no overlay change
3448 follows. This is like `next-overlay-change' but doesn't use
3449 xmalloc. */
3450
3451 static ptrdiff_t
3452 next_overlay_change (ptrdiff_t pos)
3453 {
3454 ptrdiff_t i, noverlays;
3455 ptrdiff_t endpos;
3456 Lisp_Object *overlays;
3457
3458 /* Get all overlays at the given position. */
3459 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3460
3461 /* If any of these overlays ends before endpos,
3462 use its ending point instead. */
3463 for (i = 0; i < noverlays; ++i)
3464 {
3465 Lisp_Object oend;
3466 ptrdiff_t oendpos;
3467
3468 oend = OVERLAY_END (overlays[i]);
3469 oendpos = OVERLAY_POSITION (oend);
3470 endpos = min (endpos, oendpos);
3471 }
3472
3473 return endpos;
3474 }
3475
3476 /* How many characters forward to search for a display property or
3477 display string. Searching too far forward makes the bidi display
3478 sluggish, especially in small windows. */
3479 #define MAX_DISP_SCAN 250
3480
3481 /* Return the character position of a display string at or after
3482 position specified by POSITION. If no display string exists at or
3483 after POSITION, return ZV. A display string is either an overlay
3484 with `display' property whose value is a string, or a `display'
3485 text property whose value is a string. STRING is data about the
3486 string to iterate; if STRING->lstring is nil, we are iterating a
3487 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3488 on a GUI frame. DISP_PROP is set to zero if we searched
3489 MAX_DISP_SCAN characters forward without finding any display
3490 strings, non-zero otherwise. It is set to 2 if the display string
3491 uses any kind of `(space ...)' spec that will produce a stretch of
3492 white space in the text area. */
3493 ptrdiff_t
3494 compute_display_string_pos (struct text_pos *position,
3495 struct bidi_string_data *string,
3496 int frame_window_p, int *disp_prop)
3497 {
3498 /* OBJECT = nil means current buffer. */
3499 Lisp_Object object =
3500 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3501 Lisp_Object pos, spec, limpos;
3502 int string_p = (string && (STRINGP (string->lstring) || string->s));
3503 ptrdiff_t eob = string_p ? string->schars : ZV;
3504 ptrdiff_t begb = string_p ? 0 : BEGV;
3505 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3506 ptrdiff_t lim =
3507 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3508 struct text_pos tpos;
3509 int rv = 0;
3510
3511 *disp_prop = 1;
3512
3513 if (charpos >= eob
3514 /* We don't support display properties whose values are strings
3515 that have display string properties. */
3516 || string->from_disp_str
3517 /* C strings cannot have display properties. */
3518 || (string->s && !STRINGP (object)))
3519 {
3520 *disp_prop = 0;
3521 return eob;
3522 }
3523
3524 /* If the character at CHARPOS is where the display string begins,
3525 return CHARPOS. */
3526 pos = make_number (charpos);
3527 if (STRINGP (object))
3528 bufpos = string->bufpos;
3529 else
3530 bufpos = charpos;
3531 tpos = *position;
3532 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3533 && (charpos <= begb
3534 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3535 object),
3536 spec))
3537 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3538 frame_window_p)))
3539 {
3540 if (rv == 2)
3541 *disp_prop = 2;
3542 return charpos;
3543 }
3544
3545 /* Look forward for the first character with a `display' property
3546 that will replace the underlying text when displayed. */
3547 limpos = make_number (lim);
3548 do {
3549 pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos);
3550 CHARPOS (tpos) = XFASTINT (pos);
3551 if (CHARPOS (tpos) >= lim)
3552 {
3553 *disp_prop = 0;
3554 break;
3555 }
3556 if (STRINGP (object))
3557 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3558 else
3559 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3560 spec = Fget_char_property (pos, Qdisplay, object);
3561 if (!STRINGP (object))
3562 bufpos = CHARPOS (tpos);
3563 } while (NILP (spec)
3564 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3565 bufpos, frame_window_p)));
3566 if (rv == 2)
3567 *disp_prop = 2;
3568
3569 return CHARPOS (tpos);
3570 }
3571
3572 /* Return the character position of the end of the display string that
3573 started at CHARPOS. If there's no display string at CHARPOS,
3574 return -1. A display string is either an overlay with `display'
3575 property whose value is a string or a `display' text property whose
3576 value is a string. */
3577 ptrdiff_t
3578 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3579 {
3580 /* OBJECT = nil means current buffer. */
3581 Lisp_Object object =
3582 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3583 Lisp_Object pos = make_number (charpos);
3584 ptrdiff_t eob =
3585 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3586
3587 if (charpos >= eob || (string->s && !STRINGP (object)))
3588 return eob;
3589
3590 /* It could happen that the display property or overlay was removed
3591 since we found it in compute_display_string_pos above. One way
3592 this can happen is if JIT font-lock was called (through
3593 handle_fontified_prop), and jit-lock-functions remove text
3594 properties or overlays from the portion of buffer that includes
3595 CHARPOS. Muse mode is known to do that, for example. In this
3596 case, we return -1 to the caller, to signal that no display
3597 string is actually present at CHARPOS. See bidi_fetch_char for
3598 how this is handled.
3599
3600 An alternative would be to never look for display properties past
3601 it->stop_charpos. But neither compute_display_string_pos nor
3602 bidi_fetch_char that calls it know or care where the next
3603 stop_charpos is. */
3604 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3605 return -1;
3606
3607 /* Look forward for the first character where the `display' property
3608 changes. */
3609 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3610
3611 return XFASTINT (pos);
3612 }
3613
3614
3615 \f
3616 /***********************************************************************
3617 Fontification
3618 ***********************************************************************/
3619
3620 /* Handle changes in the `fontified' property of the current buffer by
3621 calling hook functions from Qfontification_functions to fontify
3622 regions of text. */
3623
3624 static enum prop_handled
3625 handle_fontified_prop (struct it *it)
3626 {
3627 Lisp_Object prop, pos;
3628 enum prop_handled handled = HANDLED_NORMALLY;
3629
3630 if (!NILP (Vmemory_full))
3631 return handled;
3632
3633 /* Get the value of the `fontified' property at IT's current buffer
3634 position. (The `fontified' property doesn't have a special
3635 meaning in strings.) If the value is nil, call functions from
3636 Qfontification_functions. */
3637 if (!STRINGP (it->string)
3638 && it->s == NULL
3639 && !NILP (Vfontification_functions)
3640 && !NILP (Vrun_hooks)
3641 && (pos = make_number (IT_CHARPOS (*it)),
3642 prop = Fget_char_property (pos, Qfontified, Qnil),
3643 /* Ignore the special cased nil value always present at EOB since
3644 no amount of fontifying will be able to change it. */
3645 NILP (prop) && IT_CHARPOS (*it) < Z))
3646 {
3647 ptrdiff_t count = SPECPDL_INDEX ();
3648 Lisp_Object val;
3649 struct buffer *obuf = current_buffer;
3650 int begv = BEGV, zv = ZV;
3651 int old_clip_changed = current_buffer->clip_changed;
3652
3653 val = Vfontification_functions;
3654 specbind (Qfontification_functions, Qnil);
3655
3656 eassert (it->end_charpos == ZV);
3657
3658 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3659 safe_call1 (val, pos);
3660 else
3661 {
3662 Lisp_Object fns, fn;
3663 struct gcpro gcpro1, gcpro2;
3664
3665 fns = Qnil;
3666 GCPRO2 (val, fns);
3667
3668 for (; CONSP (val); val = XCDR (val))
3669 {
3670 fn = XCAR (val);
3671
3672 if (EQ (fn, Qt))
3673 {
3674 /* A value of t indicates this hook has a local
3675 binding; it means to run the global binding too.
3676 In a global value, t should not occur. If it
3677 does, we must ignore it to avoid an endless
3678 loop. */
3679 for (fns = Fdefault_value (Qfontification_functions);
3680 CONSP (fns);
3681 fns = XCDR (fns))
3682 {
3683 fn = XCAR (fns);
3684 if (!EQ (fn, Qt))
3685 safe_call1 (fn, pos);
3686 }
3687 }
3688 else
3689 safe_call1 (fn, pos);
3690 }
3691
3692 UNGCPRO;
3693 }
3694
3695 unbind_to (count, Qnil);
3696
3697 /* Fontification functions routinely call `save-restriction'.
3698 Normally, this tags clip_changed, which can confuse redisplay
3699 (see discussion in Bug#6671). Since we don't perform any
3700 special handling of fontification changes in the case where
3701 `save-restriction' isn't called, there's no point doing so in
3702 this case either. So, if the buffer's restrictions are
3703 actually left unchanged, reset clip_changed. */
3704 if (obuf == current_buffer)
3705 {
3706 if (begv == BEGV && zv == ZV)
3707 current_buffer->clip_changed = old_clip_changed;
3708 }
3709 /* There isn't much we can reasonably do to protect against
3710 misbehaving fontification, but here's a fig leaf. */
3711 else if (BUFFER_LIVE_P (obuf))
3712 set_buffer_internal_1 (obuf);
3713
3714 /* The fontification code may have added/removed text.
3715 It could do even a lot worse, but let's at least protect against
3716 the most obvious case where only the text past `pos' gets changed',
3717 as is/was done in grep.el where some escapes sequences are turned
3718 into face properties (bug#7876). */
3719 it->end_charpos = ZV;
3720
3721 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3722 something. This avoids an endless loop if they failed to
3723 fontify the text for which reason ever. */
3724 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3725 handled = HANDLED_RECOMPUTE_PROPS;
3726 }
3727
3728 return handled;
3729 }
3730
3731
3732 \f
3733 /***********************************************************************
3734 Faces
3735 ***********************************************************************/
3736
3737 /* Set up iterator IT from face properties at its current position.
3738 Called from handle_stop. */
3739
3740 static enum prop_handled
3741 handle_face_prop (struct it *it)
3742 {
3743 int new_face_id;
3744 ptrdiff_t next_stop;
3745
3746 if (!STRINGP (it->string))
3747 {
3748 new_face_id
3749 = face_at_buffer_position (it->w,
3750 IT_CHARPOS (*it),
3751 it->region_beg_charpos,
3752 it->region_end_charpos,
3753 &next_stop,
3754 (IT_CHARPOS (*it)
3755 + TEXT_PROP_DISTANCE_LIMIT),
3756 0, it->base_face_id);
3757
3758 /* Is this a start of a run of characters with box face?
3759 Caveat: this can be called for a freshly initialized
3760 iterator; face_id is -1 in this case. We know that the new
3761 face will not change until limit, i.e. if the new face has a
3762 box, all characters up to limit will have one. But, as
3763 usual, we don't know whether limit is really the end. */
3764 if (new_face_id != it->face_id)
3765 {
3766 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3767 /* If it->face_id is -1, old_face below will be NULL, see
3768 the definition of FACE_FROM_ID. This will happen if this
3769 is the initial call that gets the face. */
3770 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3771
3772 /* If the value of face_id of the iterator is -1, we have to
3773 look in front of IT's position and see whether there is a
3774 face there that's different from new_face_id. */
3775 if (!old_face && IT_CHARPOS (*it) > BEG)
3776 {
3777 int prev_face_id = face_before_it_pos (it);
3778
3779 old_face = FACE_FROM_ID (it->f, prev_face_id);
3780 }
3781
3782 /* If the new face has a box, but the old face does not,
3783 this is the start of a run of characters with box face,
3784 i.e. this character has a shadow on the left side. */
3785 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3786 && (old_face == NULL || !old_face->box));
3787 it->face_box_p = new_face->box != FACE_NO_BOX;
3788 }
3789 }
3790 else
3791 {
3792 int base_face_id;
3793 ptrdiff_t bufpos;
3794 int i;
3795 Lisp_Object from_overlay
3796 = (it->current.overlay_string_index >= 0
3797 ? it->string_overlays[it->current.overlay_string_index
3798 % OVERLAY_STRING_CHUNK_SIZE]
3799 : Qnil);
3800
3801 /* See if we got to this string directly or indirectly from
3802 an overlay property. That includes the before-string or
3803 after-string of an overlay, strings in display properties
3804 provided by an overlay, their text properties, etc.
3805
3806 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3807 if (! NILP (from_overlay))
3808 for (i = it->sp - 1; i >= 0; i--)
3809 {
3810 if (it->stack[i].current.overlay_string_index >= 0)
3811 from_overlay
3812 = it->string_overlays[it->stack[i].current.overlay_string_index
3813 % OVERLAY_STRING_CHUNK_SIZE];
3814 else if (! NILP (it->stack[i].from_overlay))
3815 from_overlay = it->stack[i].from_overlay;
3816
3817 if (!NILP (from_overlay))
3818 break;
3819 }
3820
3821 if (! NILP (from_overlay))
3822 {
3823 bufpos = IT_CHARPOS (*it);
3824 /* For a string from an overlay, the base face depends
3825 only on text properties and ignores overlays. */
3826 base_face_id
3827 = face_for_overlay_string (it->w,
3828 IT_CHARPOS (*it),
3829 it->region_beg_charpos,
3830 it->region_end_charpos,
3831 &next_stop,
3832 (IT_CHARPOS (*it)
3833 + TEXT_PROP_DISTANCE_LIMIT),
3834 0,
3835 from_overlay);
3836 }
3837 else
3838 {
3839 bufpos = 0;
3840
3841 /* For strings from a `display' property, use the face at
3842 IT's current buffer position as the base face to merge
3843 with, so that overlay strings appear in the same face as
3844 surrounding text, unless they specify their own
3845 faces. */
3846 base_face_id = it->string_from_prefix_prop_p
3847 ? DEFAULT_FACE_ID
3848 : underlying_face_id (it);
3849 }
3850
3851 new_face_id = face_at_string_position (it->w,
3852 it->string,
3853 IT_STRING_CHARPOS (*it),
3854 bufpos,
3855 it->region_beg_charpos,
3856 it->region_end_charpos,
3857 &next_stop,
3858 base_face_id, 0);
3859
3860 /* Is this a start of a run of characters with box? Caveat:
3861 this can be called for a freshly allocated iterator; face_id
3862 is -1 is this case. We know that the new face will not
3863 change until the next check pos, i.e. if the new face has a
3864 box, all characters up to that position will have a
3865 box. But, as usual, we don't know whether that position
3866 is really the end. */
3867 if (new_face_id != it->face_id)
3868 {
3869 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3870 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3871
3872 /* If new face has a box but old face hasn't, this is the
3873 start of a run of characters with box, i.e. it has a
3874 shadow on the left side. */
3875 it->start_of_box_run_p
3876 = new_face->box && (old_face == NULL || !old_face->box);
3877 it->face_box_p = new_face->box != FACE_NO_BOX;
3878 }
3879 }
3880
3881 it->face_id = new_face_id;
3882 return HANDLED_NORMALLY;
3883 }
3884
3885
3886 /* Return the ID of the face ``underlying'' IT's current position,
3887 which is in a string. If the iterator is associated with a
3888 buffer, return the face at IT's current buffer position.
3889 Otherwise, use the iterator's base_face_id. */
3890
3891 static int
3892 underlying_face_id (struct it *it)
3893 {
3894 int face_id = it->base_face_id, i;
3895
3896 eassert (STRINGP (it->string));
3897
3898 for (i = it->sp - 1; i >= 0; --i)
3899 if (NILP (it->stack[i].string))
3900 face_id = it->stack[i].face_id;
3901
3902 return face_id;
3903 }
3904
3905
3906 /* Compute the face one character before or after the current position
3907 of IT, in the visual order. BEFORE_P non-zero means get the face
3908 in front (to the left in L2R paragraphs, to the right in R2L
3909 paragraphs) of IT's screen position. Value is the ID of the face. */
3910
3911 static int
3912 face_before_or_after_it_pos (struct it *it, int before_p)
3913 {
3914 int face_id, limit;
3915 ptrdiff_t next_check_charpos;
3916 struct it it_copy;
3917 void *it_copy_data = NULL;
3918
3919 eassert (it->s == NULL);
3920
3921 if (STRINGP (it->string))
3922 {
3923 ptrdiff_t bufpos, charpos;
3924 int base_face_id;
3925
3926 /* No face change past the end of the string (for the case
3927 we are padding with spaces). No face change before the
3928 string start. */
3929 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3930 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3931 return it->face_id;
3932
3933 if (!it->bidi_p)
3934 {
3935 /* Set charpos to the position before or after IT's current
3936 position, in the logical order, which in the non-bidi
3937 case is the same as the visual order. */
3938 if (before_p)
3939 charpos = IT_STRING_CHARPOS (*it) - 1;
3940 else if (it->what == IT_COMPOSITION)
3941 /* For composition, we must check the character after the
3942 composition. */
3943 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3944 else
3945 charpos = IT_STRING_CHARPOS (*it) + 1;
3946 }
3947 else
3948 {
3949 if (before_p)
3950 {
3951 /* With bidi iteration, the character before the current
3952 in the visual order cannot be found by simple
3953 iteration, because "reverse" reordering is not
3954 supported. Instead, we need to use the move_it_*
3955 family of functions. */
3956 /* Ignore face changes before the first visible
3957 character on this display line. */
3958 if (it->current_x <= it->first_visible_x)
3959 return it->face_id;
3960 SAVE_IT (it_copy, *it, it_copy_data);
3961 /* Implementation note: Since move_it_in_display_line
3962 works in the iterator geometry, and thinks the first
3963 character is always the leftmost, even in R2L lines,
3964 we don't need to distinguish between the R2L and L2R
3965 cases here. */
3966 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3967 it_copy.current_x - 1, MOVE_TO_X);
3968 charpos = IT_STRING_CHARPOS (it_copy);
3969 RESTORE_IT (it, it, it_copy_data);
3970 }
3971 else
3972 {
3973 /* Set charpos to the string position of the character
3974 that comes after IT's current position in the visual
3975 order. */
3976 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3977
3978 it_copy = *it;
3979 while (n--)
3980 bidi_move_to_visually_next (&it_copy.bidi_it);
3981
3982 charpos = it_copy.bidi_it.charpos;
3983 }
3984 }
3985 eassert (0 <= charpos && charpos <= SCHARS (it->string));
3986
3987 if (it->current.overlay_string_index >= 0)
3988 bufpos = IT_CHARPOS (*it);
3989 else
3990 bufpos = 0;
3991
3992 base_face_id = underlying_face_id (it);
3993
3994 /* Get the face for ASCII, or unibyte. */
3995 face_id = face_at_string_position (it->w,
3996 it->string,
3997 charpos,
3998 bufpos,
3999 it->region_beg_charpos,
4000 it->region_end_charpos,
4001 &next_check_charpos,
4002 base_face_id, 0);
4003
4004 /* Correct the face for charsets different from ASCII. Do it
4005 for the multibyte case only. The face returned above is
4006 suitable for unibyte text if IT->string is unibyte. */
4007 if (STRING_MULTIBYTE (it->string))
4008 {
4009 struct text_pos pos1 = string_pos (charpos, it->string);
4010 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4011 int c, len;
4012 struct face *face = FACE_FROM_ID (it->f, face_id);
4013
4014 c = string_char_and_length (p, &len);
4015 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4016 }
4017 }
4018 else
4019 {
4020 struct text_pos pos;
4021
4022 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4023 || (IT_CHARPOS (*it) <= BEGV && before_p))
4024 return it->face_id;
4025
4026 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4027 pos = it->current.pos;
4028
4029 if (!it->bidi_p)
4030 {
4031 if (before_p)
4032 DEC_TEXT_POS (pos, it->multibyte_p);
4033 else
4034 {
4035 if (it->what == IT_COMPOSITION)
4036 {
4037 /* For composition, we must check the position after
4038 the composition. */
4039 pos.charpos += it->cmp_it.nchars;
4040 pos.bytepos += it->len;
4041 }
4042 else
4043 INC_TEXT_POS (pos, it->multibyte_p);
4044 }
4045 }
4046 else
4047 {
4048 if (before_p)
4049 {
4050 /* With bidi iteration, the character before the current
4051 in the visual order cannot be found by simple
4052 iteration, because "reverse" reordering is not
4053 supported. Instead, we need to use the move_it_*
4054 family of functions. */
4055 /* Ignore face changes before the first visible
4056 character on this display line. */
4057 if (it->current_x <= it->first_visible_x)
4058 return it->face_id;
4059 SAVE_IT (it_copy, *it, it_copy_data);
4060 /* Implementation note: Since move_it_in_display_line
4061 works in the iterator geometry, and thinks the first
4062 character is always the leftmost, even in R2L lines,
4063 we don't need to distinguish between the R2L and L2R
4064 cases here. */
4065 move_it_in_display_line (&it_copy, ZV,
4066 it_copy.current_x - 1, MOVE_TO_X);
4067 pos = it_copy.current.pos;
4068 RESTORE_IT (it, it, it_copy_data);
4069 }
4070 else
4071 {
4072 /* Set charpos to the buffer position of the character
4073 that comes after IT's current position in the visual
4074 order. */
4075 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4076
4077 it_copy = *it;
4078 while (n--)
4079 bidi_move_to_visually_next (&it_copy.bidi_it);
4080
4081 SET_TEXT_POS (pos,
4082 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4083 }
4084 }
4085 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4086
4087 /* Determine face for CHARSET_ASCII, or unibyte. */
4088 face_id = face_at_buffer_position (it->w,
4089 CHARPOS (pos),
4090 it->region_beg_charpos,
4091 it->region_end_charpos,
4092 &next_check_charpos,
4093 limit, 0, -1);
4094
4095 /* Correct the face for charsets different from ASCII. Do it
4096 for the multibyte case only. The face returned above is
4097 suitable for unibyte text if current_buffer is unibyte. */
4098 if (it->multibyte_p)
4099 {
4100 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4101 struct face *face = FACE_FROM_ID (it->f, face_id);
4102 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4103 }
4104 }
4105
4106 return face_id;
4107 }
4108
4109
4110 \f
4111 /***********************************************************************
4112 Invisible text
4113 ***********************************************************************/
4114
4115 /* Set up iterator IT from invisible properties at its current
4116 position. Called from handle_stop. */
4117
4118 static enum prop_handled
4119 handle_invisible_prop (struct it *it)
4120 {
4121 enum prop_handled handled = HANDLED_NORMALLY;
4122 int invis_p;
4123 Lisp_Object prop;
4124
4125 if (STRINGP (it->string))
4126 {
4127 Lisp_Object end_charpos, limit, charpos;
4128
4129 /* Get the value of the invisible text property at the
4130 current position. Value will be nil if there is no such
4131 property. */
4132 charpos = make_number (IT_STRING_CHARPOS (*it));
4133 prop = Fget_text_property (charpos, Qinvisible, it->string);
4134 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4135
4136 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4137 {
4138 /* Record whether we have to display an ellipsis for the
4139 invisible text. */
4140 int display_ellipsis_p = (invis_p == 2);
4141 ptrdiff_t len, endpos;
4142
4143 handled = HANDLED_RECOMPUTE_PROPS;
4144
4145 /* Get the position at which the next visible text can be
4146 found in IT->string, if any. */
4147 endpos = len = SCHARS (it->string);
4148 XSETINT (limit, len);
4149 do
4150 {
4151 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4152 it->string, limit);
4153 if (INTEGERP (end_charpos))
4154 {
4155 endpos = XFASTINT (end_charpos);
4156 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4157 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4158 if (invis_p == 2)
4159 display_ellipsis_p = 1;
4160 }
4161 }
4162 while (invis_p && endpos < len);
4163
4164 if (display_ellipsis_p)
4165 it->ellipsis_p = 1;
4166
4167 if (endpos < len)
4168 {
4169 /* Text at END_CHARPOS is visible. Move IT there. */
4170 struct text_pos old;
4171 ptrdiff_t oldpos;
4172
4173 old = it->current.string_pos;
4174 oldpos = CHARPOS (old);
4175 if (it->bidi_p)
4176 {
4177 if (it->bidi_it.first_elt
4178 && it->bidi_it.charpos < SCHARS (it->string))
4179 bidi_paragraph_init (it->paragraph_embedding,
4180 &it->bidi_it, 1);
4181 /* Bidi-iterate out of the invisible text. */
4182 do
4183 {
4184 bidi_move_to_visually_next (&it->bidi_it);
4185 }
4186 while (oldpos <= it->bidi_it.charpos
4187 && it->bidi_it.charpos < endpos);
4188
4189 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4190 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4191 if (IT_CHARPOS (*it) >= endpos)
4192 it->prev_stop = endpos;
4193 }
4194 else
4195 {
4196 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4197 compute_string_pos (&it->current.string_pos, old, it->string);
4198 }
4199 }
4200 else
4201 {
4202 /* The rest of the string is invisible. If this is an
4203 overlay string, proceed with the next overlay string
4204 or whatever comes and return a character from there. */
4205 if (it->current.overlay_string_index >= 0
4206 && !display_ellipsis_p)
4207 {
4208 next_overlay_string (it);
4209 /* Don't check for overlay strings when we just
4210 finished processing them. */
4211 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4212 }
4213 else
4214 {
4215 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4216 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4217 }
4218 }
4219 }
4220 }
4221 else
4222 {
4223 ptrdiff_t newpos, next_stop, start_charpos, tem;
4224 Lisp_Object pos, overlay;
4225
4226 /* First of all, is there invisible text at this position? */
4227 tem = start_charpos = IT_CHARPOS (*it);
4228 pos = make_number (tem);
4229 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4230 &overlay);
4231 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4232
4233 /* If we are on invisible text, skip over it. */
4234 if (invis_p && start_charpos < it->end_charpos)
4235 {
4236 /* Record whether we have to display an ellipsis for the
4237 invisible text. */
4238 int display_ellipsis_p = invis_p == 2;
4239
4240 handled = HANDLED_RECOMPUTE_PROPS;
4241
4242 /* Loop skipping over invisible text. The loop is left at
4243 ZV or with IT on the first char being visible again. */
4244 do
4245 {
4246 /* Try to skip some invisible text. Return value is the
4247 position reached which can be equal to where we start
4248 if there is nothing invisible there. This skips both
4249 over invisible text properties and overlays with
4250 invisible property. */
4251 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4252
4253 /* If we skipped nothing at all we weren't at invisible
4254 text in the first place. If everything to the end of
4255 the buffer was skipped, end the loop. */
4256 if (newpos == tem || newpos >= ZV)
4257 invis_p = 0;
4258 else
4259 {
4260 /* We skipped some characters but not necessarily
4261 all there are. Check if we ended up on visible
4262 text. Fget_char_property returns the property of
4263 the char before the given position, i.e. if we
4264 get invis_p = 0, this means that the char at
4265 newpos is visible. */
4266 pos = make_number (newpos);
4267 prop = Fget_char_property (pos, Qinvisible, it->window);
4268 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4269 }
4270
4271 /* If we ended up on invisible text, proceed to
4272 skip starting with next_stop. */
4273 if (invis_p)
4274 tem = next_stop;
4275
4276 /* If there are adjacent invisible texts, don't lose the
4277 second one's ellipsis. */
4278 if (invis_p == 2)
4279 display_ellipsis_p = 1;
4280 }
4281 while (invis_p);
4282
4283 /* The position newpos is now either ZV or on visible text. */
4284 if (it->bidi_p)
4285 {
4286 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4287 int on_newline =
4288 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4289 int after_newline =
4290 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4291
4292 /* If the invisible text ends on a newline or on a
4293 character after a newline, we can avoid the costly,
4294 character by character, bidi iteration to NEWPOS, and
4295 instead simply reseat the iterator there. That's
4296 because all bidi reordering information is tossed at
4297 the newline. This is a big win for modes that hide
4298 complete lines, like Outline, Org, etc. */
4299 if (on_newline || after_newline)
4300 {
4301 struct text_pos tpos;
4302 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4303
4304 SET_TEXT_POS (tpos, newpos, bpos);
4305 reseat_1 (it, tpos, 0);
4306 /* If we reseat on a newline/ZV, we need to prep the
4307 bidi iterator for advancing to the next character
4308 after the newline/EOB, keeping the current paragraph
4309 direction (so that PRODUCE_GLYPHS does TRT wrt
4310 prepending/appending glyphs to a glyph row). */
4311 if (on_newline)
4312 {
4313 it->bidi_it.first_elt = 0;
4314 it->bidi_it.paragraph_dir = pdir;
4315 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4316 it->bidi_it.nchars = 1;
4317 it->bidi_it.ch_len = 1;
4318 }
4319 }
4320 else /* Must use the slow method. */
4321 {
4322 /* With bidi iteration, the region of invisible text
4323 could start and/or end in the middle of a
4324 non-base embedding level. Therefore, we need to
4325 skip invisible text using the bidi iterator,
4326 starting at IT's current position, until we find
4327 ourselves outside of the invisible text.
4328 Skipping invisible text _after_ bidi iteration
4329 avoids affecting the visual order of the
4330 displayed text when invisible properties are
4331 added or removed. */
4332 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4333 {
4334 /* If we were `reseat'ed to a new paragraph,
4335 determine the paragraph base direction. We
4336 need to do it now because
4337 next_element_from_buffer may not have a
4338 chance to do it, if we are going to skip any
4339 text at the beginning, which resets the
4340 FIRST_ELT flag. */
4341 bidi_paragraph_init (it->paragraph_embedding,
4342 &it->bidi_it, 1);
4343 }
4344 do
4345 {
4346 bidi_move_to_visually_next (&it->bidi_it);
4347 }
4348 while (it->stop_charpos <= it->bidi_it.charpos
4349 && it->bidi_it.charpos < newpos);
4350 IT_CHARPOS (*it) = it->bidi_it.charpos;
4351 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4352 /* If we overstepped NEWPOS, record its position in
4353 the iterator, so that we skip invisible text if
4354 later the bidi iteration lands us in the
4355 invisible region again. */
4356 if (IT_CHARPOS (*it) >= newpos)
4357 it->prev_stop = newpos;
4358 }
4359 }
4360 else
4361 {
4362 IT_CHARPOS (*it) = newpos;
4363 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4364 }
4365
4366 /* If there are before-strings at the start of invisible
4367 text, and the text is invisible because of a text
4368 property, arrange to show before-strings because 20.x did
4369 it that way. (If the text is invisible because of an
4370 overlay property instead of a text property, this is
4371 already handled in the overlay code.) */
4372 if (NILP (overlay)
4373 && get_overlay_strings (it, it->stop_charpos))
4374 {
4375 handled = HANDLED_RECOMPUTE_PROPS;
4376 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4377 }
4378 else if (display_ellipsis_p)
4379 {
4380 /* Make sure that the glyphs of the ellipsis will get
4381 correct `charpos' values. If we would not update
4382 it->position here, the glyphs would belong to the
4383 last visible character _before_ the invisible
4384 text, which confuses `set_cursor_from_row'.
4385
4386 We use the last invisible position instead of the
4387 first because this way the cursor is always drawn on
4388 the first "." of the ellipsis, whenever PT is inside
4389 the invisible text. Otherwise the cursor would be
4390 placed _after_ the ellipsis when the point is after the
4391 first invisible character. */
4392 if (!STRINGP (it->object))
4393 {
4394 it->position.charpos = newpos - 1;
4395 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4396 }
4397 it->ellipsis_p = 1;
4398 /* Let the ellipsis display before
4399 considering any properties of the following char.
4400 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4401 handled = HANDLED_RETURN;
4402 }
4403 }
4404 }
4405
4406 return handled;
4407 }
4408
4409
4410 /* Make iterator IT return `...' next.
4411 Replaces LEN characters from buffer. */
4412
4413 static void
4414 setup_for_ellipsis (struct it *it, int len)
4415 {
4416 /* Use the display table definition for `...'. Invalid glyphs
4417 will be handled by the method returning elements from dpvec. */
4418 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4419 {
4420 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4421 it->dpvec = v->contents;
4422 it->dpend = v->contents + v->header.size;
4423 }
4424 else
4425 {
4426 /* Default `...'. */
4427 it->dpvec = default_invis_vector;
4428 it->dpend = default_invis_vector + 3;
4429 }
4430
4431 it->dpvec_char_len = len;
4432 it->current.dpvec_index = 0;
4433 it->dpvec_face_id = -1;
4434
4435 /* Remember the current face id in case glyphs specify faces.
4436 IT's face is restored in set_iterator_to_next.
4437 saved_face_id was set to preceding char's face in handle_stop. */
4438 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4439 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4440
4441 it->method = GET_FROM_DISPLAY_VECTOR;
4442 it->ellipsis_p = 1;
4443 }
4444
4445
4446 \f
4447 /***********************************************************************
4448 'display' property
4449 ***********************************************************************/
4450
4451 /* Set up iterator IT from `display' property at its current position.
4452 Called from handle_stop.
4453 We return HANDLED_RETURN if some part of the display property
4454 overrides the display of the buffer text itself.
4455 Otherwise we return HANDLED_NORMALLY. */
4456
4457 static enum prop_handled
4458 handle_display_prop (struct it *it)
4459 {
4460 Lisp_Object propval, object, overlay;
4461 struct text_pos *position;
4462 ptrdiff_t bufpos;
4463 /* Nonzero if some property replaces the display of the text itself. */
4464 int display_replaced_p = 0;
4465
4466 if (STRINGP (it->string))
4467 {
4468 object = it->string;
4469 position = &it->current.string_pos;
4470 bufpos = CHARPOS (it->current.pos);
4471 }
4472 else
4473 {
4474 XSETWINDOW (object, it->w);
4475 position = &it->current.pos;
4476 bufpos = CHARPOS (*position);
4477 }
4478
4479 /* Reset those iterator values set from display property values. */
4480 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4481 it->space_width = Qnil;
4482 it->font_height = Qnil;
4483 it->voffset = 0;
4484
4485 /* We don't support recursive `display' properties, i.e. string
4486 values that have a string `display' property, that have a string
4487 `display' property etc. */
4488 if (!it->string_from_display_prop_p)
4489 it->area = TEXT_AREA;
4490
4491 propval = get_char_property_and_overlay (make_number (position->charpos),
4492 Qdisplay, object, &overlay);
4493 if (NILP (propval))
4494 return HANDLED_NORMALLY;
4495 /* Now OVERLAY is the overlay that gave us this property, or nil
4496 if it was a text property. */
4497
4498 if (!STRINGP (it->string))
4499 object = it->w->buffer;
4500
4501 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4502 position, bufpos,
4503 FRAME_WINDOW_P (it->f));
4504
4505 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4506 }
4507
4508 /* Subroutine of handle_display_prop. Returns non-zero if the display
4509 specification in SPEC is a replacing specification, i.e. it would
4510 replace the text covered by `display' property with something else,
4511 such as an image or a display string. If SPEC includes any kind or
4512 `(space ...) specification, the value is 2; this is used by
4513 compute_display_string_pos, which see.
4514
4515 See handle_single_display_spec for documentation of arguments.
4516 frame_window_p is non-zero if the window being redisplayed is on a
4517 GUI frame; this argument is used only if IT is NULL, see below.
4518
4519 IT can be NULL, if this is called by the bidi reordering code
4520 through compute_display_string_pos, which see. In that case, this
4521 function only examines SPEC, but does not otherwise "handle" it, in
4522 the sense that it doesn't set up members of IT from the display
4523 spec. */
4524 static int
4525 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4526 Lisp_Object overlay, struct text_pos *position,
4527 ptrdiff_t bufpos, int frame_window_p)
4528 {
4529 int replacing_p = 0;
4530 int rv;
4531
4532 if (CONSP (spec)
4533 /* Simple specifications. */
4534 && !EQ (XCAR (spec), Qimage)
4535 && !EQ (XCAR (spec), Qspace)
4536 && !EQ (XCAR (spec), Qwhen)
4537 && !EQ (XCAR (spec), Qslice)
4538 && !EQ (XCAR (spec), Qspace_width)
4539 && !EQ (XCAR (spec), Qheight)
4540 && !EQ (XCAR (spec), Qraise)
4541 /* Marginal area specifications. */
4542 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4543 && !EQ (XCAR (spec), Qleft_fringe)
4544 && !EQ (XCAR (spec), Qright_fringe)
4545 && !NILP (XCAR (spec)))
4546 {
4547 for (; CONSP (spec); spec = XCDR (spec))
4548 {
4549 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4550 overlay, position, bufpos,
4551 replacing_p, frame_window_p)))
4552 {
4553 replacing_p = rv;
4554 /* If some text in a string is replaced, `position' no
4555 longer points to the position of `object'. */
4556 if (!it || STRINGP (object))
4557 break;
4558 }
4559 }
4560 }
4561 else if (VECTORP (spec))
4562 {
4563 ptrdiff_t i;
4564 for (i = 0; i < ASIZE (spec); ++i)
4565 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4566 overlay, position, bufpos,
4567 replacing_p, frame_window_p)))
4568 {
4569 replacing_p = rv;
4570 /* If some text in a string is replaced, `position' no
4571 longer points to the position of `object'. */
4572 if (!it || STRINGP (object))
4573 break;
4574 }
4575 }
4576 else
4577 {
4578 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4579 position, bufpos, 0,
4580 frame_window_p)))
4581 replacing_p = rv;
4582 }
4583
4584 return replacing_p;
4585 }
4586
4587 /* Value is the position of the end of the `display' property starting
4588 at START_POS in OBJECT. */
4589
4590 static struct text_pos
4591 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4592 {
4593 Lisp_Object end;
4594 struct text_pos end_pos;
4595
4596 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4597 Qdisplay, object, Qnil);
4598 CHARPOS (end_pos) = XFASTINT (end);
4599 if (STRINGP (object))
4600 compute_string_pos (&end_pos, start_pos, it->string);
4601 else
4602 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4603
4604 return end_pos;
4605 }
4606
4607
4608 /* Set up IT from a single `display' property specification SPEC. OBJECT
4609 is the object in which the `display' property was found. *POSITION
4610 is the position in OBJECT at which the `display' property was found.
4611 BUFPOS is the buffer position of OBJECT (different from POSITION if
4612 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4613 previously saw a display specification which already replaced text
4614 display with something else, for example an image; we ignore such
4615 properties after the first one has been processed.
4616
4617 OVERLAY is the overlay this `display' property came from,
4618 or nil if it was a text property.
4619
4620 If SPEC is a `space' or `image' specification, and in some other
4621 cases too, set *POSITION to the position where the `display'
4622 property ends.
4623
4624 If IT is NULL, only examine the property specification in SPEC, but
4625 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4626 is intended to be displayed in a window on a GUI frame.
4627
4628 Value is non-zero if something was found which replaces the display
4629 of buffer or string text. */
4630
4631 static int
4632 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4633 Lisp_Object overlay, struct text_pos *position,
4634 ptrdiff_t bufpos, int display_replaced_p,
4635 int frame_window_p)
4636 {
4637 Lisp_Object form;
4638 Lisp_Object location, value;
4639 struct text_pos start_pos = *position;
4640 int valid_p;
4641
4642 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4643 If the result is non-nil, use VALUE instead of SPEC. */
4644 form = Qt;
4645 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4646 {
4647 spec = XCDR (spec);
4648 if (!CONSP (spec))
4649 return 0;
4650 form = XCAR (spec);
4651 spec = XCDR (spec);
4652 }
4653
4654 if (!NILP (form) && !EQ (form, Qt))
4655 {
4656 ptrdiff_t count = SPECPDL_INDEX ();
4657 struct gcpro gcpro1;
4658
4659 /* Bind `object' to the object having the `display' property, a
4660 buffer or string. Bind `position' to the position in the
4661 object where the property was found, and `buffer-position'
4662 to the current position in the buffer. */
4663
4664 if (NILP (object))
4665 XSETBUFFER (object, current_buffer);
4666 specbind (Qobject, object);
4667 specbind (Qposition, make_number (CHARPOS (*position)));
4668 specbind (Qbuffer_position, make_number (bufpos));
4669 GCPRO1 (form);
4670 form = safe_eval (form);
4671 UNGCPRO;
4672 unbind_to (count, Qnil);
4673 }
4674
4675 if (NILP (form))
4676 return 0;
4677
4678 /* Handle `(height HEIGHT)' specifications. */
4679 if (CONSP (spec)
4680 && EQ (XCAR (spec), Qheight)
4681 && CONSP (XCDR (spec)))
4682 {
4683 if (it)
4684 {
4685 if (!FRAME_WINDOW_P (it->f))
4686 return 0;
4687
4688 it->font_height = XCAR (XCDR (spec));
4689 if (!NILP (it->font_height))
4690 {
4691 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4692 int new_height = -1;
4693
4694 if (CONSP (it->font_height)
4695 && (EQ (XCAR (it->font_height), Qplus)
4696 || EQ (XCAR (it->font_height), Qminus))
4697 && CONSP (XCDR (it->font_height))
4698 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4699 {
4700 /* `(+ N)' or `(- N)' where N is an integer. */
4701 int steps = XINT (XCAR (XCDR (it->font_height)));
4702 if (EQ (XCAR (it->font_height), Qplus))
4703 steps = - steps;
4704 it->face_id = smaller_face (it->f, it->face_id, steps);
4705 }
4706 else if (FUNCTIONP (it->font_height))
4707 {
4708 /* Call function with current height as argument.
4709 Value is the new height. */
4710 Lisp_Object height;
4711 height = safe_call1 (it->font_height,
4712 face->lface[LFACE_HEIGHT_INDEX]);
4713 if (NUMBERP (height))
4714 new_height = XFLOATINT (height);
4715 }
4716 else if (NUMBERP (it->font_height))
4717 {
4718 /* Value is a multiple of the canonical char height. */
4719 struct face *f;
4720
4721 f = FACE_FROM_ID (it->f,
4722 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4723 new_height = (XFLOATINT (it->font_height)
4724 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4725 }
4726 else
4727 {
4728 /* Evaluate IT->font_height with `height' bound to the
4729 current specified height to get the new height. */
4730 ptrdiff_t count = SPECPDL_INDEX ();
4731
4732 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4733 value = safe_eval (it->font_height);
4734 unbind_to (count, Qnil);
4735
4736 if (NUMBERP (value))
4737 new_height = XFLOATINT (value);
4738 }
4739
4740 if (new_height > 0)
4741 it->face_id = face_with_height (it->f, it->face_id, new_height);
4742 }
4743 }
4744
4745 return 0;
4746 }
4747
4748 /* Handle `(space-width WIDTH)'. */
4749 if (CONSP (spec)
4750 && EQ (XCAR (spec), Qspace_width)
4751 && CONSP (XCDR (spec)))
4752 {
4753 if (it)
4754 {
4755 if (!FRAME_WINDOW_P (it->f))
4756 return 0;
4757
4758 value = XCAR (XCDR (spec));
4759 if (NUMBERP (value) && XFLOATINT (value) > 0)
4760 it->space_width = value;
4761 }
4762
4763 return 0;
4764 }
4765
4766 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4767 if (CONSP (spec)
4768 && EQ (XCAR (spec), Qslice))
4769 {
4770 Lisp_Object tem;
4771
4772 if (it)
4773 {
4774 if (!FRAME_WINDOW_P (it->f))
4775 return 0;
4776
4777 if (tem = XCDR (spec), CONSP (tem))
4778 {
4779 it->slice.x = XCAR (tem);
4780 if (tem = XCDR (tem), CONSP (tem))
4781 {
4782 it->slice.y = XCAR (tem);
4783 if (tem = XCDR (tem), CONSP (tem))
4784 {
4785 it->slice.width = XCAR (tem);
4786 if (tem = XCDR (tem), CONSP (tem))
4787 it->slice.height = XCAR (tem);
4788 }
4789 }
4790 }
4791 }
4792
4793 return 0;
4794 }
4795
4796 /* Handle `(raise FACTOR)'. */
4797 if (CONSP (spec)
4798 && EQ (XCAR (spec), Qraise)
4799 && CONSP (XCDR (spec)))
4800 {
4801 if (it)
4802 {
4803 if (!FRAME_WINDOW_P (it->f))
4804 return 0;
4805
4806 #ifdef HAVE_WINDOW_SYSTEM
4807 value = XCAR (XCDR (spec));
4808 if (NUMBERP (value))
4809 {
4810 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4811 it->voffset = - (XFLOATINT (value)
4812 * (FONT_HEIGHT (face->font)));
4813 }
4814 #endif /* HAVE_WINDOW_SYSTEM */
4815 }
4816
4817 return 0;
4818 }
4819
4820 /* Don't handle the other kinds of display specifications
4821 inside a string that we got from a `display' property. */
4822 if (it && it->string_from_display_prop_p)
4823 return 0;
4824
4825 /* Characters having this form of property are not displayed, so
4826 we have to find the end of the property. */
4827 if (it)
4828 {
4829 start_pos = *position;
4830 *position = display_prop_end (it, object, start_pos);
4831 }
4832 value = Qnil;
4833
4834 /* Stop the scan at that end position--we assume that all
4835 text properties change there. */
4836 if (it)
4837 it->stop_charpos = position->charpos;
4838
4839 /* Handle `(left-fringe BITMAP [FACE])'
4840 and `(right-fringe BITMAP [FACE])'. */
4841 if (CONSP (spec)
4842 && (EQ (XCAR (spec), Qleft_fringe)
4843 || EQ (XCAR (spec), Qright_fringe))
4844 && CONSP (XCDR (spec)))
4845 {
4846 int fringe_bitmap;
4847
4848 if (it)
4849 {
4850 if (!FRAME_WINDOW_P (it->f))
4851 /* If we return here, POSITION has been advanced
4852 across the text with this property. */
4853 {
4854 /* Synchronize the bidi iterator with POSITION. This is
4855 needed because we are not going to push the iterator
4856 on behalf of this display property, so there will be
4857 no pop_it call to do this synchronization for us. */
4858 if (it->bidi_p)
4859 {
4860 it->position = *position;
4861 iterate_out_of_display_property (it);
4862 *position = it->position;
4863 }
4864 return 1;
4865 }
4866 }
4867 else if (!frame_window_p)
4868 return 1;
4869
4870 #ifdef HAVE_WINDOW_SYSTEM
4871 value = XCAR (XCDR (spec));
4872 if (!SYMBOLP (value)
4873 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4874 /* If we return here, POSITION has been advanced
4875 across the text with this property. */
4876 {
4877 if (it && it->bidi_p)
4878 {
4879 it->position = *position;
4880 iterate_out_of_display_property (it);
4881 *position = it->position;
4882 }
4883 return 1;
4884 }
4885
4886 if (it)
4887 {
4888 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4889
4890 if (CONSP (XCDR (XCDR (spec))))
4891 {
4892 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4893 int face_id2 = lookup_derived_face (it->f, face_name,
4894 FRINGE_FACE_ID, 0);
4895 if (face_id2 >= 0)
4896 face_id = face_id2;
4897 }
4898
4899 /* Save current settings of IT so that we can restore them
4900 when we are finished with the glyph property value. */
4901 push_it (it, position);
4902
4903 it->area = TEXT_AREA;
4904 it->what = IT_IMAGE;
4905 it->image_id = -1; /* no image */
4906 it->position = start_pos;
4907 it->object = NILP (object) ? it->w->buffer : object;
4908 it->method = GET_FROM_IMAGE;
4909 it->from_overlay = Qnil;
4910 it->face_id = face_id;
4911 it->from_disp_prop_p = 1;
4912
4913 /* Say that we haven't consumed the characters with
4914 `display' property yet. The call to pop_it in
4915 set_iterator_to_next will clean this up. */
4916 *position = start_pos;
4917
4918 if (EQ (XCAR (spec), Qleft_fringe))
4919 {
4920 it->left_user_fringe_bitmap = fringe_bitmap;
4921 it->left_user_fringe_face_id = face_id;
4922 }
4923 else
4924 {
4925 it->right_user_fringe_bitmap = fringe_bitmap;
4926 it->right_user_fringe_face_id = face_id;
4927 }
4928 }
4929 #endif /* HAVE_WINDOW_SYSTEM */
4930 return 1;
4931 }
4932
4933 /* Prepare to handle `((margin left-margin) ...)',
4934 `((margin right-margin) ...)' and `((margin nil) ...)'
4935 prefixes for display specifications. */
4936 location = Qunbound;
4937 if (CONSP (spec) && CONSP (XCAR (spec)))
4938 {
4939 Lisp_Object tem;
4940
4941 value = XCDR (spec);
4942 if (CONSP (value))
4943 value = XCAR (value);
4944
4945 tem = XCAR (spec);
4946 if (EQ (XCAR (tem), Qmargin)
4947 && (tem = XCDR (tem),
4948 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4949 (NILP (tem)
4950 || EQ (tem, Qleft_margin)
4951 || EQ (tem, Qright_margin))))
4952 location = tem;
4953 }
4954
4955 if (EQ (location, Qunbound))
4956 {
4957 location = Qnil;
4958 value = spec;
4959 }
4960
4961 /* After this point, VALUE is the property after any
4962 margin prefix has been stripped. It must be a string,
4963 an image specification, or `(space ...)'.
4964
4965 LOCATION specifies where to display: `left-margin',
4966 `right-margin' or nil. */
4967
4968 valid_p = (STRINGP (value)
4969 #ifdef HAVE_WINDOW_SYSTEM
4970 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4971 && valid_image_p (value))
4972 #endif /* not HAVE_WINDOW_SYSTEM */
4973 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4974
4975 if (valid_p && !display_replaced_p)
4976 {
4977 int retval = 1;
4978
4979 if (!it)
4980 {
4981 /* Callers need to know whether the display spec is any kind
4982 of `(space ...)' spec that is about to affect text-area
4983 display. */
4984 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
4985 retval = 2;
4986 return retval;
4987 }
4988
4989 /* Save current settings of IT so that we can restore them
4990 when we are finished with the glyph property value. */
4991 push_it (it, position);
4992 it->from_overlay = overlay;
4993 it->from_disp_prop_p = 1;
4994
4995 if (NILP (location))
4996 it->area = TEXT_AREA;
4997 else if (EQ (location, Qleft_margin))
4998 it->area = LEFT_MARGIN_AREA;
4999 else
5000 it->area = RIGHT_MARGIN_AREA;
5001
5002 if (STRINGP (value))
5003 {
5004 it->string = value;
5005 it->multibyte_p = STRING_MULTIBYTE (it->string);
5006 it->current.overlay_string_index = -1;
5007 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5008 it->end_charpos = it->string_nchars = SCHARS (it->string);
5009 it->method = GET_FROM_STRING;
5010 it->stop_charpos = 0;
5011 it->prev_stop = 0;
5012 it->base_level_stop = 0;
5013 it->string_from_display_prop_p = 1;
5014 /* Say that we haven't consumed the characters with
5015 `display' property yet. The call to pop_it in
5016 set_iterator_to_next will clean this up. */
5017 if (BUFFERP (object))
5018 *position = start_pos;
5019
5020 /* Force paragraph direction to be that of the parent
5021 object. If the parent object's paragraph direction is
5022 not yet determined, default to L2R. */
5023 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5024 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5025 else
5026 it->paragraph_embedding = L2R;
5027
5028 /* Set up the bidi iterator for this display string. */
5029 if (it->bidi_p)
5030 {
5031 it->bidi_it.string.lstring = it->string;
5032 it->bidi_it.string.s = NULL;
5033 it->bidi_it.string.schars = it->end_charpos;
5034 it->bidi_it.string.bufpos = bufpos;
5035 it->bidi_it.string.from_disp_str = 1;
5036 it->bidi_it.string.unibyte = !it->multibyte_p;
5037 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5038 }
5039 }
5040 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5041 {
5042 it->method = GET_FROM_STRETCH;
5043 it->object = value;
5044 *position = it->position = start_pos;
5045 retval = 1 + (it->area == TEXT_AREA);
5046 }
5047 #ifdef HAVE_WINDOW_SYSTEM
5048 else
5049 {
5050 it->what = IT_IMAGE;
5051 it->image_id = lookup_image (it->f, value);
5052 it->position = start_pos;
5053 it->object = NILP (object) ? it->w->buffer : object;
5054 it->method = GET_FROM_IMAGE;
5055
5056 /* Say that we haven't consumed the characters with
5057 `display' property yet. The call to pop_it in
5058 set_iterator_to_next will clean this up. */
5059 *position = start_pos;
5060 }
5061 #endif /* HAVE_WINDOW_SYSTEM */
5062
5063 return retval;
5064 }
5065
5066 /* Invalid property or property not supported. Restore
5067 POSITION to what it was before. */
5068 *position = start_pos;
5069 return 0;
5070 }
5071
5072 /* Check if PROP is a display property value whose text should be
5073 treated as intangible. OVERLAY is the overlay from which PROP
5074 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5075 specify the buffer position covered by PROP. */
5076
5077 int
5078 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5079 ptrdiff_t charpos, ptrdiff_t bytepos)
5080 {
5081 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5082 struct text_pos position;
5083
5084 SET_TEXT_POS (position, charpos, bytepos);
5085 return handle_display_spec (NULL, prop, Qnil, overlay,
5086 &position, charpos, frame_window_p);
5087 }
5088
5089
5090 /* Return 1 if PROP is a display sub-property value containing STRING.
5091
5092 Implementation note: this and the following function are really
5093 special cases of handle_display_spec and
5094 handle_single_display_spec, and should ideally use the same code.
5095 Until they do, these two pairs must be consistent and must be
5096 modified in sync. */
5097
5098 static int
5099 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5100 {
5101 if (EQ (string, prop))
5102 return 1;
5103
5104 /* Skip over `when FORM'. */
5105 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5106 {
5107 prop = XCDR (prop);
5108 if (!CONSP (prop))
5109 return 0;
5110 /* Actually, the condition following `when' should be eval'ed,
5111 like handle_single_display_spec does, and we should return
5112 zero if it evaluates to nil. However, this function is
5113 called only when the buffer was already displayed and some
5114 glyph in the glyph matrix was found to come from a display
5115 string. Therefore, the condition was already evaluated, and
5116 the result was non-nil, otherwise the display string wouldn't
5117 have been displayed and we would have never been called for
5118 this property. Thus, we can skip the evaluation and assume
5119 its result is non-nil. */
5120 prop = XCDR (prop);
5121 }
5122
5123 if (CONSP (prop))
5124 /* Skip over `margin LOCATION'. */
5125 if (EQ (XCAR (prop), Qmargin))
5126 {
5127 prop = XCDR (prop);
5128 if (!CONSP (prop))
5129 return 0;
5130
5131 prop = XCDR (prop);
5132 if (!CONSP (prop))
5133 return 0;
5134 }
5135
5136 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5137 }
5138
5139
5140 /* Return 1 if STRING appears in the `display' property PROP. */
5141
5142 static int
5143 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5144 {
5145 if (CONSP (prop)
5146 && !EQ (XCAR (prop), Qwhen)
5147 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5148 {
5149 /* A list of sub-properties. */
5150 while (CONSP (prop))
5151 {
5152 if (single_display_spec_string_p (XCAR (prop), string))
5153 return 1;
5154 prop = XCDR (prop);
5155 }
5156 }
5157 else if (VECTORP (prop))
5158 {
5159 /* A vector of sub-properties. */
5160 ptrdiff_t i;
5161 for (i = 0; i < ASIZE (prop); ++i)
5162 if (single_display_spec_string_p (AREF (prop, i), string))
5163 return 1;
5164 }
5165 else
5166 return single_display_spec_string_p (prop, string);
5167
5168 return 0;
5169 }
5170
5171 /* Look for STRING in overlays and text properties in the current
5172 buffer, between character positions FROM and TO (excluding TO).
5173 BACK_P non-zero means look back (in this case, TO is supposed to be
5174 less than FROM).
5175 Value is the first character position where STRING was found, or
5176 zero if it wasn't found before hitting TO.
5177
5178 This function may only use code that doesn't eval because it is
5179 called asynchronously from note_mouse_highlight. */
5180
5181 static ptrdiff_t
5182 string_buffer_position_lim (Lisp_Object string,
5183 ptrdiff_t from, ptrdiff_t to, int back_p)
5184 {
5185 Lisp_Object limit, prop, pos;
5186 int found = 0;
5187
5188 pos = make_number (max (from, BEGV));
5189
5190 if (!back_p) /* looking forward */
5191 {
5192 limit = make_number (min (to, ZV));
5193 while (!found && !EQ (pos, limit))
5194 {
5195 prop = Fget_char_property (pos, Qdisplay, Qnil);
5196 if (!NILP (prop) && display_prop_string_p (prop, string))
5197 found = 1;
5198 else
5199 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5200 limit);
5201 }
5202 }
5203 else /* looking back */
5204 {
5205 limit = make_number (max (to, BEGV));
5206 while (!found && !EQ (pos, limit))
5207 {
5208 prop = Fget_char_property (pos, Qdisplay, Qnil);
5209 if (!NILP (prop) && display_prop_string_p (prop, string))
5210 found = 1;
5211 else
5212 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5213 limit);
5214 }
5215 }
5216
5217 return found ? XINT (pos) : 0;
5218 }
5219
5220 /* Determine which buffer position in current buffer STRING comes from.
5221 AROUND_CHARPOS is an approximate position where it could come from.
5222 Value is the buffer position or 0 if it couldn't be determined.
5223
5224 This function is necessary because we don't record buffer positions
5225 in glyphs generated from strings (to keep struct glyph small).
5226 This function may only use code that doesn't eval because it is
5227 called asynchronously from note_mouse_highlight. */
5228
5229 static ptrdiff_t
5230 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5231 {
5232 const int MAX_DISTANCE = 1000;
5233 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5234 around_charpos + MAX_DISTANCE,
5235 0);
5236
5237 if (!found)
5238 found = string_buffer_position_lim (string, around_charpos,
5239 around_charpos - MAX_DISTANCE, 1);
5240 return found;
5241 }
5242
5243
5244 \f
5245 /***********************************************************************
5246 `composition' property
5247 ***********************************************************************/
5248
5249 /* Set up iterator IT from `composition' property at its current
5250 position. Called from handle_stop. */
5251
5252 static enum prop_handled
5253 handle_composition_prop (struct it *it)
5254 {
5255 Lisp_Object prop, string;
5256 ptrdiff_t pos, pos_byte, start, end;
5257
5258 if (STRINGP (it->string))
5259 {
5260 unsigned char *s;
5261
5262 pos = IT_STRING_CHARPOS (*it);
5263 pos_byte = IT_STRING_BYTEPOS (*it);
5264 string = it->string;
5265 s = SDATA (string) + pos_byte;
5266 it->c = STRING_CHAR (s);
5267 }
5268 else
5269 {
5270 pos = IT_CHARPOS (*it);
5271 pos_byte = IT_BYTEPOS (*it);
5272 string = Qnil;
5273 it->c = FETCH_CHAR (pos_byte);
5274 }
5275
5276 /* If there's a valid composition and point is not inside of the
5277 composition (in the case that the composition is from the current
5278 buffer), draw a glyph composed from the composition components. */
5279 if (find_composition (pos, -1, &start, &end, &prop, string)
5280 && COMPOSITION_VALID_P (start, end, prop)
5281 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5282 {
5283 if (start < pos)
5284 /* As we can't handle this situation (perhaps font-lock added
5285 a new composition), we just return here hoping that next
5286 redisplay will detect this composition much earlier. */
5287 return HANDLED_NORMALLY;
5288 if (start != pos)
5289 {
5290 if (STRINGP (it->string))
5291 pos_byte = string_char_to_byte (it->string, start);
5292 else
5293 pos_byte = CHAR_TO_BYTE (start);
5294 }
5295 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5296 prop, string);
5297
5298 if (it->cmp_it.id >= 0)
5299 {
5300 it->cmp_it.ch = -1;
5301 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5302 it->cmp_it.nglyphs = -1;
5303 }
5304 }
5305
5306 return HANDLED_NORMALLY;
5307 }
5308
5309
5310 \f
5311 /***********************************************************************
5312 Overlay strings
5313 ***********************************************************************/
5314
5315 /* The following structure is used to record overlay strings for
5316 later sorting in load_overlay_strings. */
5317
5318 struct overlay_entry
5319 {
5320 Lisp_Object overlay;
5321 Lisp_Object string;
5322 EMACS_INT priority;
5323 int after_string_p;
5324 };
5325
5326
5327 /* Set up iterator IT from overlay strings at its current position.
5328 Called from handle_stop. */
5329
5330 static enum prop_handled
5331 handle_overlay_change (struct it *it)
5332 {
5333 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5334 return HANDLED_RECOMPUTE_PROPS;
5335 else
5336 return HANDLED_NORMALLY;
5337 }
5338
5339
5340 /* Set up the next overlay string for delivery by IT, if there is an
5341 overlay string to deliver. Called by set_iterator_to_next when the
5342 end of the current overlay string is reached. If there are more
5343 overlay strings to display, IT->string and
5344 IT->current.overlay_string_index are set appropriately here.
5345 Otherwise IT->string is set to nil. */
5346
5347 static void
5348 next_overlay_string (struct it *it)
5349 {
5350 ++it->current.overlay_string_index;
5351 if (it->current.overlay_string_index == it->n_overlay_strings)
5352 {
5353 /* No more overlay strings. Restore IT's settings to what
5354 they were before overlay strings were processed, and
5355 continue to deliver from current_buffer. */
5356
5357 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5358 pop_it (it);
5359 eassert (it->sp > 0
5360 || (NILP (it->string)
5361 && it->method == GET_FROM_BUFFER
5362 && it->stop_charpos >= BEGV
5363 && it->stop_charpos <= it->end_charpos));
5364 it->current.overlay_string_index = -1;
5365 it->n_overlay_strings = 0;
5366 it->overlay_strings_charpos = -1;
5367 /* If there's an empty display string on the stack, pop the
5368 stack, to resync the bidi iterator with IT's position. Such
5369 empty strings are pushed onto the stack in
5370 get_overlay_strings_1. */
5371 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5372 pop_it (it);
5373
5374 /* If we're at the end of the buffer, record that we have
5375 processed the overlay strings there already, so that
5376 next_element_from_buffer doesn't try it again. */
5377 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5378 it->overlay_strings_at_end_processed_p = 1;
5379 }
5380 else
5381 {
5382 /* There are more overlay strings to process. If
5383 IT->current.overlay_string_index has advanced to a position
5384 where we must load IT->overlay_strings with more strings, do
5385 it. We must load at the IT->overlay_strings_charpos where
5386 IT->n_overlay_strings was originally computed; when invisible
5387 text is present, this might not be IT_CHARPOS (Bug#7016). */
5388 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5389
5390 if (it->current.overlay_string_index && i == 0)
5391 load_overlay_strings (it, it->overlay_strings_charpos);
5392
5393 /* Initialize IT to deliver display elements from the overlay
5394 string. */
5395 it->string = it->overlay_strings[i];
5396 it->multibyte_p = STRING_MULTIBYTE (it->string);
5397 SET_TEXT_POS (it->current.string_pos, 0, 0);
5398 it->method = GET_FROM_STRING;
5399 it->stop_charpos = 0;
5400 it->end_charpos = SCHARS (it->string);
5401 if (it->cmp_it.stop_pos >= 0)
5402 it->cmp_it.stop_pos = 0;
5403 it->prev_stop = 0;
5404 it->base_level_stop = 0;
5405
5406 /* Set up the bidi iterator for this overlay string. */
5407 if (it->bidi_p)
5408 {
5409 it->bidi_it.string.lstring = it->string;
5410 it->bidi_it.string.s = NULL;
5411 it->bidi_it.string.schars = SCHARS (it->string);
5412 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5413 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5414 it->bidi_it.string.unibyte = !it->multibyte_p;
5415 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5416 }
5417 }
5418
5419 CHECK_IT (it);
5420 }
5421
5422
5423 /* Compare two overlay_entry structures E1 and E2. Used as a
5424 comparison function for qsort in load_overlay_strings. Overlay
5425 strings for the same position are sorted so that
5426
5427 1. All after-strings come in front of before-strings, except
5428 when they come from the same overlay.
5429
5430 2. Within after-strings, strings are sorted so that overlay strings
5431 from overlays with higher priorities come first.
5432
5433 2. Within before-strings, strings are sorted so that overlay
5434 strings from overlays with higher priorities come last.
5435
5436 Value is analogous to strcmp. */
5437
5438
5439 static int
5440 compare_overlay_entries (const void *e1, const void *e2)
5441 {
5442 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
5443 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
5444 int result;
5445
5446 if (entry1->after_string_p != entry2->after_string_p)
5447 {
5448 /* Let after-strings appear in front of before-strings if
5449 they come from different overlays. */
5450 if (EQ (entry1->overlay, entry2->overlay))
5451 result = entry1->after_string_p ? 1 : -1;
5452 else
5453 result = entry1->after_string_p ? -1 : 1;
5454 }
5455 else if (entry1->priority != entry2->priority)
5456 {
5457 if (entry1->after_string_p)
5458 /* After-strings sorted in order of decreasing priority. */
5459 result = entry2->priority < entry1->priority ? -1 : 1;
5460 else
5461 /* Before-strings sorted in order of increasing priority. */
5462 result = entry1->priority < entry2->priority ? -1 : 1;
5463 }
5464 else
5465 result = 0;
5466
5467 return result;
5468 }
5469
5470
5471 /* Load the vector IT->overlay_strings with overlay strings from IT's
5472 current buffer position, or from CHARPOS if that is > 0. Set
5473 IT->n_overlays to the total number of overlay strings found.
5474
5475 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5476 a time. On entry into load_overlay_strings,
5477 IT->current.overlay_string_index gives the number of overlay
5478 strings that have already been loaded by previous calls to this
5479 function.
5480
5481 IT->add_overlay_start contains an additional overlay start
5482 position to consider for taking overlay strings from, if non-zero.
5483 This position comes into play when the overlay has an `invisible'
5484 property, and both before and after-strings. When we've skipped to
5485 the end of the overlay, because of its `invisible' property, we
5486 nevertheless want its before-string to appear.
5487 IT->add_overlay_start will contain the overlay start position
5488 in this case.
5489
5490 Overlay strings are sorted so that after-string strings come in
5491 front of before-string strings. Within before and after-strings,
5492 strings are sorted by overlay priority. See also function
5493 compare_overlay_entries. */
5494
5495 static void
5496 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5497 {
5498 Lisp_Object overlay, window, str, invisible;
5499 struct Lisp_Overlay *ov;
5500 ptrdiff_t start, end;
5501 ptrdiff_t size = 20;
5502 ptrdiff_t n = 0, i, j;
5503 int invis_p;
5504 struct overlay_entry *entries = alloca (size * sizeof *entries);
5505 USE_SAFE_ALLOCA;
5506
5507 if (charpos <= 0)
5508 charpos = IT_CHARPOS (*it);
5509
5510 /* Append the overlay string STRING of overlay OVERLAY to vector
5511 `entries' which has size `size' and currently contains `n'
5512 elements. AFTER_P non-zero means STRING is an after-string of
5513 OVERLAY. */
5514 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5515 do \
5516 { \
5517 Lisp_Object priority; \
5518 \
5519 if (n == size) \
5520 { \
5521 struct overlay_entry *old = entries; \
5522 SAFE_NALLOCA (entries, 2, size); \
5523 memcpy (entries, old, size * sizeof *entries); \
5524 size *= 2; \
5525 } \
5526 \
5527 entries[n].string = (STRING); \
5528 entries[n].overlay = (OVERLAY); \
5529 priority = Foverlay_get ((OVERLAY), Qpriority); \
5530 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5531 entries[n].after_string_p = (AFTER_P); \
5532 ++n; \
5533 } \
5534 while (0)
5535
5536 /* Process overlay before the overlay center. */
5537 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5538 {
5539 XSETMISC (overlay, ov);
5540 eassert (OVERLAYP (overlay));
5541 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5542 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5543
5544 if (end < charpos)
5545 break;
5546
5547 /* Skip this overlay if it doesn't start or end at IT's current
5548 position. */
5549 if (end != charpos && start != charpos)
5550 continue;
5551
5552 /* Skip this overlay if it doesn't apply to IT->w. */
5553 window = Foverlay_get (overlay, Qwindow);
5554 if (WINDOWP (window) && XWINDOW (window) != it->w)
5555 continue;
5556
5557 /* If the text ``under'' the overlay is invisible, both before-
5558 and after-strings from this overlay are visible; start and
5559 end position are indistinguishable. */
5560 invisible = Foverlay_get (overlay, Qinvisible);
5561 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5562
5563 /* If overlay has a non-empty before-string, record it. */
5564 if ((start == charpos || (end == charpos && invis_p))
5565 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5566 && SCHARS (str))
5567 RECORD_OVERLAY_STRING (overlay, str, 0);
5568
5569 /* If overlay has a non-empty after-string, record it. */
5570 if ((end == charpos || (start == charpos && invis_p))
5571 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5572 && SCHARS (str))
5573 RECORD_OVERLAY_STRING (overlay, str, 1);
5574 }
5575
5576 /* Process overlays after the overlay center. */
5577 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5578 {
5579 XSETMISC (overlay, ov);
5580 eassert (OVERLAYP (overlay));
5581 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5582 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5583
5584 if (start > charpos)
5585 break;
5586
5587 /* Skip this overlay if it doesn't start or end at IT's current
5588 position. */
5589 if (end != charpos && start != charpos)
5590 continue;
5591
5592 /* Skip this overlay if it doesn't apply to IT->w. */
5593 window = Foverlay_get (overlay, Qwindow);
5594 if (WINDOWP (window) && XWINDOW (window) != it->w)
5595 continue;
5596
5597 /* If the text ``under'' the overlay is invisible, it has a zero
5598 dimension, and both before- and after-strings apply. */
5599 invisible = Foverlay_get (overlay, Qinvisible);
5600 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5601
5602 /* If overlay has a non-empty before-string, record it. */
5603 if ((start == charpos || (end == charpos && invis_p))
5604 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5605 && SCHARS (str))
5606 RECORD_OVERLAY_STRING (overlay, str, 0);
5607
5608 /* If overlay has a non-empty after-string, record it. */
5609 if ((end == charpos || (start == charpos && invis_p))
5610 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5611 && SCHARS (str))
5612 RECORD_OVERLAY_STRING (overlay, str, 1);
5613 }
5614
5615 #undef RECORD_OVERLAY_STRING
5616
5617 /* Sort entries. */
5618 if (n > 1)
5619 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5620
5621 /* Record number of overlay strings, and where we computed it. */
5622 it->n_overlay_strings = n;
5623 it->overlay_strings_charpos = charpos;
5624
5625 /* IT->current.overlay_string_index is the number of overlay strings
5626 that have already been consumed by IT. Copy some of the
5627 remaining overlay strings to IT->overlay_strings. */
5628 i = 0;
5629 j = it->current.overlay_string_index;
5630 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5631 {
5632 it->overlay_strings[i] = entries[j].string;
5633 it->string_overlays[i++] = entries[j++].overlay;
5634 }
5635
5636 CHECK_IT (it);
5637 SAFE_FREE ();
5638 }
5639
5640
5641 /* Get the first chunk of overlay strings at IT's current buffer
5642 position, or at CHARPOS if that is > 0. Value is non-zero if at
5643 least one overlay string was found. */
5644
5645 static int
5646 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5647 {
5648 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5649 process. This fills IT->overlay_strings with strings, and sets
5650 IT->n_overlay_strings to the total number of strings to process.
5651 IT->pos.overlay_string_index has to be set temporarily to zero
5652 because load_overlay_strings needs this; it must be set to -1
5653 when no overlay strings are found because a zero value would
5654 indicate a position in the first overlay string. */
5655 it->current.overlay_string_index = 0;
5656 load_overlay_strings (it, charpos);
5657
5658 /* If we found overlay strings, set up IT to deliver display
5659 elements from the first one. Otherwise set up IT to deliver
5660 from current_buffer. */
5661 if (it->n_overlay_strings)
5662 {
5663 /* Make sure we know settings in current_buffer, so that we can
5664 restore meaningful values when we're done with the overlay
5665 strings. */
5666 if (compute_stop_p)
5667 compute_stop_pos (it);
5668 eassert (it->face_id >= 0);
5669
5670 /* Save IT's settings. They are restored after all overlay
5671 strings have been processed. */
5672 eassert (!compute_stop_p || it->sp == 0);
5673
5674 /* When called from handle_stop, there might be an empty display
5675 string loaded. In that case, don't bother saving it. But
5676 don't use this optimization with the bidi iterator, since we
5677 need the corresponding pop_it call to resync the bidi
5678 iterator's position with IT's position, after we are done
5679 with the overlay strings. (The corresponding call to pop_it
5680 in case of an empty display string is in
5681 next_overlay_string.) */
5682 if (!(!it->bidi_p
5683 && STRINGP (it->string) && !SCHARS (it->string)))
5684 push_it (it, NULL);
5685
5686 /* Set up IT to deliver display elements from the first overlay
5687 string. */
5688 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5689 it->string = it->overlay_strings[0];
5690 it->from_overlay = Qnil;
5691 it->stop_charpos = 0;
5692 eassert (STRINGP (it->string));
5693 it->end_charpos = SCHARS (it->string);
5694 it->prev_stop = 0;
5695 it->base_level_stop = 0;
5696 it->multibyte_p = STRING_MULTIBYTE (it->string);
5697 it->method = GET_FROM_STRING;
5698 it->from_disp_prop_p = 0;
5699
5700 /* Force paragraph direction to be that of the parent
5701 buffer. */
5702 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5703 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5704 else
5705 it->paragraph_embedding = L2R;
5706
5707 /* Set up the bidi iterator for this overlay string. */
5708 if (it->bidi_p)
5709 {
5710 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5711
5712 it->bidi_it.string.lstring = it->string;
5713 it->bidi_it.string.s = NULL;
5714 it->bidi_it.string.schars = SCHARS (it->string);
5715 it->bidi_it.string.bufpos = pos;
5716 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5717 it->bidi_it.string.unibyte = !it->multibyte_p;
5718 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5719 }
5720 return 1;
5721 }
5722
5723 it->current.overlay_string_index = -1;
5724 return 0;
5725 }
5726
5727 static int
5728 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5729 {
5730 it->string = Qnil;
5731 it->method = GET_FROM_BUFFER;
5732
5733 (void) get_overlay_strings_1 (it, charpos, 1);
5734
5735 CHECK_IT (it);
5736
5737 /* Value is non-zero if we found at least one overlay string. */
5738 return STRINGP (it->string);
5739 }
5740
5741
5742 \f
5743 /***********************************************************************
5744 Saving and restoring state
5745 ***********************************************************************/
5746
5747 /* Save current settings of IT on IT->stack. Called, for example,
5748 before setting up IT for an overlay string, to be able to restore
5749 IT's settings to what they were after the overlay string has been
5750 processed. If POSITION is non-NULL, it is the position to save on
5751 the stack instead of IT->position. */
5752
5753 static void
5754 push_it (struct it *it, struct text_pos *position)
5755 {
5756 struct iterator_stack_entry *p;
5757
5758 eassert (it->sp < IT_STACK_SIZE);
5759 p = it->stack + it->sp;
5760
5761 p->stop_charpos = it->stop_charpos;
5762 p->prev_stop = it->prev_stop;
5763 p->base_level_stop = it->base_level_stop;
5764 p->cmp_it = it->cmp_it;
5765 eassert (it->face_id >= 0);
5766 p->face_id = it->face_id;
5767 p->string = it->string;
5768 p->method = it->method;
5769 p->from_overlay = it->from_overlay;
5770 switch (p->method)
5771 {
5772 case GET_FROM_IMAGE:
5773 p->u.image.object = it->object;
5774 p->u.image.image_id = it->image_id;
5775 p->u.image.slice = it->slice;
5776 break;
5777 case GET_FROM_STRETCH:
5778 p->u.stretch.object = it->object;
5779 break;
5780 }
5781 p->position = position ? *position : it->position;
5782 p->current = it->current;
5783 p->end_charpos = it->end_charpos;
5784 p->string_nchars = it->string_nchars;
5785 p->area = it->area;
5786 p->multibyte_p = it->multibyte_p;
5787 p->avoid_cursor_p = it->avoid_cursor_p;
5788 p->space_width = it->space_width;
5789 p->font_height = it->font_height;
5790 p->voffset = it->voffset;
5791 p->string_from_display_prop_p = it->string_from_display_prop_p;
5792 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5793 p->display_ellipsis_p = 0;
5794 p->line_wrap = it->line_wrap;
5795 p->bidi_p = it->bidi_p;
5796 p->paragraph_embedding = it->paragraph_embedding;
5797 p->from_disp_prop_p = it->from_disp_prop_p;
5798 ++it->sp;
5799
5800 /* Save the state of the bidi iterator as well. */
5801 if (it->bidi_p)
5802 bidi_push_it (&it->bidi_it);
5803 }
5804
5805 static void
5806 iterate_out_of_display_property (struct it *it)
5807 {
5808 int buffer_p = !STRINGP (it->string);
5809 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5810 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5811
5812 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5813
5814 /* Maybe initialize paragraph direction. If we are at the beginning
5815 of a new paragraph, next_element_from_buffer may not have a
5816 chance to do that. */
5817 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5818 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5819 /* prev_stop can be zero, so check against BEGV as well. */
5820 while (it->bidi_it.charpos >= bob
5821 && it->prev_stop <= it->bidi_it.charpos
5822 && it->bidi_it.charpos < CHARPOS (it->position)
5823 && it->bidi_it.charpos < eob)
5824 bidi_move_to_visually_next (&it->bidi_it);
5825 /* Record the stop_pos we just crossed, for when we cross it
5826 back, maybe. */
5827 if (it->bidi_it.charpos > CHARPOS (it->position))
5828 it->prev_stop = CHARPOS (it->position);
5829 /* If we ended up not where pop_it put us, resync IT's
5830 positional members with the bidi iterator. */
5831 if (it->bidi_it.charpos != CHARPOS (it->position))
5832 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5833 if (buffer_p)
5834 it->current.pos = it->position;
5835 else
5836 it->current.string_pos = it->position;
5837 }
5838
5839 /* Restore IT's settings from IT->stack. Called, for example, when no
5840 more overlay strings must be processed, and we return to delivering
5841 display elements from a buffer, or when the end of a string from a
5842 `display' property is reached and we return to delivering display
5843 elements from an overlay string, or from a buffer. */
5844
5845 static void
5846 pop_it (struct it *it)
5847 {
5848 struct iterator_stack_entry *p;
5849 int from_display_prop = it->from_disp_prop_p;
5850
5851 eassert (it->sp > 0);
5852 --it->sp;
5853 p = it->stack + it->sp;
5854 it->stop_charpos = p->stop_charpos;
5855 it->prev_stop = p->prev_stop;
5856 it->base_level_stop = p->base_level_stop;
5857 it->cmp_it = p->cmp_it;
5858 it->face_id = p->face_id;
5859 it->current = p->current;
5860 it->position = p->position;
5861 it->string = p->string;
5862 it->from_overlay = p->from_overlay;
5863 if (NILP (it->string))
5864 SET_TEXT_POS (it->current.string_pos, -1, -1);
5865 it->method = p->method;
5866 switch (it->method)
5867 {
5868 case GET_FROM_IMAGE:
5869 it->image_id = p->u.image.image_id;
5870 it->object = p->u.image.object;
5871 it->slice = p->u.image.slice;
5872 break;
5873 case GET_FROM_STRETCH:
5874 it->object = p->u.stretch.object;
5875 break;
5876 case GET_FROM_BUFFER:
5877 it->object = it->w->buffer;
5878 break;
5879 case GET_FROM_STRING:
5880 it->object = it->string;
5881 break;
5882 case GET_FROM_DISPLAY_VECTOR:
5883 if (it->s)
5884 it->method = GET_FROM_C_STRING;
5885 else if (STRINGP (it->string))
5886 it->method = GET_FROM_STRING;
5887 else
5888 {
5889 it->method = GET_FROM_BUFFER;
5890 it->object = it->w->buffer;
5891 }
5892 }
5893 it->end_charpos = p->end_charpos;
5894 it->string_nchars = p->string_nchars;
5895 it->area = p->area;
5896 it->multibyte_p = p->multibyte_p;
5897 it->avoid_cursor_p = p->avoid_cursor_p;
5898 it->space_width = p->space_width;
5899 it->font_height = p->font_height;
5900 it->voffset = p->voffset;
5901 it->string_from_display_prop_p = p->string_from_display_prop_p;
5902 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5903 it->line_wrap = p->line_wrap;
5904 it->bidi_p = p->bidi_p;
5905 it->paragraph_embedding = p->paragraph_embedding;
5906 it->from_disp_prop_p = p->from_disp_prop_p;
5907 if (it->bidi_p)
5908 {
5909 bidi_pop_it (&it->bidi_it);
5910 /* Bidi-iterate until we get out of the portion of text, if any,
5911 covered by a `display' text property or by an overlay with
5912 `display' property. (We cannot just jump there, because the
5913 internal coherency of the bidi iterator state can not be
5914 preserved across such jumps.) We also must determine the
5915 paragraph base direction if the overlay we just processed is
5916 at the beginning of a new paragraph. */
5917 if (from_display_prop
5918 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5919 iterate_out_of_display_property (it);
5920
5921 eassert ((BUFFERP (it->object)
5922 && IT_CHARPOS (*it) == it->bidi_it.charpos
5923 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5924 || (STRINGP (it->object)
5925 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5926 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5927 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5928 }
5929 }
5930
5931
5932 \f
5933 /***********************************************************************
5934 Moving over lines
5935 ***********************************************************************/
5936
5937 /* Set IT's current position to the previous line start. */
5938
5939 static void
5940 back_to_previous_line_start (struct it *it)
5941 {
5942 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5943 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5944 }
5945
5946
5947 /* Move IT to the next line start.
5948
5949 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5950 we skipped over part of the text (as opposed to moving the iterator
5951 continuously over the text). Otherwise, don't change the value
5952 of *SKIPPED_P.
5953
5954 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5955 iterator on the newline, if it was found.
5956
5957 Newlines may come from buffer text, overlay strings, or strings
5958 displayed via the `display' property. That's the reason we can't
5959 simply use find_next_newline_no_quit.
5960
5961 Note that this function may not skip over invisible text that is so
5962 because of text properties and immediately follows a newline. If
5963 it would, function reseat_at_next_visible_line_start, when called
5964 from set_iterator_to_next, would effectively make invisible
5965 characters following a newline part of the wrong glyph row, which
5966 leads to wrong cursor motion. */
5967
5968 static int
5969 forward_to_next_line_start (struct it *it, int *skipped_p,
5970 struct bidi_it *bidi_it_prev)
5971 {
5972 ptrdiff_t old_selective;
5973 int newline_found_p, n;
5974 const int MAX_NEWLINE_DISTANCE = 500;
5975
5976 /* If already on a newline, just consume it to avoid unintended
5977 skipping over invisible text below. */
5978 if (it->what == IT_CHARACTER
5979 && it->c == '\n'
5980 && CHARPOS (it->position) == IT_CHARPOS (*it))
5981 {
5982 if (it->bidi_p && bidi_it_prev)
5983 *bidi_it_prev = it->bidi_it;
5984 set_iterator_to_next (it, 0);
5985 it->c = 0;
5986 return 1;
5987 }
5988
5989 /* Don't handle selective display in the following. It's (a)
5990 unnecessary because it's done by the caller, and (b) leads to an
5991 infinite recursion because next_element_from_ellipsis indirectly
5992 calls this function. */
5993 old_selective = it->selective;
5994 it->selective = 0;
5995
5996 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5997 from buffer text. */
5998 for (n = newline_found_p = 0;
5999 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6000 n += STRINGP (it->string) ? 0 : 1)
6001 {
6002 if (!get_next_display_element (it))
6003 return 0;
6004 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6005 if (newline_found_p && it->bidi_p && bidi_it_prev)
6006 *bidi_it_prev = it->bidi_it;
6007 set_iterator_to_next (it, 0);
6008 }
6009
6010 /* If we didn't find a newline near enough, see if we can use a
6011 short-cut. */
6012 if (!newline_found_p)
6013 {
6014 ptrdiff_t start = IT_CHARPOS (*it);
6015 ptrdiff_t limit = find_next_newline_no_quit (start, 1);
6016 Lisp_Object pos;
6017
6018 eassert (!STRINGP (it->string));
6019
6020 /* If there isn't any `display' property in sight, and no
6021 overlays, we can just use the position of the newline in
6022 buffer text. */
6023 if (it->stop_charpos >= limit
6024 || ((pos = Fnext_single_property_change (make_number (start),
6025 Qdisplay, Qnil,
6026 make_number (limit)),
6027 NILP (pos))
6028 && next_overlay_change (start) == ZV))
6029 {
6030 if (!it->bidi_p)
6031 {
6032 IT_CHARPOS (*it) = limit;
6033 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
6034 }
6035 else
6036 {
6037 struct bidi_it bprev;
6038
6039 /* Help bidi.c avoid expensive searches for display
6040 properties and overlays, by telling it that there are
6041 none up to `limit'. */
6042 if (it->bidi_it.disp_pos < limit)
6043 {
6044 it->bidi_it.disp_pos = limit;
6045 it->bidi_it.disp_prop = 0;
6046 }
6047 do {
6048 bprev = it->bidi_it;
6049 bidi_move_to_visually_next (&it->bidi_it);
6050 } while (it->bidi_it.charpos != limit);
6051 IT_CHARPOS (*it) = limit;
6052 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6053 if (bidi_it_prev)
6054 *bidi_it_prev = bprev;
6055 }
6056 *skipped_p = newline_found_p = 1;
6057 }
6058 else
6059 {
6060 while (get_next_display_element (it)
6061 && !newline_found_p)
6062 {
6063 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6064 if (newline_found_p && it->bidi_p && bidi_it_prev)
6065 *bidi_it_prev = it->bidi_it;
6066 set_iterator_to_next (it, 0);
6067 }
6068 }
6069 }
6070
6071 it->selective = old_selective;
6072 return newline_found_p;
6073 }
6074
6075
6076 /* Set IT's current position to the previous visible line start. Skip
6077 invisible text that is so either due to text properties or due to
6078 selective display. Caution: this does not change IT->current_x and
6079 IT->hpos. */
6080
6081 static void
6082 back_to_previous_visible_line_start (struct it *it)
6083 {
6084 while (IT_CHARPOS (*it) > BEGV)
6085 {
6086 back_to_previous_line_start (it);
6087
6088 if (IT_CHARPOS (*it) <= BEGV)
6089 break;
6090
6091 /* If selective > 0, then lines indented more than its value are
6092 invisible. */
6093 if (it->selective > 0
6094 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6095 it->selective))
6096 continue;
6097
6098 /* Check the newline before point for invisibility. */
6099 {
6100 Lisp_Object prop;
6101 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6102 Qinvisible, it->window);
6103 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6104 continue;
6105 }
6106
6107 if (IT_CHARPOS (*it) <= BEGV)
6108 break;
6109
6110 {
6111 struct it it2;
6112 void *it2data = NULL;
6113 ptrdiff_t pos;
6114 ptrdiff_t beg, end;
6115 Lisp_Object val, overlay;
6116
6117 SAVE_IT (it2, *it, it2data);
6118
6119 /* If newline is part of a composition, continue from start of composition */
6120 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6121 && beg < IT_CHARPOS (*it))
6122 goto replaced;
6123
6124 /* If newline is replaced by a display property, find start of overlay
6125 or interval and continue search from that point. */
6126 pos = --IT_CHARPOS (it2);
6127 --IT_BYTEPOS (it2);
6128 it2.sp = 0;
6129 bidi_unshelve_cache (NULL, 0);
6130 it2.string_from_display_prop_p = 0;
6131 it2.from_disp_prop_p = 0;
6132 if (handle_display_prop (&it2) == HANDLED_RETURN
6133 && !NILP (val = get_char_property_and_overlay
6134 (make_number (pos), Qdisplay, Qnil, &overlay))
6135 && (OVERLAYP (overlay)
6136 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6137 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6138 {
6139 RESTORE_IT (it, it, it2data);
6140 goto replaced;
6141 }
6142
6143 /* Newline is not replaced by anything -- so we are done. */
6144 RESTORE_IT (it, it, it2data);
6145 break;
6146
6147 replaced:
6148 if (beg < BEGV)
6149 beg = BEGV;
6150 IT_CHARPOS (*it) = beg;
6151 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6152 }
6153 }
6154
6155 it->continuation_lines_width = 0;
6156
6157 eassert (IT_CHARPOS (*it) >= BEGV);
6158 eassert (IT_CHARPOS (*it) == BEGV
6159 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6160 CHECK_IT (it);
6161 }
6162
6163
6164 /* Reseat iterator IT at the previous visible line start. Skip
6165 invisible text that is so either due to text properties or due to
6166 selective display. At the end, update IT's overlay information,
6167 face information etc. */
6168
6169 void
6170 reseat_at_previous_visible_line_start (struct it *it)
6171 {
6172 back_to_previous_visible_line_start (it);
6173 reseat (it, it->current.pos, 1);
6174 CHECK_IT (it);
6175 }
6176
6177
6178 /* Reseat iterator IT on the next visible line start in the current
6179 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6180 preceding the line start. Skip over invisible text that is so
6181 because of selective display. Compute faces, overlays etc at the
6182 new position. Note that this function does not skip over text that
6183 is invisible because of text properties. */
6184
6185 static void
6186 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6187 {
6188 int newline_found_p, skipped_p = 0;
6189 struct bidi_it bidi_it_prev;
6190
6191 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6192
6193 /* Skip over lines that are invisible because they are indented
6194 more than the value of IT->selective. */
6195 if (it->selective > 0)
6196 while (IT_CHARPOS (*it) < ZV
6197 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6198 it->selective))
6199 {
6200 eassert (IT_BYTEPOS (*it) == BEGV
6201 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6202 newline_found_p =
6203 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6204 }
6205
6206 /* Position on the newline if that's what's requested. */
6207 if (on_newline_p && newline_found_p)
6208 {
6209 if (STRINGP (it->string))
6210 {
6211 if (IT_STRING_CHARPOS (*it) > 0)
6212 {
6213 if (!it->bidi_p)
6214 {
6215 --IT_STRING_CHARPOS (*it);
6216 --IT_STRING_BYTEPOS (*it);
6217 }
6218 else
6219 {
6220 /* We need to restore the bidi iterator to the state
6221 it had on the newline, and resync the IT's
6222 position with that. */
6223 it->bidi_it = bidi_it_prev;
6224 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6225 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6226 }
6227 }
6228 }
6229 else if (IT_CHARPOS (*it) > BEGV)
6230 {
6231 if (!it->bidi_p)
6232 {
6233 --IT_CHARPOS (*it);
6234 --IT_BYTEPOS (*it);
6235 }
6236 else
6237 {
6238 /* We need to restore the bidi iterator to the state it
6239 had on the newline and resync IT with that. */
6240 it->bidi_it = bidi_it_prev;
6241 IT_CHARPOS (*it) = it->bidi_it.charpos;
6242 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6243 }
6244 reseat (it, it->current.pos, 0);
6245 }
6246 }
6247 else if (skipped_p)
6248 reseat (it, it->current.pos, 0);
6249
6250 CHECK_IT (it);
6251 }
6252
6253
6254 \f
6255 /***********************************************************************
6256 Changing an iterator's position
6257 ***********************************************************************/
6258
6259 /* Change IT's current position to POS in current_buffer. If FORCE_P
6260 is non-zero, always check for text properties at the new position.
6261 Otherwise, text properties are only looked up if POS >=
6262 IT->check_charpos of a property. */
6263
6264 static void
6265 reseat (struct it *it, struct text_pos pos, int force_p)
6266 {
6267 ptrdiff_t original_pos = IT_CHARPOS (*it);
6268
6269 reseat_1 (it, pos, 0);
6270
6271 /* Determine where to check text properties. Avoid doing it
6272 where possible because text property lookup is very expensive. */
6273 if (force_p
6274 || CHARPOS (pos) > it->stop_charpos
6275 || CHARPOS (pos) < original_pos)
6276 {
6277 if (it->bidi_p)
6278 {
6279 /* For bidi iteration, we need to prime prev_stop and
6280 base_level_stop with our best estimations. */
6281 /* Implementation note: Of course, POS is not necessarily a
6282 stop position, so assigning prev_pos to it is a lie; we
6283 should have called compute_stop_backwards. However, if
6284 the current buffer does not include any R2L characters,
6285 that call would be a waste of cycles, because the
6286 iterator will never move back, and thus never cross this
6287 "fake" stop position. So we delay that backward search
6288 until the time we really need it, in next_element_from_buffer. */
6289 if (CHARPOS (pos) != it->prev_stop)
6290 it->prev_stop = CHARPOS (pos);
6291 if (CHARPOS (pos) < it->base_level_stop)
6292 it->base_level_stop = 0; /* meaning it's unknown */
6293 handle_stop (it);
6294 }
6295 else
6296 {
6297 handle_stop (it);
6298 it->prev_stop = it->base_level_stop = 0;
6299 }
6300
6301 }
6302
6303 CHECK_IT (it);
6304 }
6305
6306
6307 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6308 IT->stop_pos to POS, also. */
6309
6310 static void
6311 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6312 {
6313 /* Don't call this function when scanning a C string. */
6314 eassert (it->s == NULL);
6315
6316 /* POS must be a reasonable value. */
6317 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6318
6319 it->current.pos = it->position = pos;
6320 it->end_charpos = ZV;
6321 it->dpvec = NULL;
6322 it->current.dpvec_index = -1;
6323 it->current.overlay_string_index = -1;
6324 IT_STRING_CHARPOS (*it) = -1;
6325 IT_STRING_BYTEPOS (*it) = -1;
6326 it->string = Qnil;
6327 it->method = GET_FROM_BUFFER;
6328 it->object = it->w->buffer;
6329 it->area = TEXT_AREA;
6330 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6331 it->sp = 0;
6332 it->string_from_display_prop_p = 0;
6333 it->string_from_prefix_prop_p = 0;
6334
6335 it->from_disp_prop_p = 0;
6336 it->face_before_selective_p = 0;
6337 if (it->bidi_p)
6338 {
6339 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6340 &it->bidi_it);
6341 bidi_unshelve_cache (NULL, 0);
6342 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6343 it->bidi_it.string.s = NULL;
6344 it->bidi_it.string.lstring = Qnil;
6345 it->bidi_it.string.bufpos = 0;
6346 it->bidi_it.string.unibyte = 0;
6347 }
6348
6349 if (set_stop_p)
6350 {
6351 it->stop_charpos = CHARPOS (pos);
6352 it->base_level_stop = CHARPOS (pos);
6353 }
6354 /* This make the information stored in it->cmp_it invalidate. */
6355 it->cmp_it.id = -1;
6356 }
6357
6358
6359 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6360 If S is non-null, it is a C string to iterate over. Otherwise,
6361 STRING gives a Lisp string to iterate over.
6362
6363 If PRECISION > 0, don't return more then PRECISION number of
6364 characters from the string.
6365
6366 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6367 characters have been returned. FIELD_WIDTH < 0 means an infinite
6368 field width.
6369
6370 MULTIBYTE = 0 means disable processing of multibyte characters,
6371 MULTIBYTE > 0 means enable it,
6372 MULTIBYTE < 0 means use IT->multibyte_p.
6373
6374 IT must be initialized via a prior call to init_iterator before
6375 calling this function. */
6376
6377 static void
6378 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6379 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6380 int multibyte)
6381 {
6382 /* No region in strings. */
6383 it->region_beg_charpos = it->region_end_charpos = -1;
6384
6385 /* No text property checks performed by default, but see below. */
6386 it->stop_charpos = -1;
6387
6388 /* Set iterator position and end position. */
6389 memset (&it->current, 0, sizeof it->current);
6390 it->current.overlay_string_index = -1;
6391 it->current.dpvec_index = -1;
6392 eassert (charpos >= 0);
6393
6394 /* If STRING is specified, use its multibyteness, otherwise use the
6395 setting of MULTIBYTE, if specified. */
6396 if (multibyte >= 0)
6397 it->multibyte_p = multibyte > 0;
6398
6399 /* Bidirectional reordering of strings is controlled by the default
6400 value of bidi-display-reordering. Don't try to reorder while
6401 loading loadup.el, as the necessary character property tables are
6402 not yet available. */
6403 it->bidi_p =
6404 NILP (Vpurify_flag)
6405 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6406
6407 if (s == NULL)
6408 {
6409 eassert (STRINGP (string));
6410 it->string = string;
6411 it->s = NULL;
6412 it->end_charpos = it->string_nchars = SCHARS (string);
6413 it->method = GET_FROM_STRING;
6414 it->current.string_pos = string_pos (charpos, string);
6415
6416 if (it->bidi_p)
6417 {
6418 it->bidi_it.string.lstring = string;
6419 it->bidi_it.string.s = NULL;
6420 it->bidi_it.string.schars = it->end_charpos;
6421 it->bidi_it.string.bufpos = 0;
6422 it->bidi_it.string.from_disp_str = 0;
6423 it->bidi_it.string.unibyte = !it->multibyte_p;
6424 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6425 FRAME_WINDOW_P (it->f), &it->bidi_it);
6426 }
6427 }
6428 else
6429 {
6430 it->s = (const unsigned char *) s;
6431 it->string = Qnil;
6432
6433 /* Note that we use IT->current.pos, not it->current.string_pos,
6434 for displaying C strings. */
6435 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6436 if (it->multibyte_p)
6437 {
6438 it->current.pos = c_string_pos (charpos, s, 1);
6439 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6440 }
6441 else
6442 {
6443 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6444 it->end_charpos = it->string_nchars = strlen (s);
6445 }
6446
6447 if (it->bidi_p)
6448 {
6449 it->bidi_it.string.lstring = Qnil;
6450 it->bidi_it.string.s = (const unsigned char *) s;
6451 it->bidi_it.string.schars = it->end_charpos;
6452 it->bidi_it.string.bufpos = 0;
6453 it->bidi_it.string.from_disp_str = 0;
6454 it->bidi_it.string.unibyte = !it->multibyte_p;
6455 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6456 &it->bidi_it);
6457 }
6458 it->method = GET_FROM_C_STRING;
6459 }
6460
6461 /* PRECISION > 0 means don't return more than PRECISION characters
6462 from the string. */
6463 if (precision > 0 && it->end_charpos - charpos > precision)
6464 {
6465 it->end_charpos = it->string_nchars = charpos + precision;
6466 if (it->bidi_p)
6467 it->bidi_it.string.schars = it->end_charpos;
6468 }
6469
6470 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6471 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6472 FIELD_WIDTH < 0 means infinite field width. This is useful for
6473 padding with `-' at the end of a mode line. */
6474 if (field_width < 0)
6475 field_width = INFINITY;
6476 /* Implementation note: We deliberately don't enlarge
6477 it->bidi_it.string.schars here to fit it->end_charpos, because
6478 the bidi iterator cannot produce characters out of thin air. */
6479 if (field_width > it->end_charpos - charpos)
6480 it->end_charpos = charpos + field_width;
6481
6482 /* Use the standard display table for displaying strings. */
6483 if (DISP_TABLE_P (Vstandard_display_table))
6484 it->dp = XCHAR_TABLE (Vstandard_display_table);
6485
6486 it->stop_charpos = charpos;
6487 it->prev_stop = charpos;
6488 it->base_level_stop = 0;
6489 if (it->bidi_p)
6490 {
6491 it->bidi_it.first_elt = 1;
6492 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6493 it->bidi_it.disp_pos = -1;
6494 }
6495 if (s == NULL && it->multibyte_p)
6496 {
6497 ptrdiff_t endpos = SCHARS (it->string);
6498 if (endpos > it->end_charpos)
6499 endpos = it->end_charpos;
6500 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6501 it->string);
6502 }
6503 CHECK_IT (it);
6504 }
6505
6506
6507 \f
6508 /***********************************************************************
6509 Iteration
6510 ***********************************************************************/
6511
6512 /* Map enum it_method value to corresponding next_element_from_* function. */
6513
6514 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6515 {
6516 next_element_from_buffer,
6517 next_element_from_display_vector,
6518 next_element_from_string,
6519 next_element_from_c_string,
6520 next_element_from_image,
6521 next_element_from_stretch
6522 };
6523
6524 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6525
6526
6527 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6528 (possibly with the following characters). */
6529
6530 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6531 ((IT)->cmp_it.id >= 0 \
6532 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6533 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6534 END_CHARPOS, (IT)->w, \
6535 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6536 (IT)->string)))
6537
6538
6539 /* Lookup the char-table Vglyphless_char_display for character C (-1
6540 if we want information for no-font case), and return the display
6541 method symbol. By side-effect, update it->what and
6542 it->glyphless_method. This function is called from
6543 get_next_display_element for each character element, and from
6544 x_produce_glyphs when no suitable font was found. */
6545
6546 Lisp_Object
6547 lookup_glyphless_char_display (int c, struct it *it)
6548 {
6549 Lisp_Object glyphless_method = Qnil;
6550
6551 if (CHAR_TABLE_P (Vglyphless_char_display)
6552 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6553 {
6554 if (c >= 0)
6555 {
6556 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6557 if (CONSP (glyphless_method))
6558 glyphless_method = FRAME_WINDOW_P (it->f)
6559 ? XCAR (glyphless_method)
6560 : XCDR (glyphless_method);
6561 }
6562 else
6563 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6564 }
6565
6566 retry:
6567 if (NILP (glyphless_method))
6568 {
6569 if (c >= 0)
6570 /* The default is to display the character by a proper font. */
6571 return Qnil;
6572 /* The default for the no-font case is to display an empty box. */
6573 glyphless_method = Qempty_box;
6574 }
6575 if (EQ (glyphless_method, Qzero_width))
6576 {
6577 if (c >= 0)
6578 return glyphless_method;
6579 /* This method can't be used for the no-font case. */
6580 glyphless_method = Qempty_box;
6581 }
6582 if (EQ (glyphless_method, Qthin_space))
6583 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6584 else if (EQ (glyphless_method, Qempty_box))
6585 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6586 else if (EQ (glyphless_method, Qhex_code))
6587 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6588 else if (STRINGP (glyphless_method))
6589 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6590 else
6591 {
6592 /* Invalid value. We use the default method. */
6593 glyphless_method = Qnil;
6594 goto retry;
6595 }
6596 it->what = IT_GLYPHLESS;
6597 return glyphless_method;
6598 }
6599
6600 /* Load IT's display element fields with information about the next
6601 display element from the current position of IT. Value is zero if
6602 end of buffer (or C string) is reached. */
6603
6604 static struct frame *last_escape_glyph_frame = NULL;
6605 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6606 static int last_escape_glyph_merged_face_id = 0;
6607
6608 struct frame *last_glyphless_glyph_frame = NULL;
6609 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6610 int last_glyphless_glyph_merged_face_id = 0;
6611
6612 static int
6613 get_next_display_element (struct it *it)
6614 {
6615 /* Non-zero means that we found a display element. Zero means that
6616 we hit the end of what we iterate over. Performance note: the
6617 function pointer `method' used here turns out to be faster than
6618 using a sequence of if-statements. */
6619 int success_p;
6620
6621 get_next:
6622 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6623
6624 if (it->what == IT_CHARACTER)
6625 {
6626 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6627 and only if (a) the resolved directionality of that character
6628 is R..." */
6629 /* FIXME: Do we need an exception for characters from display
6630 tables? */
6631 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6632 it->c = bidi_mirror_char (it->c);
6633 /* Map via display table or translate control characters.
6634 IT->c, IT->len etc. have been set to the next character by
6635 the function call above. If we have a display table, and it
6636 contains an entry for IT->c, translate it. Don't do this if
6637 IT->c itself comes from a display table, otherwise we could
6638 end up in an infinite recursion. (An alternative could be to
6639 count the recursion depth of this function and signal an
6640 error when a certain maximum depth is reached.) Is it worth
6641 it? */
6642 if (success_p && it->dpvec == NULL)
6643 {
6644 Lisp_Object dv;
6645 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6646 int nonascii_space_p = 0;
6647 int nonascii_hyphen_p = 0;
6648 int c = it->c; /* This is the character to display. */
6649
6650 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6651 {
6652 eassert (SINGLE_BYTE_CHAR_P (c));
6653 if (unibyte_display_via_language_environment)
6654 {
6655 c = DECODE_CHAR (unibyte, c);
6656 if (c < 0)
6657 c = BYTE8_TO_CHAR (it->c);
6658 }
6659 else
6660 c = BYTE8_TO_CHAR (it->c);
6661 }
6662
6663 if (it->dp
6664 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6665 VECTORP (dv)))
6666 {
6667 struct Lisp_Vector *v = XVECTOR (dv);
6668
6669 /* Return the first character from the display table
6670 entry, if not empty. If empty, don't display the
6671 current character. */
6672 if (v->header.size)
6673 {
6674 it->dpvec_char_len = it->len;
6675 it->dpvec = v->contents;
6676 it->dpend = v->contents + v->header.size;
6677 it->current.dpvec_index = 0;
6678 it->dpvec_face_id = -1;
6679 it->saved_face_id = it->face_id;
6680 it->method = GET_FROM_DISPLAY_VECTOR;
6681 it->ellipsis_p = 0;
6682 }
6683 else
6684 {
6685 set_iterator_to_next (it, 0);
6686 }
6687 goto get_next;
6688 }
6689
6690 if (! NILP (lookup_glyphless_char_display (c, it)))
6691 {
6692 if (it->what == IT_GLYPHLESS)
6693 goto done;
6694 /* Don't display this character. */
6695 set_iterator_to_next (it, 0);
6696 goto get_next;
6697 }
6698
6699 /* If `nobreak-char-display' is non-nil, we display
6700 non-ASCII spaces and hyphens specially. */
6701 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6702 {
6703 if (c == 0xA0)
6704 nonascii_space_p = 1;
6705 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6706 nonascii_hyphen_p = 1;
6707 }
6708
6709 /* Translate control characters into `\003' or `^C' form.
6710 Control characters coming from a display table entry are
6711 currently not translated because we use IT->dpvec to hold
6712 the translation. This could easily be changed but I
6713 don't believe that it is worth doing.
6714
6715 The characters handled by `nobreak-char-display' must be
6716 translated too.
6717
6718 Non-printable characters and raw-byte characters are also
6719 translated to octal form. */
6720 if (((c < ' ' || c == 127) /* ASCII control chars */
6721 ? (it->area != TEXT_AREA
6722 /* In mode line, treat \n, \t like other crl chars. */
6723 || (c != '\t'
6724 && it->glyph_row
6725 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6726 || (c != '\n' && c != '\t'))
6727 : (nonascii_space_p
6728 || nonascii_hyphen_p
6729 || CHAR_BYTE8_P (c)
6730 || ! CHAR_PRINTABLE_P (c))))
6731 {
6732 /* C is a control character, non-ASCII space/hyphen,
6733 raw-byte, or a non-printable character which must be
6734 displayed either as '\003' or as `^C' where the '\\'
6735 and '^' can be defined in the display table. Fill
6736 IT->ctl_chars with glyphs for what we have to
6737 display. Then, set IT->dpvec to these glyphs. */
6738 Lisp_Object gc;
6739 int ctl_len;
6740 int face_id;
6741 int lface_id = 0;
6742 int escape_glyph;
6743
6744 /* Handle control characters with ^. */
6745
6746 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6747 {
6748 int g;
6749
6750 g = '^'; /* default glyph for Control */
6751 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6752 if (it->dp
6753 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6754 {
6755 g = GLYPH_CODE_CHAR (gc);
6756 lface_id = GLYPH_CODE_FACE (gc);
6757 }
6758 if (lface_id)
6759 {
6760 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6761 }
6762 else if (it->f == last_escape_glyph_frame
6763 && it->face_id == last_escape_glyph_face_id)
6764 {
6765 face_id = last_escape_glyph_merged_face_id;
6766 }
6767 else
6768 {
6769 /* Merge the escape-glyph face into the current face. */
6770 face_id = merge_faces (it->f, Qescape_glyph, 0,
6771 it->face_id);
6772 last_escape_glyph_frame = it->f;
6773 last_escape_glyph_face_id = it->face_id;
6774 last_escape_glyph_merged_face_id = face_id;
6775 }
6776
6777 XSETINT (it->ctl_chars[0], g);
6778 XSETINT (it->ctl_chars[1], c ^ 0100);
6779 ctl_len = 2;
6780 goto display_control;
6781 }
6782
6783 /* Handle non-ascii space in the mode where it only gets
6784 highlighting. */
6785
6786 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6787 {
6788 /* Merge `nobreak-space' into the current face. */
6789 face_id = merge_faces (it->f, Qnobreak_space, 0,
6790 it->face_id);
6791 XSETINT (it->ctl_chars[0], ' ');
6792 ctl_len = 1;
6793 goto display_control;
6794 }
6795
6796 /* Handle sequences that start with the "escape glyph". */
6797
6798 /* the default escape glyph is \. */
6799 escape_glyph = '\\';
6800
6801 if (it->dp
6802 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6803 {
6804 escape_glyph = GLYPH_CODE_CHAR (gc);
6805 lface_id = GLYPH_CODE_FACE (gc);
6806 }
6807 if (lface_id)
6808 {
6809 /* The display table specified a face.
6810 Merge it into face_id and also into escape_glyph. */
6811 face_id = merge_faces (it->f, Qt, lface_id,
6812 it->face_id);
6813 }
6814 else if (it->f == last_escape_glyph_frame
6815 && it->face_id == last_escape_glyph_face_id)
6816 {
6817 face_id = last_escape_glyph_merged_face_id;
6818 }
6819 else
6820 {
6821 /* Merge the escape-glyph face into the current face. */
6822 face_id = merge_faces (it->f, Qescape_glyph, 0,
6823 it->face_id);
6824 last_escape_glyph_frame = it->f;
6825 last_escape_glyph_face_id = it->face_id;
6826 last_escape_glyph_merged_face_id = face_id;
6827 }
6828
6829 /* Draw non-ASCII hyphen with just highlighting: */
6830
6831 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6832 {
6833 XSETINT (it->ctl_chars[0], '-');
6834 ctl_len = 1;
6835 goto display_control;
6836 }
6837
6838 /* Draw non-ASCII space/hyphen with escape glyph: */
6839
6840 if (nonascii_space_p || nonascii_hyphen_p)
6841 {
6842 XSETINT (it->ctl_chars[0], escape_glyph);
6843 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6844 ctl_len = 2;
6845 goto display_control;
6846 }
6847
6848 {
6849 char str[10];
6850 int len, i;
6851
6852 if (CHAR_BYTE8_P (c))
6853 /* Display \200 instead of \17777600. */
6854 c = CHAR_TO_BYTE8 (c);
6855 len = sprintf (str, "%03o", c);
6856
6857 XSETINT (it->ctl_chars[0], escape_glyph);
6858 for (i = 0; i < len; i++)
6859 XSETINT (it->ctl_chars[i + 1], str[i]);
6860 ctl_len = len + 1;
6861 }
6862
6863 display_control:
6864 /* Set up IT->dpvec and return first character from it. */
6865 it->dpvec_char_len = it->len;
6866 it->dpvec = it->ctl_chars;
6867 it->dpend = it->dpvec + ctl_len;
6868 it->current.dpvec_index = 0;
6869 it->dpvec_face_id = face_id;
6870 it->saved_face_id = it->face_id;
6871 it->method = GET_FROM_DISPLAY_VECTOR;
6872 it->ellipsis_p = 0;
6873 goto get_next;
6874 }
6875 it->char_to_display = c;
6876 }
6877 else if (success_p)
6878 {
6879 it->char_to_display = it->c;
6880 }
6881 }
6882
6883 /* Adjust face id for a multibyte character. There are no multibyte
6884 character in unibyte text. */
6885 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6886 && it->multibyte_p
6887 && success_p
6888 && FRAME_WINDOW_P (it->f))
6889 {
6890 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6891
6892 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6893 {
6894 /* Automatic composition with glyph-string. */
6895 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6896
6897 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6898 }
6899 else
6900 {
6901 ptrdiff_t pos = (it->s ? -1
6902 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6903 : IT_CHARPOS (*it));
6904 int c;
6905
6906 if (it->what == IT_CHARACTER)
6907 c = it->char_to_display;
6908 else
6909 {
6910 struct composition *cmp = composition_table[it->cmp_it.id];
6911 int i;
6912
6913 c = ' ';
6914 for (i = 0; i < cmp->glyph_len; i++)
6915 /* TAB in a composition means display glyphs with
6916 padding space on the left or right. */
6917 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6918 break;
6919 }
6920 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6921 }
6922 }
6923
6924 done:
6925 /* Is this character the last one of a run of characters with
6926 box? If yes, set IT->end_of_box_run_p to 1. */
6927 if (it->face_box_p
6928 && it->s == NULL)
6929 {
6930 if (it->method == GET_FROM_STRING && it->sp)
6931 {
6932 int face_id = underlying_face_id (it);
6933 struct face *face = FACE_FROM_ID (it->f, face_id);
6934
6935 if (face)
6936 {
6937 if (face->box == FACE_NO_BOX)
6938 {
6939 /* If the box comes from face properties in a
6940 display string, check faces in that string. */
6941 int string_face_id = face_after_it_pos (it);
6942 it->end_of_box_run_p
6943 = (FACE_FROM_ID (it->f, string_face_id)->box
6944 == FACE_NO_BOX);
6945 }
6946 /* Otherwise, the box comes from the underlying face.
6947 If this is the last string character displayed, check
6948 the next buffer location. */
6949 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6950 && (it->current.overlay_string_index
6951 == it->n_overlay_strings - 1))
6952 {
6953 ptrdiff_t ignore;
6954 int next_face_id;
6955 struct text_pos pos = it->current.pos;
6956 INC_TEXT_POS (pos, it->multibyte_p);
6957
6958 next_face_id = face_at_buffer_position
6959 (it->w, CHARPOS (pos), it->region_beg_charpos,
6960 it->region_end_charpos, &ignore,
6961 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6962 -1);
6963 it->end_of_box_run_p
6964 = (FACE_FROM_ID (it->f, next_face_id)->box
6965 == FACE_NO_BOX);
6966 }
6967 }
6968 }
6969 else
6970 {
6971 int face_id = face_after_it_pos (it);
6972 it->end_of_box_run_p
6973 = (face_id != it->face_id
6974 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6975 }
6976 }
6977 /* If we reached the end of the object we've been iterating (e.g., a
6978 display string or an overlay string), and there's something on
6979 IT->stack, proceed with what's on the stack. It doesn't make
6980 sense to return zero if there's unprocessed stuff on the stack,
6981 because otherwise that stuff will never be displayed. */
6982 if (!success_p && it->sp > 0)
6983 {
6984 set_iterator_to_next (it, 0);
6985 success_p = get_next_display_element (it);
6986 }
6987
6988 /* Value is 0 if end of buffer or string reached. */
6989 return success_p;
6990 }
6991
6992
6993 /* Move IT to the next display element.
6994
6995 RESEAT_P non-zero means if called on a newline in buffer text,
6996 skip to the next visible line start.
6997
6998 Functions get_next_display_element and set_iterator_to_next are
6999 separate because I find this arrangement easier to handle than a
7000 get_next_display_element function that also increments IT's
7001 position. The way it is we can first look at an iterator's current
7002 display element, decide whether it fits on a line, and if it does,
7003 increment the iterator position. The other way around we probably
7004 would either need a flag indicating whether the iterator has to be
7005 incremented the next time, or we would have to implement a
7006 decrement position function which would not be easy to write. */
7007
7008 void
7009 set_iterator_to_next (struct it *it, int reseat_p)
7010 {
7011 /* Reset flags indicating start and end of a sequence of characters
7012 with box. Reset them at the start of this function because
7013 moving the iterator to a new position might set them. */
7014 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7015
7016 switch (it->method)
7017 {
7018 case GET_FROM_BUFFER:
7019 /* The current display element of IT is a character from
7020 current_buffer. Advance in the buffer, and maybe skip over
7021 invisible lines that are so because of selective display. */
7022 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7023 reseat_at_next_visible_line_start (it, 0);
7024 else if (it->cmp_it.id >= 0)
7025 {
7026 /* We are currently getting glyphs from a composition. */
7027 int i;
7028
7029 if (! it->bidi_p)
7030 {
7031 IT_CHARPOS (*it) += it->cmp_it.nchars;
7032 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7033 if (it->cmp_it.to < it->cmp_it.nglyphs)
7034 {
7035 it->cmp_it.from = it->cmp_it.to;
7036 }
7037 else
7038 {
7039 it->cmp_it.id = -1;
7040 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7041 IT_BYTEPOS (*it),
7042 it->end_charpos, Qnil);
7043 }
7044 }
7045 else if (! it->cmp_it.reversed_p)
7046 {
7047 /* Composition created while scanning forward. */
7048 /* Update IT's char/byte positions to point to the first
7049 character of the next grapheme cluster, or to the
7050 character visually after the current composition. */
7051 for (i = 0; i < it->cmp_it.nchars; i++)
7052 bidi_move_to_visually_next (&it->bidi_it);
7053 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7054 IT_CHARPOS (*it) = it->bidi_it.charpos;
7055
7056 if (it->cmp_it.to < it->cmp_it.nglyphs)
7057 {
7058 /* Proceed to the next grapheme cluster. */
7059 it->cmp_it.from = it->cmp_it.to;
7060 }
7061 else
7062 {
7063 /* No more grapheme clusters in this composition.
7064 Find the next stop position. */
7065 ptrdiff_t stop = it->end_charpos;
7066 if (it->bidi_it.scan_dir < 0)
7067 /* Now we are scanning backward and don't know
7068 where to stop. */
7069 stop = -1;
7070 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7071 IT_BYTEPOS (*it), stop, Qnil);
7072 }
7073 }
7074 else
7075 {
7076 /* Composition created while scanning backward. */
7077 /* Update IT's char/byte positions to point to the last
7078 character of the previous grapheme cluster, or the
7079 character visually after the current composition. */
7080 for (i = 0; i < it->cmp_it.nchars; i++)
7081 bidi_move_to_visually_next (&it->bidi_it);
7082 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7083 IT_CHARPOS (*it) = it->bidi_it.charpos;
7084 if (it->cmp_it.from > 0)
7085 {
7086 /* Proceed to the previous grapheme cluster. */
7087 it->cmp_it.to = it->cmp_it.from;
7088 }
7089 else
7090 {
7091 /* No more grapheme clusters in this composition.
7092 Find the next stop position. */
7093 ptrdiff_t stop = it->end_charpos;
7094 if (it->bidi_it.scan_dir < 0)
7095 /* Now we are scanning backward and don't know
7096 where to stop. */
7097 stop = -1;
7098 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7099 IT_BYTEPOS (*it), stop, Qnil);
7100 }
7101 }
7102 }
7103 else
7104 {
7105 eassert (it->len != 0);
7106
7107 if (!it->bidi_p)
7108 {
7109 IT_BYTEPOS (*it) += it->len;
7110 IT_CHARPOS (*it) += 1;
7111 }
7112 else
7113 {
7114 int prev_scan_dir = it->bidi_it.scan_dir;
7115 /* If this is a new paragraph, determine its base
7116 direction (a.k.a. its base embedding level). */
7117 if (it->bidi_it.new_paragraph)
7118 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7119 bidi_move_to_visually_next (&it->bidi_it);
7120 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7121 IT_CHARPOS (*it) = it->bidi_it.charpos;
7122 if (prev_scan_dir != it->bidi_it.scan_dir)
7123 {
7124 /* As the scan direction was changed, we must
7125 re-compute the stop position for composition. */
7126 ptrdiff_t stop = it->end_charpos;
7127 if (it->bidi_it.scan_dir < 0)
7128 stop = -1;
7129 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7130 IT_BYTEPOS (*it), stop, Qnil);
7131 }
7132 }
7133 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7134 }
7135 break;
7136
7137 case GET_FROM_C_STRING:
7138 /* Current display element of IT is from a C string. */
7139 if (!it->bidi_p
7140 /* If the string position is beyond string's end, it means
7141 next_element_from_c_string is padding the string with
7142 blanks, in which case we bypass the bidi iterator,
7143 because it cannot deal with such virtual characters. */
7144 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7145 {
7146 IT_BYTEPOS (*it) += it->len;
7147 IT_CHARPOS (*it) += 1;
7148 }
7149 else
7150 {
7151 bidi_move_to_visually_next (&it->bidi_it);
7152 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7153 IT_CHARPOS (*it) = it->bidi_it.charpos;
7154 }
7155 break;
7156
7157 case GET_FROM_DISPLAY_VECTOR:
7158 /* Current display element of IT is from a display table entry.
7159 Advance in the display table definition. Reset it to null if
7160 end reached, and continue with characters from buffers/
7161 strings. */
7162 ++it->current.dpvec_index;
7163
7164 /* Restore face of the iterator to what they were before the
7165 display vector entry (these entries may contain faces). */
7166 it->face_id = it->saved_face_id;
7167
7168 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7169 {
7170 int recheck_faces = it->ellipsis_p;
7171
7172 if (it->s)
7173 it->method = GET_FROM_C_STRING;
7174 else if (STRINGP (it->string))
7175 it->method = GET_FROM_STRING;
7176 else
7177 {
7178 it->method = GET_FROM_BUFFER;
7179 it->object = it->w->buffer;
7180 }
7181
7182 it->dpvec = NULL;
7183 it->current.dpvec_index = -1;
7184
7185 /* Skip over characters which were displayed via IT->dpvec. */
7186 if (it->dpvec_char_len < 0)
7187 reseat_at_next_visible_line_start (it, 1);
7188 else if (it->dpvec_char_len > 0)
7189 {
7190 if (it->method == GET_FROM_STRING
7191 && it->n_overlay_strings > 0)
7192 it->ignore_overlay_strings_at_pos_p = 1;
7193 it->len = it->dpvec_char_len;
7194 set_iterator_to_next (it, reseat_p);
7195 }
7196
7197 /* Maybe recheck faces after display vector */
7198 if (recheck_faces)
7199 it->stop_charpos = IT_CHARPOS (*it);
7200 }
7201 break;
7202
7203 case GET_FROM_STRING:
7204 /* Current display element is a character from a Lisp string. */
7205 eassert (it->s == NULL && STRINGP (it->string));
7206 /* Don't advance past string end. These conditions are true
7207 when set_iterator_to_next is called at the end of
7208 get_next_display_element, in which case the Lisp string is
7209 already exhausted, and all we want is pop the iterator
7210 stack. */
7211 if (it->current.overlay_string_index >= 0)
7212 {
7213 /* This is an overlay string, so there's no padding with
7214 spaces, and the number of characters in the string is
7215 where the string ends. */
7216 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7217 goto consider_string_end;
7218 }
7219 else
7220 {
7221 /* Not an overlay string. There could be padding, so test
7222 against it->end_charpos . */
7223 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7224 goto consider_string_end;
7225 }
7226 if (it->cmp_it.id >= 0)
7227 {
7228 int i;
7229
7230 if (! it->bidi_p)
7231 {
7232 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7233 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7234 if (it->cmp_it.to < it->cmp_it.nglyphs)
7235 it->cmp_it.from = it->cmp_it.to;
7236 else
7237 {
7238 it->cmp_it.id = -1;
7239 composition_compute_stop_pos (&it->cmp_it,
7240 IT_STRING_CHARPOS (*it),
7241 IT_STRING_BYTEPOS (*it),
7242 it->end_charpos, it->string);
7243 }
7244 }
7245 else if (! it->cmp_it.reversed_p)
7246 {
7247 for (i = 0; i < it->cmp_it.nchars; i++)
7248 bidi_move_to_visually_next (&it->bidi_it);
7249 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7250 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7251
7252 if (it->cmp_it.to < it->cmp_it.nglyphs)
7253 it->cmp_it.from = it->cmp_it.to;
7254 else
7255 {
7256 ptrdiff_t stop = it->end_charpos;
7257 if (it->bidi_it.scan_dir < 0)
7258 stop = -1;
7259 composition_compute_stop_pos (&it->cmp_it,
7260 IT_STRING_CHARPOS (*it),
7261 IT_STRING_BYTEPOS (*it), stop,
7262 it->string);
7263 }
7264 }
7265 else
7266 {
7267 for (i = 0; i < it->cmp_it.nchars; i++)
7268 bidi_move_to_visually_next (&it->bidi_it);
7269 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7270 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7271 if (it->cmp_it.from > 0)
7272 it->cmp_it.to = it->cmp_it.from;
7273 else
7274 {
7275 ptrdiff_t stop = it->end_charpos;
7276 if (it->bidi_it.scan_dir < 0)
7277 stop = -1;
7278 composition_compute_stop_pos (&it->cmp_it,
7279 IT_STRING_CHARPOS (*it),
7280 IT_STRING_BYTEPOS (*it), stop,
7281 it->string);
7282 }
7283 }
7284 }
7285 else
7286 {
7287 if (!it->bidi_p
7288 /* If the string position is beyond string's end, it
7289 means next_element_from_string is padding the string
7290 with blanks, in which case we bypass the bidi
7291 iterator, because it cannot deal with such virtual
7292 characters. */
7293 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7294 {
7295 IT_STRING_BYTEPOS (*it) += it->len;
7296 IT_STRING_CHARPOS (*it) += 1;
7297 }
7298 else
7299 {
7300 int prev_scan_dir = it->bidi_it.scan_dir;
7301
7302 bidi_move_to_visually_next (&it->bidi_it);
7303 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7304 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7305 if (prev_scan_dir != it->bidi_it.scan_dir)
7306 {
7307 ptrdiff_t stop = it->end_charpos;
7308
7309 if (it->bidi_it.scan_dir < 0)
7310 stop = -1;
7311 composition_compute_stop_pos (&it->cmp_it,
7312 IT_STRING_CHARPOS (*it),
7313 IT_STRING_BYTEPOS (*it), stop,
7314 it->string);
7315 }
7316 }
7317 }
7318
7319 consider_string_end:
7320
7321 if (it->current.overlay_string_index >= 0)
7322 {
7323 /* IT->string is an overlay string. Advance to the
7324 next, if there is one. */
7325 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7326 {
7327 it->ellipsis_p = 0;
7328 next_overlay_string (it);
7329 if (it->ellipsis_p)
7330 setup_for_ellipsis (it, 0);
7331 }
7332 }
7333 else
7334 {
7335 /* IT->string is not an overlay string. If we reached
7336 its end, and there is something on IT->stack, proceed
7337 with what is on the stack. This can be either another
7338 string, this time an overlay string, or a buffer. */
7339 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7340 && it->sp > 0)
7341 {
7342 pop_it (it);
7343 if (it->method == GET_FROM_STRING)
7344 goto consider_string_end;
7345 }
7346 }
7347 break;
7348
7349 case GET_FROM_IMAGE:
7350 case GET_FROM_STRETCH:
7351 /* The position etc with which we have to proceed are on
7352 the stack. The position may be at the end of a string,
7353 if the `display' property takes up the whole string. */
7354 eassert (it->sp > 0);
7355 pop_it (it);
7356 if (it->method == GET_FROM_STRING)
7357 goto consider_string_end;
7358 break;
7359
7360 default:
7361 /* There are no other methods defined, so this should be a bug. */
7362 emacs_abort ();
7363 }
7364
7365 eassert (it->method != GET_FROM_STRING
7366 || (STRINGP (it->string)
7367 && IT_STRING_CHARPOS (*it) >= 0));
7368 }
7369
7370 /* Load IT's display element fields with information about the next
7371 display element which comes from a display table entry or from the
7372 result of translating a control character to one of the forms `^C'
7373 or `\003'.
7374
7375 IT->dpvec holds the glyphs to return as characters.
7376 IT->saved_face_id holds the face id before the display vector--it
7377 is restored into IT->face_id in set_iterator_to_next. */
7378
7379 static int
7380 next_element_from_display_vector (struct it *it)
7381 {
7382 Lisp_Object gc;
7383
7384 /* Precondition. */
7385 eassert (it->dpvec && it->current.dpvec_index >= 0);
7386
7387 it->face_id = it->saved_face_id;
7388
7389 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7390 That seemed totally bogus - so I changed it... */
7391 gc = it->dpvec[it->current.dpvec_index];
7392
7393 if (GLYPH_CODE_P (gc))
7394 {
7395 it->c = GLYPH_CODE_CHAR (gc);
7396 it->len = CHAR_BYTES (it->c);
7397
7398 /* The entry may contain a face id to use. Such a face id is
7399 the id of a Lisp face, not a realized face. A face id of
7400 zero means no face is specified. */
7401 if (it->dpvec_face_id >= 0)
7402 it->face_id = it->dpvec_face_id;
7403 else
7404 {
7405 int lface_id = GLYPH_CODE_FACE (gc);
7406 if (lface_id > 0)
7407 it->face_id = merge_faces (it->f, Qt, lface_id,
7408 it->saved_face_id);
7409 }
7410 }
7411 else
7412 /* Display table entry is invalid. Return a space. */
7413 it->c = ' ', it->len = 1;
7414
7415 /* Don't change position and object of the iterator here. They are
7416 still the values of the character that had this display table
7417 entry or was translated, and that's what we want. */
7418 it->what = IT_CHARACTER;
7419 return 1;
7420 }
7421
7422 /* Get the first element of string/buffer in the visual order, after
7423 being reseated to a new position in a string or a buffer. */
7424 static void
7425 get_visually_first_element (struct it *it)
7426 {
7427 int string_p = STRINGP (it->string) || it->s;
7428 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7429 ptrdiff_t bob = (string_p ? 0 : BEGV);
7430
7431 if (STRINGP (it->string))
7432 {
7433 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7434 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7435 }
7436 else
7437 {
7438 it->bidi_it.charpos = IT_CHARPOS (*it);
7439 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7440 }
7441
7442 if (it->bidi_it.charpos == eob)
7443 {
7444 /* Nothing to do, but reset the FIRST_ELT flag, like
7445 bidi_paragraph_init does, because we are not going to
7446 call it. */
7447 it->bidi_it.first_elt = 0;
7448 }
7449 else if (it->bidi_it.charpos == bob
7450 || (!string_p
7451 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7452 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7453 {
7454 /* If we are at the beginning of a line/string, we can produce
7455 the next element right away. */
7456 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7457 bidi_move_to_visually_next (&it->bidi_it);
7458 }
7459 else
7460 {
7461 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7462
7463 /* We need to prime the bidi iterator starting at the line's or
7464 string's beginning, before we will be able to produce the
7465 next element. */
7466 if (string_p)
7467 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7468 else
7469 {
7470 it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it),
7471 -1);
7472 it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos);
7473 }
7474 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7475 do
7476 {
7477 /* Now return to buffer/string position where we were asked
7478 to get the next display element, and produce that. */
7479 bidi_move_to_visually_next (&it->bidi_it);
7480 }
7481 while (it->bidi_it.bytepos != orig_bytepos
7482 && it->bidi_it.charpos < eob);
7483 }
7484
7485 /* Adjust IT's position information to where we ended up. */
7486 if (STRINGP (it->string))
7487 {
7488 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7489 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7490 }
7491 else
7492 {
7493 IT_CHARPOS (*it) = it->bidi_it.charpos;
7494 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7495 }
7496
7497 if (STRINGP (it->string) || !it->s)
7498 {
7499 ptrdiff_t stop, charpos, bytepos;
7500
7501 if (STRINGP (it->string))
7502 {
7503 eassert (!it->s);
7504 stop = SCHARS (it->string);
7505 if (stop > it->end_charpos)
7506 stop = it->end_charpos;
7507 charpos = IT_STRING_CHARPOS (*it);
7508 bytepos = IT_STRING_BYTEPOS (*it);
7509 }
7510 else
7511 {
7512 stop = it->end_charpos;
7513 charpos = IT_CHARPOS (*it);
7514 bytepos = IT_BYTEPOS (*it);
7515 }
7516 if (it->bidi_it.scan_dir < 0)
7517 stop = -1;
7518 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7519 it->string);
7520 }
7521 }
7522
7523 /* Load IT with the next display element from Lisp string IT->string.
7524 IT->current.string_pos is the current position within the string.
7525 If IT->current.overlay_string_index >= 0, the Lisp string is an
7526 overlay string. */
7527
7528 static int
7529 next_element_from_string (struct it *it)
7530 {
7531 struct text_pos position;
7532
7533 eassert (STRINGP (it->string));
7534 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7535 eassert (IT_STRING_CHARPOS (*it) >= 0);
7536 position = it->current.string_pos;
7537
7538 /* With bidi reordering, the character to display might not be the
7539 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7540 that we were reseat()ed to a new string, whose paragraph
7541 direction is not known. */
7542 if (it->bidi_p && it->bidi_it.first_elt)
7543 {
7544 get_visually_first_element (it);
7545 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7546 }
7547
7548 /* Time to check for invisible text? */
7549 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7550 {
7551 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7552 {
7553 if (!(!it->bidi_p
7554 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7555 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7556 {
7557 /* With bidi non-linear iteration, we could find
7558 ourselves far beyond the last computed stop_charpos,
7559 with several other stop positions in between that we
7560 missed. Scan them all now, in buffer's logical
7561 order, until we find and handle the last stop_charpos
7562 that precedes our current position. */
7563 handle_stop_backwards (it, it->stop_charpos);
7564 return GET_NEXT_DISPLAY_ELEMENT (it);
7565 }
7566 else
7567 {
7568 if (it->bidi_p)
7569 {
7570 /* Take note of the stop position we just moved
7571 across, for when we will move back across it. */
7572 it->prev_stop = it->stop_charpos;
7573 /* If we are at base paragraph embedding level, take
7574 note of the last stop position seen at this
7575 level. */
7576 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7577 it->base_level_stop = it->stop_charpos;
7578 }
7579 handle_stop (it);
7580
7581 /* Since a handler may have changed IT->method, we must
7582 recurse here. */
7583 return GET_NEXT_DISPLAY_ELEMENT (it);
7584 }
7585 }
7586 else if (it->bidi_p
7587 /* If we are before prev_stop, we may have overstepped
7588 on our way backwards a stop_pos, and if so, we need
7589 to handle that stop_pos. */
7590 && IT_STRING_CHARPOS (*it) < it->prev_stop
7591 /* We can sometimes back up for reasons that have nothing
7592 to do with bidi reordering. E.g., compositions. The
7593 code below is only needed when we are above the base
7594 embedding level, so test for that explicitly. */
7595 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7596 {
7597 /* If we lost track of base_level_stop, we have no better
7598 place for handle_stop_backwards to start from than string
7599 beginning. This happens, e.g., when we were reseated to
7600 the previous screenful of text by vertical-motion. */
7601 if (it->base_level_stop <= 0
7602 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7603 it->base_level_stop = 0;
7604 handle_stop_backwards (it, it->base_level_stop);
7605 return GET_NEXT_DISPLAY_ELEMENT (it);
7606 }
7607 }
7608
7609 if (it->current.overlay_string_index >= 0)
7610 {
7611 /* Get the next character from an overlay string. In overlay
7612 strings, there is no field width or padding with spaces to
7613 do. */
7614 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7615 {
7616 it->what = IT_EOB;
7617 return 0;
7618 }
7619 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7620 IT_STRING_BYTEPOS (*it),
7621 it->bidi_it.scan_dir < 0
7622 ? -1
7623 : SCHARS (it->string))
7624 && next_element_from_composition (it))
7625 {
7626 return 1;
7627 }
7628 else if (STRING_MULTIBYTE (it->string))
7629 {
7630 const unsigned char *s = (SDATA (it->string)
7631 + IT_STRING_BYTEPOS (*it));
7632 it->c = string_char_and_length (s, &it->len);
7633 }
7634 else
7635 {
7636 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7637 it->len = 1;
7638 }
7639 }
7640 else
7641 {
7642 /* Get the next character from a Lisp string that is not an
7643 overlay string. Such strings come from the mode line, for
7644 example. We may have to pad with spaces, or truncate the
7645 string. See also next_element_from_c_string. */
7646 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7647 {
7648 it->what = IT_EOB;
7649 return 0;
7650 }
7651 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7652 {
7653 /* Pad with spaces. */
7654 it->c = ' ', it->len = 1;
7655 CHARPOS (position) = BYTEPOS (position) = -1;
7656 }
7657 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7658 IT_STRING_BYTEPOS (*it),
7659 it->bidi_it.scan_dir < 0
7660 ? -1
7661 : it->string_nchars)
7662 && next_element_from_composition (it))
7663 {
7664 return 1;
7665 }
7666 else if (STRING_MULTIBYTE (it->string))
7667 {
7668 const unsigned char *s = (SDATA (it->string)
7669 + IT_STRING_BYTEPOS (*it));
7670 it->c = string_char_and_length (s, &it->len);
7671 }
7672 else
7673 {
7674 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7675 it->len = 1;
7676 }
7677 }
7678
7679 /* Record what we have and where it came from. */
7680 it->what = IT_CHARACTER;
7681 it->object = it->string;
7682 it->position = position;
7683 return 1;
7684 }
7685
7686
7687 /* Load IT with next display element from C string IT->s.
7688 IT->string_nchars is the maximum number of characters to return
7689 from the string. IT->end_charpos may be greater than
7690 IT->string_nchars when this function is called, in which case we
7691 may have to return padding spaces. Value is zero if end of string
7692 reached, including padding spaces. */
7693
7694 static int
7695 next_element_from_c_string (struct it *it)
7696 {
7697 int success_p = 1;
7698
7699 eassert (it->s);
7700 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7701 it->what = IT_CHARACTER;
7702 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7703 it->object = Qnil;
7704
7705 /* With bidi reordering, the character to display might not be the
7706 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7707 we were reseated to a new string, whose paragraph direction is
7708 not known. */
7709 if (it->bidi_p && it->bidi_it.first_elt)
7710 get_visually_first_element (it);
7711
7712 /* IT's position can be greater than IT->string_nchars in case a
7713 field width or precision has been specified when the iterator was
7714 initialized. */
7715 if (IT_CHARPOS (*it) >= it->end_charpos)
7716 {
7717 /* End of the game. */
7718 it->what = IT_EOB;
7719 success_p = 0;
7720 }
7721 else if (IT_CHARPOS (*it) >= it->string_nchars)
7722 {
7723 /* Pad with spaces. */
7724 it->c = ' ', it->len = 1;
7725 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7726 }
7727 else if (it->multibyte_p)
7728 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7729 else
7730 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7731
7732 return success_p;
7733 }
7734
7735
7736 /* Set up IT to return characters from an ellipsis, if appropriate.
7737 The definition of the ellipsis glyphs may come from a display table
7738 entry. This function fills IT with the first glyph from the
7739 ellipsis if an ellipsis is to be displayed. */
7740
7741 static int
7742 next_element_from_ellipsis (struct it *it)
7743 {
7744 if (it->selective_display_ellipsis_p)
7745 setup_for_ellipsis (it, it->len);
7746 else
7747 {
7748 /* The face at the current position may be different from the
7749 face we find after the invisible text. Remember what it
7750 was in IT->saved_face_id, and signal that it's there by
7751 setting face_before_selective_p. */
7752 it->saved_face_id = it->face_id;
7753 it->method = GET_FROM_BUFFER;
7754 it->object = it->w->buffer;
7755 reseat_at_next_visible_line_start (it, 1);
7756 it->face_before_selective_p = 1;
7757 }
7758
7759 return GET_NEXT_DISPLAY_ELEMENT (it);
7760 }
7761
7762
7763 /* Deliver an image display element. The iterator IT is already
7764 filled with image information (done in handle_display_prop). Value
7765 is always 1. */
7766
7767
7768 static int
7769 next_element_from_image (struct it *it)
7770 {
7771 it->what = IT_IMAGE;
7772 it->ignore_overlay_strings_at_pos_p = 0;
7773 return 1;
7774 }
7775
7776
7777 /* Fill iterator IT with next display element from a stretch glyph
7778 property. IT->object is the value of the text property. Value is
7779 always 1. */
7780
7781 static int
7782 next_element_from_stretch (struct it *it)
7783 {
7784 it->what = IT_STRETCH;
7785 return 1;
7786 }
7787
7788 /* Scan backwards from IT's current position until we find a stop
7789 position, or until BEGV. This is called when we find ourself
7790 before both the last known prev_stop and base_level_stop while
7791 reordering bidirectional text. */
7792
7793 static void
7794 compute_stop_pos_backwards (struct it *it)
7795 {
7796 const int SCAN_BACK_LIMIT = 1000;
7797 struct text_pos pos;
7798 struct display_pos save_current = it->current;
7799 struct text_pos save_position = it->position;
7800 ptrdiff_t charpos = IT_CHARPOS (*it);
7801 ptrdiff_t where_we_are = charpos;
7802 ptrdiff_t save_stop_pos = it->stop_charpos;
7803 ptrdiff_t save_end_pos = it->end_charpos;
7804
7805 eassert (NILP (it->string) && !it->s);
7806 eassert (it->bidi_p);
7807 it->bidi_p = 0;
7808 do
7809 {
7810 it->end_charpos = min (charpos + 1, ZV);
7811 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7812 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7813 reseat_1 (it, pos, 0);
7814 compute_stop_pos (it);
7815 /* We must advance forward, right? */
7816 if (it->stop_charpos <= charpos)
7817 emacs_abort ();
7818 }
7819 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7820
7821 if (it->stop_charpos <= where_we_are)
7822 it->prev_stop = it->stop_charpos;
7823 else
7824 it->prev_stop = BEGV;
7825 it->bidi_p = 1;
7826 it->current = save_current;
7827 it->position = save_position;
7828 it->stop_charpos = save_stop_pos;
7829 it->end_charpos = save_end_pos;
7830 }
7831
7832 /* Scan forward from CHARPOS in the current buffer/string, until we
7833 find a stop position > current IT's position. Then handle the stop
7834 position before that. This is called when we bump into a stop
7835 position while reordering bidirectional text. CHARPOS should be
7836 the last previously processed stop_pos (or BEGV/0, if none were
7837 processed yet) whose position is less that IT's current
7838 position. */
7839
7840 static void
7841 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7842 {
7843 int bufp = !STRINGP (it->string);
7844 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7845 struct display_pos save_current = it->current;
7846 struct text_pos save_position = it->position;
7847 struct text_pos pos1;
7848 ptrdiff_t next_stop;
7849
7850 /* Scan in strict logical order. */
7851 eassert (it->bidi_p);
7852 it->bidi_p = 0;
7853 do
7854 {
7855 it->prev_stop = charpos;
7856 if (bufp)
7857 {
7858 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7859 reseat_1 (it, pos1, 0);
7860 }
7861 else
7862 it->current.string_pos = string_pos (charpos, it->string);
7863 compute_stop_pos (it);
7864 /* We must advance forward, right? */
7865 if (it->stop_charpos <= it->prev_stop)
7866 emacs_abort ();
7867 charpos = it->stop_charpos;
7868 }
7869 while (charpos <= where_we_are);
7870
7871 it->bidi_p = 1;
7872 it->current = save_current;
7873 it->position = save_position;
7874 next_stop = it->stop_charpos;
7875 it->stop_charpos = it->prev_stop;
7876 handle_stop (it);
7877 it->stop_charpos = next_stop;
7878 }
7879
7880 /* Load IT with the next display element from current_buffer. Value
7881 is zero if end of buffer reached. IT->stop_charpos is the next
7882 position at which to stop and check for text properties or buffer
7883 end. */
7884
7885 static int
7886 next_element_from_buffer (struct it *it)
7887 {
7888 int success_p = 1;
7889
7890 eassert (IT_CHARPOS (*it) >= BEGV);
7891 eassert (NILP (it->string) && !it->s);
7892 eassert (!it->bidi_p
7893 || (EQ (it->bidi_it.string.lstring, Qnil)
7894 && it->bidi_it.string.s == NULL));
7895
7896 /* With bidi reordering, the character to display might not be the
7897 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7898 we were reseat()ed to a new buffer position, which is potentially
7899 a different paragraph. */
7900 if (it->bidi_p && it->bidi_it.first_elt)
7901 {
7902 get_visually_first_element (it);
7903 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7904 }
7905
7906 if (IT_CHARPOS (*it) >= it->stop_charpos)
7907 {
7908 if (IT_CHARPOS (*it) >= it->end_charpos)
7909 {
7910 int overlay_strings_follow_p;
7911
7912 /* End of the game, except when overlay strings follow that
7913 haven't been returned yet. */
7914 if (it->overlay_strings_at_end_processed_p)
7915 overlay_strings_follow_p = 0;
7916 else
7917 {
7918 it->overlay_strings_at_end_processed_p = 1;
7919 overlay_strings_follow_p = get_overlay_strings (it, 0);
7920 }
7921
7922 if (overlay_strings_follow_p)
7923 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7924 else
7925 {
7926 it->what = IT_EOB;
7927 it->position = it->current.pos;
7928 success_p = 0;
7929 }
7930 }
7931 else if (!(!it->bidi_p
7932 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7933 || IT_CHARPOS (*it) == it->stop_charpos))
7934 {
7935 /* With bidi non-linear iteration, we could find ourselves
7936 far beyond the last computed stop_charpos, with several
7937 other stop positions in between that we missed. Scan
7938 them all now, in buffer's logical order, until we find
7939 and handle the last stop_charpos that precedes our
7940 current position. */
7941 handle_stop_backwards (it, it->stop_charpos);
7942 return GET_NEXT_DISPLAY_ELEMENT (it);
7943 }
7944 else
7945 {
7946 if (it->bidi_p)
7947 {
7948 /* Take note of the stop position we just moved across,
7949 for when we will move back across it. */
7950 it->prev_stop = it->stop_charpos;
7951 /* If we are at base paragraph embedding level, take
7952 note of the last stop position seen at this
7953 level. */
7954 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7955 it->base_level_stop = it->stop_charpos;
7956 }
7957 handle_stop (it);
7958 return GET_NEXT_DISPLAY_ELEMENT (it);
7959 }
7960 }
7961 else if (it->bidi_p
7962 /* If we are before prev_stop, we may have overstepped on
7963 our way backwards a stop_pos, and if so, we need to
7964 handle that stop_pos. */
7965 && IT_CHARPOS (*it) < it->prev_stop
7966 /* We can sometimes back up for reasons that have nothing
7967 to do with bidi reordering. E.g., compositions. The
7968 code below is only needed when we are above the base
7969 embedding level, so test for that explicitly. */
7970 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7971 {
7972 if (it->base_level_stop <= 0
7973 || IT_CHARPOS (*it) < it->base_level_stop)
7974 {
7975 /* If we lost track of base_level_stop, we need to find
7976 prev_stop by looking backwards. This happens, e.g., when
7977 we were reseated to the previous screenful of text by
7978 vertical-motion. */
7979 it->base_level_stop = BEGV;
7980 compute_stop_pos_backwards (it);
7981 handle_stop_backwards (it, it->prev_stop);
7982 }
7983 else
7984 handle_stop_backwards (it, it->base_level_stop);
7985 return GET_NEXT_DISPLAY_ELEMENT (it);
7986 }
7987 else
7988 {
7989 /* No face changes, overlays etc. in sight, so just return a
7990 character from current_buffer. */
7991 unsigned char *p;
7992 ptrdiff_t stop;
7993
7994 /* Maybe run the redisplay end trigger hook. Performance note:
7995 This doesn't seem to cost measurable time. */
7996 if (it->redisplay_end_trigger_charpos
7997 && it->glyph_row
7998 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
7999 run_redisplay_end_trigger_hook (it);
8000
8001 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8002 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8003 stop)
8004 && next_element_from_composition (it))
8005 {
8006 return 1;
8007 }
8008
8009 /* Get the next character, maybe multibyte. */
8010 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8011 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8012 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8013 else
8014 it->c = *p, it->len = 1;
8015
8016 /* Record what we have and where it came from. */
8017 it->what = IT_CHARACTER;
8018 it->object = it->w->buffer;
8019 it->position = it->current.pos;
8020
8021 /* Normally we return the character found above, except when we
8022 really want to return an ellipsis for selective display. */
8023 if (it->selective)
8024 {
8025 if (it->c == '\n')
8026 {
8027 /* A value of selective > 0 means hide lines indented more
8028 than that number of columns. */
8029 if (it->selective > 0
8030 && IT_CHARPOS (*it) + 1 < ZV
8031 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8032 IT_BYTEPOS (*it) + 1,
8033 it->selective))
8034 {
8035 success_p = next_element_from_ellipsis (it);
8036 it->dpvec_char_len = -1;
8037 }
8038 }
8039 else if (it->c == '\r' && it->selective == -1)
8040 {
8041 /* A value of selective == -1 means that everything from the
8042 CR to the end of the line is invisible, with maybe an
8043 ellipsis displayed for it. */
8044 success_p = next_element_from_ellipsis (it);
8045 it->dpvec_char_len = -1;
8046 }
8047 }
8048 }
8049
8050 /* Value is zero if end of buffer reached. */
8051 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8052 return success_p;
8053 }
8054
8055
8056 /* Run the redisplay end trigger hook for IT. */
8057
8058 static void
8059 run_redisplay_end_trigger_hook (struct it *it)
8060 {
8061 Lisp_Object args[3];
8062
8063 /* IT->glyph_row should be non-null, i.e. we should be actually
8064 displaying something, or otherwise we should not run the hook. */
8065 eassert (it->glyph_row);
8066
8067 /* Set up hook arguments. */
8068 args[0] = Qredisplay_end_trigger_functions;
8069 args[1] = it->window;
8070 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8071 it->redisplay_end_trigger_charpos = 0;
8072
8073 /* Since we are *trying* to run these functions, don't try to run
8074 them again, even if they get an error. */
8075 wset_redisplay_end_trigger (it->w, Qnil);
8076 Frun_hook_with_args (3, args);
8077
8078 /* Notice if it changed the face of the character we are on. */
8079 handle_face_prop (it);
8080 }
8081
8082
8083 /* Deliver a composition display element. Unlike the other
8084 next_element_from_XXX, this function is not registered in the array
8085 get_next_element[]. It is called from next_element_from_buffer and
8086 next_element_from_string when necessary. */
8087
8088 static int
8089 next_element_from_composition (struct it *it)
8090 {
8091 it->what = IT_COMPOSITION;
8092 it->len = it->cmp_it.nbytes;
8093 if (STRINGP (it->string))
8094 {
8095 if (it->c < 0)
8096 {
8097 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8098 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8099 return 0;
8100 }
8101 it->position = it->current.string_pos;
8102 it->object = it->string;
8103 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8104 IT_STRING_BYTEPOS (*it), it->string);
8105 }
8106 else
8107 {
8108 if (it->c < 0)
8109 {
8110 IT_CHARPOS (*it) += it->cmp_it.nchars;
8111 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8112 if (it->bidi_p)
8113 {
8114 if (it->bidi_it.new_paragraph)
8115 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8116 /* Resync the bidi iterator with IT's new position.
8117 FIXME: this doesn't support bidirectional text. */
8118 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8119 bidi_move_to_visually_next (&it->bidi_it);
8120 }
8121 return 0;
8122 }
8123 it->position = it->current.pos;
8124 it->object = it->w->buffer;
8125 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8126 IT_BYTEPOS (*it), Qnil);
8127 }
8128 return 1;
8129 }
8130
8131
8132 \f
8133 /***********************************************************************
8134 Moving an iterator without producing glyphs
8135 ***********************************************************************/
8136
8137 /* Check if iterator is at a position corresponding to a valid buffer
8138 position after some move_it_ call. */
8139
8140 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8141 ((it)->method == GET_FROM_STRING \
8142 ? IT_STRING_CHARPOS (*it) == 0 \
8143 : 1)
8144
8145
8146 /* Move iterator IT to a specified buffer or X position within one
8147 line on the display without producing glyphs.
8148
8149 OP should be a bit mask including some or all of these bits:
8150 MOVE_TO_X: Stop upon reaching x-position TO_X.
8151 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8152 Regardless of OP's value, stop upon reaching the end of the display line.
8153
8154 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8155 This means, in particular, that TO_X includes window's horizontal
8156 scroll amount.
8157
8158 The return value has several possible values that
8159 say what condition caused the scan to stop:
8160
8161 MOVE_POS_MATCH_OR_ZV
8162 - when TO_POS or ZV was reached.
8163
8164 MOVE_X_REACHED
8165 -when TO_X was reached before TO_POS or ZV were reached.
8166
8167 MOVE_LINE_CONTINUED
8168 - when we reached the end of the display area and the line must
8169 be continued.
8170
8171 MOVE_LINE_TRUNCATED
8172 - when we reached the end of the display area and the line is
8173 truncated.
8174
8175 MOVE_NEWLINE_OR_CR
8176 - when we stopped at a line end, i.e. a newline or a CR and selective
8177 display is on. */
8178
8179 static enum move_it_result
8180 move_it_in_display_line_to (struct it *it,
8181 ptrdiff_t to_charpos, int to_x,
8182 enum move_operation_enum op)
8183 {
8184 enum move_it_result result = MOVE_UNDEFINED;
8185 struct glyph_row *saved_glyph_row;
8186 struct it wrap_it, atpos_it, atx_it, ppos_it;
8187 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8188 void *ppos_data = NULL;
8189 int may_wrap = 0;
8190 enum it_method prev_method = it->method;
8191 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8192 int saw_smaller_pos = prev_pos < to_charpos;
8193
8194 /* Don't produce glyphs in produce_glyphs. */
8195 saved_glyph_row = it->glyph_row;
8196 it->glyph_row = NULL;
8197
8198 /* Use wrap_it to save a copy of IT wherever a word wrap could
8199 occur. Use atpos_it to save a copy of IT at the desired buffer
8200 position, if found, so that we can scan ahead and check if the
8201 word later overshoots the window edge. Use atx_it similarly, for
8202 pixel positions. */
8203 wrap_it.sp = -1;
8204 atpos_it.sp = -1;
8205 atx_it.sp = -1;
8206
8207 /* Use ppos_it under bidi reordering to save a copy of IT for the
8208 position > CHARPOS that is the closest to CHARPOS. We restore
8209 that position in IT when we have scanned the entire display line
8210 without finding a match for CHARPOS and all the character
8211 positions are greater than CHARPOS. */
8212 if (it->bidi_p)
8213 {
8214 SAVE_IT (ppos_it, *it, ppos_data);
8215 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8216 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8217 SAVE_IT (ppos_it, *it, ppos_data);
8218 }
8219
8220 #define BUFFER_POS_REACHED_P() \
8221 ((op & MOVE_TO_POS) != 0 \
8222 && BUFFERP (it->object) \
8223 && (IT_CHARPOS (*it) == to_charpos \
8224 || ((!it->bidi_p \
8225 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8226 && IT_CHARPOS (*it) > to_charpos) \
8227 || (it->what == IT_COMPOSITION \
8228 && ((IT_CHARPOS (*it) > to_charpos \
8229 && to_charpos >= it->cmp_it.charpos) \
8230 || (IT_CHARPOS (*it) < to_charpos \
8231 && to_charpos <= it->cmp_it.charpos)))) \
8232 && (it->method == GET_FROM_BUFFER \
8233 || (it->method == GET_FROM_DISPLAY_VECTOR \
8234 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8235
8236 /* If there's a line-/wrap-prefix, handle it. */
8237 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8238 && it->current_y < it->last_visible_y)
8239 handle_line_prefix (it);
8240
8241 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8242 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8243
8244 while (1)
8245 {
8246 int x, i, ascent = 0, descent = 0;
8247
8248 /* Utility macro to reset an iterator with x, ascent, and descent. */
8249 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8250 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8251 (IT)->max_descent = descent)
8252
8253 /* Stop if we move beyond TO_CHARPOS (after an image or a
8254 display string or stretch glyph). */
8255 if ((op & MOVE_TO_POS) != 0
8256 && BUFFERP (it->object)
8257 && it->method == GET_FROM_BUFFER
8258 && (((!it->bidi_p
8259 /* When the iterator is at base embedding level, we
8260 are guaranteed that characters are delivered for
8261 display in strictly increasing order of their
8262 buffer positions. */
8263 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8264 && IT_CHARPOS (*it) > to_charpos)
8265 || (it->bidi_p
8266 && (prev_method == GET_FROM_IMAGE
8267 || prev_method == GET_FROM_STRETCH
8268 || prev_method == GET_FROM_STRING)
8269 /* Passed TO_CHARPOS from left to right. */
8270 && ((prev_pos < to_charpos
8271 && IT_CHARPOS (*it) > to_charpos)
8272 /* Passed TO_CHARPOS from right to left. */
8273 || (prev_pos > to_charpos
8274 && IT_CHARPOS (*it) < to_charpos)))))
8275 {
8276 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8277 {
8278 result = MOVE_POS_MATCH_OR_ZV;
8279 break;
8280 }
8281 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8282 /* If wrap_it is valid, the current position might be in a
8283 word that is wrapped. So, save the iterator in
8284 atpos_it and continue to see if wrapping happens. */
8285 SAVE_IT (atpos_it, *it, atpos_data);
8286 }
8287
8288 /* Stop when ZV reached.
8289 We used to stop here when TO_CHARPOS reached as well, but that is
8290 too soon if this glyph does not fit on this line. So we handle it
8291 explicitly below. */
8292 if (!get_next_display_element (it))
8293 {
8294 result = MOVE_POS_MATCH_OR_ZV;
8295 break;
8296 }
8297
8298 if (it->line_wrap == TRUNCATE)
8299 {
8300 if (BUFFER_POS_REACHED_P ())
8301 {
8302 result = MOVE_POS_MATCH_OR_ZV;
8303 break;
8304 }
8305 }
8306 else
8307 {
8308 if (it->line_wrap == WORD_WRAP)
8309 {
8310 if (IT_DISPLAYING_WHITESPACE (it))
8311 may_wrap = 1;
8312 else if (may_wrap)
8313 {
8314 /* We have reached a glyph that follows one or more
8315 whitespace characters. If the position is
8316 already found, we are done. */
8317 if (atpos_it.sp >= 0)
8318 {
8319 RESTORE_IT (it, &atpos_it, atpos_data);
8320 result = MOVE_POS_MATCH_OR_ZV;
8321 goto done;
8322 }
8323 if (atx_it.sp >= 0)
8324 {
8325 RESTORE_IT (it, &atx_it, atx_data);
8326 result = MOVE_X_REACHED;
8327 goto done;
8328 }
8329 /* Otherwise, we can wrap here. */
8330 SAVE_IT (wrap_it, *it, wrap_data);
8331 may_wrap = 0;
8332 }
8333 }
8334 }
8335
8336 /* Remember the line height for the current line, in case
8337 the next element doesn't fit on the line. */
8338 ascent = it->max_ascent;
8339 descent = it->max_descent;
8340
8341 /* The call to produce_glyphs will get the metrics of the
8342 display element IT is loaded with. Record the x-position
8343 before this display element, in case it doesn't fit on the
8344 line. */
8345 x = it->current_x;
8346
8347 PRODUCE_GLYPHS (it);
8348
8349 if (it->area != TEXT_AREA)
8350 {
8351 prev_method = it->method;
8352 if (it->method == GET_FROM_BUFFER)
8353 prev_pos = IT_CHARPOS (*it);
8354 set_iterator_to_next (it, 1);
8355 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8356 SET_TEXT_POS (this_line_min_pos,
8357 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8358 if (it->bidi_p
8359 && (op & MOVE_TO_POS)
8360 && IT_CHARPOS (*it) > to_charpos
8361 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8362 SAVE_IT (ppos_it, *it, ppos_data);
8363 continue;
8364 }
8365
8366 /* The number of glyphs we get back in IT->nglyphs will normally
8367 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8368 character on a terminal frame, or (iii) a line end. For the
8369 second case, IT->nglyphs - 1 padding glyphs will be present.
8370 (On X frames, there is only one glyph produced for a
8371 composite character.)
8372
8373 The behavior implemented below means, for continuation lines,
8374 that as many spaces of a TAB as fit on the current line are
8375 displayed there. For terminal frames, as many glyphs of a
8376 multi-glyph character are displayed in the current line, too.
8377 This is what the old redisplay code did, and we keep it that
8378 way. Under X, the whole shape of a complex character must
8379 fit on the line or it will be completely displayed in the
8380 next line.
8381
8382 Note that both for tabs and padding glyphs, all glyphs have
8383 the same width. */
8384 if (it->nglyphs)
8385 {
8386 /* More than one glyph or glyph doesn't fit on line. All
8387 glyphs have the same width. */
8388 int single_glyph_width = it->pixel_width / it->nglyphs;
8389 int new_x;
8390 int x_before_this_char = x;
8391 int hpos_before_this_char = it->hpos;
8392
8393 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8394 {
8395 new_x = x + single_glyph_width;
8396
8397 /* We want to leave anything reaching TO_X to the caller. */
8398 if ((op & MOVE_TO_X) && new_x > to_x)
8399 {
8400 if (BUFFER_POS_REACHED_P ())
8401 {
8402 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8403 goto buffer_pos_reached;
8404 if (atpos_it.sp < 0)
8405 {
8406 SAVE_IT (atpos_it, *it, atpos_data);
8407 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8408 }
8409 }
8410 else
8411 {
8412 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8413 {
8414 it->current_x = x;
8415 result = MOVE_X_REACHED;
8416 break;
8417 }
8418 if (atx_it.sp < 0)
8419 {
8420 SAVE_IT (atx_it, *it, atx_data);
8421 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8422 }
8423 }
8424 }
8425
8426 if (/* Lines are continued. */
8427 it->line_wrap != TRUNCATE
8428 && (/* And glyph doesn't fit on the line. */
8429 new_x > it->last_visible_x
8430 /* Or it fits exactly and we're on a window
8431 system frame. */
8432 || (new_x == it->last_visible_x
8433 && FRAME_WINDOW_P (it->f)
8434 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8435 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8436 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8437 {
8438 if (/* IT->hpos == 0 means the very first glyph
8439 doesn't fit on the line, e.g. a wide image. */
8440 it->hpos == 0
8441 || (new_x == it->last_visible_x
8442 && FRAME_WINDOW_P (it->f)))
8443 {
8444 ++it->hpos;
8445 it->current_x = new_x;
8446
8447 /* The character's last glyph just barely fits
8448 in this row. */
8449 if (i == it->nglyphs - 1)
8450 {
8451 /* If this is the destination position,
8452 return a position *before* it in this row,
8453 now that we know it fits in this row. */
8454 if (BUFFER_POS_REACHED_P ())
8455 {
8456 if (it->line_wrap != WORD_WRAP
8457 || wrap_it.sp < 0)
8458 {
8459 it->hpos = hpos_before_this_char;
8460 it->current_x = x_before_this_char;
8461 result = MOVE_POS_MATCH_OR_ZV;
8462 break;
8463 }
8464 if (it->line_wrap == WORD_WRAP
8465 && atpos_it.sp < 0)
8466 {
8467 SAVE_IT (atpos_it, *it, atpos_data);
8468 atpos_it.current_x = x_before_this_char;
8469 atpos_it.hpos = hpos_before_this_char;
8470 }
8471 }
8472
8473 prev_method = it->method;
8474 if (it->method == GET_FROM_BUFFER)
8475 prev_pos = IT_CHARPOS (*it);
8476 set_iterator_to_next (it, 1);
8477 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8478 SET_TEXT_POS (this_line_min_pos,
8479 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8480 /* On graphical terminals, newlines may
8481 "overflow" into the fringe if
8482 overflow-newline-into-fringe is non-nil.
8483 On text terminals, and on graphical
8484 terminals with no right margin, newlines
8485 may overflow into the last glyph on the
8486 display line.*/
8487 if (!FRAME_WINDOW_P (it->f)
8488 || ((it->bidi_p
8489 && it->bidi_it.paragraph_dir == R2L)
8490 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8491 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8492 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8493 {
8494 if (!get_next_display_element (it))
8495 {
8496 result = MOVE_POS_MATCH_OR_ZV;
8497 break;
8498 }
8499 if (BUFFER_POS_REACHED_P ())
8500 {
8501 if (ITERATOR_AT_END_OF_LINE_P (it))
8502 result = MOVE_POS_MATCH_OR_ZV;
8503 else
8504 result = MOVE_LINE_CONTINUED;
8505 break;
8506 }
8507 if (ITERATOR_AT_END_OF_LINE_P (it))
8508 {
8509 result = MOVE_NEWLINE_OR_CR;
8510 break;
8511 }
8512 }
8513 }
8514 }
8515 else
8516 IT_RESET_X_ASCENT_DESCENT (it);
8517
8518 if (wrap_it.sp >= 0)
8519 {
8520 RESTORE_IT (it, &wrap_it, wrap_data);
8521 atpos_it.sp = -1;
8522 atx_it.sp = -1;
8523 }
8524
8525 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8526 IT_CHARPOS (*it)));
8527 result = MOVE_LINE_CONTINUED;
8528 break;
8529 }
8530
8531 if (BUFFER_POS_REACHED_P ())
8532 {
8533 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8534 goto buffer_pos_reached;
8535 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8536 {
8537 SAVE_IT (atpos_it, *it, atpos_data);
8538 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8539 }
8540 }
8541
8542 if (new_x > it->first_visible_x)
8543 {
8544 /* Glyph is visible. Increment number of glyphs that
8545 would be displayed. */
8546 ++it->hpos;
8547 }
8548 }
8549
8550 if (result != MOVE_UNDEFINED)
8551 break;
8552 }
8553 else if (BUFFER_POS_REACHED_P ())
8554 {
8555 buffer_pos_reached:
8556 IT_RESET_X_ASCENT_DESCENT (it);
8557 result = MOVE_POS_MATCH_OR_ZV;
8558 break;
8559 }
8560 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8561 {
8562 /* Stop when TO_X specified and reached. This check is
8563 necessary here because of lines consisting of a line end,
8564 only. The line end will not produce any glyphs and we
8565 would never get MOVE_X_REACHED. */
8566 eassert (it->nglyphs == 0);
8567 result = MOVE_X_REACHED;
8568 break;
8569 }
8570
8571 /* Is this a line end? If yes, we're done. */
8572 if (ITERATOR_AT_END_OF_LINE_P (it))
8573 {
8574 /* If we are past TO_CHARPOS, but never saw any character
8575 positions smaller than TO_CHARPOS, return
8576 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8577 did. */
8578 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8579 {
8580 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8581 {
8582 if (IT_CHARPOS (ppos_it) < ZV)
8583 {
8584 RESTORE_IT (it, &ppos_it, ppos_data);
8585 result = MOVE_POS_MATCH_OR_ZV;
8586 }
8587 else
8588 goto buffer_pos_reached;
8589 }
8590 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8591 && IT_CHARPOS (*it) > to_charpos)
8592 goto buffer_pos_reached;
8593 else
8594 result = MOVE_NEWLINE_OR_CR;
8595 }
8596 else
8597 result = MOVE_NEWLINE_OR_CR;
8598 break;
8599 }
8600
8601 prev_method = it->method;
8602 if (it->method == GET_FROM_BUFFER)
8603 prev_pos = IT_CHARPOS (*it);
8604 /* The current display element has been consumed. Advance
8605 to the next. */
8606 set_iterator_to_next (it, 1);
8607 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8608 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8609 if (IT_CHARPOS (*it) < to_charpos)
8610 saw_smaller_pos = 1;
8611 if (it->bidi_p
8612 && (op & MOVE_TO_POS)
8613 && IT_CHARPOS (*it) >= to_charpos
8614 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8615 SAVE_IT (ppos_it, *it, ppos_data);
8616
8617 /* Stop if lines are truncated and IT's current x-position is
8618 past the right edge of the window now. */
8619 if (it->line_wrap == TRUNCATE
8620 && it->current_x >= it->last_visible_x)
8621 {
8622 if (!FRAME_WINDOW_P (it->f)
8623 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8624 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8625 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8626 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8627 {
8628 int at_eob_p = 0;
8629
8630 if ((at_eob_p = !get_next_display_element (it))
8631 || BUFFER_POS_REACHED_P ()
8632 /* If we are past TO_CHARPOS, but never saw any
8633 character positions smaller than TO_CHARPOS,
8634 return MOVE_POS_MATCH_OR_ZV, like the
8635 unidirectional display did. */
8636 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8637 && !saw_smaller_pos
8638 && IT_CHARPOS (*it) > to_charpos))
8639 {
8640 if (it->bidi_p
8641 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8642 RESTORE_IT (it, &ppos_it, ppos_data);
8643 result = MOVE_POS_MATCH_OR_ZV;
8644 break;
8645 }
8646 if (ITERATOR_AT_END_OF_LINE_P (it))
8647 {
8648 result = MOVE_NEWLINE_OR_CR;
8649 break;
8650 }
8651 }
8652 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8653 && !saw_smaller_pos
8654 && IT_CHARPOS (*it) > to_charpos)
8655 {
8656 if (IT_CHARPOS (ppos_it) < ZV)
8657 RESTORE_IT (it, &ppos_it, ppos_data);
8658 result = MOVE_POS_MATCH_OR_ZV;
8659 break;
8660 }
8661 result = MOVE_LINE_TRUNCATED;
8662 break;
8663 }
8664 #undef IT_RESET_X_ASCENT_DESCENT
8665 }
8666
8667 #undef BUFFER_POS_REACHED_P
8668
8669 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8670 restore the saved iterator. */
8671 if (atpos_it.sp >= 0)
8672 RESTORE_IT (it, &atpos_it, atpos_data);
8673 else if (atx_it.sp >= 0)
8674 RESTORE_IT (it, &atx_it, atx_data);
8675
8676 done:
8677
8678 if (atpos_data)
8679 bidi_unshelve_cache (atpos_data, 1);
8680 if (atx_data)
8681 bidi_unshelve_cache (atx_data, 1);
8682 if (wrap_data)
8683 bidi_unshelve_cache (wrap_data, 1);
8684 if (ppos_data)
8685 bidi_unshelve_cache (ppos_data, 1);
8686
8687 /* Restore the iterator settings altered at the beginning of this
8688 function. */
8689 it->glyph_row = saved_glyph_row;
8690 return result;
8691 }
8692
8693 /* For external use. */
8694 void
8695 move_it_in_display_line (struct it *it,
8696 ptrdiff_t to_charpos, int to_x,
8697 enum move_operation_enum op)
8698 {
8699 if (it->line_wrap == WORD_WRAP
8700 && (op & MOVE_TO_X))
8701 {
8702 struct it save_it;
8703 void *save_data = NULL;
8704 int skip;
8705
8706 SAVE_IT (save_it, *it, save_data);
8707 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8708 /* When word-wrap is on, TO_X may lie past the end
8709 of a wrapped line. Then it->current is the
8710 character on the next line, so backtrack to the
8711 space before the wrap point. */
8712 if (skip == MOVE_LINE_CONTINUED)
8713 {
8714 int prev_x = max (it->current_x - 1, 0);
8715 RESTORE_IT (it, &save_it, save_data);
8716 move_it_in_display_line_to
8717 (it, -1, prev_x, MOVE_TO_X);
8718 }
8719 else
8720 bidi_unshelve_cache (save_data, 1);
8721 }
8722 else
8723 move_it_in_display_line_to (it, to_charpos, to_x, op);
8724 }
8725
8726
8727 /* Move IT forward until it satisfies one or more of the criteria in
8728 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8729
8730 OP is a bit-mask that specifies where to stop, and in particular,
8731 which of those four position arguments makes a difference. See the
8732 description of enum move_operation_enum.
8733
8734 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8735 screen line, this function will set IT to the next position that is
8736 displayed to the right of TO_CHARPOS on the screen. */
8737
8738 void
8739 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8740 {
8741 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8742 int line_height, line_start_x = 0, reached = 0;
8743 void *backup_data = NULL;
8744
8745 for (;;)
8746 {
8747 if (op & MOVE_TO_VPOS)
8748 {
8749 /* If no TO_CHARPOS and no TO_X specified, stop at the
8750 start of the line TO_VPOS. */
8751 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8752 {
8753 if (it->vpos == to_vpos)
8754 {
8755 reached = 1;
8756 break;
8757 }
8758 else
8759 skip = move_it_in_display_line_to (it, -1, -1, 0);
8760 }
8761 else
8762 {
8763 /* TO_VPOS >= 0 means stop at TO_X in the line at
8764 TO_VPOS, or at TO_POS, whichever comes first. */
8765 if (it->vpos == to_vpos)
8766 {
8767 reached = 2;
8768 break;
8769 }
8770
8771 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8772
8773 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8774 {
8775 reached = 3;
8776 break;
8777 }
8778 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8779 {
8780 /* We have reached TO_X but not in the line we want. */
8781 skip = move_it_in_display_line_to (it, to_charpos,
8782 -1, MOVE_TO_POS);
8783 if (skip == MOVE_POS_MATCH_OR_ZV)
8784 {
8785 reached = 4;
8786 break;
8787 }
8788 }
8789 }
8790 }
8791 else if (op & MOVE_TO_Y)
8792 {
8793 struct it it_backup;
8794
8795 if (it->line_wrap == WORD_WRAP)
8796 SAVE_IT (it_backup, *it, backup_data);
8797
8798 /* TO_Y specified means stop at TO_X in the line containing
8799 TO_Y---or at TO_CHARPOS if this is reached first. The
8800 problem is that we can't really tell whether the line
8801 contains TO_Y before we have completely scanned it, and
8802 this may skip past TO_X. What we do is to first scan to
8803 TO_X.
8804
8805 If TO_X is not specified, use a TO_X of zero. The reason
8806 is to make the outcome of this function more predictable.
8807 If we didn't use TO_X == 0, we would stop at the end of
8808 the line which is probably not what a caller would expect
8809 to happen. */
8810 skip = move_it_in_display_line_to
8811 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8812 (MOVE_TO_X | (op & MOVE_TO_POS)));
8813
8814 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8815 if (skip == MOVE_POS_MATCH_OR_ZV)
8816 reached = 5;
8817 else if (skip == MOVE_X_REACHED)
8818 {
8819 /* If TO_X was reached, we want to know whether TO_Y is
8820 in the line. We know this is the case if the already
8821 scanned glyphs make the line tall enough. Otherwise,
8822 we must check by scanning the rest of the line. */
8823 line_height = it->max_ascent + it->max_descent;
8824 if (to_y >= it->current_y
8825 && to_y < it->current_y + line_height)
8826 {
8827 reached = 6;
8828 break;
8829 }
8830 SAVE_IT (it_backup, *it, backup_data);
8831 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8832 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8833 op & MOVE_TO_POS);
8834 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8835 line_height = it->max_ascent + it->max_descent;
8836 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8837
8838 if (to_y >= it->current_y
8839 && to_y < it->current_y + line_height)
8840 {
8841 /* If TO_Y is in this line and TO_X was reached
8842 above, we scanned too far. We have to restore
8843 IT's settings to the ones before skipping. But
8844 keep the more accurate values of max_ascent and
8845 max_descent we've found while skipping the rest
8846 of the line, for the sake of callers, such as
8847 pos_visible_p, that need to know the line
8848 height. */
8849 int max_ascent = it->max_ascent;
8850 int max_descent = it->max_descent;
8851
8852 RESTORE_IT (it, &it_backup, backup_data);
8853 it->max_ascent = max_ascent;
8854 it->max_descent = max_descent;
8855 reached = 6;
8856 }
8857 else
8858 {
8859 skip = skip2;
8860 if (skip == MOVE_POS_MATCH_OR_ZV)
8861 reached = 7;
8862 }
8863 }
8864 else
8865 {
8866 /* Check whether TO_Y is in this line. */
8867 line_height = it->max_ascent + it->max_descent;
8868 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8869
8870 if (to_y >= it->current_y
8871 && to_y < it->current_y + line_height)
8872 {
8873 /* When word-wrap is on, TO_X may lie past the end
8874 of a wrapped line. Then it->current is the
8875 character on the next line, so backtrack to the
8876 space before the wrap point. */
8877 if (skip == MOVE_LINE_CONTINUED
8878 && it->line_wrap == WORD_WRAP)
8879 {
8880 int prev_x = max (it->current_x - 1, 0);
8881 RESTORE_IT (it, &it_backup, backup_data);
8882 skip = move_it_in_display_line_to
8883 (it, -1, prev_x, MOVE_TO_X);
8884 }
8885 reached = 6;
8886 }
8887 }
8888
8889 if (reached)
8890 break;
8891 }
8892 else if (BUFFERP (it->object)
8893 && (it->method == GET_FROM_BUFFER
8894 || it->method == GET_FROM_STRETCH)
8895 && IT_CHARPOS (*it) >= to_charpos
8896 /* Under bidi iteration, a call to set_iterator_to_next
8897 can scan far beyond to_charpos if the initial
8898 portion of the next line needs to be reordered. In
8899 that case, give move_it_in_display_line_to another
8900 chance below. */
8901 && !(it->bidi_p
8902 && it->bidi_it.scan_dir == -1))
8903 skip = MOVE_POS_MATCH_OR_ZV;
8904 else
8905 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8906
8907 switch (skip)
8908 {
8909 case MOVE_POS_MATCH_OR_ZV:
8910 reached = 8;
8911 goto out;
8912
8913 case MOVE_NEWLINE_OR_CR:
8914 set_iterator_to_next (it, 1);
8915 it->continuation_lines_width = 0;
8916 break;
8917
8918 case MOVE_LINE_TRUNCATED:
8919 it->continuation_lines_width = 0;
8920 reseat_at_next_visible_line_start (it, 0);
8921 if ((op & MOVE_TO_POS) != 0
8922 && IT_CHARPOS (*it) > to_charpos)
8923 {
8924 reached = 9;
8925 goto out;
8926 }
8927 break;
8928
8929 case MOVE_LINE_CONTINUED:
8930 /* For continued lines ending in a tab, some of the glyphs
8931 associated with the tab are displayed on the current
8932 line. Since it->current_x does not include these glyphs,
8933 we use it->last_visible_x instead. */
8934 if (it->c == '\t')
8935 {
8936 it->continuation_lines_width += it->last_visible_x;
8937 /* When moving by vpos, ensure that the iterator really
8938 advances to the next line (bug#847, bug#969). Fixme:
8939 do we need to do this in other circumstances? */
8940 if (it->current_x != it->last_visible_x
8941 && (op & MOVE_TO_VPOS)
8942 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
8943 {
8944 line_start_x = it->current_x + it->pixel_width
8945 - it->last_visible_x;
8946 set_iterator_to_next (it, 0);
8947 }
8948 }
8949 else
8950 it->continuation_lines_width += it->current_x;
8951 break;
8952
8953 default:
8954 emacs_abort ();
8955 }
8956
8957 /* Reset/increment for the next run. */
8958 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
8959 it->current_x = line_start_x;
8960 line_start_x = 0;
8961 it->hpos = 0;
8962 it->current_y += it->max_ascent + it->max_descent;
8963 ++it->vpos;
8964 last_height = it->max_ascent + it->max_descent;
8965 last_max_ascent = it->max_ascent;
8966 it->max_ascent = it->max_descent = 0;
8967 }
8968
8969 out:
8970
8971 /* On text terminals, we may stop at the end of a line in the middle
8972 of a multi-character glyph. If the glyph itself is continued,
8973 i.e. it is actually displayed on the next line, don't treat this
8974 stopping point as valid; move to the next line instead (unless
8975 that brings us offscreen). */
8976 if (!FRAME_WINDOW_P (it->f)
8977 && op & MOVE_TO_POS
8978 && IT_CHARPOS (*it) == to_charpos
8979 && it->what == IT_CHARACTER
8980 && it->nglyphs > 1
8981 && it->line_wrap == WINDOW_WRAP
8982 && it->current_x == it->last_visible_x - 1
8983 && it->c != '\n'
8984 && it->c != '\t'
8985 && it->vpos < XFASTINT (it->w->window_end_vpos))
8986 {
8987 it->continuation_lines_width += it->current_x;
8988 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
8989 it->current_y += it->max_ascent + it->max_descent;
8990 ++it->vpos;
8991 last_height = it->max_ascent + it->max_descent;
8992 last_max_ascent = it->max_ascent;
8993 }
8994
8995 if (backup_data)
8996 bidi_unshelve_cache (backup_data, 1);
8997
8998 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
8999 }
9000
9001
9002 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9003
9004 If DY > 0, move IT backward at least that many pixels. DY = 0
9005 means move IT backward to the preceding line start or BEGV. This
9006 function may move over more than DY pixels if IT->current_y - DY
9007 ends up in the middle of a line; in this case IT->current_y will be
9008 set to the top of the line moved to. */
9009
9010 void
9011 move_it_vertically_backward (struct it *it, int dy)
9012 {
9013 int nlines, h;
9014 struct it it2, it3;
9015 void *it2data = NULL, *it3data = NULL;
9016 ptrdiff_t start_pos;
9017
9018 move_further_back:
9019 eassert (dy >= 0);
9020
9021 start_pos = IT_CHARPOS (*it);
9022
9023 /* Estimate how many newlines we must move back. */
9024 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
9025
9026 /* Set the iterator's position that many lines back. */
9027 while (nlines-- && IT_CHARPOS (*it) > BEGV)
9028 back_to_previous_visible_line_start (it);
9029
9030 /* Reseat the iterator here. When moving backward, we don't want
9031 reseat to skip forward over invisible text, set up the iterator
9032 to deliver from overlay strings at the new position etc. So,
9033 use reseat_1 here. */
9034 reseat_1 (it, it->current.pos, 1);
9035
9036 /* We are now surely at a line start. */
9037 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9038 reordering is in effect. */
9039 it->continuation_lines_width = 0;
9040
9041 /* Move forward and see what y-distance we moved. First move to the
9042 start of the next line so that we get its height. We need this
9043 height to be able to tell whether we reached the specified
9044 y-distance. */
9045 SAVE_IT (it2, *it, it2data);
9046 it2.max_ascent = it2.max_descent = 0;
9047 do
9048 {
9049 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9050 MOVE_TO_POS | MOVE_TO_VPOS);
9051 }
9052 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9053 /* If we are in a display string which starts at START_POS,
9054 and that display string includes a newline, and we are
9055 right after that newline (i.e. at the beginning of a
9056 display line), exit the loop, because otherwise we will
9057 infloop, since move_it_to will see that it is already at
9058 START_POS and will not move. */
9059 || (it2.method == GET_FROM_STRING
9060 && IT_CHARPOS (it2) == start_pos
9061 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9062 eassert (IT_CHARPOS (*it) >= BEGV);
9063 SAVE_IT (it3, it2, it3data);
9064
9065 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9066 eassert (IT_CHARPOS (*it) >= BEGV);
9067 /* H is the actual vertical distance from the position in *IT
9068 and the starting position. */
9069 h = it2.current_y - it->current_y;
9070 /* NLINES is the distance in number of lines. */
9071 nlines = it2.vpos - it->vpos;
9072
9073 /* Correct IT's y and vpos position
9074 so that they are relative to the starting point. */
9075 it->vpos -= nlines;
9076 it->current_y -= h;
9077
9078 if (dy == 0)
9079 {
9080 /* DY == 0 means move to the start of the screen line. The
9081 value of nlines is > 0 if continuation lines were involved,
9082 or if the original IT position was at start of a line. */
9083 RESTORE_IT (it, it, it2data);
9084 if (nlines > 0)
9085 move_it_by_lines (it, nlines);
9086 /* The above code moves us to some position NLINES down,
9087 usually to its first glyph (leftmost in an L2R line), but
9088 that's not necessarily the start of the line, under bidi
9089 reordering. We want to get to the character position
9090 that is immediately after the newline of the previous
9091 line. */
9092 if (it->bidi_p
9093 && !it->continuation_lines_width
9094 && !STRINGP (it->string)
9095 && IT_CHARPOS (*it) > BEGV
9096 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9097 {
9098 ptrdiff_t nl_pos =
9099 find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
9100
9101 move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS);
9102 }
9103 bidi_unshelve_cache (it3data, 1);
9104 }
9105 else
9106 {
9107 /* The y-position we try to reach, relative to *IT.
9108 Note that H has been subtracted in front of the if-statement. */
9109 int target_y = it->current_y + h - dy;
9110 int y0 = it3.current_y;
9111 int y1;
9112 int line_height;
9113
9114 RESTORE_IT (&it3, &it3, it3data);
9115 y1 = line_bottom_y (&it3);
9116 line_height = y1 - y0;
9117 RESTORE_IT (it, it, it2data);
9118 /* If we did not reach target_y, try to move further backward if
9119 we can. If we moved too far backward, try to move forward. */
9120 if (target_y < it->current_y
9121 /* This is heuristic. In a window that's 3 lines high, with
9122 a line height of 13 pixels each, recentering with point
9123 on the bottom line will try to move -39/2 = 19 pixels
9124 backward. Try to avoid moving into the first line. */
9125 && (it->current_y - target_y
9126 > min (window_box_height (it->w), line_height * 2 / 3))
9127 && IT_CHARPOS (*it) > BEGV)
9128 {
9129 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9130 target_y - it->current_y));
9131 dy = it->current_y - target_y;
9132 goto move_further_back;
9133 }
9134 else if (target_y >= it->current_y + line_height
9135 && IT_CHARPOS (*it) < ZV)
9136 {
9137 /* Should move forward by at least one line, maybe more.
9138
9139 Note: Calling move_it_by_lines can be expensive on
9140 terminal frames, where compute_motion is used (via
9141 vmotion) to do the job, when there are very long lines
9142 and truncate-lines is nil. That's the reason for
9143 treating terminal frames specially here. */
9144
9145 if (!FRAME_WINDOW_P (it->f))
9146 move_it_vertically (it, target_y - (it->current_y + line_height));
9147 else
9148 {
9149 do
9150 {
9151 move_it_by_lines (it, 1);
9152 }
9153 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9154 }
9155 }
9156 }
9157 }
9158
9159
9160 /* Move IT by a specified amount of pixel lines DY. DY negative means
9161 move backwards. DY = 0 means move to start of screen line. At the
9162 end, IT will be on the start of a screen line. */
9163
9164 void
9165 move_it_vertically (struct it *it, int dy)
9166 {
9167 if (dy <= 0)
9168 move_it_vertically_backward (it, -dy);
9169 else
9170 {
9171 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9172 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9173 MOVE_TO_POS | MOVE_TO_Y);
9174 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9175
9176 /* If buffer ends in ZV without a newline, move to the start of
9177 the line to satisfy the post-condition. */
9178 if (IT_CHARPOS (*it) == ZV
9179 && ZV > BEGV
9180 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9181 move_it_by_lines (it, 0);
9182 }
9183 }
9184
9185
9186 /* Move iterator IT past the end of the text line it is in. */
9187
9188 void
9189 move_it_past_eol (struct it *it)
9190 {
9191 enum move_it_result rc;
9192
9193 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9194 if (rc == MOVE_NEWLINE_OR_CR)
9195 set_iterator_to_next (it, 0);
9196 }
9197
9198
9199 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9200 negative means move up. DVPOS == 0 means move to the start of the
9201 screen line.
9202
9203 Optimization idea: If we would know that IT->f doesn't use
9204 a face with proportional font, we could be faster for
9205 truncate-lines nil. */
9206
9207 void
9208 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9209 {
9210
9211 /* The commented-out optimization uses vmotion on terminals. This
9212 gives bad results, because elements like it->what, on which
9213 callers such as pos_visible_p rely, aren't updated. */
9214 /* struct position pos;
9215 if (!FRAME_WINDOW_P (it->f))
9216 {
9217 struct text_pos textpos;
9218
9219 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9220 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9221 reseat (it, textpos, 1);
9222 it->vpos += pos.vpos;
9223 it->current_y += pos.vpos;
9224 }
9225 else */
9226
9227 if (dvpos == 0)
9228 {
9229 /* DVPOS == 0 means move to the start of the screen line. */
9230 move_it_vertically_backward (it, 0);
9231 /* Let next call to line_bottom_y calculate real line height */
9232 last_height = 0;
9233 }
9234 else if (dvpos > 0)
9235 {
9236 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9237 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9238 {
9239 /* Only move to the next buffer position if we ended up in a
9240 string from display property, not in an overlay string
9241 (before-string or after-string). That is because the
9242 latter don't conceal the underlying buffer position, so
9243 we can ask to move the iterator to the exact position we
9244 are interested in. Note that, even if we are already at
9245 IT_CHARPOS (*it), the call below is not a no-op, as it
9246 will detect that we are at the end of the string, pop the
9247 iterator, and compute it->current_x and it->hpos
9248 correctly. */
9249 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9250 -1, -1, -1, MOVE_TO_POS);
9251 }
9252 }
9253 else
9254 {
9255 struct it it2;
9256 void *it2data = NULL;
9257 ptrdiff_t start_charpos, i;
9258
9259 /* Start at the beginning of the screen line containing IT's
9260 position. This may actually move vertically backwards,
9261 in case of overlays, so adjust dvpos accordingly. */
9262 dvpos += it->vpos;
9263 move_it_vertically_backward (it, 0);
9264 dvpos -= it->vpos;
9265
9266 /* Go back -DVPOS visible lines and reseat the iterator there. */
9267 start_charpos = IT_CHARPOS (*it);
9268 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
9269 back_to_previous_visible_line_start (it);
9270 reseat (it, it->current.pos, 1);
9271
9272 /* Move further back if we end up in a string or an image. */
9273 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9274 {
9275 /* First try to move to start of display line. */
9276 dvpos += it->vpos;
9277 move_it_vertically_backward (it, 0);
9278 dvpos -= it->vpos;
9279 if (IT_POS_VALID_AFTER_MOVE_P (it))
9280 break;
9281 /* If start of line is still in string or image,
9282 move further back. */
9283 back_to_previous_visible_line_start (it);
9284 reseat (it, it->current.pos, 1);
9285 dvpos--;
9286 }
9287
9288 it->current_x = it->hpos = 0;
9289
9290 /* Above call may have moved too far if continuation lines
9291 are involved. Scan forward and see if it did. */
9292 SAVE_IT (it2, *it, it2data);
9293 it2.vpos = it2.current_y = 0;
9294 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9295 it->vpos -= it2.vpos;
9296 it->current_y -= it2.current_y;
9297 it->current_x = it->hpos = 0;
9298
9299 /* If we moved too far back, move IT some lines forward. */
9300 if (it2.vpos > -dvpos)
9301 {
9302 int delta = it2.vpos + dvpos;
9303
9304 RESTORE_IT (&it2, &it2, it2data);
9305 SAVE_IT (it2, *it, it2data);
9306 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9307 /* Move back again if we got too far ahead. */
9308 if (IT_CHARPOS (*it) >= start_charpos)
9309 RESTORE_IT (it, &it2, it2data);
9310 else
9311 bidi_unshelve_cache (it2data, 1);
9312 }
9313 else
9314 RESTORE_IT (it, it, it2data);
9315 }
9316 }
9317
9318 /* Return 1 if IT points into the middle of a display vector. */
9319
9320 int
9321 in_display_vector_p (struct it *it)
9322 {
9323 return (it->method == GET_FROM_DISPLAY_VECTOR
9324 && it->current.dpvec_index > 0
9325 && it->dpvec + it->current.dpvec_index != it->dpend);
9326 }
9327
9328 \f
9329 /***********************************************************************
9330 Messages
9331 ***********************************************************************/
9332
9333
9334 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9335 to *Messages*. */
9336
9337 void
9338 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9339 {
9340 Lisp_Object args[3];
9341 Lisp_Object msg, fmt;
9342 char *buffer;
9343 ptrdiff_t len;
9344 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9345 USE_SAFE_ALLOCA;
9346
9347 fmt = msg = Qnil;
9348 GCPRO4 (fmt, msg, arg1, arg2);
9349
9350 args[0] = fmt = build_string (format);
9351 args[1] = arg1;
9352 args[2] = arg2;
9353 msg = Fformat (3, args);
9354
9355 len = SBYTES (msg) + 1;
9356 buffer = SAFE_ALLOCA (len);
9357 memcpy (buffer, SDATA (msg), len);
9358
9359 message_dolog (buffer, len - 1, 1, 0);
9360 SAFE_FREE ();
9361
9362 UNGCPRO;
9363 }
9364
9365
9366 /* Output a newline in the *Messages* buffer if "needs" one. */
9367
9368 void
9369 message_log_maybe_newline (void)
9370 {
9371 if (message_log_need_newline)
9372 message_dolog ("", 0, 1, 0);
9373 }
9374
9375
9376 /* Add a string M of length NBYTES to the message log, optionally
9377 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
9378 nonzero, means interpret the contents of M as multibyte. This
9379 function calls low-level routines in order to bypass text property
9380 hooks, etc. which might not be safe to run.
9381
9382 This may GC (insert may run before/after change hooks),
9383 so the buffer M must NOT point to a Lisp string. */
9384
9385 void
9386 message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte)
9387 {
9388 const unsigned char *msg = (const unsigned char *) m;
9389
9390 if (!NILP (Vmemory_full))
9391 return;
9392
9393 if (!NILP (Vmessage_log_max))
9394 {
9395 struct buffer *oldbuf;
9396 Lisp_Object oldpoint, oldbegv, oldzv;
9397 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9398 ptrdiff_t point_at_end = 0;
9399 ptrdiff_t zv_at_end = 0;
9400 Lisp_Object old_deactivate_mark;
9401 bool shown;
9402 struct gcpro gcpro1;
9403
9404 old_deactivate_mark = Vdeactivate_mark;
9405 oldbuf = current_buffer;
9406 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9407 bset_undo_list (current_buffer, Qt);
9408
9409 oldpoint = message_dolog_marker1;
9410 set_marker_restricted (oldpoint, make_number (PT), Qnil);
9411 oldbegv = message_dolog_marker2;
9412 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
9413 oldzv = message_dolog_marker3;
9414 set_marker_restricted (oldzv, make_number (ZV), Qnil);
9415 GCPRO1 (old_deactivate_mark);
9416
9417 if (PT == Z)
9418 point_at_end = 1;
9419 if (ZV == Z)
9420 zv_at_end = 1;
9421
9422 BEGV = BEG;
9423 BEGV_BYTE = BEG_BYTE;
9424 ZV = Z;
9425 ZV_BYTE = Z_BYTE;
9426 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9427
9428 /* Insert the string--maybe converting multibyte to single byte
9429 or vice versa, so that all the text fits the buffer. */
9430 if (multibyte
9431 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9432 {
9433 ptrdiff_t i;
9434 int c, char_bytes;
9435 char work[1];
9436
9437 /* Convert a multibyte string to single-byte
9438 for the *Message* buffer. */
9439 for (i = 0; i < nbytes; i += char_bytes)
9440 {
9441 c = string_char_and_length (msg + i, &char_bytes);
9442 work[0] = (ASCII_CHAR_P (c)
9443 ? c
9444 : multibyte_char_to_unibyte (c));
9445 insert_1_both (work, 1, 1, 1, 0, 0);
9446 }
9447 }
9448 else if (! multibyte
9449 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9450 {
9451 ptrdiff_t i;
9452 int c, char_bytes;
9453 unsigned char str[MAX_MULTIBYTE_LENGTH];
9454 /* Convert a single-byte string to multibyte
9455 for the *Message* buffer. */
9456 for (i = 0; i < nbytes; i++)
9457 {
9458 c = msg[i];
9459 MAKE_CHAR_MULTIBYTE (c);
9460 char_bytes = CHAR_STRING (c, str);
9461 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9462 }
9463 }
9464 else if (nbytes)
9465 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9466
9467 if (nlflag)
9468 {
9469 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9470 printmax_t dups;
9471
9472 insert_1_both ("\n", 1, 1, 1, 0, 0);
9473
9474 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9475 this_bol = PT;
9476 this_bol_byte = PT_BYTE;
9477
9478 /* See if this line duplicates the previous one.
9479 If so, combine duplicates. */
9480 if (this_bol > BEG)
9481 {
9482 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9483 prev_bol = PT;
9484 prev_bol_byte = PT_BYTE;
9485
9486 dups = message_log_check_duplicate (prev_bol_byte,
9487 this_bol_byte);
9488 if (dups)
9489 {
9490 del_range_both (prev_bol, prev_bol_byte,
9491 this_bol, this_bol_byte, 0);
9492 if (dups > 1)
9493 {
9494 char dupstr[sizeof " [ times]"
9495 + INT_STRLEN_BOUND (printmax_t)];
9496
9497 /* If you change this format, don't forget to also
9498 change message_log_check_duplicate. */
9499 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9500 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9501 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9502 }
9503 }
9504 }
9505
9506 /* If we have more than the desired maximum number of lines
9507 in the *Messages* buffer now, delete the oldest ones.
9508 This is safe because we don't have undo in this buffer. */
9509
9510 if (NATNUMP (Vmessage_log_max))
9511 {
9512 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9513 -XFASTINT (Vmessage_log_max) - 1, 0);
9514 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9515 }
9516 }
9517 BEGV = marker_position (oldbegv);
9518 BEGV_BYTE = marker_byte_position (oldbegv);
9519
9520 if (zv_at_end)
9521 {
9522 ZV = Z;
9523 ZV_BYTE = Z_BYTE;
9524 }
9525 else
9526 {
9527 ZV = marker_position (oldzv);
9528 ZV_BYTE = marker_byte_position (oldzv);
9529 }
9530
9531 if (point_at_end)
9532 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9533 else
9534 /* We can't do Fgoto_char (oldpoint) because it will run some
9535 Lisp code. */
9536 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9537 marker_byte_position (oldpoint));
9538
9539 UNGCPRO;
9540 unchain_marker (XMARKER (oldpoint));
9541 unchain_marker (XMARKER (oldbegv));
9542 unchain_marker (XMARKER (oldzv));
9543
9544 shown = buffer_window_count (current_buffer) > 0;
9545 set_buffer_internal (oldbuf);
9546 if (!shown)
9547 windows_or_buffers_changed = old_windows_or_buffers_changed;
9548 message_log_need_newline = !nlflag;
9549 Vdeactivate_mark = old_deactivate_mark;
9550 }
9551 }
9552
9553
9554 /* We are at the end of the buffer after just having inserted a newline.
9555 (Note: We depend on the fact we won't be crossing the gap.)
9556 Check to see if the most recent message looks a lot like the previous one.
9557 Return 0 if different, 1 if the new one should just replace it, or a
9558 value N > 1 if we should also append " [N times]". */
9559
9560 static intmax_t
9561 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9562 {
9563 ptrdiff_t i;
9564 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9565 int seen_dots = 0;
9566 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9567 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9568
9569 for (i = 0; i < len; i++)
9570 {
9571 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9572 seen_dots = 1;
9573 if (p1[i] != p2[i])
9574 return seen_dots;
9575 }
9576 p1 += len;
9577 if (*p1 == '\n')
9578 return 2;
9579 if (*p1++ == ' ' && *p1++ == '[')
9580 {
9581 char *pend;
9582 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9583 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9584 return n + 1;
9585 }
9586 return 0;
9587 }
9588 \f
9589
9590 /* Display an echo area message M with a specified length of NBYTES
9591 bytes. The string may include null characters. If M is not a
9592 string, clear out any existing message, and let the mini-buffer
9593 text show through.
9594
9595 This function cancels echoing. */
9596
9597 void
9598 message3 (Lisp_Object m)
9599 {
9600 struct gcpro gcpro1;
9601
9602 GCPRO1 (m);
9603 clear_message (1,1);
9604 cancel_echoing ();
9605
9606 /* First flush out any partial line written with print. */
9607 message_log_maybe_newline ();
9608 if (STRINGP (m))
9609 {
9610 ptrdiff_t nbytes = SBYTES (m);
9611 int multibyte = STRING_MULTIBYTE (m);
9612 USE_SAFE_ALLOCA;
9613 char *buffer = SAFE_ALLOCA (nbytes);
9614 memcpy (buffer, SDATA (m), nbytes);
9615 message_dolog (buffer, nbytes, 1, multibyte);
9616 SAFE_FREE ();
9617 }
9618 message3_nolog (m);
9619
9620 UNGCPRO;
9621 }
9622
9623
9624 /* The non-logging version of message3.
9625 This does not cancel echoing, because it is used for echoing.
9626 Perhaps we need to make a separate function for echoing
9627 and make this cancel echoing. */
9628
9629 void
9630 message3_nolog (Lisp_Object m)
9631 {
9632 struct frame *sf = SELECTED_FRAME ();
9633
9634 if (FRAME_INITIAL_P (sf))
9635 {
9636 if (noninteractive_need_newline)
9637 putc ('\n', stderr);
9638 noninteractive_need_newline = 0;
9639 if (STRINGP (m))
9640 fwrite (SDATA (m), SBYTES (m), 1, stderr);
9641 if (cursor_in_echo_area == 0)
9642 fprintf (stderr, "\n");
9643 fflush (stderr);
9644 }
9645 /* Error messages get reported properly by cmd_error, so this must be just an
9646 informative message; if the frame hasn't really been initialized yet, just
9647 toss it. */
9648 else if (INTERACTIVE && sf->glyphs_initialized_p)
9649 {
9650 /* Get the frame containing the mini-buffer
9651 that the selected frame is using. */
9652 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9653 Lisp_Object frame = XWINDOW (mini_window)->frame;
9654 struct frame *f = XFRAME (frame);
9655
9656 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9657 Fmake_frame_visible (frame);
9658
9659 if (STRINGP (m) && SCHARS (m) > 0)
9660 {
9661 set_message (m);
9662 if (minibuffer_auto_raise)
9663 Fraise_frame (frame);
9664 /* Assume we are not echoing.
9665 (If we are, echo_now will override this.) */
9666 echo_message_buffer = Qnil;
9667 }
9668 else
9669 clear_message (1, 1);
9670
9671 do_pending_window_change (0);
9672 echo_area_display (1);
9673 do_pending_window_change (0);
9674 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9675 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9676 }
9677 }
9678
9679
9680 /* Display a null-terminated echo area message M. If M is 0, clear
9681 out any existing message, and let the mini-buffer text show through.
9682
9683 The buffer M must continue to exist until after the echo area gets
9684 cleared or some other message gets displayed there. Do not pass
9685 text that is stored in a Lisp string. Do not pass text in a buffer
9686 that was alloca'd. */
9687
9688 void
9689 message1 (const char *m)
9690 {
9691 message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil);
9692 }
9693
9694
9695 /* The non-logging counterpart of message1. */
9696
9697 void
9698 message1_nolog (const char *m)
9699 {
9700 message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil);
9701 }
9702
9703 /* Display a message M which contains a single %s
9704 which gets replaced with STRING. */
9705
9706 void
9707 message_with_string (const char *m, Lisp_Object string, int log)
9708 {
9709 CHECK_STRING (string);
9710
9711 if (noninteractive)
9712 {
9713 if (m)
9714 {
9715 if (noninteractive_need_newline)
9716 putc ('\n', stderr);
9717 noninteractive_need_newline = 0;
9718 fprintf (stderr, m, SDATA (string));
9719 if (!cursor_in_echo_area)
9720 fprintf (stderr, "\n");
9721 fflush (stderr);
9722 }
9723 }
9724 else if (INTERACTIVE)
9725 {
9726 /* The frame whose minibuffer we're going to display the message on.
9727 It may be larger than the selected frame, so we need
9728 to use its buffer, not the selected frame's buffer. */
9729 Lisp_Object mini_window;
9730 struct frame *f, *sf = SELECTED_FRAME ();
9731
9732 /* Get the frame containing the minibuffer
9733 that the selected frame is using. */
9734 mini_window = FRAME_MINIBUF_WINDOW (sf);
9735 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9736
9737 /* Error messages get reported properly by cmd_error, so this must be
9738 just an informative message; if the frame hasn't really been
9739 initialized yet, just toss it. */
9740 if (f->glyphs_initialized_p)
9741 {
9742 Lisp_Object args[2], msg;
9743 struct gcpro gcpro1, gcpro2;
9744
9745 args[0] = build_string (m);
9746 args[1] = msg = string;
9747 GCPRO2 (args[0], msg);
9748 gcpro1.nvars = 2;
9749
9750 msg = Fformat (2, args);
9751
9752 if (log)
9753 message3 (msg);
9754 else
9755 message3_nolog (msg);
9756
9757 UNGCPRO;
9758
9759 /* Print should start at the beginning of the message
9760 buffer next time. */
9761 message_buf_print = 0;
9762 }
9763 }
9764 }
9765
9766
9767 /* Dump an informative message to the minibuf. If M is 0, clear out
9768 any existing message, and let the mini-buffer text show through. */
9769
9770 static void
9771 vmessage (const char *m, va_list ap)
9772 {
9773 if (noninteractive)
9774 {
9775 if (m)
9776 {
9777 if (noninteractive_need_newline)
9778 putc ('\n', stderr);
9779 noninteractive_need_newline = 0;
9780 vfprintf (stderr, m, ap);
9781 if (cursor_in_echo_area == 0)
9782 fprintf (stderr, "\n");
9783 fflush (stderr);
9784 }
9785 }
9786 else if (INTERACTIVE)
9787 {
9788 /* The frame whose mini-buffer we're going to display the message
9789 on. It may be larger than the selected frame, so we need to
9790 use its buffer, not the selected frame's buffer. */
9791 Lisp_Object mini_window;
9792 struct frame *f, *sf = SELECTED_FRAME ();
9793
9794 /* Get the frame containing the mini-buffer
9795 that the selected frame is using. */
9796 mini_window = FRAME_MINIBUF_WINDOW (sf);
9797 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9798
9799 /* Error messages get reported properly by cmd_error, so this must be
9800 just an informative message; if the frame hasn't really been
9801 initialized yet, just toss it. */
9802 if (f->glyphs_initialized_p)
9803 {
9804 if (m)
9805 {
9806 ptrdiff_t len;
9807 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9808 char *message_buf = alloca (maxsize + 1);
9809
9810 len = doprnt (message_buf, maxsize, m, (char *)0, ap);
9811
9812 message3 (make_string (message_buf, len));
9813 }
9814 else
9815 message1 (0);
9816
9817 /* Print should start at the beginning of the message
9818 buffer next time. */
9819 message_buf_print = 0;
9820 }
9821 }
9822 }
9823
9824 void
9825 message (const char *m, ...)
9826 {
9827 va_list ap;
9828 va_start (ap, m);
9829 vmessage (m, ap);
9830 va_end (ap);
9831 }
9832
9833
9834 #if 0
9835 /* The non-logging version of message. */
9836
9837 void
9838 message_nolog (const char *m, ...)
9839 {
9840 Lisp_Object old_log_max;
9841 va_list ap;
9842 va_start (ap, m);
9843 old_log_max = Vmessage_log_max;
9844 Vmessage_log_max = Qnil;
9845 vmessage (m, ap);
9846 Vmessage_log_max = old_log_max;
9847 va_end (ap);
9848 }
9849 #endif
9850
9851
9852 /* Display the current message in the current mini-buffer. This is
9853 only called from error handlers in process.c, and is not time
9854 critical. */
9855
9856 void
9857 update_echo_area (void)
9858 {
9859 if (!NILP (echo_area_buffer[0]))
9860 {
9861 Lisp_Object string;
9862 string = Fcurrent_message ();
9863 message3 (string);
9864 }
9865 }
9866
9867
9868 /* Make sure echo area buffers in `echo_buffers' are live.
9869 If they aren't, make new ones. */
9870
9871 static void
9872 ensure_echo_area_buffers (void)
9873 {
9874 int i;
9875
9876 for (i = 0; i < 2; ++i)
9877 if (!BUFFERP (echo_buffer[i])
9878 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
9879 {
9880 char name[30];
9881 Lisp_Object old_buffer;
9882 int j;
9883
9884 old_buffer = echo_buffer[i];
9885 echo_buffer[i] = Fget_buffer_create
9886 (make_formatted_string (name, " *Echo Area %d*", i));
9887 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
9888 /* to force word wrap in echo area -
9889 it was decided to postpone this*/
9890 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9891
9892 for (j = 0; j < 2; ++j)
9893 if (EQ (old_buffer, echo_area_buffer[j]))
9894 echo_area_buffer[j] = echo_buffer[i];
9895 }
9896 }
9897
9898
9899 /* Call FN with args A1..A2 with either the current or last displayed
9900 echo_area_buffer as current buffer.
9901
9902 WHICH zero means use the current message buffer
9903 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9904 from echo_buffer[] and clear it.
9905
9906 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9907 suitable buffer from echo_buffer[] and clear it.
9908
9909 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9910 that the current message becomes the last displayed one, make
9911 choose a suitable buffer for echo_area_buffer[0], and clear it.
9912
9913 Value is what FN returns. */
9914
9915 static int
9916 with_echo_area_buffer (struct window *w, int which,
9917 int (*fn) (ptrdiff_t, Lisp_Object),
9918 ptrdiff_t a1, Lisp_Object a2)
9919 {
9920 Lisp_Object buffer;
9921 int this_one, the_other, clear_buffer_p, rc;
9922 ptrdiff_t count = SPECPDL_INDEX ();
9923
9924 /* If buffers aren't live, make new ones. */
9925 ensure_echo_area_buffers ();
9926
9927 clear_buffer_p = 0;
9928
9929 if (which == 0)
9930 this_one = 0, the_other = 1;
9931 else if (which > 0)
9932 this_one = 1, the_other = 0;
9933 else
9934 {
9935 this_one = 0, the_other = 1;
9936 clear_buffer_p = 1;
9937
9938 /* We need a fresh one in case the current echo buffer equals
9939 the one containing the last displayed echo area message. */
9940 if (!NILP (echo_area_buffer[this_one])
9941 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
9942 echo_area_buffer[this_one] = Qnil;
9943 }
9944
9945 /* Choose a suitable buffer from echo_buffer[] is we don't
9946 have one. */
9947 if (NILP (echo_area_buffer[this_one]))
9948 {
9949 echo_area_buffer[this_one]
9950 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
9951 ? echo_buffer[the_other]
9952 : echo_buffer[this_one]);
9953 clear_buffer_p = 1;
9954 }
9955
9956 buffer = echo_area_buffer[this_one];
9957
9958 /* Don't get confused by reusing the buffer used for echoing
9959 for a different purpose. */
9960 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
9961 cancel_echoing ();
9962
9963 record_unwind_protect (unwind_with_echo_area_buffer,
9964 with_echo_area_buffer_unwind_data (w));
9965
9966 /* Make the echo area buffer current. Note that for display
9967 purposes, it is not necessary that the displayed window's buffer
9968 == current_buffer, except for text property lookup. So, let's
9969 only set that buffer temporarily here without doing a full
9970 Fset_window_buffer. We must also change w->pointm, though,
9971 because otherwise an assertions in unshow_buffer fails, and Emacs
9972 aborts. */
9973 set_buffer_internal_1 (XBUFFER (buffer));
9974 if (w)
9975 {
9976 wset_buffer (w, buffer);
9977 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
9978 }
9979
9980 bset_undo_list (current_buffer, Qt);
9981 bset_read_only (current_buffer, Qnil);
9982 specbind (Qinhibit_read_only, Qt);
9983 specbind (Qinhibit_modification_hooks, Qt);
9984
9985 if (clear_buffer_p && Z > BEG)
9986 del_range (BEG, Z);
9987
9988 eassert (BEGV >= BEG);
9989 eassert (ZV <= Z && ZV >= BEGV);
9990
9991 rc = fn (a1, a2);
9992
9993 eassert (BEGV >= BEG);
9994 eassert (ZV <= Z && ZV >= BEGV);
9995
9996 unbind_to (count, Qnil);
9997 return rc;
9998 }
9999
10000
10001 /* Save state that should be preserved around the call to the function
10002 FN called in with_echo_area_buffer. */
10003
10004 static Lisp_Object
10005 with_echo_area_buffer_unwind_data (struct window *w)
10006 {
10007 int i = 0;
10008 Lisp_Object vector, tmp;
10009
10010 /* Reduce consing by keeping one vector in
10011 Vwith_echo_area_save_vector. */
10012 vector = Vwith_echo_area_save_vector;
10013 Vwith_echo_area_save_vector = Qnil;
10014
10015 if (NILP (vector))
10016 vector = Fmake_vector (make_number (7), Qnil);
10017
10018 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10019 ASET (vector, i, Vdeactivate_mark); ++i;
10020 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10021
10022 if (w)
10023 {
10024 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10025 ASET (vector, i, w->buffer); ++i;
10026 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10027 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10028 }
10029 else
10030 {
10031 int end = i + 4;
10032 for (; i < end; ++i)
10033 ASET (vector, i, Qnil);
10034 }
10035
10036 eassert (i == ASIZE (vector));
10037 return vector;
10038 }
10039
10040
10041 /* Restore global state from VECTOR which was created by
10042 with_echo_area_buffer_unwind_data. */
10043
10044 static Lisp_Object
10045 unwind_with_echo_area_buffer (Lisp_Object vector)
10046 {
10047 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10048 Vdeactivate_mark = AREF (vector, 1);
10049 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10050
10051 if (WINDOWP (AREF (vector, 3)))
10052 {
10053 struct window *w;
10054 Lisp_Object buffer, charpos, bytepos;
10055
10056 w = XWINDOW (AREF (vector, 3));
10057 buffer = AREF (vector, 4);
10058 charpos = AREF (vector, 5);
10059 bytepos = AREF (vector, 6);
10060
10061 wset_buffer (w, buffer);
10062 set_marker_both (w->pointm, buffer,
10063 XFASTINT (charpos), XFASTINT (bytepos));
10064 }
10065
10066 Vwith_echo_area_save_vector = vector;
10067 return Qnil;
10068 }
10069
10070
10071 /* Set up the echo area for use by print functions. MULTIBYTE_P
10072 non-zero means we will print multibyte. */
10073
10074 void
10075 setup_echo_area_for_printing (int multibyte_p)
10076 {
10077 /* If we can't find an echo area any more, exit. */
10078 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10079 Fkill_emacs (Qnil);
10080
10081 ensure_echo_area_buffers ();
10082
10083 if (!message_buf_print)
10084 {
10085 /* A message has been output since the last time we printed.
10086 Choose a fresh echo area buffer. */
10087 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10088 echo_area_buffer[0] = echo_buffer[1];
10089 else
10090 echo_area_buffer[0] = echo_buffer[0];
10091
10092 /* Switch to that buffer and clear it. */
10093 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10094 bset_truncate_lines (current_buffer, Qnil);
10095
10096 if (Z > BEG)
10097 {
10098 ptrdiff_t count = SPECPDL_INDEX ();
10099 specbind (Qinhibit_read_only, Qt);
10100 /* Note that undo recording is always disabled. */
10101 del_range (BEG, Z);
10102 unbind_to (count, Qnil);
10103 }
10104 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10105
10106 /* Set up the buffer for the multibyteness we need. */
10107 if (multibyte_p
10108 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10109 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10110
10111 /* Raise the frame containing the echo area. */
10112 if (minibuffer_auto_raise)
10113 {
10114 struct frame *sf = SELECTED_FRAME ();
10115 Lisp_Object mini_window;
10116 mini_window = FRAME_MINIBUF_WINDOW (sf);
10117 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10118 }
10119
10120 message_log_maybe_newline ();
10121 message_buf_print = 1;
10122 }
10123 else
10124 {
10125 if (NILP (echo_area_buffer[0]))
10126 {
10127 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10128 echo_area_buffer[0] = echo_buffer[1];
10129 else
10130 echo_area_buffer[0] = echo_buffer[0];
10131 }
10132
10133 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10134 {
10135 /* Someone switched buffers between print requests. */
10136 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10137 bset_truncate_lines (current_buffer, Qnil);
10138 }
10139 }
10140 }
10141
10142
10143 /* Display an echo area message in window W. Value is non-zero if W's
10144 height is changed. If display_last_displayed_message_p is
10145 non-zero, display the message that was last displayed, otherwise
10146 display the current message. */
10147
10148 static int
10149 display_echo_area (struct window *w)
10150 {
10151 int i, no_message_p, window_height_changed_p;
10152
10153 /* Temporarily disable garbage collections while displaying the echo
10154 area. This is done because a GC can print a message itself.
10155 That message would modify the echo area buffer's contents while a
10156 redisplay of the buffer is going on, and seriously confuse
10157 redisplay. */
10158 ptrdiff_t count = inhibit_garbage_collection ();
10159
10160 /* If there is no message, we must call display_echo_area_1
10161 nevertheless because it resizes the window. But we will have to
10162 reset the echo_area_buffer in question to nil at the end because
10163 with_echo_area_buffer will sets it to an empty buffer. */
10164 i = display_last_displayed_message_p ? 1 : 0;
10165 no_message_p = NILP (echo_area_buffer[i]);
10166
10167 window_height_changed_p
10168 = with_echo_area_buffer (w, display_last_displayed_message_p,
10169 display_echo_area_1,
10170 (intptr_t) w, Qnil);
10171
10172 if (no_message_p)
10173 echo_area_buffer[i] = Qnil;
10174
10175 unbind_to (count, Qnil);
10176 return window_height_changed_p;
10177 }
10178
10179
10180 /* Helper for display_echo_area. Display the current buffer which
10181 contains the current echo area message in window W, a mini-window,
10182 a pointer to which is passed in A1. A2..A4 are currently not used.
10183 Change the height of W so that all of the message is displayed.
10184 Value is non-zero if height of W was changed. */
10185
10186 static int
10187 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10188 {
10189 intptr_t i1 = a1;
10190 struct window *w = (struct window *) i1;
10191 Lisp_Object window;
10192 struct text_pos start;
10193 int window_height_changed_p = 0;
10194
10195 /* Do this before displaying, so that we have a large enough glyph
10196 matrix for the display. If we can't get enough space for the
10197 whole text, display the last N lines. That works by setting w->start. */
10198 window_height_changed_p = resize_mini_window (w, 0);
10199
10200 /* Use the starting position chosen by resize_mini_window. */
10201 SET_TEXT_POS_FROM_MARKER (start, w->start);
10202
10203 /* Display. */
10204 clear_glyph_matrix (w->desired_matrix);
10205 XSETWINDOW (window, w);
10206 try_window (window, start, 0);
10207
10208 return window_height_changed_p;
10209 }
10210
10211
10212 /* Resize the echo area window to exactly the size needed for the
10213 currently displayed message, if there is one. If a mini-buffer
10214 is active, don't shrink it. */
10215
10216 void
10217 resize_echo_area_exactly (void)
10218 {
10219 if (BUFFERP (echo_area_buffer[0])
10220 && WINDOWP (echo_area_window))
10221 {
10222 struct window *w = XWINDOW (echo_area_window);
10223 int resized_p;
10224 Lisp_Object resize_exactly;
10225
10226 if (minibuf_level == 0)
10227 resize_exactly = Qt;
10228 else
10229 resize_exactly = Qnil;
10230
10231 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10232 (intptr_t) w, resize_exactly);
10233 if (resized_p)
10234 {
10235 ++windows_or_buffers_changed;
10236 ++update_mode_lines;
10237 redisplay_internal ();
10238 }
10239 }
10240 }
10241
10242
10243 /* Callback function for with_echo_area_buffer, when used from
10244 resize_echo_area_exactly. A1 contains a pointer to the window to
10245 resize, EXACTLY non-nil means resize the mini-window exactly to the
10246 size of the text displayed. A3 and A4 are not used. Value is what
10247 resize_mini_window returns. */
10248
10249 static int
10250 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10251 {
10252 intptr_t i1 = a1;
10253 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10254 }
10255
10256
10257 /* Resize mini-window W to fit the size of its contents. EXACT_P
10258 means size the window exactly to the size needed. Otherwise, it's
10259 only enlarged until W's buffer is empty.
10260
10261 Set W->start to the right place to begin display. If the whole
10262 contents fit, start at the beginning. Otherwise, start so as
10263 to make the end of the contents appear. This is particularly
10264 important for y-or-n-p, but seems desirable generally.
10265
10266 Value is non-zero if the window height has been changed. */
10267
10268 int
10269 resize_mini_window (struct window *w, int exact_p)
10270 {
10271 struct frame *f = XFRAME (w->frame);
10272 int window_height_changed_p = 0;
10273
10274 eassert (MINI_WINDOW_P (w));
10275
10276 /* By default, start display at the beginning. */
10277 set_marker_both (w->start, w->buffer,
10278 BUF_BEGV (XBUFFER (w->buffer)),
10279 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
10280
10281 /* Don't resize windows while redisplaying a window; it would
10282 confuse redisplay functions when the size of the window they are
10283 displaying changes from under them. Such a resizing can happen,
10284 for instance, when which-func prints a long message while
10285 we are running fontification-functions. We're running these
10286 functions with safe_call which binds inhibit-redisplay to t. */
10287 if (!NILP (Vinhibit_redisplay))
10288 return 0;
10289
10290 /* Nil means don't try to resize. */
10291 if (NILP (Vresize_mini_windows)
10292 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10293 return 0;
10294
10295 if (!FRAME_MINIBUF_ONLY_P (f))
10296 {
10297 struct it it;
10298 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10299 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10300 int height;
10301 EMACS_INT max_height;
10302 int unit = FRAME_LINE_HEIGHT (f);
10303 struct text_pos start;
10304 struct buffer *old_current_buffer = NULL;
10305
10306 if (current_buffer != XBUFFER (w->buffer))
10307 {
10308 old_current_buffer = current_buffer;
10309 set_buffer_internal (XBUFFER (w->buffer));
10310 }
10311
10312 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10313
10314 /* Compute the max. number of lines specified by the user. */
10315 if (FLOATP (Vmax_mini_window_height))
10316 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10317 else if (INTEGERP (Vmax_mini_window_height))
10318 max_height = XINT (Vmax_mini_window_height);
10319 else
10320 max_height = total_height / 4;
10321
10322 /* Correct that max. height if it's bogus. */
10323 max_height = clip_to_bounds (1, max_height, total_height);
10324
10325 /* Find out the height of the text in the window. */
10326 if (it.line_wrap == TRUNCATE)
10327 height = 1;
10328 else
10329 {
10330 last_height = 0;
10331 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10332 if (it.max_ascent == 0 && it.max_descent == 0)
10333 height = it.current_y + last_height;
10334 else
10335 height = it.current_y + it.max_ascent + it.max_descent;
10336 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10337 height = (height + unit - 1) / unit;
10338 }
10339
10340 /* Compute a suitable window start. */
10341 if (height > max_height)
10342 {
10343 height = max_height;
10344 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10345 move_it_vertically_backward (&it, (height - 1) * unit);
10346 start = it.current.pos;
10347 }
10348 else
10349 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10350 SET_MARKER_FROM_TEXT_POS (w->start, start);
10351
10352 if (EQ (Vresize_mini_windows, Qgrow_only))
10353 {
10354 /* Let it grow only, until we display an empty message, in which
10355 case the window shrinks again. */
10356 if (height > WINDOW_TOTAL_LINES (w))
10357 {
10358 int old_height = WINDOW_TOTAL_LINES (w);
10359 freeze_window_starts (f, 1);
10360 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10361 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10362 }
10363 else if (height < WINDOW_TOTAL_LINES (w)
10364 && (exact_p || BEGV == ZV))
10365 {
10366 int old_height = WINDOW_TOTAL_LINES (w);
10367 freeze_window_starts (f, 0);
10368 shrink_mini_window (w);
10369 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10370 }
10371 }
10372 else
10373 {
10374 /* Always resize to exact size needed. */
10375 if (height > WINDOW_TOTAL_LINES (w))
10376 {
10377 int old_height = WINDOW_TOTAL_LINES (w);
10378 freeze_window_starts (f, 1);
10379 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10380 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10381 }
10382 else if (height < WINDOW_TOTAL_LINES (w))
10383 {
10384 int old_height = WINDOW_TOTAL_LINES (w);
10385 freeze_window_starts (f, 0);
10386 shrink_mini_window (w);
10387
10388 if (height)
10389 {
10390 freeze_window_starts (f, 1);
10391 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10392 }
10393
10394 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10395 }
10396 }
10397
10398 if (old_current_buffer)
10399 set_buffer_internal (old_current_buffer);
10400 }
10401
10402 return window_height_changed_p;
10403 }
10404
10405
10406 /* Value is the current message, a string, or nil if there is no
10407 current message. */
10408
10409 Lisp_Object
10410 current_message (void)
10411 {
10412 Lisp_Object msg;
10413
10414 if (!BUFFERP (echo_area_buffer[0]))
10415 msg = Qnil;
10416 else
10417 {
10418 with_echo_area_buffer (0, 0, current_message_1,
10419 (intptr_t) &msg, Qnil);
10420 if (NILP (msg))
10421 echo_area_buffer[0] = Qnil;
10422 }
10423
10424 return msg;
10425 }
10426
10427
10428 static int
10429 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10430 {
10431 intptr_t i1 = a1;
10432 Lisp_Object *msg = (Lisp_Object *) i1;
10433
10434 if (Z > BEG)
10435 *msg = make_buffer_string (BEG, Z, 1);
10436 else
10437 *msg = Qnil;
10438 return 0;
10439 }
10440
10441
10442 /* Push the current message on Vmessage_stack for later restoration
10443 by restore_message. Value is non-zero if the current message isn't
10444 empty. This is a relatively infrequent operation, so it's not
10445 worth optimizing. */
10446
10447 bool
10448 push_message (void)
10449 {
10450 Lisp_Object msg = current_message ();
10451 Vmessage_stack = Fcons (msg, Vmessage_stack);
10452 return STRINGP (msg);
10453 }
10454
10455
10456 /* Restore message display from the top of Vmessage_stack. */
10457
10458 void
10459 restore_message (void)
10460 {
10461 eassert (CONSP (Vmessage_stack));
10462 message3_nolog (XCAR (Vmessage_stack));
10463 }
10464
10465
10466 /* Handler for record_unwind_protect calling pop_message. */
10467
10468 Lisp_Object
10469 pop_message_unwind (Lisp_Object dummy)
10470 {
10471 pop_message ();
10472 return Qnil;
10473 }
10474
10475 /* Pop the top-most entry off Vmessage_stack. */
10476
10477 static void
10478 pop_message (void)
10479 {
10480 eassert (CONSP (Vmessage_stack));
10481 Vmessage_stack = XCDR (Vmessage_stack);
10482 }
10483
10484
10485 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10486 exits. If the stack is not empty, we have a missing pop_message
10487 somewhere. */
10488
10489 void
10490 check_message_stack (void)
10491 {
10492 if (!NILP (Vmessage_stack))
10493 emacs_abort ();
10494 }
10495
10496
10497 /* Truncate to NCHARS what will be displayed in the echo area the next
10498 time we display it---but don't redisplay it now. */
10499
10500 void
10501 truncate_echo_area (ptrdiff_t nchars)
10502 {
10503 if (nchars == 0)
10504 echo_area_buffer[0] = Qnil;
10505 else if (!noninteractive
10506 && INTERACTIVE
10507 && !NILP (echo_area_buffer[0]))
10508 {
10509 struct frame *sf = SELECTED_FRAME ();
10510 /* Error messages get reported properly by cmd_error, so this must be
10511 just an informative message; if the frame hasn't really been
10512 initialized yet, just toss it. */
10513 if (sf->glyphs_initialized_p)
10514 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10515 }
10516 }
10517
10518
10519 /* Helper function for truncate_echo_area. Truncate the current
10520 message to at most NCHARS characters. */
10521
10522 static int
10523 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10524 {
10525 if (BEG + nchars < Z)
10526 del_range (BEG + nchars, Z);
10527 if (Z == BEG)
10528 echo_area_buffer[0] = Qnil;
10529 return 0;
10530 }
10531
10532 /* Set the current message to STRING. */
10533
10534 static void
10535 set_message (Lisp_Object string)
10536 {
10537 eassert (STRINGP (string));
10538
10539 message_enable_multibyte = STRING_MULTIBYTE (string);
10540
10541 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10542 message_buf_print = 0;
10543 help_echo_showing_p = 0;
10544
10545 if (STRINGP (Vdebug_on_message)
10546 && fast_string_match (Vdebug_on_message, string) >= 0)
10547 call_debugger (list2 (Qerror, string));
10548 }
10549
10550
10551 /* Helper function for set_message. First argument is ignored and second
10552 argument has the same meaning as for set_message.
10553 This function is called with the echo area buffer being current. */
10554
10555 static int
10556 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10557 {
10558 eassert (STRINGP (string));
10559
10560 /* Change multibyteness of the echo buffer appropriately. */
10561 if (message_enable_multibyte
10562 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10563 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10564
10565 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10566 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10567 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10568
10569 /* Insert new message at BEG. */
10570 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10571
10572 /* This function takes care of single/multibyte conversion.
10573 We just have to ensure that the echo area buffer has the right
10574 setting of enable_multibyte_characters. */
10575 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10576
10577 return 0;
10578 }
10579
10580
10581 /* Clear messages. CURRENT_P non-zero means clear the current
10582 message. LAST_DISPLAYED_P non-zero means clear the message
10583 last displayed. */
10584
10585 void
10586 clear_message (int current_p, int last_displayed_p)
10587 {
10588 if (current_p)
10589 {
10590 echo_area_buffer[0] = Qnil;
10591 message_cleared_p = 1;
10592 }
10593
10594 if (last_displayed_p)
10595 echo_area_buffer[1] = Qnil;
10596
10597 message_buf_print = 0;
10598 }
10599
10600 /* Clear garbaged frames.
10601
10602 This function is used where the old redisplay called
10603 redraw_garbaged_frames which in turn called redraw_frame which in
10604 turn called clear_frame. The call to clear_frame was a source of
10605 flickering. I believe a clear_frame is not necessary. It should
10606 suffice in the new redisplay to invalidate all current matrices,
10607 and ensure a complete redisplay of all windows. */
10608
10609 static void
10610 clear_garbaged_frames (void)
10611 {
10612 if (frame_garbaged)
10613 {
10614 Lisp_Object tail, frame;
10615 int changed_count = 0;
10616
10617 FOR_EACH_FRAME (tail, frame)
10618 {
10619 struct frame *f = XFRAME (frame);
10620
10621 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10622 {
10623 if (f->resized_p)
10624 {
10625 redraw_frame (f);
10626 f->force_flush_display_p = 1;
10627 }
10628 clear_current_matrices (f);
10629 changed_count++;
10630 f->garbaged = 0;
10631 f->resized_p = 0;
10632 }
10633 }
10634
10635 frame_garbaged = 0;
10636 if (changed_count)
10637 ++windows_or_buffers_changed;
10638 }
10639 }
10640
10641
10642 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10643 is non-zero update selected_frame. Value is non-zero if the
10644 mini-windows height has been changed. */
10645
10646 static int
10647 echo_area_display (int update_frame_p)
10648 {
10649 Lisp_Object mini_window;
10650 struct window *w;
10651 struct frame *f;
10652 int window_height_changed_p = 0;
10653 struct frame *sf = SELECTED_FRAME ();
10654
10655 mini_window = FRAME_MINIBUF_WINDOW (sf);
10656 w = XWINDOW (mini_window);
10657 f = XFRAME (WINDOW_FRAME (w));
10658
10659 /* Don't display if frame is invisible or not yet initialized. */
10660 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10661 return 0;
10662
10663 #ifdef HAVE_WINDOW_SYSTEM
10664 /* When Emacs starts, selected_frame may be the initial terminal
10665 frame. If we let this through, a message would be displayed on
10666 the terminal. */
10667 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10668 return 0;
10669 #endif /* HAVE_WINDOW_SYSTEM */
10670
10671 /* Redraw garbaged frames. */
10672 clear_garbaged_frames ();
10673
10674 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10675 {
10676 echo_area_window = mini_window;
10677 window_height_changed_p = display_echo_area (w);
10678 w->must_be_updated_p = 1;
10679
10680 /* Update the display, unless called from redisplay_internal.
10681 Also don't update the screen during redisplay itself. The
10682 update will happen at the end of redisplay, and an update
10683 here could cause confusion. */
10684 if (update_frame_p && !redisplaying_p)
10685 {
10686 int n = 0;
10687
10688 /* If the display update has been interrupted by pending
10689 input, update mode lines in the frame. Due to the
10690 pending input, it might have been that redisplay hasn't
10691 been called, so that mode lines above the echo area are
10692 garbaged. This looks odd, so we prevent it here. */
10693 if (!display_completed)
10694 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10695
10696 if (window_height_changed_p
10697 /* Don't do this if Emacs is shutting down. Redisplay
10698 needs to run hooks. */
10699 && !NILP (Vrun_hooks))
10700 {
10701 /* Must update other windows. Likewise as in other
10702 cases, don't let this update be interrupted by
10703 pending input. */
10704 ptrdiff_t count = SPECPDL_INDEX ();
10705 specbind (Qredisplay_dont_pause, Qt);
10706 windows_or_buffers_changed = 1;
10707 redisplay_internal ();
10708 unbind_to (count, Qnil);
10709 }
10710 else if (FRAME_WINDOW_P (f) && n == 0)
10711 {
10712 /* Window configuration is the same as before.
10713 Can do with a display update of the echo area,
10714 unless we displayed some mode lines. */
10715 update_single_window (w, 1);
10716 FRAME_RIF (f)->flush_display (f);
10717 }
10718 else
10719 update_frame (f, 1, 1);
10720
10721 /* If cursor is in the echo area, make sure that the next
10722 redisplay displays the minibuffer, so that the cursor will
10723 be replaced with what the minibuffer wants. */
10724 if (cursor_in_echo_area)
10725 ++windows_or_buffers_changed;
10726 }
10727 }
10728 else if (!EQ (mini_window, selected_window))
10729 windows_or_buffers_changed++;
10730
10731 /* Last displayed message is now the current message. */
10732 echo_area_buffer[1] = echo_area_buffer[0];
10733 /* Inform read_char that we're not echoing. */
10734 echo_message_buffer = Qnil;
10735
10736 /* Prevent redisplay optimization in redisplay_internal by resetting
10737 this_line_start_pos. This is done because the mini-buffer now
10738 displays the message instead of its buffer text. */
10739 if (EQ (mini_window, selected_window))
10740 CHARPOS (this_line_start_pos) = 0;
10741
10742 return window_height_changed_p;
10743 }
10744
10745 /* Nonzero if the current window's buffer is shown in more than one
10746 window and was modified since last redisplay. */
10747
10748 static int
10749 buffer_shared_and_changed (void)
10750 {
10751 return (buffer_window_count (current_buffer) > 1
10752 && UNCHANGED_MODIFIED < MODIFF);
10753 }
10754
10755 /* Nonzero if W doesn't reflect the actual state of current buffer due
10756 to its text or overlays change. FIXME: this may be called when
10757 XBUFFER (w->buffer) != current_buffer, which looks suspicious. */
10758
10759 static int
10760 window_outdated (struct window *w)
10761 {
10762 return (w->last_modified < MODIFF
10763 || w->last_overlay_modified < OVERLAY_MODIFF);
10764 }
10765
10766 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10767 is enabled and mark of W's buffer was changed since last W's update. */
10768
10769 static int
10770 window_buffer_changed (struct window *w)
10771 {
10772 struct buffer *b = XBUFFER (w->buffer);
10773
10774 eassert (BUFFER_LIVE_P (b));
10775
10776 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10777 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10778 != !NILP (w->region_showing)));
10779 }
10780
10781 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10782
10783 static int
10784 mode_line_update_needed (struct window *w)
10785 {
10786 return (!NILP (w->column_number_displayed)
10787 && !(PT == w->last_point && !window_outdated (w))
10788 && (XFASTINT (w->column_number_displayed) != current_column ()));
10789 }
10790
10791 /***********************************************************************
10792 Mode Lines and Frame Titles
10793 ***********************************************************************/
10794
10795 /* A buffer for constructing non-propertized mode-line strings and
10796 frame titles in it; allocated from the heap in init_xdisp and
10797 resized as needed in store_mode_line_noprop_char. */
10798
10799 static char *mode_line_noprop_buf;
10800
10801 /* The buffer's end, and a current output position in it. */
10802
10803 static char *mode_line_noprop_buf_end;
10804 static char *mode_line_noprop_ptr;
10805
10806 #define MODE_LINE_NOPROP_LEN(start) \
10807 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10808
10809 static enum {
10810 MODE_LINE_DISPLAY = 0,
10811 MODE_LINE_TITLE,
10812 MODE_LINE_NOPROP,
10813 MODE_LINE_STRING
10814 } mode_line_target;
10815
10816 /* Alist that caches the results of :propertize.
10817 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10818 static Lisp_Object mode_line_proptrans_alist;
10819
10820 /* List of strings making up the mode-line. */
10821 static Lisp_Object mode_line_string_list;
10822
10823 /* Base face property when building propertized mode line string. */
10824 static Lisp_Object mode_line_string_face;
10825 static Lisp_Object mode_line_string_face_prop;
10826
10827
10828 /* Unwind data for mode line strings */
10829
10830 static Lisp_Object Vmode_line_unwind_vector;
10831
10832 static Lisp_Object
10833 format_mode_line_unwind_data (struct frame *target_frame,
10834 struct buffer *obuf,
10835 Lisp_Object owin,
10836 int save_proptrans)
10837 {
10838 Lisp_Object vector, tmp;
10839
10840 /* Reduce consing by keeping one vector in
10841 Vwith_echo_area_save_vector. */
10842 vector = Vmode_line_unwind_vector;
10843 Vmode_line_unwind_vector = Qnil;
10844
10845 if (NILP (vector))
10846 vector = Fmake_vector (make_number (10), Qnil);
10847
10848 ASET (vector, 0, make_number (mode_line_target));
10849 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10850 ASET (vector, 2, mode_line_string_list);
10851 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10852 ASET (vector, 4, mode_line_string_face);
10853 ASET (vector, 5, mode_line_string_face_prop);
10854
10855 if (obuf)
10856 XSETBUFFER (tmp, obuf);
10857 else
10858 tmp = Qnil;
10859 ASET (vector, 6, tmp);
10860 ASET (vector, 7, owin);
10861 if (target_frame)
10862 {
10863 /* Similarly to `with-selected-window', if the operation selects
10864 a window on another frame, we must restore that frame's
10865 selected window, and (for a tty) the top-frame. */
10866 ASET (vector, 8, target_frame->selected_window);
10867 if (FRAME_TERMCAP_P (target_frame))
10868 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
10869 }
10870
10871 return vector;
10872 }
10873
10874 static Lisp_Object
10875 unwind_format_mode_line (Lisp_Object vector)
10876 {
10877 Lisp_Object old_window = AREF (vector, 7);
10878 Lisp_Object target_frame_window = AREF (vector, 8);
10879 Lisp_Object old_top_frame = AREF (vector, 9);
10880
10881 mode_line_target = XINT (AREF (vector, 0));
10882 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10883 mode_line_string_list = AREF (vector, 2);
10884 if (! EQ (AREF (vector, 3), Qt))
10885 mode_line_proptrans_alist = AREF (vector, 3);
10886 mode_line_string_face = AREF (vector, 4);
10887 mode_line_string_face_prop = AREF (vector, 5);
10888
10889 /* Select window before buffer, since it may change the buffer. */
10890 if (!NILP (old_window))
10891 {
10892 /* If the operation that we are unwinding had selected a window
10893 on a different frame, reset its frame-selected-window. For a
10894 text terminal, reset its top-frame if necessary. */
10895 if (!NILP (target_frame_window))
10896 {
10897 Lisp_Object frame
10898 = WINDOW_FRAME (XWINDOW (target_frame_window));
10899
10900 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
10901 Fselect_window (target_frame_window, Qt);
10902
10903 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
10904 Fselect_frame (old_top_frame, Qt);
10905 }
10906
10907 Fselect_window (old_window, Qt);
10908 }
10909
10910 if (!NILP (AREF (vector, 6)))
10911 {
10912 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
10913 ASET (vector, 6, Qnil);
10914 }
10915
10916 Vmode_line_unwind_vector = vector;
10917 return Qnil;
10918 }
10919
10920
10921 /* Store a single character C for the frame title in mode_line_noprop_buf.
10922 Re-allocate mode_line_noprop_buf if necessary. */
10923
10924 static void
10925 store_mode_line_noprop_char (char c)
10926 {
10927 /* If output position has reached the end of the allocated buffer,
10928 increase the buffer's size. */
10929 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
10930 {
10931 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
10932 ptrdiff_t size = len;
10933 mode_line_noprop_buf =
10934 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
10935 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
10936 mode_line_noprop_ptr = mode_line_noprop_buf + len;
10937 }
10938
10939 *mode_line_noprop_ptr++ = c;
10940 }
10941
10942
10943 /* Store part of a frame title in mode_line_noprop_buf, beginning at
10944 mode_line_noprop_ptr. STRING is the string to store. Do not copy
10945 characters that yield more columns than PRECISION; PRECISION <= 0
10946 means copy the whole string. Pad with spaces until FIELD_WIDTH
10947 number of characters have been copied; FIELD_WIDTH <= 0 means don't
10948 pad. Called from display_mode_element when it is used to build a
10949 frame title. */
10950
10951 static int
10952 store_mode_line_noprop (const char *string, int field_width, int precision)
10953 {
10954 const unsigned char *str = (const unsigned char *) string;
10955 int n = 0;
10956 ptrdiff_t dummy, nbytes;
10957
10958 /* Copy at most PRECISION chars from STR. */
10959 nbytes = strlen (string);
10960 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
10961 while (nbytes--)
10962 store_mode_line_noprop_char (*str++);
10963
10964 /* Fill up with spaces until FIELD_WIDTH reached. */
10965 while (field_width > 0
10966 && n < field_width)
10967 {
10968 store_mode_line_noprop_char (' ');
10969 ++n;
10970 }
10971
10972 return n;
10973 }
10974
10975 /***********************************************************************
10976 Frame Titles
10977 ***********************************************************************/
10978
10979 #ifdef HAVE_WINDOW_SYSTEM
10980
10981 /* Set the title of FRAME, if it has changed. The title format is
10982 Vicon_title_format if FRAME is iconified, otherwise it is
10983 frame_title_format. */
10984
10985 static void
10986 x_consider_frame_title (Lisp_Object frame)
10987 {
10988 struct frame *f = XFRAME (frame);
10989
10990 if (FRAME_WINDOW_P (f)
10991 || FRAME_MINIBUF_ONLY_P (f)
10992 || f->explicit_name)
10993 {
10994 /* Do we have more than one visible frame on this X display? */
10995 Lisp_Object tail, other_frame, fmt;
10996 ptrdiff_t title_start;
10997 char *title;
10998 ptrdiff_t len;
10999 struct it it;
11000 ptrdiff_t count = SPECPDL_INDEX ();
11001
11002 FOR_EACH_FRAME (tail, other_frame)
11003 {
11004 struct frame *tf = XFRAME (other_frame);
11005
11006 if (tf != f
11007 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11008 && !FRAME_MINIBUF_ONLY_P (tf)
11009 && !EQ (other_frame, tip_frame)
11010 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11011 break;
11012 }
11013
11014 /* Set global variable indicating that multiple frames exist. */
11015 multiple_frames = CONSP (tail);
11016
11017 /* Switch to the buffer of selected window of the frame. Set up
11018 mode_line_target so that display_mode_element will output into
11019 mode_line_noprop_buf; then display the title. */
11020 record_unwind_protect (unwind_format_mode_line,
11021 format_mode_line_unwind_data
11022 (f, current_buffer, selected_window, 0));
11023
11024 Fselect_window (f->selected_window, Qt);
11025 set_buffer_internal_1
11026 (XBUFFER (XWINDOW (f->selected_window)->buffer));
11027 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11028
11029 mode_line_target = MODE_LINE_TITLE;
11030 title_start = MODE_LINE_NOPROP_LEN (0);
11031 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11032 NULL, DEFAULT_FACE_ID);
11033 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11034 len = MODE_LINE_NOPROP_LEN (title_start);
11035 title = mode_line_noprop_buf + title_start;
11036 unbind_to (count, Qnil);
11037
11038 /* Set the title only if it's changed. This avoids consing in
11039 the common case where it hasn't. (If it turns out that we've
11040 already wasted too much time by walking through the list with
11041 display_mode_element, then we might need to optimize at a
11042 higher level than this.) */
11043 if (! STRINGP (f->name)
11044 || SBYTES (f->name) != len
11045 || memcmp (title, SDATA (f->name), len) != 0)
11046 x_implicitly_set_name (f, make_string (title, len), Qnil);
11047 }
11048 }
11049
11050 #endif /* not HAVE_WINDOW_SYSTEM */
11051
11052 \f
11053 /***********************************************************************
11054 Menu Bars
11055 ***********************************************************************/
11056
11057
11058 /* Prepare for redisplay by updating menu-bar item lists when
11059 appropriate. This can call eval. */
11060
11061 void
11062 prepare_menu_bars (void)
11063 {
11064 int all_windows;
11065 struct gcpro gcpro1, gcpro2;
11066 struct frame *f;
11067 Lisp_Object tooltip_frame;
11068
11069 #ifdef HAVE_WINDOW_SYSTEM
11070 tooltip_frame = tip_frame;
11071 #else
11072 tooltip_frame = Qnil;
11073 #endif
11074
11075 /* Update all frame titles based on their buffer names, etc. We do
11076 this before the menu bars so that the buffer-menu will show the
11077 up-to-date frame titles. */
11078 #ifdef HAVE_WINDOW_SYSTEM
11079 if (windows_or_buffers_changed || update_mode_lines)
11080 {
11081 Lisp_Object tail, frame;
11082
11083 FOR_EACH_FRAME (tail, frame)
11084 {
11085 f = XFRAME (frame);
11086 if (!EQ (frame, tooltip_frame)
11087 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
11088 x_consider_frame_title (frame);
11089 }
11090 }
11091 #endif /* HAVE_WINDOW_SYSTEM */
11092
11093 /* Update the menu bar item lists, if appropriate. This has to be
11094 done before any actual redisplay or generation of display lines. */
11095 all_windows = (update_mode_lines
11096 || buffer_shared_and_changed ()
11097 || windows_or_buffers_changed);
11098 if (all_windows)
11099 {
11100 Lisp_Object tail, frame;
11101 ptrdiff_t count = SPECPDL_INDEX ();
11102 /* 1 means that update_menu_bar has run its hooks
11103 so any further calls to update_menu_bar shouldn't do so again. */
11104 int menu_bar_hooks_run = 0;
11105
11106 record_unwind_save_match_data ();
11107
11108 FOR_EACH_FRAME (tail, frame)
11109 {
11110 f = XFRAME (frame);
11111
11112 /* Ignore tooltip frame. */
11113 if (EQ (frame, tooltip_frame))
11114 continue;
11115
11116 /* If a window on this frame changed size, report that to
11117 the user and clear the size-change flag. */
11118 if (FRAME_WINDOW_SIZES_CHANGED (f))
11119 {
11120 Lisp_Object functions;
11121
11122 /* Clear flag first in case we get an error below. */
11123 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11124 functions = Vwindow_size_change_functions;
11125 GCPRO2 (tail, functions);
11126
11127 while (CONSP (functions))
11128 {
11129 if (!EQ (XCAR (functions), Qt))
11130 call1 (XCAR (functions), frame);
11131 functions = XCDR (functions);
11132 }
11133 UNGCPRO;
11134 }
11135
11136 GCPRO1 (tail);
11137 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11138 #ifdef HAVE_WINDOW_SYSTEM
11139 update_tool_bar (f, 0);
11140 #endif
11141 #ifdef HAVE_NS
11142 if (windows_or_buffers_changed
11143 && FRAME_NS_P (f))
11144 ns_set_doc_edited
11145 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->buffer));
11146 #endif
11147 UNGCPRO;
11148 }
11149
11150 unbind_to (count, Qnil);
11151 }
11152 else
11153 {
11154 struct frame *sf = SELECTED_FRAME ();
11155 update_menu_bar (sf, 1, 0);
11156 #ifdef HAVE_WINDOW_SYSTEM
11157 update_tool_bar (sf, 1);
11158 #endif
11159 }
11160 }
11161
11162
11163 /* Update the menu bar item list for frame F. This has to be done
11164 before we start to fill in any display lines, because it can call
11165 eval.
11166
11167 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11168
11169 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11170 already ran the menu bar hooks for this redisplay, so there
11171 is no need to run them again. The return value is the
11172 updated value of this flag, to pass to the next call. */
11173
11174 static int
11175 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11176 {
11177 Lisp_Object window;
11178 register struct window *w;
11179
11180 /* If called recursively during a menu update, do nothing. This can
11181 happen when, for instance, an activate-menubar-hook causes a
11182 redisplay. */
11183 if (inhibit_menubar_update)
11184 return hooks_run;
11185
11186 window = FRAME_SELECTED_WINDOW (f);
11187 w = XWINDOW (window);
11188
11189 if (FRAME_WINDOW_P (f)
11190 ?
11191 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11192 || defined (HAVE_NS) || defined (USE_GTK)
11193 FRAME_EXTERNAL_MENU_BAR (f)
11194 #else
11195 FRAME_MENU_BAR_LINES (f) > 0
11196 #endif
11197 : FRAME_MENU_BAR_LINES (f) > 0)
11198 {
11199 /* If the user has switched buffers or windows, we need to
11200 recompute to reflect the new bindings. But we'll
11201 recompute when update_mode_lines is set too; that means
11202 that people can use force-mode-line-update to request
11203 that the menu bar be recomputed. The adverse effect on
11204 the rest of the redisplay algorithm is about the same as
11205 windows_or_buffers_changed anyway. */
11206 if (windows_or_buffers_changed
11207 /* This used to test w->update_mode_line, but we believe
11208 there is no need to recompute the menu in that case. */
11209 || update_mode_lines
11210 || window_buffer_changed (w))
11211 {
11212 struct buffer *prev = current_buffer;
11213 ptrdiff_t count = SPECPDL_INDEX ();
11214
11215 specbind (Qinhibit_menubar_update, Qt);
11216
11217 set_buffer_internal_1 (XBUFFER (w->buffer));
11218 if (save_match_data)
11219 record_unwind_save_match_data ();
11220 if (NILP (Voverriding_local_map_menu_flag))
11221 {
11222 specbind (Qoverriding_terminal_local_map, Qnil);
11223 specbind (Qoverriding_local_map, Qnil);
11224 }
11225
11226 if (!hooks_run)
11227 {
11228 /* Run the Lucid hook. */
11229 safe_run_hooks (Qactivate_menubar_hook);
11230
11231 /* If it has changed current-menubar from previous value,
11232 really recompute the menu-bar from the value. */
11233 if (! NILP (Vlucid_menu_bar_dirty_flag))
11234 call0 (Qrecompute_lucid_menubar);
11235
11236 safe_run_hooks (Qmenu_bar_update_hook);
11237
11238 hooks_run = 1;
11239 }
11240
11241 XSETFRAME (Vmenu_updating_frame, f);
11242 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11243
11244 /* Redisplay the menu bar in case we changed it. */
11245 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11246 || defined (HAVE_NS) || defined (USE_GTK)
11247 if (FRAME_WINDOW_P (f))
11248 {
11249 #if defined (HAVE_NS)
11250 /* All frames on Mac OS share the same menubar. So only
11251 the selected frame should be allowed to set it. */
11252 if (f == SELECTED_FRAME ())
11253 #endif
11254 set_frame_menubar (f, 0, 0);
11255 }
11256 else
11257 /* On a terminal screen, the menu bar is an ordinary screen
11258 line, and this makes it get updated. */
11259 w->update_mode_line = 1;
11260 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11261 /* In the non-toolkit version, the menu bar is an ordinary screen
11262 line, and this makes it get updated. */
11263 w->update_mode_line = 1;
11264 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11265
11266 unbind_to (count, Qnil);
11267 set_buffer_internal_1 (prev);
11268 }
11269 }
11270
11271 return hooks_run;
11272 }
11273
11274
11275 \f
11276 /***********************************************************************
11277 Output Cursor
11278 ***********************************************************************/
11279
11280 #ifdef HAVE_WINDOW_SYSTEM
11281
11282 /* EXPORT:
11283 Nominal cursor position -- where to draw output.
11284 HPOS and VPOS are window relative glyph matrix coordinates.
11285 X and Y are window relative pixel coordinates. */
11286
11287 struct cursor_pos output_cursor;
11288
11289
11290 /* EXPORT:
11291 Set the global variable output_cursor to CURSOR. All cursor
11292 positions are relative to updated_window. */
11293
11294 void
11295 set_output_cursor (struct cursor_pos *cursor)
11296 {
11297 output_cursor.hpos = cursor->hpos;
11298 output_cursor.vpos = cursor->vpos;
11299 output_cursor.x = cursor->x;
11300 output_cursor.y = cursor->y;
11301 }
11302
11303
11304 /* EXPORT for RIF:
11305 Set a nominal cursor position.
11306
11307 HPOS and VPOS are column/row positions in a window glyph matrix. X
11308 and Y are window text area relative pixel positions.
11309
11310 If this is done during an update, updated_window will contain the
11311 window that is being updated and the position is the future output
11312 cursor position for that window. If updated_window is null, use
11313 selected_window and display the cursor at the given position. */
11314
11315 void
11316 x_cursor_to (int vpos, int hpos, int y, int x)
11317 {
11318 struct window *w;
11319
11320 /* If updated_window is not set, work on selected_window. */
11321 if (updated_window)
11322 w = updated_window;
11323 else
11324 w = XWINDOW (selected_window);
11325
11326 /* Set the output cursor. */
11327 output_cursor.hpos = hpos;
11328 output_cursor.vpos = vpos;
11329 output_cursor.x = x;
11330 output_cursor.y = y;
11331
11332 /* If not called as part of an update, really display the cursor.
11333 This will also set the cursor position of W. */
11334 if (updated_window == NULL)
11335 {
11336 block_input ();
11337 display_and_set_cursor (w, 1, hpos, vpos, x, y);
11338 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11339 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
11340 unblock_input ();
11341 }
11342 }
11343
11344 #endif /* HAVE_WINDOW_SYSTEM */
11345
11346 \f
11347 /***********************************************************************
11348 Tool-bars
11349 ***********************************************************************/
11350
11351 #ifdef HAVE_WINDOW_SYSTEM
11352
11353 /* Where the mouse was last time we reported a mouse event. */
11354
11355 FRAME_PTR last_mouse_frame;
11356
11357 /* Tool-bar item index of the item on which a mouse button was pressed
11358 or -1. */
11359
11360 int last_tool_bar_item;
11361
11362 /* Select `frame' temporarily without running all the code in
11363 do_switch_frame.
11364 FIXME: Maybe do_switch_frame should be trimmed down similarly
11365 when `norecord' is set. */
11366 static Lisp_Object
11367 fast_set_selected_frame (Lisp_Object frame)
11368 {
11369 if (!EQ (selected_frame, frame))
11370 {
11371 selected_frame = frame;
11372 selected_window = XFRAME (frame)->selected_window;
11373 }
11374 return Qnil;
11375 }
11376
11377 /* Update the tool-bar item list for frame F. This has to be done
11378 before we start to fill in any display lines. Called from
11379 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11380 and restore it here. */
11381
11382 static void
11383 update_tool_bar (struct frame *f, int save_match_data)
11384 {
11385 #if defined (USE_GTK) || defined (HAVE_NS)
11386 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11387 #else
11388 int do_update = WINDOWP (f->tool_bar_window)
11389 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11390 #endif
11391
11392 if (do_update)
11393 {
11394 Lisp_Object window;
11395 struct window *w;
11396
11397 window = FRAME_SELECTED_WINDOW (f);
11398 w = XWINDOW (window);
11399
11400 /* If the user has switched buffers or windows, we need to
11401 recompute to reflect the new bindings. But we'll
11402 recompute when update_mode_lines is set too; that means
11403 that people can use force-mode-line-update to request
11404 that the menu bar be recomputed. The adverse effect on
11405 the rest of the redisplay algorithm is about the same as
11406 windows_or_buffers_changed anyway. */
11407 if (windows_or_buffers_changed
11408 || w->update_mode_line
11409 || update_mode_lines
11410 || window_buffer_changed (w))
11411 {
11412 struct buffer *prev = current_buffer;
11413 ptrdiff_t count = SPECPDL_INDEX ();
11414 Lisp_Object frame, new_tool_bar;
11415 int new_n_tool_bar;
11416 struct gcpro gcpro1;
11417
11418 /* Set current_buffer to the buffer of the selected
11419 window of the frame, so that we get the right local
11420 keymaps. */
11421 set_buffer_internal_1 (XBUFFER (w->buffer));
11422
11423 /* Save match data, if we must. */
11424 if (save_match_data)
11425 record_unwind_save_match_data ();
11426
11427 /* Make sure that we don't accidentally use bogus keymaps. */
11428 if (NILP (Voverriding_local_map_menu_flag))
11429 {
11430 specbind (Qoverriding_terminal_local_map, Qnil);
11431 specbind (Qoverriding_local_map, Qnil);
11432 }
11433
11434 GCPRO1 (new_tool_bar);
11435
11436 /* We must temporarily set the selected frame to this frame
11437 before calling tool_bar_items, because the calculation of
11438 the tool-bar keymap uses the selected frame (see
11439 `tool-bar-make-keymap' in tool-bar.el). */
11440 eassert (EQ (selected_window,
11441 /* Since we only explicitly preserve selected_frame,
11442 check that selected_window would be redundant. */
11443 XFRAME (selected_frame)->selected_window));
11444 record_unwind_protect (fast_set_selected_frame, selected_frame);
11445 XSETFRAME (frame, f);
11446 fast_set_selected_frame (frame);
11447
11448 /* Build desired tool-bar items from keymaps. */
11449 new_tool_bar
11450 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11451 &new_n_tool_bar);
11452
11453 /* Redisplay the tool-bar if we changed it. */
11454 if (new_n_tool_bar != f->n_tool_bar_items
11455 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11456 {
11457 /* Redisplay that happens asynchronously due to an expose event
11458 may access f->tool_bar_items. Make sure we update both
11459 variables within BLOCK_INPUT so no such event interrupts. */
11460 block_input ();
11461 fset_tool_bar_items (f, new_tool_bar);
11462 f->n_tool_bar_items = new_n_tool_bar;
11463 w->update_mode_line = 1;
11464 unblock_input ();
11465 }
11466
11467 UNGCPRO;
11468
11469 unbind_to (count, Qnil);
11470 set_buffer_internal_1 (prev);
11471 }
11472 }
11473 }
11474
11475
11476 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11477 F's desired tool-bar contents. F->tool_bar_items must have
11478 been set up previously by calling prepare_menu_bars. */
11479
11480 static void
11481 build_desired_tool_bar_string (struct frame *f)
11482 {
11483 int i, size, size_needed;
11484 struct gcpro gcpro1, gcpro2, gcpro3;
11485 Lisp_Object image, plist, props;
11486
11487 image = plist = props = Qnil;
11488 GCPRO3 (image, plist, props);
11489
11490 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11491 Otherwise, make a new string. */
11492
11493 /* The size of the string we might be able to reuse. */
11494 size = (STRINGP (f->desired_tool_bar_string)
11495 ? SCHARS (f->desired_tool_bar_string)
11496 : 0);
11497
11498 /* We need one space in the string for each image. */
11499 size_needed = f->n_tool_bar_items;
11500
11501 /* Reuse f->desired_tool_bar_string, if possible. */
11502 if (size < size_needed || NILP (f->desired_tool_bar_string))
11503 fset_desired_tool_bar_string
11504 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11505 else
11506 {
11507 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11508 Fremove_text_properties (make_number (0), make_number (size),
11509 props, f->desired_tool_bar_string);
11510 }
11511
11512 /* Put a `display' property on the string for the images to display,
11513 put a `menu_item' property on tool-bar items with a value that
11514 is the index of the item in F's tool-bar item vector. */
11515 for (i = 0; i < f->n_tool_bar_items; ++i)
11516 {
11517 #define PROP(IDX) \
11518 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11519
11520 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11521 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11522 int hmargin, vmargin, relief, idx, end;
11523
11524 /* If image is a vector, choose the image according to the
11525 button state. */
11526 image = PROP (TOOL_BAR_ITEM_IMAGES);
11527 if (VECTORP (image))
11528 {
11529 if (enabled_p)
11530 idx = (selected_p
11531 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11532 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11533 else
11534 idx = (selected_p
11535 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11536 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11537
11538 eassert (ASIZE (image) >= idx);
11539 image = AREF (image, idx);
11540 }
11541 else
11542 idx = -1;
11543
11544 /* Ignore invalid image specifications. */
11545 if (!valid_image_p (image))
11546 continue;
11547
11548 /* Display the tool-bar button pressed, or depressed. */
11549 plist = Fcopy_sequence (XCDR (image));
11550
11551 /* Compute margin and relief to draw. */
11552 relief = (tool_bar_button_relief >= 0
11553 ? tool_bar_button_relief
11554 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11555 hmargin = vmargin = relief;
11556
11557 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11558 INT_MAX - max (hmargin, vmargin)))
11559 {
11560 hmargin += XFASTINT (Vtool_bar_button_margin);
11561 vmargin += XFASTINT (Vtool_bar_button_margin);
11562 }
11563 else if (CONSP (Vtool_bar_button_margin))
11564 {
11565 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11566 INT_MAX - hmargin))
11567 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11568
11569 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11570 INT_MAX - vmargin))
11571 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11572 }
11573
11574 if (auto_raise_tool_bar_buttons_p)
11575 {
11576 /* Add a `:relief' property to the image spec if the item is
11577 selected. */
11578 if (selected_p)
11579 {
11580 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11581 hmargin -= relief;
11582 vmargin -= relief;
11583 }
11584 }
11585 else
11586 {
11587 /* If image is selected, display it pressed, i.e. with a
11588 negative relief. If it's not selected, display it with a
11589 raised relief. */
11590 plist = Fplist_put (plist, QCrelief,
11591 (selected_p
11592 ? make_number (-relief)
11593 : make_number (relief)));
11594 hmargin -= relief;
11595 vmargin -= relief;
11596 }
11597
11598 /* Put a margin around the image. */
11599 if (hmargin || vmargin)
11600 {
11601 if (hmargin == vmargin)
11602 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11603 else
11604 plist = Fplist_put (plist, QCmargin,
11605 Fcons (make_number (hmargin),
11606 make_number (vmargin)));
11607 }
11608
11609 /* If button is not enabled, and we don't have special images
11610 for the disabled state, make the image appear disabled by
11611 applying an appropriate algorithm to it. */
11612 if (!enabled_p && idx < 0)
11613 plist = Fplist_put (plist, QCconversion, Qdisabled);
11614
11615 /* Put a `display' text property on the string for the image to
11616 display. Put a `menu-item' property on the string that gives
11617 the start of this item's properties in the tool-bar items
11618 vector. */
11619 image = Fcons (Qimage, plist);
11620 props = list4 (Qdisplay, image,
11621 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11622
11623 /* Let the last image hide all remaining spaces in the tool bar
11624 string. The string can be longer than needed when we reuse a
11625 previous string. */
11626 if (i + 1 == f->n_tool_bar_items)
11627 end = SCHARS (f->desired_tool_bar_string);
11628 else
11629 end = i + 1;
11630 Fadd_text_properties (make_number (i), make_number (end),
11631 props, f->desired_tool_bar_string);
11632 #undef PROP
11633 }
11634
11635 UNGCPRO;
11636 }
11637
11638
11639 /* Display one line of the tool-bar of frame IT->f.
11640
11641 HEIGHT specifies the desired height of the tool-bar line.
11642 If the actual height of the glyph row is less than HEIGHT, the
11643 row's height is increased to HEIGHT, and the icons are centered
11644 vertically in the new height.
11645
11646 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11647 count a final empty row in case the tool-bar width exactly matches
11648 the window width.
11649 */
11650
11651 static void
11652 display_tool_bar_line (struct it *it, int height)
11653 {
11654 struct glyph_row *row = it->glyph_row;
11655 int max_x = it->last_visible_x;
11656 struct glyph *last;
11657
11658 prepare_desired_row (row);
11659 row->y = it->current_y;
11660
11661 /* Note that this isn't made use of if the face hasn't a box,
11662 so there's no need to check the face here. */
11663 it->start_of_box_run_p = 1;
11664
11665 while (it->current_x < max_x)
11666 {
11667 int x, n_glyphs_before, i, nglyphs;
11668 struct it it_before;
11669
11670 /* Get the next display element. */
11671 if (!get_next_display_element (it))
11672 {
11673 /* Don't count empty row if we are counting needed tool-bar lines. */
11674 if (height < 0 && !it->hpos)
11675 return;
11676 break;
11677 }
11678
11679 /* Produce glyphs. */
11680 n_glyphs_before = row->used[TEXT_AREA];
11681 it_before = *it;
11682
11683 PRODUCE_GLYPHS (it);
11684
11685 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11686 i = 0;
11687 x = it_before.current_x;
11688 while (i < nglyphs)
11689 {
11690 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11691
11692 if (x + glyph->pixel_width > max_x)
11693 {
11694 /* Glyph doesn't fit on line. Backtrack. */
11695 row->used[TEXT_AREA] = n_glyphs_before;
11696 *it = it_before;
11697 /* If this is the only glyph on this line, it will never fit on the
11698 tool-bar, so skip it. But ensure there is at least one glyph,
11699 so we don't accidentally disable the tool-bar. */
11700 if (n_glyphs_before == 0
11701 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11702 break;
11703 goto out;
11704 }
11705
11706 ++it->hpos;
11707 x += glyph->pixel_width;
11708 ++i;
11709 }
11710
11711 /* Stop at line end. */
11712 if (ITERATOR_AT_END_OF_LINE_P (it))
11713 break;
11714
11715 set_iterator_to_next (it, 1);
11716 }
11717
11718 out:;
11719
11720 row->displays_text_p = row->used[TEXT_AREA] != 0;
11721
11722 /* Use default face for the border below the tool bar.
11723
11724 FIXME: When auto-resize-tool-bars is grow-only, there is
11725 no additional border below the possibly empty tool-bar lines.
11726 So to make the extra empty lines look "normal", we have to
11727 use the tool-bar face for the border too. */
11728 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11729 it->face_id = DEFAULT_FACE_ID;
11730
11731 extend_face_to_end_of_line (it);
11732 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11733 last->right_box_line_p = 1;
11734 if (last == row->glyphs[TEXT_AREA])
11735 last->left_box_line_p = 1;
11736
11737 /* Make line the desired height and center it vertically. */
11738 if ((height -= it->max_ascent + it->max_descent) > 0)
11739 {
11740 /* Don't add more than one line height. */
11741 height %= FRAME_LINE_HEIGHT (it->f);
11742 it->max_ascent += height / 2;
11743 it->max_descent += (height + 1) / 2;
11744 }
11745
11746 compute_line_metrics (it);
11747
11748 /* If line is empty, make it occupy the rest of the tool-bar. */
11749 if (!row->displays_text_p)
11750 {
11751 row->height = row->phys_height = it->last_visible_y - row->y;
11752 row->visible_height = row->height;
11753 row->ascent = row->phys_ascent = 0;
11754 row->extra_line_spacing = 0;
11755 }
11756
11757 row->full_width_p = 1;
11758 row->continued_p = 0;
11759 row->truncated_on_left_p = 0;
11760 row->truncated_on_right_p = 0;
11761
11762 it->current_x = it->hpos = 0;
11763 it->current_y += row->height;
11764 ++it->vpos;
11765 ++it->glyph_row;
11766 }
11767
11768
11769 /* Max tool-bar height. */
11770
11771 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11772 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11773
11774 /* Value is the number of screen lines needed to make all tool-bar
11775 items of frame F visible. The number of actual rows needed is
11776 returned in *N_ROWS if non-NULL. */
11777
11778 static int
11779 tool_bar_lines_needed (struct frame *f, int *n_rows)
11780 {
11781 struct window *w = XWINDOW (f->tool_bar_window);
11782 struct it it;
11783 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11784 the desired matrix, so use (unused) mode-line row as temporary row to
11785 avoid destroying the first tool-bar row. */
11786 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11787
11788 /* Initialize an iterator for iteration over
11789 F->desired_tool_bar_string in the tool-bar window of frame F. */
11790 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11791 it.first_visible_x = 0;
11792 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11793 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11794 it.paragraph_embedding = L2R;
11795
11796 while (!ITERATOR_AT_END_P (&it))
11797 {
11798 clear_glyph_row (temp_row);
11799 it.glyph_row = temp_row;
11800 display_tool_bar_line (&it, -1);
11801 }
11802 clear_glyph_row (temp_row);
11803
11804 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11805 if (n_rows)
11806 *n_rows = it.vpos > 0 ? it.vpos : -1;
11807
11808 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11809 }
11810
11811
11812 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11813 0, 1, 0,
11814 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11815 If FRAME is nil or omitted, use the selected frame. */)
11816 (Lisp_Object frame)
11817 {
11818 struct frame *f = decode_any_frame (frame);
11819 struct window *w;
11820 int nlines = 0;
11821
11822 if (WINDOWP (f->tool_bar_window)
11823 && (w = XWINDOW (f->tool_bar_window),
11824 WINDOW_TOTAL_LINES (w) > 0))
11825 {
11826 update_tool_bar (f, 1);
11827 if (f->n_tool_bar_items)
11828 {
11829 build_desired_tool_bar_string (f);
11830 nlines = tool_bar_lines_needed (f, NULL);
11831 }
11832 }
11833
11834 return make_number (nlines);
11835 }
11836
11837
11838 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11839 height should be changed. */
11840
11841 static int
11842 redisplay_tool_bar (struct frame *f)
11843 {
11844 struct window *w;
11845 struct it it;
11846 struct glyph_row *row;
11847
11848 #if defined (USE_GTK) || defined (HAVE_NS)
11849 if (FRAME_EXTERNAL_TOOL_BAR (f))
11850 update_frame_tool_bar (f);
11851 return 0;
11852 #endif
11853
11854 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11855 do anything. This means you must start with tool-bar-lines
11856 non-zero to get the auto-sizing effect. Or in other words, you
11857 can turn off tool-bars by specifying tool-bar-lines zero. */
11858 if (!WINDOWP (f->tool_bar_window)
11859 || (w = XWINDOW (f->tool_bar_window),
11860 WINDOW_TOTAL_LINES (w) == 0))
11861 return 0;
11862
11863 /* Set up an iterator for the tool-bar window. */
11864 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11865 it.first_visible_x = 0;
11866 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11867 row = it.glyph_row;
11868
11869 /* Build a string that represents the contents of the tool-bar. */
11870 build_desired_tool_bar_string (f);
11871 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11872 /* FIXME: This should be controlled by a user option. But it
11873 doesn't make sense to have an R2L tool bar if the menu bar cannot
11874 be drawn also R2L, and making the menu bar R2L is tricky due
11875 toolkit-specific code that implements it. If an R2L tool bar is
11876 ever supported, display_tool_bar_line should also be augmented to
11877 call unproduce_glyphs like display_line and display_string
11878 do. */
11879 it.paragraph_embedding = L2R;
11880
11881 if (f->n_tool_bar_rows == 0)
11882 {
11883 int nlines;
11884
11885 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11886 nlines != WINDOW_TOTAL_LINES (w)))
11887 {
11888 Lisp_Object frame;
11889 int old_height = WINDOW_TOTAL_LINES (w);
11890
11891 XSETFRAME (frame, f);
11892 Fmodify_frame_parameters (frame,
11893 Fcons (Fcons (Qtool_bar_lines,
11894 make_number (nlines)),
11895 Qnil));
11896 if (WINDOW_TOTAL_LINES (w) != old_height)
11897 {
11898 clear_glyph_matrix (w->desired_matrix);
11899 fonts_changed_p = 1;
11900 return 1;
11901 }
11902 }
11903 }
11904
11905 /* Display as many lines as needed to display all tool-bar items. */
11906
11907 if (f->n_tool_bar_rows > 0)
11908 {
11909 int border, rows, height, extra;
11910
11911 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
11912 border = XINT (Vtool_bar_border);
11913 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11914 border = FRAME_INTERNAL_BORDER_WIDTH (f);
11915 else if (EQ (Vtool_bar_border, Qborder_width))
11916 border = f->border_width;
11917 else
11918 border = 0;
11919 if (border < 0)
11920 border = 0;
11921
11922 rows = f->n_tool_bar_rows;
11923 height = max (1, (it.last_visible_y - border) / rows);
11924 extra = it.last_visible_y - border - height * rows;
11925
11926 while (it.current_y < it.last_visible_y)
11927 {
11928 int h = 0;
11929 if (extra > 0 && rows-- > 0)
11930 {
11931 h = (extra + rows - 1) / rows;
11932 extra -= h;
11933 }
11934 display_tool_bar_line (&it, height + h);
11935 }
11936 }
11937 else
11938 {
11939 while (it.current_y < it.last_visible_y)
11940 display_tool_bar_line (&it, 0);
11941 }
11942
11943 /* It doesn't make much sense to try scrolling in the tool-bar
11944 window, so don't do it. */
11945 w->desired_matrix->no_scrolling_p = 1;
11946 w->must_be_updated_p = 1;
11947
11948 if (!NILP (Vauto_resize_tool_bars))
11949 {
11950 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
11951 int change_height_p = 0;
11952
11953 /* If we couldn't display everything, change the tool-bar's
11954 height if there is room for more. */
11955 if (IT_STRING_CHARPOS (it) < it.end_charpos
11956 && it.current_y < max_tool_bar_height)
11957 change_height_p = 1;
11958
11959 row = it.glyph_row - 1;
11960
11961 /* If there are blank lines at the end, except for a partially
11962 visible blank line at the end that is smaller than
11963 FRAME_LINE_HEIGHT, change the tool-bar's height. */
11964 if (!row->displays_text_p
11965 && row->height >= FRAME_LINE_HEIGHT (f))
11966 change_height_p = 1;
11967
11968 /* If row displays tool-bar items, but is partially visible,
11969 change the tool-bar's height. */
11970 if (row->displays_text_p
11971 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
11972 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
11973 change_height_p = 1;
11974
11975 /* Resize windows as needed by changing the `tool-bar-lines'
11976 frame parameter. */
11977 if (change_height_p)
11978 {
11979 Lisp_Object frame;
11980 int old_height = WINDOW_TOTAL_LINES (w);
11981 int nrows;
11982 int nlines = tool_bar_lines_needed (f, &nrows);
11983
11984 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
11985 && !f->minimize_tool_bar_window_p)
11986 ? (nlines > old_height)
11987 : (nlines != old_height));
11988 f->minimize_tool_bar_window_p = 0;
11989
11990 if (change_height_p)
11991 {
11992 XSETFRAME (frame, f);
11993 Fmodify_frame_parameters (frame,
11994 Fcons (Fcons (Qtool_bar_lines,
11995 make_number (nlines)),
11996 Qnil));
11997 if (WINDOW_TOTAL_LINES (w) != old_height)
11998 {
11999 clear_glyph_matrix (w->desired_matrix);
12000 f->n_tool_bar_rows = nrows;
12001 fonts_changed_p = 1;
12002 return 1;
12003 }
12004 }
12005 }
12006 }
12007
12008 f->minimize_tool_bar_window_p = 0;
12009 return 0;
12010 }
12011
12012
12013 /* Get information about the tool-bar item which is displayed in GLYPH
12014 on frame F. Return in *PROP_IDX the index where tool-bar item
12015 properties start in F->tool_bar_items. Value is zero if
12016 GLYPH doesn't display a tool-bar item. */
12017
12018 static int
12019 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12020 {
12021 Lisp_Object prop;
12022 int success_p;
12023 int charpos;
12024
12025 /* This function can be called asynchronously, which means we must
12026 exclude any possibility that Fget_text_property signals an
12027 error. */
12028 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12029 charpos = max (0, charpos);
12030
12031 /* Get the text property `menu-item' at pos. The value of that
12032 property is the start index of this item's properties in
12033 F->tool_bar_items. */
12034 prop = Fget_text_property (make_number (charpos),
12035 Qmenu_item, f->current_tool_bar_string);
12036 if (INTEGERP (prop))
12037 {
12038 *prop_idx = XINT (prop);
12039 success_p = 1;
12040 }
12041 else
12042 success_p = 0;
12043
12044 return success_p;
12045 }
12046
12047 \f
12048 /* Get information about the tool-bar item at position X/Y on frame F.
12049 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12050 the current matrix of the tool-bar window of F, or NULL if not
12051 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12052 item in F->tool_bar_items. Value is
12053
12054 -1 if X/Y is not on a tool-bar item
12055 0 if X/Y is on the same item that was highlighted before.
12056 1 otherwise. */
12057
12058 static int
12059 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12060 int *hpos, int *vpos, int *prop_idx)
12061 {
12062 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12063 struct window *w = XWINDOW (f->tool_bar_window);
12064 int area;
12065
12066 /* Find the glyph under X/Y. */
12067 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12068 if (*glyph == NULL)
12069 return -1;
12070
12071 /* Get the start of this tool-bar item's properties in
12072 f->tool_bar_items. */
12073 if (!tool_bar_item_info (f, *glyph, prop_idx))
12074 return -1;
12075
12076 /* Is mouse on the highlighted item? */
12077 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12078 && *vpos >= hlinfo->mouse_face_beg_row
12079 && *vpos <= hlinfo->mouse_face_end_row
12080 && (*vpos > hlinfo->mouse_face_beg_row
12081 || *hpos >= hlinfo->mouse_face_beg_col)
12082 && (*vpos < hlinfo->mouse_face_end_row
12083 || *hpos < hlinfo->mouse_face_end_col
12084 || hlinfo->mouse_face_past_end))
12085 return 0;
12086
12087 return 1;
12088 }
12089
12090
12091 /* EXPORT:
12092 Handle mouse button event on the tool-bar of frame F, at
12093 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12094 0 for button release. MODIFIERS is event modifiers for button
12095 release. */
12096
12097 void
12098 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12099 int modifiers)
12100 {
12101 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12102 struct window *w = XWINDOW (f->tool_bar_window);
12103 int hpos, vpos, prop_idx;
12104 struct glyph *glyph;
12105 Lisp_Object enabled_p;
12106
12107 /* If not on the highlighted tool-bar item, return. */
12108 frame_to_window_pixel_xy (w, &x, &y);
12109 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
12110 return;
12111
12112 /* If item is disabled, do nothing. */
12113 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12114 if (NILP (enabled_p))
12115 return;
12116
12117 if (down_p)
12118 {
12119 /* Show item in pressed state. */
12120 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12121 last_tool_bar_item = prop_idx;
12122 }
12123 else
12124 {
12125 Lisp_Object key, frame;
12126 struct input_event event;
12127 EVENT_INIT (event);
12128
12129 /* Show item in released state. */
12130 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12131
12132 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12133
12134 XSETFRAME (frame, f);
12135 event.kind = TOOL_BAR_EVENT;
12136 event.frame_or_window = frame;
12137 event.arg = frame;
12138 kbd_buffer_store_event (&event);
12139
12140 event.kind = TOOL_BAR_EVENT;
12141 event.frame_or_window = frame;
12142 event.arg = key;
12143 event.modifiers = modifiers;
12144 kbd_buffer_store_event (&event);
12145 last_tool_bar_item = -1;
12146 }
12147 }
12148
12149
12150 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12151 tool-bar window-relative coordinates X/Y. Called from
12152 note_mouse_highlight. */
12153
12154 static void
12155 note_tool_bar_highlight (struct frame *f, int x, int y)
12156 {
12157 Lisp_Object window = f->tool_bar_window;
12158 struct window *w = XWINDOW (window);
12159 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12160 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12161 int hpos, vpos;
12162 struct glyph *glyph;
12163 struct glyph_row *row;
12164 int i;
12165 Lisp_Object enabled_p;
12166 int prop_idx;
12167 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12168 int mouse_down_p, rc;
12169
12170 /* Function note_mouse_highlight is called with negative X/Y
12171 values when mouse moves outside of the frame. */
12172 if (x <= 0 || y <= 0)
12173 {
12174 clear_mouse_face (hlinfo);
12175 return;
12176 }
12177
12178 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12179 if (rc < 0)
12180 {
12181 /* Not on tool-bar item. */
12182 clear_mouse_face (hlinfo);
12183 return;
12184 }
12185 else if (rc == 0)
12186 /* On same tool-bar item as before. */
12187 goto set_help_echo;
12188
12189 clear_mouse_face (hlinfo);
12190
12191 /* Mouse is down, but on different tool-bar item? */
12192 mouse_down_p = (dpyinfo->grabbed
12193 && f == last_mouse_frame
12194 && FRAME_LIVE_P (f));
12195 if (mouse_down_p
12196 && last_tool_bar_item != prop_idx)
12197 return;
12198
12199 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12200
12201 /* If tool-bar item is not enabled, don't highlight it. */
12202 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12203 if (!NILP (enabled_p))
12204 {
12205 /* Compute the x-position of the glyph. In front and past the
12206 image is a space. We include this in the highlighted area. */
12207 row = MATRIX_ROW (w->current_matrix, vpos);
12208 for (i = x = 0; i < hpos; ++i)
12209 x += row->glyphs[TEXT_AREA][i].pixel_width;
12210
12211 /* Record this as the current active region. */
12212 hlinfo->mouse_face_beg_col = hpos;
12213 hlinfo->mouse_face_beg_row = vpos;
12214 hlinfo->mouse_face_beg_x = x;
12215 hlinfo->mouse_face_beg_y = row->y;
12216 hlinfo->mouse_face_past_end = 0;
12217
12218 hlinfo->mouse_face_end_col = hpos + 1;
12219 hlinfo->mouse_face_end_row = vpos;
12220 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12221 hlinfo->mouse_face_end_y = row->y;
12222 hlinfo->mouse_face_window = window;
12223 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12224
12225 /* Display it as active. */
12226 show_mouse_face (hlinfo, draw);
12227 }
12228
12229 set_help_echo:
12230
12231 /* Set help_echo_string to a help string to display for this tool-bar item.
12232 XTread_socket does the rest. */
12233 help_echo_object = help_echo_window = Qnil;
12234 help_echo_pos = -1;
12235 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12236 if (NILP (help_echo_string))
12237 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12238 }
12239
12240 #endif /* HAVE_WINDOW_SYSTEM */
12241
12242
12243 \f
12244 /************************************************************************
12245 Horizontal scrolling
12246 ************************************************************************/
12247
12248 static int hscroll_window_tree (Lisp_Object);
12249 static int hscroll_windows (Lisp_Object);
12250
12251 /* For all leaf windows in the window tree rooted at WINDOW, set their
12252 hscroll value so that PT is (i) visible in the window, and (ii) so
12253 that it is not within a certain margin at the window's left and
12254 right border. Value is non-zero if any window's hscroll has been
12255 changed. */
12256
12257 static int
12258 hscroll_window_tree (Lisp_Object window)
12259 {
12260 int hscrolled_p = 0;
12261 int hscroll_relative_p = FLOATP (Vhscroll_step);
12262 int hscroll_step_abs = 0;
12263 double hscroll_step_rel = 0;
12264
12265 if (hscroll_relative_p)
12266 {
12267 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12268 if (hscroll_step_rel < 0)
12269 {
12270 hscroll_relative_p = 0;
12271 hscroll_step_abs = 0;
12272 }
12273 }
12274 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12275 {
12276 hscroll_step_abs = XINT (Vhscroll_step);
12277 if (hscroll_step_abs < 0)
12278 hscroll_step_abs = 0;
12279 }
12280 else
12281 hscroll_step_abs = 0;
12282
12283 while (WINDOWP (window))
12284 {
12285 struct window *w = XWINDOW (window);
12286
12287 if (WINDOWP (w->hchild))
12288 hscrolled_p |= hscroll_window_tree (w->hchild);
12289 else if (WINDOWP (w->vchild))
12290 hscrolled_p |= hscroll_window_tree (w->vchild);
12291 else if (w->cursor.vpos >= 0)
12292 {
12293 int h_margin;
12294 int text_area_width;
12295 struct glyph_row *current_cursor_row
12296 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12297 struct glyph_row *desired_cursor_row
12298 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12299 struct glyph_row *cursor_row
12300 = (desired_cursor_row->enabled_p
12301 ? desired_cursor_row
12302 : current_cursor_row);
12303 int row_r2l_p = cursor_row->reversed_p;
12304
12305 text_area_width = window_box_width (w, TEXT_AREA);
12306
12307 /* Scroll when cursor is inside this scroll margin. */
12308 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12309
12310 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
12311 /* For left-to-right rows, hscroll when cursor is either
12312 (i) inside the right hscroll margin, or (ii) if it is
12313 inside the left margin and the window is already
12314 hscrolled. */
12315 && ((!row_r2l_p
12316 && ((w->hscroll
12317 && w->cursor.x <= h_margin)
12318 || (cursor_row->enabled_p
12319 && cursor_row->truncated_on_right_p
12320 && (w->cursor.x >= text_area_width - h_margin))))
12321 /* For right-to-left rows, the logic is similar,
12322 except that rules for scrolling to left and right
12323 are reversed. E.g., if cursor.x <= h_margin, we
12324 need to hscroll "to the right" unconditionally,
12325 and that will scroll the screen to the left so as
12326 to reveal the next portion of the row. */
12327 || (row_r2l_p
12328 && ((cursor_row->enabled_p
12329 /* FIXME: It is confusing to set the
12330 truncated_on_right_p flag when R2L rows
12331 are actually truncated on the left. */
12332 && cursor_row->truncated_on_right_p
12333 && w->cursor.x <= h_margin)
12334 || (w->hscroll
12335 && (w->cursor.x >= text_area_width - h_margin))))))
12336 {
12337 struct it it;
12338 ptrdiff_t hscroll;
12339 struct buffer *saved_current_buffer;
12340 ptrdiff_t pt;
12341 int wanted_x;
12342
12343 /* Find point in a display of infinite width. */
12344 saved_current_buffer = current_buffer;
12345 current_buffer = XBUFFER (w->buffer);
12346
12347 if (w == XWINDOW (selected_window))
12348 pt = PT;
12349 else
12350 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12351
12352 /* Move iterator to pt starting at cursor_row->start in
12353 a line with infinite width. */
12354 init_to_row_start (&it, w, cursor_row);
12355 it.last_visible_x = INFINITY;
12356 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12357 current_buffer = saved_current_buffer;
12358
12359 /* Position cursor in window. */
12360 if (!hscroll_relative_p && hscroll_step_abs == 0)
12361 hscroll = max (0, (it.current_x
12362 - (ITERATOR_AT_END_OF_LINE_P (&it)
12363 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12364 : (text_area_width / 2))))
12365 / FRAME_COLUMN_WIDTH (it.f);
12366 else if ((!row_r2l_p
12367 && w->cursor.x >= text_area_width - h_margin)
12368 || (row_r2l_p && w->cursor.x <= h_margin))
12369 {
12370 if (hscroll_relative_p)
12371 wanted_x = text_area_width * (1 - hscroll_step_rel)
12372 - h_margin;
12373 else
12374 wanted_x = text_area_width
12375 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12376 - h_margin;
12377 hscroll
12378 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12379 }
12380 else
12381 {
12382 if (hscroll_relative_p)
12383 wanted_x = text_area_width * hscroll_step_rel
12384 + h_margin;
12385 else
12386 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12387 + h_margin;
12388 hscroll
12389 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12390 }
12391 hscroll = max (hscroll, w->min_hscroll);
12392
12393 /* Don't prevent redisplay optimizations if hscroll
12394 hasn't changed, as it will unnecessarily slow down
12395 redisplay. */
12396 if (w->hscroll != hscroll)
12397 {
12398 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
12399 w->hscroll = hscroll;
12400 hscrolled_p = 1;
12401 }
12402 }
12403 }
12404
12405 window = w->next;
12406 }
12407
12408 /* Value is non-zero if hscroll of any leaf window has been changed. */
12409 return hscrolled_p;
12410 }
12411
12412
12413 /* Set hscroll so that cursor is visible and not inside horizontal
12414 scroll margins for all windows in the tree rooted at WINDOW. See
12415 also hscroll_window_tree above. Value is non-zero if any window's
12416 hscroll has been changed. If it has, desired matrices on the frame
12417 of WINDOW are cleared. */
12418
12419 static int
12420 hscroll_windows (Lisp_Object window)
12421 {
12422 int hscrolled_p = hscroll_window_tree (window);
12423 if (hscrolled_p)
12424 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12425 return hscrolled_p;
12426 }
12427
12428
12429 \f
12430 /************************************************************************
12431 Redisplay
12432 ************************************************************************/
12433
12434 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12435 to a non-zero value. This is sometimes handy to have in a debugger
12436 session. */
12437
12438 #ifdef GLYPH_DEBUG
12439
12440 /* First and last unchanged row for try_window_id. */
12441
12442 static int debug_first_unchanged_at_end_vpos;
12443 static int debug_last_unchanged_at_beg_vpos;
12444
12445 /* Delta vpos and y. */
12446
12447 static int debug_dvpos, debug_dy;
12448
12449 /* Delta in characters and bytes for try_window_id. */
12450
12451 static ptrdiff_t debug_delta, debug_delta_bytes;
12452
12453 /* Values of window_end_pos and window_end_vpos at the end of
12454 try_window_id. */
12455
12456 static ptrdiff_t debug_end_vpos;
12457
12458 /* Append a string to W->desired_matrix->method. FMT is a printf
12459 format string. If trace_redisplay_p is non-zero also printf the
12460 resulting string to stderr. */
12461
12462 static void debug_method_add (struct window *, char const *, ...)
12463 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12464
12465 static void
12466 debug_method_add (struct window *w, char const *fmt, ...)
12467 {
12468 char *method = w->desired_matrix->method;
12469 int len = strlen (method);
12470 int size = sizeof w->desired_matrix->method;
12471 int remaining = size - len - 1;
12472 va_list ap;
12473
12474 if (len && remaining)
12475 {
12476 method[len] = '|';
12477 --remaining, ++len;
12478 }
12479
12480 va_start (ap, fmt);
12481 vsnprintf (method + len, remaining + 1, fmt, ap);
12482 va_end (ap);
12483
12484 if (trace_redisplay_p)
12485 fprintf (stderr, "%p (%s): %s\n",
12486 w,
12487 ((BUFFERP (w->buffer)
12488 && STRINGP (BVAR (XBUFFER (w->buffer), name)))
12489 ? SSDATA (BVAR (XBUFFER (w->buffer), name))
12490 : "no buffer"),
12491 method + len);
12492 }
12493
12494 #endif /* GLYPH_DEBUG */
12495
12496
12497 /* Value is non-zero if all changes in window W, which displays
12498 current_buffer, are in the text between START and END. START is a
12499 buffer position, END is given as a distance from Z. Used in
12500 redisplay_internal for display optimization. */
12501
12502 static int
12503 text_outside_line_unchanged_p (struct window *w,
12504 ptrdiff_t start, ptrdiff_t end)
12505 {
12506 int unchanged_p = 1;
12507
12508 /* If text or overlays have changed, see where. */
12509 if (window_outdated (w))
12510 {
12511 /* Gap in the line? */
12512 if (GPT < start || Z - GPT < end)
12513 unchanged_p = 0;
12514
12515 /* Changes start in front of the line, or end after it? */
12516 if (unchanged_p
12517 && (BEG_UNCHANGED < start - 1
12518 || END_UNCHANGED < end))
12519 unchanged_p = 0;
12520
12521 /* If selective display, can't optimize if changes start at the
12522 beginning of the line. */
12523 if (unchanged_p
12524 && INTEGERP (BVAR (current_buffer, selective_display))
12525 && XINT (BVAR (current_buffer, selective_display)) > 0
12526 && (BEG_UNCHANGED < start || GPT <= start))
12527 unchanged_p = 0;
12528
12529 /* If there are overlays at the start or end of the line, these
12530 may have overlay strings with newlines in them. A change at
12531 START, for instance, may actually concern the display of such
12532 overlay strings as well, and they are displayed on different
12533 lines. So, quickly rule out this case. (For the future, it
12534 might be desirable to implement something more telling than
12535 just BEG/END_UNCHANGED.) */
12536 if (unchanged_p)
12537 {
12538 if (BEG + BEG_UNCHANGED == start
12539 && overlay_touches_p (start))
12540 unchanged_p = 0;
12541 if (END_UNCHANGED == end
12542 && overlay_touches_p (Z - end))
12543 unchanged_p = 0;
12544 }
12545
12546 /* Under bidi reordering, adding or deleting a character in the
12547 beginning of a paragraph, before the first strong directional
12548 character, can change the base direction of the paragraph (unless
12549 the buffer specifies a fixed paragraph direction), which will
12550 require to redisplay the whole paragraph. It might be worthwhile
12551 to find the paragraph limits and widen the range of redisplayed
12552 lines to that, but for now just give up this optimization. */
12553 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
12554 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
12555 unchanged_p = 0;
12556 }
12557
12558 return unchanged_p;
12559 }
12560
12561
12562 /* Do a frame update, taking possible shortcuts into account. This is
12563 the main external entry point for redisplay.
12564
12565 If the last redisplay displayed an echo area message and that message
12566 is no longer requested, we clear the echo area or bring back the
12567 mini-buffer if that is in use. */
12568
12569 void
12570 redisplay (void)
12571 {
12572 redisplay_internal ();
12573 }
12574
12575
12576 static Lisp_Object
12577 overlay_arrow_string_or_property (Lisp_Object var)
12578 {
12579 Lisp_Object val;
12580
12581 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12582 return val;
12583
12584 return Voverlay_arrow_string;
12585 }
12586
12587 /* Return 1 if there are any overlay-arrows in current_buffer. */
12588 static int
12589 overlay_arrow_in_current_buffer_p (void)
12590 {
12591 Lisp_Object vlist;
12592
12593 for (vlist = Voverlay_arrow_variable_list;
12594 CONSP (vlist);
12595 vlist = XCDR (vlist))
12596 {
12597 Lisp_Object var = XCAR (vlist);
12598 Lisp_Object val;
12599
12600 if (!SYMBOLP (var))
12601 continue;
12602 val = find_symbol_value (var);
12603 if (MARKERP (val)
12604 && current_buffer == XMARKER (val)->buffer)
12605 return 1;
12606 }
12607 return 0;
12608 }
12609
12610
12611 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12612 has changed. */
12613
12614 static int
12615 overlay_arrows_changed_p (void)
12616 {
12617 Lisp_Object vlist;
12618
12619 for (vlist = Voverlay_arrow_variable_list;
12620 CONSP (vlist);
12621 vlist = XCDR (vlist))
12622 {
12623 Lisp_Object var = XCAR (vlist);
12624 Lisp_Object val, pstr;
12625
12626 if (!SYMBOLP (var))
12627 continue;
12628 val = find_symbol_value (var);
12629 if (!MARKERP (val))
12630 continue;
12631 if (! EQ (COERCE_MARKER (val),
12632 Fget (var, Qlast_arrow_position))
12633 || ! (pstr = overlay_arrow_string_or_property (var),
12634 EQ (pstr, Fget (var, Qlast_arrow_string))))
12635 return 1;
12636 }
12637 return 0;
12638 }
12639
12640 /* Mark overlay arrows to be updated on next redisplay. */
12641
12642 static void
12643 update_overlay_arrows (int up_to_date)
12644 {
12645 Lisp_Object vlist;
12646
12647 for (vlist = Voverlay_arrow_variable_list;
12648 CONSP (vlist);
12649 vlist = XCDR (vlist))
12650 {
12651 Lisp_Object var = XCAR (vlist);
12652
12653 if (!SYMBOLP (var))
12654 continue;
12655
12656 if (up_to_date > 0)
12657 {
12658 Lisp_Object val = find_symbol_value (var);
12659 Fput (var, Qlast_arrow_position,
12660 COERCE_MARKER (val));
12661 Fput (var, Qlast_arrow_string,
12662 overlay_arrow_string_or_property (var));
12663 }
12664 else if (up_to_date < 0
12665 || !NILP (Fget (var, Qlast_arrow_position)))
12666 {
12667 Fput (var, Qlast_arrow_position, Qt);
12668 Fput (var, Qlast_arrow_string, Qt);
12669 }
12670 }
12671 }
12672
12673
12674 /* Return overlay arrow string to display at row.
12675 Return integer (bitmap number) for arrow bitmap in left fringe.
12676 Return nil if no overlay arrow. */
12677
12678 static Lisp_Object
12679 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12680 {
12681 Lisp_Object vlist;
12682
12683 for (vlist = Voverlay_arrow_variable_list;
12684 CONSP (vlist);
12685 vlist = XCDR (vlist))
12686 {
12687 Lisp_Object var = XCAR (vlist);
12688 Lisp_Object val;
12689
12690 if (!SYMBOLP (var))
12691 continue;
12692
12693 val = find_symbol_value (var);
12694
12695 if (MARKERP (val)
12696 && current_buffer == XMARKER (val)->buffer
12697 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12698 {
12699 if (FRAME_WINDOW_P (it->f)
12700 /* FIXME: if ROW->reversed_p is set, this should test
12701 the right fringe, not the left one. */
12702 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12703 {
12704 #ifdef HAVE_WINDOW_SYSTEM
12705 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12706 {
12707 int fringe_bitmap;
12708 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12709 return make_number (fringe_bitmap);
12710 }
12711 #endif
12712 return make_number (-1); /* Use default arrow bitmap. */
12713 }
12714 return overlay_arrow_string_or_property (var);
12715 }
12716 }
12717
12718 return Qnil;
12719 }
12720
12721 /* Return 1 if point moved out of or into a composition. Otherwise
12722 return 0. PREV_BUF and PREV_PT are the last point buffer and
12723 position. BUF and PT are the current point buffer and position. */
12724
12725 static int
12726 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12727 struct buffer *buf, ptrdiff_t pt)
12728 {
12729 ptrdiff_t start, end;
12730 Lisp_Object prop;
12731 Lisp_Object buffer;
12732
12733 XSETBUFFER (buffer, buf);
12734 /* Check a composition at the last point if point moved within the
12735 same buffer. */
12736 if (prev_buf == buf)
12737 {
12738 if (prev_pt == pt)
12739 /* Point didn't move. */
12740 return 0;
12741
12742 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12743 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12744 && COMPOSITION_VALID_P (start, end, prop)
12745 && start < prev_pt && end > prev_pt)
12746 /* The last point was within the composition. Return 1 iff
12747 point moved out of the composition. */
12748 return (pt <= start || pt >= end);
12749 }
12750
12751 /* Check a composition at the current point. */
12752 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12753 && find_composition (pt, -1, &start, &end, &prop, buffer)
12754 && COMPOSITION_VALID_P (start, end, prop)
12755 && start < pt && end > pt);
12756 }
12757
12758
12759 /* Reconsider the setting of B->clip_changed which is displayed
12760 in window W. */
12761
12762 static void
12763 reconsider_clip_changes (struct window *w, struct buffer *b)
12764 {
12765 if (b->clip_changed
12766 && w->window_end_valid
12767 && w->current_matrix->buffer == b
12768 && w->current_matrix->zv == BUF_ZV (b)
12769 && w->current_matrix->begv == BUF_BEGV (b))
12770 b->clip_changed = 0;
12771
12772 /* If display wasn't paused, and W is not a tool bar window, see if
12773 point has been moved into or out of a composition. In that case,
12774 we set b->clip_changed to 1 to force updating the screen. If
12775 b->clip_changed has already been set to 1, we can skip this
12776 check. */
12777 if (!b->clip_changed && BUFFERP (w->buffer) && w->window_end_valid)
12778 {
12779 ptrdiff_t pt;
12780
12781 if (w == XWINDOW (selected_window))
12782 pt = PT;
12783 else
12784 pt = marker_position (w->pointm);
12785
12786 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
12787 || pt != w->last_point)
12788 && check_point_in_composition (w->current_matrix->buffer,
12789 w->last_point,
12790 XBUFFER (w->buffer), pt))
12791 b->clip_changed = 1;
12792 }
12793 }
12794 \f
12795
12796 #define STOP_POLLING \
12797 do { if (! polling_stopped_here) stop_polling (); \
12798 polling_stopped_here = 1; } while (0)
12799
12800 #define RESUME_POLLING \
12801 do { if (polling_stopped_here) start_polling (); \
12802 polling_stopped_here = 0; } while (0)
12803
12804
12805 /* Perhaps in the future avoid recentering windows if it
12806 is not necessary; currently that causes some problems. */
12807
12808 static void
12809 redisplay_internal (void)
12810 {
12811 struct window *w = XWINDOW (selected_window);
12812 struct window *sw;
12813 struct frame *fr;
12814 int pending;
12815 int must_finish = 0;
12816 struct text_pos tlbufpos, tlendpos;
12817 int number_of_visible_frames;
12818 ptrdiff_t count, count1;
12819 struct frame *sf;
12820 int polling_stopped_here = 0;
12821 Lisp_Object tail, frame;
12822 struct backtrace backtrace;
12823
12824 /* Non-zero means redisplay has to consider all windows on all
12825 frames. Zero means, only selected_window is considered. */
12826 int consider_all_windows_p;
12827
12828 /* Non-zero means redisplay has to redisplay the miniwindow. */
12829 int update_miniwindow_p = 0;
12830
12831 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12832
12833 /* No redisplay if running in batch mode or frame is not yet fully
12834 initialized, or redisplay is explicitly turned off by setting
12835 Vinhibit_redisplay. */
12836 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12837 || !NILP (Vinhibit_redisplay))
12838 return;
12839
12840 /* Don't examine these until after testing Vinhibit_redisplay.
12841 When Emacs is shutting down, perhaps because its connection to
12842 X has dropped, we should not look at them at all. */
12843 fr = XFRAME (w->frame);
12844 sf = SELECTED_FRAME ();
12845
12846 if (!fr->glyphs_initialized_p)
12847 return;
12848
12849 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12850 if (popup_activated ())
12851 return;
12852 #endif
12853
12854 /* I don't think this happens but let's be paranoid. */
12855 if (redisplaying_p)
12856 return;
12857
12858 /* Record a function that clears redisplaying_p
12859 when we leave this function. */
12860 count = SPECPDL_INDEX ();
12861 record_unwind_protect (unwind_redisplay, selected_frame);
12862 redisplaying_p = 1;
12863 specbind (Qinhibit_free_realized_faces, Qnil);
12864
12865 /* Record this function, so it appears on the profiler's backtraces. */
12866 backtrace.next = backtrace_list;
12867 backtrace.function = Qredisplay_internal;
12868 backtrace.args = &Qnil;
12869 backtrace.nargs = 0;
12870 backtrace.debug_on_exit = 0;
12871 backtrace_list = &backtrace;
12872
12873 FOR_EACH_FRAME (tail, frame)
12874 XFRAME (frame)->already_hscrolled_p = 0;
12875
12876 retry:
12877 /* Remember the currently selected window. */
12878 sw = w;
12879
12880 pending = 0;
12881 reconsider_clip_changes (w, current_buffer);
12882 last_escape_glyph_frame = NULL;
12883 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12884 last_glyphless_glyph_frame = NULL;
12885 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12886
12887 /* If new fonts have been loaded that make a glyph matrix adjustment
12888 necessary, do it. */
12889 if (fonts_changed_p)
12890 {
12891 adjust_glyphs (NULL);
12892 ++windows_or_buffers_changed;
12893 fonts_changed_p = 0;
12894 }
12895
12896 /* If face_change_count is non-zero, init_iterator will free all
12897 realized faces, which includes the faces referenced from current
12898 matrices. So, we can't reuse current matrices in this case. */
12899 if (face_change_count)
12900 ++windows_or_buffers_changed;
12901
12902 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12903 && FRAME_TTY (sf)->previous_frame != sf)
12904 {
12905 /* Since frames on a single ASCII terminal share the same
12906 display area, displaying a different frame means redisplay
12907 the whole thing. */
12908 windows_or_buffers_changed++;
12909 SET_FRAME_GARBAGED (sf);
12910 #ifndef DOS_NT
12911 set_tty_color_mode (FRAME_TTY (sf), sf);
12912 #endif
12913 FRAME_TTY (sf)->previous_frame = sf;
12914 }
12915
12916 /* Set the visible flags for all frames. Do this before checking for
12917 resized or garbaged frames; they want to know if their frames are
12918 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
12919 number_of_visible_frames = 0;
12920
12921 FOR_EACH_FRAME (tail, frame)
12922 {
12923 struct frame *f = XFRAME (frame);
12924
12925 if (FRAME_VISIBLE_P (f))
12926 ++number_of_visible_frames;
12927 clear_desired_matrices (f);
12928 }
12929
12930 /* Notice any pending interrupt request to change frame size. */
12931 do_pending_window_change (1);
12932
12933 /* do_pending_window_change could change the selected_window due to
12934 frame resizing which makes the selected window too small. */
12935 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
12936 {
12937 sw = w;
12938 reconsider_clip_changes (w, current_buffer);
12939 }
12940
12941 /* Clear frames marked as garbaged. */
12942 clear_garbaged_frames ();
12943
12944 /* Build menubar and tool-bar items. */
12945 if (NILP (Vmemory_full))
12946 prepare_menu_bars ();
12947
12948 if (windows_or_buffers_changed)
12949 update_mode_lines++;
12950
12951 /* Detect case that we need to write or remove a star in the mode line. */
12952 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
12953 {
12954 w->update_mode_line = 1;
12955 if (buffer_shared_and_changed ())
12956 update_mode_lines++;
12957 }
12958
12959 /* Avoid invocation of point motion hooks by `current_column' below. */
12960 count1 = SPECPDL_INDEX ();
12961 specbind (Qinhibit_point_motion_hooks, Qt);
12962
12963 if (mode_line_update_needed (w))
12964 w->update_mode_line = 1;
12965
12966 unbind_to (count1, Qnil);
12967
12968 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
12969
12970 consider_all_windows_p = (update_mode_lines
12971 || buffer_shared_and_changed ()
12972 || cursor_type_changed);
12973
12974 /* If specs for an arrow have changed, do thorough redisplay
12975 to ensure we remove any arrow that should no longer exist. */
12976 if (overlay_arrows_changed_p ())
12977 consider_all_windows_p = windows_or_buffers_changed = 1;
12978
12979 /* Normally the message* functions will have already displayed and
12980 updated the echo area, but the frame may have been trashed, or
12981 the update may have been preempted, so display the echo area
12982 again here. Checking message_cleared_p captures the case that
12983 the echo area should be cleared. */
12984 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
12985 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
12986 || (message_cleared_p
12987 && minibuf_level == 0
12988 /* If the mini-window is currently selected, this means the
12989 echo-area doesn't show through. */
12990 && !MINI_WINDOW_P (XWINDOW (selected_window))))
12991 {
12992 int window_height_changed_p = echo_area_display (0);
12993
12994 if (message_cleared_p)
12995 update_miniwindow_p = 1;
12996
12997 must_finish = 1;
12998
12999 /* If we don't display the current message, don't clear the
13000 message_cleared_p flag, because, if we did, we wouldn't clear
13001 the echo area in the next redisplay which doesn't preserve
13002 the echo area. */
13003 if (!display_last_displayed_message_p)
13004 message_cleared_p = 0;
13005
13006 if (fonts_changed_p)
13007 goto retry;
13008 else if (window_height_changed_p)
13009 {
13010 consider_all_windows_p = 1;
13011 ++update_mode_lines;
13012 ++windows_or_buffers_changed;
13013
13014 /* If window configuration was changed, frames may have been
13015 marked garbaged. Clear them or we will experience
13016 surprises wrt scrolling. */
13017 clear_garbaged_frames ();
13018 }
13019 }
13020 else if (EQ (selected_window, minibuf_window)
13021 && (current_buffer->clip_changed || window_outdated (w))
13022 && resize_mini_window (w, 0))
13023 {
13024 /* Resized active mini-window to fit the size of what it is
13025 showing if its contents might have changed. */
13026 must_finish = 1;
13027 /* FIXME: this causes all frames to be updated, which seems unnecessary
13028 since only the current frame needs to be considered. This function
13029 needs to be rewritten with two variables, consider_all_windows and
13030 consider_all_frames. */
13031 consider_all_windows_p = 1;
13032 ++windows_or_buffers_changed;
13033 ++update_mode_lines;
13034
13035 /* If window configuration was changed, frames may have been
13036 marked garbaged. Clear them or we will experience
13037 surprises wrt scrolling. */
13038 clear_garbaged_frames ();
13039 }
13040
13041
13042 /* If showing the region, and mark has changed, we must redisplay
13043 the whole window. The assignment to this_line_start_pos prevents
13044 the optimization directly below this if-statement. */
13045 if (((!NILP (Vtransient_mark_mode)
13046 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
13047 != !NILP (w->region_showing))
13048 || (!NILP (w->region_showing)
13049 && !EQ (w->region_showing,
13050 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
13051 CHARPOS (this_line_start_pos) = 0;
13052
13053 /* Optimize the case that only the line containing the cursor in the
13054 selected window has changed. Variables starting with this_ are
13055 set in display_line and record information about the line
13056 containing the cursor. */
13057 tlbufpos = this_line_start_pos;
13058 tlendpos = this_line_end_pos;
13059 if (!consider_all_windows_p
13060 && CHARPOS (tlbufpos) > 0
13061 && !w->update_mode_line
13062 && !current_buffer->clip_changed
13063 && !current_buffer->prevent_redisplay_optimizations_p
13064 && FRAME_VISIBLE_P (XFRAME (w->frame))
13065 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13066 /* Make sure recorded data applies to current buffer, etc. */
13067 && this_line_buffer == current_buffer
13068 && current_buffer == XBUFFER (w->buffer)
13069 && !w->force_start
13070 && !w->optional_new_start
13071 /* Point must be on the line that we have info recorded about. */
13072 && PT >= CHARPOS (tlbufpos)
13073 && PT <= Z - CHARPOS (tlendpos)
13074 /* All text outside that line, including its final newline,
13075 must be unchanged. */
13076 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13077 CHARPOS (tlendpos)))
13078 {
13079 if (CHARPOS (tlbufpos) > BEGV
13080 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13081 && (CHARPOS (tlbufpos) == ZV
13082 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13083 /* Former continuation line has disappeared by becoming empty. */
13084 goto cancel;
13085 else if (window_outdated (w) || MINI_WINDOW_P (w))
13086 {
13087 /* We have to handle the case of continuation around a
13088 wide-column character (see the comment in indent.c around
13089 line 1340).
13090
13091 For instance, in the following case:
13092
13093 -------- Insert --------
13094 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13095 J_I_ ==> J_I_ `^^' are cursors.
13096 ^^ ^^
13097 -------- --------
13098
13099 As we have to redraw the line above, we cannot use this
13100 optimization. */
13101
13102 struct it it;
13103 int line_height_before = this_line_pixel_height;
13104
13105 /* Note that start_display will handle the case that the
13106 line starting at tlbufpos is a continuation line. */
13107 start_display (&it, w, tlbufpos);
13108
13109 /* Implementation note: It this still necessary? */
13110 if (it.current_x != this_line_start_x)
13111 goto cancel;
13112
13113 TRACE ((stderr, "trying display optimization 1\n"));
13114 w->cursor.vpos = -1;
13115 overlay_arrow_seen = 0;
13116 it.vpos = this_line_vpos;
13117 it.current_y = this_line_y;
13118 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13119 display_line (&it);
13120
13121 /* If line contains point, is not continued,
13122 and ends at same distance from eob as before, we win. */
13123 if (w->cursor.vpos >= 0
13124 /* Line is not continued, otherwise this_line_start_pos
13125 would have been set to 0 in display_line. */
13126 && CHARPOS (this_line_start_pos)
13127 /* Line ends as before. */
13128 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13129 /* Line has same height as before. Otherwise other lines
13130 would have to be shifted up or down. */
13131 && this_line_pixel_height == line_height_before)
13132 {
13133 /* If this is not the window's last line, we must adjust
13134 the charstarts of the lines below. */
13135 if (it.current_y < it.last_visible_y)
13136 {
13137 struct glyph_row *row
13138 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13139 ptrdiff_t delta, delta_bytes;
13140
13141 /* We used to distinguish between two cases here,
13142 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13143 when the line ends in a newline or the end of the
13144 buffer's accessible portion. But both cases did
13145 the same, so they were collapsed. */
13146 delta = (Z
13147 - CHARPOS (tlendpos)
13148 - MATRIX_ROW_START_CHARPOS (row));
13149 delta_bytes = (Z_BYTE
13150 - BYTEPOS (tlendpos)
13151 - MATRIX_ROW_START_BYTEPOS (row));
13152
13153 increment_matrix_positions (w->current_matrix,
13154 this_line_vpos + 1,
13155 w->current_matrix->nrows,
13156 delta, delta_bytes);
13157 }
13158
13159 /* If this row displays text now but previously didn't,
13160 or vice versa, w->window_end_vpos may have to be
13161 adjusted. */
13162 if ((it.glyph_row - 1)->displays_text_p)
13163 {
13164 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
13165 wset_window_end_vpos (w, make_number (this_line_vpos));
13166 }
13167 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13168 && this_line_vpos > 0)
13169 wset_window_end_vpos (w, make_number (this_line_vpos - 1));
13170 w->window_end_valid = 0;
13171
13172 /* Update hint: No need to try to scroll in update_window. */
13173 w->desired_matrix->no_scrolling_p = 1;
13174
13175 #ifdef GLYPH_DEBUG
13176 *w->desired_matrix->method = 0;
13177 debug_method_add (w, "optimization 1");
13178 #endif
13179 #ifdef HAVE_WINDOW_SYSTEM
13180 update_window_fringes (w, 0);
13181 #endif
13182 goto update;
13183 }
13184 else
13185 goto cancel;
13186 }
13187 else if (/* Cursor position hasn't changed. */
13188 PT == w->last_point
13189 /* Make sure the cursor was last displayed
13190 in this window. Otherwise we have to reposition it. */
13191 && 0 <= w->cursor.vpos
13192 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
13193 {
13194 if (!must_finish)
13195 {
13196 do_pending_window_change (1);
13197 /* If selected_window changed, redisplay again. */
13198 if (WINDOWP (selected_window)
13199 && (w = XWINDOW (selected_window)) != sw)
13200 goto retry;
13201
13202 /* We used to always goto end_of_redisplay here, but this
13203 isn't enough if we have a blinking cursor. */
13204 if (w->cursor_off_p == w->last_cursor_off_p)
13205 goto end_of_redisplay;
13206 }
13207 goto update;
13208 }
13209 /* If highlighting the region, or if the cursor is in the echo area,
13210 then we can't just move the cursor. */
13211 else if (! (!NILP (Vtransient_mark_mode)
13212 && !NILP (BVAR (current_buffer, mark_active)))
13213 && (EQ (selected_window,
13214 BVAR (current_buffer, last_selected_window))
13215 || highlight_nonselected_windows)
13216 && NILP (w->region_showing)
13217 && NILP (Vshow_trailing_whitespace)
13218 && !cursor_in_echo_area)
13219 {
13220 struct it it;
13221 struct glyph_row *row;
13222
13223 /* Skip from tlbufpos to PT and see where it is. Note that
13224 PT may be in invisible text. If so, we will end at the
13225 next visible position. */
13226 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13227 NULL, DEFAULT_FACE_ID);
13228 it.current_x = this_line_start_x;
13229 it.current_y = this_line_y;
13230 it.vpos = this_line_vpos;
13231
13232 /* The call to move_it_to stops in front of PT, but
13233 moves over before-strings. */
13234 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13235
13236 if (it.vpos == this_line_vpos
13237 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13238 row->enabled_p))
13239 {
13240 eassert (this_line_vpos == it.vpos);
13241 eassert (this_line_y == it.current_y);
13242 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13243 #ifdef GLYPH_DEBUG
13244 *w->desired_matrix->method = 0;
13245 debug_method_add (w, "optimization 3");
13246 #endif
13247 goto update;
13248 }
13249 else
13250 goto cancel;
13251 }
13252
13253 cancel:
13254 /* Text changed drastically or point moved off of line. */
13255 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13256 }
13257
13258 CHARPOS (this_line_start_pos) = 0;
13259 consider_all_windows_p |= buffer_shared_and_changed ();
13260 ++clear_face_cache_count;
13261 #ifdef HAVE_WINDOW_SYSTEM
13262 ++clear_image_cache_count;
13263 #endif
13264
13265 /* Build desired matrices, and update the display. If
13266 consider_all_windows_p is non-zero, do it for all windows on all
13267 frames. Otherwise do it for selected_window, only. */
13268
13269 if (consider_all_windows_p)
13270 {
13271 FOR_EACH_FRAME (tail, frame)
13272 XFRAME (frame)->updated_p = 0;
13273
13274 FOR_EACH_FRAME (tail, frame)
13275 {
13276 struct frame *f = XFRAME (frame);
13277
13278 /* We don't have to do anything for unselected terminal
13279 frames. */
13280 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13281 && !EQ (FRAME_TTY (f)->top_frame, frame))
13282 continue;
13283
13284 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13285 {
13286 /* Mark all the scroll bars to be removed; we'll redeem
13287 the ones we want when we redisplay their windows. */
13288 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13289 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13290
13291 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13292 redisplay_windows (FRAME_ROOT_WINDOW (f));
13293
13294 /* The X error handler may have deleted that frame. */
13295 if (!FRAME_LIVE_P (f))
13296 continue;
13297
13298 /* Any scroll bars which redisplay_windows should have
13299 nuked should now go away. */
13300 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13301 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13302
13303 /* If fonts changed, display again. */
13304 /* ??? rms: I suspect it is a mistake to jump all the way
13305 back to retry here. It should just retry this frame. */
13306 if (fonts_changed_p)
13307 goto retry;
13308
13309 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13310 {
13311 /* See if we have to hscroll. */
13312 if (!f->already_hscrolled_p)
13313 {
13314 f->already_hscrolled_p = 1;
13315 if (hscroll_windows (f->root_window))
13316 goto retry;
13317 }
13318
13319 /* Prevent various kinds of signals during display
13320 update. stdio is not robust about handling
13321 signals, which can cause an apparent I/O
13322 error. */
13323 if (interrupt_input)
13324 unrequest_sigio ();
13325 STOP_POLLING;
13326
13327 /* Update the display. */
13328 set_window_update_flags (XWINDOW (f->root_window), 1);
13329 pending |= update_frame (f, 0, 0);
13330 f->updated_p = 1;
13331 }
13332 }
13333 }
13334
13335 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13336
13337 if (!pending)
13338 {
13339 /* Do the mark_window_display_accurate after all windows have
13340 been redisplayed because this call resets flags in buffers
13341 which are needed for proper redisplay. */
13342 FOR_EACH_FRAME (tail, frame)
13343 {
13344 struct frame *f = XFRAME (frame);
13345 if (f->updated_p)
13346 {
13347 mark_window_display_accurate (f->root_window, 1);
13348 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13349 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13350 }
13351 }
13352 }
13353 }
13354 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13355 {
13356 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13357 struct frame *mini_frame;
13358
13359 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
13360 /* Use list_of_error, not Qerror, so that
13361 we catch only errors and don't run the debugger. */
13362 internal_condition_case_1 (redisplay_window_1, selected_window,
13363 list_of_error,
13364 redisplay_window_error);
13365 if (update_miniwindow_p)
13366 internal_condition_case_1 (redisplay_window_1, mini_window,
13367 list_of_error,
13368 redisplay_window_error);
13369
13370 /* Compare desired and current matrices, perform output. */
13371
13372 update:
13373 /* If fonts changed, display again. */
13374 if (fonts_changed_p)
13375 goto retry;
13376
13377 /* Prevent various kinds of signals during display update.
13378 stdio is not robust about handling signals,
13379 which can cause an apparent I/O error. */
13380 if (interrupt_input)
13381 unrequest_sigio ();
13382 STOP_POLLING;
13383
13384 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13385 {
13386 if (hscroll_windows (selected_window))
13387 goto retry;
13388
13389 XWINDOW (selected_window)->must_be_updated_p = 1;
13390 pending = update_frame (sf, 0, 0);
13391 }
13392
13393 /* We may have called echo_area_display at the top of this
13394 function. If the echo area is on another frame, that may
13395 have put text on a frame other than the selected one, so the
13396 above call to update_frame would not have caught it. Catch
13397 it here. */
13398 mini_window = FRAME_MINIBUF_WINDOW (sf);
13399 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13400
13401 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13402 {
13403 XWINDOW (mini_window)->must_be_updated_p = 1;
13404 pending |= update_frame (mini_frame, 0, 0);
13405 if (!pending && hscroll_windows (mini_window))
13406 goto retry;
13407 }
13408 }
13409
13410 /* If display was paused because of pending input, make sure we do a
13411 thorough update the next time. */
13412 if (pending)
13413 {
13414 /* Prevent the optimization at the beginning of
13415 redisplay_internal that tries a single-line update of the
13416 line containing the cursor in the selected window. */
13417 CHARPOS (this_line_start_pos) = 0;
13418
13419 /* Let the overlay arrow be updated the next time. */
13420 update_overlay_arrows (0);
13421
13422 /* If we pause after scrolling, some rows in the current
13423 matrices of some windows are not valid. */
13424 if (!WINDOW_FULL_WIDTH_P (w)
13425 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13426 update_mode_lines = 1;
13427 }
13428 else
13429 {
13430 if (!consider_all_windows_p)
13431 {
13432 /* This has already been done above if
13433 consider_all_windows_p is set. */
13434 mark_window_display_accurate_1 (w, 1);
13435
13436 /* Say overlay arrows are up to date. */
13437 update_overlay_arrows (1);
13438
13439 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13440 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13441 }
13442
13443 update_mode_lines = 0;
13444 windows_or_buffers_changed = 0;
13445 cursor_type_changed = 0;
13446 }
13447
13448 /* Start SIGIO interrupts coming again. Having them off during the
13449 code above makes it less likely one will discard output, but not
13450 impossible, since there might be stuff in the system buffer here.
13451 But it is much hairier to try to do anything about that. */
13452 if (interrupt_input)
13453 request_sigio ();
13454 RESUME_POLLING;
13455
13456 /* If a frame has become visible which was not before, redisplay
13457 again, so that we display it. Expose events for such a frame
13458 (which it gets when becoming visible) don't call the parts of
13459 redisplay constructing glyphs, so simply exposing a frame won't
13460 display anything in this case. So, we have to display these
13461 frames here explicitly. */
13462 if (!pending)
13463 {
13464 int new_count = 0;
13465
13466 FOR_EACH_FRAME (tail, frame)
13467 {
13468 int this_is_visible = 0;
13469
13470 if (XFRAME (frame)->visible)
13471 this_is_visible = 1;
13472
13473 if (this_is_visible)
13474 new_count++;
13475 }
13476
13477 if (new_count != number_of_visible_frames)
13478 windows_or_buffers_changed++;
13479 }
13480
13481 /* Change frame size now if a change is pending. */
13482 do_pending_window_change (1);
13483
13484 /* If we just did a pending size change, or have additional
13485 visible frames, or selected_window changed, redisplay again. */
13486 if ((windows_or_buffers_changed && !pending)
13487 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13488 goto retry;
13489
13490 /* Clear the face and image caches.
13491
13492 We used to do this only if consider_all_windows_p. But the cache
13493 needs to be cleared if a timer creates images in the current
13494 buffer (e.g. the test case in Bug#6230). */
13495
13496 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13497 {
13498 clear_face_cache (0);
13499 clear_face_cache_count = 0;
13500 }
13501
13502 #ifdef HAVE_WINDOW_SYSTEM
13503 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13504 {
13505 clear_image_caches (Qnil);
13506 clear_image_cache_count = 0;
13507 }
13508 #endif /* HAVE_WINDOW_SYSTEM */
13509
13510 end_of_redisplay:
13511 backtrace_list = backtrace.next;
13512 unbind_to (count, Qnil);
13513 RESUME_POLLING;
13514 }
13515
13516
13517 /* Redisplay, but leave alone any recent echo area message unless
13518 another message has been requested in its place.
13519
13520 This is useful in situations where you need to redisplay but no
13521 user action has occurred, making it inappropriate for the message
13522 area to be cleared. See tracking_off and
13523 wait_reading_process_output for examples of these situations.
13524
13525 FROM_WHERE is an integer saying from where this function was
13526 called. This is useful for debugging. */
13527
13528 void
13529 redisplay_preserve_echo_area (int from_where)
13530 {
13531 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13532
13533 if (!NILP (echo_area_buffer[1]))
13534 {
13535 /* We have a previously displayed message, but no current
13536 message. Redisplay the previous message. */
13537 display_last_displayed_message_p = 1;
13538 redisplay_internal ();
13539 display_last_displayed_message_p = 0;
13540 }
13541 else
13542 redisplay_internal ();
13543
13544 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13545 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13546 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13547 }
13548
13549
13550 /* Function registered with record_unwind_protect in redisplay_internal.
13551 Clear redisplaying_p. Also select the previously selected frame. */
13552
13553 static Lisp_Object
13554 unwind_redisplay (Lisp_Object old_frame)
13555 {
13556 redisplaying_p = 0;
13557 return Qnil;
13558 }
13559
13560
13561 /* Mark the display of leaf window W as accurate or inaccurate.
13562 If ACCURATE_P is non-zero mark display of W as accurate. If
13563 ACCURATE_P is zero, arrange for W to be redisplayed the next
13564 time redisplay_internal is called. */
13565
13566 static void
13567 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13568 {
13569 struct buffer *b = XBUFFER (w->buffer);
13570
13571 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13572 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13573 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13574
13575 if (accurate_p)
13576 {
13577 b->clip_changed = 0;
13578 b->prevent_redisplay_optimizations_p = 0;
13579
13580 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13581 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13582 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13583 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13584
13585 w->current_matrix->buffer = b;
13586 w->current_matrix->begv = BUF_BEGV (b);
13587 w->current_matrix->zv = BUF_ZV (b);
13588
13589 w->last_cursor = w->cursor;
13590 w->last_cursor_off_p = w->cursor_off_p;
13591
13592 if (w == XWINDOW (selected_window))
13593 w->last_point = BUF_PT (b);
13594 else
13595 w->last_point = marker_position (w->pointm);
13596
13597 w->window_end_valid = 1;
13598 w->update_mode_line = 0;
13599 }
13600 }
13601
13602
13603 /* Mark the display of windows in the window tree rooted at WINDOW as
13604 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13605 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13606 be redisplayed the next time redisplay_internal is called. */
13607
13608 void
13609 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13610 {
13611 struct window *w;
13612
13613 for (; !NILP (window); window = w->next)
13614 {
13615 w = XWINDOW (window);
13616 if (!NILP (w->vchild))
13617 mark_window_display_accurate (w->vchild, accurate_p);
13618 else if (!NILP (w->hchild))
13619 mark_window_display_accurate (w->hchild, accurate_p);
13620 else if (BUFFERP (w->buffer))
13621 mark_window_display_accurate_1 (w, accurate_p);
13622 }
13623
13624 if (accurate_p)
13625 update_overlay_arrows (1);
13626 else
13627 /* Force a thorough redisplay the next time by setting
13628 last_arrow_position and last_arrow_string to t, which is
13629 unequal to any useful value of Voverlay_arrow_... */
13630 update_overlay_arrows (-1);
13631 }
13632
13633
13634 /* Return value in display table DP (Lisp_Char_Table *) for character
13635 C. Since a display table doesn't have any parent, we don't have to
13636 follow parent. Do not call this function directly but use the
13637 macro DISP_CHAR_VECTOR. */
13638
13639 Lisp_Object
13640 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13641 {
13642 Lisp_Object val;
13643
13644 if (ASCII_CHAR_P (c))
13645 {
13646 val = dp->ascii;
13647 if (SUB_CHAR_TABLE_P (val))
13648 val = XSUB_CHAR_TABLE (val)->contents[c];
13649 }
13650 else
13651 {
13652 Lisp_Object table;
13653
13654 XSETCHAR_TABLE (table, dp);
13655 val = char_table_ref (table, c);
13656 }
13657 if (NILP (val))
13658 val = dp->defalt;
13659 return val;
13660 }
13661
13662
13663 \f
13664 /***********************************************************************
13665 Window Redisplay
13666 ***********************************************************************/
13667
13668 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13669
13670 static void
13671 redisplay_windows (Lisp_Object window)
13672 {
13673 while (!NILP (window))
13674 {
13675 struct window *w = XWINDOW (window);
13676
13677 if (!NILP (w->hchild))
13678 redisplay_windows (w->hchild);
13679 else if (!NILP (w->vchild))
13680 redisplay_windows (w->vchild);
13681 else if (!NILP (w->buffer))
13682 {
13683 displayed_buffer = XBUFFER (w->buffer);
13684 /* Use list_of_error, not Qerror, so that
13685 we catch only errors and don't run the debugger. */
13686 internal_condition_case_1 (redisplay_window_0, window,
13687 list_of_error,
13688 redisplay_window_error);
13689 }
13690
13691 window = w->next;
13692 }
13693 }
13694
13695 static Lisp_Object
13696 redisplay_window_error (Lisp_Object ignore)
13697 {
13698 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13699 return Qnil;
13700 }
13701
13702 static Lisp_Object
13703 redisplay_window_0 (Lisp_Object window)
13704 {
13705 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13706 redisplay_window (window, 0);
13707 return Qnil;
13708 }
13709
13710 static Lisp_Object
13711 redisplay_window_1 (Lisp_Object window)
13712 {
13713 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13714 redisplay_window (window, 1);
13715 return Qnil;
13716 }
13717 \f
13718
13719 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13720 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13721 which positions recorded in ROW differ from current buffer
13722 positions.
13723
13724 Return 0 if cursor is not on this row, 1 otherwise. */
13725
13726 static int
13727 set_cursor_from_row (struct window *w, struct glyph_row *row,
13728 struct glyph_matrix *matrix,
13729 ptrdiff_t delta, ptrdiff_t delta_bytes,
13730 int dy, int dvpos)
13731 {
13732 struct glyph *glyph = row->glyphs[TEXT_AREA];
13733 struct glyph *end = glyph + row->used[TEXT_AREA];
13734 struct glyph *cursor = NULL;
13735 /* The last known character position in row. */
13736 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13737 int x = row->x;
13738 ptrdiff_t pt_old = PT - delta;
13739 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13740 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13741 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13742 /* A glyph beyond the edge of TEXT_AREA which we should never
13743 touch. */
13744 struct glyph *glyphs_end = end;
13745 /* Non-zero means we've found a match for cursor position, but that
13746 glyph has the avoid_cursor_p flag set. */
13747 int match_with_avoid_cursor = 0;
13748 /* Non-zero means we've seen at least one glyph that came from a
13749 display string. */
13750 int string_seen = 0;
13751 /* Largest and smallest buffer positions seen so far during scan of
13752 glyph row. */
13753 ptrdiff_t bpos_max = pos_before;
13754 ptrdiff_t bpos_min = pos_after;
13755 /* Last buffer position covered by an overlay string with an integer
13756 `cursor' property. */
13757 ptrdiff_t bpos_covered = 0;
13758 /* Non-zero means the display string on which to display the cursor
13759 comes from a text property, not from an overlay. */
13760 int string_from_text_prop = 0;
13761
13762 /* Don't even try doing anything if called for a mode-line or
13763 header-line row, since the rest of the code isn't prepared to
13764 deal with such calamities. */
13765 eassert (!row->mode_line_p);
13766 if (row->mode_line_p)
13767 return 0;
13768
13769 /* Skip over glyphs not having an object at the start and the end of
13770 the row. These are special glyphs like truncation marks on
13771 terminal frames. */
13772 if (row->displays_text_p)
13773 {
13774 if (!row->reversed_p)
13775 {
13776 while (glyph < end
13777 && INTEGERP (glyph->object)
13778 && glyph->charpos < 0)
13779 {
13780 x += glyph->pixel_width;
13781 ++glyph;
13782 }
13783 while (end > glyph
13784 && INTEGERP ((end - 1)->object)
13785 /* CHARPOS is zero for blanks and stretch glyphs
13786 inserted by extend_face_to_end_of_line. */
13787 && (end - 1)->charpos <= 0)
13788 --end;
13789 glyph_before = glyph - 1;
13790 glyph_after = end;
13791 }
13792 else
13793 {
13794 struct glyph *g;
13795
13796 /* If the glyph row is reversed, we need to process it from back
13797 to front, so swap the edge pointers. */
13798 glyphs_end = end = glyph - 1;
13799 glyph += row->used[TEXT_AREA] - 1;
13800
13801 while (glyph > end + 1
13802 && INTEGERP (glyph->object)
13803 && glyph->charpos < 0)
13804 {
13805 --glyph;
13806 x -= glyph->pixel_width;
13807 }
13808 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13809 --glyph;
13810 /* By default, in reversed rows we put the cursor on the
13811 rightmost (first in the reading order) glyph. */
13812 for (g = end + 1; g < glyph; g++)
13813 x += g->pixel_width;
13814 while (end < glyph
13815 && INTEGERP ((end + 1)->object)
13816 && (end + 1)->charpos <= 0)
13817 ++end;
13818 glyph_before = glyph + 1;
13819 glyph_after = end;
13820 }
13821 }
13822 else if (row->reversed_p)
13823 {
13824 /* In R2L rows that don't display text, put the cursor on the
13825 rightmost glyph. Case in point: an empty last line that is
13826 part of an R2L paragraph. */
13827 cursor = end - 1;
13828 /* Avoid placing the cursor on the last glyph of the row, where
13829 on terminal frames we hold the vertical border between
13830 adjacent windows. */
13831 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13832 && !WINDOW_RIGHTMOST_P (w)
13833 && cursor == row->glyphs[LAST_AREA] - 1)
13834 cursor--;
13835 x = -1; /* will be computed below, at label compute_x */
13836 }
13837
13838 /* Step 1: Try to find the glyph whose character position
13839 corresponds to point. If that's not possible, find 2 glyphs
13840 whose character positions are the closest to point, one before
13841 point, the other after it. */
13842 if (!row->reversed_p)
13843 while (/* not marched to end of glyph row */
13844 glyph < end
13845 /* glyph was not inserted by redisplay for internal purposes */
13846 && !INTEGERP (glyph->object))
13847 {
13848 if (BUFFERP (glyph->object))
13849 {
13850 ptrdiff_t dpos = glyph->charpos - pt_old;
13851
13852 if (glyph->charpos > bpos_max)
13853 bpos_max = glyph->charpos;
13854 if (glyph->charpos < bpos_min)
13855 bpos_min = glyph->charpos;
13856 if (!glyph->avoid_cursor_p)
13857 {
13858 /* If we hit point, we've found the glyph on which to
13859 display the cursor. */
13860 if (dpos == 0)
13861 {
13862 match_with_avoid_cursor = 0;
13863 break;
13864 }
13865 /* See if we've found a better approximation to
13866 POS_BEFORE or to POS_AFTER. */
13867 if (0 > dpos && dpos > pos_before - pt_old)
13868 {
13869 pos_before = glyph->charpos;
13870 glyph_before = glyph;
13871 }
13872 else if (0 < dpos && dpos < pos_after - pt_old)
13873 {
13874 pos_after = glyph->charpos;
13875 glyph_after = glyph;
13876 }
13877 }
13878 else if (dpos == 0)
13879 match_with_avoid_cursor = 1;
13880 }
13881 else if (STRINGP (glyph->object))
13882 {
13883 Lisp_Object chprop;
13884 ptrdiff_t glyph_pos = glyph->charpos;
13885
13886 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13887 glyph->object);
13888 if (!NILP (chprop))
13889 {
13890 /* If the string came from a `display' text property,
13891 look up the buffer position of that property and
13892 use that position to update bpos_max, as if we
13893 actually saw such a position in one of the row's
13894 glyphs. This helps with supporting integer values
13895 of `cursor' property on the display string in
13896 situations where most or all of the row's buffer
13897 text is completely covered by display properties,
13898 so that no glyph with valid buffer positions is
13899 ever seen in the row. */
13900 ptrdiff_t prop_pos =
13901 string_buffer_position_lim (glyph->object, pos_before,
13902 pos_after, 0);
13903
13904 if (prop_pos >= pos_before)
13905 bpos_max = prop_pos - 1;
13906 }
13907 if (INTEGERP (chprop))
13908 {
13909 bpos_covered = bpos_max + XINT (chprop);
13910 /* If the `cursor' property covers buffer positions up
13911 to and including point, we should display cursor on
13912 this glyph. Note that, if a `cursor' property on one
13913 of the string's characters has an integer value, we
13914 will break out of the loop below _before_ we get to
13915 the position match above. IOW, integer values of
13916 the `cursor' property override the "exact match for
13917 point" strategy of positioning the cursor. */
13918 /* Implementation note: bpos_max == pt_old when, e.g.,
13919 we are in an empty line, where bpos_max is set to
13920 MATRIX_ROW_START_CHARPOS, see above. */
13921 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13922 {
13923 cursor = glyph;
13924 break;
13925 }
13926 }
13927
13928 string_seen = 1;
13929 }
13930 x += glyph->pixel_width;
13931 ++glyph;
13932 }
13933 else if (glyph > end) /* row is reversed */
13934 while (!INTEGERP (glyph->object))
13935 {
13936 if (BUFFERP (glyph->object))
13937 {
13938 ptrdiff_t dpos = glyph->charpos - pt_old;
13939
13940 if (glyph->charpos > bpos_max)
13941 bpos_max = glyph->charpos;
13942 if (glyph->charpos < bpos_min)
13943 bpos_min = glyph->charpos;
13944 if (!glyph->avoid_cursor_p)
13945 {
13946 if (dpos == 0)
13947 {
13948 match_with_avoid_cursor = 0;
13949 break;
13950 }
13951 if (0 > dpos && dpos > pos_before - pt_old)
13952 {
13953 pos_before = glyph->charpos;
13954 glyph_before = glyph;
13955 }
13956 else if (0 < dpos && dpos < pos_after - pt_old)
13957 {
13958 pos_after = glyph->charpos;
13959 glyph_after = glyph;
13960 }
13961 }
13962 else if (dpos == 0)
13963 match_with_avoid_cursor = 1;
13964 }
13965 else if (STRINGP (glyph->object))
13966 {
13967 Lisp_Object chprop;
13968 ptrdiff_t glyph_pos = glyph->charpos;
13969
13970 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13971 glyph->object);
13972 if (!NILP (chprop))
13973 {
13974 ptrdiff_t prop_pos =
13975 string_buffer_position_lim (glyph->object, pos_before,
13976 pos_after, 0);
13977
13978 if (prop_pos >= pos_before)
13979 bpos_max = prop_pos - 1;
13980 }
13981 if (INTEGERP (chprop))
13982 {
13983 bpos_covered = bpos_max + XINT (chprop);
13984 /* If the `cursor' property covers buffer positions up
13985 to and including point, we should display cursor on
13986 this glyph. */
13987 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13988 {
13989 cursor = glyph;
13990 break;
13991 }
13992 }
13993 string_seen = 1;
13994 }
13995 --glyph;
13996 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
13997 {
13998 x--; /* can't use any pixel_width */
13999 break;
14000 }
14001 x -= glyph->pixel_width;
14002 }
14003
14004 /* Step 2: If we didn't find an exact match for point, we need to
14005 look for a proper place to put the cursor among glyphs between
14006 GLYPH_BEFORE and GLYPH_AFTER. */
14007 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14008 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14009 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14010 {
14011 /* An empty line has a single glyph whose OBJECT is zero and
14012 whose CHARPOS is the position of a newline on that line.
14013 Note that on a TTY, there are more glyphs after that, which
14014 were produced by extend_face_to_end_of_line, but their
14015 CHARPOS is zero or negative. */
14016 int empty_line_p =
14017 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14018 && INTEGERP (glyph->object) && glyph->charpos > 0
14019 /* On a TTY, continued and truncated rows also have a glyph at
14020 their end whose OBJECT is zero and whose CHARPOS is
14021 positive (the continuation and truncation glyphs), but such
14022 rows are obviously not "empty". */
14023 && !(row->continued_p || row->truncated_on_right_p);
14024
14025 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14026 {
14027 ptrdiff_t ellipsis_pos;
14028
14029 /* Scan back over the ellipsis glyphs. */
14030 if (!row->reversed_p)
14031 {
14032 ellipsis_pos = (glyph - 1)->charpos;
14033 while (glyph > row->glyphs[TEXT_AREA]
14034 && (glyph - 1)->charpos == ellipsis_pos)
14035 glyph--, x -= glyph->pixel_width;
14036 /* That loop always goes one position too far, including
14037 the glyph before the ellipsis. So scan forward over
14038 that one. */
14039 x += glyph->pixel_width;
14040 glyph++;
14041 }
14042 else /* row is reversed */
14043 {
14044 ellipsis_pos = (glyph + 1)->charpos;
14045 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14046 && (glyph + 1)->charpos == ellipsis_pos)
14047 glyph++, x += glyph->pixel_width;
14048 x -= glyph->pixel_width;
14049 glyph--;
14050 }
14051 }
14052 else if (match_with_avoid_cursor)
14053 {
14054 cursor = glyph_after;
14055 x = -1;
14056 }
14057 else if (string_seen)
14058 {
14059 int incr = row->reversed_p ? -1 : +1;
14060
14061 /* Need to find the glyph that came out of a string which is
14062 present at point. That glyph is somewhere between
14063 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14064 positioned between POS_BEFORE and POS_AFTER in the
14065 buffer. */
14066 struct glyph *start, *stop;
14067 ptrdiff_t pos = pos_before;
14068
14069 x = -1;
14070
14071 /* If the row ends in a newline from a display string,
14072 reordering could have moved the glyphs belonging to the
14073 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14074 in this case we extend the search to the last glyph in
14075 the row that was not inserted by redisplay. */
14076 if (row->ends_in_newline_from_string_p)
14077 {
14078 glyph_after = end;
14079 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14080 }
14081
14082 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14083 correspond to POS_BEFORE and POS_AFTER, respectively. We
14084 need START and STOP in the order that corresponds to the
14085 row's direction as given by its reversed_p flag. If the
14086 directionality of characters between POS_BEFORE and
14087 POS_AFTER is the opposite of the row's base direction,
14088 these characters will have been reordered for display,
14089 and we need to reverse START and STOP. */
14090 if (!row->reversed_p)
14091 {
14092 start = min (glyph_before, glyph_after);
14093 stop = max (glyph_before, glyph_after);
14094 }
14095 else
14096 {
14097 start = max (glyph_before, glyph_after);
14098 stop = min (glyph_before, glyph_after);
14099 }
14100 for (glyph = start + incr;
14101 row->reversed_p ? glyph > stop : glyph < stop; )
14102 {
14103
14104 /* Any glyphs that come from the buffer are here because
14105 of bidi reordering. Skip them, and only pay
14106 attention to glyphs that came from some string. */
14107 if (STRINGP (glyph->object))
14108 {
14109 Lisp_Object str;
14110 ptrdiff_t tem;
14111 /* If the display property covers the newline, we
14112 need to search for it one position farther. */
14113 ptrdiff_t lim = pos_after
14114 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14115
14116 string_from_text_prop = 0;
14117 str = glyph->object;
14118 tem = string_buffer_position_lim (str, pos, lim, 0);
14119 if (tem == 0 /* from overlay */
14120 || pos <= tem)
14121 {
14122 /* If the string from which this glyph came is
14123 found in the buffer at point, or at position
14124 that is closer to point than pos_after, then
14125 we've found the glyph we've been looking for.
14126 If it comes from an overlay (tem == 0), and
14127 it has the `cursor' property on one of its
14128 glyphs, record that glyph as a candidate for
14129 displaying the cursor. (As in the
14130 unidirectional version, we will display the
14131 cursor on the last candidate we find.) */
14132 if (tem == 0
14133 || tem == pt_old
14134 || (tem - pt_old > 0 && tem < pos_after))
14135 {
14136 /* The glyphs from this string could have
14137 been reordered. Find the one with the
14138 smallest string position. Or there could
14139 be a character in the string with the
14140 `cursor' property, which means display
14141 cursor on that character's glyph. */
14142 ptrdiff_t strpos = glyph->charpos;
14143
14144 if (tem)
14145 {
14146 cursor = glyph;
14147 string_from_text_prop = 1;
14148 }
14149 for ( ;
14150 (row->reversed_p ? glyph > stop : glyph < stop)
14151 && EQ (glyph->object, str);
14152 glyph += incr)
14153 {
14154 Lisp_Object cprop;
14155 ptrdiff_t gpos = glyph->charpos;
14156
14157 cprop = Fget_char_property (make_number (gpos),
14158 Qcursor,
14159 glyph->object);
14160 if (!NILP (cprop))
14161 {
14162 cursor = glyph;
14163 break;
14164 }
14165 if (tem && glyph->charpos < strpos)
14166 {
14167 strpos = glyph->charpos;
14168 cursor = glyph;
14169 }
14170 }
14171
14172 if (tem == pt_old
14173 || (tem - pt_old > 0 && tem < pos_after))
14174 goto compute_x;
14175 }
14176 if (tem)
14177 pos = tem + 1; /* don't find previous instances */
14178 }
14179 /* This string is not what we want; skip all of the
14180 glyphs that came from it. */
14181 while ((row->reversed_p ? glyph > stop : glyph < stop)
14182 && EQ (glyph->object, str))
14183 glyph += incr;
14184 }
14185 else
14186 glyph += incr;
14187 }
14188
14189 /* If we reached the end of the line, and END was from a string,
14190 the cursor is not on this line. */
14191 if (cursor == NULL
14192 && (row->reversed_p ? glyph <= end : glyph >= end)
14193 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14194 && STRINGP (end->object)
14195 && row->continued_p)
14196 return 0;
14197 }
14198 /* A truncated row may not include PT among its character positions.
14199 Setting the cursor inside the scroll margin will trigger
14200 recalculation of hscroll in hscroll_window_tree. But if a
14201 display string covers point, defer to the string-handling
14202 code below to figure this out. */
14203 else if (row->truncated_on_left_p && pt_old < bpos_min)
14204 {
14205 cursor = glyph_before;
14206 x = -1;
14207 }
14208 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14209 /* Zero-width characters produce no glyphs. */
14210 || (!empty_line_p
14211 && (row->reversed_p
14212 ? glyph_after > glyphs_end
14213 : glyph_after < glyphs_end)))
14214 {
14215 cursor = glyph_after;
14216 x = -1;
14217 }
14218 }
14219
14220 compute_x:
14221 if (cursor != NULL)
14222 glyph = cursor;
14223 else if (glyph == glyphs_end
14224 && pos_before == pos_after
14225 && STRINGP ((row->reversed_p
14226 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14227 : row->glyphs[TEXT_AREA])->object))
14228 {
14229 /* If all the glyphs of this row came from strings, put the
14230 cursor on the first glyph of the row. This avoids having the
14231 cursor outside of the text area in this very rare and hard
14232 use case. */
14233 glyph =
14234 row->reversed_p
14235 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14236 : row->glyphs[TEXT_AREA];
14237 }
14238 if (x < 0)
14239 {
14240 struct glyph *g;
14241
14242 /* Need to compute x that corresponds to GLYPH. */
14243 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14244 {
14245 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14246 emacs_abort ();
14247 x += g->pixel_width;
14248 }
14249 }
14250
14251 /* ROW could be part of a continued line, which, under bidi
14252 reordering, might have other rows whose start and end charpos
14253 occlude point. Only set w->cursor if we found a better
14254 approximation to the cursor position than we have from previously
14255 examined candidate rows belonging to the same continued line. */
14256 if (/* we already have a candidate row */
14257 w->cursor.vpos >= 0
14258 /* that candidate is not the row we are processing */
14259 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14260 /* Make sure cursor.vpos specifies a row whose start and end
14261 charpos occlude point, and it is valid candidate for being a
14262 cursor-row. This is because some callers of this function
14263 leave cursor.vpos at the row where the cursor was displayed
14264 during the last redisplay cycle. */
14265 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14266 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14267 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14268 {
14269 struct glyph *g1 =
14270 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14271
14272 /* Don't consider glyphs that are outside TEXT_AREA. */
14273 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14274 return 0;
14275 /* Keep the candidate whose buffer position is the closest to
14276 point or has the `cursor' property. */
14277 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14278 w->cursor.hpos >= 0
14279 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14280 && ((BUFFERP (g1->object)
14281 && (g1->charpos == pt_old /* an exact match always wins */
14282 || (BUFFERP (glyph->object)
14283 && eabs (g1->charpos - pt_old)
14284 < eabs (glyph->charpos - pt_old))))
14285 /* previous candidate is a glyph from a string that has
14286 a non-nil `cursor' property */
14287 || (STRINGP (g1->object)
14288 && (!NILP (Fget_char_property (make_number (g1->charpos),
14289 Qcursor, g1->object))
14290 /* previous candidate is from the same display
14291 string as this one, and the display string
14292 came from a text property */
14293 || (EQ (g1->object, glyph->object)
14294 && string_from_text_prop)
14295 /* this candidate is from newline and its
14296 position is not an exact match */
14297 || (INTEGERP (glyph->object)
14298 && glyph->charpos != pt_old)))))
14299 return 0;
14300 /* If this candidate gives an exact match, use that. */
14301 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14302 /* If this candidate is a glyph created for the
14303 terminating newline of a line, and point is on that
14304 newline, it wins because it's an exact match. */
14305 || (!row->continued_p
14306 && INTEGERP (glyph->object)
14307 && glyph->charpos == 0
14308 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14309 /* Otherwise, keep the candidate that comes from a row
14310 spanning less buffer positions. This may win when one or
14311 both candidate positions are on glyphs that came from
14312 display strings, for which we cannot compare buffer
14313 positions. */
14314 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14315 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14316 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14317 return 0;
14318 }
14319 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14320 w->cursor.x = x;
14321 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14322 w->cursor.y = row->y + dy;
14323
14324 if (w == XWINDOW (selected_window))
14325 {
14326 if (!row->continued_p
14327 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14328 && row->x == 0)
14329 {
14330 this_line_buffer = XBUFFER (w->buffer);
14331
14332 CHARPOS (this_line_start_pos)
14333 = MATRIX_ROW_START_CHARPOS (row) + delta;
14334 BYTEPOS (this_line_start_pos)
14335 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14336
14337 CHARPOS (this_line_end_pos)
14338 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14339 BYTEPOS (this_line_end_pos)
14340 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14341
14342 this_line_y = w->cursor.y;
14343 this_line_pixel_height = row->height;
14344 this_line_vpos = w->cursor.vpos;
14345 this_line_start_x = row->x;
14346 }
14347 else
14348 CHARPOS (this_line_start_pos) = 0;
14349 }
14350
14351 return 1;
14352 }
14353
14354
14355 /* Run window scroll functions, if any, for WINDOW with new window
14356 start STARTP. Sets the window start of WINDOW to that position.
14357
14358 We assume that the window's buffer is really current. */
14359
14360 static struct text_pos
14361 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14362 {
14363 struct window *w = XWINDOW (window);
14364 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14365
14366 if (current_buffer != XBUFFER (w->buffer))
14367 emacs_abort ();
14368
14369 if (!NILP (Vwindow_scroll_functions))
14370 {
14371 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14372 make_number (CHARPOS (startp)));
14373 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14374 /* In case the hook functions switch buffers. */
14375 set_buffer_internal (XBUFFER (w->buffer));
14376 }
14377
14378 return startp;
14379 }
14380
14381
14382 /* Make sure the line containing the cursor is fully visible.
14383 A value of 1 means there is nothing to be done.
14384 (Either the line is fully visible, or it cannot be made so,
14385 or we cannot tell.)
14386
14387 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14388 is higher than window.
14389
14390 A value of 0 means the caller should do scrolling
14391 as if point had gone off the screen. */
14392
14393 static int
14394 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14395 {
14396 struct glyph_matrix *matrix;
14397 struct glyph_row *row;
14398 int window_height;
14399
14400 if (!make_cursor_line_fully_visible_p)
14401 return 1;
14402
14403 /* It's not always possible to find the cursor, e.g, when a window
14404 is full of overlay strings. Don't do anything in that case. */
14405 if (w->cursor.vpos < 0)
14406 return 1;
14407
14408 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14409 row = MATRIX_ROW (matrix, w->cursor.vpos);
14410
14411 /* If the cursor row is not partially visible, there's nothing to do. */
14412 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14413 return 1;
14414
14415 /* If the row the cursor is in is taller than the window's height,
14416 it's not clear what to do, so do nothing. */
14417 window_height = window_box_height (w);
14418 if (row->height >= window_height)
14419 {
14420 if (!force_p || MINI_WINDOW_P (w)
14421 || w->vscroll || w->cursor.vpos == 0)
14422 return 1;
14423 }
14424 return 0;
14425 }
14426
14427
14428 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14429 non-zero means only WINDOW is redisplayed in redisplay_internal.
14430 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14431 in redisplay_window to bring a partially visible line into view in
14432 the case that only the cursor has moved.
14433
14434 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14435 last screen line's vertical height extends past the end of the screen.
14436
14437 Value is
14438
14439 1 if scrolling succeeded
14440
14441 0 if scrolling didn't find point.
14442
14443 -1 if new fonts have been loaded so that we must interrupt
14444 redisplay, adjust glyph matrices, and try again. */
14445
14446 enum
14447 {
14448 SCROLLING_SUCCESS,
14449 SCROLLING_FAILED,
14450 SCROLLING_NEED_LARGER_MATRICES
14451 };
14452
14453 /* If scroll-conservatively is more than this, never recenter.
14454
14455 If you change this, don't forget to update the doc string of
14456 `scroll-conservatively' and the Emacs manual. */
14457 #define SCROLL_LIMIT 100
14458
14459 static int
14460 try_scrolling (Lisp_Object window, int just_this_one_p,
14461 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14462 int temp_scroll_step, int last_line_misfit)
14463 {
14464 struct window *w = XWINDOW (window);
14465 struct frame *f = XFRAME (w->frame);
14466 struct text_pos pos, startp;
14467 struct it it;
14468 int this_scroll_margin, scroll_max, rc, height;
14469 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14470 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14471 Lisp_Object aggressive;
14472 /* We will never try scrolling more than this number of lines. */
14473 int scroll_limit = SCROLL_LIMIT;
14474
14475 #ifdef GLYPH_DEBUG
14476 debug_method_add (w, "try_scrolling");
14477 #endif
14478
14479 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14480
14481 /* Compute scroll margin height in pixels. We scroll when point is
14482 within this distance from the top or bottom of the window. */
14483 if (scroll_margin > 0)
14484 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14485 * FRAME_LINE_HEIGHT (f);
14486 else
14487 this_scroll_margin = 0;
14488
14489 /* Force arg_scroll_conservatively to have a reasonable value, to
14490 avoid scrolling too far away with slow move_it_* functions. Note
14491 that the user can supply scroll-conservatively equal to
14492 `most-positive-fixnum', which can be larger than INT_MAX. */
14493 if (arg_scroll_conservatively > scroll_limit)
14494 {
14495 arg_scroll_conservatively = scroll_limit + 1;
14496 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
14497 }
14498 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14499 /* Compute how much we should try to scroll maximally to bring
14500 point into view. */
14501 scroll_max = (max (scroll_step,
14502 max (arg_scroll_conservatively, temp_scroll_step))
14503 * FRAME_LINE_HEIGHT (f));
14504 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14505 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14506 /* We're trying to scroll because of aggressive scrolling but no
14507 scroll_step is set. Choose an arbitrary one. */
14508 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
14509 else
14510 scroll_max = 0;
14511
14512 too_near_end:
14513
14514 /* Decide whether to scroll down. */
14515 if (PT > CHARPOS (startp))
14516 {
14517 int scroll_margin_y;
14518
14519 /* Compute the pixel ypos of the scroll margin, then move IT to
14520 either that ypos or PT, whichever comes first. */
14521 start_display (&it, w, startp);
14522 scroll_margin_y = it.last_visible_y - this_scroll_margin
14523 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
14524 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14525 (MOVE_TO_POS | MOVE_TO_Y));
14526
14527 if (PT > CHARPOS (it.current.pos))
14528 {
14529 int y0 = line_bottom_y (&it);
14530 /* Compute how many pixels below window bottom to stop searching
14531 for PT. This avoids costly search for PT that is far away if
14532 the user limited scrolling by a small number of lines, but
14533 always finds PT if scroll_conservatively is set to a large
14534 number, such as most-positive-fixnum. */
14535 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
14536 int y_to_move = it.last_visible_y + slack;
14537
14538 /* Compute the distance from the scroll margin to PT or to
14539 the scroll limit, whichever comes first. This should
14540 include the height of the cursor line, to make that line
14541 fully visible. */
14542 move_it_to (&it, PT, -1, y_to_move,
14543 -1, MOVE_TO_POS | MOVE_TO_Y);
14544 dy = line_bottom_y (&it) - y0;
14545
14546 if (dy > scroll_max)
14547 return SCROLLING_FAILED;
14548
14549 if (dy > 0)
14550 scroll_down_p = 1;
14551 }
14552 }
14553
14554 if (scroll_down_p)
14555 {
14556 /* Point is in or below the bottom scroll margin, so move the
14557 window start down. If scrolling conservatively, move it just
14558 enough down to make point visible. If scroll_step is set,
14559 move it down by scroll_step. */
14560 if (arg_scroll_conservatively)
14561 amount_to_scroll
14562 = min (max (dy, FRAME_LINE_HEIGHT (f)),
14563 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
14564 else if (scroll_step || temp_scroll_step)
14565 amount_to_scroll = scroll_max;
14566 else
14567 {
14568 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14569 height = WINDOW_BOX_TEXT_HEIGHT (w);
14570 if (NUMBERP (aggressive))
14571 {
14572 double float_amount = XFLOATINT (aggressive) * height;
14573 int aggressive_scroll = float_amount;
14574 if (aggressive_scroll == 0 && float_amount > 0)
14575 aggressive_scroll = 1;
14576 /* Don't let point enter the scroll margin near top of
14577 the window. This could happen if the value of
14578 scroll_up_aggressively is too large and there are
14579 non-zero margins, because scroll_up_aggressively
14580 means put point that fraction of window height
14581 _from_the_bottom_margin_. */
14582 if (aggressive_scroll + 2*this_scroll_margin > height)
14583 aggressive_scroll = height - 2*this_scroll_margin;
14584 amount_to_scroll = dy + aggressive_scroll;
14585 }
14586 }
14587
14588 if (amount_to_scroll <= 0)
14589 return SCROLLING_FAILED;
14590
14591 start_display (&it, w, startp);
14592 if (arg_scroll_conservatively <= scroll_limit)
14593 move_it_vertically (&it, amount_to_scroll);
14594 else
14595 {
14596 /* Extra precision for users who set scroll-conservatively
14597 to a large number: make sure the amount we scroll
14598 the window start is never less than amount_to_scroll,
14599 which was computed as distance from window bottom to
14600 point. This matters when lines at window top and lines
14601 below window bottom have different height. */
14602 struct it it1;
14603 void *it1data = NULL;
14604 /* We use a temporary it1 because line_bottom_y can modify
14605 its argument, if it moves one line down; see there. */
14606 int start_y;
14607
14608 SAVE_IT (it1, it, it1data);
14609 start_y = line_bottom_y (&it1);
14610 do {
14611 RESTORE_IT (&it, &it, it1data);
14612 move_it_by_lines (&it, 1);
14613 SAVE_IT (it1, it, it1data);
14614 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14615 }
14616
14617 /* If STARTP is unchanged, move it down another screen line. */
14618 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14619 move_it_by_lines (&it, 1);
14620 startp = it.current.pos;
14621 }
14622 else
14623 {
14624 struct text_pos scroll_margin_pos = startp;
14625
14626 /* See if point is inside the scroll margin at the top of the
14627 window. */
14628 if (this_scroll_margin)
14629 {
14630 start_display (&it, w, startp);
14631 move_it_vertically (&it, this_scroll_margin);
14632 scroll_margin_pos = it.current.pos;
14633 }
14634
14635 if (PT < CHARPOS (scroll_margin_pos))
14636 {
14637 /* Point is in the scroll margin at the top of the window or
14638 above what is displayed in the window. */
14639 int y0, y_to_move;
14640
14641 /* Compute the vertical distance from PT to the scroll
14642 margin position. Move as far as scroll_max allows, or
14643 one screenful, or 10 screen lines, whichever is largest.
14644 Give up if distance is greater than scroll_max or if we
14645 didn't reach the scroll margin position. */
14646 SET_TEXT_POS (pos, PT, PT_BYTE);
14647 start_display (&it, w, pos);
14648 y0 = it.current_y;
14649 y_to_move = max (it.last_visible_y,
14650 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
14651 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14652 y_to_move, -1,
14653 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14654 dy = it.current_y - y0;
14655 if (dy > scroll_max
14656 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14657 return SCROLLING_FAILED;
14658
14659 /* Compute new window start. */
14660 start_display (&it, w, startp);
14661
14662 if (arg_scroll_conservatively)
14663 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
14664 max (scroll_step, temp_scroll_step));
14665 else if (scroll_step || temp_scroll_step)
14666 amount_to_scroll = scroll_max;
14667 else
14668 {
14669 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14670 height = WINDOW_BOX_TEXT_HEIGHT (w);
14671 if (NUMBERP (aggressive))
14672 {
14673 double float_amount = XFLOATINT (aggressive) * height;
14674 int aggressive_scroll = float_amount;
14675 if (aggressive_scroll == 0 && float_amount > 0)
14676 aggressive_scroll = 1;
14677 /* Don't let point enter the scroll margin near
14678 bottom of the window, if the value of
14679 scroll_down_aggressively happens to be too
14680 large. */
14681 if (aggressive_scroll + 2*this_scroll_margin > height)
14682 aggressive_scroll = height - 2*this_scroll_margin;
14683 amount_to_scroll = dy + aggressive_scroll;
14684 }
14685 }
14686
14687 if (amount_to_scroll <= 0)
14688 return SCROLLING_FAILED;
14689
14690 move_it_vertically_backward (&it, amount_to_scroll);
14691 startp = it.current.pos;
14692 }
14693 }
14694
14695 /* Run window scroll functions. */
14696 startp = run_window_scroll_functions (window, startp);
14697
14698 /* Display the window. Give up if new fonts are loaded, or if point
14699 doesn't appear. */
14700 if (!try_window (window, startp, 0))
14701 rc = SCROLLING_NEED_LARGER_MATRICES;
14702 else if (w->cursor.vpos < 0)
14703 {
14704 clear_glyph_matrix (w->desired_matrix);
14705 rc = SCROLLING_FAILED;
14706 }
14707 else
14708 {
14709 /* Maybe forget recorded base line for line number display. */
14710 if (!just_this_one_p
14711 || current_buffer->clip_changed
14712 || BEG_UNCHANGED < CHARPOS (startp))
14713 wset_base_line_number (w, Qnil);
14714
14715 /* If cursor ends up on a partially visible line,
14716 treat that as being off the bottom of the screen. */
14717 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14718 /* It's possible that the cursor is on the first line of the
14719 buffer, which is partially obscured due to a vscroll
14720 (Bug#7537). In that case, avoid looping forever . */
14721 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14722 {
14723 clear_glyph_matrix (w->desired_matrix);
14724 ++extra_scroll_margin_lines;
14725 goto too_near_end;
14726 }
14727 rc = SCROLLING_SUCCESS;
14728 }
14729
14730 return rc;
14731 }
14732
14733
14734 /* Compute a suitable window start for window W if display of W starts
14735 on a continuation line. Value is non-zero if a new window start
14736 was computed.
14737
14738 The new window start will be computed, based on W's width, starting
14739 from the start of the continued line. It is the start of the
14740 screen line with the minimum distance from the old start W->start. */
14741
14742 static int
14743 compute_window_start_on_continuation_line (struct window *w)
14744 {
14745 struct text_pos pos, start_pos;
14746 int window_start_changed_p = 0;
14747
14748 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14749
14750 /* If window start is on a continuation line... Window start may be
14751 < BEGV in case there's invisible text at the start of the
14752 buffer (M-x rmail, for example). */
14753 if (CHARPOS (start_pos) > BEGV
14754 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14755 {
14756 struct it it;
14757 struct glyph_row *row;
14758
14759 /* Handle the case that the window start is out of range. */
14760 if (CHARPOS (start_pos) < BEGV)
14761 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14762 else if (CHARPOS (start_pos) > ZV)
14763 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14764
14765 /* Find the start of the continued line. This should be fast
14766 because scan_buffer is fast (newline cache). */
14767 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14768 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14769 row, DEFAULT_FACE_ID);
14770 reseat_at_previous_visible_line_start (&it);
14771
14772 /* If the line start is "too far" away from the window start,
14773 say it takes too much time to compute a new window start. */
14774 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14775 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14776 {
14777 int min_distance, distance;
14778
14779 /* Move forward by display lines to find the new window
14780 start. If window width was enlarged, the new start can
14781 be expected to be > the old start. If window width was
14782 decreased, the new window start will be < the old start.
14783 So, we're looking for the display line start with the
14784 minimum distance from the old window start. */
14785 pos = it.current.pos;
14786 min_distance = INFINITY;
14787 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14788 distance < min_distance)
14789 {
14790 min_distance = distance;
14791 pos = it.current.pos;
14792 move_it_by_lines (&it, 1);
14793 }
14794
14795 /* Set the window start there. */
14796 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14797 window_start_changed_p = 1;
14798 }
14799 }
14800
14801 return window_start_changed_p;
14802 }
14803
14804
14805 /* Try cursor movement in case text has not changed in window WINDOW,
14806 with window start STARTP. Value is
14807
14808 CURSOR_MOVEMENT_SUCCESS if successful
14809
14810 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14811
14812 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14813 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14814 we want to scroll as if scroll-step were set to 1. See the code.
14815
14816 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14817 which case we have to abort this redisplay, and adjust matrices
14818 first. */
14819
14820 enum
14821 {
14822 CURSOR_MOVEMENT_SUCCESS,
14823 CURSOR_MOVEMENT_CANNOT_BE_USED,
14824 CURSOR_MOVEMENT_MUST_SCROLL,
14825 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14826 };
14827
14828 static int
14829 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14830 {
14831 struct window *w = XWINDOW (window);
14832 struct frame *f = XFRAME (w->frame);
14833 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14834
14835 #ifdef GLYPH_DEBUG
14836 if (inhibit_try_cursor_movement)
14837 return rc;
14838 #endif
14839
14840 /* Previously, there was a check for Lisp integer in the
14841 if-statement below. Now, this field is converted to
14842 ptrdiff_t, thus zero means invalid position in a buffer. */
14843 eassert (w->last_point > 0);
14844
14845 /* Handle case where text has not changed, only point, and it has
14846 not moved off the frame. */
14847 if (/* Point may be in this window. */
14848 PT >= CHARPOS (startp)
14849 /* Selective display hasn't changed. */
14850 && !current_buffer->clip_changed
14851 /* Function force-mode-line-update is used to force a thorough
14852 redisplay. It sets either windows_or_buffers_changed or
14853 update_mode_lines. So don't take a shortcut here for these
14854 cases. */
14855 && !update_mode_lines
14856 && !windows_or_buffers_changed
14857 && !cursor_type_changed
14858 /* Can't use this case if highlighting a region. When a
14859 region exists, cursor movement has to do more than just
14860 set the cursor. */
14861 && markpos_of_region () < 0
14862 && NILP (w->region_showing)
14863 && NILP (Vshow_trailing_whitespace)
14864 /* This code is not used for mini-buffer for the sake of the case
14865 of redisplaying to replace an echo area message; since in
14866 that case the mini-buffer contents per se are usually
14867 unchanged. This code is of no real use in the mini-buffer
14868 since the handling of this_line_start_pos, etc., in redisplay
14869 handles the same cases. */
14870 && !EQ (window, minibuf_window)
14871 /* When splitting windows or for new windows, it happens that
14872 redisplay is called with a nil window_end_vpos or one being
14873 larger than the window. This should really be fixed in
14874 window.c. I don't have this on my list, now, so we do
14875 approximately the same as the old redisplay code. --gerd. */
14876 && INTEGERP (w->window_end_vpos)
14877 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14878 && (FRAME_WINDOW_P (f)
14879 || !overlay_arrow_in_current_buffer_p ()))
14880 {
14881 int this_scroll_margin, top_scroll_margin;
14882 struct glyph_row *row = NULL;
14883
14884 #ifdef GLYPH_DEBUG
14885 debug_method_add (w, "cursor movement");
14886 #endif
14887
14888 /* Scroll if point within this distance from the top or bottom
14889 of the window. This is a pixel value. */
14890 if (scroll_margin > 0)
14891 {
14892 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14893 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14894 }
14895 else
14896 this_scroll_margin = 0;
14897
14898 top_scroll_margin = this_scroll_margin;
14899 if (WINDOW_WANTS_HEADER_LINE_P (w))
14900 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
14901
14902 /* Start with the row the cursor was displayed during the last
14903 not paused redisplay. Give up if that row is not valid. */
14904 if (w->last_cursor.vpos < 0
14905 || w->last_cursor.vpos >= w->current_matrix->nrows)
14906 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14907 else
14908 {
14909 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
14910 if (row->mode_line_p)
14911 ++row;
14912 if (!row->enabled_p)
14913 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14914 }
14915
14916 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
14917 {
14918 int scroll_p = 0, must_scroll = 0;
14919 int last_y = window_text_bottom_y (w) - this_scroll_margin;
14920
14921 if (PT > w->last_point)
14922 {
14923 /* Point has moved forward. */
14924 while (MATRIX_ROW_END_CHARPOS (row) < PT
14925 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
14926 {
14927 eassert (row->enabled_p);
14928 ++row;
14929 }
14930
14931 /* If the end position of a row equals the start
14932 position of the next row, and PT is at that position,
14933 we would rather display cursor in the next line. */
14934 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14935 && MATRIX_ROW_END_CHARPOS (row) == PT
14936 && row < w->current_matrix->rows
14937 + w->current_matrix->nrows - 1
14938 && MATRIX_ROW_START_CHARPOS (row+1) == PT
14939 && !cursor_row_p (row))
14940 ++row;
14941
14942 /* If within the scroll margin, scroll. Note that
14943 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
14944 the next line would be drawn, and that
14945 this_scroll_margin can be zero. */
14946 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
14947 || PT > MATRIX_ROW_END_CHARPOS (row)
14948 /* Line is completely visible last line in window
14949 and PT is to be set in the next line. */
14950 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
14951 && PT == MATRIX_ROW_END_CHARPOS (row)
14952 && !row->ends_at_zv_p
14953 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14954 scroll_p = 1;
14955 }
14956 else if (PT < w->last_point)
14957 {
14958 /* Cursor has to be moved backward. Note that PT >=
14959 CHARPOS (startp) because of the outer if-statement. */
14960 while (!row->mode_line_p
14961 && (MATRIX_ROW_START_CHARPOS (row) > PT
14962 || (MATRIX_ROW_START_CHARPOS (row) == PT
14963 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
14964 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
14965 row > w->current_matrix->rows
14966 && (row-1)->ends_in_newline_from_string_p))))
14967 && (row->y > top_scroll_margin
14968 || CHARPOS (startp) == BEGV))
14969 {
14970 eassert (row->enabled_p);
14971 --row;
14972 }
14973
14974 /* Consider the following case: Window starts at BEGV,
14975 there is invisible, intangible text at BEGV, so that
14976 display starts at some point START > BEGV. It can
14977 happen that we are called with PT somewhere between
14978 BEGV and START. Try to handle that case. */
14979 if (row < w->current_matrix->rows
14980 || row->mode_line_p)
14981 {
14982 row = w->current_matrix->rows;
14983 if (row->mode_line_p)
14984 ++row;
14985 }
14986
14987 /* Due to newlines in overlay strings, we may have to
14988 skip forward over overlay strings. */
14989 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14990 && MATRIX_ROW_END_CHARPOS (row) == PT
14991 && !cursor_row_p (row))
14992 ++row;
14993
14994 /* If within the scroll margin, scroll. */
14995 if (row->y < top_scroll_margin
14996 && CHARPOS (startp) != BEGV)
14997 scroll_p = 1;
14998 }
14999 else
15000 {
15001 /* Cursor did not move. So don't scroll even if cursor line
15002 is partially visible, as it was so before. */
15003 rc = CURSOR_MOVEMENT_SUCCESS;
15004 }
15005
15006 if (PT < MATRIX_ROW_START_CHARPOS (row)
15007 || PT > MATRIX_ROW_END_CHARPOS (row))
15008 {
15009 /* if PT is not in the glyph row, give up. */
15010 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15011 must_scroll = 1;
15012 }
15013 else if (rc != CURSOR_MOVEMENT_SUCCESS
15014 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15015 {
15016 struct glyph_row *row1;
15017
15018 /* If rows are bidi-reordered and point moved, back up
15019 until we find a row that does not belong to a
15020 continuation line. This is because we must consider
15021 all rows of a continued line as candidates for the
15022 new cursor positioning, since row start and end
15023 positions change non-linearly with vertical position
15024 in such rows. */
15025 /* FIXME: Revisit this when glyph ``spilling'' in
15026 continuation lines' rows is implemented for
15027 bidi-reordered rows. */
15028 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15029 MATRIX_ROW_CONTINUATION_LINE_P (row);
15030 --row)
15031 {
15032 /* If we hit the beginning of the displayed portion
15033 without finding the first row of a continued
15034 line, give up. */
15035 if (row <= row1)
15036 {
15037 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15038 break;
15039 }
15040 eassert (row->enabled_p);
15041 }
15042 }
15043 if (must_scroll)
15044 ;
15045 else if (rc != CURSOR_MOVEMENT_SUCCESS
15046 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15047 /* Make sure this isn't a header line by any chance, since
15048 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15049 && !row->mode_line_p
15050 && make_cursor_line_fully_visible_p)
15051 {
15052 if (PT == MATRIX_ROW_END_CHARPOS (row)
15053 && !row->ends_at_zv_p
15054 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15055 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15056 else if (row->height > window_box_height (w))
15057 {
15058 /* If we end up in a partially visible line, let's
15059 make it fully visible, except when it's taller
15060 than the window, in which case we can't do much
15061 about it. */
15062 *scroll_step = 1;
15063 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15064 }
15065 else
15066 {
15067 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15068 if (!cursor_row_fully_visible_p (w, 0, 1))
15069 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15070 else
15071 rc = CURSOR_MOVEMENT_SUCCESS;
15072 }
15073 }
15074 else if (scroll_p)
15075 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15076 else if (rc != CURSOR_MOVEMENT_SUCCESS
15077 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15078 {
15079 /* With bidi-reordered rows, there could be more than
15080 one candidate row whose start and end positions
15081 occlude point. We need to let set_cursor_from_row
15082 find the best candidate. */
15083 /* FIXME: Revisit this when glyph ``spilling'' in
15084 continuation lines' rows is implemented for
15085 bidi-reordered rows. */
15086 int rv = 0;
15087
15088 do
15089 {
15090 int at_zv_p = 0, exact_match_p = 0;
15091
15092 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15093 && PT <= MATRIX_ROW_END_CHARPOS (row)
15094 && cursor_row_p (row))
15095 rv |= set_cursor_from_row (w, row, w->current_matrix,
15096 0, 0, 0, 0);
15097 /* As soon as we've found the exact match for point,
15098 or the first suitable row whose ends_at_zv_p flag
15099 is set, we are done. */
15100 at_zv_p =
15101 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15102 if (rv && !at_zv_p
15103 && w->cursor.hpos >= 0
15104 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15105 w->cursor.vpos))
15106 {
15107 struct glyph_row *candidate =
15108 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15109 struct glyph *g =
15110 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15111 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15112
15113 exact_match_p =
15114 (BUFFERP (g->object) && g->charpos == PT)
15115 || (INTEGERP (g->object)
15116 && (g->charpos == PT
15117 || (g->charpos == 0 && endpos - 1 == PT)));
15118 }
15119 if (rv && (at_zv_p || exact_match_p))
15120 {
15121 rc = CURSOR_MOVEMENT_SUCCESS;
15122 break;
15123 }
15124 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15125 break;
15126 ++row;
15127 }
15128 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15129 || row->continued_p)
15130 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15131 || (MATRIX_ROW_START_CHARPOS (row) == PT
15132 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15133 /* If we didn't find any candidate rows, or exited the
15134 loop before all the candidates were examined, signal
15135 to the caller that this method failed. */
15136 if (rc != CURSOR_MOVEMENT_SUCCESS
15137 && !(rv
15138 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15139 && !row->continued_p))
15140 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15141 else if (rv)
15142 rc = CURSOR_MOVEMENT_SUCCESS;
15143 }
15144 else
15145 {
15146 do
15147 {
15148 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15149 {
15150 rc = CURSOR_MOVEMENT_SUCCESS;
15151 break;
15152 }
15153 ++row;
15154 }
15155 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15156 && MATRIX_ROW_START_CHARPOS (row) == PT
15157 && cursor_row_p (row));
15158 }
15159 }
15160 }
15161
15162 return rc;
15163 }
15164
15165 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15166 static
15167 #endif
15168 void
15169 set_vertical_scroll_bar (struct window *w)
15170 {
15171 ptrdiff_t start, end, whole;
15172
15173 /* Calculate the start and end positions for the current window.
15174 At some point, it would be nice to choose between scrollbars
15175 which reflect the whole buffer size, with special markers
15176 indicating narrowing, and scrollbars which reflect only the
15177 visible region.
15178
15179 Note that mini-buffers sometimes aren't displaying any text. */
15180 if (!MINI_WINDOW_P (w)
15181 || (w == XWINDOW (minibuf_window)
15182 && NILP (echo_area_buffer[0])))
15183 {
15184 struct buffer *buf = XBUFFER (w->buffer);
15185 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15186 start = marker_position (w->start) - BUF_BEGV (buf);
15187 /* I don't think this is guaranteed to be right. For the
15188 moment, we'll pretend it is. */
15189 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
15190
15191 if (end < start)
15192 end = start;
15193 if (whole < (end - start))
15194 whole = end - start;
15195 }
15196 else
15197 start = end = whole = 0;
15198
15199 /* Indicate what this scroll bar ought to be displaying now. */
15200 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15201 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15202 (w, end - start, whole, start);
15203 }
15204
15205
15206 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15207 selected_window is redisplayed.
15208
15209 We can return without actually redisplaying the window if
15210 fonts_changed_p. In that case, redisplay_internal will
15211 retry. */
15212
15213 static void
15214 redisplay_window (Lisp_Object window, int just_this_one_p)
15215 {
15216 struct window *w = XWINDOW (window);
15217 struct frame *f = XFRAME (w->frame);
15218 struct buffer *buffer = XBUFFER (w->buffer);
15219 struct buffer *old = current_buffer;
15220 struct text_pos lpoint, opoint, startp;
15221 int update_mode_line;
15222 int tem;
15223 struct it it;
15224 /* Record it now because it's overwritten. */
15225 int current_matrix_up_to_date_p = 0;
15226 int used_current_matrix_p = 0;
15227 /* This is less strict than current_matrix_up_to_date_p.
15228 It indicates that the buffer contents and narrowing are unchanged. */
15229 int buffer_unchanged_p = 0;
15230 int temp_scroll_step = 0;
15231 ptrdiff_t count = SPECPDL_INDEX ();
15232 int rc;
15233 int centering_position = -1;
15234 int last_line_misfit = 0;
15235 ptrdiff_t beg_unchanged, end_unchanged;
15236
15237 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15238 opoint = lpoint;
15239
15240 /* W must be a leaf window here. */
15241 eassert (!NILP (w->buffer));
15242 #ifdef GLYPH_DEBUG
15243 *w->desired_matrix->method = 0;
15244 #endif
15245
15246 restart:
15247 reconsider_clip_changes (w, buffer);
15248
15249 /* Has the mode line to be updated? */
15250 update_mode_line = (w->update_mode_line
15251 || update_mode_lines
15252 || buffer->clip_changed
15253 || buffer->prevent_redisplay_optimizations_p);
15254
15255 if (MINI_WINDOW_P (w))
15256 {
15257 if (w == XWINDOW (echo_area_window)
15258 && !NILP (echo_area_buffer[0]))
15259 {
15260 if (update_mode_line)
15261 /* We may have to update a tty frame's menu bar or a
15262 tool-bar. Example `M-x C-h C-h C-g'. */
15263 goto finish_menu_bars;
15264 else
15265 /* We've already displayed the echo area glyphs in this window. */
15266 goto finish_scroll_bars;
15267 }
15268 else if ((w != XWINDOW (minibuf_window)
15269 || minibuf_level == 0)
15270 /* When buffer is nonempty, redisplay window normally. */
15271 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
15272 /* Quail displays non-mini buffers in minibuffer window.
15273 In that case, redisplay the window normally. */
15274 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
15275 {
15276 /* W is a mini-buffer window, but it's not active, so clear
15277 it. */
15278 int yb = window_text_bottom_y (w);
15279 struct glyph_row *row;
15280 int y;
15281
15282 for (y = 0, row = w->desired_matrix->rows;
15283 y < yb;
15284 y += row->height, ++row)
15285 blank_row (w, row, y);
15286 goto finish_scroll_bars;
15287 }
15288
15289 clear_glyph_matrix (w->desired_matrix);
15290 }
15291
15292 /* Otherwise set up data on this window; select its buffer and point
15293 value. */
15294 /* Really select the buffer, for the sake of buffer-local
15295 variables. */
15296 set_buffer_internal_1 (XBUFFER (w->buffer));
15297
15298 current_matrix_up_to_date_p
15299 = (w->window_end_valid
15300 && !current_buffer->clip_changed
15301 && !current_buffer->prevent_redisplay_optimizations_p
15302 && !window_outdated (w));
15303
15304 /* Run the window-bottom-change-functions
15305 if it is possible that the text on the screen has changed
15306 (either due to modification of the text, or any other reason). */
15307 if (!current_matrix_up_to_date_p
15308 && !NILP (Vwindow_text_change_functions))
15309 {
15310 safe_run_hooks (Qwindow_text_change_functions);
15311 goto restart;
15312 }
15313
15314 beg_unchanged = BEG_UNCHANGED;
15315 end_unchanged = END_UNCHANGED;
15316
15317 SET_TEXT_POS (opoint, PT, PT_BYTE);
15318
15319 specbind (Qinhibit_point_motion_hooks, Qt);
15320
15321 buffer_unchanged_p
15322 = (w->window_end_valid
15323 && !current_buffer->clip_changed
15324 && !window_outdated (w));
15325
15326 /* When windows_or_buffers_changed is non-zero, we can't rely on
15327 the window end being valid, so set it to nil there. */
15328 if (windows_or_buffers_changed)
15329 {
15330 /* If window starts on a continuation line, maybe adjust the
15331 window start in case the window's width changed. */
15332 if (XMARKER (w->start)->buffer == current_buffer)
15333 compute_window_start_on_continuation_line (w);
15334
15335 w->window_end_valid = 0;
15336 }
15337
15338 /* Some sanity checks. */
15339 CHECK_WINDOW_END (w);
15340 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15341 emacs_abort ();
15342 if (BYTEPOS (opoint) < CHARPOS (opoint))
15343 emacs_abort ();
15344
15345 if (mode_line_update_needed (w))
15346 update_mode_line = 1;
15347
15348 /* Point refers normally to the selected window. For any other
15349 window, set up appropriate value. */
15350 if (!EQ (window, selected_window))
15351 {
15352 ptrdiff_t new_pt = marker_position (w->pointm);
15353 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15354 if (new_pt < BEGV)
15355 {
15356 new_pt = BEGV;
15357 new_pt_byte = BEGV_BYTE;
15358 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15359 }
15360 else if (new_pt > (ZV - 1))
15361 {
15362 new_pt = ZV;
15363 new_pt_byte = ZV_BYTE;
15364 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15365 }
15366
15367 /* We don't use SET_PT so that the point-motion hooks don't run. */
15368 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15369 }
15370
15371 /* If any of the character widths specified in the display table
15372 have changed, invalidate the width run cache. It's true that
15373 this may be a bit late to catch such changes, but the rest of
15374 redisplay goes (non-fatally) haywire when the display table is
15375 changed, so why should we worry about doing any better? */
15376 if (current_buffer->width_run_cache)
15377 {
15378 struct Lisp_Char_Table *disptab = buffer_display_table ();
15379
15380 if (! disptab_matches_widthtab
15381 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15382 {
15383 invalidate_region_cache (current_buffer,
15384 current_buffer->width_run_cache,
15385 BEG, Z);
15386 recompute_width_table (current_buffer, disptab);
15387 }
15388 }
15389
15390 /* If window-start is screwed up, choose a new one. */
15391 if (XMARKER (w->start)->buffer != current_buffer)
15392 goto recenter;
15393
15394 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15395
15396 /* If someone specified a new starting point but did not insist,
15397 check whether it can be used. */
15398 if (w->optional_new_start
15399 && CHARPOS (startp) >= BEGV
15400 && CHARPOS (startp) <= ZV)
15401 {
15402 w->optional_new_start = 0;
15403 start_display (&it, w, startp);
15404 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15405 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15406 if (IT_CHARPOS (it) == PT)
15407 w->force_start = 1;
15408 /* IT may overshoot PT if text at PT is invisible. */
15409 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15410 w->force_start = 1;
15411 }
15412
15413 force_start:
15414
15415 /* Handle case where place to start displaying has been specified,
15416 unless the specified location is outside the accessible range. */
15417 if (w->force_start || w->frozen_window_start_p)
15418 {
15419 /* We set this later on if we have to adjust point. */
15420 int new_vpos = -1;
15421
15422 w->force_start = 0;
15423 w->vscroll = 0;
15424 w->window_end_valid = 0;
15425
15426 /* Forget any recorded base line for line number display. */
15427 if (!buffer_unchanged_p)
15428 wset_base_line_number (w, Qnil);
15429
15430 /* Redisplay the mode line. Select the buffer properly for that.
15431 Also, run the hook window-scroll-functions
15432 because we have scrolled. */
15433 /* Note, we do this after clearing force_start because
15434 if there's an error, it is better to forget about force_start
15435 than to get into an infinite loop calling the hook functions
15436 and having them get more errors. */
15437 if (!update_mode_line
15438 || ! NILP (Vwindow_scroll_functions))
15439 {
15440 update_mode_line = 1;
15441 w->update_mode_line = 1;
15442 startp = run_window_scroll_functions (window, startp);
15443 }
15444
15445 w->last_modified = 0;
15446 w->last_overlay_modified = 0;
15447 if (CHARPOS (startp) < BEGV)
15448 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15449 else if (CHARPOS (startp) > ZV)
15450 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15451
15452 /* Redisplay, then check if cursor has been set during the
15453 redisplay. Give up if new fonts were loaded. */
15454 /* We used to issue a CHECK_MARGINS argument to try_window here,
15455 but this causes scrolling to fail when point begins inside
15456 the scroll margin (bug#148) -- cyd */
15457 if (!try_window (window, startp, 0))
15458 {
15459 w->force_start = 1;
15460 clear_glyph_matrix (w->desired_matrix);
15461 goto need_larger_matrices;
15462 }
15463
15464 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15465 {
15466 /* If point does not appear, try to move point so it does
15467 appear. The desired matrix has been built above, so we
15468 can use it here. */
15469 new_vpos = window_box_height (w) / 2;
15470 }
15471
15472 if (!cursor_row_fully_visible_p (w, 0, 0))
15473 {
15474 /* Point does appear, but on a line partly visible at end of window.
15475 Move it back to a fully-visible line. */
15476 new_vpos = window_box_height (w);
15477 }
15478 else if (w->cursor.vpos >=0)
15479 {
15480 /* Some people insist on not letting point enter the scroll
15481 margin, even though this part handles windows that didn't
15482 scroll at all. */
15483 int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15484 int pixel_margin = margin * FRAME_LINE_HEIGHT (f);
15485 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15486
15487 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15488 below, which finds the row to move point to, advances by
15489 the Y coordinate of the _next_ row, see the definition of
15490 MATRIX_ROW_BOTTOM_Y. */
15491 if (w->cursor.vpos < margin + header_line)
15492 new_vpos
15493 = pixel_margin + (header_line
15494 ? CURRENT_HEADER_LINE_HEIGHT (w)
15495 : 0) + FRAME_LINE_HEIGHT (f);
15496 else
15497 {
15498 int window_height = window_box_height (w);
15499
15500 if (header_line)
15501 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15502 if (w->cursor.y >= window_height - pixel_margin)
15503 new_vpos = window_height - pixel_margin;
15504 }
15505 }
15506
15507 /* If we need to move point for either of the above reasons,
15508 now actually do it. */
15509 if (new_vpos >= 0)
15510 {
15511 struct glyph_row *row;
15512
15513 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15514 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15515 ++row;
15516
15517 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15518 MATRIX_ROW_START_BYTEPOS (row));
15519
15520 if (w != XWINDOW (selected_window))
15521 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15522 else if (current_buffer == old)
15523 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15524
15525 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15526
15527 /* If we are highlighting the region, then we just changed
15528 the region, so redisplay to show it. */
15529 if (0 <= markpos_of_region ())
15530 {
15531 clear_glyph_matrix (w->desired_matrix);
15532 if (!try_window (window, startp, 0))
15533 goto need_larger_matrices;
15534 }
15535 }
15536
15537 #ifdef GLYPH_DEBUG
15538 debug_method_add (w, "forced window start");
15539 #endif
15540 goto done;
15541 }
15542
15543 /* Handle case where text has not changed, only point, and it has
15544 not moved off the frame, and we are not retrying after hscroll.
15545 (current_matrix_up_to_date_p is nonzero when retrying.) */
15546 if (current_matrix_up_to_date_p
15547 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15548 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15549 {
15550 switch (rc)
15551 {
15552 case CURSOR_MOVEMENT_SUCCESS:
15553 used_current_matrix_p = 1;
15554 goto done;
15555
15556 case CURSOR_MOVEMENT_MUST_SCROLL:
15557 goto try_to_scroll;
15558
15559 default:
15560 emacs_abort ();
15561 }
15562 }
15563 /* If current starting point was originally the beginning of a line
15564 but no longer is, find a new starting point. */
15565 else if (w->start_at_line_beg
15566 && !(CHARPOS (startp) <= BEGV
15567 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15568 {
15569 #ifdef GLYPH_DEBUG
15570 debug_method_add (w, "recenter 1");
15571 #endif
15572 goto recenter;
15573 }
15574
15575 /* Try scrolling with try_window_id. Value is > 0 if update has
15576 been done, it is -1 if we know that the same window start will
15577 not work. It is 0 if unsuccessful for some other reason. */
15578 else if ((tem = try_window_id (w)) != 0)
15579 {
15580 #ifdef GLYPH_DEBUG
15581 debug_method_add (w, "try_window_id %d", tem);
15582 #endif
15583
15584 if (fonts_changed_p)
15585 goto need_larger_matrices;
15586 if (tem > 0)
15587 goto done;
15588
15589 /* Otherwise try_window_id has returned -1 which means that we
15590 don't want the alternative below this comment to execute. */
15591 }
15592 else if (CHARPOS (startp) >= BEGV
15593 && CHARPOS (startp) <= ZV
15594 && PT >= CHARPOS (startp)
15595 && (CHARPOS (startp) < ZV
15596 /* Avoid starting at end of buffer. */
15597 || CHARPOS (startp) == BEGV
15598 || !window_outdated (w)))
15599 {
15600 int d1, d2, d3, d4, d5, d6;
15601
15602 /* If first window line is a continuation line, and window start
15603 is inside the modified region, but the first change is before
15604 current window start, we must select a new window start.
15605
15606 However, if this is the result of a down-mouse event (e.g. by
15607 extending the mouse-drag-overlay), we don't want to select a
15608 new window start, since that would change the position under
15609 the mouse, resulting in an unwanted mouse-movement rather
15610 than a simple mouse-click. */
15611 if (!w->start_at_line_beg
15612 && NILP (do_mouse_tracking)
15613 && CHARPOS (startp) > BEGV
15614 && CHARPOS (startp) > BEG + beg_unchanged
15615 && CHARPOS (startp) <= Z - end_unchanged
15616 /* Even if w->start_at_line_beg is nil, a new window may
15617 start at a line_beg, since that's how set_buffer_window
15618 sets it. So, we need to check the return value of
15619 compute_window_start_on_continuation_line. (See also
15620 bug#197). */
15621 && XMARKER (w->start)->buffer == current_buffer
15622 && compute_window_start_on_continuation_line (w)
15623 /* It doesn't make sense to force the window start like we
15624 do at label force_start if it is already known that point
15625 will not be visible in the resulting window, because
15626 doing so will move point from its correct position
15627 instead of scrolling the window to bring point into view.
15628 See bug#9324. */
15629 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15630 {
15631 w->force_start = 1;
15632 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15633 goto force_start;
15634 }
15635
15636 #ifdef GLYPH_DEBUG
15637 debug_method_add (w, "same window start");
15638 #endif
15639
15640 /* Try to redisplay starting at same place as before.
15641 If point has not moved off frame, accept the results. */
15642 if (!current_matrix_up_to_date_p
15643 /* Don't use try_window_reusing_current_matrix in this case
15644 because a window scroll function can have changed the
15645 buffer. */
15646 || !NILP (Vwindow_scroll_functions)
15647 || MINI_WINDOW_P (w)
15648 || !(used_current_matrix_p
15649 = try_window_reusing_current_matrix (w)))
15650 {
15651 IF_DEBUG (debug_method_add (w, "1"));
15652 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15653 /* -1 means we need to scroll.
15654 0 means we need new matrices, but fonts_changed_p
15655 is set in that case, so we will detect it below. */
15656 goto try_to_scroll;
15657 }
15658
15659 if (fonts_changed_p)
15660 goto need_larger_matrices;
15661
15662 if (w->cursor.vpos >= 0)
15663 {
15664 if (!just_this_one_p
15665 || current_buffer->clip_changed
15666 || BEG_UNCHANGED < CHARPOS (startp))
15667 /* Forget any recorded base line for line number display. */
15668 wset_base_line_number (w, Qnil);
15669
15670 if (!cursor_row_fully_visible_p (w, 1, 0))
15671 {
15672 clear_glyph_matrix (w->desired_matrix);
15673 last_line_misfit = 1;
15674 }
15675 /* Drop through and scroll. */
15676 else
15677 goto done;
15678 }
15679 else
15680 clear_glyph_matrix (w->desired_matrix);
15681 }
15682
15683 try_to_scroll:
15684
15685 w->last_modified = 0;
15686 w->last_overlay_modified = 0;
15687
15688 /* Redisplay the mode line. Select the buffer properly for that. */
15689 if (!update_mode_line)
15690 {
15691 update_mode_line = 1;
15692 w->update_mode_line = 1;
15693 }
15694
15695 /* Try to scroll by specified few lines. */
15696 if ((scroll_conservatively
15697 || emacs_scroll_step
15698 || temp_scroll_step
15699 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15700 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15701 && CHARPOS (startp) >= BEGV
15702 && CHARPOS (startp) <= ZV)
15703 {
15704 /* The function returns -1 if new fonts were loaded, 1 if
15705 successful, 0 if not successful. */
15706 int ss = try_scrolling (window, just_this_one_p,
15707 scroll_conservatively,
15708 emacs_scroll_step,
15709 temp_scroll_step, last_line_misfit);
15710 switch (ss)
15711 {
15712 case SCROLLING_SUCCESS:
15713 goto done;
15714
15715 case SCROLLING_NEED_LARGER_MATRICES:
15716 goto need_larger_matrices;
15717
15718 case SCROLLING_FAILED:
15719 break;
15720
15721 default:
15722 emacs_abort ();
15723 }
15724 }
15725
15726 /* Finally, just choose a place to start which positions point
15727 according to user preferences. */
15728
15729 recenter:
15730
15731 #ifdef GLYPH_DEBUG
15732 debug_method_add (w, "recenter");
15733 #endif
15734
15735 /* w->vscroll = 0; */
15736
15737 /* Forget any previously recorded base line for line number display. */
15738 if (!buffer_unchanged_p)
15739 wset_base_line_number (w, Qnil);
15740
15741 /* Determine the window start relative to point. */
15742 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15743 it.current_y = it.last_visible_y;
15744 if (centering_position < 0)
15745 {
15746 int margin =
15747 scroll_margin > 0
15748 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15749 : 0;
15750 ptrdiff_t margin_pos = CHARPOS (startp);
15751 Lisp_Object aggressive;
15752 int scrolling_up;
15753
15754 /* If there is a scroll margin at the top of the window, find
15755 its character position. */
15756 if (margin
15757 /* Cannot call start_display if startp is not in the
15758 accessible region of the buffer. This can happen when we
15759 have just switched to a different buffer and/or changed
15760 its restriction. In that case, startp is initialized to
15761 the character position 1 (BEGV) because we did not yet
15762 have chance to display the buffer even once. */
15763 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15764 {
15765 struct it it1;
15766 void *it1data = NULL;
15767
15768 SAVE_IT (it1, it, it1data);
15769 start_display (&it1, w, startp);
15770 move_it_vertically (&it1, margin * FRAME_LINE_HEIGHT (f));
15771 margin_pos = IT_CHARPOS (it1);
15772 RESTORE_IT (&it, &it, it1data);
15773 }
15774 scrolling_up = PT > margin_pos;
15775 aggressive =
15776 scrolling_up
15777 ? BVAR (current_buffer, scroll_up_aggressively)
15778 : BVAR (current_buffer, scroll_down_aggressively);
15779
15780 if (!MINI_WINDOW_P (w)
15781 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15782 {
15783 int pt_offset = 0;
15784
15785 /* Setting scroll-conservatively overrides
15786 scroll-*-aggressively. */
15787 if (!scroll_conservatively && NUMBERP (aggressive))
15788 {
15789 double float_amount = XFLOATINT (aggressive);
15790
15791 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15792 if (pt_offset == 0 && float_amount > 0)
15793 pt_offset = 1;
15794 if (pt_offset && margin > 0)
15795 margin -= 1;
15796 }
15797 /* Compute how much to move the window start backward from
15798 point so that point will be displayed where the user
15799 wants it. */
15800 if (scrolling_up)
15801 {
15802 centering_position = it.last_visible_y;
15803 if (pt_offset)
15804 centering_position -= pt_offset;
15805 centering_position -=
15806 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
15807 + WINDOW_HEADER_LINE_HEIGHT (w);
15808 /* Don't let point enter the scroll margin near top of
15809 the window. */
15810 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
15811 centering_position = margin * FRAME_LINE_HEIGHT (f);
15812 }
15813 else
15814 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
15815 }
15816 else
15817 /* Set the window start half the height of the window backward
15818 from point. */
15819 centering_position = window_box_height (w) / 2;
15820 }
15821 move_it_vertically_backward (&it, centering_position);
15822
15823 eassert (IT_CHARPOS (it) >= BEGV);
15824
15825 /* The function move_it_vertically_backward may move over more
15826 than the specified y-distance. If it->w is small, e.g. a
15827 mini-buffer window, we may end up in front of the window's
15828 display area. Start displaying at the start of the line
15829 containing PT in this case. */
15830 if (it.current_y <= 0)
15831 {
15832 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15833 move_it_vertically_backward (&it, 0);
15834 it.current_y = 0;
15835 }
15836
15837 it.current_x = it.hpos = 0;
15838
15839 /* Set the window start position here explicitly, to avoid an
15840 infinite loop in case the functions in window-scroll-functions
15841 get errors. */
15842 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15843
15844 /* Run scroll hooks. */
15845 startp = run_window_scroll_functions (window, it.current.pos);
15846
15847 /* Redisplay the window. */
15848 if (!current_matrix_up_to_date_p
15849 || windows_or_buffers_changed
15850 || cursor_type_changed
15851 /* Don't use try_window_reusing_current_matrix in this case
15852 because it can have changed the buffer. */
15853 || !NILP (Vwindow_scroll_functions)
15854 || !just_this_one_p
15855 || MINI_WINDOW_P (w)
15856 || !(used_current_matrix_p
15857 = try_window_reusing_current_matrix (w)))
15858 try_window (window, startp, 0);
15859
15860 /* If new fonts have been loaded (due to fontsets), give up. We
15861 have to start a new redisplay since we need to re-adjust glyph
15862 matrices. */
15863 if (fonts_changed_p)
15864 goto need_larger_matrices;
15865
15866 /* If cursor did not appear assume that the middle of the window is
15867 in the first line of the window. Do it again with the next line.
15868 (Imagine a window of height 100, displaying two lines of height
15869 60. Moving back 50 from it->last_visible_y will end in the first
15870 line.) */
15871 if (w->cursor.vpos < 0)
15872 {
15873 if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos))
15874 {
15875 clear_glyph_matrix (w->desired_matrix);
15876 move_it_by_lines (&it, 1);
15877 try_window (window, it.current.pos, 0);
15878 }
15879 else if (PT < IT_CHARPOS (it))
15880 {
15881 clear_glyph_matrix (w->desired_matrix);
15882 move_it_by_lines (&it, -1);
15883 try_window (window, it.current.pos, 0);
15884 }
15885 else
15886 {
15887 /* Not much we can do about it. */
15888 }
15889 }
15890
15891 /* Consider the following case: Window starts at BEGV, there is
15892 invisible, intangible text at BEGV, so that display starts at
15893 some point START > BEGV. It can happen that we are called with
15894 PT somewhere between BEGV and START. Try to handle that case. */
15895 if (w->cursor.vpos < 0)
15896 {
15897 struct glyph_row *row = w->current_matrix->rows;
15898 if (row->mode_line_p)
15899 ++row;
15900 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15901 }
15902
15903 if (!cursor_row_fully_visible_p (w, 0, 0))
15904 {
15905 /* If vscroll is enabled, disable it and try again. */
15906 if (w->vscroll)
15907 {
15908 w->vscroll = 0;
15909 clear_glyph_matrix (w->desired_matrix);
15910 goto recenter;
15911 }
15912
15913 /* Users who set scroll-conservatively to a large number want
15914 point just above/below the scroll margin. If we ended up
15915 with point's row partially visible, move the window start to
15916 make that row fully visible and out of the margin. */
15917 if (scroll_conservatively > SCROLL_LIMIT)
15918 {
15919 int margin =
15920 scroll_margin > 0
15921 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15922 : 0;
15923 int move_down = w->cursor.vpos >= WINDOW_TOTAL_LINES (w) / 2;
15924
15925 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
15926 clear_glyph_matrix (w->desired_matrix);
15927 if (1 == try_window (window, it.current.pos,
15928 TRY_WINDOW_CHECK_MARGINS))
15929 goto done;
15930 }
15931
15932 /* If centering point failed to make the whole line visible,
15933 put point at the top instead. That has to make the whole line
15934 visible, if it can be done. */
15935 if (centering_position == 0)
15936 goto done;
15937
15938 clear_glyph_matrix (w->desired_matrix);
15939 centering_position = 0;
15940 goto recenter;
15941 }
15942
15943 done:
15944
15945 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15946 w->start_at_line_beg = (CHARPOS (startp) == BEGV
15947 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
15948
15949 /* Display the mode line, if we must. */
15950 if ((update_mode_line
15951 /* If window not full width, must redo its mode line
15952 if (a) the window to its side is being redone and
15953 (b) we do a frame-based redisplay. This is a consequence
15954 of how inverted lines are drawn in frame-based redisplay. */
15955 || (!just_this_one_p
15956 && !FRAME_WINDOW_P (f)
15957 && !WINDOW_FULL_WIDTH_P (w))
15958 /* Line number to display. */
15959 || INTEGERP (w->base_line_pos)
15960 /* Column number is displayed and different from the one displayed. */
15961 || (!NILP (w->column_number_displayed)
15962 && (XFASTINT (w->column_number_displayed) != current_column ())))
15963 /* This means that the window has a mode line. */
15964 && (WINDOW_WANTS_MODELINE_P (w)
15965 || WINDOW_WANTS_HEADER_LINE_P (w)))
15966 {
15967 display_mode_lines (w);
15968
15969 /* If mode line height has changed, arrange for a thorough
15970 immediate redisplay using the correct mode line height. */
15971 if (WINDOW_WANTS_MODELINE_P (w)
15972 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
15973 {
15974 fonts_changed_p = 1;
15975 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
15976 = DESIRED_MODE_LINE_HEIGHT (w);
15977 }
15978
15979 /* If header line height has changed, arrange for a thorough
15980 immediate redisplay using the correct header line height. */
15981 if (WINDOW_WANTS_HEADER_LINE_P (w)
15982 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
15983 {
15984 fonts_changed_p = 1;
15985 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
15986 = DESIRED_HEADER_LINE_HEIGHT (w);
15987 }
15988
15989 if (fonts_changed_p)
15990 goto need_larger_matrices;
15991 }
15992
15993 if (!line_number_displayed
15994 && !BUFFERP (w->base_line_pos))
15995 {
15996 wset_base_line_pos (w, Qnil);
15997 wset_base_line_number (w, Qnil);
15998 }
15999
16000 finish_menu_bars:
16001
16002 /* When we reach a frame's selected window, redo the frame's menu bar. */
16003 if (update_mode_line
16004 && EQ (FRAME_SELECTED_WINDOW (f), window))
16005 {
16006 int redisplay_menu_p = 0;
16007
16008 if (FRAME_WINDOW_P (f))
16009 {
16010 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16011 || defined (HAVE_NS) || defined (USE_GTK)
16012 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16013 #else
16014 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16015 #endif
16016 }
16017 else
16018 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16019
16020 if (redisplay_menu_p)
16021 display_menu_bar (w);
16022
16023 #ifdef HAVE_WINDOW_SYSTEM
16024 if (FRAME_WINDOW_P (f))
16025 {
16026 #if defined (USE_GTK) || defined (HAVE_NS)
16027 if (FRAME_EXTERNAL_TOOL_BAR (f))
16028 redisplay_tool_bar (f);
16029 #else
16030 if (WINDOWP (f->tool_bar_window)
16031 && (FRAME_TOOL_BAR_LINES (f) > 0
16032 || !NILP (Vauto_resize_tool_bars))
16033 && redisplay_tool_bar (f))
16034 ignore_mouse_drag_p = 1;
16035 #endif
16036 }
16037 #endif
16038 }
16039
16040 #ifdef HAVE_WINDOW_SYSTEM
16041 if (FRAME_WINDOW_P (f)
16042 && update_window_fringes (w, (just_this_one_p
16043 || (!used_current_matrix_p && !overlay_arrow_seen)
16044 || w->pseudo_window_p)))
16045 {
16046 update_begin (f);
16047 block_input ();
16048 if (draw_window_fringes (w, 1))
16049 x_draw_vertical_border (w);
16050 unblock_input ();
16051 update_end (f);
16052 }
16053 #endif /* HAVE_WINDOW_SYSTEM */
16054
16055 /* We go to this label, with fonts_changed_p set,
16056 if it is necessary to try again using larger glyph matrices.
16057 We have to redeem the scroll bar even in this case,
16058 because the loop in redisplay_internal expects that. */
16059 need_larger_matrices:
16060 ;
16061 finish_scroll_bars:
16062
16063 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16064 {
16065 /* Set the thumb's position and size. */
16066 set_vertical_scroll_bar (w);
16067
16068 /* Note that we actually used the scroll bar attached to this
16069 window, so it shouldn't be deleted at the end of redisplay. */
16070 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16071 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16072 }
16073
16074 /* Restore current_buffer and value of point in it. The window
16075 update may have changed the buffer, so first make sure `opoint'
16076 is still valid (Bug#6177). */
16077 if (CHARPOS (opoint) < BEGV)
16078 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16079 else if (CHARPOS (opoint) > ZV)
16080 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16081 else
16082 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16083
16084 set_buffer_internal_1 (old);
16085 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16086 shorter. This can be caused by log truncation in *Messages*. */
16087 if (CHARPOS (lpoint) <= ZV)
16088 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16089
16090 unbind_to (count, Qnil);
16091 }
16092
16093
16094 /* Build the complete desired matrix of WINDOW with a window start
16095 buffer position POS.
16096
16097 Value is 1 if successful. It is zero if fonts were loaded during
16098 redisplay which makes re-adjusting glyph matrices necessary, and -1
16099 if point would appear in the scroll margins.
16100 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16101 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16102 set in FLAGS.) */
16103
16104 int
16105 try_window (Lisp_Object window, struct text_pos pos, int flags)
16106 {
16107 struct window *w = XWINDOW (window);
16108 struct it it;
16109 struct glyph_row *last_text_row = NULL;
16110 struct frame *f = XFRAME (w->frame);
16111
16112 /* Make POS the new window start. */
16113 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16114
16115 /* Mark cursor position as unknown. No overlay arrow seen. */
16116 w->cursor.vpos = -1;
16117 overlay_arrow_seen = 0;
16118
16119 /* Initialize iterator and info to start at POS. */
16120 start_display (&it, w, pos);
16121
16122 /* Display all lines of W. */
16123 while (it.current_y < it.last_visible_y)
16124 {
16125 if (display_line (&it))
16126 last_text_row = it.glyph_row - 1;
16127 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16128 return 0;
16129 }
16130
16131 /* Don't let the cursor end in the scroll margins. */
16132 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16133 && !MINI_WINDOW_P (w))
16134 {
16135 int this_scroll_margin;
16136
16137 if (scroll_margin > 0)
16138 {
16139 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
16140 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
16141 }
16142 else
16143 this_scroll_margin = 0;
16144
16145 if ((w->cursor.y >= 0 /* not vscrolled */
16146 && w->cursor.y < this_scroll_margin
16147 && CHARPOS (pos) > BEGV
16148 && IT_CHARPOS (it) < ZV)
16149 /* rms: considering make_cursor_line_fully_visible_p here
16150 seems to give wrong results. We don't want to recenter
16151 when the last line is partly visible, we want to allow
16152 that case to be handled in the usual way. */
16153 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16154 {
16155 w->cursor.vpos = -1;
16156 clear_glyph_matrix (w->desired_matrix);
16157 return -1;
16158 }
16159 }
16160
16161 /* If bottom moved off end of frame, change mode line percentage. */
16162 if (XFASTINT (w->window_end_pos) <= 0
16163 && Z != IT_CHARPOS (it))
16164 w->update_mode_line = 1;
16165
16166 /* Set window_end_pos to the offset of the last character displayed
16167 on the window from the end of current_buffer. Set
16168 window_end_vpos to its row number. */
16169 if (last_text_row)
16170 {
16171 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16172 w->window_end_bytepos
16173 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16174 wset_window_end_pos
16175 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16176 wset_window_end_vpos
16177 (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
16178 eassert
16179 (MATRIX_ROW (w->desired_matrix,
16180 XFASTINT (w->window_end_vpos))->displays_text_p);
16181 }
16182 else
16183 {
16184 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16185 wset_window_end_pos (w, make_number (Z - ZV));
16186 wset_window_end_vpos (w, make_number (0));
16187 }
16188
16189 /* But that is not valid info until redisplay finishes. */
16190 w->window_end_valid = 0;
16191 return 1;
16192 }
16193
16194
16195 \f
16196 /************************************************************************
16197 Window redisplay reusing current matrix when buffer has not changed
16198 ************************************************************************/
16199
16200 /* Try redisplay of window W showing an unchanged buffer with a
16201 different window start than the last time it was displayed by
16202 reusing its current matrix. Value is non-zero if successful.
16203 W->start is the new window start. */
16204
16205 static int
16206 try_window_reusing_current_matrix (struct window *w)
16207 {
16208 struct frame *f = XFRAME (w->frame);
16209 struct glyph_row *bottom_row;
16210 struct it it;
16211 struct run run;
16212 struct text_pos start, new_start;
16213 int nrows_scrolled, i;
16214 struct glyph_row *last_text_row;
16215 struct glyph_row *last_reused_text_row;
16216 struct glyph_row *start_row;
16217 int start_vpos, min_y, max_y;
16218
16219 #ifdef GLYPH_DEBUG
16220 if (inhibit_try_window_reusing)
16221 return 0;
16222 #endif
16223
16224 if (/* This function doesn't handle terminal frames. */
16225 !FRAME_WINDOW_P (f)
16226 /* Don't try to reuse the display if windows have been split
16227 or such. */
16228 || windows_or_buffers_changed
16229 || cursor_type_changed)
16230 return 0;
16231
16232 /* Can't do this if region may have changed. */
16233 if (0 <= markpos_of_region ()
16234 || !NILP (w->region_showing)
16235 || !NILP (Vshow_trailing_whitespace))
16236 return 0;
16237
16238 /* If top-line visibility has changed, give up. */
16239 if (WINDOW_WANTS_HEADER_LINE_P (w)
16240 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16241 return 0;
16242
16243 /* Give up if old or new display is scrolled vertically. We could
16244 make this function handle this, but right now it doesn't. */
16245 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16246 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16247 return 0;
16248
16249 /* The variable new_start now holds the new window start. The old
16250 start `start' can be determined from the current matrix. */
16251 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16252 start = start_row->minpos;
16253 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16254
16255 /* Clear the desired matrix for the display below. */
16256 clear_glyph_matrix (w->desired_matrix);
16257
16258 if (CHARPOS (new_start) <= CHARPOS (start))
16259 {
16260 /* Don't use this method if the display starts with an ellipsis
16261 displayed for invisible text. It's not easy to handle that case
16262 below, and it's certainly not worth the effort since this is
16263 not a frequent case. */
16264 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16265 return 0;
16266
16267 IF_DEBUG (debug_method_add (w, "twu1"));
16268
16269 /* Display up to a row that can be reused. The variable
16270 last_text_row is set to the last row displayed that displays
16271 text. Note that it.vpos == 0 if or if not there is a
16272 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16273 start_display (&it, w, new_start);
16274 w->cursor.vpos = -1;
16275 last_text_row = last_reused_text_row = NULL;
16276
16277 while (it.current_y < it.last_visible_y
16278 && !fonts_changed_p)
16279 {
16280 /* If we have reached into the characters in the START row,
16281 that means the line boundaries have changed. So we
16282 can't start copying with the row START. Maybe it will
16283 work to start copying with the following row. */
16284 while (IT_CHARPOS (it) > CHARPOS (start))
16285 {
16286 /* Advance to the next row as the "start". */
16287 start_row++;
16288 start = start_row->minpos;
16289 /* If there are no more rows to try, or just one, give up. */
16290 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16291 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16292 || CHARPOS (start) == ZV)
16293 {
16294 clear_glyph_matrix (w->desired_matrix);
16295 return 0;
16296 }
16297
16298 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16299 }
16300 /* If we have reached alignment, we can copy the rest of the
16301 rows. */
16302 if (IT_CHARPOS (it) == CHARPOS (start)
16303 /* Don't accept "alignment" inside a display vector,
16304 since start_row could have started in the middle of
16305 that same display vector (thus their character
16306 positions match), and we have no way of telling if
16307 that is the case. */
16308 && it.current.dpvec_index < 0)
16309 break;
16310
16311 if (display_line (&it))
16312 last_text_row = it.glyph_row - 1;
16313
16314 }
16315
16316 /* A value of current_y < last_visible_y means that we stopped
16317 at the previous window start, which in turn means that we
16318 have at least one reusable row. */
16319 if (it.current_y < it.last_visible_y)
16320 {
16321 struct glyph_row *row;
16322
16323 /* IT.vpos always starts from 0; it counts text lines. */
16324 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16325
16326 /* Find PT if not already found in the lines displayed. */
16327 if (w->cursor.vpos < 0)
16328 {
16329 int dy = it.current_y - start_row->y;
16330
16331 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16332 row = row_containing_pos (w, PT, row, NULL, dy);
16333 if (row)
16334 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16335 dy, nrows_scrolled);
16336 else
16337 {
16338 clear_glyph_matrix (w->desired_matrix);
16339 return 0;
16340 }
16341 }
16342
16343 /* Scroll the display. Do it before the current matrix is
16344 changed. The problem here is that update has not yet
16345 run, i.e. part of the current matrix is not up to date.
16346 scroll_run_hook will clear the cursor, and use the
16347 current matrix to get the height of the row the cursor is
16348 in. */
16349 run.current_y = start_row->y;
16350 run.desired_y = it.current_y;
16351 run.height = it.last_visible_y - it.current_y;
16352
16353 if (run.height > 0 && run.current_y != run.desired_y)
16354 {
16355 update_begin (f);
16356 FRAME_RIF (f)->update_window_begin_hook (w);
16357 FRAME_RIF (f)->clear_window_mouse_face (w);
16358 FRAME_RIF (f)->scroll_run_hook (w, &run);
16359 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16360 update_end (f);
16361 }
16362
16363 /* Shift current matrix down by nrows_scrolled lines. */
16364 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16365 rotate_matrix (w->current_matrix,
16366 start_vpos,
16367 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16368 nrows_scrolled);
16369
16370 /* Disable lines that must be updated. */
16371 for (i = 0; i < nrows_scrolled; ++i)
16372 (start_row + i)->enabled_p = 0;
16373
16374 /* Re-compute Y positions. */
16375 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16376 max_y = it.last_visible_y;
16377 for (row = start_row + nrows_scrolled;
16378 row < bottom_row;
16379 ++row)
16380 {
16381 row->y = it.current_y;
16382 row->visible_height = row->height;
16383
16384 if (row->y < min_y)
16385 row->visible_height -= min_y - row->y;
16386 if (row->y + row->height > max_y)
16387 row->visible_height -= row->y + row->height - max_y;
16388 if (row->fringe_bitmap_periodic_p)
16389 row->redraw_fringe_bitmaps_p = 1;
16390
16391 it.current_y += row->height;
16392
16393 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16394 last_reused_text_row = row;
16395 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16396 break;
16397 }
16398
16399 /* Disable lines in the current matrix which are now
16400 below the window. */
16401 for (++row; row < bottom_row; ++row)
16402 row->enabled_p = row->mode_line_p = 0;
16403 }
16404
16405 /* Update window_end_pos etc.; last_reused_text_row is the last
16406 reused row from the current matrix containing text, if any.
16407 The value of last_text_row is the last displayed line
16408 containing text. */
16409 if (last_reused_text_row)
16410 {
16411 w->window_end_bytepos
16412 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16413 wset_window_end_pos
16414 (w, make_number (Z
16415 - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
16416 wset_window_end_vpos
16417 (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16418 w->current_matrix)));
16419 }
16420 else if (last_text_row)
16421 {
16422 w->window_end_bytepos
16423 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16424 wset_window_end_pos
16425 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16426 wset_window_end_vpos
16427 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16428 w->desired_matrix)));
16429 }
16430 else
16431 {
16432 /* This window must be completely empty. */
16433 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16434 wset_window_end_pos (w, make_number (Z - ZV));
16435 wset_window_end_vpos (w, make_number (0));
16436 }
16437 w->window_end_valid = 0;
16438
16439 /* Update hint: don't try scrolling again in update_window. */
16440 w->desired_matrix->no_scrolling_p = 1;
16441
16442 #ifdef GLYPH_DEBUG
16443 debug_method_add (w, "try_window_reusing_current_matrix 1");
16444 #endif
16445 return 1;
16446 }
16447 else if (CHARPOS (new_start) > CHARPOS (start))
16448 {
16449 struct glyph_row *pt_row, *row;
16450 struct glyph_row *first_reusable_row;
16451 struct glyph_row *first_row_to_display;
16452 int dy;
16453 int yb = window_text_bottom_y (w);
16454
16455 /* Find the row starting at new_start, if there is one. Don't
16456 reuse a partially visible line at the end. */
16457 first_reusable_row = start_row;
16458 while (first_reusable_row->enabled_p
16459 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16460 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16461 < CHARPOS (new_start)))
16462 ++first_reusable_row;
16463
16464 /* Give up if there is no row to reuse. */
16465 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16466 || !first_reusable_row->enabled_p
16467 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16468 != CHARPOS (new_start)))
16469 return 0;
16470
16471 /* We can reuse fully visible rows beginning with
16472 first_reusable_row to the end of the window. Set
16473 first_row_to_display to the first row that cannot be reused.
16474 Set pt_row to the row containing point, if there is any. */
16475 pt_row = NULL;
16476 for (first_row_to_display = first_reusable_row;
16477 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16478 ++first_row_to_display)
16479 {
16480 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16481 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16482 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16483 && first_row_to_display->ends_at_zv_p
16484 && pt_row == NULL)))
16485 pt_row = first_row_to_display;
16486 }
16487
16488 /* Start displaying at the start of first_row_to_display. */
16489 eassert (first_row_to_display->y < yb);
16490 init_to_row_start (&it, w, first_row_to_display);
16491
16492 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16493 - start_vpos);
16494 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16495 - nrows_scrolled);
16496 it.current_y = (first_row_to_display->y - first_reusable_row->y
16497 + WINDOW_HEADER_LINE_HEIGHT (w));
16498
16499 /* Display lines beginning with first_row_to_display in the
16500 desired matrix. Set last_text_row to the last row displayed
16501 that displays text. */
16502 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16503 if (pt_row == NULL)
16504 w->cursor.vpos = -1;
16505 last_text_row = NULL;
16506 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16507 if (display_line (&it))
16508 last_text_row = it.glyph_row - 1;
16509
16510 /* If point is in a reused row, adjust y and vpos of the cursor
16511 position. */
16512 if (pt_row)
16513 {
16514 w->cursor.vpos -= nrows_scrolled;
16515 w->cursor.y -= first_reusable_row->y - start_row->y;
16516 }
16517
16518 /* Give up if point isn't in a row displayed or reused. (This
16519 also handles the case where w->cursor.vpos < nrows_scrolled
16520 after the calls to display_line, which can happen with scroll
16521 margins. See bug#1295.) */
16522 if (w->cursor.vpos < 0)
16523 {
16524 clear_glyph_matrix (w->desired_matrix);
16525 return 0;
16526 }
16527
16528 /* Scroll the display. */
16529 run.current_y = first_reusable_row->y;
16530 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16531 run.height = it.last_visible_y - run.current_y;
16532 dy = run.current_y - run.desired_y;
16533
16534 if (run.height)
16535 {
16536 update_begin (f);
16537 FRAME_RIF (f)->update_window_begin_hook (w);
16538 FRAME_RIF (f)->clear_window_mouse_face (w);
16539 FRAME_RIF (f)->scroll_run_hook (w, &run);
16540 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16541 update_end (f);
16542 }
16543
16544 /* Adjust Y positions of reused rows. */
16545 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16546 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16547 max_y = it.last_visible_y;
16548 for (row = first_reusable_row; row < first_row_to_display; ++row)
16549 {
16550 row->y -= dy;
16551 row->visible_height = row->height;
16552 if (row->y < min_y)
16553 row->visible_height -= min_y - row->y;
16554 if (row->y + row->height > max_y)
16555 row->visible_height -= row->y + row->height - max_y;
16556 if (row->fringe_bitmap_periodic_p)
16557 row->redraw_fringe_bitmaps_p = 1;
16558 }
16559
16560 /* Scroll the current matrix. */
16561 eassert (nrows_scrolled > 0);
16562 rotate_matrix (w->current_matrix,
16563 start_vpos,
16564 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16565 -nrows_scrolled);
16566
16567 /* Disable rows not reused. */
16568 for (row -= nrows_scrolled; row < bottom_row; ++row)
16569 row->enabled_p = 0;
16570
16571 /* Point may have moved to a different line, so we cannot assume that
16572 the previous cursor position is valid; locate the correct row. */
16573 if (pt_row)
16574 {
16575 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16576 row < bottom_row
16577 && PT >= MATRIX_ROW_END_CHARPOS (row)
16578 && !row->ends_at_zv_p;
16579 row++)
16580 {
16581 w->cursor.vpos++;
16582 w->cursor.y = row->y;
16583 }
16584 if (row < bottom_row)
16585 {
16586 /* Can't simply scan the row for point with
16587 bidi-reordered glyph rows. Let set_cursor_from_row
16588 figure out where to put the cursor, and if it fails,
16589 give up. */
16590 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
16591 {
16592 if (!set_cursor_from_row (w, row, w->current_matrix,
16593 0, 0, 0, 0))
16594 {
16595 clear_glyph_matrix (w->desired_matrix);
16596 return 0;
16597 }
16598 }
16599 else
16600 {
16601 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16602 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16603
16604 for (; glyph < end
16605 && (!BUFFERP (glyph->object)
16606 || glyph->charpos < PT);
16607 glyph++)
16608 {
16609 w->cursor.hpos++;
16610 w->cursor.x += glyph->pixel_width;
16611 }
16612 }
16613 }
16614 }
16615
16616 /* Adjust window end. A null value of last_text_row means that
16617 the window end is in reused rows which in turn means that
16618 only its vpos can have changed. */
16619 if (last_text_row)
16620 {
16621 w->window_end_bytepos
16622 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16623 wset_window_end_pos
16624 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16625 wset_window_end_vpos
16626 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16627 w->desired_matrix)));
16628 }
16629 else
16630 {
16631 wset_window_end_vpos
16632 (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
16633 }
16634
16635 w->window_end_valid = 0;
16636 w->desired_matrix->no_scrolling_p = 1;
16637
16638 #ifdef GLYPH_DEBUG
16639 debug_method_add (w, "try_window_reusing_current_matrix 2");
16640 #endif
16641 return 1;
16642 }
16643
16644 return 0;
16645 }
16646
16647
16648 \f
16649 /************************************************************************
16650 Window redisplay reusing current matrix when buffer has changed
16651 ************************************************************************/
16652
16653 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16654 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16655 ptrdiff_t *, ptrdiff_t *);
16656 static struct glyph_row *
16657 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16658 struct glyph_row *);
16659
16660
16661 /* Return the last row in MATRIX displaying text. If row START is
16662 non-null, start searching with that row. IT gives the dimensions
16663 of the display. Value is null if matrix is empty; otherwise it is
16664 a pointer to the row found. */
16665
16666 static struct glyph_row *
16667 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16668 struct glyph_row *start)
16669 {
16670 struct glyph_row *row, *row_found;
16671
16672 /* Set row_found to the last row in IT->w's current matrix
16673 displaying text. The loop looks funny but think of partially
16674 visible lines. */
16675 row_found = NULL;
16676 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16677 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16678 {
16679 eassert (row->enabled_p);
16680 row_found = row;
16681 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16682 break;
16683 ++row;
16684 }
16685
16686 return row_found;
16687 }
16688
16689
16690 /* Return the last row in the current matrix of W that is not affected
16691 by changes at the start of current_buffer that occurred since W's
16692 current matrix was built. Value is null if no such row exists.
16693
16694 BEG_UNCHANGED us the number of characters unchanged at the start of
16695 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16696 first changed character in current_buffer. Characters at positions <
16697 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16698 when the current matrix was built. */
16699
16700 static struct glyph_row *
16701 find_last_unchanged_at_beg_row (struct window *w)
16702 {
16703 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16704 struct glyph_row *row;
16705 struct glyph_row *row_found = NULL;
16706 int yb = window_text_bottom_y (w);
16707
16708 /* Find the last row displaying unchanged text. */
16709 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16710 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16711 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16712 ++row)
16713 {
16714 if (/* If row ends before first_changed_pos, it is unchanged,
16715 except in some case. */
16716 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16717 /* When row ends in ZV and we write at ZV it is not
16718 unchanged. */
16719 && !row->ends_at_zv_p
16720 /* When first_changed_pos is the end of a continued line,
16721 row is not unchanged because it may be no longer
16722 continued. */
16723 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16724 && (row->continued_p
16725 || row->exact_window_width_line_p))
16726 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16727 needs to be recomputed, so don't consider this row as
16728 unchanged. This happens when the last line was
16729 bidi-reordered and was killed immediately before this
16730 redisplay cycle. In that case, ROW->end stores the
16731 buffer position of the first visual-order character of
16732 the killed text, which is now beyond ZV. */
16733 && CHARPOS (row->end.pos) <= ZV)
16734 row_found = row;
16735
16736 /* Stop if last visible row. */
16737 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16738 break;
16739 }
16740
16741 return row_found;
16742 }
16743
16744
16745 /* Find the first glyph row in the current matrix of W that is not
16746 affected by changes at the end of current_buffer since the
16747 time W's current matrix was built.
16748
16749 Return in *DELTA the number of chars by which buffer positions in
16750 unchanged text at the end of current_buffer must be adjusted.
16751
16752 Return in *DELTA_BYTES the corresponding number of bytes.
16753
16754 Value is null if no such row exists, i.e. all rows are affected by
16755 changes. */
16756
16757 static struct glyph_row *
16758 find_first_unchanged_at_end_row (struct window *w,
16759 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16760 {
16761 struct glyph_row *row;
16762 struct glyph_row *row_found = NULL;
16763
16764 *delta = *delta_bytes = 0;
16765
16766 /* Display must not have been paused, otherwise the current matrix
16767 is not up to date. */
16768 eassert (w->window_end_valid);
16769
16770 /* A value of window_end_pos >= END_UNCHANGED means that the window
16771 end is in the range of changed text. If so, there is no
16772 unchanged row at the end of W's current matrix. */
16773 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16774 return NULL;
16775
16776 /* Set row to the last row in W's current matrix displaying text. */
16777 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16778
16779 /* If matrix is entirely empty, no unchanged row exists. */
16780 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16781 {
16782 /* The value of row is the last glyph row in the matrix having a
16783 meaningful buffer position in it. The end position of row
16784 corresponds to window_end_pos. This allows us to translate
16785 buffer positions in the current matrix to current buffer
16786 positions for characters not in changed text. */
16787 ptrdiff_t Z_old =
16788 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16789 ptrdiff_t Z_BYTE_old =
16790 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16791 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16792 struct glyph_row *first_text_row
16793 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16794
16795 *delta = Z - Z_old;
16796 *delta_bytes = Z_BYTE - Z_BYTE_old;
16797
16798 /* Set last_unchanged_pos to the buffer position of the last
16799 character in the buffer that has not been changed. Z is the
16800 index + 1 of the last character in current_buffer, i.e. by
16801 subtracting END_UNCHANGED we get the index of the last
16802 unchanged character, and we have to add BEG to get its buffer
16803 position. */
16804 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16805 last_unchanged_pos_old = last_unchanged_pos - *delta;
16806
16807 /* Search backward from ROW for a row displaying a line that
16808 starts at a minimum position >= last_unchanged_pos_old. */
16809 for (; row > first_text_row; --row)
16810 {
16811 /* This used to abort, but it can happen.
16812 It is ok to just stop the search instead here. KFS. */
16813 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16814 break;
16815
16816 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16817 row_found = row;
16818 }
16819 }
16820
16821 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16822
16823 return row_found;
16824 }
16825
16826
16827 /* Make sure that glyph rows in the current matrix of window W
16828 reference the same glyph memory as corresponding rows in the
16829 frame's frame matrix. This function is called after scrolling W's
16830 current matrix on a terminal frame in try_window_id and
16831 try_window_reusing_current_matrix. */
16832
16833 static void
16834 sync_frame_with_window_matrix_rows (struct window *w)
16835 {
16836 struct frame *f = XFRAME (w->frame);
16837 struct glyph_row *window_row, *window_row_end, *frame_row;
16838
16839 /* Preconditions: W must be a leaf window and full-width. Its frame
16840 must have a frame matrix. */
16841 eassert (NILP (w->hchild) && NILP (w->vchild));
16842 eassert (WINDOW_FULL_WIDTH_P (w));
16843 eassert (!FRAME_WINDOW_P (f));
16844
16845 /* If W is a full-width window, glyph pointers in W's current matrix
16846 have, by definition, to be the same as glyph pointers in the
16847 corresponding frame matrix. Note that frame matrices have no
16848 marginal areas (see build_frame_matrix). */
16849 window_row = w->current_matrix->rows;
16850 window_row_end = window_row + w->current_matrix->nrows;
16851 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16852 while (window_row < window_row_end)
16853 {
16854 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16855 struct glyph *end = window_row->glyphs[LAST_AREA];
16856
16857 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16858 frame_row->glyphs[TEXT_AREA] = start;
16859 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16860 frame_row->glyphs[LAST_AREA] = end;
16861
16862 /* Disable frame rows whose corresponding window rows have
16863 been disabled in try_window_id. */
16864 if (!window_row->enabled_p)
16865 frame_row->enabled_p = 0;
16866
16867 ++window_row, ++frame_row;
16868 }
16869 }
16870
16871
16872 /* Find the glyph row in window W containing CHARPOS. Consider all
16873 rows between START and END (not inclusive). END null means search
16874 all rows to the end of the display area of W. Value is the row
16875 containing CHARPOS or null. */
16876
16877 struct glyph_row *
16878 row_containing_pos (struct window *w, ptrdiff_t charpos,
16879 struct glyph_row *start, struct glyph_row *end, int dy)
16880 {
16881 struct glyph_row *row = start;
16882 struct glyph_row *best_row = NULL;
16883 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
16884 int last_y;
16885
16886 /* If we happen to start on a header-line, skip that. */
16887 if (row->mode_line_p)
16888 ++row;
16889
16890 if ((end && row >= end) || !row->enabled_p)
16891 return NULL;
16892
16893 last_y = window_text_bottom_y (w) - dy;
16894
16895 while (1)
16896 {
16897 /* Give up if we have gone too far. */
16898 if (end && row >= end)
16899 return NULL;
16900 /* This formerly returned if they were equal.
16901 I think that both quantities are of a "last plus one" type;
16902 if so, when they are equal, the row is within the screen. -- rms. */
16903 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
16904 return NULL;
16905
16906 /* If it is in this row, return this row. */
16907 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
16908 || (MATRIX_ROW_END_CHARPOS (row) == charpos
16909 /* The end position of a row equals the start
16910 position of the next row. If CHARPOS is there, we
16911 would rather display it in the next line, except
16912 when this line ends in ZV. */
16913 && !row->ends_at_zv_p
16914 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16915 && charpos >= MATRIX_ROW_START_CHARPOS (row))
16916 {
16917 struct glyph *g;
16918
16919 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16920 || (!best_row && !row->continued_p))
16921 return row;
16922 /* In bidi-reordered rows, there could be several rows
16923 occluding point, all of them belonging to the same
16924 continued line. We need to find the row which fits
16925 CHARPOS the best. */
16926 for (g = row->glyphs[TEXT_AREA];
16927 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16928 g++)
16929 {
16930 if (!STRINGP (g->object))
16931 {
16932 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
16933 {
16934 mindif = eabs (g->charpos - charpos);
16935 best_row = row;
16936 /* Exact match always wins. */
16937 if (mindif == 0)
16938 return best_row;
16939 }
16940 }
16941 }
16942 }
16943 else if (best_row && !row->continued_p)
16944 return best_row;
16945 ++row;
16946 }
16947 }
16948
16949
16950 /* Try to redisplay window W by reusing its existing display. W's
16951 current matrix must be up to date when this function is called,
16952 i.e. window_end_valid must be nonzero.
16953
16954 Value is
16955
16956 1 if display has been updated
16957 0 if otherwise unsuccessful
16958 -1 if redisplay with same window start is known not to succeed
16959
16960 The following steps are performed:
16961
16962 1. Find the last row in the current matrix of W that is not
16963 affected by changes at the start of current_buffer. If no such row
16964 is found, give up.
16965
16966 2. Find the first row in W's current matrix that is not affected by
16967 changes at the end of current_buffer. Maybe there is no such row.
16968
16969 3. Display lines beginning with the row + 1 found in step 1 to the
16970 row found in step 2 or, if step 2 didn't find a row, to the end of
16971 the window.
16972
16973 4. If cursor is not known to appear on the window, give up.
16974
16975 5. If display stopped at the row found in step 2, scroll the
16976 display and current matrix as needed.
16977
16978 6. Maybe display some lines at the end of W, if we must. This can
16979 happen under various circumstances, like a partially visible line
16980 becoming fully visible, or because newly displayed lines are displayed
16981 in smaller font sizes.
16982
16983 7. Update W's window end information. */
16984
16985 static int
16986 try_window_id (struct window *w)
16987 {
16988 struct frame *f = XFRAME (w->frame);
16989 struct glyph_matrix *current_matrix = w->current_matrix;
16990 struct glyph_matrix *desired_matrix = w->desired_matrix;
16991 struct glyph_row *last_unchanged_at_beg_row;
16992 struct glyph_row *first_unchanged_at_end_row;
16993 struct glyph_row *row;
16994 struct glyph_row *bottom_row;
16995 int bottom_vpos;
16996 struct it it;
16997 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
16998 int dvpos, dy;
16999 struct text_pos start_pos;
17000 struct run run;
17001 int first_unchanged_at_end_vpos = 0;
17002 struct glyph_row *last_text_row, *last_text_row_at_end;
17003 struct text_pos start;
17004 ptrdiff_t first_changed_charpos, last_changed_charpos;
17005
17006 #ifdef GLYPH_DEBUG
17007 if (inhibit_try_window_id)
17008 return 0;
17009 #endif
17010
17011 /* This is handy for debugging. */
17012 #if 0
17013 #define GIVE_UP(X) \
17014 do { \
17015 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17016 return 0; \
17017 } while (0)
17018 #else
17019 #define GIVE_UP(X) return 0
17020 #endif
17021
17022 SET_TEXT_POS_FROM_MARKER (start, w->start);
17023
17024 /* Don't use this for mini-windows because these can show
17025 messages and mini-buffers, and we don't handle that here. */
17026 if (MINI_WINDOW_P (w))
17027 GIVE_UP (1);
17028
17029 /* This flag is used to prevent redisplay optimizations. */
17030 if (windows_or_buffers_changed || cursor_type_changed)
17031 GIVE_UP (2);
17032
17033 /* Verify that narrowing has not changed.
17034 Also verify that we were not told to prevent redisplay optimizations.
17035 It would be nice to further
17036 reduce the number of cases where this prevents try_window_id. */
17037 if (current_buffer->clip_changed
17038 || current_buffer->prevent_redisplay_optimizations_p)
17039 GIVE_UP (3);
17040
17041 /* Window must either use window-based redisplay or be full width. */
17042 if (!FRAME_WINDOW_P (f)
17043 && (!FRAME_LINE_INS_DEL_OK (f)
17044 || !WINDOW_FULL_WIDTH_P (w)))
17045 GIVE_UP (4);
17046
17047 /* Give up if point is known NOT to appear in W. */
17048 if (PT < CHARPOS (start))
17049 GIVE_UP (5);
17050
17051 /* Another way to prevent redisplay optimizations. */
17052 if (w->last_modified == 0)
17053 GIVE_UP (6);
17054
17055 /* Verify that window is not hscrolled. */
17056 if (w->hscroll != 0)
17057 GIVE_UP (7);
17058
17059 /* Verify that display wasn't paused. */
17060 if (!w->window_end_valid)
17061 GIVE_UP (8);
17062
17063 /* Can't use this if highlighting a region because a cursor movement
17064 will do more than just set the cursor. */
17065 if (0 <= markpos_of_region ())
17066 GIVE_UP (9);
17067
17068 /* Likewise if highlighting trailing whitespace. */
17069 if (!NILP (Vshow_trailing_whitespace))
17070 GIVE_UP (11);
17071
17072 /* Likewise if showing a region. */
17073 if (!NILP (w->region_showing))
17074 GIVE_UP (10);
17075
17076 /* Can't use this if overlay arrow position and/or string have
17077 changed. */
17078 if (overlay_arrows_changed_p ())
17079 GIVE_UP (12);
17080
17081 /* When word-wrap is on, adding a space to the first word of a
17082 wrapped line can change the wrap position, altering the line
17083 above it. It might be worthwhile to handle this more
17084 intelligently, but for now just redisplay from scratch. */
17085 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
17086 GIVE_UP (21);
17087
17088 /* Under bidi reordering, adding or deleting a character in the
17089 beginning of a paragraph, before the first strong directional
17090 character, can change the base direction of the paragraph (unless
17091 the buffer specifies a fixed paragraph direction), which will
17092 require to redisplay the whole paragraph. It might be worthwhile
17093 to find the paragraph limits and widen the range of redisplayed
17094 lines to that, but for now just give up this optimization and
17095 redisplay from scratch. */
17096 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
17097 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
17098 GIVE_UP (22);
17099
17100 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17101 only if buffer has really changed. The reason is that the gap is
17102 initially at Z for freshly visited files. The code below would
17103 set end_unchanged to 0 in that case. */
17104 if (MODIFF > SAVE_MODIFF
17105 /* This seems to happen sometimes after saving a buffer. */
17106 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17107 {
17108 if (GPT - BEG < BEG_UNCHANGED)
17109 BEG_UNCHANGED = GPT - BEG;
17110 if (Z - GPT < END_UNCHANGED)
17111 END_UNCHANGED = Z - GPT;
17112 }
17113
17114 /* The position of the first and last character that has been changed. */
17115 first_changed_charpos = BEG + BEG_UNCHANGED;
17116 last_changed_charpos = Z - END_UNCHANGED;
17117
17118 /* If window starts after a line end, and the last change is in
17119 front of that newline, then changes don't affect the display.
17120 This case happens with stealth-fontification. Note that although
17121 the display is unchanged, glyph positions in the matrix have to
17122 be adjusted, of course. */
17123 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17124 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17125 && ((last_changed_charpos < CHARPOS (start)
17126 && CHARPOS (start) == BEGV)
17127 || (last_changed_charpos < CHARPOS (start) - 1
17128 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17129 {
17130 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17131 struct glyph_row *r0;
17132
17133 /* Compute how many chars/bytes have been added to or removed
17134 from the buffer. */
17135 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17136 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17137 Z_delta = Z - Z_old;
17138 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17139
17140 /* Give up if PT is not in the window. Note that it already has
17141 been checked at the start of try_window_id that PT is not in
17142 front of the window start. */
17143 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17144 GIVE_UP (13);
17145
17146 /* If window start is unchanged, we can reuse the whole matrix
17147 as is, after adjusting glyph positions. No need to compute
17148 the window end again, since its offset from Z hasn't changed. */
17149 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17150 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17151 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17152 /* PT must not be in a partially visible line. */
17153 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17154 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17155 {
17156 /* Adjust positions in the glyph matrix. */
17157 if (Z_delta || Z_delta_bytes)
17158 {
17159 struct glyph_row *r1
17160 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17161 increment_matrix_positions (w->current_matrix,
17162 MATRIX_ROW_VPOS (r0, current_matrix),
17163 MATRIX_ROW_VPOS (r1, current_matrix),
17164 Z_delta, Z_delta_bytes);
17165 }
17166
17167 /* Set the cursor. */
17168 row = row_containing_pos (w, PT, r0, NULL, 0);
17169 if (row)
17170 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17171 else
17172 emacs_abort ();
17173 return 1;
17174 }
17175 }
17176
17177 /* Handle the case that changes are all below what is displayed in
17178 the window, and that PT is in the window. This shortcut cannot
17179 be taken if ZV is visible in the window, and text has been added
17180 there that is visible in the window. */
17181 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17182 /* ZV is not visible in the window, or there are no
17183 changes at ZV, actually. */
17184 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17185 || first_changed_charpos == last_changed_charpos))
17186 {
17187 struct glyph_row *r0;
17188
17189 /* Give up if PT is not in the window. Note that it already has
17190 been checked at the start of try_window_id that PT is not in
17191 front of the window start. */
17192 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17193 GIVE_UP (14);
17194
17195 /* If window start is unchanged, we can reuse the whole matrix
17196 as is, without changing glyph positions since no text has
17197 been added/removed in front of the window end. */
17198 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17199 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17200 /* PT must not be in a partially visible line. */
17201 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17202 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17203 {
17204 /* We have to compute the window end anew since text
17205 could have been added/removed after it. */
17206 wset_window_end_pos
17207 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17208 w->window_end_bytepos
17209 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17210
17211 /* Set the cursor. */
17212 row = row_containing_pos (w, PT, r0, NULL, 0);
17213 if (row)
17214 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17215 else
17216 emacs_abort ();
17217 return 2;
17218 }
17219 }
17220
17221 /* Give up if window start is in the changed area.
17222
17223 The condition used to read
17224
17225 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17226
17227 but why that was tested escapes me at the moment. */
17228 if (CHARPOS (start) >= first_changed_charpos
17229 && CHARPOS (start) <= last_changed_charpos)
17230 GIVE_UP (15);
17231
17232 /* Check that window start agrees with the start of the first glyph
17233 row in its current matrix. Check this after we know the window
17234 start is not in changed text, otherwise positions would not be
17235 comparable. */
17236 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17237 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17238 GIVE_UP (16);
17239
17240 /* Give up if the window ends in strings. Overlay strings
17241 at the end are difficult to handle, so don't try. */
17242 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17243 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17244 GIVE_UP (20);
17245
17246 /* Compute the position at which we have to start displaying new
17247 lines. Some of the lines at the top of the window might be
17248 reusable because they are not displaying changed text. Find the
17249 last row in W's current matrix not affected by changes at the
17250 start of current_buffer. Value is null if changes start in the
17251 first line of window. */
17252 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17253 if (last_unchanged_at_beg_row)
17254 {
17255 /* Avoid starting to display in the middle of a character, a TAB
17256 for instance. This is easier than to set up the iterator
17257 exactly, and it's not a frequent case, so the additional
17258 effort wouldn't really pay off. */
17259 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17260 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17261 && last_unchanged_at_beg_row > w->current_matrix->rows)
17262 --last_unchanged_at_beg_row;
17263
17264 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17265 GIVE_UP (17);
17266
17267 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17268 GIVE_UP (18);
17269 start_pos = it.current.pos;
17270
17271 /* Start displaying new lines in the desired matrix at the same
17272 vpos we would use in the current matrix, i.e. below
17273 last_unchanged_at_beg_row. */
17274 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17275 current_matrix);
17276 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17277 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17278
17279 eassert (it.hpos == 0 && it.current_x == 0);
17280 }
17281 else
17282 {
17283 /* There are no reusable lines at the start of the window.
17284 Start displaying in the first text line. */
17285 start_display (&it, w, start);
17286 it.vpos = it.first_vpos;
17287 start_pos = it.current.pos;
17288 }
17289
17290 /* Find the first row that is not affected by changes at the end of
17291 the buffer. Value will be null if there is no unchanged row, in
17292 which case we must redisplay to the end of the window. delta
17293 will be set to the value by which buffer positions beginning with
17294 first_unchanged_at_end_row have to be adjusted due to text
17295 changes. */
17296 first_unchanged_at_end_row
17297 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17298 IF_DEBUG (debug_delta = delta);
17299 IF_DEBUG (debug_delta_bytes = delta_bytes);
17300
17301 /* Set stop_pos to the buffer position up to which we will have to
17302 display new lines. If first_unchanged_at_end_row != NULL, this
17303 is the buffer position of the start of the line displayed in that
17304 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17305 that we don't stop at a buffer position. */
17306 stop_pos = 0;
17307 if (first_unchanged_at_end_row)
17308 {
17309 eassert (last_unchanged_at_beg_row == NULL
17310 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17311
17312 /* If this is a continuation line, move forward to the next one
17313 that isn't. Changes in lines above affect this line.
17314 Caution: this may move first_unchanged_at_end_row to a row
17315 not displaying text. */
17316 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17317 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17318 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17319 < it.last_visible_y))
17320 ++first_unchanged_at_end_row;
17321
17322 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17323 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17324 >= it.last_visible_y))
17325 first_unchanged_at_end_row = NULL;
17326 else
17327 {
17328 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17329 + delta);
17330 first_unchanged_at_end_vpos
17331 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17332 eassert (stop_pos >= Z - END_UNCHANGED);
17333 }
17334 }
17335 else if (last_unchanged_at_beg_row == NULL)
17336 GIVE_UP (19);
17337
17338
17339 #ifdef GLYPH_DEBUG
17340
17341 /* Either there is no unchanged row at the end, or the one we have
17342 now displays text. This is a necessary condition for the window
17343 end pos calculation at the end of this function. */
17344 eassert (first_unchanged_at_end_row == NULL
17345 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17346
17347 debug_last_unchanged_at_beg_vpos
17348 = (last_unchanged_at_beg_row
17349 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17350 : -1);
17351 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17352
17353 #endif /* GLYPH_DEBUG */
17354
17355
17356 /* Display new lines. Set last_text_row to the last new line
17357 displayed which has text on it, i.e. might end up as being the
17358 line where the window_end_vpos is. */
17359 w->cursor.vpos = -1;
17360 last_text_row = NULL;
17361 overlay_arrow_seen = 0;
17362 while (it.current_y < it.last_visible_y
17363 && !fonts_changed_p
17364 && (first_unchanged_at_end_row == NULL
17365 || IT_CHARPOS (it) < stop_pos))
17366 {
17367 if (display_line (&it))
17368 last_text_row = it.glyph_row - 1;
17369 }
17370
17371 if (fonts_changed_p)
17372 return -1;
17373
17374
17375 /* Compute differences in buffer positions, y-positions etc. for
17376 lines reused at the bottom of the window. Compute what we can
17377 scroll. */
17378 if (first_unchanged_at_end_row
17379 /* No lines reused because we displayed everything up to the
17380 bottom of the window. */
17381 && it.current_y < it.last_visible_y)
17382 {
17383 dvpos = (it.vpos
17384 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17385 current_matrix));
17386 dy = it.current_y - first_unchanged_at_end_row->y;
17387 run.current_y = first_unchanged_at_end_row->y;
17388 run.desired_y = run.current_y + dy;
17389 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17390 }
17391 else
17392 {
17393 delta = delta_bytes = dvpos = dy
17394 = run.current_y = run.desired_y = run.height = 0;
17395 first_unchanged_at_end_row = NULL;
17396 }
17397 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17398
17399
17400 /* Find the cursor if not already found. We have to decide whether
17401 PT will appear on this window (it sometimes doesn't, but this is
17402 not a very frequent case.) This decision has to be made before
17403 the current matrix is altered. A value of cursor.vpos < 0 means
17404 that PT is either in one of the lines beginning at
17405 first_unchanged_at_end_row or below the window. Don't care for
17406 lines that might be displayed later at the window end; as
17407 mentioned, this is not a frequent case. */
17408 if (w->cursor.vpos < 0)
17409 {
17410 /* Cursor in unchanged rows at the top? */
17411 if (PT < CHARPOS (start_pos)
17412 && last_unchanged_at_beg_row)
17413 {
17414 row = row_containing_pos (w, PT,
17415 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17416 last_unchanged_at_beg_row + 1, 0);
17417 if (row)
17418 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17419 }
17420
17421 /* Start from first_unchanged_at_end_row looking for PT. */
17422 else if (first_unchanged_at_end_row)
17423 {
17424 row = row_containing_pos (w, PT - delta,
17425 first_unchanged_at_end_row, NULL, 0);
17426 if (row)
17427 set_cursor_from_row (w, row, w->current_matrix, delta,
17428 delta_bytes, dy, dvpos);
17429 }
17430
17431 /* Give up if cursor was not found. */
17432 if (w->cursor.vpos < 0)
17433 {
17434 clear_glyph_matrix (w->desired_matrix);
17435 return -1;
17436 }
17437 }
17438
17439 /* Don't let the cursor end in the scroll margins. */
17440 {
17441 int this_scroll_margin, cursor_height;
17442
17443 this_scroll_margin =
17444 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
17445 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
17446 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17447
17448 if ((w->cursor.y < this_scroll_margin
17449 && CHARPOS (start) > BEGV)
17450 /* Old redisplay didn't take scroll margin into account at the bottom,
17451 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17452 || (w->cursor.y + (make_cursor_line_fully_visible_p
17453 ? cursor_height + this_scroll_margin
17454 : 1)) > it.last_visible_y)
17455 {
17456 w->cursor.vpos = -1;
17457 clear_glyph_matrix (w->desired_matrix);
17458 return -1;
17459 }
17460 }
17461
17462 /* Scroll the display. Do it before changing the current matrix so
17463 that xterm.c doesn't get confused about where the cursor glyph is
17464 found. */
17465 if (dy && run.height)
17466 {
17467 update_begin (f);
17468
17469 if (FRAME_WINDOW_P (f))
17470 {
17471 FRAME_RIF (f)->update_window_begin_hook (w);
17472 FRAME_RIF (f)->clear_window_mouse_face (w);
17473 FRAME_RIF (f)->scroll_run_hook (w, &run);
17474 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17475 }
17476 else
17477 {
17478 /* Terminal frame. In this case, dvpos gives the number of
17479 lines to scroll by; dvpos < 0 means scroll up. */
17480 int from_vpos
17481 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17482 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17483 int end = (WINDOW_TOP_EDGE_LINE (w)
17484 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17485 + window_internal_height (w));
17486
17487 #if defined (HAVE_GPM) || defined (MSDOS)
17488 x_clear_window_mouse_face (w);
17489 #endif
17490 /* Perform the operation on the screen. */
17491 if (dvpos > 0)
17492 {
17493 /* Scroll last_unchanged_at_beg_row to the end of the
17494 window down dvpos lines. */
17495 set_terminal_window (f, end);
17496
17497 /* On dumb terminals delete dvpos lines at the end
17498 before inserting dvpos empty lines. */
17499 if (!FRAME_SCROLL_REGION_OK (f))
17500 ins_del_lines (f, end - dvpos, -dvpos);
17501
17502 /* Insert dvpos empty lines in front of
17503 last_unchanged_at_beg_row. */
17504 ins_del_lines (f, from, dvpos);
17505 }
17506 else if (dvpos < 0)
17507 {
17508 /* Scroll up last_unchanged_at_beg_vpos to the end of
17509 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17510 set_terminal_window (f, end);
17511
17512 /* Delete dvpos lines in front of
17513 last_unchanged_at_beg_vpos. ins_del_lines will set
17514 the cursor to the given vpos and emit |dvpos| delete
17515 line sequences. */
17516 ins_del_lines (f, from + dvpos, dvpos);
17517
17518 /* On a dumb terminal insert dvpos empty lines at the
17519 end. */
17520 if (!FRAME_SCROLL_REGION_OK (f))
17521 ins_del_lines (f, end + dvpos, -dvpos);
17522 }
17523
17524 set_terminal_window (f, 0);
17525 }
17526
17527 update_end (f);
17528 }
17529
17530 /* Shift reused rows of the current matrix to the right position.
17531 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17532 text. */
17533 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17534 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17535 if (dvpos < 0)
17536 {
17537 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17538 bottom_vpos, dvpos);
17539 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17540 bottom_vpos);
17541 }
17542 else if (dvpos > 0)
17543 {
17544 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17545 bottom_vpos, dvpos);
17546 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17547 first_unchanged_at_end_vpos + dvpos);
17548 }
17549
17550 /* For frame-based redisplay, make sure that current frame and window
17551 matrix are in sync with respect to glyph memory. */
17552 if (!FRAME_WINDOW_P (f))
17553 sync_frame_with_window_matrix_rows (w);
17554
17555 /* Adjust buffer positions in reused rows. */
17556 if (delta || delta_bytes)
17557 increment_matrix_positions (current_matrix,
17558 first_unchanged_at_end_vpos + dvpos,
17559 bottom_vpos, delta, delta_bytes);
17560
17561 /* Adjust Y positions. */
17562 if (dy)
17563 shift_glyph_matrix (w, current_matrix,
17564 first_unchanged_at_end_vpos + dvpos,
17565 bottom_vpos, dy);
17566
17567 if (first_unchanged_at_end_row)
17568 {
17569 first_unchanged_at_end_row += dvpos;
17570 if (first_unchanged_at_end_row->y >= it.last_visible_y
17571 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17572 first_unchanged_at_end_row = NULL;
17573 }
17574
17575 /* If scrolling up, there may be some lines to display at the end of
17576 the window. */
17577 last_text_row_at_end = NULL;
17578 if (dy < 0)
17579 {
17580 /* Scrolling up can leave for example a partially visible line
17581 at the end of the window to be redisplayed. */
17582 /* Set last_row to the glyph row in the current matrix where the
17583 window end line is found. It has been moved up or down in
17584 the matrix by dvpos. */
17585 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17586 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17587
17588 /* If last_row is the window end line, it should display text. */
17589 eassert (last_row->displays_text_p);
17590
17591 /* If window end line was partially visible before, begin
17592 displaying at that line. Otherwise begin displaying with the
17593 line following it. */
17594 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17595 {
17596 init_to_row_start (&it, w, last_row);
17597 it.vpos = last_vpos;
17598 it.current_y = last_row->y;
17599 }
17600 else
17601 {
17602 init_to_row_end (&it, w, last_row);
17603 it.vpos = 1 + last_vpos;
17604 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17605 ++last_row;
17606 }
17607
17608 /* We may start in a continuation line. If so, we have to
17609 get the right continuation_lines_width and current_x. */
17610 it.continuation_lines_width = last_row->continuation_lines_width;
17611 it.hpos = it.current_x = 0;
17612
17613 /* Display the rest of the lines at the window end. */
17614 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17615 while (it.current_y < it.last_visible_y
17616 && !fonts_changed_p)
17617 {
17618 /* Is it always sure that the display agrees with lines in
17619 the current matrix? I don't think so, so we mark rows
17620 displayed invalid in the current matrix by setting their
17621 enabled_p flag to zero. */
17622 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17623 if (display_line (&it))
17624 last_text_row_at_end = it.glyph_row - 1;
17625 }
17626 }
17627
17628 /* Update window_end_pos and window_end_vpos. */
17629 if (first_unchanged_at_end_row
17630 && !last_text_row_at_end)
17631 {
17632 /* Window end line if one of the preserved rows from the current
17633 matrix. Set row to the last row displaying text in current
17634 matrix starting at first_unchanged_at_end_row, after
17635 scrolling. */
17636 eassert (first_unchanged_at_end_row->displays_text_p);
17637 row = find_last_row_displaying_text (w->current_matrix, &it,
17638 first_unchanged_at_end_row);
17639 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17640
17641 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17642 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17643 wset_window_end_vpos
17644 (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
17645 eassert (w->window_end_bytepos >= 0);
17646 IF_DEBUG (debug_method_add (w, "A"));
17647 }
17648 else if (last_text_row_at_end)
17649 {
17650 wset_window_end_pos
17651 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
17652 w->window_end_bytepos
17653 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17654 wset_window_end_vpos
17655 (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
17656 desired_matrix)));
17657 eassert (w->window_end_bytepos >= 0);
17658 IF_DEBUG (debug_method_add (w, "B"));
17659 }
17660 else if (last_text_row)
17661 {
17662 /* We have displayed either to the end of the window or at the
17663 end of the window, i.e. the last row with text is to be found
17664 in the desired matrix. */
17665 wset_window_end_pos
17666 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
17667 w->window_end_bytepos
17668 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17669 wset_window_end_vpos
17670 (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
17671 eassert (w->window_end_bytepos >= 0);
17672 }
17673 else if (first_unchanged_at_end_row == NULL
17674 && last_text_row == NULL
17675 && last_text_row_at_end == NULL)
17676 {
17677 /* Displayed to end of window, but no line containing text was
17678 displayed. Lines were deleted at the end of the window. */
17679 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17680 int vpos = XFASTINT (w->window_end_vpos);
17681 struct glyph_row *current_row = current_matrix->rows + vpos;
17682 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17683
17684 for (row = NULL;
17685 row == NULL && vpos >= first_vpos;
17686 --vpos, --current_row, --desired_row)
17687 {
17688 if (desired_row->enabled_p)
17689 {
17690 if (desired_row->displays_text_p)
17691 row = desired_row;
17692 }
17693 else if (current_row->displays_text_p)
17694 row = current_row;
17695 }
17696
17697 eassert (row != NULL);
17698 wset_window_end_vpos (w, make_number (vpos + 1));
17699 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17700 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17701 eassert (w->window_end_bytepos >= 0);
17702 IF_DEBUG (debug_method_add (w, "C"));
17703 }
17704 else
17705 emacs_abort ();
17706
17707 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17708 debug_end_vpos = XFASTINT (w->window_end_vpos));
17709
17710 /* Record that display has not been completed. */
17711 w->window_end_valid = 0;
17712 w->desired_matrix->no_scrolling_p = 1;
17713 return 3;
17714
17715 #undef GIVE_UP
17716 }
17717
17718
17719 \f
17720 /***********************************************************************
17721 More debugging support
17722 ***********************************************************************/
17723
17724 #ifdef GLYPH_DEBUG
17725
17726 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17727 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17728 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17729
17730
17731 /* Dump the contents of glyph matrix MATRIX on stderr.
17732
17733 GLYPHS 0 means don't show glyph contents.
17734 GLYPHS 1 means show glyphs in short form
17735 GLYPHS > 1 means show glyphs in long form. */
17736
17737 void
17738 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17739 {
17740 int i;
17741 for (i = 0; i < matrix->nrows; ++i)
17742 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17743 }
17744
17745
17746 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17747 the glyph row and area where the glyph comes from. */
17748
17749 void
17750 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17751 {
17752 if (glyph->type == CHAR_GLYPH
17753 || glyph->type == GLYPHLESS_GLYPH)
17754 {
17755 fprintf (stderr,
17756 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17757 glyph - row->glyphs[TEXT_AREA],
17758 (glyph->type == CHAR_GLYPH
17759 ? 'C'
17760 : 'G'),
17761 glyph->charpos,
17762 (BUFFERP (glyph->object)
17763 ? 'B'
17764 : (STRINGP (glyph->object)
17765 ? 'S'
17766 : (INTEGERP (glyph->object)
17767 ? '0'
17768 : '-'))),
17769 glyph->pixel_width,
17770 glyph->u.ch,
17771 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17772 ? glyph->u.ch
17773 : '.'),
17774 glyph->face_id,
17775 glyph->left_box_line_p,
17776 glyph->right_box_line_p);
17777 }
17778 else if (glyph->type == STRETCH_GLYPH)
17779 {
17780 fprintf (stderr,
17781 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17782 glyph - row->glyphs[TEXT_AREA],
17783 'S',
17784 glyph->charpos,
17785 (BUFFERP (glyph->object)
17786 ? 'B'
17787 : (STRINGP (glyph->object)
17788 ? 'S'
17789 : (INTEGERP (glyph->object)
17790 ? '0'
17791 : '-'))),
17792 glyph->pixel_width,
17793 0,
17794 ' ',
17795 glyph->face_id,
17796 glyph->left_box_line_p,
17797 glyph->right_box_line_p);
17798 }
17799 else if (glyph->type == IMAGE_GLYPH)
17800 {
17801 fprintf (stderr,
17802 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17803 glyph - row->glyphs[TEXT_AREA],
17804 'I',
17805 glyph->charpos,
17806 (BUFFERP (glyph->object)
17807 ? 'B'
17808 : (STRINGP (glyph->object)
17809 ? 'S'
17810 : (INTEGERP (glyph->object)
17811 ? '0'
17812 : '-'))),
17813 glyph->pixel_width,
17814 glyph->u.img_id,
17815 '.',
17816 glyph->face_id,
17817 glyph->left_box_line_p,
17818 glyph->right_box_line_p);
17819 }
17820 else if (glyph->type == COMPOSITE_GLYPH)
17821 {
17822 fprintf (stderr,
17823 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17824 glyph - row->glyphs[TEXT_AREA],
17825 '+',
17826 glyph->charpos,
17827 (BUFFERP (glyph->object)
17828 ? 'B'
17829 : (STRINGP (glyph->object)
17830 ? 'S'
17831 : (INTEGERP (glyph->object)
17832 ? '0'
17833 : '-'))),
17834 glyph->pixel_width,
17835 glyph->u.cmp.id);
17836 if (glyph->u.cmp.automatic)
17837 fprintf (stderr,
17838 "[%d-%d]",
17839 glyph->slice.cmp.from, glyph->slice.cmp.to);
17840 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17841 glyph->face_id,
17842 glyph->left_box_line_p,
17843 glyph->right_box_line_p);
17844 }
17845 }
17846
17847
17848 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17849 GLYPHS 0 means don't show glyph contents.
17850 GLYPHS 1 means show glyphs in short form
17851 GLYPHS > 1 means show glyphs in long form. */
17852
17853 void
17854 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17855 {
17856 if (glyphs != 1)
17857 {
17858 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17859 fprintf (stderr, "==============================================================================\n");
17860
17861 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17862 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17863 vpos,
17864 MATRIX_ROW_START_CHARPOS (row),
17865 MATRIX_ROW_END_CHARPOS (row),
17866 row->used[TEXT_AREA],
17867 row->contains_overlapping_glyphs_p,
17868 row->enabled_p,
17869 row->truncated_on_left_p,
17870 row->truncated_on_right_p,
17871 row->continued_p,
17872 MATRIX_ROW_CONTINUATION_LINE_P (row),
17873 row->displays_text_p,
17874 row->ends_at_zv_p,
17875 row->fill_line_p,
17876 row->ends_in_middle_of_char_p,
17877 row->starts_in_middle_of_char_p,
17878 row->mouse_face_p,
17879 row->x,
17880 row->y,
17881 row->pixel_width,
17882 row->height,
17883 row->visible_height,
17884 row->ascent,
17885 row->phys_ascent);
17886 /* The next 3 lines should align to "Start" in the header. */
17887 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
17888 row->end.overlay_string_index,
17889 row->continuation_lines_width);
17890 fprintf (stderr, " %9"pI"d %9"pI"d\n",
17891 CHARPOS (row->start.string_pos),
17892 CHARPOS (row->end.string_pos));
17893 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
17894 row->end.dpvec_index);
17895 }
17896
17897 if (glyphs > 1)
17898 {
17899 int area;
17900
17901 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17902 {
17903 struct glyph *glyph = row->glyphs[area];
17904 struct glyph *glyph_end = glyph + row->used[area];
17905
17906 /* Glyph for a line end in text. */
17907 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
17908 ++glyph_end;
17909
17910 if (glyph < glyph_end)
17911 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
17912
17913 for (; glyph < glyph_end; ++glyph)
17914 dump_glyph (row, glyph, area);
17915 }
17916 }
17917 else if (glyphs == 1)
17918 {
17919 int area;
17920
17921 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17922 {
17923 char *s = alloca (row->used[area] + 4);
17924 int i;
17925
17926 for (i = 0; i < row->used[area]; ++i)
17927 {
17928 struct glyph *glyph = row->glyphs[area] + i;
17929 if (i == row->used[area] - 1
17930 && area == TEXT_AREA
17931 && INTEGERP (glyph->object)
17932 && glyph->type == CHAR_GLYPH
17933 && glyph->u.ch == ' ')
17934 {
17935 strcpy (&s[i], "[\\n]");
17936 i += 4;
17937 }
17938 else if (glyph->type == CHAR_GLYPH
17939 && glyph->u.ch < 0x80
17940 && glyph->u.ch >= ' ')
17941 s[i] = glyph->u.ch;
17942 else
17943 s[i] = '.';
17944 }
17945
17946 s[i] = '\0';
17947 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
17948 }
17949 }
17950 }
17951
17952
17953 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
17954 Sdump_glyph_matrix, 0, 1, "p",
17955 doc: /* Dump the current matrix of the selected window to stderr.
17956 Shows contents of glyph row structures. With non-nil
17957 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
17958 glyphs in short form, otherwise show glyphs in long form. */)
17959 (Lisp_Object glyphs)
17960 {
17961 struct window *w = XWINDOW (selected_window);
17962 struct buffer *buffer = XBUFFER (w->buffer);
17963
17964 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
17965 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
17966 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
17967 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
17968 fprintf (stderr, "=============================================\n");
17969 dump_glyph_matrix (w->current_matrix,
17970 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
17971 return Qnil;
17972 }
17973
17974
17975 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
17976 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
17977 (void)
17978 {
17979 struct frame *f = XFRAME (selected_frame);
17980 dump_glyph_matrix (f->current_matrix, 1);
17981 return Qnil;
17982 }
17983
17984
17985 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
17986 doc: /* Dump glyph row ROW to stderr.
17987 GLYPH 0 means don't dump glyphs.
17988 GLYPH 1 means dump glyphs in short form.
17989 GLYPH > 1 or omitted means dump glyphs in long form. */)
17990 (Lisp_Object row, Lisp_Object glyphs)
17991 {
17992 struct glyph_matrix *matrix;
17993 EMACS_INT vpos;
17994
17995 CHECK_NUMBER (row);
17996 matrix = XWINDOW (selected_window)->current_matrix;
17997 vpos = XINT (row);
17998 if (vpos >= 0 && vpos < matrix->nrows)
17999 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18000 vpos,
18001 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18002 return Qnil;
18003 }
18004
18005
18006 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18007 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18008 GLYPH 0 means don't dump glyphs.
18009 GLYPH 1 means dump glyphs in short form.
18010 GLYPH > 1 or omitted means dump glyphs in long form. */)
18011 (Lisp_Object row, Lisp_Object glyphs)
18012 {
18013 struct frame *sf = SELECTED_FRAME ();
18014 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18015 EMACS_INT vpos;
18016
18017 CHECK_NUMBER (row);
18018 vpos = XINT (row);
18019 if (vpos >= 0 && vpos < m->nrows)
18020 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18021 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18022 return Qnil;
18023 }
18024
18025
18026 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18027 doc: /* Toggle tracing of redisplay.
18028 With ARG, turn tracing on if and only if ARG is positive. */)
18029 (Lisp_Object arg)
18030 {
18031 if (NILP (arg))
18032 trace_redisplay_p = !trace_redisplay_p;
18033 else
18034 {
18035 arg = Fprefix_numeric_value (arg);
18036 trace_redisplay_p = XINT (arg) > 0;
18037 }
18038
18039 return Qnil;
18040 }
18041
18042
18043 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18044 doc: /* Like `format', but print result to stderr.
18045 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18046 (ptrdiff_t nargs, Lisp_Object *args)
18047 {
18048 Lisp_Object s = Fformat (nargs, args);
18049 fprintf (stderr, "%s", SDATA (s));
18050 return Qnil;
18051 }
18052
18053 #endif /* GLYPH_DEBUG */
18054
18055
18056 \f
18057 /***********************************************************************
18058 Building Desired Matrix Rows
18059 ***********************************************************************/
18060
18061 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18062 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18063
18064 static struct glyph_row *
18065 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18066 {
18067 struct frame *f = XFRAME (WINDOW_FRAME (w));
18068 struct buffer *buffer = XBUFFER (w->buffer);
18069 struct buffer *old = current_buffer;
18070 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18071 int arrow_len = SCHARS (overlay_arrow_string);
18072 const unsigned char *arrow_end = arrow_string + arrow_len;
18073 const unsigned char *p;
18074 struct it it;
18075 int multibyte_p;
18076 int n_glyphs_before;
18077
18078 set_buffer_temp (buffer);
18079 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18080 it.glyph_row->used[TEXT_AREA] = 0;
18081 SET_TEXT_POS (it.position, 0, 0);
18082
18083 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18084 p = arrow_string;
18085 while (p < arrow_end)
18086 {
18087 Lisp_Object face, ilisp;
18088
18089 /* Get the next character. */
18090 if (multibyte_p)
18091 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18092 else
18093 {
18094 it.c = it.char_to_display = *p, it.len = 1;
18095 if (! ASCII_CHAR_P (it.c))
18096 it.char_to_display = BYTE8_TO_CHAR (it.c);
18097 }
18098 p += it.len;
18099
18100 /* Get its face. */
18101 ilisp = make_number (p - arrow_string);
18102 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18103 it.face_id = compute_char_face (f, it.char_to_display, face);
18104
18105 /* Compute its width, get its glyphs. */
18106 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18107 SET_TEXT_POS (it.position, -1, -1);
18108 PRODUCE_GLYPHS (&it);
18109
18110 /* If this character doesn't fit any more in the line, we have
18111 to remove some glyphs. */
18112 if (it.current_x > it.last_visible_x)
18113 {
18114 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18115 break;
18116 }
18117 }
18118
18119 set_buffer_temp (old);
18120 return it.glyph_row;
18121 }
18122
18123
18124 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18125 glyphs to insert is determined by produce_special_glyphs. */
18126
18127 static void
18128 insert_left_trunc_glyphs (struct it *it)
18129 {
18130 struct it truncate_it;
18131 struct glyph *from, *end, *to, *toend;
18132
18133 eassert (!FRAME_WINDOW_P (it->f)
18134 || (!it->glyph_row->reversed_p
18135 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18136 || (it->glyph_row->reversed_p
18137 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18138
18139 /* Get the truncation glyphs. */
18140 truncate_it = *it;
18141 truncate_it.current_x = 0;
18142 truncate_it.face_id = DEFAULT_FACE_ID;
18143 truncate_it.glyph_row = &scratch_glyph_row;
18144 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18145 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18146 truncate_it.object = make_number (0);
18147 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18148
18149 /* Overwrite glyphs from IT with truncation glyphs. */
18150 if (!it->glyph_row->reversed_p)
18151 {
18152 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18153
18154 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18155 end = from + tused;
18156 to = it->glyph_row->glyphs[TEXT_AREA];
18157 toend = to + it->glyph_row->used[TEXT_AREA];
18158 if (FRAME_WINDOW_P (it->f))
18159 {
18160 /* On GUI frames, when variable-size fonts are displayed,
18161 the truncation glyphs may need more pixels than the row's
18162 glyphs they overwrite. We overwrite more glyphs to free
18163 enough screen real estate, and enlarge the stretch glyph
18164 on the right (see display_line), if there is one, to
18165 preserve the screen position of the truncation glyphs on
18166 the right. */
18167 int w = 0;
18168 struct glyph *g = to;
18169 short used;
18170
18171 /* The first glyph could be partially visible, in which case
18172 it->glyph_row->x will be negative. But we want the left
18173 truncation glyphs to be aligned at the left margin of the
18174 window, so we override the x coordinate at which the row
18175 will begin. */
18176 it->glyph_row->x = 0;
18177 while (g < toend && w < it->truncation_pixel_width)
18178 {
18179 w += g->pixel_width;
18180 ++g;
18181 }
18182 if (g - to - tused > 0)
18183 {
18184 memmove (to + tused, g, (toend - g) * sizeof(*g));
18185 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18186 }
18187 used = it->glyph_row->used[TEXT_AREA];
18188 if (it->glyph_row->truncated_on_right_p
18189 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18190 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18191 == STRETCH_GLYPH)
18192 {
18193 int extra = w - it->truncation_pixel_width;
18194
18195 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18196 }
18197 }
18198
18199 while (from < end)
18200 *to++ = *from++;
18201
18202 /* There may be padding glyphs left over. Overwrite them too. */
18203 if (!FRAME_WINDOW_P (it->f))
18204 {
18205 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18206 {
18207 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18208 while (from < end)
18209 *to++ = *from++;
18210 }
18211 }
18212
18213 if (to > toend)
18214 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18215 }
18216 else
18217 {
18218 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18219
18220 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18221 that back to front. */
18222 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18223 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18224 toend = it->glyph_row->glyphs[TEXT_AREA];
18225 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18226 if (FRAME_WINDOW_P (it->f))
18227 {
18228 int w = 0;
18229 struct glyph *g = to;
18230
18231 while (g >= toend && w < it->truncation_pixel_width)
18232 {
18233 w += g->pixel_width;
18234 --g;
18235 }
18236 if (to - g - tused > 0)
18237 to = g + tused;
18238 if (it->glyph_row->truncated_on_right_p
18239 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18240 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18241 {
18242 int extra = w - it->truncation_pixel_width;
18243
18244 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18245 }
18246 }
18247
18248 while (from >= end && to >= toend)
18249 *to-- = *from--;
18250 if (!FRAME_WINDOW_P (it->f))
18251 {
18252 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18253 {
18254 from =
18255 truncate_it.glyph_row->glyphs[TEXT_AREA]
18256 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18257 while (from >= end && to >= toend)
18258 *to-- = *from--;
18259 }
18260 }
18261 if (from >= end)
18262 {
18263 /* Need to free some room before prepending additional
18264 glyphs. */
18265 int move_by = from - end + 1;
18266 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18267 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18268
18269 for ( ; g >= g0; g--)
18270 g[move_by] = *g;
18271 while (from >= end)
18272 *to-- = *from--;
18273 it->glyph_row->used[TEXT_AREA] += move_by;
18274 }
18275 }
18276 }
18277
18278 /* Compute the hash code for ROW. */
18279 unsigned
18280 row_hash (struct glyph_row *row)
18281 {
18282 int area, k;
18283 unsigned hashval = 0;
18284
18285 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18286 for (k = 0; k < row->used[area]; ++k)
18287 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18288 + row->glyphs[area][k].u.val
18289 + row->glyphs[area][k].face_id
18290 + row->glyphs[area][k].padding_p
18291 + (row->glyphs[area][k].type << 2));
18292
18293 return hashval;
18294 }
18295
18296 /* Compute the pixel height and width of IT->glyph_row.
18297
18298 Most of the time, ascent and height of a display line will be equal
18299 to the max_ascent and max_height values of the display iterator
18300 structure. This is not the case if
18301
18302 1. We hit ZV without displaying anything. In this case, max_ascent
18303 and max_height will be zero.
18304
18305 2. We have some glyphs that don't contribute to the line height.
18306 (The glyph row flag contributes_to_line_height_p is for future
18307 pixmap extensions).
18308
18309 The first case is easily covered by using default values because in
18310 these cases, the line height does not really matter, except that it
18311 must not be zero. */
18312
18313 static void
18314 compute_line_metrics (struct it *it)
18315 {
18316 struct glyph_row *row = it->glyph_row;
18317
18318 if (FRAME_WINDOW_P (it->f))
18319 {
18320 int i, min_y, max_y;
18321
18322 /* The line may consist of one space only, that was added to
18323 place the cursor on it. If so, the row's height hasn't been
18324 computed yet. */
18325 if (row->height == 0)
18326 {
18327 if (it->max_ascent + it->max_descent == 0)
18328 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18329 row->ascent = it->max_ascent;
18330 row->height = it->max_ascent + it->max_descent;
18331 row->phys_ascent = it->max_phys_ascent;
18332 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18333 row->extra_line_spacing = it->max_extra_line_spacing;
18334 }
18335
18336 /* Compute the width of this line. */
18337 row->pixel_width = row->x;
18338 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18339 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18340
18341 eassert (row->pixel_width >= 0);
18342 eassert (row->ascent >= 0 && row->height > 0);
18343
18344 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18345 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18346
18347 /* If first line's physical ascent is larger than its logical
18348 ascent, use the physical ascent, and make the row taller.
18349 This makes accented characters fully visible. */
18350 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18351 && row->phys_ascent > row->ascent)
18352 {
18353 row->height += row->phys_ascent - row->ascent;
18354 row->ascent = row->phys_ascent;
18355 }
18356
18357 /* Compute how much of the line is visible. */
18358 row->visible_height = row->height;
18359
18360 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18361 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18362
18363 if (row->y < min_y)
18364 row->visible_height -= min_y - row->y;
18365 if (row->y + row->height > max_y)
18366 row->visible_height -= row->y + row->height - max_y;
18367 }
18368 else
18369 {
18370 row->pixel_width = row->used[TEXT_AREA];
18371 if (row->continued_p)
18372 row->pixel_width -= it->continuation_pixel_width;
18373 else if (row->truncated_on_right_p)
18374 row->pixel_width -= it->truncation_pixel_width;
18375 row->ascent = row->phys_ascent = 0;
18376 row->height = row->phys_height = row->visible_height = 1;
18377 row->extra_line_spacing = 0;
18378 }
18379
18380 /* Compute a hash code for this row. */
18381 row->hash = row_hash (row);
18382
18383 it->max_ascent = it->max_descent = 0;
18384 it->max_phys_ascent = it->max_phys_descent = 0;
18385 }
18386
18387
18388 /* Append one space to the glyph row of iterator IT if doing a
18389 window-based redisplay. The space has the same face as
18390 IT->face_id. Value is non-zero if a space was added.
18391
18392 This function is called to make sure that there is always one glyph
18393 at the end of a glyph row that the cursor can be set on under
18394 window-systems. (If there weren't such a glyph we would not know
18395 how wide and tall a box cursor should be displayed).
18396
18397 At the same time this space let's a nicely handle clearing to the
18398 end of the line if the row ends in italic text. */
18399
18400 static int
18401 append_space_for_newline (struct it *it, int default_face_p)
18402 {
18403 if (FRAME_WINDOW_P (it->f))
18404 {
18405 int n = it->glyph_row->used[TEXT_AREA];
18406
18407 if (it->glyph_row->glyphs[TEXT_AREA] + n
18408 < it->glyph_row->glyphs[1 + TEXT_AREA])
18409 {
18410 /* Save some values that must not be changed.
18411 Must save IT->c and IT->len because otherwise
18412 ITERATOR_AT_END_P wouldn't work anymore after
18413 append_space_for_newline has been called. */
18414 enum display_element_type saved_what = it->what;
18415 int saved_c = it->c, saved_len = it->len;
18416 int saved_char_to_display = it->char_to_display;
18417 int saved_x = it->current_x;
18418 int saved_face_id = it->face_id;
18419 int saved_box_end = it->end_of_box_run_p;
18420 struct text_pos saved_pos;
18421 Lisp_Object saved_object;
18422 struct face *face;
18423
18424 saved_object = it->object;
18425 saved_pos = it->position;
18426
18427 it->what = IT_CHARACTER;
18428 memset (&it->position, 0, sizeof it->position);
18429 it->object = make_number (0);
18430 it->c = it->char_to_display = ' ';
18431 it->len = 1;
18432
18433 /* If the default face was remapped, be sure to use the
18434 remapped face for the appended newline. */
18435 if (default_face_p)
18436 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18437 else if (it->face_before_selective_p)
18438 it->face_id = it->saved_face_id;
18439 face = FACE_FROM_ID (it->f, it->face_id);
18440 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18441 /* In R2L rows, we will prepend a stretch glyph that will
18442 have the end_of_box_run_p flag set for it, so there's no
18443 need for the appended newline glyph to have that flag
18444 set. */
18445 if (it->glyph_row->reversed_p
18446 /* But if the appended newline glyph goes all the way to
18447 the end of the row, there will be no stretch glyph,
18448 so leave the box flag set. */
18449 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18450 it->end_of_box_run_p = 0;
18451
18452 PRODUCE_GLYPHS (it);
18453
18454 it->override_ascent = -1;
18455 it->constrain_row_ascent_descent_p = 0;
18456 it->current_x = saved_x;
18457 it->object = saved_object;
18458 it->position = saved_pos;
18459 it->what = saved_what;
18460 it->face_id = saved_face_id;
18461 it->len = saved_len;
18462 it->c = saved_c;
18463 it->char_to_display = saved_char_to_display;
18464 it->end_of_box_run_p = saved_box_end;
18465 return 1;
18466 }
18467 }
18468
18469 return 0;
18470 }
18471
18472
18473 /* Extend the face of the last glyph in the text area of IT->glyph_row
18474 to the end of the display line. Called from display_line. If the
18475 glyph row is empty, add a space glyph to it so that we know the
18476 face to draw. Set the glyph row flag fill_line_p. If the glyph
18477 row is R2L, prepend a stretch glyph to cover the empty space to the
18478 left of the leftmost glyph. */
18479
18480 static void
18481 extend_face_to_end_of_line (struct it *it)
18482 {
18483 struct face *face, *default_face;
18484 struct frame *f = it->f;
18485
18486 /* If line is already filled, do nothing. Non window-system frames
18487 get a grace of one more ``pixel'' because their characters are
18488 1-``pixel'' wide, so they hit the equality too early. This grace
18489 is needed only for R2L rows that are not continued, to produce
18490 one extra blank where we could display the cursor. */
18491 if (it->current_x >= it->last_visible_x
18492 + (!FRAME_WINDOW_P (f)
18493 && it->glyph_row->reversed_p
18494 && !it->glyph_row->continued_p))
18495 return;
18496
18497 /* The default face, possibly remapped. */
18498 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18499
18500 /* Face extension extends the background and box of IT->face_id
18501 to the end of the line. If the background equals the background
18502 of the frame, we don't have to do anything. */
18503 if (it->face_before_selective_p)
18504 face = FACE_FROM_ID (f, it->saved_face_id);
18505 else
18506 face = FACE_FROM_ID (f, it->face_id);
18507
18508 if (FRAME_WINDOW_P (f)
18509 && it->glyph_row->displays_text_p
18510 && face->box == FACE_NO_BOX
18511 && face->background == FRAME_BACKGROUND_PIXEL (f)
18512 && !face->stipple
18513 && !it->glyph_row->reversed_p)
18514 return;
18515
18516 /* Set the glyph row flag indicating that the face of the last glyph
18517 in the text area has to be drawn to the end of the text area. */
18518 it->glyph_row->fill_line_p = 1;
18519
18520 /* If current character of IT is not ASCII, make sure we have the
18521 ASCII face. This will be automatically undone the next time
18522 get_next_display_element returns a multibyte character. Note
18523 that the character will always be single byte in unibyte
18524 text. */
18525 if (!ASCII_CHAR_P (it->c))
18526 {
18527 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18528 }
18529
18530 if (FRAME_WINDOW_P (f))
18531 {
18532 /* If the row is empty, add a space with the current face of IT,
18533 so that we know which face to draw. */
18534 if (it->glyph_row->used[TEXT_AREA] == 0)
18535 {
18536 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18537 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18538 it->glyph_row->used[TEXT_AREA] = 1;
18539 }
18540 #ifdef HAVE_WINDOW_SYSTEM
18541 if (it->glyph_row->reversed_p)
18542 {
18543 /* Prepend a stretch glyph to the row, such that the
18544 rightmost glyph will be drawn flushed all the way to the
18545 right margin of the window. The stretch glyph that will
18546 occupy the empty space, if any, to the left of the
18547 glyphs. */
18548 struct font *font = face->font ? face->font : FRAME_FONT (f);
18549 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18550 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18551 struct glyph *g;
18552 int row_width, stretch_ascent, stretch_width;
18553 struct text_pos saved_pos;
18554 int saved_face_id, saved_avoid_cursor, saved_box_start;
18555
18556 for (row_width = 0, g = row_start; g < row_end; g++)
18557 row_width += g->pixel_width;
18558 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18559 if (stretch_width > 0)
18560 {
18561 stretch_ascent =
18562 (((it->ascent + it->descent)
18563 * FONT_BASE (font)) / FONT_HEIGHT (font));
18564 saved_pos = it->position;
18565 memset (&it->position, 0, sizeof it->position);
18566 saved_avoid_cursor = it->avoid_cursor_p;
18567 it->avoid_cursor_p = 1;
18568 saved_face_id = it->face_id;
18569 saved_box_start = it->start_of_box_run_p;
18570 /* The last row's stretch glyph should get the default
18571 face, to avoid painting the rest of the window with
18572 the region face, if the region ends at ZV. */
18573 if (it->glyph_row->ends_at_zv_p)
18574 it->face_id = default_face->id;
18575 else
18576 it->face_id = face->id;
18577 it->start_of_box_run_p = 0;
18578 append_stretch_glyph (it, make_number (0), stretch_width,
18579 it->ascent + it->descent, stretch_ascent);
18580 it->position = saved_pos;
18581 it->avoid_cursor_p = saved_avoid_cursor;
18582 it->face_id = saved_face_id;
18583 it->start_of_box_run_p = saved_box_start;
18584 }
18585 }
18586 #endif /* HAVE_WINDOW_SYSTEM */
18587 }
18588 else
18589 {
18590 /* Save some values that must not be changed. */
18591 int saved_x = it->current_x;
18592 struct text_pos saved_pos;
18593 Lisp_Object saved_object;
18594 enum display_element_type saved_what = it->what;
18595 int saved_face_id = it->face_id;
18596
18597 saved_object = it->object;
18598 saved_pos = it->position;
18599
18600 it->what = IT_CHARACTER;
18601 memset (&it->position, 0, sizeof it->position);
18602 it->object = make_number (0);
18603 it->c = it->char_to_display = ' ';
18604 it->len = 1;
18605 /* The last row's blank glyphs should get the default face, to
18606 avoid painting the rest of the window with the region face,
18607 if the region ends at ZV. */
18608 if (it->glyph_row->ends_at_zv_p)
18609 it->face_id = default_face->id;
18610 else
18611 it->face_id = face->id;
18612
18613 PRODUCE_GLYPHS (it);
18614
18615 while (it->current_x <= it->last_visible_x)
18616 PRODUCE_GLYPHS (it);
18617
18618 /* Don't count these blanks really. It would let us insert a left
18619 truncation glyph below and make us set the cursor on them, maybe. */
18620 it->current_x = saved_x;
18621 it->object = saved_object;
18622 it->position = saved_pos;
18623 it->what = saved_what;
18624 it->face_id = saved_face_id;
18625 }
18626 }
18627
18628
18629 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18630 trailing whitespace. */
18631
18632 static int
18633 trailing_whitespace_p (ptrdiff_t charpos)
18634 {
18635 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18636 int c = 0;
18637
18638 while (bytepos < ZV_BYTE
18639 && (c = FETCH_CHAR (bytepos),
18640 c == ' ' || c == '\t'))
18641 ++bytepos;
18642
18643 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18644 {
18645 if (bytepos != PT_BYTE)
18646 return 1;
18647 }
18648 return 0;
18649 }
18650
18651
18652 /* Highlight trailing whitespace, if any, in ROW. */
18653
18654 static void
18655 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18656 {
18657 int used = row->used[TEXT_AREA];
18658
18659 if (used)
18660 {
18661 struct glyph *start = row->glyphs[TEXT_AREA];
18662 struct glyph *glyph = start + used - 1;
18663
18664 if (row->reversed_p)
18665 {
18666 /* Right-to-left rows need to be processed in the opposite
18667 direction, so swap the edge pointers. */
18668 glyph = start;
18669 start = row->glyphs[TEXT_AREA] + used - 1;
18670 }
18671
18672 /* Skip over glyphs inserted to display the cursor at the
18673 end of a line, for extending the face of the last glyph
18674 to the end of the line on terminals, and for truncation
18675 and continuation glyphs. */
18676 if (!row->reversed_p)
18677 {
18678 while (glyph >= start
18679 && glyph->type == CHAR_GLYPH
18680 && INTEGERP (glyph->object))
18681 --glyph;
18682 }
18683 else
18684 {
18685 while (glyph <= start
18686 && glyph->type == CHAR_GLYPH
18687 && INTEGERP (glyph->object))
18688 ++glyph;
18689 }
18690
18691 /* If last glyph is a space or stretch, and it's trailing
18692 whitespace, set the face of all trailing whitespace glyphs in
18693 IT->glyph_row to `trailing-whitespace'. */
18694 if ((row->reversed_p ? glyph <= start : glyph >= start)
18695 && BUFFERP (glyph->object)
18696 && (glyph->type == STRETCH_GLYPH
18697 || (glyph->type == CHAR_GLYPH
18698 && glyph->u.ch == ' '))
18699 && trailing_whitespace_p (glyph->charpos))
18700 {
18701 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18702 if (face_id < 0)
18703 return;
18704
18705 if (!row->reversed_p)
18706 {
18707 while (glyph >= start
18708 && BUFFERP (glyph->object)
18709 && (glyph->type == STRETCH_GLYPH
18710 || (glyph->type == CHAR_GLYPH
18711 && glyph->u.ch == ' ')))
18712 (glyph--)->face_id = face_id;
18713 }
18714 else
18715 {
18716 while (glyph <= start
18717 && BUFFERP (glyph->object)
18718 && (glyph->type == STRETCH_GLYPH
18719 || (glyph->type == CHAR_GLYPH
18720 && glyph->u.ch == ' ')))
18721 (glyph++)->face_id = face_id;
18722 }
18723 }
18724 }
18725 }
18726
18727
18728 /* Value is non-zero if glyph row ROW should be
18729 used to hold the cursor. */
18730
18731 static int
18732 cursor_row_p (struct glyph_row *row)
18733 {
18734 int result = 1;
18735
18736 if (PT == CHARPOS (row->end.pos)
18737 || PT == MATRIX_ROW_END_CHARPOS (row))
18738 {
18739 /* Suppose the row ends on a string.
18740 Unless the row is continued, that means it ends on a newline
18741 in the string. If it's anything other than a display string
18742 (e.g., a before-string from an overlay), we don't want the
18743 cursor there. (This heuristic seems to give the optimal
18744 behavior for the various types of multi-line strings.)
18745 One exception: if the string has `cursor' property on one of
18746 its characters, we _do_ want the cursor there. */
18747 if (CHARPOS (row->end.string_pos) >= 0)
18748 {
18749 if (row->continued_p)
18750 result = 1;
18751 else
18752 {
18753 /* Check for `display' property. */
18754 struct glyph *beg = row->glyphs[TEXT_AREA];
18755 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18756 struct glyph *glyph;
18757
18758 result = 0;
18759 for (glyph = end; glyph >= beg; --glyph)
18760 if (STRINGP (glyph->object))
18761 {
18762 Lisp_Object prop
18763 = Fget_char_property (make_number (PT),
18764 Qdisplay, Qnil);
18765 result =
18766 (!NILP (prop)
18767 && display_prop_string_p (prop, glyph->object));
18768 /* If there's a `cursor' property on one of the
18769 string's characters, this row is a cursor row,
18770 even though this is not a display string. */
18771 if (!result)
18772 {
18773 Lisp_Object s = glyph->object;
18774
18775 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18776 {
18777 ptrdiff_t gpos = glyph->charpos;
18778
18779 if (!NILP (Fget_char_property (make_number (gpos),
18780 Qcursor, s)))
18781 {
18782 result = 1;
18783 break;
18784 }
18785 }
18786 }
18787 break;
18788 }
18789 }
18790 }
18791 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18792 {
18793 /* If the row ends in middle of a real character,
18794 and the line is continued, we want the cursor here.
18795 That's because CHARPOS (ROW->end.pos) would equal
18796 PT if PT is before the character. */
18797 if (!row->ends_in_ellipsis_p)
18798 result = row->continued_p;
18799 else
18800 /* If the row ends in an ellipsis, then
18801 CHARPOS (ROW->end.pos) will equal point after the
18802 invisible text. We want that position to be displayed
18803 after the ellipsis. */
18804 result = 0;
18805 }
18806 /* If the row ends at ZV, display the cursor at the end of that
18807 row instead of at the start of the row below. */
18808 else if (row->ends_at_zv_p)
18809 result = 1;
18810 else
18811 result = 0;
18812 }
18813
18814 return result;
18815 }
18816
18817 \f
18818
18819 /* Push the property PROP so that it will be rendered at the current
18820 position in IT. Return 1 if PROP was successfully pushed, 0
18821 otherwise. Called from handle_line_prefix to handle the
18822 `line-prefix' and `wrap-prefix' properties. */
18823
18824 static int
18825 push_prefix_prop (struct it *it, Lisp_Object prop)
18826 {
18827 struct text_pos pos =
18828 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18829
18830 eassert (it->method == GET_FROM_BUFFER
18831 || it->method == GET_FROM_DISPLAY_VECTOR
18832 || it->method == GET_FROM_STRING);
18833
18834 /* We need to save the current buffer/string position, so it will be
18835 restored by pop_it, because iterate_out_of_display_property
18836 depends on that being set correctly, but some situations leave
18837 it->position not yet set when this function is called. */
18838 push_it (it, &pos);
18839
18840 if (STRINGP (prop))
18841 {
18842 if (SCHARS (prop) == 0)
18843 {
18844 pop_it (it);
18845 return 0;
18846 }
18847
18848 it->string = prop;
18849 it->string_from_prefix_prop_p = 1;
18850 it->multibyte_p = STRING_MULTIBYTE (it->string);
18851 it->current.overlay_string_index = -1;
18852 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18853 it->end_charpos = it->string_nchars = SCHARS (it->string);
18854 it->method = GET_FROM_STRING;
18855 it->stop_charpos = 0;
18856 it->prev_stop = 0;
18857 it->base_level_stop = 0;
18858
18859 /* Force paragraph direction to be that of the parent
18860 buffer/string. */
18861 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18862 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18863 else
18864 it->paragraph_embedding = L2R;
18865
18866 /* Set up the bidi iterator for this display string. */
18867 if (it->bidi_p)
18868 {
18869 it->bidi_it.string.lstring = it->string;
18870 it->bidi_it.string.s = NULL;
18871 it->bidi_it.string.schars = it->end_charpos;
18872 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18873 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18874 it->bidi_it.string.unibyte = !it->multibyte_p;
18875 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18876 }
18877 }
18878 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18879 {
18880 it->method = GET_FROM_STRETCH;
18881 it->object = prop;
18882 }
18883 #ifdef HAVE_WINDOW_SYSTEM
18884 else if (IMAGEP (prop))
18885 {
18886 it->what = IT_IMAGE;
18887 it->image_id = lookup_image (it->f, prop);
18888 it->method = GET_FROM_IMAGE;
18889 }
18890 #endif /* HAVE_WINDOW_SYSTEM */
18891 else
18892 {
18893 pop_it (it); /* bogus display property, give up */
18894 return 0;
18895 }
18896
18897 return 1;
18898 }
18899
18900 /* Return the character-property PROP at the current position in IT. */
18901
18902 static Lisp_Object
18903 get_it_property (struct it *it, Lisp_Object prop)
18904 {
18905 Lisp_Object position;
18906
18907 if (STRINGP (it->object))
18908 position = make_number (IT_STRING_CHARPOS (*it));
18909 else if (BUFFERP (it->object))
18910 position = make_number (IT_CHARPOS (*it));
18911 else
18912 return Qnil;
18913
18914 return Fget_char_property (position, prop, it->object);
18915 }
18916
18917 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18918
18919 static void
18920 handle_line_prefix (struct it *it)
18921 {
18922 Lisp_Object prefix;
18923
18924 if (it->continuation_lines_width > 0)
18925 {
18926 prefix = get_it_property (it, Qwrap_prefix);
18927 if (NILP (prefix))
18928 prefix = Vwrap_prefix;
18929 }
18930 else
18931 {
18932 prefix = get_it_property (it, Qline_prefix);
18933 if (NILP (prefix))
18934 prefix = Vline_prefix;
18935 }
18936 if (! NILP (prefix) && push_prefix_prop (it, prefix))
18937 {
18938 /* If the prefix is wider than the window, and we try to wrap
18939 it, it would acquire its own wrap prefix, and so on till the
18940 iterator stack overflows. So, don't wrap the prefix. */
18941 it->line_wrap = TRUNCATE;
18942 it->avoid_cursor_p = 1;
18943 }
18944 }
18945
18946 \f
18947
18948 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
18949 only for R2L lines from display_line and display_string, when they
18950 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
18951 the line/string needs to be continued on the next glyph row. */
18952 static void
18953 unproduce_glyphs (struct it *it, int n)
18954 {
18955 struct glyph *glyph, *end;
18956
18957 eassert (it->glyph_row);
18958 eassert (it->glyph_row->reversed_p);
18959 eassert (it->area == TEXT_AREA);
18960 eassert (n <= it->glyph_row->used[TEXT_AREA]);
18961
18962 if (n > it->glyph_row->used[TEXT_AREA])
18963 n = it->glyph_row->used[TEXT_AREA];
18964 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
18965 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
18966 for ( ; glyph < end; glyph++)
18967 glyph[-n] = *glyph;
18968 }
18969
18970 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
18971 and ROW->maxpos. */
18972 static void
18973 find_row_edges (struct it *it, struct glyph_row *row,
18974 ptrdiff_t min_pos, ptrdiff_t min_bpos,
18975 ptrdiff_t max_pos, ptrdiff_t max_bpos)
18976 {
18977 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18978 lines' rows is implemented for bidi-reordered rows. */
18979
18980 /* ROW->minpos is the value of min_pos, the minimal buffer position
18981 we have in ROW, or ROW->start.pos if that is smaller. */
18982 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
18983 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
18984 else
18985 /* We didn't find buffer positions smaller than ROW->start, or
18986 didn't find _any_ valid buffer positions in any of the glyphs,
18987 so we must trust the iterator's computed positions. */
18988 row->minpos = row->start.pos;
18989 if (max_pos <= 0)
18990 {
18991 max_pos = CHARPOS (it->current.pos);
18992 max_bpos = BYTEPOS (it->current.pos);
18993 }
18994
18995 /* Here are the various use-cases for ending the row, and the
18996 corresponding values for ROW->maxpos:
18997
18998 Line ends in a newline from buffer eol_pos + 1
18999 Line is continued from buffer max_pos + 1
19000 Line is truncated on right it->current.pos
19001 Line ends in a newline from string max_pos + 1(*)
19002 (*) + 1 only when line ends in a forward scan
19003 Line is continued from string max_pos
19004 Line is continued from display vector max_pos
19005 Line is entirely from a string min_pos == max_pos
19006 Line is entirely from a display vector min_pos == max_pos
19007 Line that ends at ZV ZV
19008
19009 If you discover other use-cases, please add them here as
19010 appropriate. */
19011 if (row->ends_at_zv_p)
19012 row->maxpos = it->current.pos;
19013 else if (row->used[TEXT_AREA])
19014 {
19015 int seen_this_string = 0;
19016 struct glyph_row *r1 = row - 1;
19017
19018 /* Did we see the same display string on the previous row? */
19019 if (STRINGP (it->object)
19020 /* this is not the first row */
19021 && row > it->w->desired_matrix->rows
19022 /* previous row is not the header line */
19023 && !r1->mode_line_p
19024 /* previous row also ends in a newline from a string */
19025 && r1->ends_in_newline_from_string_p)
19026 {
19027 struct glyph *start, *end;
19028
19029 /* Search for the last glyph of the previous row that came
19030 from buffer or string. Depending on whether the row is
19031 L2R or R2L, we need to process it front to back or the
19032 other way round. */
19033 if (!r1->reversed_p)
19034 {
19035 start = r1->glyphs[TEXT_AREA];
19036 end = start + r1->used[TEXT_AREA];
19037 /* Glyphs inserted by redisplay have an integer (zero)
19038 as their object. */
19039 while (end > start
19040 && INTEGERP ((end - 1)->object)
19041 && (end - 1)->charpos <= 0)
19042 --end;
19043 if (end > start)
19044 {
19045 if (EQ ((end - 1)->object, it->object))
19046 seen_this_string = 1;
19047 }
19048 else
19049 /* If all the glyphs of the previous row were inserted
19050 by redisplay, it means the previous row was
19051 produced from a single newline, which is only
19052 possible if that newline came from the same string
19053 as the one which produced this ROW. */
19054 seen_this_string = 1;
19055 }
19056 else
19057 {
19058 end = r1->glyphs[TEXT_AREA] - 1;
19059 start = end + r1->used[TEXT_AREA];
19060 while (end < start
19061 && INTEGERP ((end + 1)->object)
19062 && (end + 1)->charpos <= 0)
19063 ++end;
19064 if (end < start)
19065 {
19066 if (EQ ((end + 1)->object, it->object))
19067 seen_this_string = 1;
19068 }
19069 else
19070 seen_this_string = 1;
19071 }
19072 }
19073 /* Take note of each display string that covers a newline only
19074 once, the first time we see it. This is for when a display
19075 string includes more than one newline in it. */
19076 if (row->ends_in_newline_from_string_p && !seen_this_string)
19077 {
19078 /* If we were scanning the buffer forward when we displayed
19079 the string, we want to account for at least one buffer
19080 position that belongs to this row (position covered by
19081 the display string), so that cursor positioning will
19082 consider this row as a candidate when point is at the end
19083 of the visual line represented by this row. This is not
19084 required when scanning back, because max_pos will already
19085 have a much larger value. */
19086 if (CHARPOS (row->end.pos) > max_pos)
19087 INC_BOTH (max_pos, max_bpos);
19088 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19089 }
19090 else if (CHARPOS (it->eol_pos) > 0)
19091 SET_TEXT_POS (row->maxpos,
19092 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19093 else if (row->continued_p)
19094 {
19095 /* If max_pos is different from IT's current position, it
19096 means IT->method does not belong to the display element
19097 at max_pos. However, it also means that the display
19098 element at max_pos was displayed in its entirety on this
19099 line, which is equivalent to saying that the next line
19100 starts at the next buffer position. */
19101 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19102 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19103 else
19104 {
19105 INC_BOTH (max_pos, max_bpos);
19106 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19107 }
19108 }
19109 else if (row->truncated_on_right_p)
19110 /* display_line already called reseat_at_next_visible_line_start,
19111 which puts the iterator at the beginning of the next line, in
19112 the logical order. */
19113 row->maxpos = it->current.pos;
19114 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19115 /* A line that is entirely from a string/image/stretch... */
19116 row->maxpos = row->minpos;
19117 else
19118 emacs_abort ();
19119 }
19120 else
19121 row->maxpos = it->current.pos;
19122 }
19123
19124 /* Construct the glyph row IT->glyph_row in the desired matrix of
19125 IT->w from text at the current position of IT. See dispextern.h
19126 for an overview of struct it. Value is non-zero if
19127 IT->glyph_row displays text, as opposed to a line displaying ZV
19128 only. */
19129
19130 static int
19131 display_line (struct it *it)
19132 {
19133 struct glyph_row *row = it->glyph_row;
19134 Lisp_Object overlay_arrow_string;
19135 struct it wrap_it;
19136 void *wrap_data = NULL;
19137 int may_wrap = 0, wrap_x IF_LINT (= 0);
19138 int wrap_row_used = -1;
19139 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19140 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19141 int wrap_row_extra_line_spacing IF_LINT (= 0);
19142 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19143 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19144 int cvpos;
19145 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19146 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19147
19148 /* We always start displaying at hpos zero even if hscrolled. */
19149 eassert (it->hpos == 0 && it->current_x == 0);
19150
19151 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19152 >= it->w->desired_matrix->nrows)
19153 {
19154 it->w->nrows_scale_factor++;
19155 fonts_changed_p = 1;
19156 return 0;
19157 }
19158
19159 /* Is IT->w showing the region? */
19160 wset_region_showing (it->w, it->region_beg_charpos > 0 ? Qt : Qnil);
19161
19162 /* Clear the result glyph row and enable it. */
19163 prepare_desired_row (row);
19164
19165 row->y = it->current_y;
19166 row->start = it->start;
19167 row->continuation_lines_width = it->continuation_lines_width;
19168 row->displays_text_p = 1;
19169 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19170 it->starts_in_middle_of_char_p = 0;
19171
19172 /* Arrange the overlays nicely for our purposes. Usually, we call
19173 display_line on only one line at a time, in which case this
19174 can't really hurt too much, or we call it on lines which appear
19175 one after another in the buffer, in which case all calls to
19176 recenter_overlay_lists but the first will be pretty cheap. */
19177 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19178
19179 /* Move over display elements that are not visible because we are
19180 hscrolled. This may stop at an x-position < IT->first_visible_x
19181 if the first glyph is partially visible or if we hit a line end. */
19182 if (it->current_x < it->first_visible_x)
19183 {
19184 enum move_it_result move_result;
19185
19186 this_line_min_pos = row->start.pos;
19187 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19188 MOVE_TO_POS | MOVE_TO_X);
19189 /* If we are under a large hscroll, move_it_in_display_line_to
19190 could hit the end of the line without reaching
19191 it->first_visible_x. Pretend that we did reach it. This is
19192 especially important on a TTY, where we will call
19193 extend_face_to_end_of_line, which needs to know how many
19194 blank glyphs to produce. */
19195 if (it->current_x < it->first_visible_x
19196 && (move_result == MOVE_NEWLINE_OR_CR
19197 || move_result == MOVE_POS_MATCH_OR_ZV))
19198 it->current_x = it->first_visible_x;
19199
19200 /* Record the smallest positions seen while we moved over
19201 display elements that are not visible. This is needed by
19202 redisplay_internal for optimizing the case where the cursor
19203 stays inside the same line. The rest of this function only
19204 considers positions that are actually displayed, so
19205 RECORD_MAX_MIN_POS will not otherwise record positions that
19206 are hscrolled to the left of the left edge of the window. */
19207 min_pos = CHARPOS (this_line_min_pos);
19208 min_bpos = BYTEPOS (this_line_min_pos);
19209 }
19210 else
19211 {
19212 /* We only do this when not calling `move_it_in_display_line_to'
19213 above, because move_it_in_display_line_to calls
19214 handle_line_prefix itself. */
19215 handle_line_prefix (it);
19216 }
19217
19218 /* Get the initial row height. This is either the height of the
19219 text hscrolled, if there is any, or zero. */
19220 row->ascent = it->max_ascent;
19221 row->height = it->max_ascent + it->max_descent;
19222 row->phys_ascent = it->max_phys_ascent;
19223 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19224 row->extra_line_spacing = it->max_extra_line_spacing;
19225
19226 /* Utility macro to record max and min buffer positions seen until now. */
19227 #define RECORD_MAX_MIN_POS(IT) \
19228 do \
19229 { \
19230 int composition_p = !STRINGP ((IT)->string) \
19231 && ((IT)->what == IT_COMPOSITION); \
19232 ptrdiff_t current_pos = \
19233 composition_p ? (IT)->cmp_it.charpos \
19234 : IT_CHARPOS (*(IT)); \
19235 ptrdiff_t current_bpos = \
19236 composition_p ? CHAR_TO_BYTE (current_pos) \
19237 : IT_BYTEPOS (*(IT)); \
19238 if (current_pos < min_pos) \
19239 { \
19240 min_pos = current_pos; \
19241 min_bpos = current_bpos; \
19242 } \
19243 if (IT_CHARPOS (*it) > max_pos) \
19244 { \
19245 max_pos = IT_CHARPOS (*it); \
19246 max_bpos = IT_BYTEPOS (*it); \
19247 } \
19248 } \
19249 while (0)
19250
19251 /* Loop generating characters. The loop is left with IT on the next
19252 character to display. */
19253 while (1)
19254 {
19255 int n_glyphs_before, hpos_before, x_before;
19256 int x, nglyphs;
19257 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19258
19259 /* Retrieve the next thing to display. Value is zero if end of
19260 buffer reached. */
19261 if (!get_next_display_element (it))
19262 {
19263 /* Maybe add a space at the end of this line that is used to
19264 display the cursor there under X. Set the charpos of the
19265 first glyph of blank lines not corresponding to any text
19266 to -1. */
19267 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19268 row->exact_window_width_line_p = 1;
19269 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19270 || row->used[TEXT_AREA] == 0)
19271 {
19272 row->glyphs[TEXT_AREA]->charpos = -1;
19273 row->displays_text_p = 0;
19274
19275 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
19276 && (!MINI_WINDOW_P (it->w)
19277 || (minibuf_level && EQ (it->window, minibuf_window))))
19278 row->indicate_empty_line_p = 1;
19279 }
19280
19281 it->continuation_lines_width = 0;
19282 row->ends_at_zv_p = 1;
19283 /* A row that displays right-to-left text must always have
19284 its last face extended all the way to the end of line,
19285 even if this row ends in ZV, because we still write to
19286 the screen left to right. We also need to extend the
19287 last face if the default face is remapped to some
19288 different face, otherwise the functions that clear
19289 portions of the screen will clear with the default face's
19290 background color. */
19291 if (row->reversed_p
19292 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19293 extend_face_to_end_of_line (it);
19294 break;
19295 }
19296
19297 /* Now, get the metrics of what we want to display. This also
19298 generates glyphs in `row' (which is IT->glyph_row). */
19299 n_glyphs_before = row->used[TEXT_AREA];
19300 x = it->current_x;
19301
19302 /* Remember the line height so far in case the next element doesn't
19303 fit on the line. */
19304 if (it->line_wrap != TRUNCATE)
19305 {
19306 ascent = it->max_ascent;
19307 descent = it->max_descent;
19308 phys_ascent = it->max_phys_ascent;
19309 phys_descent = it->max_phys_descent;
19310
19311 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19312 {
19313 if (IT_DISPLAYING_WHITESPACE (it))
19314 may_wrap = 1;
19315 else if (may_wrap)
19316 {
19317 SAVE_IT (wrap_it, *it, wrap_data);
19318 wrap_x = x;
19319 wrap_row_used = row->used[TEXT_AREA];
19320 wrap_row_ascent = row->ascent;
19321 wrap_row_height = row->height;
19322 wrap_row_phys_ascent = row->phys_ascent;
19323 wrap_row_phys_height = row->phys_height;
19324 wrap_row_extra_line_spacing = row->extra_line_spacing;
19325 wrap_row_min_pos = min_pos;
19326 wrap_row_min_bpos = min_bpos;
19327 wrap_row_max_pos = max_pos;
19328 wrap_row_max_bpos = max_bpos;
19329 may_wrap = 0;
19330 }
19331 }
19332 }
19333
19334 PRODUCE_GLYPHS (it);
19335
19336 /* If this display element was in marginal areas, continue with
19337 the next one. */
19338 if (it->area != TEXT_AREA)
19339 {
19340 row->ascent = max (row->ascent, it->max_ascent);
19341 row->height = max (row->height, it->max_ascent + it->max_descent);
19342 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19343 row->phys_height = max (row->phys_height,
19344 it->max_phys_ascent + it->max_phys_descent);
19345 row->extra_line_spacing = max (row->extra_line_spacing,
19346 it->max_extra_line_spacing);
19347 set_iterator_to_next (it, 1);
19348 continue;
19349 }
19350
19351 /* Does the display element fit on the line? If we truncate
19352 lines, we should draw past the right edge of the window. If
19353 we don't truncate, we want to stop so that we can display the
19354 continuation glyph before the right margin. If lines are
19355 continued, there are two possible strategies for characters
19356 resulting in more than 1 glyph (e.g. tabs): Display as many
19357 glyphs as possible in this line and leave the rest for the
19358 continuation line, or display the whole element in the next
19359 line. Original redisplay did the former, so we do it also. */
19360 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19361 hpos_before = it->hpos;
19362 x_before = x;
19363
19364 if (/* Not a newline. */
19365 nglyphs > 0
19366 /* Glyphs produced fit entirely in the line. */
19367 && it->current_x < it->last_visible_x)
19368 {
19369 it->hpos += nglyphs;
19370 row->ascent = max (row->ascent, it->max_ascent);
19371 row->height = max (row->height, it->max_ascent + it->max_descent);
19372 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19373 row->phys_height = max (row->phys_height,
19374 it->max_phys_ascent + it->max_phys_descent);
19375 row->extra_line_spacing = max (row->extra_line_spacing,
19376 it->max_extra_line_spacing);
19377 if (it->current_x - it->pixel_width < it->first_visible_x)
19378 row->x = x - it->first_visible_x;
19379 /* Record the maximum and minimum buffer positions seen so
19380 far in glyphs that will be displayed by this row. */
19381 if (it->bidi_p)
19382 RECORD_MAX_MIN_POS (it);
19383 }
19384 else
19385 {
19386 int i, new_x;
19387 struct glyph *glyph;
19388
19389 for (i = 0; i < nglyphs; ++i, x = new_x)
19390 {
19391 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19392 new_x = x + glyph->pixel_width;
19393
19394 if (/* Lines are continued. */
19395 it->line_wrap != TRUNCATE
19396 && (/* Glyph doesn't fit on the line. */
19397 new_x > it->last_visible_x
19398 /* Or it fits exactly on a window system frame. */
19399 || (new_x == it->last_visible_x
19400 && FRAME_WINDOW_P (it->f)
19401 && (row->reversed_p
19402 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19403 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19404 {
19405 /* End of a continued line. */
19406
19407 if (it->hpos == 0
19408 || (new_x == it->last_visible_x
19409 && FRAME_WINDOW_P (it->f)
19410 && (row->reversed_p
19411 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19412 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19413 {
19414 /* Current glyph is the only one on the line or
19415 fits exactly on the line. We must continue
19416 the line because we can't draw the cursor
19417 after the glyph. */
19418 row->continued_p = 1;
19419 it->current_x = new_x;
19420 it->continuation_lines_width += new_x;
19421 ++it->hpos;
19422 if (i == nglyphs - 1)
19423 {
19424 /* If line-wrap is on, check if a previous
19425 wrap point was found. */
19426 if (wrap_row_used > 0
19427 /* Even if there is a previous wrap
19428 point, continue the line here as
19429 usual, if (i) the previous character
19430 was a space or tab AND (ii) the
19431 current character is not. */
19432 && (!may_wrap
19433 || IT_DISPLAYING_WHITESPACE (it)))
19434 goto back_to_wrap;
19435
19436 /* Record the maximum and minimum buffer
19437 positions seen so far in glyphs that will be
19438 displayed by this row. */
19439 if (it->bidi_p)
19440 RECORD_MAX_MIN_POS (it);
19441 set_iterator_to_next (it, 1);
19442 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19443 {
19444 if (!get_next_display_element (it))
19445 {
19446 row->exact_window_width_line_p = 1;
19447 it->continuation_lines_width = 0;
19448 row->continued_p = 0;
19449 row->ends_at_zv_p = 1;
19450 }
19451 else if (ITERATOR_AT_END_OF_LINE_P (it))
19452 {
19453 row->continued_p = 0;
19454 row->exact_window_width_line_p = 1;
19455 }
19456 }
19457 }
19458 else if (it->bidi_p)
19459 RECORD_MAX_MIN_POS (it);
19460 }
19461 else if (CHAR_GLYPH_PADDING_P (*glyph)
19462 && !FRAME_WINDOW_P (it->f))
19463 {
19464 /* A padding glyph that doesn't fit on this line.
19465 This means the whole character doesn't fit
19466 on the line. */
19467 if (row->reversed_p)
19468 unproduce_glyphs (it, row->used[TEXT_AREA]
19469 - n_glyphs_before);
19470 row->used[TEXT_AREA] = n_glyphs_before;
19471
19472 /* Fill the rest of the row with continuation
19473 glyphs like in 20.x. */
19474 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19475 < row->glyphs[1 + TEXT_AREA])
19476 produce_special_glyphs (it, IT_CONTINUATION);
19477
19478 row->continued_p = 1;
19479 it->current_x = x_before;
19480 it->continuation_lines_width += x_before;
19481
19482 /* Restore the height to what it was before the
19483 element not fitting on the line. */
19484 it->max_ascent = ascent;
19485 it->max_descent = descent;
19486 it->max_phys_ascent = phys_ascent;
19487 it->max_phys_descent = phys_descent;
19488 }
19489 else if (wrap_row_used > 0)
19490 {
19491 back_to_wrap:
19492 if (row->reversed_p)
19493 unproduce_glyphs (it,
19494 row->used[TEXT_AREA] - wrap_row_used);
19495 RESTORE_IT (it, &wrap_it, wrap_data);
19496 it->continuation_lines_width += wrap_x;
19497 row->used[TEXT_AREA] = wrap_row_used;
19498 row->ascent = wrap_row_ascent;
19499 row->height = wrap_row_height;
19500 row->phys_ascent = wrap_row_phys_ascent;
19501 row->phys_height = wrap_row_phys_height;
19502 row->extra_line_spacing = wrap_row_extra_line_spacing;
19503 min_pos = wrap_row_min_pos;
19504 min_bpos = wrap_row_min_bpos;
19505 max_pos = wrap_row_max_pos;
19506 max_bpos = wrap_row_max_bpos;
19507 row->continued_p = 1;
19508 row->ends_at_zv_p = 0;
19509 row->exact_window_width_line_p = 0;
19510 it->continuation_lines_width += x;
19511
19512 /* Make sure that a non-default face is extended
19513 up to the right margin of the window. */
19514 extend_face_to_end_of_line (it);
19515 }
19516 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19517 {
19518 /* A TAB that extends past the right edge of the
19519 window. This produces a single glyph on
19520 window system frames. We leave the glyph in
19521 this row and let it fill the row, but don't
19522 consume the TAB. */
19523 if ((row->reversed_p
19524 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19525 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19526 produce_special_glyphs (it, IT_CONTINUATION);
19527 it->continuation_lines_width += it->last_visible_x;
19528 row->ends_in_middle_of_char_p = 1;
19529 row->continued_p = 1;
19530 glyph->pixel_width = it->last_visible_x - x;
19531 it->starts_in_middle_of_char_p = 1;
19532 }
19533 else
19534 {
19535 /* Something other than a TAB that draws past
19536 the right edge of the window. Restore
19537 positions to values before the element. */
19538 if (row->reversed_p)
19539 unproduce_glyphs (it, row->used[TEXT_AREA]
19540 - (n_glyphs_before + i));
19541 row->used[TEXT_AREA] = n_glyphs_before + i;
19542
19543 /* Display continuation glyphs. */
19544 it->current_x = x_before;
19545 it->continuation_lines_width += x;
19546 if (!FRAME_WINDOW_P (it->f)
19547 || (row->reversed_p
19548 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19549 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19550 produce_special_glyphs (it, IT_CONTINUATION);
19551 row->continued_p = 1;
19552
19553 extend_face_to_end_of_line (it);
19554
19555 if (nglyphs > 1 && i > 0)
19556 {
19557 row->ends_in_middle_of_char_p = 1;
19558 it->starts_in_middle_of_char_p = 1;
19559 }
19560
19561 /* Restore the height to what it was before the
19562 element not fitting on the line. */
19563 it->max_ascent = ascent;
19564 it->max_descent = descent;
19565 it->max_phys_ascent = phys_ascent;
19566 it->max_phys_descent = phys_descent;
19567 }
19568
19569 break;
19570 }
19571 else if (new_x > it->first_visible_x)
19572 {
19573 /* Increment number of glyphs actually displayed. */
19574 ++it->hpos;
19575
19576 /* Record the maximum and minimum buffer positions
19577 seen so far in glyphs that will be displayed by
19578 this row. */
19579 if (it->bidi_p)
19580 RECORD_MAX_MIN_POS (it);
19581
19582 if (x < it->first_visible_x)
19583 /* Glyph is partially visible, i.e. row starts at
19584 negative X position. */
19585 row->x = x - it->first_visible_x;
19586 }
19587 else
19588 {
19589 /* Glyph is completely off the left margin of the
19590 window. This should not happen because of the
19591 move_it_in_display_line at the start of this
19592 function, unless the text display area of the
19593 window is empty. */
19594 eassert (it->first_visible_x <= it->last_visible_x);
19595 }
19596 }
19597 /* Even if this display element produced no glyphs at all,
19598 we want to record its position. */
19599 if (it->bidi_p && nglyphs == 0)
19600 RECORD_MAX_MIN_POS (it);
19601
19602 row->ascent = max (row->ascent, it->max_ascent);
19603 row->height = max (row->height, it->max_ascent + it->max_descent);
19604 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19605 row->phys_height = max (row->phys_height,
19606 it->max_phys_ascent + it->max_phys_descent);
19607 row->extra_line_spacing = max (row->extra_line_spacing,
19608 it->max_extra_line_spacing);
19609
19610 /* End of this display line if row is continued. */
19611 if (row->continued_p || row->ends_at_zv_p)
19612 break;
19613 }
19614
19615 at_end_of_line:
19616 /* Is this a line end? If yes, we're also done, after making
19617 sure that a non-default face is extended up to the right
19618 margin of the window. */
19619 if (ITERATOR_AT_END_OF_LINE_P (it))
19620 {
19621 int used_before = row->used[TEXT_AREA];
19622
19623 row->ends_in_newline_from_string_p = STRINGP (it->object);
19624
19625 /* Add a space at the end of the line that is used to
19626 display the cursor there. */
19627 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19628 append_space_for_newline (it, 0);
19629
19630 /* Extend the face to the end of the line. */
19631 extend_face_to_end_of_line (it);
19632
19633 /* Make sure we have the position. */
19634 if (used_before == 0)
19635 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19636
19637 /* Record the position of the newline, for use in
19638 find_row_edges. */
19639 it->eol_pos = it->current.pos;
19640
19641 /* Consume the line end. This skips over invisible lines. */
19642 set_iterator_to_next (it, 1);
19643 it->continuation_lines_width = 0;
19644 break;
19645 }
19646
19647 /* Proceed with next display element. Note that this skips
19648 over lines invisible because of selective display. */
19649 set_iterator_to_next (it, 1);
19650
19651 /* If we truncate lines, we are done when the last displayed
19652 glyphs reach past the right margin of the window. */
19653 if (it->line_wrap == TRUNCATE
19654 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19655 ? (it->current_x >= it->last_visible_x)
19656 : (it->current_x > it->last_visible_x)))
19657 {
19658 /* Maybe add truncation glyphs. */
19659 if (!FRAME_WINDOW_P (it->f)
19660 || (row->reversed_p
19661 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19662 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19663 {
19664 int i, n;
19665
19666 if (!row->reversed_p)
19667 {
19668 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19669 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19670 break;
19671 }
19672 else
19673 {
19674 for (i = 0; i < row->used[TEXT_AREA]; i++)
19675 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19676 break;
19677 /* Remove any padding glyphs at the front of ROW, to
19678 make room for the truncation glyphs we will be
19679 adding below. The loop below always inserts at
19680 least one truncation glyph, so also remove the
19681 last glyph added to ROW. */
19682 unproduce_glyphs (it, i + 1);
19683 /* Adjust i for the loop below. */
19684 i = row->used[TEXT_AREA] - (i + 1);
19685 }
19686
19687 it->current_x = x_before;
19688 if (!FRAME_WINDOW_P (it->f))
19689 {
19690 for (n = row->used[TEXT_AREA]; i < n; ++i)
19691 {
19692 row->used[TEXT_AREA] = i;
19693 produce_special_glyphs (it, IT_TRUNCATION);
19694 }
19695 }
19696 else
19697 {
19698 row->used[TEXT_AREA] = i;
19699 produce_special_glyphs (it, IT_TRUNCATION);
19700 }
19701 }
19702 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19703 {
19704 /* Don't truncate if we can overflow newline into fringe. */
19705 if (!get_next_display_element (it))
19706 {
19707 it->continuation_lines_width = 0;
19708 row->ends_at_zv_p = 1;
19709 row->exact_window_width_line_p = 1;
19710 break;
19711 }
19712 if (ITERATOR_AT_END_OF_LINE_P (it))
19713 {
19714 row->exact_window_width_line_p = 1;
19715 goto at_end_of_line;
19716 }
19717 it->current_x = x_before;
19718 }
19719
19720 row->truncated_on_right_p = 1;
19721 it->continuation_lines_width = 0;
19722 reseat_at_next_visible_line_start (it, 0);
19723 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19724 it->hpos = hpos_before;
19725 break;
19726 }
19727 }
19728
19729 if (wrap_data)
19730 bidi_unshelve_cache (wrap_data, 1);
19731
19732 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19733 at the left window margin. */
19734 if (it->first_visible_x
19735 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19736 {
19737 if (!FRAME_WINDOW_P (it->f)
19738 || (row->reversed_p
19739 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19740 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19741 insert_left_trunc_glyphs (it);
19742 row->truncated_on_left_p = 1;
19743 }
19744
19745 /* Remember the position at which this line ends.
19746
19747 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19748 cannot be before the call to find_row_edges below, since that is
19749 where these positions are determined. */
19750 row->end = it->current;
19751 if (!it->bidi_p)
19752 {
19753 row->minpos = row->start.pos;
19754 row->maxpos = row->end.pos;
19755 }
19756 else
19757 {
19758 /* ROW->minpos and ROW->maxpos must be the smallest and
19759 `1 + the largest' buffer positions in ROW. But if ROW was
19760 bidi-reordered, these two positions can be anywhere in the
19761 row, so we must determine them now. */
19762 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19763 }
19764
19765 /* If the start of this line is the overlay arrow-position, then
19766 mark this glyph row as the one containing the overlay arrow.
19767 This is clearly a mess with variable size fonts. It would be
19768 better to let it be displayed like cursors under X. */
19769 if ((row->displays_text_p || !overlay_arrow_seen)
19770 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19771 !NILP (overlay_arrow_string)))
19772 {
19773 /* Overlay arrow in window redisplay is a fringe bitmap. */
19774 if (STRINGP (overlay_arrow_string))
19775 {
19776 struct glyph_row *arrow_row
19777 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19778 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19779 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19780 struct glyph *p = row->glyphs[TEXT_AREA];
19781 struct glyph *p2, *end;
19782
19783 /* Copy the arrow glyphs. */
19784 while (glyph < arrow_end)
19785 *p++ = *glyph++;
19786
19787 /* Throw away padding glyphs. */
19788 p2 = p;
19789 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19790 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19791 ++p2;
19792 if (p2 > p)
19793 {
19794 while (p2 < end)
19795 *p++ = *p2++;
19796 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19797 }
19798 }
19799 else
19800 {
19801 eassert (INTEGERP (overlay_arrow_string));
19802 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19803 }
19804 overlay_arrow_seen = 1;
19805 }
19806
19807 /* Highlight trailing whitespace. */
19808 if (!NILP (Vshow_trailing_whitespace))
19809 highlight_trailing_whitespace (it->f, it->glyph_row);
19810
19811 /* Compute pixel dimensions of this line. */
19812 compute_line_metrics (it);
19813
19814 /* Implementation note: No changes in the glyphs of ROW or in their
19815 faces can be done past this point, because compute_line_metrics
19816 computes ROW's hash value and stores it within the glyph_row
19817 structure. */
19818
19819 /* Record whether this row ends inside an ellipsis. */
19820 row->ends_in_ellipsis_p
19821 = (it->method == GET_FROM_DISPLAY_VECTOR
19822 && it->ellipsis_p);
19823
19824 /* Save fringe bitmaps in this row. */
19825 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19826 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19827 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19828 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19829
19830 it->left_user_fringe_bitmap = 0;
19831 it->left_user_fringe_face_id = 0;
19832 it->right_user_fringe_bitmap = 0;
19833 it->right_user_fringe_face_id = 0;
19834
19835 /* Maybe set the cursor. */
19836 cvpos = it->w->cursor.vpos;
19837 if ((cvpos < 0
19838 /* In bidi-reordered rows, keep checking for proper cursor
19839 position even if one has been found already, because buffer
19840 positions in such rows change non-linearly with ROW->VPOS,
19841 when a line is continued. One exception: when we are at ZV,
19842 display cursor on the first suitable glyph row, since all
19843 the empty rows after that also have their position set to ZV. */
19844 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19845 lines' rows is implemented for bidi-reordered rows. */
19846 || (it->bidi_p
19847 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19848 && PT >= MATRIX_ROW_START_CHARPOS (row)
19849 && PT <= MATRIX_ROW_END_CHARPOS (row)
19850 && cursor_row_p (row))
19851 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19852
19853 /* Prepare for the next line. This line starts horizontally at (X
19854 HPOS) = (0 0). Vertical positions are incremented. As a
19855 convenience for the caller, IT->glyph_row is set to the next
19856 row to be used. */
19857 it->current_x = it->hpos = 0;
19858 it->current_y += row->height;
19859 SET_TEXT_POS (it->eol_pos, 0, 0);
19860 ++it->vpos;
19861 ++it->glyph_row;
19862 /* The next row should by default use the same value of the
19863 reversed_p flag as this one. set_iterator_to_next decides when
19864 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19865 the flag accordingly. */
19866 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19867 it->glyph_row->reversed_p = row->reversed_p;
19868 it->start = row->end;
19869 return row->displays_text_p;
19870
19871 #undef RECORD_MAX_MIN_POS
19872 }
19873
19874 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19875 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19876 doc: /* Return paragraph direction at point in BUFFER.
19877 Value is either `left-to-right' or `right-to-left'.
19878 If BUFFER is omitted or nil, it defaults to the current buffer.
19879
19880 Paragraph direction determines how the text in the paragraph is displayed.
19881 In left-to-right paragraphs, text begins at the left margin of the window
19882 and the reading direction is generally left to right. In right-to-left
19883 paragraphs, text begins at the right margin and is read from right to left.
19884
19885 See also `bidi-paragraph-direction'. */)
19886 (Lisp_Object buffer)
19887 {
19888 struct buffer *buf = current_buffer;
19889 struct buffer *old = buf;
19890
19891 if (! NILP (buffer))
19892 {
19893 CHECK_BUFFER (buffer);
19894 buf = XBUFFER (buffer);
19895 }
19896
19897 if (NILP (BVAR (buf, bidi_display_reordering))
19898 || NILP (BVAR (buf, enable_multibyte_characters))
19899 /* When we are loading loadup.el, the character property tables
19900 needed for bidi iteration are not yet available. */
19901 || !NILP (Vpurify_flag))
19902 return Qleft_to_right;
19903 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19904 return BVAR (buf, bidi_paragraph_direction);
19905 else
19906 {
19907 /* Determine the direction from buffer text. We could try to
19908 use current_matrix if it is up to date, but this seems fast
19909 enough as it is. */
19910 struct bidi_it itb;
19911 ptrdiff_t pos = BUF_PT (buf);
19912 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
19913 int c;
19914 void *itb_data = bidi_shelve_cache ();
19915
19916 set_buffer_temp (buf);
19917 /* bidi_paragraph_init finds the base direction of the paragraph
19918 by searching forward from paragraph start. We need the base
19919 direction of the current or _previous_ paragraph, so we need
19920 to make sure we are within that paragraph. To that end, find
19921 the previous non-empty line. */
19922 if (pos >= ZV && pos > BEGV)
19923 {
19924 pos--;
19925 bytepos = CHAR_TO_BYTE (pos);
19926 }
19927 if (fast_looking_at (build_string ("[\f\t ]*\n"),
19928 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
19929 {
19930 while ((c = FETCH_BYTE (bytepos)) == '\n'
19931 || c == ' ' || c == '\t' || c == '\f')
19932 {
19933 if (bytepos <= BEGV_BYTE)
19934 break;
19935 bytepos--;
19936 pos--;
19937 }
19938 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
19939 bytepos--;
19940 }
19941 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
19942 itb.paragraph_dir = NEUTRAL_DIR;
19943 itb.string.s = NULL;
19944 itb.string.lstring = Qnil;
19945 itb.string.bufpos = 0;
19946 itb.string.unibyte = 0;
19947 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
19948 bidi_unshelve_cache (itb_data, 0);
19949 set_buffer_temp (old);
19950 switch (itb.paragraph_dir)
19951 {
19952 case L2R:
19953 return Qleft_to_right;
19954 break;
19955 case R2L:
19956 return Qright_to_left;
19957 break;
19958 default:
19959 emacs_abort ();
19960 }
19961 }
19962 }
19963
19964
19965 \f
19966 /***********************************************************************
19967 Menu Bar
19968 ***********************************************************************/
19969
19970 /* Redisplay the menu bar in the frame for window W.
19971
19972 The menu bar of X frames that don't have X toolkit support is
19973 displayed in a special window W->frame->menu_bar_window.
19974
19975 The menu bar of terminal frames is treated specially as far as
19976 glyph matrices are concerned. Menu bar lines are not part of
19977 windows, so the update is done directly on the frame matrix rows
19978 for the menu bar. */
19979
19980 static void
19981 display_menu_bar (struct window *w)
19982 {
19983 struct frame *f = XFRAME (WINDOW_FRAME (w));
19984 struct it it;
19985 Lisp_Object items;
19986 int i;
19987
19988 /* Don't do all this for graphical frames. */
19989 #ifdef HAVE_NTGUI
19990 if (FRAME_W32_P (f))
19991 return;
19992 #endif
19993 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
19994 if (FRAME_X_P (f))
19995 return;
19996 #endif
19997
19998 #ifdef HAVE_NS
19999 if (FRAME_NS_P (f))
20000 return;
20001 #endif /* HAVE_NS */
20002
20003 #ifdef USE_X_TOOLKIT
20004 eassert (!FRAME_WINDOW_P (f));
20005 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20006 it.first_visible_x = 0;
20007 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20008 #else /* not USE_X_TOOLKIT */
20009 if (FRAME_WINDOW_P (f))
20010 {
20011 /* Menu bar lines are displayed in the desired matrix of the
20012 dummy window menu_bar_window. */
20013 struct window *menu_w;
20014 eassert (WINDOWP (f->menu_bar_window));
20015 menu_w = XWINDOW (f->menu_bar_window);
20016 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20017 MENU_FACE_ID);
20018 it.first_visible_x = 0;
20019 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20020 }
20021 else
20022 {
20023 /* This is a TTY frame, i.e. character hpos/vpos are used as
20024 pixel x/y. */
20025 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20026 MENU_FACE_ID);
20027 it.first_visible_x = 0;
20028 it.last_visible_x = FRAME_COLS (f);
20029 }
20030 #endif /* not USE_X_TOOLKIT */
20031
20032 /* FIXME: This should be controlled by a user option. See the
20033 comments in redisplay_tool_bar and display_mode_line about
20034 this. */
20035 it.paragraph_embedding = L2R;
20036
20037 /* Clear all rows of the menu bar. */
20038 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20039 {
20040 struct glyph_row *row = it.glyph_row + i;
20041 clear_glyph_row (row);
20042 row->enabled_p = 1;
20043 row->full_width_p = 1;
20044 }
20045
20046 /* Display all items of the menu bar. */
20047 items = FRAME_MENU_BAR_ITEMS (it.f);
20048 for (i = 0; i < ASIZE (items); i += 4)
20049 {
20050 Lisp_Object string;
20051
20052 /* Stop at nil string. */
20053 string = AREF (items, i + 1);
20054 if (NILP (string))
20055 break;
20056
20057 /* Remember where item was displayed. */
20058 ASET (items, i + 3, make_number (it.hpos));
20059
20060 /* Display the item, pad with one space. */
20061 if (it.current_x < it.last_visible_x)
20062 display_string (NULL, string, Qnil, 0, 0, &it,
20063 SCHARS (string) + 1, 0, 0, -1);
20064 }
20065
20066 /* Fill out the line with spaces. */
20067 if (it.current_x < it.last_visible_x)
20068 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20069
20070 /* Compute the total height of the lines. */
20071 compute_line_metrics (&it);
20072 }
20073
20074
20075 \f
20076 /***********************************************************************
20077 Mode Line
20078 ***********************************************************************/
20079
20080 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20081 FORCE is non-zero, redisplay mode lines unconditionally.
20082 Otherwise, redisplay only mode lines that are garbaged. Value is
20083 the number of windows whose mode lines were redisplayed. */
20084
20085 static int
20086 redisplay_mode_lines (Lisp_Object window, int force)
20087 {
20088 int nwindows = 0;
20089
20090 while (!NILP (window))
20091 {
20092 struct window *w = XWINDOW (window);
20093
20094 if (WINDOWP (w->hchild))
20095 nwindows += redisplay_mode_lines (w->hchild, force);
20096 else if (WINDOWP (w->vchild))
20097 nwindows += redisplay_mode_lines (w->vchild, force);
20098 else if (force
20099 || FRAME_GARBAGED_P (XFRAME (w->frame))
20100 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20101 {
20102 struct text_pos lpoint;
20103 struct buffer *old = current_buffer;
20104
20105 /* Set the window's buffer for the mode line display. */
20106 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20107 set_buffer_internal_1 (XBUFFER (w->buffer));
20108
20109 /* Point refers normally to the selected window. For any
20110 other window, set up appropriate value. */
20111 if (!EQ (window, selected_window))
20112 {
20113 struct text_pos pt;
20114
20115 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20116 if (CHARPOS (pt) < BEGV)
20117 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20118 else if (CHARPOS (pt) > (ZV - 1))
20119 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20120 else
20121 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20122 }
20123
20124 /* Display mode lines. */
20125 clear_glyph_matrix (w->desired_matrix);
20126 if (display_mode_lines (w))
20127 {
20128 ++nwindows;
20129 w->must_be_updated_p = 1;
20130 }
20131
20132 /* Restore old settings. */
20133 set_buffer_internal_1 (old);
20134 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20135 }
20136
20137 window = w->next;
20138 }
20139
20140 return nwindows;
20141 }
20142
20143
20144 /* Display the mode and/or header line of window W. Value is the
20145 sum number of mode lines and header lines displayed. */
20146
20147 static int
20148 display_mode_lines (struct window *w)
20149 {
20150 Lisp_Object old_selected_window = selected_window;
20151 Lisp_Object old_selected_frame = selected_frame;
20152 Lisp_Object new_frame = w->frame;
20153 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20154 int n = 0;
20155
20156 selected_frame = new_frame;
20157 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20158 or window's point, then we'd need select_window_1 here as well. */
20159 XSETWINDOW (selected_window, w);
20160 XFRAME (new_frame)->selected_window = selected_window;
20161
20162 /* These will be set while the mode line specs are processed. */
20163 line_number_displayed = 0;
20164 wset_column_number_displayed (w, Qnil);
20165
20166 if (WINDOW_WANTS_MODELINE_P (w))
20167 {
20168 struct window *sel_w = XWINDOW (old_selected_window);
20169
20170 /* Select mode line face based on the real selected window. */
20171 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20172 BVAR (current_buffer, mode_line_format));
20173 ++n;
20174 }
20175
20176 if (WINDOW_WANTS_HEADER_LINE_P (w))
20177 {
20178 display_mode_line (w, HEADER_LINE_FACE_ID,
20179 BVAR (current_buffer, header_line_format));
20180 ++n;
20181 }
20182
20183 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20184 selected_frame = old_selected_frame;
20185 selected_window = old_selected_window;
20186 return n;
20187 }
20188
20189
20190 /* Display mode or header line of window W. FACE_ID specifies which
20191 line to display; it is either MODE_LINE_FACE_ID or
20192 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20193 display. Value is the pixel height of the mode/header line
20194 displayed. */
20195
20196 static int
20197 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20198 {
20199 struct it it;
20200 struct face *face;
20201 ptrdiff_t count = SPECPDL_INDEX ();
20202
20203 init_iterator (&it, w, -1, -1, NULL, face_id);
20204 /* Don't extend on a previously drawn mode-line.
20205 This may happen if called from pos_visible_p. */
20206 it.glyph_row->enabled_p = 0;
20207 prepare_desired_row (it.glyph_row);
20208
20209 it.glyph_row->mode_line_p = 1;
20210
20211 /* FIXME: This should be controlled by a user option. But
20212 supporting such an option is not trivial, since the mode line is
20213 made up of many separate strings. */
20214 it.paragraph_embedding = L2R;
20215
20216 record_unwind_protect (unwind_format_mode_line,
20217 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20218
20219 mode_line_target = MODE_LINE_DISPLAY;
20220
20221 /* Temporarily make frame's keyboard the current kboard so that
20222 kboard-local variables in the mode_line_format will get the right
20223 values. */
20224 push_kboard (FRAME_KBOARD (it.f));
20225 record_unwind_save_match_data ();
20226 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20227 pop_kboard ();
20228
20229 unbind_to (count, Qnil);
20230
20231 /* Fill up with spaces. */
20232 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20233
20234 compute_line_metrics (&it);
20235 it.glyph_row->full_width_p = 1;
20236 it.glyph_row->continued_p = 0;
20237 it.glyph_row->truncated_on_left_p = 0;
20238 it.glyph_row->truncated_on_right_p = 0;
20239
20240 /* Make a 3D mode-line have a shadow at its right end. */
20241 face = FACE_FROM_ID (it.f, face_id);
20242 extend_face_to_end_of_line (&it);
20243 if (face->box != FACE_NO_BOX)
20244 {
20245 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20246 + it.glyph_row->used[TEXT_AREA] - 1);
20247 last->right_box_line_p = 1;
20248 }
20249
20250 return it.glyph_row->height;
20251 }
20252
20253 /* Move element ELT in LIST to the front of LIST.
20254 Return the updated list. */
20255
20256 static Lisp_Object
20257 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20258 {
20259 register Lisp_Object tail, prev;
20260 register Lisp_Object tem;
20261
20262 tail = list;
20263 prev = Qnil;
20264 while (CONSP (tail))
20265 {
20266 tem = XCAR (tail);
20267
20268 if (EQ (elt, tem))
20269 {
20270 /* Splice out the link TAIL. */
20271 if (NILP (prev))
20272 list = XCDR (tail);
20273 else
20274 Fsetcdr (prev, XCDR (tail));
20275
20276 /* Now make it the first. */
20277 Fsetcdr (tail, list);
20278 return tail;
20279 }
20280 else
20281 prev = tail;
20282 tail = XCDR (tail);
20283 QUIT;
20284 }
20285
20286 /* Not found--return unchanged LIST. */
20287 return list;
20288 }
20289
20290 /* Contribute ELT to the mode line for window IT->w. How it
20291 translates into text depends on its data type.
20292
20293 IT describes the display environment in which we display, as usual.
20294
20295 DEPTH is the depth in recursion. It is used to prevent
20296 infinite recursion here.
20297
20298 FIELD_WIDTH is the number of characters the display of ELT should
20299 occupy in the mode line, and PRECISION is the maximum number of
20300 characters to display from ELT's representation. See
20301 display_string for details.
20302
20303 Returns the hpos of the end of the text generated by ELT.
20304
20305 PROPS is a property list to add to any string we encounter.
20306
20307 If RISKY is nonzero, remove (disregard) any properties in any string
20308 we encounter, and ignore :eval and :propertize.
20309
20310 The global variable `mode_line_target' determines whether the
20311 output is passed to `store_mode_line_noprop',
20312 `store_mode_line_string', or `display_string'. */
20313
20314 static int
20315 display_mode_element (struct it *it, int depth, int field_width, int precision,
20316 Lisp_Object elt, Lisp_Object props, int risky)
20317 {
20318 int n = 0, field, prec;
20319 int literal = 0;
20320
20321 tail_recurse:
20322 if (depth > 100)
20323 elt = build_string ("*too-deep*");
20324
20325 depth++;
20326
20327 switch (XTYPE (elt))
20328 {
20329 case Lisp_String:
20330 {
20331 /* A string: output it and check for %-constructs within it. */
20332 unsigned char c;
20333 ptrdiff_t offset = 0;
20334
20335 if (SCHARS (elt) > 0
20336 && (!NILP (props) || risky))
20337 {
20338 Lisp_Object oprops, aelt;
20339 oprops = Ftext_properties_at (make_number (0), elt);
20340
20341 /* If the starting string's properties are not what
20342 we want, translate the string. Also, if the string
20343 is risky, do that anyway. */
20344
20345 if (NILP (Fequal (props, oprops)) || risky)
20346 {
20347 /* If the starting string has properties,
20348 merge the specified ones onto the existing ones. */
20349 if (! NILP (oprops) && !risky)
20350 {
20351 Lisp_Object tem;
20352
20353 oprops = Fcopy_sequence (oprops);
20354 tem = props;
20355 while (CONSP (tem))
20356 {
20357 oprops = Fplist_put (oprops, XCAR (tem),
20358 XCAR (XCDR (tem)));
20359 tem = XCDR (XCDR (tem));
20360 }
20361 props = oprops;
20362 }
20363
20364 aelt = Fassoc (elt, mode_line_proptrans_alist);
20365 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20366 {
20367 /* AELT is what we want. Move it to the front
20368 without consing. */
20369 elt = XCAR (aelt);
20370 mode_line_proptrans_alist
20371 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20372 }
20373 else
20374 {
20375 Lisp_Object tem;
20376
20377 /* If AELT has the wrong props, it is useless.
20378 so get rid of it. */
20379 if (! NILP (aelt))
20380 mode_line_proptrans_alist
20381 = Fdelq (aelt, mode_line_proptrans_alist);
20382
20383 elt = Fcopy_sequence (elt);
20384 Fset_text_properties (make_number (0), Flength (elt),
20385 props, elt);
20386 /* Add this item to mode_line_proptrans_alist. */
20387 mode_line_proptrans_alist
20388 = Fcons (Fcons (elt, props),
20389 mode_line_proptrans_alist);
20390 /* Truncate mode_line_proptrans_alist
20391 to at most 50 elements. */
20392 tem = Fnthcdr (make_number (50),
20393 mode_line_proptrans_alist);
20394 if (! NILP (tem))
20395 XSETCDR (tem, Qnil);
20396 }
20397 }
20398 }
20399
20400 offset = 0;
20401
20402 if (literal)
20403 {
20404 prec = precision - n;
20405 switch (mode_line_target)
20406 {
20407 case MODE_LINE_NOPROP:
20408 case MODE_LINE_TITLE:
20409 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20410 break;
20411 case MODE_LINE_STRING:
20412 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20413 break;
20414 case MODE_LINE_DISPLAY:
20415 n += display_string (NULL, elt, Qnil, 0, 0, it,
20416 0, prec, 0, STRING_MULTIBYTE (elt));
20417 break;
20418 }
20419
20420 break;
20421 }
20422
20423 /* Handle the non-literal case. */
20424
20425 while ((precision <= 0 || n < precision)
20426 && SREF (elt, offset) != 0
20427 && (mode_line_target != MODE_LINE_DISPLAY
20428 || it->current_x < it->last_visible_x))
20429 {
20430 ptrdiff_t last_offset = offset;
20431
20432 /* Advance to end of string or next format specifier. */
20433 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20434 ;
20435
20436 if (offset - 1 != last_offset)
20437 {
20438 ptrdiff_t nchars, nbytes;
20439
20440 /* Output to end of string or up to '%'. Field width
20441 is length of string. Don't output more than
20442 PRECISION allows us. */
20443 offset--;
20444
20445 prec = c_string_width (SDATA (elt) + last_offset,
20446 offset - last_offset, precision - n,
20447 &nchars, &nbytes);
20448
20449 switch (mode_line_target)
20450 {
20451 case MODE_LINE_NOPROP:
20452 case MODE_LINE_TITLE:
20453 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20454 break;
20455 case MODE_LINE_STRING:
20456 {
20457 ptrdiff_t bytepos = last_offset;
20458 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20459 ptrdiff_t endpos = (precision <= 0
20460 ? string_byte_to_char (elt, offset)
20461 : charpos + nchars);
20462
20463 n += store_mode_line_string (NULL,
20464 Fsubstring (elt, make_number (charpos),
20465 make_number (endpos)),
20466 0, 0, 0, Qnil);
20467 }
20468 break;
20469 case MODE_LINE_DISPLAY:
20470 {
20471 ptrdiff_t bytepos = last_offset;
20472 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20473
20474 if (precision <= 0)
20475 nchars = string_byte_to_char (elt, offset) - charpos;
20476 n += display_string (NULL, elt, Qnil, 0, charpos,
20477 it, 0, nchars, 0,
20478 STRING_MULTIBYTE (elt));
20479 }
20480 break;
20481 }
20482 }
20483 else /* c == '%' */
20484 {
20485 ptrdiff_t percent_position = offset;
20486
20487 /* Get the specified minimum width. Zero means
20488 don't pad. */
20489 field = 0;
20490 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20491 field = field * 10 + c - '0';
20492
20493 /* Don't pad beyond the total padding allowed. */
20494 if (field_width - n > 0 && field > field_width - n)
20495 field = field_width - n;
20496
20497 /* Note that either PRECISION <= 0 or N < PRECISION. */
20498 prec = precision - n;
20499
20500 if (c == 'M')
20501 n += display_mode_element (it, depth, field, prec,
20502 Vglobal_mode_string, props,
20503 risky);
20504 else if (c != 0)
20505 {
20506 int multibyte;
20507 ptrdiff_t bytepos, charpos;
20508 const char *spec;
20509 Lisp_Object string;
20510
20511 bytepos = percent_position;
20512 charpos = (STRING_MULTIBYTE (elt)
20513 ? string_byte_to_char (elt, bytepos)
20514 : bytepos);
20515 spec = decode_mode_spec (it->w, c, field, &string);
20516 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20517
20518 switch (mode_line_target)
20519 {
20520 case MODE_LINE_NOPROP:
20521 case MODE_LINE_TITLE:
20522 n += store_mode_line_noprop (spec, field, prec);
20523 break;
20524 case MODE_LINE_STRING:
20525 {
20526 Lisp_Object tem = build_string (spec);
20527 props = Ftext_properties_at (make_number (charpos), elt);
20528 /* Should only keep face property in props */
20529 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
20530 }
20531 break;
20532 case MODE_LINE_DISPLAY:
20533 {
20534 int nglyphs_before, nwritten;
20535
20536 nglyphs_before = it->glyph_row->used[TEXT_AREA];
20537 nwritten = display_string (spec, string, elt,
20538 charpos, 0, it,
20539 field, prec, 0,
20540 multibyte);
20541
20542 /* Assign to the glyphs written above the
20543 string where the `%x' came from, position
20544 of the `%'. */
20545 if (nwritten > 0)
20546 {
20547 struct glyph *glyph
20548 = (it->glyph_row->glyphs[TEXT_AREA]
20549 + nglyphs_before);
20550 int i;
20551
20552 for (i = 0; i < nwritten; ++i)
20553 {
20554 glyph[i].object = elt;
20555 glyph[i].charpos = charpos;
20556 }
20557
20558 n += nwritten;
20559 }
20560 }
20561 break;
20562 }
20563 }
20564 else /* c == 0 */
20565 break;
20566 }
20567 }
20568 }
20569 break;
20570
20571 case Lisp_Symbol:
20572 /* A symbol: process the value of the symbol recursively
20573 as if it appeared here directly. Avoid error if symbol void.
20574 Special case: if value of symbol is a string, output the string
20575 literally. */
20576 {
20577 register Lisp_Object tem;
20578
20579 /* If the variable is not marked as risky to set
20580 then its contents are risky to use. */
20581 if (NILP (Fget (elt, Qrisky_local_variable)))
20582 risky = 1;
20583
20584 tem = Fboundp (elt);
20585 if (!NILP (tem))
20586 {
20587 tem = Fsymbol_value (elt);
20588 /* If value is a string, output that string literally:
20589 don't check for % within it. */
20590 if (STRINGP (tem))
20591 literal = 1;
20592
20593 if (!EQ (tem, elt))
20594 {
20595 /* Give up right away for nil or t. */
20596 elt = tem;
20597 goto tail_recurse;
20598 }
20599 }
20600 }
20601 break;
20602
20603 case Lisp_Cons:
20604 {
20605 register Lisp_Object car, tem;
20606
20607 /* A cons cell: five distinct cases.
20608 If first element is :eval or :propertize, do something special.
20609 If first element is a string or a cons, process all the elements
20610 and effectively concatenate them.
20611 If first element is a negative number, truncate displaying cdr to
20612 at most that many characters. If positive, pad (with spaces)
20613 to at least that many characters.
20614 If first element is a symbol, process the cadr or caddr recursively
20615 according to whether the symbol's value is non-nil or nil. */
20616 car = XCAR (elt);
20617 if (EQ (car, QCeval))
20618 {
20619 /* An element of the form (:eval FORM) means evaluate FORM
20620 and use the result as mode line elements. */
20621
20622 if (risky)
20623 break;
20624
20625 if (CONSP (XCDR (elt)))
20626 {
20627 Lisp_Object spec;
20628 spec = safe_eval (XCAR (XCDR (elt)));
20629 n += display_mode_element (it, depth, field_width - n,
20630 precision - n, spec, props,
20631 risky);
20632 }
20633 }
20634 else if (EQ (car, QCpropertize))
20635 {
20636 /* An element of the form (:propertize ELT PROPS...)
20637 means display ELT but applying properties PROPS. */
20638
20639 if (risky)
20640 break;
20641
20642 if (CONSP (XCDR (elt)))
20643 n += display_mode_element (it, depth, field_width - n,
20644 precision - n, XCAR (XCDR (elt)),
20645 XCDR (XCDR (elt)), risky);
20646 }
20647 else if (SYMBOLP (car))
20648 {
20649 tem = Fboundp (car);
20650 elt = XCDR (elt);
20651 if (!CONSP (elt))
20652 goto invalid;
20653 /* elt is now the cdr, and we know it is a cons cell.
20654 Use its car if CAR has a non-nil value. */
20655 if (!NILP (tem))
20656 {
20657 tem = Fsymbol_value (car);
20658 if (!NILP (tem))
20659 {
20660 elt = XCAR (elt);
20661 goto tail_recurse;
20662 }
20663 }
20664 /* Symbol's value is nil (or symbol is unbound)
20665 Get the cddr of the original list
20666 and if possible find the caddr and use that. */
20667 elt = XCDR (elt);
20668 if (NILP (elt))
20669 break;
20670 else if (!CONSP (elt))
20671 goto invalid;
20672 elt = XCAR (elt);
20673 goto tail_recurse;
20674 }
20675 else if (INTEGERP (car))
20676 {
20677 register int lim = XINT (car);
20678 elt = XCDR (elt);
20679 if (lim < 0)
20680 {
20681 /* Negative int means reduce maximum width. */
20682 if (precision <= 0)
20683 precision = -lim;
20684 else
20685 precision = min (precision, -lim);
20686 }
20687 else if (lim > 0)
20688 {
20689 /* Padding specified. Don't let it be more than
20690 current maximum. */
20691 if (precision > 0)
20692 lim = min (precision, lim);
20693
20694 /* If that's more padding than already wanted, queue it.
20695 But don't reduce padding already specified even if
20696 that is beyond the current truncation point. */
20697 field_width = max (lim, field_width);
20698 }
20699 goto tail_recurse;
20700 }
20701 else if (STRINGP (car) || CONSP (car))
20702 {
20703 Lisp_Object halftail = elt;
20704 int len = 0;
20705
20706 while (CONSP (elt)
20707 && (precision <= 0 || n < precision))
20708 {
20709 n += display_mode_element (it, depth,
20710 /* Do padding only after the last
20711 element in the list. */
20712 (! CONSP (XCDR (elt))
20713 ? field_width - n
20714 : 0),
20715 precision - n, XCAR (elt),
20716 props, risky);
20717 elt = XCDR (elt);
20718 len++;
20719 if ((len & 1) == 0)
20720 halftail = XCDR (halftail);
20721 /* Check for cycle. */
20722 if (EQ (halftail, elt))
20723 break;
20724 }
20725 }
20726 }
20727 break;
20728
20729 default:
20730 invalid:
20731 elt = build_string ("*invalid*");
20732 goto tail_recurse;
20733 }
20734
20735 /* Pad to FIELD_WIDTH. */
20736 if (field_width > 0 && n < field_width)
20737 {
20738 switch (mode_line_target)
20739 {
20740 case MODE_LINE_NOPROP:
20741 case MODE_LINE_TITLE:
20742 n += store_mode_line_noprop ("", field_width - n, 0);
20743 break;
20744 case MODE_LINE_STRING:
20745 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
20746 break;
20747 case MODE_LINE_DISPLAY:
20748 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
20749 0, 0, 0);
20750 break;
20751 }
20752 }
20753
20754 return n;
20755 }
20756
20757 /* Store a mode-line string element in mode_line_string_list.
20758
20759 If STRING is non-null, display that C string. Otherwise, the Lisp
20760 string LISP_STRING is displayed.
20761
20762 FIELD_WIDTH is the minimum number of output glyphs to produce.
20763 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20764 with spaces. FIELD_WIDTH <= 0 means don't pad.
20765
20766 PRECISION is the maximum number of characters to output from
20767 STRING. PRECISION <= 0 means don't truncate the string.
20768
20769 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
20770 properties to the string.
20771
20772 PROPS are the properties to add to the string.
20773 The mode_line_string_face face property is always added to the string.
20774 */
20775
20776 static int
20777 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
20778 int field_width, int precision, Lisp_Object props)
20779 {
20780 ptrdiff_t len;
20781 int n = 0;
20782
20783 if (string != NULL)
20784 {
20785 len = strlen (string);
20786 if (precision > 0 && len > precision)
20787 len = precision;
20788 lisp_string = make_string (string, len);
20789 if (NILP (props))
20790 props = mode_line_string_face_prop;
20791 else if (!NILP (mode_line_string_face))
20792 {
20793 Lisp_Object face = Fplist_get (props, Qface);
20794 props = Fcopy_sequence (props);
20795 if (NILP (face))
20796 face = mode_line_string_face;
20797 else
20798 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20799 props = Fplist_put (props, Qface, face);
20800 }
20801 Fadd_text_properties (make_number (0), make_number (len),
20802 props, lisp_string);
20803 }
20804 else
20805 {
20806 len = XFASTINT (Flength (lisp_string));
20807 if (precision > 0 && len > precision)
20808 {
20809 len = precision;
20810 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
20811 precision = -1;
20812 }
20813 if (!NILP (mode_line_string_face))
20814 {
20815 Lisp_Object face;
20816 if (NILP (props))
20817 props = Ftext_properties_at (make_number (0), lisp_string);
20818 face = Fplist_get (props, Qface);
20819 if (NILP (face))
20820 face = mode_line_string_face;
20821 else
20822 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20823 props = Fcons (Qface, Fcons (face, Qnil));
20824 if (copy_string)
20825 lisp_string = Fcopy_sequence (lisp_string);
20826 }
20827 if (!NILP (props))
20828 Fadd_text_properties (make_number (0), make_number (len),
20829 props, lisp_string);
20830 }
20831
20832 if (len > 0)
20833 {
20834 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20835 n += len;
20836 }
20837
20838 if (field_width > len)
20839 {
20840 field_width -= len;
20841 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
20842 if (!NILP (props))
20843 Fadd_text_properties (make_number (0), make_number (field_width),
20844 props, lisp_string);
20845 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20846 n += field_width;
20847 }
20848
20849 return n;
20850 }
20851
20852
20853 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
20854 1, 4, 0,
20855 doc: /* Format a string out of a mode line format specification.
20856 First arg FORMAT specifies the mode line format (see `mode-line-format'
20857 for details) to use.
20858
20859 By default, the format is evaluated for the currently selected window.
20860
20861 Optional second arg FACE specifies the face property to put on all
20862 characters for which no face is specified. The value nil means the
20863 default face. The value t means whatever face the window's mode line
20864 currently uses (either `mode-line' or `mode-line-inactive',
20865 depending on whether the window is the selected window or not).
20866 An integer value means the value string has no text
20867 properties.
20868
20869 Optional third and fourth args WINDOW and BUFFER specify the window
20870 and buffer to use as the context for the formatting (defaults
20871 are the selected window and the WINDOW's buffer). */)
20872 (Lisp_Object format, Lisp_Object face,
20873 Lisp_Object window, Lisp_Object buffer)
20874 {
20875 struct it it;
20876 int len;
20877 struct window *w;
20878 struct buffer *old_buffer = NULL;
20879 int face_id;
20880 int no_props = INTEGERP (face);
20881 ptrdiff_t count = SPECPDL_INDEX ();
20882 Lisp_Object str;
20883 int string_start = 0;
20884
20885 w = decode_any_window (window);
20886 XSETWINDOW (window, w);
20887
20888 if (NILP (buffer))
20889 buffer = w->buffer;
20890 CHECK_BUFFER (buffer);
20891
20892 /* Make formatting the modeline a non-op when noninteractive, otherwise
20893 there will be problems later caused by a partially initialized frame. */
20894 if (NILP (format) || noninteractive)
20895 return empty_unibyte_string;
20896
20897 if (no_props)
20898 face = Qnil;
20899
20900 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
20901 : EQ (face, Qt) ? (EQ (window, selected_window)
20902 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
20903 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
20904 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
20905 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
20906 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
20907 : DEFAULT_FACE_ID;
20908
20909 old_buffer = current_buffer;
20910
20911 /* Save things including mode_line_proptrans_alist,
20912 and set that to nil so that we don't alter the outer value. */
20913 record_unwind_protect (unwind_format_mode_line,
20914 format_mode_line_unwind_data
20915 (XFRAME (WINDOW_FRAME (w)),
20916 old_buffer, selected_window, 1));
20917 mode_line_proptrans_alist = Qnil;
20918
20919 Fselect_window (window, Qt);
20920 set_buffer_internal_1 (XBUFFER (buffer));
20921
20922 init_iterator (&it, w, -1, -1, NULL, face_id);
20923
20924 if (no_props)
20925 {
20926 mode_line_target = MODE_LINE_NOPROP;
20927 mode_line_string_face_prop = Qnil;
20928 mode_line_string_list = Qnil;
20929 string_start = MODE_LINE_NOPROP_LEN (0);
20930 }
20931 else
20932 {
20933 mode_line_target = MODE_LINE_STRING;
20934 mode_line_string_list = Qnil;
20935 mode_line_string_face = face;
20936 mode_line_string_face_prop
20937 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
20938 }
20939
20940 push_kboard (FRAME_KBOARD (it.f));
20941 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20942 pop_kboard ();
20943
20944 if (no_props)
20945 {
20946 len = MODE_LINE_NOPROP_LEN (string_start);
20947 str = make_string (mode_line_noprop_buf + string_start, len);
20948 }
20949 else
20950 {
20951 mode_line_string_list = Fnreverse (mode_line_string_list);
20952 str = Fmapconcat (intern ("identity"), mode_line_string_list,
20953 empty_unibyte_string);
20954 }
20955
20956 unbind_to (count, Qnil);
20957 return str;
20958 }
20959
20960 /* Write a null-terminated, right justified decimal representation of
20961 the positive integer D to BUF using a minimal field width WIDTH. */
20962
20963 static void
20964 pint2str (register char *buf, register int width, register ptrdiff_t d)
20965 {
20966 register char *p = buf;
20967
20968 if (d <= 0)
20969 *p++ = '0';
20970 else
20971 {
20972 while (d > 0)
20973 {
20974 *p++ = d % 10 + '0';
20975 d /= 10;
20976 }
20977 }
20978
20979 for (width -= (int) (p - buf); width > 0; --width)
20980 *p++ = ' ';
20981 *p-- = '\0';
20982 while (p > buf)
20983 {
20984 d = *buf;
20985 *buf++ = *p;
20986 *p-- = d;
20987 }
20988 }
20989
20990 /* Write a null-terminated, right justified decimal and "human
20991 readable" representation of the nonnegative integer D to BUF using
20992 a minimal field width WIDTH. D should be smaller than 999.5e24. */
20993
20994 static const char power_letter[] =
20995 {
20996 0, /* no letter */
20997 'k', /* kilo */
20998 'M', /* mega */
20999 'G', /* giga */
21000 'T', /* tera */
21001 'P', /* peta */
21002 'E', /* exa */
21003 'Z', /* zetta */
21004 'Y' /* yotta */
21005 };
21006
21007 static void
21008 pint2hrstr (char *buf, int width, ptrdiff_t d)
21009 {
21010 /* We aim to represent the nonnegative integer D as
21011 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21012 ptrdiff_t quotient = d;
21013 int remainder = 0;
21014 /* -1 means: do not use TENTHS. */
21015 int tenths = -1;
21016 int exponent = 0;
21017
21018 /* Length of QUOTIENT.TENTHS as a string. */
21019 int length;
21020
21021 char * psuffix;
21022 char * p;
21023
21024 if (1000 <= quotient)
21025 {
21026 /* Scale to the appropriate EXPONENT. */
21027 do
21028 {
21029 remainder = quotient % 1000;
21030 quotient /= 1000;
21031 exponent++;
21032 }
21033 while (1000 <= quotient);
21034
21035 /* Round to nearest and decide whether to use TENTHS or not. */
21036 if (quotient <= 9)
21037 {
21038 tenths = remainder / 100;
21039 if (50 <= remainder % 100)
21040 {
21041 if (tenths < 9)
21042 tenths++;
21043 else
21044 {
21045 quotient++;
21046 if (quotient == 10)
21047 tenths = -1;
21048 else
21049 tenths = 0;
21050 }
21051 }
21052 }
21053 else
21054 if (500 <= remainder)
21055 {
21056 if (quotient < 999)
21057 quotient++;
21058 else
21059 {
21060 quotient = 1;
21061 exponent++;
21062 tenths = 0;
21063 }
21064 }
21065 }
21066
21067 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21068 if (tenths == -1 && quotient <= 99)
21069 if (quotient <= 9)
21070 length = 1;
21071 else
21072 length = 2;
21073 else
21074 length = 3;
21075 p = psuffix = buf + max (width, length);
21076
21077 /* Print EXPONENT. */
21078 *psuffix++ = power_letter[exponent];
21079 *psuffix = '\0';
21080
21081 /* Print TENTHS. */
21082 if (tenths >= 0)
21083 {
21084 *--p = '0' + tenths;
21085 *--p = '.';
21086 }
21087
21088 /* Print QUOTIENT. */
21089 do
21090 {
21091 int digit = quotient % 10;
21092 *--p = '0' + digit;
21093 }
21094 while ((quotient /= 10) != 0);
21095
21096 /* Print leading spaces. */
21097 while (buf < p)
21098 *--p = ' ';
21099 }
21100
21101 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21102 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21103 type of CODING_SYSTEM. Return updated pointer into BUF. */
21104
21105 static unsigned char invalid_eol_type[] = "(*invalid*)";
21106
21107 static char *
21108 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21109 {
21110 Lisp_Object val;
21111 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21112 const unsigned char *eol_str;
21113 int eol_str_len;
21114 /* The EOL conversion we are using. */
21115 Lisp_Object eoltype;
21116
21117 val = CODING_SYSTEM_SPEC (coding_system);
21118 eoltype = Qnil;
21119
21120 if (!VECTORP (val)) /* Not yet decided. */
21121 {
21122 *buf++ = multibyte ? '-' : ' ';
21123 if (eol_flag)
21124 eoltype = eol_mnemonic_undecided;
21125 /* Don't mention EOL conversion if it isn't decided. */
21126 }
21127 else
21128 {
21129 Lisp_Object attrs;
21130 Lisp_Object eolvalue;
21131
21132 attrs = AREF (val, 0);
21133 eolvalue = AREF (val, 2);
21134
21135 *buf++ = multibyte
21136 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21137 : ' ';
21138
21139 if (eol_flag)
21140 {
21141 /* The EOL conversion that is normal on this system. */
21142
21143 if (NILP (eolvalue)) /* Not yet decided. */
21144 eoltype = eol_mnemonic_undecided;
21145 else if (VECTORP (eolvalue)) /* Not yet decided. */
21146 eoltype = eol_mnemonic_undecided;
21147 else /* eolvalue is Qunix, Qdos, or Qmac. */
21148 eoltype = (EQ (eolvalue, Qunix)
21149 ? eol_mnemonic_unix
21150 : (EQ (eolvalue, Qdos) == 1
21151 ? eol_mnemonic_dos : eol_mnemonic_mac));
21152 }
21153 }
21154
21155 if (eol_flag)
21156 {
21157 /* Mention the EOL conversion if it is not the usual one. */
21158 if (STRINGP (eoltype))
21159 {
21160 eol_str = SDATA (eoltype);
21161 eol_str_len = SBYTES (eoltype);
21162 }
21163 else if (CHARACTERP (eoltype))
21164 {
21165 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21166 int c = XFASTINT (eoltype);
21167 eol_str_len = CHAR_STRING (c, tmp);
21168 eol_str = tmp;
21169 }
21170 else
21171 {
21172 eol_str = invalid_eol_type;
21173 eol_str_len = sizeof (invalid_eol_type) - 1;
21174 }
21175 memcpy (buf, eol_str, eol_str_len);
21176 buf += eol_str_len;
21177 }
21178
21179 return buf;
21180 }
21181
21182 /* Return a string for the output of a mode line %-spec for window W,
21183 generated by character C. FIELD_WIDTH > 0 means pad the string
21184 returned with spaces to that value. Return a Lisp string in
21185 *STRING if the resulting string is taken from that Lisp string.
21186
21187 Note we operate on the current buffer for most purposes,
21188 the exception being w->base_line_pos. */
21189
21190 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21191
21192 static const char *
21193 decode_mode_spec (struct window *w, register int c, int field_width,
21194 Lisp_Object *string)
21195 {
21196 Lisp_Object obj;
21197 struct frame *f = XFRAME (WINDOW_FRAME (w));
21198 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21199 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21200 produce strings from numerical values, so limit preposterously
21201 large values of FIELD_WIDTH to avoid overrunning the buffer's
21202 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21203 bytes plus the terminating null. */
21204 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21205 struct buffer *b = current_buffer;
21206
21207 obj = Qnil;
21208 *string = Qnil;
21209
21210 switch (c)
21211 {
21212 case '*':
21213 if (!NILP (BVAR (b, read_only)))
21214 return "%";
21215 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21216 return "*";
21217 return "-";
21218
21219 case '+':
21220 /* This differs from %* only for a modified read-only buffer. */
21221 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21222 return "*";
21223 if (!NILP (BVAR (b, read_only)))
21224 return "%";
21225 return "-";
21226
21227 case '&':
21228 /* This differs from %* in ignoring read-only-ness. */
21229 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21230 return "*";
21231 return "-";
21232
21233 case '%':
21234 return "%";
21235
21236 case '[':
21237 {
21238 int i;
21239 char *p;
21240
21241 if (command_loop_level > 5)
21242 return "[[[... ";
21243 p = decode_mode_spec_buf;
21244 for (i = 0; i < command_loop_level; i++)
21245 *p++ = '[';
21246 *p = 0;
21247 return decode_mode_spec_buf;
21248 }
21249
21250 case ']':
21251 {
21252 int i;
21253 char *p;
21254
21255 if (command_loop_level > 5)
21256 return " ...]]]";
21257 p = decode_mode_spec_buf;
21258 for (i = 0; i < command_loop_level; i++)
21259 *p++ = ']';
21260 *p = 0;
21261 return decode_mode_spec_buf;
21262 }
21263
21264 case '-':
21265 {
21266 register int i;
21267
21268 /* Let lots_of_dashes be a string of infinite length. */
21269 if (mode_line_target == MODE_LINE_NOPROP
21270 || mode_line_target == MODE_LINE_STRING)
21271 return "--";
21272 if (field_width <= 0
21273 || field_width > sizeof (lots_of_dashes))
21274 {
21275 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21276 decode_mode_spec_buf[i] = '-';
21277 decode_mode_spec_buf[i] = '\0';
21278 return decode_mode_spec_buf;
21279 }
21280 else
21281 return lots_of_dashes;
21282 }
21283
21284 case 'b':
21285 obj = BVAR (b, name);
21286 break;
21287
21288 case 'c':
21289 /* %c and %l are ignored in `frame-title-format'.
21290 (In redisplay_internal, the frame title is drawn _before_ the
21291 windows are updated, so the stuff which depends on actual
21292 window contents (such as %l) may fail to render properly, or
21293 even crash emacs.) */
21294 if (mode_line_target == MODE_LINE_TITLE)
21295 return "";
21296 else
21297 {
21298 ptrdiff_t col = current_column ();
21299 wset_column_number_displayed (w, make_number (col));
21300 pint2str (decode_mode_spec_buf, width, col);
21301 return decode_mode_spec_buf;
21302 }
21303
21304 case 'e':
21305 #ifndef SYSTEM_MALLOC
21306 {
21307 if (NILP (Vmemory_full))
21308 return "";
21309 else
21310 return "!MEM FULL! ";
21311 }
21312 #else
21313 return "";
21314 #endif
21315
21316 case 'F':
21317 /* %F displays the frame name. */
21318 if (!NILP (f->title))
21319 return SSDATA (f->title);
21320 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21321 return SSDATA (f->name);
21322 return "Emacs";
21323
21324 case 'f':
21325 obj = BVAR (b, filename);
21326 break;
21327
21328 case 'i':
21329 {
21330 ptrdiff_t size = ZV - BEGV;
21331 pint2str (decode_mode_spec_buf, width, size);
21332 return decode_mode_spec_buf;
21333 }
21334
21335 case 'I':
21336 {
21337 ptrdiff_t size = ZV - BEGV;
21338 pint2hrstr (decode_mode_spec_buf, width, size);
21339 return decode_mode_spec_buf;
21340 }
21341
21342 case 'l':
21343 {
21344 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21345 ptrdiff_t topline, nlines, height;
21346 ptrdiff_t junk;
21347
21348 /* %c and %l are ignored in `frame-title-format'. */
21349 if (mode_line_target == MODE_LINE_TITLE)
21350 return "";
21351
21352 startpos = marker_position (w->start);
21353 startpos_byte = marker_byte_position (w->start);
21354 height = WINDOW_TOTAL_LINES (w);
21355
21356 /* If we decided that this buffer isn't suitable for line numbers,
21357 don't forget that too fast. */
21358 if (EQ (w->base_line_pos, w->buffer))
21359 goto no_value;
21360 /* But do forget it, if the window shows a different buffer now. */
21361 else if (BUFFERP (w->base_line_pos))
21362 wset_base_line_pos (w, Qnil);
21363
21364 /* If the buffer is very big, don't waste time. */
21365 if (INTEGERP (Vline_number_display_limit)
21366 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21367 {
21368 wset_base_line_pos (w, Qnil);
21369 wset_base_line_number (w, Qnil);
21370 goto no_value;
21371 }
21372
21373 if (INTEGERP (w->base_line_number)
21374 && INTEGERP (w->base_line_pos)
21375 && XFASTINT (w->base_line_pos) <= startpos)
21376 {
21377 line = XFASTINT (w->base_line_number);
21378 linepos = XFASTINT (w->base_line_pos);
21379 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21380 }
21381 else
21382 {
21383 line = 1;
21384 linepos = BUF_BEGV (b);
21385 linepos_byte = BUF_BEGV_BYTE (b);
21386 }
21387
21388 /* Count lines from base line to window start position. */
21389 nlines = display_count_lines (linepos_byte,
21390 startpos_byte,
21391 startpos, &junk);
21392
21393 topline = nlines + line;
21394
21395 /* Determine a new base line, if the old one is too close
21396 or too far away, or if we did not have one.
21397 "Too close" means it's plausible a scroll-down would
21398 go back past it. */
21399 if (startpos == BUF_BEGV (b))
21400 {
21401 wset_base_line_number (w, make_number (topline));
21402 wset_base_line_pos (w, make_number (BUF_BEGV (b)));
21403 }
21404 else if (nlines < height + 25 || nlines > height * 3 + 50
21405 || linepos == BUF_BEGV (b))
21406 {
21407 ptrdiff_t limit = BUF_BEGV (b);
21408 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21409 ptrdiff_t position;
21410 ptrdiff_t distance =
21411 (height * 2 + 30) * line_number_display_limit_width;
21412
21413 if (startpos - distance > limit)
21414 {
21415 limit = startpos - distance;
21416 limit_byte = CHAR_TO_BYTE (limit);
21417 }
21418
21419 nlines = display_count_lines (startpos_byte,
21420 limit_byte,
21421 - (height * 2 + 30),
21422 &position);
21423 /* If we couldn't find the lines we wanted within
21424 line_number_display_limit_width chars per line,
21425 give up on line numbers for this window. */
21426 if (position == limit_byte && limit == startpos - distance)
21427 {
21428 wset_base_line_pos (w, w->buffer);
21429 wset_base_line_number (w, Qnil);
21430 goto no_value;
21431 }
21432
21433 wset_base_line_number (w, make_number (topline - nlines));
21434 wset_base_line_pos (w, make_number (BYTE_TO_CHAR (position)));
21435 }
21436
21437 /* Now count lines from the start pos to point. */
21438 nlines = display_count_lines (startpos_byte,
21439 PT_BYTE, PT, &junk);
21440
21441 /* Record that we did display the line number. */
21442 line_number_displayed = 1;
21443
21444 /* Make the string to show. */
21445 pint2str (decode_mode_spec_buf, width, topline + nlines);
21446 return decode_mode_spec_buf;
21447 no_value:
21448 {
21449 char* p = decode_mode_spec_buf;
21450 int pad = width - 2;
21451 while (pad-- > 0)
21452 *p++ = ' ';
21453 *p++ = '?';
21454 *p++ = '?';
21455 *p = '\0';
21456 return decode_mode_spec_buf;
21457 }
21458 }
21459 break;
21460
21461 case 'm':
21462 obj = BVAR (b, mode_name);
21463 break;
21464
21465 case 'n':
21466 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21467 return " Narrow";
21468 break;
21469
21470 case 'p':
21471 {
21472 ptrdiff_t pos = marker_position (w->start);
21473 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21474
21475 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21476 {
21477 if (pos <= BUF_BEGV (b))
21478 return "All";
21479 else
21480 return "Bottom";
21481 }
21482 else if (pos <= BUF_BEGV (b))
21483 return "Top";
21484 else
21485 {
21486 if (total > 1000000)
21487 /* Do it differently for a large value, to avoid overflow. */
21488 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21489 else
21490 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21491 /* We can't normally display a 3-digit number,
21492 so get us a 2-digit number that is close. */
21493 if (total == 100)
21494 total = 99;
21495 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21496 return decode_mode_spec_buf;
21497 }
21498 }
21499
21500 /* Display percentage of size above the bottom of the screen. */
21501 case 'P':
21502 {
21503 ptrdiff_t toppos = marker_position (w->start);
21504 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21505 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21506
21507 if (botpos >= BUF_ZV (b))
21508 {
21509 if (toppos <= BUF_BEGV (b))
21510 return "All";
21511 else
21512 return "Bottom";
21513 }
21514 else
21515 {
21516 if (total > 1000000)
21517 /* Do it differently for a large value, to avoid overflow. */
21518 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21519 else
21520 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21521 /* We can't normally display a 3-digit number,
21522 so get us a 2-digit number that is close. */
21523 if (total == 100)
21524 total = 99;
21525 if (toppos <= BUF_BEGV (b))
21526 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
21527 else
21528 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21529 return decode_mode_spec_buf;
21530 }
21531 }
21532
21533 case 's':
21534 /* status of process */
21535 obj = Fget_buffer_process (Fcurrent_buffer ());
21536 if (NILP (obj))
21537 return "no process";
21538 #ifndef MSDOS
21539 obj = Fsymbol_name (Fprocess_status (obj));
21540 #endif
21541 break;
21542
21543 case '@':
21544 {
21545 ptrdiff_t count = inhibit_garbage_collection ();
21546 Lisp_Object val = call1 (intern ("file-remote-p"),
21547 BVAR (current_buffer, directory));
21548 unbind_to (count, Qnil);
21549
21550 if (NILP (val))
21551 return "-";
21552 else
21553 return "@";
21554 }
21555
21556 case 't': /* indicate TEXT or BINARY */
21557 return "T";
21558
21559 case 'z':
21560 /* coding-system (not including end-of-line format) */
21561 case 'Z':
21562 /* coding-system (including end-of-line type) */
21563 {
21564 int eol_flag = (c == 'Z');
21565 char *p = decode_mode_spec_buf;
21566
21567 if (! FRAME_WINDOW_P (f))
21568 {
21569 /* No need to mention EOL here--the terminal never needs
21570 to do EOL conversion. */
21571 p = decode_mode_spec_coding (CODING_ID_NAME
21572 (FRAME_KEYBOARD_CODING (f)->id),
21573 p, 0);
21574 p = decode_mode_spec_coding (CODING_ID_NAME
21575 (FRAME_TERMINAL_CODING (f)->id),
21576 p, 0);
21577 }
21578 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
21579 p, eol_flag);
21580
21581 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21582 #ifdef subprocesses
21583 obj = Fget_buffer_process (Fcurrent_buffer ());
21584 if (PROCESSP (obj))
21585 {
21586 p = decode_mode_spec_coding
21587 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
21588 p = decode_mode_spec_coding
21589 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
21590 }
21591 #endif /* subprocesses */
21592 #endif /* 0 */
21593 *p = 0;
21594 return decode_mode_spec_buf;
21595 }
21596 }
21597
21598 if (STRINGP (obj))
21599 {
21600 *string = obj;
21601 return SSDATA (obj);
21602 }
21603 else
21604 return "";
21605 }
21606
21607
21608 /* Count up to COUNT lines starting from START_BYTE.
21609 But don't go beyond LIMIT_BYTE.
21610 Return the number of lines thus found (always nonnegative).
21611
21612 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
21613
21614 static ptrdiff_t
21615 display_count_lines (ptrdiff_t start_byte,
21616 ptrdiff_t limit_byte, ptrdiff_t count,
21617 ptrdiff_t *byte_pos_ptr)
21618 {
21619 register unsigned char *cursor;
21620 unsigned char *base;
21621
21622 register ptrdiff_t ceiling;
21623 register unsigned char *ceiling_addr;
21624 ptrdiff_t orig_count = count;
21625
21626 /* If we are not in selective display mode,
21627 check only for newlines. */
21628 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
21629 && !INTEGERP (BVAR (current_buffer, selective_display)));
21630
21631 if (count > 0)
21632 {
21633 while (start_byte < limit_byte)
21634 {
21635 ceiling = BUFFER_CEILING_OF (start_byte);
21636 ceiling = min (limit_byte - 1, ceiling);
21637 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21638 base = (cursor = BYTE_POS_ADDR (start_byte));
21639 while (1)
21640 {
21641 if (selective_display)
21642 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
21643 ;
21644 else
21645 while (*cursor != '\n' && ++cursor != ceiling_addr)
21646 ;
21647
21648 if (cursor != ceiling_addr)
21649 {
21650 if (--count == 0)
21651 {
21652 start_byte += cursor - base + 1;
21653 *byte_pos_ptr = start_byte;
21654 return orig_count;
21655 }
21656 else
21657 if (++cursor == ceiling_addr)
21658 break;
21659 }
21660 else
21661 break;
21662 }
21663 start_byte += cursor - base;
21664 }
21665 }
21666 else
21667 {
21668 while (start_byte > limit_byte)
21669 {
21670 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21671 ceiling = max (limit_byte, ceiling);
21672 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
21673 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21674 while (1)
21675 {
21676 if (selective_display)
21677 while (--cursor != ceiling_addr
21678 && *cursor != '\n' && *cursor != 015)
21679 ;
21680 else
21681 while (--cursor != ceiling_addr && *cursor != '\n')
21682 ;
21683
21684 if (cursor != ceiling_addr)
21685 {
21686 if (++count == 0)
21687 {
21688 start_byte += cursor - base + 1;
21689 *byte_pos_ptr = start_byte;
21690 /* When scanning backwards, we should
21691 not count the newline posterior to which we stop. */
21692 return - orig_count - 1;
21693 }
21694 }
21695 else
21696 break;
21697 }
21698 /* Here we add 1 to compensate for the last decrement
21699 of CURSOR, which took it past the valid range. */
21700 start_byte += cursor - base + 1;
21701 }
21702 }
21703
21704 *byte_pos_ptr = limit_byte;
21705
21706 if (count < 0)
21707 return - orig_count + count;
21708 return orig_count - count;
21709
21710 }
21711
21712
21713 \f
21714 /***********************************************************************
21715 Displaying strings
21716 ***********************************************************************/
21717
21718 /* Display a NUL-terminated string, starting with index START.
21719
21720 If STRING is non-null, display that C string. Otherwise, the Lisp
21721 string LISP_STRING is displayed. There's a case that STRING is
21722 non-null and LISP_STRING is not nil. It means STRING is a string
21723 data of LISP_STRING. In that case, we display LISP_STRING while
21724 ignoring its text properties.
21725
21726 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21727 FACE_STRING. Display STRING or LISP_STRING with the face at
21728 FACE_STRING_POS in FACE_STRING:
21729
21730 Display the string in the environment given by IT, but use the
21731 standard display table, temporarily.
21732
21733 FIELD_WIDTH is the minimum number of output glyphs to produce.
21734 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21735 with spaces. If STRING has more characters, more than FIELD_WIDTH
21736 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21737
21738 PRECISION is the maximum number of characters to output from
21739 STRING. PRECISION < 0 means don't truncate the string.
21740
21741 This is roughly equivalent to printf format specifiers:
21742
21743 FIELD_WIDTH PRECISION PRINTF
21744 ----------------------------------------
21745 -1 -1 %s
21746 -1 10 %.10s
21747 10 -1 %10s
21748 20 10 %20.10s
21749
21750 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21751 display them, and < 0 means obey the current buffer's value of
21752 enable_multibyte_characters.
21753
21754 Value is the number of columns displayed. */
21755
21756 static int
21757 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
21758 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
21759 int field_width, int precision, int max_x, int multibyte)
21760 {
21761 int hpos_at_start = it->hpos;
21762 int saved_face_id = it->face_id;
21763 struct glyph_row *row = it->glyph_row;
21764 ptrdiff_t it_charpos;
21765
21766 /* Initialize the iterator IT for iteration over STRING beginning
21767 with index START. */
21768 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
21769 precision, field_width, multibyte);
21770 if (string && STRINGP (lisp_string))
21771 /* LISP_STRING is the one returned by decode_mode_spec. We should
21772 ignore its text properties. */
21773 it->stop_charpos = it->end_charpos;
21774
21775 /* If displaying STRING, set up the face of the iterator from
21776 FACE_STRING, if that's given. */
21777 if (STRINGP (face_string))
21778 {
21779 ptrdiff_t endptr;
21780 struct face *face;
21781
21782 it->face_id
21783 = face_at_string_position (it->w, face_string, face_string_pos,
21784 0, it->region_beg_charpos,
21785 it->region_end_charpos,
21786 &endptr, it->base_face_id, 0);
21787 face = FACE_FROM_ID (it->f, it->face_id);
21788 it->face_box_p = face->box != FACE_NO_BOX;
21789 }
21790
21791 /* Set max_x to the maximum allowed X position. Don't let it go
21792 beyond the right edge of the window. */
21793 if (max_x <= 0)
21794 max_x = it->last_visible_x;
21795 else
21796 max_x = min (max_x, it->last_visible_x);
21797
21798 /* Skip over display elements that are not visible. because IT->w is
21799 hscrolled. */
21800 if (it->current_x < it->first_visible_x)
21801 move_it_in_display_line_to (it, 100000, it->first_visible_x,
21802 MOVE_TO_POS | MOVE_TO_X);
21803
21804 row->ascent = it->max_ascent;
21805 row->height = it->max_ascent + it->max_descent;
21806 row->phys_ascent = it->max_phys_ascent;
21807 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21808 row->extra_line_spacing = it->max_extra_line_spacing;
21809
21810 if (STRINGP (it->string))
21811 it_charpos = IT_STRING_CHARPOS (*it);
21812 else
21813 it_charpos = IT_CHARPOS (*it);
21814
21815 /* This condition is for the case that we are called with current_x
21816 past last_visible_x. */
21817 while (it->current_x < max_x)
21818 {
21819 int x_before, x, n_glyphs_before, i, nglyphs;
21820
21821 /* Get the next display element. */
21822 if (!get_next_display_element (it))
21823 break;
21824
21825 /* Produce glyphs. */
21826 x_before = it->current_x;
21827 n_glyphs_before = row->used[TEXT_AREA];
21828 PRODUCE_GLYPHS (it);
21829
21830 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21831 i = 0;
21832 x = x_before;
21833 while (i < nglyphs)
21834 {
21835 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21836
21837 if (it->line_wrap != TRUNCATE
21838 && x + glyph->pixel_width > max_x)
21839 {
21840 /* End of continued line or max_x reached. */
21841 if (CHAR_GLYPH_PADDING_P (*glyph))
21842 {
21843 /* A wide character is unbreakable. */
21844 if (row->reversed_p)
21845 unproduce_glyphs (it, row->used[TEXT_AREA]
21846 - n_glyphs_before);
21847 row->used[TEXT_AREA] = n_glyphs_before;
21848 it->current_x = x_before;
21849 }
21850 else
21851 {
21852 if (row->reversed_p)
21853 unproduce_glyphs (it, row->used[TEXT_AREA]
21854 - (n_glyphs_before + i));
21855 row->used[TEXT_AREA] = n_glyphs_before + i;
21856 it->current_x = x;
21857 }
21858 break;
21859 }
21860 else if (x + glyph->pixel_width >= it->first_visible_x)
21861 {
21862 /* Glyph is at least partially visible. */
21863 ++it->hpos;
21864 if (x < it->first_visible_x)
21865 row->x = x - it->first_visible_x;
21866 }
21867 else
21868 {
21869 /* Glyph is off the left margin of the display area.
21870 Should not happen. */
21871 emacs_abort ();
21872 }
21873
21874 row->ascent = max (row->ascent, it->max_ascent);
21875 row->height = max (row->height, it->max_ascent + it->max_descent);
21876 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21877 row->phys_height = max (row->phys_height,
21878 it->max_phys_ascent + it->max_phys_descent);
21879 row->extra_line_spacing = max (row->extra_line_spacing,
21880 it->max_extra_line_spacing);
21881 x += glyph->pixel_width;
21882 ++i;
21883 }
21884
21885 /* Stop if max_x reached. */
21886 if (i < nglyphs)
21887 break;
21888
21889 /* Stop at line ends. */
21890 if (ITERATOR_AT_END_OF_LINE_P (it))
21891 {
21892 it->continuation_lines_width = 0;
21893 break;
21894 }
21895
21896 set_iterator_to_next (it, 1);
21897 if (STRINGP (it->string))
21898 it_charpos = IT_STRING_CHARPOS (*it);
21899 else
21900 it_charpos = IT_CHARPOS (*it);
21901
21902 /* Stop if truncating at the right edge. */
21903 if (it->line_wrap == TRUNCATE
21904 && it->current_x >= it->last_visible_x)
21905 {
21906 /* Add truncation mark, but don't do it if the line is
21907 truncated at a padding space. */
21908 if (it_charpos < it->string_nchars)
21909 {
21910 if (!FRAME_WINDOW_P (it->f))
21911 {
21912 int ii, n;
21913
21914 if (it->current_x > it->last_visible_x)
21915 {
21916 if (!row->reversed_p)
21917 {
21918 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
21919 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21920 break;
21921 }
21922 else
21923 {
21924 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
21925 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21926 break;
21927 unproduce_glyphs (it, ii + 1);
21928 ii = row->used[TEXT_AREA] - (ii + 1);
21929 }
21930 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
21931 {
21932 row->used[TEXT_AREA] = ii;
21933 produce_special_glyphs (it, IT_TRUNCATION);
21934 }
21935 }
21936 produce_special_glyphs (it, IT_TRUNCATION);
21937 }
21938 row->truncated_on_right_p = 1;
21939 }
21940 break;
21941 }
21942 }
21943
21944 /* Maybe insert a truncation at the left. */
21945 if (it->first_visible_x
21946 && it_charpos > 0)
21947 {
21948 if (!FRAME_WINDOW_P (it->f)
21949 || (row->reversed_p
21950 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
21951 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
21952 insert_left_trunc_glyphs (it);
21953 row->truncated_on_left_p = 1;
21954 }
21955
21956 it->face_id = saved_face_id;
21957
21958 /* Value is number of columns displayed. */
21959 return it->hpos - hpos_at_start;
21960 }
21961
21962
21963 \f
21964 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
21965 appears as an element of LIST or as the car of an element of LIST.
21966 If PROPVAL is a list, compare each element against LIST in that
21967 way, and return 1/2 if any element of PROPVAL is found in LIST.
21968 Otherwise return 0. This function cannot quit.
21969 The return value is 2 if the text is invisible but with an ellipsis
21970 and 1 if it's invisible and without an ellipsis. */
21971
21972 int
21973 invisible_p (register Lisp_Object propval, Lisp_Object list)
21974 {
21975 register Lisp_Object tail, proptail;
21976
21977 for (tail = list; CONSP (tail); tail = XCDR (tail))
21978 {
21979 register Lisp_Object tem;
21980 tem = XCAR (tail);
21981 if (EQ (propval, tem))
21982 return 1;
21983 if (CONSP (tem) && EQ (propval, XCAR (tem)))
21984 return NILP (XCDR (tem)) ? 1 : 2;
21985 }
21986
21987 if (CONSP (propval))
21988 {
21989 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
21990 {
21991 Lisp_Object propelt;
21992 propelt = XCAR (proptail);
21993 for (tail = list; CONSP (tail); tail = XCDR (tail))
21994 {
21995 register Lisp_Object tem;
21996 tem = XCAR (tail);
21997 if (EQ (propelt, tem))
21998 return 1;
21999 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22000 return NILP (XCDR (tem)) ? 1 : 2;
22001 }
22002 }
22003 }
22004
22005 return 0;
22006 }
22007
22008 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22009 doc: /* Non-nil if the property makes the text invisible.
22010 POS-OR-PROP can be a marker or number, in which case it is taken to be
22011 a position in the current buffer and the value of the `invisible' property
22012 is checked; or it can be some other value, which is then presumed to be the
22013 value of the `invisible' property of the text of interest.
22014 The non-nil value returned can be t for truly invisible text or something
22015 else if the text is replaced by an ellipsis. */)
22016 (Lisp_Object pos_or_prop)
22017 {
22018 Lisp_Object prop
22019 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22020 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22021 : pos_or_prop);
22022 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22023 return (invis == 0 ? Qnil
22024 : invis == 1 ? Qt
22025 : make_number (invis));
22026 }
22027
22028 /* Calculate a width or height in pixels from a specification using
22029 the following elements:
22030
22031 SPEC ::=
22032 NUM - a (fractional) multiple of the default font width/height
22033 (NUM) - specifies exactly NUM pixels
22034 UNIT - a fixed number of pixels, see below.
22035 ELEMENT - size of a display element in pixels, see below.
22036 (NUM . SPEC) - equals NUM * SPEC
22037 (+ SPEC SPEC ...) - add pixel values
22038 (- SPEC SPEC ...) - subtract pixel values
22039 (- SPEC) - negate pixel value
22040
22041 NUM ::=
22042 INT or FLOAT - a number constant
22043 SYMBOL - use symbol's (buffer local) variable binding.
22044
22045 UNIT ::=
22046 in - pixels per inch *)
22047 mm - pixels per 1/1000 meter *)
22048 cm - pixels per 1/100 meter *)
22049 width - width of current font in pixels.
22050 height - height of current font in pixels.
22051
22052 *) using the ratio(s) defined in display-pixels-per-inch.
22053
22054 ELEMENT ::=
22055
22056 left-fringe - left fringe width in pixels
22057 right-fringe - right fringe width in pixels
22058
22059 left-margin - left margin width in pixels
22060 right-margin - right margin width in pixels
22061
22062 scroll-bar - scroll-bar area width in pixels
22063
22064 Examples:
22065
22066 Pixels corresponding to 5 inches:
22067 (5 . in)
22068
22069 Total width of non-text areas on left side of window (if scroll-bar is on left):
22070 '(space :width (+ left-fringe left-margin scroll-bar))
22071
22072 Align to first text column (in header line):
22073 '(space :align-to 0)
22074
22075 Align to middle of text area minus half the width of variable `my-image'
22076 containing a loaded image:
22077 '(space :align-to (0.5 . (- text my-image)))
22078
22079 Width of left margin minus width of 1 character in the default font:
22080 '(space :width (- left-margin 1))
22081
22082 Width of left margin minus width of 2 characters in the current font:
22083 '(space :width (- left-margin (2 . width)))
22084
22085 Center 1 character over left-margin (in header line):
22086 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22087
22088 Different ways to express width of left fringe plus left margin minus one pixel:
22089 '(space :width (- (+ left-fringe left-margin) (1)))
22090 '(space :width (+ left-fringe left-margin (- (1))))
22091 '(space :width (+ left-fringe left-margin (-1)))
22092
22093 */
22094
22095 #define NUMVAL(X) \
22096 ((INTEGERP (X) || FLOATP (X)) \
22097 ? XFLOATINT (X) \
22098 : - 1)
22099
22100 static int
22101 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22102 struct font *font, int width_p, int *align_to)
22103 {
22104 double pixels;
22105
22106 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22107 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22108
22109 if (NILP (prop))
22110 return OK_PIXELS (0);
22111
22112 eassert (FRAME_LIVE_P (it->f));
22113
22114 if (SYMBOLP (prop))
22115 {
22116 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22117 {
22118 char *unit = SSDATA (SYMBOL_NAME (prop));
22119
22120 if (unit[0] == 'i' && unit[1] == 'n')
22121 pixels = 1.0;
22122 else if (unit[0] == 'm' && unit[1] == 'm')
22123 pixels = 25.4;
22124 else if (unit[0] == 'c' && unit[1] == 'm')
22125 pixels = 2.54;
22126 else
22127 pixels = 0;
22128 if (pixels > 0)
22129 {
22130 double ppi;
22131 #ifdef HAVE_WINDOW_SYSTEM
22132 if (FRAME_WINDOW_P (it->f)
22133 && (ppi = (width_p
22134 ? FRAME_X_DISPLAY_INFO (it->f)->resx
22135 : FRAME_X_DISPLAY_INFO (it->f)->resy),
22136 ppi > 0))
22137 return OK_PIXELS (ppi / pixels);
22138 #endif
22139
22140 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
22141 || (CONSP (Vdisplay_pixels_per_inch)
22142 && (ppi = (width_p
22143 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
22144 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
22145 ppi > 0)))
22146 return OK_PIXELS (ppi / pixels);
22147
22148 return 0;
22149 }
22150 }
22151
22152 #ifdef HAVE_WINDOW_SYSTEM
22153 if (EQ (prop, Qheight))
22154 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22155 if (EQ (prop, Qwidth))
22156 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22157 #else
22158 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22159 return OK_PIXELS (1);
22160 #endif
22161
22162 if (EQ (prop, Qtext))
22163 return OK_PIXELS (width_p
22164 ? window_box_width (it->w, TEXT_AREA)
22165 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22166
22167 if (align_to && *align_to < 0)
22168 {
22169 *res = 0;
22170 if (EQ (prop, Qleft))
22171 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22172 if (EQ (prop, Qright))
22173 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22174 if (EQ (prop, Qcenter))
22175 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22176 + window_box_width (it->w, TEXT_AREA) / 2);
22177 if (EQ (prop, Qleft_fringe))
22178 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22179 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22180 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22181 if (EQ (prop, Qright_fringe))
22182 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22183 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22184 : window_box_right_offset (it->w, TEXT_AREA));
22185 if (EQ (prop, Qleft_margin))
22186 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22187 if (EQ (prop, Qright_margin))
22188 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22189 if (EQ (prop, Qscroll_bar))
22190 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22191 ? 0
22192 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22193 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22194 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22195 : 0)));
22196 }
22197 else
22198 {
22199 if (EQ (prop, Qleft_fringe))
22200 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22201 if (EQ (prop, Qright_fringe))
22202 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22203 if (EQ (prop, Qleft_margin))
22204 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22205 if (EQ (prop, Qright_margin))
22206 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22207 if (EQ (prop, Qscroll_bar))
22208 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22209 }
22210
22211 prop = buffer_local_value_1 (prop, it->w->buffer);
22212 if (EQ (prop, Qunbound))
22213 prop = Qnil;
22214 }
22215
22216 if (INTEGERP (prop) || FLOATP (prop))
22217 {
22218 int base_unit = (width_p
22219 ? FRAME_COLUMN_WIDTH (it->f)
22220 : FRAME_LINE_HEIGHT (it->f));
22221 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22222 }
22223
22224 if (CONSP (prop))
22225 {
22226 Lisp_Object car = XCAR (prop);
22227 Lisp_Object cdr = XCDR (prop);
22228
22229 if (SYMBOLP (car))
22230 {
22231 #ifdef HAVE_WINDOW_SYSTEM
22232 if (FRAME_WINDOW_P (it->f)
22233 && valid_image_p (prop))
22234 {
22235 ptrdiff_t id = lookup_image (it->f, prop);
22236 struct image *img = IMAGE_FROM_ID (it->f, id);
22237
22238 return OK_PIXELS (width_p ? img->width : img->height);
22239 }
22240 #endif
22241 if (EQ (car, Qplus) || EQ (car, Qminus))
22242 {
22243 int first = 1;
22244 double px;
22245
22246 pixels = 0;
22247 while (CONSP (cdr))
22248 {
22249 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22250 font, width_p, align_to))
22251 return 0;
22252 if (first)
22253 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22254 else
22255 pixels += px;
22256 cdr = XCDR (cdr);
22257 }
22258 if (EQ (car, Qminus))
22259 pixels = -pixels;
22260 return OK_PIXELS (pixels);
22261 }
22262
22263 car = buffer_local_value_1 (car, it->w->buffer);
22264 if (EQ (car, Qunbound))
22265 car = Qnil;
22266 }
22267
22268 if (INTEGERP (car) || FLOATP (car))
22269 {
22270 double fact;
22271 pixels = XFLOATINT (car);
22272 if (NILP (cdr))
22273 return OK_PIXELS (pixels);
22274 if (calc_pixel_width_or_height (&fact, it, cdr,
22275 font, width_p, align_to))
22276 return OK_PIXELS (pixels * fact);
22277 return 0;
22278 }
22279
22280 return 0;
22281 }
22282
22283 return 0;
22284 }
22285
22286 \f
22287 /***********************************************************************
22288 Glyph Display
22289 ***********************************************************************/
22290
22291 #ifdef HAVE_WINDOW_SYSTEM
22292
22293 #ifdef GLYPH_DEBUG
22294
22295 void
22296 dump_glyph_string (struct glyph_string *s)
22297 {
22298 fprintf (stderr, "glyph string\n");
22299 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22300 s->x, s->y, s->width, s->height);
22301 fprintf (stderr, " ybase = %d\n", s->ybase);
22302 fprintf (stderr, " hl = %d\n", s->hl);
22303 fprintf (stderr, " left overhang = %d, right = %d\n",
22304 s->left_overhang, s->right_overhang);
22305 fprintf (stderr, " nchars = %d\n", s->nchars);
22306 fprintf (stderr, " extends to end of line = %d\n",
22307 s->extends_to_end_of_line_p);
22308 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22309 fprintf (stderr, " bg width = %d\n", s->background_width);
22310 }
22311
22312 #endif /* GLYPH_DEBUG */
22313
22314 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22315 of XChar2b structures for S; it can't be allocated in
22316 init_glyph_string because it must be allocated via `alloca'. W
22317 is the window on which S is drawn. ROW and AREA are the glyph row
22318 and area within the row from which S is constructed. START is the
22319 index of the first glyph structure covered by S. HL is a
22320 face-override for drawing S. */
22321
22322 #ifdef HAVE_NTGUI
22323 #define OPTIONAL_HDC(hdc) HDC hdc,
22324 #define DECLARE_HDC(hdc) HDC hdc;
22325 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22326 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22327 #endif
22328
22329 #ifndef OPTIONAL_HDC
22330 #define OPTIONAL_HDC(hdc)
22331 #define DECLARE_HDC(hdc)
22332 #define ALLOCATE_HDC(hdc, f)
22333 #define RELEASE_HDC(hdc, f)
22334 #endif
22335
22336 static void
22337 init_glyph_string (struct glyph_string *s,
22338 OPTIONAL_HDC (hdc)
22339 XChar2b *char2b, struct window *w, struct glyph_row *row,
22340 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22341 {
22342 memset (s, 0, sizeof *s);
22343 s->w = w;
22344 s->f = XFRAME (w->frame);
22345 #ifdef HAVE_NTGUI
22346 s->hdc = hdc;
22347 #endif
22348 s->display = FRAME_X_DISPLAY (s->f);
22349 s->window = FRAME_X_WINDOW (s->f);
22350 s->char2b = char2b;
22351 s->hl = hl;
22352 s->row = row;
22353 s->area = area;
22354 s->first_glyph = row->glyphs[area] + start;
22355 s->height = row->height;
22356 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22357 s->ybase = s->y + row->ascent;
22358 }
22359
22360
22361 /* Append the list of glyph strings with head H and tail T to the list
22362 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22363
22364 static void
22365 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22366 struct glyph_string *h, struct glyph_string *t)
22367 {
22368 if (h)
22369 {
22370 if (*head)
22371 (*tail)->next = h;
22372 else
22373 *head = h;
22374 h->prev = *tail;
22375 *tail = t;
22376 }
22377 }
22378
22379
22380 /* Prepend the list of glyph strings with head H and tail T to the
22381 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22382 result. */
22383
22384 static void
22385 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22386 struct glyph_string *h, struct glyph_string *t)
22387 {
22388 if (h)
22389 {
22390 if (*head)
22391 (*head)->prev = t;
22392 else
22393 *tail = t;
22394 t->next = *head;
22395 *head = h;
22396 }
22397 }
22398
22399
22400 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22401 Set *HEAD and *TAIL to the resulting list. */
22402
22403 static void
22404 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22405 struct glyph_string *s)
22406 {
22407 s->next = s->prev = NULL;
22408 append_glyph_string_lists (head, tail, s, s);
22409 }
22410
22411
22412 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22413 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22414 make sure that X resources for the face returned are allocated.
22415 Value is a pointer to a realized face that is ready for display if
22416 DISPLAY_P is non-zero. */
22417
22418 static struct face *
22419 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22420 XChar2b *char2b, int display_p)
22421 {
22422 struct face *face = FACE_FROM_ID (f, face_id);
22423
22424 if (face->font)
22425 {
22426 unsigned code = face->font->driver->encode_char (face->font, c);
22427
22428 if (code != FONT_INVALID_CODE)
22429 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22430 else
22431 STORE_XCHAR2B (char2b, 0, 0);
22432 }
22433
22434 /* Make sure X resources of the face are allocated. */
22435 #ifdef HAVE_X_WINDOWS
22436 if (display_p)
22437 #endif
22438 {
22439 eassert (face != NULL);
22440 PREPARE_FACE_FOR_DISPLAY (f, face);
22441 }
22442
22443 return face;
22444 }
22445
22446
22447 /* Get face and two-byte form of character glyph GLYPH on frame F.
22448 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22449 a pointer to a realized face that is ready for display. */
22450
22451 static struct face *
22452 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22453 XChar2b *char2b, int *two_byte_p)
22454 {
22455 struct face *face;
22456
22457 eassert (glyph->type == CHAR_GLYPH);
22458 face = FACE_FROM_ID (f, glyph->face_id);
22459
22460 if (two_byte_p)
22461 *two_byte_p = 0;
22462
22463 if (face->font)
22464 {
22465 unsigned code;
22466
22467 if (CHAR_BYTE8_P (glyph->u.ch))
22468 code = CHAR_TO_BYTE8 (glyph->u.ch);
22469 else
22470 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22471
22472 if (code != FONT_INVALID_CODE)
22473 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22474 else
22475 STORE_XCHAR2B (char2b, 0, 0);
22476 }
22477
22478 /* Make sure X resources of the face are allocated. */
22479 eassert (face != NULL);
22480 PREPARE_FACE_FOR_DISPLAY (f, face);
22481 return face;
22482 }
22483
22484
22485 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22486 Return 1 if FONT has a glyph for C, otherwise return 0. */
22487
22488 static int
22489 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22490 {
22491 unsigned code;
22492
22493 if (CHAR_BYTE8_P (c))
22494 code = CHAR_TO_BYTE8 (c);
22495 else
22496 code = font->driver->encode_char (font, c);
22497
22498 if (code == FONT_INVALID_CODE)
22499 return 0;
22500 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22501 return 1;
22502 }
22503
22504
22505 /* Fill glyph string S with composition components specified by S->cmp.
22506
22507 BASE_FACE is the base face of the composition.
22508 S->cmp_from is the index of the first component for S.
22509
22510 OVERLAPS non-zero means S should draw the foreground only, and use
22511 its physical height for clipping. See also draw_glyphs.
22512
22513 Value is the index of a component not in S. */
22514
22515 static int
22516 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22517 int overlaps)
22518 {
22519 int i;
22520 /* For all glyphs of this composition, starting at the offset
22521 S->cmp_from, until we reach the end of the definition or encounter a
22522 glyph that requires the different face, add it to S. */
22523 struct face *face;
22524
22525 eassert (s);
22526
22527 s->for_overlaps = overlaps;
22528 s->face = NULL;
22529 s->font = NULL;
22530 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22531 {
22532 int c = COMPOSITION_GLYPH (s->cmp, i);
22533
22534 /* TAB in a composition means display glyphs with padding space
22535 on the left or right. */
22536 if (c != '\t')
22537 {
22538 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
22539 -1, Qnil);
22540
22541 face = get_char_face_and_encoding (s->f, c, face_id,
22542 s->char2b + i, 1);
22543 if (face)
22544 {
22545 if (! s->face)
22546 {
22547 s->face = face;
22548 s->font = s->face->font;
22549 }
22550 else if (s->face != face)
22551 break;
22552 }
22553 }
22554 ++s->nchars;
22555 }
22556 s->cmp_to = i;
22557
22558 if (s->face == NULL)
22559 {
22560 s->face = base_face->ascii_face;
22561 s->font = s->face->font;
22562 }
22563
22564 /* All glyph strings for the same composition has the same width,
22565 i.e. the width set for the first component of the composition. */
22566 s->width = s->first_glyph->pixel_width;
22567
22568 /* If the specified font could not be loaded, use the frame's
22569 default font, but record the fact that we couldn't load it in
22570 the glyph string so that we can draw rectangles for the
22571 characters of the glyph string. */
22572 if (s->font == NULL)
22573 {
22574 s->font_not_found_p = 1;
22575 s->font = FRAME_FONT (s->f);
22576 }
22577
22578 /* Adjust base line for subscript/superscript text. */
22579 s->ybase += s->first_glyph->voffset;
22580
22581 /* This glyph string must always be drawn with 16-bit functions. */
22582 s->two_byte_p = 1;
22583
22584 return s->cmp_to;
22585 }
22586
22587 static int
22588 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
22589 int start, int end, int overlaps)
22590 {
22591 struct glyph *glyph, *last;
22592 Lisp_Object lgstring;
22593 int i;
22594
22595 s->for_overlaps = overlaps;
22596 glyph = s->row->glyphs[s->area] + start;
22597 last = s->row->glyphs[s->area] + end;
22598 s->cmp_id = glyph->u.cmp.id;
22599 s->cmp_from = glyph->slice.cmp.from;
22600 s->cmp_to = glyph->slice.cmp.to + 1;
22601 s->face = FACE_FROM_ID (s->f, face_id);
22602 lgstring = composition_gstring_from_id (s->cmp_id);
22603 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
22604 glyph++;
22605 while (glyph < last
22606 && glyph->u.cmp.automatic
22607 && glyph->u.cmp.id == s->cmp_id
22608 && s->cmp_to == glyph->slice.cmp.from)
22609 s->cmp_to = (glyph++)->slice.cmp.to + 1;
22610
22611 for (i = s->cmp_from; i < s->cmp_to; i++)
22612 {
22613 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
22614 unsigned code = LGLYPH_CODE (lglyph);
22615
22616 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
22617 }
22618 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
22619 return glyph - s->row->glyphs[s->area];
22620 }
22621
22622
22623 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22624 See the comment of fill_glyph_string for arguments.
22625 Value is the index of the first glyph not in S. */
22626
22627
22628 static int
22629 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
22630 int start, int end, int overlaps)
22631 {
22632 struct glyph *glyph, *last;
22633 int voffset;
22634
22635 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
22636 s->for_overlaps = overlaps;
22637 glyph = s->row->glyphs[s->area] + start;
22638 last = s->row->glyphs[s->area] + end;
22639 voffset = glyph->voffset;
22640 s->face = FACE_FROM_ID (s->f, face_id);
22641 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
22642 s->nchars = 1;
22643 s->width = glyph->pixel_width;
22644 glyph++;
22645 while (glyph < last
22646 && glyph->type == GLYPHLESS_GLYPH
22647 && glyph->voffset == voffset
22648 && glyph->face_id == face_id)
22649 {
22650 s->nchars++;
22651 s->width += glyph->pixel_width;
22652 glyph++;
22653 }
22654 s->ybase += voffset;
22655 return glyph - s->row->glyphs[s->area];
22656 }
22657
22658
22659 /* Fill glyph string S from a sequence of character glyphs.
22660
22661 FACE_ID is the face id of the string. START is the index of the
22662 first glyph to consider, END is the index of the last + 1.
22663 OVERLAPS non-zero means S should draw the foreground only, and use
22664 its physical height for clipping. See also draw_glyphs.
22665
22666 Value is the index of the first glyph not in S. */
22667
22668 static int
22669 fill_glyph_string (struct glyph_string *s, int face_id,
22670 int start, int end, int overlaps)
22671 {
22672 struct glyph *glyph, *last;
22673 int voffset;
22674 int glyph_not_available_p;
22675
22676 eassert (s->f == XFRAME (s->w->frame));
22677 eassert (s->nchars == 0);
22678 eassert (start >= 0 && end > start);
22679
22680 s->for_overlaps = overlaps;
22681 glyph = s->row->glyphs[s->area] + start;
22682 last = s->row->glyphs[s->area] + end;
22683 voffset = glyph->voffset;
22684 s->padding_p = glyph->padding_p;
22685 glyph_not_available_p = glyph->glyph_not_available_p;
22686
22687 while (glyph < last
22688 && glyph->type == CHAR_GLYPH
22689 && glyph->voffset == voffset
22690 /* Same face id implies same font, nowadays. */
22691 && glyph->face_id == face_id
22692 && glyph->glyph_not_available_p == glyph_not_available_p)
22693 {
22694 int two_byte_p;
22695
22696 s->face = get_glyph_face_and_encoding (s->f, glyph,
22697 s->char2b + s->nchars,
22698 &two_byte_p);
22699 s->two_byte_p = two_byte_p;
22700 ++s->nchars;
22701 eassert (s->nchars <= end - start);
22702 s->width += glyph->pixel_width;
22703 if (glyph++->padding_p != s->padding_p)
22704 break;
22705 }
22706
22707 s->font = s->face->font;
22708
22709 /* If the specified font could not be loaded, use the frame's font,
22710 but record the fact that we couldn't load it in
22711 S->font_not_found_p so that we can draw rectangles for the
22712 characters of the glyph string. */
22713 if (s->font == NULL || glyph_not_available_p)
22714 {
22715 s->font_not_found_p = 1;
22716 s->font = FRAME_FONT (s->f);
22717 }
22718
22719 /* Adjust base line for subscript/superscript text. */
22720 s->ybase += voffset;
22721
22722 eassert (s->face && s->face->gc);
22723 return glyph - s->row->glyphs[s->area];
22724 }
22725
22726
22727 /* Fill glyph string S from image glyph S->first_glyph. */
22728
22729 static void
22730 fill_image_glyph_string (struct glyph_string *s)
22731 {
22732 eassert (s->first_glyph->type == IMAGE_GLYPH);
22733 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
22734 eassert (s->img);
22735 s->slice = s->first_glyph->slice.img;
22736 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22737 s->font = s->face->font;
22738 s->width = s->first_glyph->pixel_width;
22739
22740 /* Adjust base line for subscript/superscript text. */
22741 s->ybase += s->first_glyph->voffset;
22742 }
22743
22744
22745 /* Fill glyph string S from a sequence of stretch glyphs.
22746
22747 START is the index of the first glyph to consider,
22748 END is the index of the last + 1.
22749
22750 Value is the index of the first glyph not in S. */
22751
22752 static int
22753 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
22754 {
22755 struct glyph *glyph, *last;
22756 int voffset, face_id;
22757
22758 eassert (s->first_glyph->type == STRETCH_GLYPH);
22759
22760 glyph = s->row->glyphs[s->area] + start;
22761 last = s->row->glyphs[s->area] + end;
22762 face_id = glyph->face_id;
22763 s->face = FACE_FROM_ID (s->f, face_id);
22764 s->font = s->face->font;
22765 s->width = glyph->pixel_width;
22766 s->nchars = 1;
22767 voffset = glyph->voffset;
22768
22769 for (++glyph;
22770 (glyph < last
22771 && glyph->type == STRETCH_GLYPH
22772 && glyph->voffset == voffset
22773 && glyph->face_id == face_id);
22774 ++glyph)
22775 s->width += glyph->pixel_width;
22776
22777 /* Adjust base line for subscript/superscript text. */
22778 s->ybase += voffset;
22779
22780 /* The case that face->gc == 0 is handled when drawing the glyph
22781 string by calling PREPARE_FACE_FOR_DISPLAY. */
22782 eassert (s->face);
22783 return glyph - s->row->glyphs[s->area];
22784 }
22785
22786 static struct font_metrics *
22787 get_per_char_metric (struct font *font, XChar2b *char2b)
22788 {
22789 static struct font_metrics metrics;
22790 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
22791
22792 if (! font || code == FONT_INVALID_CODE)
22793 return NULL;
22794 font->driver->text_extents (font, &code, 1, &metrics);
22795 return &metrics;
22796 }
22797
22798 /* EXPORT for RIF:
22799 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
22800 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
22801 assumed to be zero. */
22802
22803 void
22804 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
22805 {
22806 *left = *right = 0;
22807
22808 if (glyph->type == CHAR_GLYPH)
22809 {
22810 struct face *face;
22811 XChar2b char2b;
22812 struct font_metrics *pcm;
22813
22814 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
22815 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
22816 {
22817 if (pcm->rbearing > pcm->width)
22818 *right = pcm->rbearing - pcm->width;
22819 if (pcm->lbearing < 0)
22820 *left = -pcm->lbearing;
22821 }
22822 }
22823 else if (glyph->type == COMPOSITE_GLYPH)
22824 {
22825 if (! glyph->u.cmp.automatic)
22826 {
22827 struct composition *cmp = composition_table[glyph->u.cmp.id];
22828
22829 if (cmp->rbearing > cmp->pixel_width)
22830 *right = cmp->rbearing - cmp->pixel_width;
22831 if (cmp->lbearing < 0)
22832 *left = - cmp->lbearing;
22833 }
22834 else
22835 {
22836 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
22837 struct font_metrics metrics;
22838
22839 composition_gstring_width (gstring, glyph->slice.cmp.from,
22840 glyph->slice.cmp.to + 1, &metrics);
22841 if (metrics.rbearing > metrics.width)
22842 *right = metrics.rbearing - metrics.width;
22843 if (metrics.lbearing < 0)
22844 *left = - metrics.lbearing;
22845 }
22846 }
22847 }
22848
22849
22850 /* Return the index of the first glyph preceding glyph string S that
22851 is overwritten by S because of S's left overhang. Value is -1
22852 if no glyphs are overwritten. */
22853
22854 static int
22855 left_overwritten (struct glyph_string *s)
22856 {
22857 int k;
22858
22859 if (s->left_overhang)
22860 {
22861 int x = 0, i;
22862 struct glyph *glyphs = s->row->glyphs[s->area];
22863 int first = s->first_glyph - glyphs;
22864
22865 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
22866 x -= glyphs[i].pixel_width;
22867
22868 k = i + 1;
22869 }
22870 else
22871 k = -1;
22872
22873 return k;
22874 }
22875
22876
22877 /* Return the index of the first glyph preceding glyph string S that
22878 is overwriting S because of its right overhang. Value is -1 if no
22879 glyph in front of S overwrites S. */
22880
22881 static int
22882 left_overwriting (struct glyph_string *s)
22883 {
22884 int i, k, x;
22885 struct glyph *glyphs = s->row->glyphs[s->area];
22886 int first = s->first_glyph - glyphs;
22887
22888 k = -1;
22889 x = 0;
22890 for (i = first - 1; i >= 0; --i)
22891 {
22892 int left, right;
22893 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22894 if (x + right > 0)
22895 k = i;
22896 x -= glyphs[i].pixel_width;
22897 }
22898
22899 return k;
22900 }
22901
22902
22903 /* Return the index of the last glyph following glyph string S that is
22904 overwritten by S because of S's right overhang. Value is -1 if
22905 no such glyph is found. */
22906
22907 static int
22908 right_overwritten (struct glyph_string *s)
22909 {
22910 int k = -1;
22911
22912 if (s->right_overhang)
22913 {
22914 int x = 0, i;
22915 struct glyph *glyphs = s->row->glyphs[s->area];
22916 int first = (s->first_glyph - glyphs
22917 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
22918 int end = s->row->used[s->area];
22919
22920 for (i = first; i < end && s->right_overhang > x; ++i)
22921 x += glyphs[i].pixel_width;
22922
22923 k = i;
22924 }
22925
22926 return k;
22927 }
22928
22929
22930 /* Return the index of the last glyph following glyph string S that
22931 overwrites S because of its left overhang. Value is negative
22932 if no such glyph is found. */
22933
22934 static int
22935 right_overwriting (struct glyph_string *s)
22936 {
22937 int i, k, x;
22938 int end = s->row->used[s->area];
22939 struct glyph *glyphs = s->row->glyphs[s->area];
22940 int first = (s->first_glyph - glyphs
22941 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
22942
22943 k = -1;
22944 x = 0;
22945 for (i = first; i < end; ++i)
22946 {
22947 int left, right;
22948 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22949 if (x - left < 0)
22950 k = i;
22951 x += glyphs[i].pixel_width;
22952 }
22953
22954 return k;
22955 }
22956
22957
22958 /* Set background width of glyph string S. START is the index of the
22959 first glyph following S. LAST_X is the right-most x-position + 1
22960 in the drawing area. */
22961
22962 static void
22963 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
22964 {
22965 /* If the face of this glyph string has to be drawn to the end of
22966 the drawing area, set S->extends_to_end_of_line_p. */
22967
22968 if (start == s->row->used[s->area]
22969 && s->area == TEXT_AREA
22970 && ((s->row->fill_line_p
22971 && (s->hl == DRAW_NORMAL_TEXT
22972 || s->hl == DRAW_IMAGE_RAISED
22973 || s->hl == DRAW_IMAGE_SUNKEN))
22974 || s->hl == DRAW_MOUSE_FACE))
22975 s->extends_to_end_of_line_p = 1;
22976
22977 /* If S extends its face to the end of the line, set its
22978 background_width to the distance to the right edge of the drawing
22979 area. */
22980 if (s->extends_to_end_of_line_p)
22981 s->background_width = last_x - s->x + 1;
22982 else
22983 s->background_width = s->width;
22984 }
22985
22986
22987 /* Compute overhangs and x-positions for glyph string S and its
22988 predecessors, or successors. X is the starting x-position for S.
22989 BACKWARD_P non-zero means process predecessors. */
22990
22991 static void
22992 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
22993 {
22994 if (backward_p)
22995 {
22996 while (s)
22997 {
22998 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22999 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23000 x -= s->width;
23001 s->x = x;
23002 s = s->prev;
23003 }
23004 }
23005 else
23006 {
23007 while (s)
23008 {
23009 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23010 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23011 s->x = x;
23012 x += s->width;
23013 s = s->next;
23014 }
23015 }
23016 }
23017
23018
23019
23020 /* The following macros are only called from draw_glyphs below.
23021 They reference the following parameters of that function directly:
23022 `w', `row', `area', and `overlap_p'
23023 as well as the following local variables:
23024 `s', `f', and `hdc' (in W32) */
23025
23026 #ifdef HAVE_NTGUI
23027 /* On W32, silently add local `hdc' variable to argument list of
23028 init_glyph_string. */
23029 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23030 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23031 #else
23032 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23033 init_glyph_string (s, char2b, w, row, area, start, hl)
23034 #endif
23035
23036 /* Add a glyph string for a stretch glyph to the list of strings
23037 between HEAD and TAIL. START is the index of the stretch glyph in
23038 row area AREA of glyph row ROW. END is the index of the last glyph
23039 in that glyph row area. X is the current output position assigned
23040 to the new glyph string constructed. HL overrides that face of the
23041 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23042 is the right-most x-position of the drawing area. */
23043
23044 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23045 and below -- keep them on one line. */
23046 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23047 do \
23048 { \
23049 s = alloca (sizeof *s); \
23050 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23051 START = fill_stretch_glyph_string (s, START, END); \
23052 append_glyph_string (&HEAD, &TAIL, s); \
23053 s->x = (X); \
23054 } \
23055 while (0)
23056
23057
23058 /* Add a glyph string for an image glyph to the list of strings
23059 between HEAD and TAIL. START is the index of the image glyph in
23060 row area AREA of glyph row ROW. END is the index of the last glyph
23061 in that glyph row area. X is the current output position assigned
23062 to the new glyph string constructed. HL overrides that face of the
23063 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23064 is the right-most x-position of the drawing area. */
23065
23066 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23067 do \
23068 { \
23069 s = alloca (sizeof *s); \
23070 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23071 fill_image_glyph_string (s); \
23072 append_glyph_string (&HEAD, &TAIL, s); \
23073 ++START; \
23074 s->x = (X); \
23075 } \
23076 while (0)
23077
23078
23079 /* Add a glyph string for a sequence of character glyphs to the list
23080 of strings between HEAD and TAIL. START is the index of the first
23081 glyph in row area AREA of glyph row ROW that is part of the new
23082 glyph string. END is the index of the last glyph in that glyph row
23083 area. X is the current output position assigned to the new glyph
23084 string constructed. HL overrides that face of the glyph; e.g. it
23085 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23086 right-most x-position of the drawing area. */
23087
23088 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23089 do \
23090 { \
23091 int face_id; \
23092 XChar2b *char2b; \
23093 \
23094 face_id = (row)->glyphs[area][START].face_id; \
23095 \
23096 s = alloca (sizeof *s); \
23097 char2b = alloca ((END - START) * sizeof *char2b); \
23098 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23099 append_glyph_string (&HEAD, &TAIL, s); \
23100 s->x = (X); \
23101 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23102 } \
23103 while (0)
23104
23105
23106 /* Add a glyph string for a composite sequence to the list of strings
23107 between HEAD and TAIL. START is the index of the first glyph in
23108 row area AREA of glyph row ROW that is part of the new glyph
23109 string. END is the index of the last glyph in that glyph row area.
23110 X is the current output position assigned to the new glyph string
23111 constructed. HL overrides that face of the glyph; e.g. it is
23112 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23113 x-position of the drawing area. */
23114
23115 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23116 do { \
23117 int face_id = (row)->glyphs[area][START].face_id; \
23118 struct face *base_face = FACE_FROM_ID (f, face_id); \
23119 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23120 struct composition *cmp = composition_table[cmp_id]; \
23121 XChar2b *char2b; \
23122 struct glyph_string *first_s = NULL; \
23123 int n; \
23124 \
23125 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23126 \
23127 /* Make glyph_strings for each glyph sequence that is drawable by \
23128 the same face, and append them to HEAD/TAIL. */ \
23129 for (n = 0; n < cmp->glyph_len;) \
23130 { \
23131 s = alloca (sizeof *s); \
23132 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23133 append_glyph_string (&(HEAD), &(TAIL), s); \
23134 s->cmp = cmp; \
23135 s->cmp_from = n; \
23136 s->x = (X); \
23137 if (n == 0) \
23138 first_s = s; \
23139 n = fill_composite_glyph_string (s, base_face, overlaps); \
23140 } \
23141 \
23142 ++START; \
23143 s = first_s; \
23144 } while (0)
23145
23146
23147 /* Add a glyph string for a glyph-string sequence to the list of strings
23148 between HEAD and TAIL. */
23149
23150 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23151 do { \
23152 int face_id; \
23153 XChar2b *char2b; \
23154 Lisp_Object gstring; \
23155 \
23156 face_id = (row)->glyphs[area][START].face_id; \
23157 gstring = (composition_gstring_from_id \
23158 ((row)->glyphs[area][START].u.cmp.id)); \
23159 s = alloca (sizeof *s); \
23160 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23161 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23162 append_glyph_string (&(HEAD), &(TAIL), s); \
23163 s->x = (X); \
23164 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23165 } while (0)
23166
23167
23168 /* Add a glyph string for a sequence of glyphless character's glyphs
23169 to the list of strings between HEAD and TAIL. The meanings of
23170 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23171
23172 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23173 do \
23174 { \
23175 int face_id; \
23176 \
23177 face_id = (row)->glyphs[area][START].face_id; \
23178 \
23179 s = alloca (sizeof *s); \
23180 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23181 append_glyph_string (&HEAD, &TAIL, s); \
23182 s->x = (X); \
23183 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23184 overlaps); \
23185 } \
23186 while (0)
23187
23188
23189 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23190 of AREA of glyph row ROW on window W between indices START and END.
23191 HL overrides the face for drawing glyph strings, e.g. it is
23192 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23193 x-positions of the drawing area.
23194
23195 This is an ugly monster macro construct because we must use alloca
23196 to allocate glyph strings (because draw_glyphs can be called
23197 asynchronously). */
23198
23199 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23200 do \
23201 { \
23202 HEAD = TAIL = NULL; \
23203 while (START < END) \
23204 { \
23205 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23206 switch (first_glyph->type) \
23207 { \
23208 case CHAR_GLYPH: \
23209 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23210 HL, X, LAST_X); \
23211 break; \
23212 \
23213 case COMPOSITE_GLYPH: \
23214 if (first_glyph->u.cmp.automatic) \
23215 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23216 HL, X, LAST_X); \
23217 else \
23218 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23219 HL, X, LAST_X); \
23220 break; \
23221 \
23222 case STRETCH_GLYPH: \
23223 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23224 HL, X, LAST_X); \
23225 break; \
23226 \
23227 case IMAGE_GLYPH: \
23228 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23229 HL, X, LAST_X); \
23230 break; \
23231 \
23232 case GLYPHLESS_GLYPH: \
23233 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23234 HL, X, LAST_X); \
23235 break; \
23236 \
23237 default: \
23238 emacs_abort (); \
23239 } \
23240 \
23241 if (s) \
23242 { \
23243 set_glyph_string_background_width (s, START, LAST_X); \
23244 (X) += s->width; \
23245 } \
23246 } \
23247 } while (0)
23248
23249
23250 /* Draw glyphs between START and END in AREA of ROW on window W,
23251 starting at x-position X. X is relative to AREA in W. HL is a
23252 face-override with the following meaning:
23253
23254 DRAW_NORMAL_TEXT draw normally
23255 DRAW_CURSOR draw in cursor face
23256 DRAW_MOUSE_FACE draw in mouse face.
23257 DRAW_INVERSE_VIDEO draw in mode line face
23258 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23259 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23260
23261 If OVERLAPS is non-zero, draw only the foreground of characters and
23262 clip to the physical height of ROW. Non-zero value also defines
23263 the overlapping part to be drawn:
23264
23265 OVERLAPS_PRED overlap with preceding rows
23266 OVERLAPS_SUCC overlap with succeeding rows
23267 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23268 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23269
23270 Value is the x-position reached, relative to AREA of W. */
23271
23272 static int
23273 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23274 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23275 enum draw_glyphs_face hl, int overlaps)
23276 {
23277 struct glyph_string *head, *tail;
23278 struct glyph_string *s;
23279 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23280 int i, j, x_reached, last_x, area_left = 0;
23281 struct frame *f = XFRAME (WINDOW_FRAME (w));
23282 DECLARE_HDC (hdc);
23283
23284 ALLOCATE_HDC (hdc, f);
23285
23286 /* Let's rather be paranoid than getting a SEGV. */
23287 end = min (end, row->used[area]);
23288 start = clip_to_bounds (0, start, end);
23289
23290 /* Translate X to frame coordinates. Set last_x to the right
23291 end of the drawing area. */
23292 if (row->full_width_p)
23293 {
23294 /* X is relative to the left edge of W, without scroll bars
23295 or fringes. */
23296 area_left = WINDOW_LEFT_EDGE_X (w);
23297 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23298 }
23299 else
23300 {
23301 area_left = window_box_left (w, area);
23302 last_x = area_left + window_box_width (w, area);
23303 }
23304 x += area_left;
23305
23306 /* Build a doubly-linked list of glyph_string structures between
23307 head and tail from what we have to draw. Note that the macro
23308 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23309 the reason we use a separate variable `i'. */
23310 i = start;
23311 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23312 if (tail)
23313 x_reached = tail->x + tail->background_width;
23314 else
23315 x_reached = x;
23316
23317 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23318 the row, redraw some glyphs in front or following the glyph
23319 strings built above. */
23320 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23321 {
23322 struct glyph_string *h, *t;
23323 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23324 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23325 int check_mouse_face = 0;
23326 int dummy_x = 0;
23327
23328 /* If mouse highlighting is on, we may need to draw adjacent
23329 glyphs using mouse-face highlighting. */
23330 if (area == TEXT_AREA && row->mouse_face_p
23331 && hlinfo->mouse_face_beg_row >= 0
23332 && hlinfo->mouse_face_end_row >= 0)
23333 {
23334 struct glyph_row *mouse_beg_row, *mouse_end_row;
23335
23336 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23337 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23338
23339 if (row >= mouse_beg_row && row <= mouse_end_row)
23340 {
23341 check_mouse_face = 1;
23342 mouse_beg_col = (row == mouse_beg_row)
23343 ? hlinfo->mouse_face_beg_col : 0;
23344 mouse_end_col = (row == mouse_end_row)
23345 ? hlinfo->mouse_face_end_col
23346 : row->used[TEXT_AREA];
23347 }
23348 }
23349
23350 /* Compute overhangs for all glyph strings. */
23351 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23352 for (s = head; s; s = s->next)
23353 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23354
23355 /* Prepend glyph strings for glyphs in front of the first glyph
23356 string that are overwritten because of the first glyph
23357 string's left overhang. The background of all strings
23358 prepended must be drawn because the first glyph string
23359 draws over it. */
23360 i = left_overwritten (head);
23361 if (i >= 0)
23362 {
23363 enum draw_glyphs_face overlap_hl;
23364
23365 /* If this row contains mouse highlighting, attempt to draw
23366 the overlapped glyphs with the correct highlight. This
23367 code fails if the overlap encompasses more than one glyph
23368 and mouse-highlight spans only some of these glyphs.
23369 However, making it work perfectly involves a lot more
23370 code, and I don't know if the pathological case occurs in
23371 practice, so we'll stick to this for now. --- cyd */
23372 if (check_mouse_face
23373 && mouse_beg_col < start && mouse_end_col > i)
23374 overlap_hl = DRAW_MOUSE_FACE;
23375 else
23376 overlap_hl = DRAW_NORMAL_TEXT;
23377
23378 j = i;
23379 BUILD_GLYPH_STRINGS (j, start, h, t,
23380 overlap_hl, dummy_x, last_x);
23381 start = i;
23382 compute_overhangs_and_x (t, head->x, 1);
23383 prepend_glyph_string_lists (&head, &tail, h, t);
23384 clip_head = head;
23385 }
23386
23387 /* Prepend glyph strings for glyphs in front of the first glyph
23388 string that overwrite that glyph string because of their
23389 right overhang. For these strings, only the foreground must
23390 be drawn, because it draws over the glyph string at `head'.
23391 The background must not be drawn because this would overwrite
23392 right overhangs of preceding glyphs for which no glyph
23393 strings exist. */
23394 i = left_overwriting (head);
23395 if (i >= 0)
23396 {
23397 enum draw_glyphs_face overlap_hl;
23398
23399 if (check_mouse_face
23400 && mouse_beg_col < start && mouse_end_col > i)
23401 overlap_hl = DRAW_MOUSE_FACE;
23402 else
23403 overlap_hl = DRAW_NORMAL_TEXT;
23404
23405 clip_head = head;
23406 BUILD_GLYPH_STRINGS (i, start, h, t,
23407 overlap_hl, dummy_x, last_x);
23408 for (s = h; s; s = s->next)
23409 s->background_filled_p = 1;
23410 compute_overhangs_and_x (t, head->x, 1);
23411 prepend_glyph_string_lists (&head, &tail, h, t);
23412 }
23413
23414 /* Append glyphs strings for glyphs following the last glyph
23415 string tail that are overwritten by tail. The background of
23416 these strings has to be drawn because tail's foreground draws
23417 over it. */
23418 i = right_overwritten (tail);
23419 if (i >= 0)
23420 {
23421 enum draw_glyphs_face overlap_hl;
23422
23423 if (check_mouse_face
23424 && mouse_beg_col < i && mouse_end_col > end)
23425 overlap_hl = DRAW_MOUSE_FACE;
23426 else
23427 overlap_hl = DRAW_NORMAL_TEXT;
23428
23429 BUILD_GLYPH_STRINGS (end, i, h, t,
23430 overlap_hl, x, last_x);
23431 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23432 we don't have `end = i;' here. */
23433 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23434 append_glyph_string_lists (&head, &tail, h, t);
23435 clip_tail = tail;
23436 }
23437
23438 /* Append glyph strings for glyphs following the last glyph
23439 string tail that overwrite tail. The foreground of such
23440 glyphs has to be drawn because it writes into the background
23441 of tail. The background must not be drawn because it could
23442 paint over the foreground of following glyphs. */
23443 i = right_overwriting (tail);
23444 if (i >= 0)
23445 {
23446 enum draw_glyphs_face overlap_hl;
23447 if (check_mouse_face
23448 && mouse_beg_col < i && mouse_end_col > end)
23449 overlap_hl = DRAW_MOUSE_FACE;
23450 else
23451 overlap_hl = DRAW_NORMAL_TEXT;
23452
23453 clip_tail = tail;
23454 i++; /* We must include the Ith glyph. */
23455 BUILD_GLYPH_STRINGS (end, i, h, t,
23456 overlap_hl, x, last_x);
23457 for (s = h; s; s = s->next)
23458 s->background_filled_p = 1;
23459 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23460 append_glyph_string_lists (&head, &tail, h, t);
23461 }
23462 if (clip_head || clip_tail)
23463 for (s = head; s; s = s->next)
23464 {
23465 s->clip_head = clip_head;
23466 s->clip_tail = clip_tail;
23467 }
23468 }
23469
23470 /* Draw all strings. */
23471 for (s = head; s; s = s->next)
23472 FRAME_RIF (f)->draw_glyph_string (s);
23473
23474 #ifndef HAVE_NS
23475 /* When focus a sole frame and move horizontally, this sets on_p to 0
23476 causing a failure to erase prev cursor position. */
23477 if (area == TEXT_AREA
23478 && !row->full_width_p
23479 /* When drawing overlapping rows, only the glyph strings'
23480 foreground is drawn, which doesn't erase a cursor
23481 completely. */
23482 && !overlaps)
23483 {
23484 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23485 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23486 : (tail ? tail->x + tail->background_width : x));
23487 x0 -= area_left;
23488 x1 -= area_left;
23489
23490 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23491 row->y, MATRIX_ROW_BOTTOM_Y (row));
23492 }
23493 #endif
23494
23495 /* Value is the x-position up to which drawn, relative to AREA of W.
23496 This doesn't include parts drawn because of overhangs. */
23497 if (row->full_width_p)
23498 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23499 else
23500 x_reached -= area_left;
23501
23502 RELEASE_HDC (hdc, f);
23503
23504 return x_reached;
23505 }
23506
23507 /* Expand row matrix if too narrow. Don't expand if area
23508 is not present. */
23509
23510 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23511 { \
23512 if (!fonts_changed_p \
23513 && (it->glyph_row->glyphs[area] \
23514 < it->glyph_row->glyphs[area + 1])) \
23515 { \
23516 it->w->ncols_scale_factor++; \
23517 fonts_changed_p = 1; \
23518 } \
23519 }
23520
23521 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23522 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23523
23524 static void
23525 append_glyph (struct it *it)
23526 {
23527 struct glyph *glyph;
23528 enum glyph_row_area area = it->area;
23529
23530 eassert (it->glyph_row);
23531 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23532
23533 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23534 if (glyph < it->glyph_row->glyphs[area + 1])
23535 {
23536 /* If the glyph row is reversed, we need to prepend the glyph
23537 rather than append it. */
23538 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23539 {
23540 struct glyph *g;
23541
23542 /* Make room for the additional glyph. */
23543 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23544 g[1] = *g;
23545 glyph = it->glyph_row->glyphs[area];
23546 }
23547 glyph->charpos = CHARPOS (it->position);
23548 glyph->object = it->object;
23549 if (it->pixel_width > 0)
23550 {
23551 glyph->pixel_width = it->pixel_width;
23552 glyph->padding_p = 0;
23553 }
23554 else
23555 {
23556 /* Assure at least 1-pixel width. Otherwise, cursor can't
23557 be displayed correctly. */
23558 glyph->pixel_width = 1;
23559 glyph->padding_p = 1;
23560 }
23561 glyph->ascent = it->ascent;
23562 glyph->descent = it->descent;
23563 glyph->voffset = it->voffset;
23564 glyph->type = CHAR_GLYPH;
23565 glyph->avoid_cursor_p = it->avoid_cursor_p;
23566 glyph->multibyte_p = it->multibyte_p;
23567 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23568 {
23569 /* In R2L rows, the left and the right box edges need to be
23570 drawn in reverse direction. */
23571 glyph->right_box_line_p = it->start_of_box_run_p;
23572 glyph->left_box_line_p = it->end_of_box_run_p;
23573 }
23574 else
23575 {
23576 glyph->left_box_line_p = it->start_of_box_run_p;
23577 glyph->right_box_line_p = it->end_of_box_run_p;
23578 }
23579 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23580 || it->phys_descent > it->descent);
23581 glyph->glyph_not_available_p = it->glyph_not_available_p;
23582 glyph->face_id = it->face_id;
23583 glyph->u.ch = it->char_to_display;
23584 glyph->slice.img = null_glyph_slice;
23585 glyph->font_type = FONT_TYPE_UNKNOWN;
23586 if (it->bidi_p)
23587 {
23588 glyph->resolved_level = it->bidi_it.resolved_level;
23589 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23590 emacs_abort ();
23591 glyph->bidi_type = it->bidi_it.type;
23592 }
23593 else
23594 {
23595 glyph->resolved_level = 0;
23596 glyph->bidi_type = UNKNOWN_BT;
23597 }
23598 ++it->glyph_row->used[area];
23599 }
23600 else
23601 IT_EXPAND_MATRIX_WIDTH (it, area);
23602 }
23603
23604 /* Store one glyph for the composition IT->cmp_it.id in
23605 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23606 non-null. */
23607
23608 static void
23609 append_composite_glyph (struct it *it)
23610 {
23611 struct glyph *glyph;
23612 enum glyph_row_area area = it->area;
23613
23614 eassert (it->glyph_row);
23615
23616 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23617 if (glyph < it->glyph_row->glyphs[area + 1])
23618 {
23619 /* If the glyph row is reversed, we need to prepend the glyph
23620 rather than append it. */
23621 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
23622 {
23623 struct glyph *g;
23624
23625 /* Make room for the new glyph. */
23626 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
23627 g[1] = *g;
23628 glyph = it->glyph_row->glyphs[it->area];
23629 }
23630 glyph->charpos = it->cmp_it.charpos;
23631 glyph->object = it->object;
23632 glyph->pixel_width = it->pixel_width;
23633 glyph->ascent = it->ascent;
23634 glyph->descent = it->descent;
23635 glyph->voffset = it->voffset;
23636 glyph->type = COMPOSITE_GLYPH;
23637 if (it->cmp_it.ch < 0)
23638 {
23639 glyph->u.cmp.automatic = 0;
23640 glyph->u.cmp.id = it->cmp_it.id;
23641 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
23642 }
23643 else
23644 {
23645 glyph->u.cmp.automatic = 1;
23646 glyph->u.cmp.id = it->cmp_it.id;
23647 glyph->slice.cmp.from = it->cmp_it.from;
23648 glyph->slice.cmp.to = it->cmp_it.to - 1;
23649 }
23650 glyph->avoid_cursor_p = it->avoid_cursor_p;
23651 glyph->multibyte_p = it->multibyte_p;
23652 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23653 {
23654 /* In R2L rows, the left and the right box edges need to be
23655 drawn in reverse direction. */
23656 glyph->right_box_line_p = it->start_of_box_run_p;
23657 glyph->left_box_line_p = it->end_of_box_run_p;
23658 }
23659 else
23660 {
23661 glyph->left_box_line_p = it->start_of_box_run_p;
23662 glyph->right_box_line_p = it->end_of_box_run_p;
23663 }
23664 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23665 || it->phys_descent > it->descent);
23666 glyph->padding_p = 0;
23667 glyph->glyph_not_available_p = 0;
23668 glyph->face_id = it->face_id;
23669 glyph->font_type = FONT_TYPE_UNKNOWN;
23670 if (it->bidi_p)
23671 {
23672 glyph->resolved_level = it->bidi_it.resolved_level;
23673 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23674 emacs_abort ();
23675 glyph->bidi_type = it->bidi_it.type;
23676 }
23677 ++it->glyph_row->used[area];
23678 }
23679 else
23680 IT_EXPAND_MATRIX_WIDTH (it, area);
23681 }
23682
23683
23684 /* Change IT->ascent and IT->height according to the setting of
23685 IT->voffset. */
23686
23687 static void
23688 take_vertical_position_into_account (struct it *it)
23689 {
23690 if (it->voffset)
23691 {
23692 if (it->voffset < 0)
23693 /* Increase the ascent so that we can display the text higher
23694 in the line. */
23695 it->ascent -= it->voffset;
23696 else
23697 /* Increase the descent so that we can display the text lower
23698 in the line. */
23699 it->descent += it->voffset;
23700 }
23701 }
23702
23703
23704 /* Produce glyphs/get display metrics for the image IT is loaded with.
23705 See the description of struct display_iterator in dispextern.h for
23706 an overview of struct display_iterator. */
23707
23708 static void
23709 produce_image_glyph (struct it *it)
23710 {
23711 struct image *img;
23712 struct face *face;
23713 int glyph_ascent, crop;
23714 struct glyph_slice slice;
23715
23716 eassert (it->what == IT_IMAGE);
23717
23718 face = FACE_FROM_ID (it->f, it->face_id);
23719 eassert (face);
23720 /* Make sure X resources of the face is loaded. */
23721 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23722
23723 if (it->image_id < 0)
23724 {
23725 /* Fringe bitmap. */
23726 it->ascent = it->phys_ascent = 0;
23727 it->descent = it->phys_descent = 0;
23728 it->pixel_width = 0;
23729 it->nglyphs = 0;
23730 return;
23731 }
23732
23733 img = IMAGE_FROM_ID (it->f, it->image_id);
23734 eassert (img);
23735 /* Make sure X resources of the image is loaded. */
23736 prepare_image_for_display (it->f, img);
23737
23738 slice.x = slice.y = 0;
23739 slice.width = img->width;
23740 slice.height = img->height;
23741
23742 if (INTEGERP (it->slice.x))
23743 slice.x = XINT (it->slice.x);
23744 else if (FLOATP (it->slice.x))
23745 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
23746
23747 if (INTEGERP (it->slice.y))
23748 slice.y = XINT (it->slice.y);
23749 else if (FLOATP (it->slice.y))
23750 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
23751
23752 if (INTEGERP (it->slice.width))
23753 slice.width = XINT (it->slice.width);
23754 else if (FLOATP (it->slice.width))
23755 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
23756
23757 if (INTEGERP (it->slice.height))
23758 slice.height = XINT (it->slice.height);
23759 else if (FLOATP (it->slice.height))
23760 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
23761
23762 if (slice.x >= img->width)
23763 slice.x = img->width;
23764 if (slice.y >= img->height)
23765 slice.y = img->height;
23766 if (slice.x + slice.width >= img->width)
23767 slice.width = img->width - slice.x;
23768 if (slice.y + slice.height > img->height)
23769 slice.height = img->height - slice.y;
23770
23771 if (slice.width == 0 || slice.height == 0)
23772 return;
23773
23774 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
23775
23776 it->descent = slice.height - glyph_ascent;
23777 if (slice.y == 0)
23778 it->descent += img->vmargin;
23779 if (slice.y + slice.height == img->height)
23780 it->descent += img->vmargin;
23781 it->phys_descent = it->descent;
23782
23783 it->pixel_width = slice.width;
23784 if (slice.x == 0)
23785 it->pixel_width += img->hmargin;
23786 if (slice.x + slice.width == img->width)
23787 it->pixel_width += img->hmargin;
23788
23789 /* It's quite possible for images to have an ascent greater than
23790 their height, so don't get confused in that case. */
23791 if (it->descent < 0)
23792 it->descent = 0;
23793
23794 it->nglyphs = 1;
23795
23796 if (face->box != FACE_NO_BOX)
23797 {
23798 if (face->box_line_width > 0)
23799 {
23800 if (slice.y == 0)
23801 it->ascent += face->box_line_width;
23802 if (slice.y + slice.height == img->height)
23803 it->descent += face->box_line_width;
23804 }
23805
23806 if (it->start_of_box_run_p && slice.x == 0)
23807 it->pixel_width += eabs (face->box_line_width);
23808 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
23809 it->pixel_width += eabs (face->box_line_width);
23810 }
23811
23812 take_vertical_position_into_account (it);
23813
23814 /* Automatically crop wide image glyphs at right edge so we can
23815 draw the cursor on same display row. */
23816 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
23817 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
23818 {
23819 it->pixel_width -= crop;
23820 slice.width -= crop;
23821 }
23822
23823 if (it->glyph_row)
23824 {
23825 struct glyph *glyph;
23826 enum glyph_row_area area = it->area;
23827
23828 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23829 if (glyph < it->glyph_row->glyphs[area + 1])
23830 {
23831 glyph->charpos = CHARPOS (it->position);
23832 glyph->object = it->object;
23833 glyph->pixel_width = it->pixel_width;
23834 glyph->ascent = glyph_ascent;
23835 glyph->descent = it->descent;
23836 glyph->voffset = it->voffset;
23837 glyph->type = IMAGE_GLYPH;
23838 glyph->avoid_cursor_p = it->avoid_cursor_p;
23839 glyph->multibyte_p = it->multibyte_p;
23840 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23841 {
23842 /* In R2L rows, the left and the right box edges need to be
23843 drawn in reverse direction. */
23844 glyph->right_box_line_p = it->start_of_box_run_p;
23845 glyph->left_box_line_p = it->end_of_box_run_p;
23846 }
23847 else
23848 {
23849 glyph->left_box_line_p = it->start_of_box_run_p;
23850 glyph->right_box_line_p = it->end_of_box_run_p;
23851 }
23852 glyph->overlaps_vertically_p = 0;
23853 glyph->padding_p = 0;
23854 glyph->glyph_not_available_p = 0;
23855 glyph->face_id = it->face_id;
23856 glyph->u.img_id = img->id;
23857 glyph->slice.img = slice;
23858 glyph->font_type = FONT_TYPE_UNKNOWN;
23859 if (it->bidi_p)
23860 {
23861 glyph->resolved_level = it->bidi_it.resolved_level;
23862 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23863 emacs_abort ();
23864 glyph->bidi_type = it->bidi_it.type;
23865 }
23866 ++it->glyph_row->used[area];
23867 }
23868 else
23869 IT_EXPAND_MATRIX_WIDTH (it, area);
23870 }
23871 }
23872
23873
23874 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23875 of the glyph, WIDTH and HEIGHT are the width and height of the
23876 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23877
23878 static void
23879 append_stretch_glyph (struct it *it, Lisp_Object object,
23880 int width, int height, int ascent)
23881 {
23882 struct glyph *glyph;
23883 enum glyph_row_area area = it->area;
23884
23885 eassert (ascent >= 0 && ascent <= height);
23886
23887 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23888 if (glyph < it->glyph_row->glyphs[area + 1])
23889 {
23890 /* If the glyph row is reversed, we need to prepend the glyph
23891 rather than append it. */
23892 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23893 {
23894 struct glyph *g;
23895
23896 /* Make room for the additional glyph. */
23897 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23898 g[1] = *g;
23899 glyph = it->glyph_row->glyphs[area];
23900 }
23901 glyph->charpos = CHARPOS (it->position);
23902 glyph->object = object;
23903 glyph->pixel_width = width;
23904 glyph->ascent = ascent;
23905 glyph->descent = height - ascent;
23906 glyph->voffset = it->voffset;
23907 glyph->type = STRETCH_GLYPH;
23908 glyph->avoid_cursor_p = it->avoid_cursor_p;
23909 glyph->multibyte_p = it->multibyte_p;
23910 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23911 {
23912 /* In R2L rows, the left and the right box edges need to be
23913 drawn in reverse direction. */
23914 glyph->right_box_line_p = it->start_of_box_run_p;
23915 glyph->left_box_line_p = it->end_of_box_run_p;
23916 }
23917 else
23918 {
23919 glyph->left_box_line_p = it->start_of_box_run_p;
23920 glyph->right_box_line_p = it->end_of_box_run_p;
23921 }
23922 glyph->overlaps_vertically_p = 0;
23923 glyph->padding_p = 0;
23924 glyph->glyph_not_available_p = 0;
23925 glyph->face_id = it->face_id;
23926 glyph->u.stretch.ascent = ascent;
23927 glyph->u.stretch.height = height;
23928 glyph->slice.img = null_glyph_slice;
23929 glyph->font_type = FONT_TYPE_UNKNOWN;
23930 if (it->bidi_p)
23931 {
23932 glyph->resolved_level = it->bidi_it.resolved_level;
23933 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23934 emacs_abort ();
23935 glyph->bidi_type = it->bidi_it.type;
23936 }
23937 else
23938 {
23939 glyph->resolved_level = 0;
23940 glyph->bidi_type = UNKNOWN_BT;
23941 }
23942 ++it->glyph_row->used[area];
23943 }
23944 else
23945 IT_EXPAND_MATRIX_WIDTH (it, area);
23946 }
23947
23948 #endif /* HAVE_WINDOW_SYSTEM */
23949
23950 /* Produce a stretch glyph for iterator IT. IT->object is the value
23951 of the glyph property displayed. The value must be a list
23952 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
23953 being recognized:
23954
23955 1. `:width WIDTH' specifies that the space should be WIDTH *
23956 canonical char width wide. WIDTH may be an integer or floating
23957 point number.
23958
23959 2. `:relative-width FACTOR' specifies that the width of the stretch
23960 should be computed from the width of the first character having the
23961 `glyph' property, and should be FACTOR times that width.
23962
23963 3. `:align-to HPOS' specifies that the space should be wide enough
23964 to reach HPOS, a value in canonical character units.
23965
23966 Exactly one of the above pairs must be present.
23967
23968 4. `:height HEIGHT' specifies that the height of the stretch produced
23969 should be HEIGHT, measured in canonical character units.
23970
23971 5. `:relative-height FACTOR' specifies that the height of the
23972 stretch should be FACTOR times the height of the characters having
23973 the glyph property.
23974
23975 Either none or exactly one of 4 or 5 must be present.
23976
23977 6. `:ascent ASCENT' specifies that ASCENT percent of the height
23978 of the stretch should be used for the ascent of the stretch.
23979 ASCENT must be in the range 0 <= ASCENT <= 100. */
23980
23981 void
23982 produce_stretch_glyph (struct it *it)
23983 {
23984 /* (space :width WIDTH :height HEIGHT ...) */
23985 Lisp_Object prop, plist;
23986 int width = 0, height = 0, align_to = -1;
23987 int zero_width_ok_p = 0;
23988 double tem;
23989 struct font *font = NULL;
23990
23991 #ifdef HAVE_WINDOW_SYSTEM
23992 int ascent = 0;
23993 int zero_height_ok_p = 0;
23994
23995 if (FRAME_WINDOW_P (it->f))
23996 {
23997 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23998 font = face->font ? face->font : FRAME_FONT (it->f);
23999 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24000 }
24001 #endif
24002
24003 /* List should start with `space'. */
24004 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24005 plist = XCDR (it->object);
24006
24007 /* Compute the width of the stretch. */
24008 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24009 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24010 {
24011 /* Absolute width `:width WIDTH' specified and valid. */
24012 zero_width_ok_p = 1;
24013 width = (int)tem;
24014 }
24015 #ifdef HAVE_WINDOW_SYSTEM
24016 else if (FRAME_WINDOW_P (it->f)
24017 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24018 {
24019 /* Relative width `:relative-width FACTOR' specified and valid.
24020 Compute the width of the characters having the `glyph'
24021 property. */
24022 struct it it2;
24023 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24024
24025 it2 = *it;
24026 if (it->multibyte_p)
24027 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24028 else
24029 {
24030 it2.c = it2.char_to_display = *p, it2.len = 1;
24031 if (! ASCII_CHAR_P (it2.c))
24032 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24033 }
24034
24035 it2.glyph_row = NULL;
24036 it2.what = IT_CHARACTER;
24037 x_produce_glyphs (&it2);
24038 width = NUMVAL (prop) * it2.pixel_width;
24039 }
24040 #endif /* HAVE_WINDOW_SYSTEM */
24041 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24042 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24043 {
24044 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24045 align_to = (align_to < 0
24046 ? 0
24047 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24048 else if (align_to < 0)
24049 align_to = window_box_left_offset (it->w, TEXT_AREA);
24050 width = max (0, (int)tem + align_to - it->current_x);
24051 zero_width_ok_p = 1;
24052 }
24053 else
24054 /* Nothing specified -> width defaults to canonical char width. */
24055 width = FRAME_COLUMN_WIDTH (it->f);
24056
24057 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24058 width = 1;
24059
24060 #ifdef HAVE_WINDOW_SYSTEM
24061 /* Compute height. */
24062 if (FRAME_WINDOW_P (it->f))
24063 {
24064 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24065 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24066 {
24067 height = (int)tem;
24068 zero_height_ok_p = 1;
24069 }
24070 else if (prop = Fplist_get (plist, QCrelative_height),
24071 NUMVAL (prop) > 0)
24072 height = FONT_HEIGHT (font) * NUMVAL (prop);
24073 else
24074 height = FONT_HEIGHT (font);
24075
24076 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24077 height = 1;
24078
24079 /* Compute percentage of height used for ascent. If
24080 `:ascent ASCENT' is present and valid, use that. Otherwise,
24081 derive the ascent from the font in use. */
24082 if (prop = Fplist_get (plist, QCascent),
24083 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24084 ascent = height * NUMVAL (prop) / 100.0;
24085 else if (!NILP (prop)
24086 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24087 ascent = min (max (0, (int)tem), height);
24088 else
24089 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24090 }
24091 else
24092 #endif /* HAVE_WINDOW_SYSTEM */
24093 height = 1;
24094
24095 if (width > 0 && it->line_wrap != TRUNCATE
24096 && it->current_x + width > it->last_visible_x)
24097 {
24098 width = it->last_visible_x - it->current_x;
24099 #ifdef HAVE_WINDOW_SYSTEM
24100 /* Subtract one more pixel from the stretch width, but only on
24101 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24102 width -= FRAME_WINDOW_P (it->f);
24103 #endif
24104 }
24105
24106 if (width > 0 && height > 0 && it->glyph_row)
24107 {
24108 Lisp_Object o_object = it->object;
24109 Lisp_Object object = it->stack[it->sp - 1].string;
24110 int n = width;
24111
24112 if (!STRINGP (object))
24113 object = it->w->buffer;
24114 #ifdef HAVE_WINDOW_SYSTEM
24115 if (FRAME_WINDOW_P (it->f))
24116 append_stretch_glyph (it, object, width, height, ascent);
24117 else
24118 #endif
24119 {
24120 it->object = object;
24121 it->char_to_display = ' ';
24122 it->pixel_width = it->len = 1;
24123 while (n--)
24124 tty_append_glyph (it);
24125 it->object = o_object;
24126 }
24127 }
24128
24129 it->pixel_width = width;
24130 #ifdef HAVE_WINDOW_SYSTEM
24131 if (FRAME_WINDOW_P (it->f))
24132 {
24133 it->ascent = it->phys_ascent = ascent;
24134 it->descent = it->phys_descent = height - it->ascent;
24135 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24136 take_vertical_position_into_account (it);
24137 }
24138 else
24139 #endif
24140 it->nglyphs = width;
24141 }
24142
24143 /* Get information about special display element WHAT in an
24144 environment described by IT. WHAT is one of IT_TRUNCATION or
24145 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24146 non-null glyph_row member. This function ensures that fields like
24147 face_id, c, len of IT are left untouched. */
24148
24149 static void
24150 produce_special_glyphs (struct it *it, enum display_element_type what)
24151 {
24152 struct it temp_it;
24153 Lisp_Object gc;
24154 GLYPH glyph;
24155
24156 temp_it = *it;
24157 temp_it.object = make_number (0);
24158 memset (&temp_it.current, 0, sizeof temp_it.current);
24159
24160 if (what == IT_CONTINUATION)
24161 {
24162 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24163 if (it->bidi_it.paragraph_dir == R2L)
24164 SET_GLYPH_FROM_CHAR (glyph, '/');
24165 else
24166 SET_GLYPH_FROM_CHAR (glyph, '\\');
24167 if (it->dp
24168 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24169 {
24170 /* FIXME: Should we mirror GC for R2L lines? */
24171 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24172 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24173 }
24174 }
24175 else if (what == IT_TRUNCATION)
24176 {
24177 /* Truncation glyph. */
24178 SET_GLYPH_FROM_CHAR (glyph, '$');
24179 if (it->dp
24180 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24181 {
24182 /* FIXME: Should we mirror GC for R2L lines? */
24183 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24184 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24185 }
24186 }
24187 else
24188 emacs_abort ();
24189
24190 #ifdef HAVE_WINDOW_SYSTEM
24191 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24192 is turned off, we precede the truncation/continuation glyphs by a
24193 stretch glyph whose width is computed such that these special
24194 glyphs are aligned at the window margin, even when very different
24195 fonts are used in different glyph rows. */
24196 if (FRAME_WINDOW_P (temp_it.f)
24197 /* init_iterator calls this with it->glyph_row == NULL, and it
24198 wants only the pixel width of the truncation/continuation
24199 glyphs. */
24200 && temp_it.glyph_row
24201 /* insert_left_trunc_glyphs calls us at the beginning of the
24202 row, and it has its own calculation of the stretch glyph
24203 width. */
24204 && temp_it.glyph_row->used[TEXT_AREA] > 0
24205 && (temp_it.glyph_row->reversed_p
24206 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24207 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24208 {
24209 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24210
24211 if (stretch_width > 0)
24212 {
24213 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24214 struct font *font =
24215 face->font ? face->font : FRAME_FONT (temp_it.f);
24216 int stretch_ascent =
24217 (((temp_it.ascent + temp_it.descent)
24218 * FONT_BASE (font)) / FONT_HEIGHT (font));
24219
24220 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24221 temp_it.ascent + temp_it.descent,
24222 stretch_ascent);
24223 }
24224 }
24225 #endif
24226
24227 temp_it.dp = NULL;
24228 temp_it.what = IT_CHARACTER;
24229 temp_it.len = 1;
24230 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24231 temp_it.face_id = GLYPH_FACE (glyph);
24232 temp_it.len = CHAR_BYTES (temp_it.c);
24233
24234 PRODUCE_GLYPHS (&temp_it);
24235 it->pixel_width = temp_it.pixel_width;
24236 it->nglyphs = temp_it.pixel_width;
24237 }
24238
24239 #ifdef HAVE_WINDOW_SYSTEM
24240
24241 /* Calculate line-height and line-spacing properties.
24242 An integer value specifies explicit pixel value.
24243 A float value specifies relative value to current face height.
24244 A cons (float . face-name) specifies relative value to
24245 height of specified face font.
24246
24247 Returns height in pixels, or nil. */
24248
24249
24250 static Lisp_Object
24251 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24252 int boff, int override)
24253 {
24254 Lisp_Object face_name = Qnil;
24255 int ascent, descent, height;
24256
24257 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24258 return val;
24259
24260 if (CONSP (val))
24261 {
24262 face_name = XCAR (val);
24263 val = XCDR (val);
24264 if (!NUMBERP (val))
24265 val = make_number (1);
24266 if (NILP (face_name))
24267 {
24268 height = it->ascent + it->descent;
24269 goto scale;
24270 }
24271 }
24272
24273 if (NILP (face_name))
24274 {
24275 font = FRAME_FONT (it->f);
24276 boff = FRAME_BASELINE_OFFSET (it->f);
24277 }
24278 else if (EQ (face_name, Qt))
24279 {
24280 override = 0;
24281 }
24282 else
24283 {
24284 int face_id;
24285 struct face *face;
24286
24287 face_id = lookup_named_face (it->f, face_name, 0);
24288 if (face_id < 0)
24289 return make_number (-1);
24290
24291 face = FACE_FROM_ID (it->f, face_id);
24292 font = face->font;
24293 if (font == NULL)
24294 return make_number (-1);
24295 boff = font->baseline_offset;
24296 if (font->vertical_centering)
24297 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24298 }
24299
24300 ascent = FONT_BASE (font) + boff;
24301 descent = FONT_DESCENT (font) - boff;
24302
24303 if (override)
24304 {
24305 it->override_ascent = ascent;
24306 it->override_descent = descent;
24307 it->override_boff = boff;
24308 }
24309
24310 height = ascent + descent;
24311
24312 scale:
24313 if (FLOATP (val))
24314 height = (int)(XFLOAT_DATA (val) * height);
24315 else if (INTEGERP (val))
24316 height *= XINT (val);
24317
24318 return make_number (height);
24319 }
24320
24321
24322 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24323 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24324 and only if this is for a character for which no font was found.
24325
24326 If the display method (it->glyphless_method) is
24327 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24328 length of the acronym or the hexadecimal string, UPPER_XOFF and
24329 UPPER_YOFF are pixel offsets for the upper part of the string,
24330 LOWER_XOFF and LOWER_YOFF are for the lower part.
24331
24332 For the other display methods, LEN through LOWER_YOFF are zero. */
24333
24334 static void
24335 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24336 short upper_xoff, short upper_yoff,
24337 short lower_xoff, short lower_yoff)
24338 {
24339 struct glyph *glyph;
24340 enum glyph_row_area area = it->area;
24341
24342 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24343 if (glyph < it->glyph_row->glyphs[area + 1])
24344 {
24345 /* If the glyph row is reversed, we need to prepend the glyph
24346 rather than append it. */
24347 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24348 {
24349 struct glyph *g;
24350
24351 /* Make room for the additional glyph. */
24352 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24353 g[1] = *g;
24354 glyph = it->glyph_row->glyphs[area];
24355 }
24356 glyph->charpos = CHARPOS (it->position);
24357 glyph->object = it->object;
24358 glyph->pixel_width = it->pixel_width;
24359 glyph->ascent = it->ascent;
24360 glyph->descent = it->descent;
24361 glyph->voffset = it->voffset;
24362 glyph->type = GLYPHLESS_GLYPH;
24363 glyph->u.glyphless.method = it->glyphless_method;
24364 glyph->u.glyphless.for_no_font = for_no_font;
24365 glyph->u.glyphless.len = len;
24366 glyph->u.glyphless.ch = it->c;
24367 glyph->slice.glyphless.upper_xoff = upper_xoff;
24368 glyph->slice.glyphless.upper_yoff = upper_yoff;
24369 glyph->slice.glyphless.lower_xoff = lower_xoff;
24370 glyph->slice.glyphless.lower_yoff = lower_yoff;
24371 glyph->avoid_cursor_p = it->avoid_cursor_p;
24372 glyph->multibyte_p = it->multibyte_p;
24373 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24374 {
24375 /* In R2L rows, the left and the right box edges need to be
24376 drawn in reverse direction. */
24377 glyph->right_box_line_p = it->start_of_box_run_p;
24378 glyph->left_box_line_p = it->end_of_box_run_p;
24379 }
24380 else
24381 {
24382 glyph->left_box_line_p = it->start_of_box_run_p;
24383 glyph->right_box_line_p = it->end_of_box_run_p;
24384 }
24385 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24386 || it->phys_descent > it->descent);
24387 glyph->padding_p = 0;
24388 glyph->glyph_not_available_p = 0;
24389 glyph->face_id = face_id;
24390 glyph->font_type = FONT_TYPE_UNKNOWN;
24391 if (it->bidi_p)
24392 {
24393 glyph->resolved_level = it->bidi_it.resolved_level;
24394 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24395 emacs_abort ();
24396 glyph->bidi_type = it->bidi_it.type;
24397 }
24398 ++it->glyph_row->used[area];
24399 }
24400 else
24401 IT_EXPAND_MATRIX_WIDTH (it, area);
24402 }
24403
24404
24405 /* Produce a glyph for a glyphless character for iterator IT.
24406 IT->glyphless_method specifies which method to use for displaying
24407 the character. See the description of enum
24408 glyphless_display_method in dispextern.h for the detail.
24409
24410 FOR_NO_FONT is nonzero if and only if this is for a character for
24411 which no font was found. ACRONYM, if non-nil, is an acronym string
24412 for the character. */
24413
24414 static void
24415 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24416 {
24417 int face_id;
24418 struct face *face;
24419 struct font *font;
24420 int base_width, base_height, width, height;
24421 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24422 int len;
24423
24424 /* Get the metrics of the base font. We always refer to the current
24425 ASCII face. */
24426 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24427 font = face->font ? face->font : FRAME_FONT (it->f);
24428 it->ascent = FONT_BASE (font) + font->baseline_offset;
24429 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24430 base_height = it->ascent + it->descent;
24431 base_width = font->average_width;
24432
24433 /* Get a face ID for the glyph by utilizing a cache (the same way as
24434 done for `escape-glyph' in get_next_display_element). */
24435 if (it->f == last_glyphless_glyph_frame
24436 && it->face_id == last_glyphless_glyph_face_id)
24437 {
24438 face_id = last_glyphless_glyph_merged_face_id;
24439 }
24440 else
24441 {
24442 /* Merge the `glyphless-char' face into the current face. */
24443 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24444 last_glyphless_glyph_frame = it->f;
24445 last_glyphless_glyph_face_id = it->face_id;
24446 last_glyphless_glyph_merged_face_id = face_id;
24447 }
24448
24449 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24450 {
24451 it->pixel_width = THIN_SPACE_WIDTH;
24452 len = 0;
24453 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24454 }
24455 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24456 {
24457 width = CHAR_WIDTH (it->c);
24458 if (width == 0)
24459 width = 1;
24460 else if (width > 4)
24461 width = 4;
24462 it->pixel_width = base_width * width;
24463 len = 0;
24464 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24465 }
24466 else
24467 {
24468 char buf[7];
24469 const char *str;
24470 unsigned int code[6];
24471 int upper_len;
24472 int ascent, descent;
24473 struct font_metrics metrics_upper, metrics_lower;
24474
24475 face = FACE_FROM_ID (it->f, face_id);
24476 font = face->font ? face->font : FRAME_FONT (it->f);
24477 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24478
24479 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24480 {
24481 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24482 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24483 if (CONSP (acronym))
24484 acronym = XCAR (acronym);
24485 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24486 }
24487 else
24488 {
24489 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24490 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24491 str = buf;
24492 }
24493 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24494 code[len] = font->driver->encode_char (font, str[len]);
24495 upper_len = (len + 1) / 2;
24496 font->driver->text_extents (font, code, upper_len,
24497 &metrics_upper);
24498 font->driver->text_extents (font, code + upper_len, len - upper_len,
24499 &metrics_lower);
24500
24501
24502
24503 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24504 width = max (metrics_upper.width, metrics_lower.width) + 4;
24505 upper_xoff = upper_yoff = 2; /* the typical case */
24506 if (base_width >= width)
24507 {
24508 /* Align the upper to the left, the lower to the right. */
24509 it->pixel_width = base_width;
24510 lower_xoff = base_width - 2 - metrics_lower.width;
24511 }
24512 else
24513 {
24514 /* Center the shorter one. */
24515 it->pixel_width = width;
24516 if (metrics_upper.width >= metrics_lower.width)
24517 lower_xoff = (width - metrics_lower.width) / 2;
24518 else
24519 {
24520 /* FIXME: This code doesn't look right. It formerly was
24521 missing the "lower_xoff = 0;", which couldn't have
24522 been right since it left lower_xoff uninitialized. */
24523 lower_xoff = 0;
24524 upper_xoff = (width - metrics_upper.width) / 2;
24525 }
24526 }
24527
24528 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24529 top, bottom, and between upper and lower strings. */
24530 height = (metrics_upper.ascent + metrics_upper.descent
24531 + metrics_lower.ascent + metrics_lower.descent) + 5;
24532 /* Center vertically.
24533 H:base_height, D:base_descent
24534 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
24535
24536 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
24537 descent = D - H/2 + h/2;
24538 lower_yoff = descent - 2 - ld;
24539 upper_yoff = lower_yoff - la - 1 - ud; */
24540 ascent = - (it->descent - (base_height + height + 1) / 2);
24541 descent = it->descent - (base_height - height) / 2;
24542 lower_yoff = descent - 2 - metrics_lower.descent;
24543 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
24544 - metrics_upper.descent);
24545 /* Don't make the height shorter than the base height. */
24546 if (height > base_height)
24547 {
24548 it->ascent = ascent;
24549 it->descent = descent;
24550 }
24551 }
24552
24553 it->phys_ascent = it->ascent;
24554 it->phys_descent = it->descent;
24555 if (it->glyph_row)
24556 append_glyphless_glyph (it, face_id, for_no_font, len,
24557 upper_xoff, upper_yoff,
24558 lower_xoff, lower_yoff);
24559 it->nglyphs = 1;
24560 take_vertical_position_into_account (it);
24561 }
24562
24563
24564 /* RIF:
24565 Produce glyphs/get display metrics for the display element IT is
24566 loaded with. See the description of struct it in dispextern.h
24567 for an overview of struct it. */
24568
24569 void
24570 x_produce_glyphs (struct it *it)
24571 {
24572 int extra_line_spacing = it->extra_line_spacing;
24573
24574 it->glyph_not_available_p = 0;
24575
24576 if (it->what == IT_CHARACTER)
24577 {
24578 XChar2b char2b;
24579 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24580 struct font *font = face->font;
24581 struct font_metrics *pcm = NULL;
24582 int boff; /* baseline offset */
24583
24584 if (font == NULL)
24585 {
24586 /* When no suitable font is found, display this character by
24587 the method specified in the first extra slot of
24588 Vglyphless_char_display. */
24589 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
24590
24591 eassert (it->what == IT_GLYPHLESS);
24592 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
24593 goto done;
24594 }
24595
24596 boff = font->baseline_offset;
24597 if (font->vertical_centering)
24598 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24599
24600 if (it->char_to_display != '\n' && it->char_to_display != '\t')
24601 {
24602 int stretched_p;
24603
24604 it->nglyphs = 1;
24605
24606 if (it->override_ascent >= 0)
24607 {
24608 it->ascent = it->override_ascent;
24609 it->descent = it->override_descent;
24610 boff = it->override_boff;
24611 }
24612 else
24613 {
24614 it->ascent = FONT_BASE (font) + boff;
24615 it->descent = FONT_DESCENT (font) - boff;
24616 }
24617
24618 if (get_char_glyph_code (it->char_to_display, font, &char2b))
24619 {
24620 pcm = get_per_char_metric (font, &char2b);
24621 if (pcm->width == 0
24622 && pcm->rbearing == 0 && pcm->lbearing == 0)
24623 pcm = NULL;
24624 }
24625
24626 if (pcm)
24627 {
24628 it->phys_ascent = pcm->ascent + boff;
24629 it->phys_descent = pcm->descent - boff;
24630 it->pixel_width = pcm->width;
24631 }
24632 else
24633 {
24634 it->glyph_not_available_p = 1;
24635 it->phys_ascent = it->ascent;
24636 it->phys_descent = it->descent;
24637 it->pixel_width = font->space_width;
24638 }
24639
24640 if (it->constrain_row_ascent_descent_p)
24641 {
24642 if (it->descent > it->max_descent)
24643 {
24644 it->ascent += it->descent - it->max_descent;
24645 it->descent = it->max_descent;
24646 }
24647 if (it->ascent > it->max_ascent)
24648 {
24649 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24650 it->ascent = it->max_ascent;
24651 }
24652 it->phys_ascent = min (it->phys_ascent, it->ascent);
24653 it->phys_descent = min (it->phys_descent, it->descent);
24654 extra_line_spacing = 0;
24655 }
24656
24657 /* If this is a space inside a region of text with
24658 `space-width' property, change its width. */
24659 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
24660 if (stretched_p)
24661 it->pixel_width *= XFLOATINT (it->space_width);
24662
24663 /* If face has a box, add the box thickness to the character
24664 height. If character has a box line to the left and/or
24665 right, add the box line width to the character's width. */
24666 if (face->box != FACE_NO_BOX)
24667 {
24668 int thick = face->box_line_width;
24669
24670 if (thick > 0)
24671 {
24672 it->ascent += thick;
24673 it->descent += thick;
24674 }
24675 else
24676 thick = -thick;
24677
24678 if (it->start_of_box_run_p)
24679 it->pixel_width += thick;
24680 if (it->end_of_box_run_p)
24681 it->pixel_width += thick;
24682 }
24683
24684 /* If face has an overline, add the height of the overline
24685 (1 pixel) and a 1 pixel margin to the character height. */
24686 if (face->overline_p)
24687 it->ascent += overline_margin;
24688
24689 if (it->constrain_row_ascent_descent_p)
24690 {
24691 if (it->ascent > it->max_ascent)
24692 it->ascent = it->max_ascent;
24693 if (it->descent > it->max_descent)
24694 it->descent = it->max_descent;
24695 }
24696
24697 take_vertical_position_into_account (it);
24698
24699 /* If we have to actually produce glyphs, do it. */
24700 if (it->glyph_row)
24701 {
24702 if (stretched_p)
24703 {
24704 /* Translate a space with a `space-width' property
24705 into a stretch glyph. */
24706 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
24707 / FONT_HEIGHT (font));
24708 append_stretch_glyph (it, it->object, it->pixel_width,
24709 it->ascent + it->descent, ascent);
24710 }
24711 else
24712 append_glyph (it);
24713
24714 /* If characters with lbearing or rbearing are displayed
24715 in this line, record that fact in a flag of the
24716 glyph row. This is used to optimize X output code. */
24717 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
24718 it->glyph_row->contains_overlapping_glyphs_p = 1;
24719 }
24720 if (! stretched_p && it->pixel_width == 0)
24721 /* We assure that all visible glyphs have at least 1-pixel
24722 width. */
24723 it->pixel_width = 1;
24724 }
24725 else if (it->char_to_display == '\n')
24726 {
24727 /* A newline has no width, but we need the height of the
24728 line. But if previous part of the line sets a height,
24729 don't increase that height */
24730
24731 Lisp_Object height;
24732 Lisp_Object total_height = Qnil;
24733
24734 it->override_ascent = -1;
24735 it->pixel_width = 0;
24736 it->nglyphs = 0;
24737
24738 height = get_it_property (it, Qline_height);
24739 /* Split (line-height total-height) list */
24740 if (CONSP (height)
24741 && CONSP (XCDR (height))
24742 && NILP (XCDR (XCDR (height))))
24743 {
24744 total_height = XCAR (XCDR (height));
24745 height = XCAR (height);
24746 }
24747 height = calc_line_height_property (it, height, font, boff, 1);
24748
24749 if (it->override_ascent >= 0)
24750 {
24751 it->ascent = it->override_ascent;
24752 it->descent = it->override_descent;
24753 boff = it->override_boff;
24754 }
24755 else
24756 {
24757 it->ascent = FONT_BASE (font) + boff;
24758 it->descent = FONT_DESCENT (font) - boff;
24759 }
24760
24761 if (EQ (height, Qt))
24762 {
24763 if (it->descent > it->max_descent)
24764 {
24765 it->ascent += it->descent - it->max_descent;
24766 it->descent = it->max_descent;
24767 }
24768 if (it->ascent > it->max_ascent)
24769 {
24770 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24771 it->ascent = it->max_ascent;
24772 }
24773 it->phys_ascent = min (it->phys_ascent, it->ascent);
24774 it->phys_descent = min (it->phys_descent, it->descent);
24775 it->constrain_row_ascent_descent_p = 1;
24776 extra_line_spacing = 0;
24777 }
24778 else
24779 {
24780 Lisp_Object spacing;
24781
24782 it->phys_ascent = it->ascent;
24783 it->phys_descent = it->descent;
24784
24785 if ((it->max_ascent > 0 || it->max_descent > 0)
24786 && face->box != FACE_NO_BOX
24787 && face->box_line_width > 0)
24788 {
24789 it->ascent += face->box_line_width;
24790 it->descent += face->box_line_width;
24791 }
24792 if (!NILP (height)
24793 && XINT (height) > it->ascent + it->descent)
24794 it->ascent = XINT (height) - it->descent;
24795
24796 if (!NILP (total_height))
24797 spacing = calc_line_height_property (it, total_height, font, boff, 0);
24798 else
24799 {
24800 spacing = get_it_property (it, Qline_spacing);
24801 spacing = calc_line_height_property (it, spacing, font, boff, 0);
24802 }
24803 if (INTEGERP (spacing))
24804 {
24805 extra_line_spacing = XINT (spacing);
24806 if (!NILP (total_height))
24807 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
24808 }
24809 }
24810 }
24811 else /* i.e. (it->char_to_display == '\t') */
24812 {
24813 if (font->space_width > 0)
24814 {
24815 int tab_width = it->tab_width * font->space_width;
24816 int x = it->current_x + it->continuation_lines_width;
24817 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
24818
24819 /* If the distance from the current position to the next tab
24820 stop is less than a space character width, use the
24821 tab stop after that. */
24822 if (next_tab_x - x < font->space_width)
24823 next_tab_x += tab_width;
24824
24825 it->pixel_width = next_tab_x - x;
24826 it->nglyphs = 1;
24827 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
24828 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
24829
24830 if (it->glyph_row)
24831 {
24832 append_stretch_glyph (it, it->object, it->pixel_width,
24833 it->ascent + it->descent, it->ascent);
24834 }
24835 }
24836 else
24837 {
24838 it->pixel_width = 0;
24839 it->nglyphs = 1;
24840 }
24841 }
24842 }
24843 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
24844 {
24845 /* A static composition.
24846
24847 Note: A composition is represented as one glyph in the
24848 glyph matrix. There are no padding glyphs.
24849
24850 Important note: pixel_width, ascent, and descent are the
24851 values of what is drawn by draw_glyphs (i.e. the values of
24852 the overall glyphs composed). */
24853 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24854 int boff; /* baseline offset */
24855 struct composition *cmp = composition_table[it->cmp_it.id];
24856 int glyph_len = cmp->glyph_len;
24857 struct font *font = face->font;
24858
24859 it->nglyphs = 1;
24860
24861 /* If we have not yet calculated pixel size data of glyphs of
24862 the composition for the current face font, calculate them
24863 now. Theoretically, we have to check all fonts for the
24864 glyphs, but that requires much time and memory space. So,
24865 here we check only the font of the first glyph. This may
24866 lead to incorrect display, but it's very rare, and C-l
24867 (recenter-top-bottom) can correct the display anyway. */
24868 if (! cmp->font || cmp->font != font)
24869 {
24870 /* Ascent and descent of the font of the first character
24871 of this composition (adjusted by baseline offset).
24872 Ascent and descent of overall glyphs should not be less
24873 than these, respectively. */
24874 int font_ascent, font_descent, font_height;
24875 /* Bounding box of the overall glyphs. */
24876 int leftmost, rightmost, lowest, highest;
24877 int lbearing, rbearing;
24878 int i, width, ascent, descent;
24879 int left_padded = 0, right_padded = 0;
24880 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
24881 XChar2b char2b;
24882 struct font_metrics *pcm;
24883 int font_not_found_p;
24884 ptrdiff_t pos;
24885
24886 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
24887 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
24888 break;
24889 if (glyph_len < cmp->glyph_len)
24890 right_padded = 1;
24891 for (i = 0; i < glyph_len; i++)
24892 {
24893 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
24894 break;
24895 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24896 }
24897 if (i > 0)
24898 left_padded = 1;
24899
24900 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
24901 : IT_CHARPOS (*it));
24902 /* If no suitable font is found, use the default font. */
24903 font_not_found_p = font == NULL;
24904 if (font_not_found_p)
24905 {
24906 face = face->ascii_face;
24907 font = face->font;
24908 }
24909 boff = font->baseline_offset;
24910 if (font->vertical_centering)
24911 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24912 font_ascent = FONT_BASE (font) + boff;
24913 font_descent = FONT_DESCENT (font) - boff;
24914 font_height = FONT_HEIGHT (font);
24915
24916 cmp->font = font;
24917
24918 pcm = NULL;
24919 if (! font_not_found_p)
24920 {
24921 get_char_face_and_encoding (it->f, c, it->face_id,
24922 &char2b, 0);
24923 pcm = get_per_char_metric (font, &char2b);
24924 }
24925
24926 /* Initialize the bounding box. */
24927 if (pcm)
24928 {
24929 width = cmp->glyph_len > 0 ? pcm->width : 0;
24930 ascent = pcm->ascent;
24931 descent = pcm->descent;
24932 lbearing = pcm->lbearing;
24933 rbearing = pcm->rbearing;
24934 }
24935 else
24936 {
24937 width = cmp->glyph_len > 0 ? font->space_width : 0;
24938 ascent = FONT_BASE (font);
24939 descent = FONT_DESCENT (font);
24940 lbearing = 0;
24941 rbearing = width;
24942 }
24943
24944 rightmost = width;
24945 leftmost = 0;
24946 lowest = - descent + boff;
24947 highest = ascent + boff;
24948
24949 if (! font_not_found_p
24950 && font->default_ascent
24951 && CHAR_TABLE_P (Vuse_default_ascent)
24952 && !NILP (Faref (Vuse_default_ascent,
24953 make_number (it->char_to_display))))
24954 highest = font->default_ascent + boff;
24955
24956 /* Draw the first glyph at the normal position. It may be
24957 shifted to right later if some other glyphs are drawn
24958 at the left. */
24959 cmp->offsets[i * 2] = 0;
24960 cmp->offsets[i * 2 + 1] = boff;
24961 cmp->lbearing = lbearing;
24962 cmp->rbearing = rbearing;
24963
24964 /* Set cmp->offsets for the remaining glyphs. */
24965 for (i++; i < glyph_len; i++)
24966 {
24967 int left, right, btm, top;
24968 int ch = COMPOSITION_GLYPH (cmp, i);
24969 int face_id;
24970 struct face *this_face;
24971
24972 if (ch == '\t')
24973 ch = ' ';
24974 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
24975 this_face = FACE_FROM_ID (it->f, face_id);
24976 font = this_face->font;
24977
24978 if (font == NULL)
24979 pcm = NULL;
24980 else
24981 {
24982 get_char_face_and_encoding (it->f, ch, face_id,
24983 &char2b, 0);
24984 pcm = get_per_char_metric (font, &char2b);
24985 }
24986 if (! pcm)
24987 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24988 else
24989 {
24990 width = pcm->width;
24991 ascent = pcm->ascent;
24992 descent = pcm->descent;
24993 lbearing = pcm->lbearing;
24994 rbearing = pcm->rbearing;
24995 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
24996 {
24997 /* Relative composition with or without
24998 alternate chars. */
24999 left = (leftmost + rightmost - width) / 2;
25000 btm = - descent + boff;
25001 if (font->relative_compose
25002 && (! CHAR_TABLE_P (Vignore_relative_composition)
25003 || NILP (Faref (Vignore_relative_composition,
25004 make_number (ch)))))
25005 {
25006
25007 if (- descent >= font->relative_compose)
25008 /* One extra pixel between two glyphs. */
25009 btm = highest + 1;
25010 else if (ascent <= 0)
25011 /* One extra pixel between two glyphs. */
25012 btm = lowest - 1 - ascent - descent;
25013 }
25014 }
25015 else
25016 {
25017 /* A composition rule is specified by an integer
25018 value that encodes global and new reference
25019 points (GREF and NREF). GREF and NREF are
25020 specified by numbers as below:
25021
25022 0---1---2 -- ascent
25023 | |
25024 | |
25025 | |
25026 9--10--11 -- center
25027 | |
25028 ---3---4---5--- baseline
25029 | |
25030 6---7---8 -- descent
25031 */
25032 int rule = COMPOSITION_RULE (cmp, i);
25033 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25034
25035 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25036 grefx = gref % 3, nrefx = nref % 3;
25037 grefy = gref / 3, nrefy = nref / 3;
25038 if (xoff)
25039 xoff = font_height * (xoff - 128) / 256;
25040 if (yoff)
25041 yoff = font_height * (yoff - 128) / 256;
25042
25043 left = (leftmost
25044 + grefx * (rightmost - leftmost) / 2
25045 - nrefx * width / 2
25046 + xoff);
25047
25048 btm = ((grefy == 0 ? highest
25049 : grefy == 1 ? 0
25050 : grefy == 2 ? lowest
25051 : (highest + lowest) / 2)
25052 - (nrefy == 0 ? ascent + descent
25053 : nrefy == 1 ? descent - boff
25054 : nrefy == 2 ? 0
25055 : (ascent + descent) / 2)
25056 + yoff);
25057 }
25058
25059 cmp->offsets[i * 2] = left;
25060 cmp->offsets[i * 2 + 1] = btm + descent;
25061
25062 /* Update the bounding box of the overall glyphs. */
25063 if (width > 0)
25064 {
25065 right = left + width;
25066 if (left < leftmost)
25067 leftmost = left;
25068 if (right > rightmost)
25069 rightmost = right;
25070 }
25071 top = btm + descent + ascent;
25072 if (top > highest)
25073 highest = top;
25074 if (btm < lowest)
25075 lowest = btm;
25076
25077 if (cmp->lbearing > left + lbearing)
25078 cmp->lbearing = left + lbearing;
25079 if (cmp->rbearing < left + rbearing)
25080 cmp->rbearing = left + rbearing;
25081 }
25082 }
25083
25084 /* If there are glyphs whose x-offsets are negative,
25085 shift all glyphs to the right and make all x-offsets
25086 non-negative. */
25087 if (leftmost < 0)
25088 {
25089 for (i = 0; i < cmp->glyph_len; i++)
25090 cmp->offsets[i * 2] -= leftmost;
25091 rightmost -= leftmost;
25092 cmp->lbearing -= leftmost;
25093 cmp->rbearing -= leftmost;
25094 }
25095
25096 if (left_padded && cmp->lbearing < 0)
25097 {
25098 for (i = 0; i < cmp->glyph_len; i++)
25099 cmp->offsets[i * 2] -= cmp->lbearing;
25100 rightmost -= cmp->lbearing;
25101 cmp->rbearing -= cmp->lbearing;
25102 cmp->lbearing = 0;
25103 }
25104 if (right_padded && rightmost < cmp->rbearing)
25105 {
25106 rightmost = cmp->rbearing;
25107 }
25108
25109 cmp->pixel_width = rightmost;
25110 cmp->ascent = highest;
25111 cmp->descent = - lowest;
25112 if (cmp->ascent < font_ascent)
25113 cmp->ascent = font_ascent;
25114 if (cmp->descent < font_descent)
25115 cmp->descent = font_descent;
25116 }
25117
25118 if (it->glyph_row
25119 && (cmp->lbearing < 0
25120 || cmp->rbearing > cmp->pixel_width))
25121 it->glyph_row->contains_overlapping_glyphs_p = 1;
25122
25123 it->pixel_width = cmp->pixel_width;
25124 it->ascent = it->phys_ascent = cmp->ascent;
25125 it->descent = it->phys_descent = cmp->descent;
25126 if (face->box != FACE_NO_BOX)
25127 {
25128 int thick = face->box_line_width;
25129
25130 if (thick > 0)
25131 {
25132 it->ascent += thick;
25133 it->descent += thick;
25134 }
25135 else
25136 thick = - thick;
25137
25138 if (it->start_of_box_run_p)
25139 it->pixel_width += thick;
25140 if (it->end_of_box_run_p)
25141 it->pixel_width += thick;
25142 }
25143
25144 /* If face has an overline, add the height of the overline
25145 (1 pixel) and a 1 pixel margin to the character height. */
25146 if (face->overline_p)
25147 it->ascent += overline_margin;
25148
25149 take_vertical_position_into_account (it);
25150 if (it->ascent < 0)
25151 it->ascent = 0;
25152 if (it->descent < 0)
25153 it->descent = 0;
25154
25155 if (it->glyph_row && cmp->glyph_len > 0)
25156 append_composite_glyph (it);
25157 }
25158 else if (it->what == IT_COMPOSITION)
25159 {
25160 /* A dynamic (automatic) composition. */
25161 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25162 Lisp_Object gstring;
25163 struct font_metrics metrics;
25164
25165 it->nglyphs = 1;
25166
25167 gstring = composition_gstring_from_id (it->cmp_it.id);
25168 it->pixel_width
25169 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25170 &metrics);
25171 if (it->glyph_row
25172 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25173 it->glyph_row->contains_overlapping_glyphs_p = 1;
25174 it->ascent = it->phys_ascent = metrics.ascent;
25175 it->descent = it->phys_descent = metrics.descent;
25176 if (face->box != FACE_NO_BOX)
25177 {
25178 int thick = face->box_line_width;
25179
25180 if (thick > 0)
25181 {
25182 it->ascent += thick;
25183 it->descent += thick;
25184 }
25185 else
25186 thick = - thick;
25187
25188 if (it->start_of_box_run_p)
25189 it->pixel_width += thick;
25190 if (it->end_of_box_run_p)
25191 it->pixel_width += thick;
25192 }
25193 /* If face has an overline, add the height of the overline
25194 (1 pixel) and a 1 pixel margin to the character height. */
25195 if (face->overline_p)
25196 it->ascent += overline_margin;
25197 take_vertical_position_into_account (it);
25198 if (it->ascent < 0)
25199 it->ascent = 0;
25200 if (it->descent < 0)
25201 it->descent = 0;
25202
25203 if (it->glyph_row)
25204 append_composite_glyph (it);
25205 }
25206 else if (it->what == IT_GLYPHLESS)
25207 produce_glyphless_glyph (it, 0, Qnil);
25208 else if (it->what == IT_IMAGE)
25209 produce_image_glyph (it);
25210 else if (it->what == IT_STRETCH)
25211 produce_stretch_glyph (it);
25212
25213 done:
25214 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25215 because this isn't true for images with `:ascent 100'. */
25216 eassert (it->ascent >= 0 && it->descent >= 0);
25217 if (it->area == TEXT_AREA)
25218 it->current_x += it->pixel_width;
25219
25220 if (extra_line_spacing > 0)
25221 {
25222 it->descent += extra_line_spacing;
25223 if (extra_line_spacing > it->max_extra_line_spacing)
25224 it->max_extra_line_spacing = extra_line_spacing;
25225 }
25226
25227 it->max_ascent = max (it->max_ascent, it->ascent);
25228 it->max_descent = max (it->max_descent, it->descent);
25229 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25230 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25231 }
25232
25233 /* EXPORT for RIF:
25234 Output LEN glyphs starting at START at the nominal cursor position.
25235 Advance the nominal cursor over the text. The global variable
25236 updated_window contains the window being updated, updated_row is
25237 the glyph row being updated, and updated_area is the area of that
25238 row being updated. */
25239
25240 void
25241 x_write_glyphs (struct glyph *start, int len)
25242 {
25243 int x, hpos, chpos = updated_window->phys_cursor.hpos;
25244
25245 eassert (updated_window && updated_row);
25246 /* When the window is hscrolled, cursor hpos can legitimately be out
25247 of bounds, but we draw the cursor at the corresponding window
25248 margin in that case. */
25249 if (!updated_row->reversed_p && chpos < 0)
25250 chpos = 0;
25251 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25252 chpos = updated_row->used[TEXT_AREA] - 1;
25253
25254 block_input ();
25255
25256 /* Write glyphs. */
25257
25258 hpos = start - updated_row->glyphs[updated_area];
25259 x = draw_glyphs (updated_window, output_cursor.x,
25260 updated_row, updated_area,
25261 hpos, hpos + len,
25262 DRAW_NORMAL_TEXT, 0);
25263
25264 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25265 if (updated_area == TEXT_AREA
25266 && updated_window->phys_cursor_on_p
25267 && updated_window->phys_cursor.vpos == output_cursor.vpos
25268 && chpos >= hpos
25269 && chpos < hpos + len)
25270 updated_window->phys_cursor_on_p = 0;
25271
25272 unblock_input ();
25273
25274 /* Advance the output cursor. */
25275 output_cursor.hpos += len;
25276 output_cursor.x = x;
25277 }
25278
25279
25280 /* EXPORT for RIF:
25281 Insert LEN glyphs from START at the nominal cursor position. */
25282
25283 void
25284 x_insert_glyphs (struct glyph *start, int len)
25285 {
25286 struct frame *f;
25287 struct window *w;
25288 int line_height, shift_by_width, shifted_region_width;
25289 struct glyph_row *row;
25290 struct glyph *glyph;
25291 int frame_x, frame_y;
25292 ptrdiff_t hpos;
25293
25294 eassert (updated_window && updated_row);
25295 block_input ();
25296 w = updated_window;
25297 f = XFRAME (WINDOW_FRAME (w));
25298
25299 /* Get the height of the line we are in. */
25300 row = updated_row;
25301 line_height = row->height;
25302
25303 /* Get the width of the glyphs to insert. */
25304 shift_by_width = 0;
25305 for (glyph = start; glyph < start + len; ++glyph)
25306 shift_by_width += glyph->pixel_width;
25307
25308 /* Get the width of the region to shift right. */
25309 shifted_region_width = (window_box_width (w, updated_area)
25310 - output_cursor.x
25311 - shift_by_width);
25312
25313 /* Shift right. */
25314 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25315 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25316
25317 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25318 line_height, shift_by_width);
25319
25320 /* Write the glyphs. */
25321 hpos = start - row->glyphs[updated_area];
25322 draw_glyphs (w, output_cursor.x, row, updated_area,
25323 hpos, hpos + len,
25324 DRAW_NORMAL_TEXT, 0);
25325
25326 /* Advance the output cursor. */
25327 output_cursor.hpos += len;
25328 output_cursor.x += shift_by_width;
25329 unblock_input ();
25330 }
25331
25332
25333 /* EXPORT for RIF:
25334 Erase the current text line from the nominal cursor position
25335 (inclusive) to pixel column TO_X (exclusive). The idea is that
25336 everything from TO_X onward is already erased.
25337
25338 TO_X is a pixel position relative to updated_area of
25339 updated_window. TO_X == -1 means clear to the end of this area. */
25340
25341 void
25342 x_clear_end_of_line (int to_x)
25343 {
25344 struct frame *f;
25345 struct window *w = updated_window;
25346 int max_x, min_y, max_y;
25347 int from_x, from_y, to_y;
25348
25349 eassert (updated_window && updated_row);
25350 f = XFRAME (w->frame);
25351
25352 if (updated_row->full_width_p)
25353 max_x = WINDOW_TOTAL_WIDTH (w);
25354 else
25355 max_x = window_box_width (w, updated_area);
25356 max_y = window_text_bottom_y (w);
25357
25358 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25359 of window. For TO_X > 0, truncate to end of drawing area. */
25360 if (to_x == 0)
25361 return;
25362 else if (to_x < 0)
25363 to_x = max_x;
25364 else
25365 to_x = min (to_x, max_x);
25366
25367 to_y = min (max_y, output_cursor.y + updated_row->height);
25368
25369 /* Notice if the cursor will be cleared by this operation. */
25370 if (!updated_row->full_width_p)
25371 notice_overwritten_cursor (w, updated_area,
25372 output_cursor.x, -1,
25373 updated_row->y,
25374 MATRIX_ROW_BOTTOM_Y (updated_row));
25375
25376 from_x = output_cursor.x;
25377
25378 /* Translate to frame coordinates. */
25379 if (updated_row->full_width_p)
25380 {
25381 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25382 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25383 }
25384 else
25385 {
25386 int area_left = window_box_left (w, updated_area);
25387 from_x += area_left;
25388 to_x += area_left;
25389 }
25390
25391 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25392 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25393 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25394
25395 /* Prevent inadvertently clearing to end of the X window. */
25396 if (to_x > from_x && to_y > from_y)
25397 {
25398 block_input ();
25399 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25400 to_x - from_x, to_y - from_y);
25401 unblock_input ();
25402 }
25403 }
25404
25405 #endif /* HAVE_WINDOW_SYSTEM */
25406
25407
25408 \f
25409 /***********************************************************************
25410 Cursor types
25411 ***********************************************************************/
25412
25413 /* Value is the internal representation of the specified cursor type
25414 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25415 of the bar cursor. */
25416
25417 static enum text_cursor_kinds
25418 get_specified_cursor_type (Lisp_Object arg, int *width)
25419 {
25420 enum text_cursor_kinds type;
25421
25422 if (NILP (arg))
25423 return NO_CURSOR;
25424
25425 if (EQ (arg, Qbox))
25426 return FILLED_BOX_CURSOR;
25427
25428 if (EQ (arg, Qhollow))
25429 return HOLLOW_BOX_CURSOR;
25430
25431 if (EQ (arg, Qbar))
25432 {
25433 *width = 2;
25434 return BAR_CURSOR;
25435 }
25436
25437 if (CONSP (arg)
25438 && EQ (XCAR (arg), Qbar)
25439 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25440 {
25441 *width = XINT (XCDR (arg));
25442 return BAR_CURSOR;
25443 }
25444
25445 if (EQ (arg, Qhbar))
25446 {
25447 *width = 2;
25448 return HBAR_CURSOR;
25449 }
25450
25451 if (CONSP (arg)
25452 && EQ (XCAR (arg), Qhbar)
25453 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25454 {
25455 *width = XINT (XCDR (arg));
25456 return HBAR_CURSOR;
25457 }
25458
25459 /* Treat anything unknown as "hollow box cursor".
25460 It was bad to signal an error; people have trouble fixing
25461 .Xdefaults with Emacs, when it has something bad in it. */
25462 type = HOLLOW_BOX_CURSOR;
25463
25464 return type;
25465 }
25466
25467 /* Set the default cursor types for specified frame. */
25468 void
25469 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25470 {
25471 int width = 1;
25472 Lisp_Object tem;
25473
25474 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25475 FRAME_CURSOR_WIDTH (f) = width;
25476
25477 /* By default, set up the blink-off state depending on the on-state. */
25478
25479 tem = Fassoc (arg, Vblink_cursor_alist);
25480 if (!NILP (tem))
25481 {
25482 FRAME_BLINK_OFF_CURSOR (f)
25483 = get_specified_cursor_type (XCDR (tem), &width);
25484 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25485 }
25486 else
25487 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25488 }
25489
25490
25491 #ifdef HAVE_WINDOW_SYSTEM
25492
25493 /* Return the cursor we want to be displayed in window W. Return
25494 width of bar/hbar cursor through WIDTH arg. Return with
25495 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25496 (i.e. if the `system caret' should track this cursor).
25497
25498 In a mini-buffer window, we want the cursor only to appear if we
25499 are reading input from this window. For the selected window, we
25500 want the cursor type given by the frame parameter or buffer local
25501 setting of cursor-type. If explicitly marked off, draw no cursor.
25502 In all other cases, we want a hollow box cursor. */
25503
25504 static enum text_cursor_kinds
25505 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25506 int *active_cursor)
25507 {
25508 struct frame *f = XFRAME (w->frame);
25509 struct buffer *b = XBUFFER (w->buffer);
25510 int cursor_type = DEFAULT_CURSOR;
25511 Lisp_Object alt_cursor;
25512 int non_selected = 0;
25513
25514 *active_cursor = 1;
25515
25516 /* Echo area */
25517 if (cursor_in_echo_area
25518 && FRAME_HAS_MINIBUF_P (f)
25519 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25520 {
25521 if (w == XWINDOW (echo_area_window))
25522 {
25523 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25524 {
25525 *width = FRAME_CURSOR_WIDTH (f);
25526 return FRAME_DESIRED_CURSOR (f);
25527 }
25528 else
25529 return get_specified_cursor_type (BVAR (b, cursor_type), width);
25530 }
25531
25532 *active_cursor = 0;
25533 non_selected = 1;
25534 }
25535
25536 /* Detect a nonselected window or nonselected frame. */
25537 else if (w != XWINDOW (f->selected_window)
25538 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
25539 {
25540 *active_cursor = 0;
25541
25542 if (MINI_WINDOW_P (w) && minibuf_level == 0)
25543 return NO_CURSOR;
25544
25545 non_selected = 1;
25546 }
25547
25548 /* Never display a cursor in a window in which cursor-type is nil. */
25549 if (NILP (BVAR (b, cursor_type)))
25550 return NO_CURSOR;
25551
25552 /* Get the normal cursor type for this window. */
25553 if (EQ (BVAR (b, cursor_type), Qt))
25554 {
25555 cursor_type = FRAME_DESIRED_CURSOR (f);
25556 *width = FRAME_CURSOR_WIDTH (f);
25557 }
25558 else
25559 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
25560
25561 /* Use cursor-in-non-selected-windows instead
25562 for non-selected window or frame. */
25563 if (non_selected)
25564 {
25565 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
25566 if (!EQ (Qt, alt_cursor))
25567 return get_specified_cursor_type (alt_cursor, width);
25568 /* t means modify the normal cursor type. */
25569 if (cursor_type == FILLED_BOX_CURSOR)
25570 cursor_type = HOLLOW_BOX_CURSOR;
25571 else if (cursor_type == BAR_CURSOR && *width > 1)
25572 --*width;
25573 return cursor_type;
25574 }
25575
25576 /* Use normal cursor if not blinked off. */
25577 if (!w->cursor_off_p)
25578 {
25579 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25580 {
25581 if (cursor_type == FILLED_BOX_CURSOR)
25582 {
25583 /* Using a block cursor on large images can be very annoying.
25584 So use a hollow cursor for "large" images.
25585 If image is not transparent (no mask), also use hollow cursor. */
25586 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25587 if (img != NULL && IMAGEP (img->spec))
25588 {
25589 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
25590 where N = size of default frame font size.
25591 This should cover most of the "tiny" icons people may use. */
25592 if (!img->mask
25593 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
25594 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
25595 cursor_type = HOLLOW_BOX_CURSOR;
25596 }
25597 }
25598 else if (cursor_type != NO_CURSOR)
25599 {
25600 /* Display current only supports BOX and HOLLOW cursors for images.
25601 So for now, unconditionally use a HOLLOW cursor when cursor is
25602 not a solid box cursor. */
25603 cursor_type = HOLLOW_BOX_CURSOR;
25604 }
25605 }
25606 return cursor_type;
25607 }
25608
25609 /* Cursor is blinked off, so determine how to "toggle" it. */
25610
25611 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25612 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
25613 return get_specified_cursor_type (XCDR (alt_cursor), width);
25614
25615 /* Then see if frame has specified a specific blink off cursor type. */
25616 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
25617 {
25618 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
25619 return FRAME_BLINK_OFF_CURSOR (f);
25620 }
25621
25622 #if 0
25623 /* Some people liked having a permanently visible blinking cursor,
25624 while others had very strong opinions against it. So it was
25625 decided to remove it. KFS 2003-09-03 */
25626
25627 /* Finally perform built-in cursor blinking:
25628 filled box <-> hollow box
25629 wide [h]bar <-> narrow [h]bar
25630 narrow [h]bar <-> no cursor
25631 other type <-> no cursor */
25632
25633 if (cursor_type == FILLED_BOX_CURSOR)
25634 return HOLLOW_BOX_CURSOR;
25635
25636 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
25637 {
25638 *width = 1;
25639 return cursor_type;
25640 }
25641 #endif
25642
25643 return NO_CURSOR;
25644 }
25645
25646
25647 /* Notice when the text cursor of window W has been completely
25648 overwritten by a drawing operation that outputs glyphs in AREA
25649 starting at X0 and ending at X1 in the line starting at Y0 and
25650 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25651 the rest of the line after X0 has been written. Y coordinates
25652 are window-relative. */
25653
25654 static void
25655 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
25656 int x0, int x1, int y0, int y1)
25657 {
25658 int cx0, cx1, cy0, cy1;
25659 struct glyph_row *row;
25660
25661 if (!w->phys_cursor_on_p)
25662 return;
25663 if (area != TEXT_AREA)
25664 return;
25665
25666 if (w->phys_cursor.vpos < 0
25667 || w->phys_cursor.vpos >= w->current_matrix->nrows
25668 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
25669 !(row->enabled_p && row->displays_text_p)))
25670 return;
25671
25672 if (row->cursor_in_fringe_p)
25673 {
25674 row->cursor_in_fringe_p = 0;
25675 draw_fringe_bitmap (w, row, row->reversed_p);
25676 w->phys_cursor_on_p = 0;
25677 return;
25678 }
25679
25680 cx0 = w->phys_cursor.x;
25681 cx1 = cx0 + w->phys_cursor_width;
25682 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
25683 return;
25684
25685 /* The cursor image will be completely removed from the
25686 screen if the output area intersects the cursor area in
25687 y-direction. When we draw in [y0 y1[, and some part of
25688 the cursor is at y < y0, that part must have been drawn
25689 before. When scrolling, the cursor is erased before
25690 actually scrolling, so we don't come here. When not
25691 scrolling, the rows above the old cursor row must have
25692 changed, and in this case these rows must have written
25693 over the cursor image.
25694
25695 Likewise if part of the cursor is below y1, with the
25696 exception of the cursor being in the first blank row at
25697 the buffer and window end because update_text_area
25698 doesn't draw that row. (Except when it does, but
25699 that's handled in update_text_area.) */
25700
25701 cy0 = w->phys_cursor.y;
25702 cy1 = cy0 + w->phys_cursor_height;
25703 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
25704 return;
25705
25706 w->phys_cursor_on_p = 0;
25707 }
25708
25709 #endif /* HAVE_WINDOW_SYSTEM */
25710
25711 \f
25712 /************************************************************************
25713 Mouse Face
25714 ************************************************************************/
25715
25716 #ifdef HAVE_WINDOW_SYSTEM
25717
25718 /* EXPORT for RIF:
25719 Fix the display of area AREA of overlapping row ROW in window W
25720 with respect to the overlapping part OVERLAPS. */
25721
25722 void
25723 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
25724 enum glyph_row_area area, int overlaps)
25725 {
25726 int i, x;
25727
25728 block_input ();
25729
25730 x = 0;
25731 for (i = 0; i < row->used[area];)
25732 {
25733 if (row->glyphs[area][i].overlaps_vertically_p)
25734 {
25735 int start = i, start_x = x;
25736
25737 do
25738 {
25739 x += row->glyphs[area][i].pixel_width;
25740 ++i;
25741 }
25742 while (i < row->used[area]
25743 && row->glyphs[area][i].overlaps_vertically_p);
25744
25745 draw_glyphs (w, start_x, row, area,
25746 start, i,
25747 DRAW_NORMAL_TEXT, overlaps);
25748 }
25749 else
25750 {
25751 x += row->glyphs[area][i].pixel_width;
25752 ++i;
25753 }
25754 }
25755
25756 unblock_input ();
25757 }
25758
25759
25760 /* EXPORT:
25761 Draw the cursor glyph of window W in glyph row ROW. See the
25762 comment of draw_glyphs for the meaning of HL. */
25763
25764 void
25765 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
25766 enum draw_glyphs_face hl)
25767 {
25768 /* If cursor hpos is out of bounds, don't draw garbage. This can
25769 happen in mini-buffer windows when switching between echo area
25770 glyphs and mini-buffer. */
25771 if ((row->reversed_p
25772 ? (w->phys_cursor.hpos >= 0)
25773 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
25774 {
25775 int on_p = w->phys_cursor_on_p;
25776 int x1;
25777 int hpos = w->phys_cursor.hpos;
25778
25779 /* When the window is hscrolled, cursor hpos can legitimately be
25780 out of bounds, but we draw the cursor at the corresponding
25781 window margin in that case. */
25782 if (!row->reversed_p && hpos < 0)
25783 hpos = 0;
25784 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
25785 hpos = row->used[TEXT_AREA] - 1;
25786
25787 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
25788 hl, 0);
25789 w->phys_cursor_on_p = on_p;
25790
25791 if (hl == DRAW_CURSOR)
25792 w->phys_cursor_width = x1 - w->phys_cursor.x;
25793 /* When we erase the cursor, and ROW is overlapped by other
25794 rows, make sure that these overlapping parts of other rows
25795 are redrawn. */
25796 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
25797 {
25798 w->phys_cursor_width = x1 - w->phys_cursor.x;
25799
25800 if (row > w->current_matrix->rows
25801 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
25802 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
25803 OVERLAPS_ERASED_CURSOR);
25804
25805 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
25806 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
25807 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
25808 OVERLAPS_ERASED_CURSOR);
25809 }
25810 }
25811 }
25812
25813
25814 /* EXPORT:
25815 Erase the image of a cursor of window W from the screen. */
25816
25817 void
25818 erase_phys_cursor (struct window *w)
25819 {
25820 struct frame *f = XFRAME (w->frame);
25821 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25822 int hpos = w->phys_cursor.hpos;
25823 int vpos = w->phys_cursor.vpos;
25824 int mouse_face_here_p = 0;
25825 struct glyph_matrix *active_glyphs = w->current_matrix;
25826 struct glyph_row *cursor_row;
25827 struct glyph *cursor_glyph;
25828 enum draw_glyphs_face hl;
25829
25830 /* No cursor displayed or row invalidated => nothing to do on the
25831 screen. */
25832 if (w->phys_cursor_type == NO_CURSOR)
25833 goto mark_cursor_off;
25834
25835 /* VPOS >= active_glyphs->nrows means that window has been resized.
25836 Don't bother to erase the cursor. */
25837 if (vpos >= active_glyphs->nrows)
25838 goto mark_cursor_off;
25839
25840 /* If row containing cursor is marked invalid, there is nothing we
25841 can do. */
25842 cursor_row = MATRIX_ROW (active_glyphs, vpos);
25843 if (!cursor_row->enabled_p)
25844 goto mark_cursor_off;
25845
25846 /* If line spacing is > 0, old cursor may only be partially visible in
25847 window after split-window. So adjust visible height. */
25848 cursor_row->visible_height = min (cursor_row->visible_height,
25849 window_text_bottom_y (w) - cursor_row->y);
25850
25851 /* If row is completely invisible, don't attempt to delete a cursor which
25852 isn't there. This can happen if cursor is at top of a window, and
25853 we switch to a buffer with a header line in that window. */
25854 if (cursor_row->visible_height <= 0)
25855 goto mark_cursor_off;
25856
25857 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
25858 if (cursor_row->cursor_in_fringe_p)
25859 {
25860 cursor_row->cursor_in_fringe_p = 0;
25861 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
25862 goto mark_cursor_off;
25863 }
25864
25865 /* This can happen when the new row is shorter than the old one.
25866 In this case, either draw_glyphs or clear_end_of_line
25867 should have cleared the cursor. Note that we wouldn't be
25868 able to erase the cursor in this case because we don't have a
25869 cursor glyph at hand. */
25870 if ((cursor_row->reversed_p
25871 ? (w->phys_cursor.hpos < 0)
25872 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
25873 goto mark_cursor_off;
25874
25875 /* When the window is hscrolled, cursor hpos can legitimately be out
25876 of bounds, but we draw the cursor at the corresponding window
25877 margin in that case. */
25878 if (!cursor_row->reversed_p && hpos < 0)
25879 hpos = 0;
25880 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
25881 hpos = cursor_row->used[TEXT_AREA] - 1;
25882
25883 /* If the cursor is in the mouse face area, redisplay that when
25884 we clear the cursor. */
25885 if (! NILP (hlinfo->mouse_face_window)
25886 && coords_in_mouse_face_p (w, hpos, vpos)
25887 /* Don't redraw the cursor's spot in mouse face if it is at the
25888 end of a line (on a newline). The cursor appears there, but
25889 mouse highlighting does not. */
25890 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
25891 mouse_face_here_p = 1;
25892
25893 /* Maybe clear the display under the cursor. */
25894 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
25895 {
25896 int x, y, left_x;
25897 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
25898 int width;
25899
25900 cursor_glyph = get_phys_cursor_glyph (w);
25901 if (cursor_glyph == NULL)
25902 goto mark_cursor_off;
25903
25904 width = cursor_glyph->pixel_width;
25905 left_x = window_box_left_offset (w, TEXT_AREA);
25906 x = w->phys_cursor.x;
25907 if (x < left_x)
25908 width -= left_x - x;
25909 width = min (width, window_box_width (w, TEXT_AREA) - x);
25910 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
25911 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
25912
25913 if (width > 0)
25914 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
25915 }
25916
25917 /* Erase the cursor by redrawing the character underneath it. */
25918 if (mouse_face_here_p)
25919 hl = DRAW_MOUSE_FACE;
25920 else
25921 hl = DRAW_NORMAL_TEXT;
25922 draw_phys_cursor_glyph (w, cursor_row, hl);
25923
25924 mark_cursor_off:
25925 w->phys_cursor_on_p = 0;
25926 w->phys_cursor_type = NO_CURSOR;
25927 }
25928
25929
25930 /* EXPORT:
25931 Display or clear cursor of window W. If ON is zero, clear the
25932 cursor. If it is non-zero, display the cursor. If ON is nonzero,
25933 where to put the cursor is specified by HPOS, VPOS, X and Y. */
25934
25935 void
25936 display_and_set_cursor (struct window *w, int on,
25937 int hpos, int vpos, int x, int y)
25938 {
25939 struct frame *f = XFRAME (w->frame);
25940 int new_cursor_type;
25941 int new_cursor_width;
25942 int active_cursor;
25943 struct glyph_row *glyph_row;
25944 struct glyph *glyph;
25945
25946 /* This is pointless on invisible frames, and dangerous on garbaged
25947 windows and frames; in the latter case, the frame or window may
25948 be in the midst of changing its size, and x and y may be off the
25949 window. */
25950 if (! FRAME_VISIBLE_P (f)
25951 || FRAME_GARBAGED_P (f)
25952 || vpos >= w->current_matrix->nrows
25953 || hpos >= w->current_matrix->matrix_w)
25954 return;
25955
25956 /* If cursor is off and we want it off, return quickly. */
25957 if (!on && !w->phys_cursor_on_p)
25958 return;
25959
25960 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
25961 /* If cursor row is not enabled, we don't really know where to
25962 display the cursor. */
25963 if (!glyph_row->enabled_p)
25964 {
25965 w->phys_cursor_on_p = 0;
25966 return;
25967 }
25968
25969 glyph = NULL;
25970 if (!glyph_row->exact_window_width_line_p
25971 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
25972 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
25973
25974 eassert (input_blocked_p ());
25975
25976 /* Set new_cursor_type to the cursor we want to be displayed. */
25977 new_cursor_type = get_window_cursor_type (w, glyph,
25978 &new_cursor_width, &active_cursor);
25979
25980 /* If cursor is currently being shown and we don't want it to be or
25981 it is in the wrong place, or the cursor type is not what we want,
25982 erase it. */
25983 if (w->phys_cursor_on_p
25984 && (!on
25985 || w->phys_cursor.x != x
25986 || w->phys_cursor.y != y
25987 || new_cursor_type != w->phys_cursor_type
25988 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
25989 && new_cursor_width != w->phys_cursor_width)))
25990 erase_phys_cursor (w);
25991
25992 /* Don't check phys_cursor_on_p here because that flag is only set
25993 to zero in some cases where we know that the cursor has been
25994 completely erased, to avoid the extra work of erasing the cursor
25995 twice. In other words, phys_cursor_on_p can be 1 and the cursor
25996 still not be visible, or it has only been partly erased. */
25997 if (on)
25998 {
25999 w->phys_cursor_ascent = glyph_row->ascent;
26000 w->phys_cursor_height = glyph_row->height;
26001
26002 /* Set phys_cursor_.* before x_draw_.* is called because some
26003 of them may need the information. */
26004 w->phys_cursor.x = x;
26005 w->phys_cursor.y = glyph_row->y;
26006 w->phys_cursor.hpos = hpos;
26007 w->phys_cursor.vpos = vpos;
26008 }
26009
26010 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26011 new_cursor_type, new_cursor_width,
26012 on, active_cursor);
26013 }
26014
26015
26016 /* Switch the display of W's cursor on or off, according to the value
26017 of ON. */
26018
26019 static void
26020 update_window_cursor (struct window *w, int on)
26021 {
26022 /* Don't update cursor in windows whose frame is in the process
26023 of being deleted. */
26024 if (w->current_matrix)
26025 {
26026 int hpos = w->phys_cursor.hpos;
26027 int vpos = w->phys_cursor.vpos;
26028 struct glyph_row *row;
26029
26030 if (vpos >= w->current_matrix->nrows
26031 || hpos >= w->current_matrix->matrix_w)
26032 return;
26033
26034 row = MATRIX_ROW (w->current_matrix, vpos);
26035
26036 /* When the window is hscrolled, cursor hpos can legitimately be
26037 out of bounds, but we draw the cursor at the corresponding
26038 window margin in that case. */
26039 if (!row->reversed_p && hpos < 0)
26040 hpos = 0;
26041 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26042 hpos = row->used[TEXT_AREA] - 1;
26043
26044 block_input ();
26045 display_and_set_cursor (w, on, hpos, vpos,
26046 w->phys_cursor.x, w->phys_cursor.y);
26047 unblock_input ();
26048 }
26049 }
26050
26051
26052 /* Call update_window_cursor with parameter ON_P on all leaf windows
26053 in the window tree rooted at W. */
26054
26055 static void
26056 update_cursor_in_window_tree (struct window *w, int on_p)
26057 {
26058 while (w)
26059 {
26060 if (!NILP (w->hchild))
26061 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
26062 else if (!NILP (w->vchild))
26063 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
26064 else
26065 update_window_cursor (w, on_p);
26066
26067 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26068 }
26069 }
26070
26071
26072 /* EXPORT:
26073 Display the cursor on window W, or clear it, according to ON_P.
26074 Don't change the cursor's position. */
26075
26076 void
26077 x_update_cursor (struct frame *f, int on_p)
26078 {
26079 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26080 }
26081
26082
26083 /* EXPORT:
26084 Clear the cursor of window W to background color, and mark the
26085 cursor as not shown. This is used when the text where the cursor
26086 is about to be rewritten. */
26087
26088 void
26089 x_clear_cursor (struct window *w)
26090 {
26091 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26092 update_window_cursor (w, 0);
26093 }
26094
26095 #endif /* HAVE_WINDOW_SYSTEM */
26096
26097 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26098 and MSDOS. */
26099 static void
26100 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26101 int start_hpos, int end_hpos,
26102 enum draw_glyphs_face draw)
26103 {
26104 #ifdef HAVE_WINDOW_SYSTEM
26105 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26106 {
26107 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26108 return;
26109 }
26110 #endif
26111 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26112 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26113 #endif
26114 }
26115
26116 /* Display the active region described by mouse_face_* according to DRAW. */
26117
26118 static void
26119 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26120 {
26121 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26122 struct frame *f = XFRAME (WINDOW_FRAME (w));
26123
26124 if (/* If window is in the process of being destroyed, don't bother
26125 to do anything. */
26126 w->current_matrix != NULL
26127 /* Don't update mouse highlight if hidden */
26128 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26129 /* Recognize when we are called to operate on rows that don't exist
26130 anymore. This can happen when a window is split. */
26131 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26132 {
26133 int phys_cursor_on_p = w->phys_cursor_on_p;
26134 struct glyph_row *row, *first, *last;
26135
26136 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26137 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26138
26139 for (row = first; row <= last && row->enabled_p; ++row)
26140 {
26141 int start_hpos, end_hpos, start_x;
26142
26143 /* For all but the first row, the highlight starts at column 0. */
26144 if (row == first)
26145 {
26146 /* R2L rows have BEG and END in reversed order, but the
26147 screen drawing geometry is always left to right. So
26148 we need to mirror the beginning and end of the
26149 highlighted area in R2L rows. */
26150 if (!row->reversed_p)
26151 {
26152 start_hpos = hlinfo->mouse_face_beg_col;
26153 start_x = hlinfo->mouse_face_beg_x;
26154 }
26155 else if (row == last)
26156 {
26157 start_hpos = hlinfo->mouse_face_end_col;
26158 start_x = hlinfo->mouse_face_end_x;
26159 }
26160 else
26161 {
26162 start_hpos = 0;
26163 start_x = 0;
26164 }
26165 }
26166 else if (row->reversed_p && row == last)
26167 {
26168 start_hpos = hlinfo->mouse_face_end_col;
26169 start_x = hlinfo->mouse_face_end_x;
26170 }
26171 else
26172 {
26173 start_hpos = 0;
26174 start_x = 0;
26175 }
26176
26177 if (row == last)
26178 {
26179 if (!row->reversed_p)
26180 end_hpos = hlinfo->mouse_face_end_col;
26181 else if (row == first)
26182 end_hpos = hlinfo->mouse_face_beg_col;
26183 else
26184 {
26185 end_hpos = row->used[TEXT_AREA];
26186 if (draw == DRAW_NORMAL_TEXT)
26187 row->fill_line_p = 1; /* Clear to end of line */
26188 }
26189 }
26190 else if (row->reversed_p && row == first)
26191 end_hpos = hlinfo->mouse_face_beg_col;
26192 else
26193 {
26194 end_hpos = row->used[TEXT_AREA];
26195 if (draw == DRAW_NORMAL_TEXT)
26196 row->fill_line_p = 1; /* Clear to end of line */
26197 }
26198
26199 if (end_hpos > start_hpos)
26200 {
26201 draw_row_with_mouse_face (w, start_x, row,
26202 start_hpos, end_hpos, draw);
26203
26204 row->mouse_face_p
26205 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26206 }
26207 }
26208
26209 #ifdef HAVE_WINDOW_SYSTEM
26210 /* When we've written over the cursor, arrange for it to
26211 be displayed again. */
26212 if (FRAME_WINDOW_P (f)
26213 && phys_cursor_on_p && !w->phys_cursor_on_p)
26214 {
26215 int hpos = w->phys_cursor.hpos;
26216
26217 /* When the window is hscrolled, cursor hpos can legitimately be
26218 out of bounds, but we draw the cursor at the corresponding
26219 window margin in that case. */
26220 if (!row->reversed_p && hpos < 0)
26221 hpos = 0;
26222 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26223 hpos = row->used[TEXT_AREA] - 1;
26224
26225 block_input ();
26226 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26227 w->phys_cursor.x, w->phys_cursor.y);
26228 unblock_input ();
26229 }
26230 #endif /* HAVE_WINDOW_SYSTEM */
26231 }
26232
26233 #ifdef HAVE_WINDOW_SYSTEM
26234 /* Change the mouse cursor. */
26235 if (FRAME_WINDOW_P (f))
26236 {
26237 if (draw == DRAW_NORMAL_TEXT
26238 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26239 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26240 else if (draw == DRAW_MOUSE_FACE)
26241 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26242 else
26243 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26244 }
26245 #endif /* HAVE_WINDOW_SYSTEM */
26246 }
26247
26248 /* EXPORT:
26249 Clear out the mouse-highlighted active region.
26250 Redraw it un-highlighted first. Value is non-zero if mouse
26251 face was actually drawn unhighlighted. */
26252
26253 int
26254 clear_mouse_face (Mouse_HLInfo *hlinfo)
26255 {
26256 int cleared = 0;
26257
26258 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26259 {
26260 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26261 cleared = 1;
26262 }
26263
26264 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26265 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26266 hlinfo->mouse_face_window = Qnil;
26267 hlinfo->mouse_face_overlay = Qnil;
26268 return cleared;
26269 }
26270
26271 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26272 within the mouse face on that window. */
26273 static int
26274 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26275 {
26276 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26277
26278 /* Quickly resolve the easy cases. */
26279 if (!(WINDOWP (hlinfo->mouse_face_window)
26280 && XWINDOW (hlinfo->mouse_face_window) == w))
26281 return 0;
26282 if (vpos < hlinfo->mouse_face_beg_row
26283 || vpos > hlinfo->mouse_face_end_row)
26284 return 0;
26285 if (vpos > hlinfo->mouse_face_beg_row
26286 && vpos < hlinfo->mouse_face_end_row)
26287 return 1;
26288
26289 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26290 {
26291 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26292 {
26293 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26294 return 1;
26295 }
26296 else if ((vpos == hlinfo->mouse_face_beg_row
26297 && hpos >= hlinfo->mouse_face_beg_col)
26298 || (vpos == hlinfo->mouse_face_end_row
26299 && hpos < hlinfo->mouse_face_end_col))
26300 return 1;
26301 }
26302 else
26303 {
26304 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26305 {
26306 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26307 return 1;
26308 }
26309 else if ((vpos == hlinfo->mouse_face_beg_row
26310 && hpos <= hlinfo->mouse_face_beg_col)
26311 || (vpos == hlinfo->mouse_face_end_row
26312 && hpos > hlinfo->mouse_face_end_col))
26313 return 1;
26314 }
26315 return 0;
26316 }
26317
26318
26319 /* EXPORT:
26320 Non-zero if physical cursor of window W is within mouse face. */
26321
26322 int
26323 cursor_in_mouse_face_p (struct window *w)
26324 {
26325 int hpos = w->phys_cursor.hpos;
26326 int vpos = w->phys_cursor.vpos;
26327 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26328
26329 /* When the window is hscrolled, cursor hpos can legitimately be out
26330 of bounds, but we draw the cursor at the corresponding window
26331 margin in that case. */
26332 if (!row->reversed_p && hpos < 0)
26333 hpos = 0;
26334 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26335 hpos = row->used[TEXT_AREA] - 1;
26336
26337 return coords_in_mouse_face_p (w, hpos, vpos);
26338 }
26339
26340
26341 \f
26342 /* Find the glyph rows START_ROW and END_ROW of window W that display
26343 characters between buffer positions START_CHARPOS and END_CHARPOS
26344 (excluding END_CHARPOS). DISP_STRING is a display string that
26345 covers these buffer positions. This is similar to
26346 row_containing_pos, but is more accurate when bidi reordering makes
26347 buffer positions change non-linearly with glyph rows. */
26348 static void
26349 rows_from_pos_range (struct window *w,
26350 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26351 Lisp_Object disp_string,
26352 struct glyph_row **start, struct glyph_row **end)
26353 {
26354 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26355 int last_y = window_text_bottom_y (w);
26356 struct glyph_row *row;
26357
26358 *start = NULL;
26359 *end = NULL;
26360
26361 while (!first->enabled_p
26362 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26363 first++;
26364
26365 /* Find the START row. */
26366 for (row = first;
26367 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26368 row++)
26369 {
26370 /* A row can potentially be the START row if the range of the
26371 characters it displays intersects the range
26372 [START_CHARPOS..END_CHARPOS). */
26373 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26374 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26375 /* See the commentary in row_containing_pos, for the
26376 explanation of the complicated way to check whether
26377 some position is beyond the end of the characters
26378 displayed by a row. */
26379 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26380 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26381 && !row->ends_at_zv_p
26382 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26383 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26384 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26385 && !row->ends_at_zv_p
26386 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26387 {
26388 /* Found a candidate row. Now make sure at least one of the
26389 glyphs it displays has a charpos from the range
26390 [START_CHARPOS..END_CHARPOS).
26391
26392 This is not obvious because bidi reordering could make
26393 buffer positions of a row be 1,2,3,102,101,100, and if we
26394 want to highlight characters in [50..60), we don't want
26395 this row, even though [50..60) does intersect [1..103),
26396 the range of character positions given by the row's start
26397 and end positions. */
26398 struct glyph *g = row->glyphs[TEXT_AREA];
26399 struct glyph *e = g + row->used[TEXT_AREA];
26400
26401 while (g < e)
26402 {
26403 if (((BUFFERP (g->object) || INTEGERP (g->object))
26404 && start_charpos <= g->charpos && g->charpos < end_charpos)
26405 /* A glyph that comes from DISP_STRING is by
26406 definition to be highlighted. */
26407 || EQ (g->object, disp_string))
26408 *start = row;
26409 g++;
26410 }
26411 if (*start)
26412 break;
26413 }
26414 }
26415
26416 /* Find the END row. */
26417 if (!*start
26418 /* If the last row is partially visible, start looking for END
26419 from that row, instead of starting from FIRST. */
26420 && !(row->enabled_p
26421 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26422 row = first;
26423 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26424 {
26425 struct glyph_row *next = row + 1;
26426 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26427
26428 if (!next->enabled_p
26429 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26430 /* The first row >= START whose range of displayed characters
26431 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26432 is the row END + 1. */
26433 || (start_charpos < next_start
26434 && end_charpos < next_start)
26435 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26436 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26437 && !next->ends_at_zv_p
26438 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26439 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26440 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26441 && !next->ends_at_zv_p
26442 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26443 {
26444 *end = row;
26445 break;
26446 }
26447 else
26448 {
26449 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26450 but none of the characters it displays are in the range, it is
26451 also END + 1. */
26452 struct glyph *g = next->glyphs[TEXT_AREA];
26453 struct glyph *s = g;
26454 struct glyph *e = g + next->used[TEXT_AREA];
26455
26456 while (g < e)
26457 {
26458 if (((BUFFERP (g->object) || INTEGERP (g->object))
26459 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26460 /* If the buffer position of the first glyph in
26461 the row is equal to END_CHARPOS, it means
26462 the last character to be highlighted is the
26463 newline of ROW, and we must consider NEXT as
26464 END, not END+1. */
26465 || (((!next->reversed_p && g == s)
26466 || (next->reversed_p && g == e - 1))
26467 && (g->charpos == end_charpos
26468 /* Special case for when NEXT is an
26469 empty line at ZV. */
26470 || (g->charpos == -1
26471 && !row->ends_at_zv_p
26472 && next_start == end_charpos)))))
26473 /* A glyph that comes from DISP_STRING is by
26474 definition to be highlighted. */
26475 || EQ (g->object, disp_string))
26476 break;
26477 g++;
26478 }
26479 if (g == e)
26480 {
26481 *end = row;
26482 break;
26483 }
26484 /* The first row that ends at ZV must be the last to be
26485 highlighted. */
26486 else if (next->ends_at_zv_p)
26487 {
26488 *end = next;
26489 break;
26490 }
26491 }
26492 }
26493 }
26494
26495 /* This function sets the mouse_face_* elements of HLINFO, assuming
26496 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26497 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26498 for the overlay or run of text properties specifying the mouse
26499 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26500 before-string and after-string that must also be highlighted.
26501 DISP_STRING, if non-nil, is a display string that may cover some
26502 or all of the highlighted text. */
26503
26504 static void
26505 mouse_face_from_buffer_pos (Lisp_Object window,
26506 Mouse_HLInfo *hlinfo,
26507 ptrdiff_t mouse_charpos,
26508 ptrdiff_t start_charpos,
26509 ptrdiff_t end_charpos,
26510 Lisp_Object before_string,
26511 Lisp_Object after_string,
26512 Lisp_Object disp_string)
26513 {
26514 struct window *w = XWINDOW (window);
26515 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26516 struct glyph_row *r1, *r2;
26517 struct glyph *glyph, *end;
26518 ptrdiff_t ignore, pos;
26519 int x;
26520
26521 eassert (NILP (disp_string) || STRINGP (disp_string));
26522 eassert (NILP (before_string) || STRINGP (before_string));
26523 eassert (NILP (after_string) || STRINGP (after_string));
26524
26525 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26526 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26527 if (r1 == NULL)
26528 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26529 /* If the before-string or display-string contains newlines,
26530 rows_from_pos_range skips to its last row. Move back. */
26531 if (!NILP (before_string) || !NILP (disp_string))
26532 {
26533 struct glyph_row *prev;
26534 while ((prev = r1 - 1, prev >= first)
26535 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
26536 && prev->used[TEXT_AREA] > 0)
26537 {
26538 struct glyph *beg = prev->glyphs[TEXT_AREA];
26539 glyph = beg + prev->used[TEXT_AREA];
26540 while (--glyph >= beg && INTEGERP (glyph->object));
26541 if (glyph < beg
26542 || !(EQ (glyph->object, before_string)
26543 || EQ (glyph->object, disp_string)))
26544 break;
26545 r1 = prev;
26546 }
26547 }
26548 if (r2 == NULL)
26549 {
26550 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26551 hlinfo->mouse_face_past_end = 1;
26552 }
26553 else if (!NILP (after_string))
26554 {
26555 /* If the after-string has newlines, advance to its last row. */
26556 struct glyph_row *next;
26557 struct glyph_row *last
26558 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26559
26560 for (next = r2 + 1;
26561 next <= last
26562 && next->used[TEXT_AREA] > 0
26563 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
26564 ++next)
26565 r2 = next;
26566 }
26567 /* The rest of the display engine assumes that mouse_face_beg_row is
26568 either above mouse_face_end_row or identical to it. But with
26569 bidi-reordered continued lines, the row for START_CHARPOS could
26570 be below the row for END_CHARPOS. If so, swap the rows and store
26571 them in correct order. */
26572 if (r1->y > r2->y)
26573 {
26574 struct glyph_row *tem = r2;
26575
26576 r2 = r1;
26577 r1 = tem;
26578 }
26579
26580 hlinfo->mouse_face_beg_y = r1->y;
26581 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
26582 hlinfo->mouse_face_end_y = r2->y;
26583 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
26584
26585 /* For a bidi-reordered row, the positions of BEFORE_STRING,
26586 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
26587 could be anywhere in the row and in any order. The strategy
26588 below is to find the leftmost and the rightmost glyph that
26589 belongs to either of these 3 strings, or whose position is
26590 between START_CHARPOS and END_CHARPOS, and highlight all the
26591 glyphs between those two. This may cover more than just the text
26592 between START_CHARPOS and END_CHARPOS if the range of characters
26593 strides the bidi level boundary, e.g. if the beginning is in R2L
26594 text while the end is in L2R text or vice versa. */
26595 if (!r1->reversed_p)
26596 {
26597 /* This row is in a left to right paragraph. Scan it left to
26598 right. */
26599 glyph = r1->glyphs[TEXT_AREA];
26600 end = glyph + r1->used[TEXT_AREA];
26601 x = r1->x;
26602
26603 /* Skip truncation glyphs at the start of the glyph row. */
26604 if (r1->displays_text_p)
26605 for (; glyph < end
26606 && INTEGERP (glyph->object)
26607 && glyph->charpos < 0;
26608 ++glyph)
26609 x += glyph->pixel_width;
26610
26611 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26612 or DISP_STRING, and the first glyph from buffer whose
26613 position is between START_CHARPOS and END_CHARPOS. */
26614 for (; glyph < end
26615 && !INTEGERP (glyph->object)
26616 && !EQ (glyph->object, disp_string)
26617 && !(BUFFERP (glyph->object)
26618 && (glyph->charpos >= start_charpos
26619 && glyph->charpos < end_charpos));
26620 ++glyph)
26621 {
26622 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26623 are present at buffer positions between START_CHARPOS and
26624 END_CHARPOS, or if they come from an overlay. */
26625 if (EQ (glyph->object, before_string))
26626 {
26627 pos = string_buffer_position (before_string,
26628 start_charpos);
26629 /* If pos == 0, it means before_string came from an
26630 overlay, not from a buffer position. */
26631 if (!pos || (pos >= start_charpos && pos < end_charpos))
26632 break;
26633 }
26634 else if (EQ (glyph->object, after_string))
26635 {
26636 pos = string_buffer_position (after_string, end_charpos);
26637 if (!pos || (pos >= start_charpos && pos < end_charpos))
26638 break;
26639 }
26640 x += glyph->pixel_width;
26641 }
26642 hlinfo->mouse_face_beg_x = x;
26643 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26644 }
26645 else
26646 {
26647 /* This row is in a right to left paragraph. Scan it right to
26648 left. */
26649 struct glyph *g;
26650
26651 end = r1->glyphs[TEXT_AREA] - 1;
26652 glyph = end + r1->used[TEXT_AREA];
26653
26654 /* Skip truncation glyphs at the start of the glyph row. */
26655 if (r1->displays_text_p)
26656 for (; glyph > end
26657 && INTEGERP (glyph->object)
26658 && glyph->charpos < 0;
26659 --glyph)
26660 ;
26661
26662 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26663 or DISP_STRING, and the first glyph from buffer whose
26664 position is between START_CHARPOS and END_CHARPOS. */
26665 for (; glyph > end
26666 && !INTEGERP (glyph->object)
26667 && !EQ (glyph->object, disp_string)
26668 && !(BUFFERP (glyph->object)
26669 && (glyph->charpos >= start_charpos
26670 && glyph->charpos < end_charpos));
26671 --glyph)
26672 {
26673 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26674 are present at buffer positions between START_CHARPOS and
26675 END_CHARPOS, or if they come from an overlay. */
26676 if (EQ (glyph->object, before_string))
26677 {
26678 pos = string_buffer_position (before_string, start_charpos);
26679 /* If pos == 0, it means before_string came from an
26680 overlay, not from a buffer position. */
26681 if (!pos || (pos >= start_charpos && pos < end_charpos))
26682 break;
26683 }
26684 else if (EQ (glyph->object, after_string))
26685 {
26686 pos = string_buffer_position (after_string, end_charpos);
26687 if (!pos || (pos >= start_charpos && pos < end_charpos))
26688 break;
26689 }
26690 }
26691
26692 glyph++; /* first glyph to the right of the highlighted area */
26693 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
26694 x += g->pixel_width;
26695 hlinfo->mouse_face_beg_x = x;
26696 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26697 }
26698
26699 /* If the highlight ends in a different row, compute GLYPH and END
26700 for the end row. Otherwise, reuse the values computed above for
26701 the row where the highlight begins. */
26702 if (r2 != r1)
26703 {
26704 if (!r2->reversed_p)
26705 {
26706 glyph = r2->glyphs[TEXT_AREA];
26707 end = glyph + r2->used[TEXT_AREA];
26708 x = r2->x;
26709 }
26710 else
26711 {
26712 end = r2->glyphs[TEXT_AREA] - 1;
26713 glyph = end + r2->used[TEXT_AREA];
26714 }
26715 }
26716
26717 if (!r2->reversed_p)
26718 {
26719 /* Skip truncation and continuation glyphs near the end of the
26720 row, and also blanks and stretch glyphs inserted by
26721 extend_face_to_end_of_line. */
26722 while (end > glyph
26723 && INTEGERP ((end - 1)->object))
26724 --end;
26725 /* Scan the rest of the glyph row from the end, looking for the
26726 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26727 DISP_STRING, or whose position is between START_CHARPOS
26728 and END_CHARPOS */
26729 for (--end;
26730 end > glyph
26731 && !INTEGERP (end->object)
26732 && !EQ (end->object, disp_string)
26733 && !(BUFFERP (end->object)
26734 && (end->charpos >= start_charpos
26735 && end->charpos < end_charpos));
26736 --end)
26737 {
26738 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26739 are present at buffer positions between START_CHARPOS and
26740 END_CHARPOS, or if they come from an overlay. */
26741 if (EQ (end->object, before_string))
26742 {
26743 pos = string_buffer_position (before_string, start_charpos);
26744 if (!pos || (pos >= start_charpos && pos < end_charpos))
26745 break;
26746 }
26747 else if (EQ (end->object, after_string))
26748 {
26749 pos = string_buffer_position (after_string, end_charpos);
26750 if (!pos || (pos >= start_charpos && pos < end_charpos))
26751 break;
26752 }
26753 }
26754 /* Find the X coordinate of the last glyph to be highlighted. */
26755 for (; glyph <= end; ++glyph)
26756 x += glyph->pixel_width;
26757
26758 hlinfo->mouse_face_end_x = x;
26759 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
26760 }
26761 else
26762 {
26763 /* Skip truncation and continuation glyphs near the end of the
26764 row, and also blanks and stretch glyphs inserted by
26765 extend_face_to_end_of_line. */
26766 x = r2->x;
26767 end++;
26768 while (end < glyph
26769 && INTEGERP (end->object))
26770 {
26771 x += end->pixel_width;
26772 ++end;
26773 }
26774 /* Scan the rest of the glyph row from the end, looking for the
26775 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26776 DISP_STRING, or whose position is between START_CHARPOS
26777 and END_CHARPOS */
26778 for ( ;
26779 end < glyph
26780 && !INTEGERP (end->object)
26781 && !EQ (end->object, disp_string)
26782 && !(BUFFERP (end->object)
26783 && (end->charpos >= start_charpos
26784 && end->charpos < end_charpos));
26785 ++end)
26786 {
26787 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26788 are present at buffer positions between START_CHARPOS and
26789 END_CHARPOS, or if they come from an overlay. */
26790 if (EQ (end->object, before_string))
26791 {
26792 pos = string_buffer_position (before_string, start_charpos);
26793 if (!pos || (pos >= start_charpos && pos < end_charpos))
26794 break;
26795 }
26796 else if (EQ (end->object, after_string))
26797 {
26798 pos = string_buffer_position (after_string, end_charpos);
26799 if (!pos || (pos >= start_charpos && pos < end_charpos))
26800 break;
26801 }
26802 x += end->pixel_width;
26803 }
26804 /* If we exited the above loop because we arrived at the last
26805 glyph of the row, and its buffer position is still not in
26806 range, it means the last character in range is the preceding
26807 newline. Bump the end column and x values to get past the
26808 last glyph. */
26809 if (end == glyph
26810 && BUFFERP (end->object)
26811 && (end->charpos < start_charpos
26812 || end->charpos >= end_charpos))
26813 {
26814 x += end->pixel_width;
26815 ++end;
26816 }
26817 hlinfo->mouse_face_end_x = x;
26818 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
26819 }
26820
26821 hlinfo->mouse_face_window = window;
26822 hlinfo->mouse_face_face_id
26823 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
26824 mouse_charpos + 1,
26825 !hlinfo->mouse_face_hidden, -1);
26826 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26827 }
26828
26829 /* The following function is not used anymore (replaced with
26830 mouse_face_from_string_pos), but I leave it here for the time
26831 being, in case someone would. */
26832
26833 #if 0 /* not used */
26834
26835 /* Find the position of the glyph for position POS in OBJECT in
26836 window W's current matrix, and return in *X, *Y the pixel
26837 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
26838
26839 RIGHT_P non-zero means return the position of the right edge of the
26840 glyph, RIGHT_P zero means return the left edge position.
26841
26842 If no glyph for POS exists in the matrix, return the position of
26843 the glyph with the next smaller position that is in the matrix, if
26844 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
26845 exists in the matrix, return the position of the glyph with the
26846 next larger position in OBJECT.
26847
26848 Value is non-zero if a glyph was found. */
26849
26850 static int
26851 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
26852 int *hpos, int *vpos, int *x, int *y, int right_p)
26853 {
26854 int yb = window_text_bottom_y (w);
26855 struct glyph_row *r;
26856 struct glyph *best_glyph = NULL;
26857 struct glyph_row *best_row = NULL;
26858 int best_x = 0;
26859
26860 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26861 r->enabled_p && r->y < yb;
26862 ++r)
26863 {
26864 struct glyph *g = r->glyphs[TEXT_AREA];
26865 struct glyph *e = g + r->used[TEXT_AREA];
26866 int gx;
26867
26868 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26869 if (EQ (g->object, object))
26870 {
26871 if (g->charpos == pos)
26872 {
26873 best_glyph = g;
26874 best_x = gx;
26875 best_row = r;
26876 goto found;
26877 }
26878 else if (best_glyph == NULL
26879 || ((eabs (g->charpos - pos)
26880 < eabs (best_glyph->charpos - pos))
26881 && (right_p
26882 ? g->charpos < pos
26883 : g->charpos > pos)))
26884 {
26885 best_glyph = g;
26886 best_x = gx;
26887 best_row = r;
26888 }
26889 }
26890 }
26891
26892 found:
26893
26894 if (best_glyph)
26895 {
26896 *x = best_x;
26897 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
26898
26899 if (right_p)
26900 {
26901 *x += best_glyph->pixel_width;
26902 ++*hpos;
26903 }
26904
26905 *y = best_row->y;
26906 *vpos = best_row - w->current_matrix->rows;
26907 }
26908
26909 return best_glyph != NULL;
26910 }
26911 #endif /* not used */
26912
26913 /* Find the positions of the first and the last glyphs in window W's
26914 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
26915 (assumed to be a string), and return in HLINFO's mouse_face_*
26916 members the pixel and column/row coordinates of those glyphs. */
26917
26918 static void
26919 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
26920 Lisp_Object object,
26921 ptrdiff_t startpos, ptrdiff_t endpos)
26922 {
26923 int yb = window_text_bottom_y (w);
26924 struct glyph_row *r;
26925 struct glyph *g, *e;
26926 int gx;
26927 int found = 0;
26928
26929 /* Find the glyph row with at least one position in the range
26930 [STARTPOS..ENDPOS], and the first glyph in that row whose
26931 position belongs to that range. */
26932 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26933 r->enabled_p && r->y < yb;
26934 ++r)
26935 {
26936 if (!r->reversed_p)
26937 {
26938 g = r->glyphs[TEXT_AREA];
26939 e = g + r->used[TEXT_AREA];
26940 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26941 if (EQ (g->object, object)
26942 && startpos <= g->charpos && g->charpos <= endpos)
26943 {
26944 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
26945 hlinfo->mouse_face_beg_y = r->y;
26946 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26947 hlinfo->mouse_face_beg_x = gx;
26948 found = 1;
26949 break;
26950 }
26951 }
26952 else
26953 {
26954 struct glyph *g1;
26955
26956 e = r->glyphs[TEXT_AREA];
26957 g = e + r->used[TEXT_AREA];
26958 for ( ; g > e; --g)
26959 if (EQ ((g-1)->object, object)
26960 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
26961 {
26962 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
26963 hlinfo->mouse_face_beg_y = r->y;
26964 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26965 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
26966 gx += g1->pixel_width;
26967 hlinfo->mouse_face_beg_x = gx;
26968 found = 1;
26969 break;
26970 }
26971 }
26972 if (found)
26973 break;
26974 }
26975
26976 if (!found)
26977 return;
26978
26979 /* Starting with the next row, look for the first row which does NOT
26980 include any glyphs whose positions are in the range. */
26981 for (++r; r->enabled_p && r->y < yb; ++r)
26982 {
26983 g = r->glyphs[TEXT_AREA];
26984 e = g + r->used[TEXT_AREA];
26985 found = 0;
26986 for ( ; g < e; ++g)
26987 if (EQ (g->object, object)
26988 && startpos <= g->charpos && g->charpos <= endpos)
26989 {
26990 found = 1;
26991 break;
26992 }
26993 if (!found)
26994 break;
26995 }
26996
26997 /* The highlighted region ends on the previous row. */
26998 r--;
26999
27000 /* Set the end row and its vertical pixel coordinate. */
27001 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
27002 hlinfo->mouse_face_end_y = r->y;
27003
27004 /* Compute and set the end column and the end column's horizontal
27005 pixel coordinate. */
27006 if (!r->reversed_p)
27007 {
27008 g = r->glyphs[TEXT_AREA];
27009 e = g + r->used[TEXT_AREA];
27010 for ( ; e > g; --e)
27011 if (EQ ((e-1)->object, object)
27012 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27013 break;
27014 hlinfo->mouse_face_end_col = e - g;
27015
27016 for (gx = r->x; g < e; ++g)
27017 gx += g->pixel_width;
27018 hlinfo->mouse_face_end_x = gx;
27019 }
27020 else
27021 {
27022 e = r->glyphs[TEXT_AREA];
27023 g = e + r->used[TEXT_AREA];
27024 for (gx = r->x ; e < g; ++e)
27025 {
27026 if (EQ (e->object, object)
27027 && startpos <= e->charpos && e->charpos <= endpos)
27028 break;
27029 gx += e->pixel_width;
27030 }
27031 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27032 hlinfo->mouse_face_end_x = gx;
27033 }
27034 }
27035
27036 #ifdef HAVE_WINDOW_SYSTEM
27037
27038 /* See if position X, Y is within a hot-spot of an image. */
27039
27040 static int
27041 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27042 {
27043 if (!CONSP (hot_spot))
27044 return 0;
27045
27046 if (EQ (XCAR (hot_spot), Qrect))
27047 {
27048 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27049 Lisp_Object rect = XCDR (hot_spot);
27050 Lisp_Object tem;
27051 if (!CONSP (rect))
27052 return 0;
27053 if (!CONSP (XCAR (rect)))
27054 return 0;
27055 if (!CONSP (XCDR (rect)))
27056 return 0;
27057 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27058 return 0;
27059 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27060 return 0;
27061 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27062 return 0;
27063 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27064 return 0;
27065 return 1;
27066 }
27067 else if (EQ (XCAR (hot_spot), Qcircle))
27068 {
27069 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27070 Lisp_Object circ = XCDR (hot_spot);
27071 Lisp_Object lr, lx0, ly0;
27072 if (CONSP (circ)
27073 && CONSP (XCAR (circ))
27074 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27075 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27076 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27077 {
27078 double r = XFLOATINT (lr);
27079 double dx = XINT (lx0) - x;
27080 double dy = XINT (ly0) - y;
27081 return (dx * dx + dy * dy <= r * r);
27082 }
27083 }
27084 else if (EQ (XCAR (hot_spot), Qpoly))
27085 {
27086 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27087 if (VECTORP (XCDR (hot_spot)))
27088 {
27089 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27090 Lisp_Object *poly = v->contents;
27091 ptrdiff_t n = v->header.size;
27092 ptrdiff_t i;
27093 int inside = 0;
27094 Lisp_Object lx, ly;
27095 int x0, y0;
27096
27097 /* Need an even number of coordinates, and at least 3 edges. */
27098 if (n < 6 || n & 1)
27099 return 0;
27100
27101 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27102 If count is odd, we are inside polygon. Pixels on edges
27103 may or may not be included depending on actual geometry of the
27104 polygon. */
27105 if ((lx = poly[n-2], !INTEGERP (lx))
27106 || (ly = poly[n-1], !INTEGERP (lx)))
27107 return 0;
27108 x0 = XINT (lx), y0 = XINT (ly);
27109 for (i = 0; i < n; i += 2)
27110 {
27111 int x1 = x0, y1 = y0;
27112 if ((lx = poly[i], !INTEGERP (lx))
27113 || (ly = poly[i+1], !INTEGERP (ly)))
27114 return 0;
27115 x0 = XINT (lx), y0 = XINT (ly);
27116
27117 /* Does this segment cross the X line? */
27118 if (x0 >= x)
27119 {
27120 if (x1 >= x)
27121 continue;
27122 }
27123 else if (x1 < x)
27124 continue;
27125 if (y > y0 && y > y1)
27126 continue;
27127 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27128 inside = !inside;
27129 }
27130 return inside;
27131 }
27132 }
27133 return 0;
27134 }
27135
27136 Lisp_Object
27137 find_hot_spot (Lisp_Object map, int x, int y)
27138 {
27139 while (CONSP (map))
27140 {
27141 if (CONSP (XCAR (map))
27142 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27143 return XCAR (map);
27144 map = XCDR (map);
27145 }
27146
27147 return Qnil;
27148 }
27149
27150 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27151 3, 3, 0,
27152 doc: /* Lookup in image map MAP coordinates X and Y.
27153 An image map is an alist where each element has the format (AREA ID PLIST).
27154 An AREA is specified as either a rectangle, a circle, or a polygon:
27155 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27156 pixel coordinates of the upper left and bottom right corners.
27157 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27158 and the radius of the circle; r may be a float or integer.
27159 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27160 vector describes one corner in the polygon.
27161 Returns the alist element for the first matching AREA in MAP. */)
27162 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27163 {
27164 if (NILP (map))
27165 return Qnil;
27166
27167 CHECK_NUMBER (x);
27168 CHECK_NUMBER (y);
27169
27170 return find_hot_spot (map,
27171 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27172 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27173 }
27174
27175
27176 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27177 static void
27178 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27179 {
27180 /* Do not change cursor shape while dragging mouse. */
27181 if (!NILP (do_mouse_tracking))
27182 return;
27183
27184 if (!NILP (pointer))
27185 {
27186 if (EQ (pointer, Qarrow))
27187 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27188 else if (EQ (pointer, Qhand))
27189 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27190 else if (EQ (pointer, Qtext))
27191 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27192 else if (EQ (pointer, intern ("hdrag")))
27193 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27194 #ifdef HAVE_X_WINDOWS
27195 else if (EQ (pointer, intern ("vdrag")))
27196 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27197 #endif
27198 else if (EQ (pointer, intern ("hourglass")))
27199 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27200 else if (EQ (pointer, Qmodeline))
27201 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27202 else
27203 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27204 }
27205
27206 if (cursor != No_Cursor)
27207 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27208 }
27209
27210 #endif /* HAVE_WINDOW_SYSTEM */
27211
27212 /* Take proper action when mouse has moved to the mode or header line
27213 or marginal area AREA of window W, x-position X and y-position Y.
27214 X is relative to the start of the text display area of W, so the
27215 width of bitmap areas and scroll bars must be subtracted to get a
27216 position relative to the start of the mode line. */
27217
27218 static void
27219 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27220 enum window_part area)
27221 {
27222 struct window *w = XWINDOW (window);
27223 struct frame *f = XFRAME (w->frame);
27224 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27225 #ifdef HAVE_WINDOW_SYSTEM
27226 Display_Info *dpyinfo;
27227 #endif
27228 Cursor cursor = No_Cursor;
27229 Lisp_Object pointer = Qnil;
27230 int dx, dy, width, height;
27231 ptrdiff_t charpos;
27232 Lisp_Object string, object = Qnil;
27233 Lisp_Object pos IF_LINT (= Qnil), help;
27234
27235 Lisp_Object mouse_face;
27236 int original_x_pixel = x;
27237 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27238 struct glyph_row *row IF_LINT (= 0);
27239
27240 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27241 {
27242 int x0;
27243 struct glyph *end;
27244
27245 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27246 returns them in row/column units! */
27247 string = mode_line_string (w, area, &x, &y, &charpos,
27248 &object, &dx, &dy, &width, &height);
27249
27250 row = (area == ON_MODE_LINE
27251 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27252 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27253
27254 /* Find the glyph under the mouse pointer. */
27255 if (row->mode_line_p && row->enabled_p)
27256 {
27257 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27258 end = glyph + row->used[TEXT_AREA];
27259
27260 for (x0 = original_x_pixel;
27261 glyph < end && x0 >= glyph->pixel_width;
27262 ++glyph)
27263 x0 -= glyph->pixel_width;
27264
27265 if (glyph >= end)
27266 glyph = NULL;
27267 }
27268 }
27269 else
27270 {
27271 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27272 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27273 returns them in row/column units! */
27274 string = marginal_area_string (w, area, &x, &y, &charpos,
27275 &object, &dx, &dy, &width, &height);
27276 }
27277
27278 help = Qnil;
27279
27280 #ifdef HAVE_WINDOW_SYSTEM
27281 if (IMAGEP (object))
27282 {
27283 Lisp_Object image_map, hotspot;
27284 if ((image_map = Fplist_get (XCDR (object), QCmap),
27285 !NILP (image_map))
27286 && (hotspot = find_hot_spot (image_map, dx, dy),
27287 CONSP (hotspot))
27288 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27289 {
27290 Lisp_Object plist;
27291
27292 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27293 If so, we could look for mouse-enter, mouse-leave
27294 properties in PLIST (and do something...). */
27295 hotspot = XCDR (hotspot);
27296 if (CONSP (hotspot)
27297 && (plist = XCAR (hotspot), CONSP (plist)))
27298 {
27299 pointer = Fplist_get (plist, Qpointer);
27300 if (NILP (pointer))
27301 pointer = Qhand;
27302 help = Fplist_get (plist, Qhelp_echo);
27303 if (!NILP (help))
27304 {
27305 help_echo_string = help;
27306 XSETWINDOW (help_echo_window, w);
27307 help_echo_object = w->buffer;
27308 help_echo_pos = charpos;
27309 }
27310 }
27311 }
27312 if (NILP (pointer))
27313 pointer = Fplist_get (XCDR (object), QCpointer);
27314 }
27315 #endif /* HAVE_WINDOW_SYSTEM */
27316
27317 if (STRINGP (string))
27318 pos = make_number (charpos);
27319
27320 /* Set the help text and mouse pointer. If the mouse is on a part
27321 of the mode line without any text (e.g. past the right edge of
27322 the mode line text), use the default help text and pointer. */
27323 if (STRINGP (string) || area == ON_MODE_LINE)
27324 {
27325 /* Arrange to display the help by setting the global variables
27326 help_echo_string, help_echo_object, and help_echo_pos. */
27327 if (NILP (help))
27328 {
27329 if (STRINGP (string))
27330 help = Fget_text_property (pos, Qhelp_echo, string);
27331
27332 if (!NILP (help))
27333 {
27334 help_echo_string = help;
27335 XSETWINDOW (help_echo_window, w);
27336 help_echo_object = string;
27337 help_echo_pos = charpos;
27338 }
27339 else if (area == ON_MODE_LINE)
27340 {
27341 Lisp_Object default_help
27342 = buffer_local_value_1 (Qmode_line_default_help_echo,
27343 w->buffer);
27344
27345 if (STRINGP (default_help))
27346 {
27347 help_echo_string = default_help;
27348 XSETWINDOW (help_echo_window, w);
27349 help_echo_object = Qnil;
27350 help_echo_pos = -1;
27351 }
27352 }
27353 }
27354
27355 #ifdef HAVE_WINDOW_SYSTEM
27356 /* Change the mouse pointer according to what is under it. */
27357 if (FRAME_WINDOW_P (f))
27358 {
27359 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27360 if (STRINGP (string))
27361 {
27362 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27363
27364 if (NILP (pointer))
27365 pointer = Fget_text_property (pos, Qpointer, string);
27366
27367 /* Change the mouse pointer according to what is under X/Y. */
27368 if (NILP (pointer)
27369 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27370 {
27371 Lisp_Object map;
27372 map = Fget_text_property (pos, Qlocal_map, string);
27373 if (!KEYMAPP (map))
27374 map = Fget_text_property (pos, Qkeymap, string);
27375 if (!KEYMAPP (map))
27376 cursor = dpyinfo->vertical_scroll_bar_cursor;
27377 }
27378 }
27379 else
27380 /* Default mode-line pointer. */
27381 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27382 }
27383 #endif
27384 }
27385
27386 /* Change the mouse face according to what is under X/Y. */
27387 if (STRINGP (string))
27388 {
27389 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27390 if (!NILP (mouse_face)
27391 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27392 && glyph)
27393 {
27394 Lisp_Object b, e;
27395
27396 struct glyph * tmp_glyph;
27397
27398 int gpos;
27399 int gseq_length;
27400 int total_pixel_width;
27401 ptrdiff_t begpos, endpos, ignore;
27402
27403 int vpos, hpos;
27404
27405 b = Fprevious_single_property_change (make_number (charpos + 1),
27406 Qmouse_face, string, Qnil);
27407 if (NILP (b))
27408 begpos = 0;
27409 else
27410 begpos = XINT (b);
27411
27412 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27413 if (NILP (e))
27414 endpos = SCHARS (string);
27415 else
27416 endpos = XINT (e);
27417
27418 /* Calculate the glyph position GPOS of GLYPH in the
27419 displayed string, relative to the beginning of the
27420 highlighted part of the string.
27421
27422 Note: GPOS is different from CHARPOS. CHARPOS is the
27423 position of GLYPH in the internal string object. A mode
27424 line string format has structures which are converted to
27425 a flattened string by the Emacs Lisp interpreter. The
27426 internal string is an element of those structures. The
27427 displayed string is the flattened string. */
27428 tmp_glyph = row_start_glyph;
27429 while (tmp_glyph < glyph
27430 && (!(EQ (tmp_glyph->object, glyph->object)
27431 && begpos <= tmp_glyph->charpos
27432 && tmp_glyph->charpos < endpos)))
27433 tmp_glyph++;
27434 gpos = glyph - tmp_glyph;
27435
27436 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27437 the highlighted part of the displayed string to which
27438 GLYPH belongs. Note: GSEQ_LENGTH is different from
27439 SCHARS (STRING), because the latter returns the length of
27440 the internal string. */
27441 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27442 tmp_glyph > glyph
27443 && (!(EQ (tmp_glyph->object, glyph->object)
27444 && begpos <= tmp_glyph->charpos
27445 && tmp_glyph->charpos < endpos));
27446 tmp_glyph--)
27447 ;
27448 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27449
27450 /* Calculate the total pixel width of all the glyphs between
27451 the beginning of the highlighted area and GLYPH. */
27452 total_pixel_width = 0;
27453 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27454 total_pixel_width += tmp_glyph->pixel_width;
27455
27456 /* Pre calculation of re-rendering position. Note: X is in
27457 column units here, after the call to mode_line_string or
27458 marginal_area_string. */
27459 hpos = x - gpos;
27460 vpos = (area == ON_MODE_LINE
27461 ? (w->current_matrix)->nrows - 1
27462 : 0);
27463
27464 /* If GLYPH's position is included in the region that is
27465 already drawn in mouse face, we have nothing to do. */
27466 if ( EQ (window, hlinfo->mouse_face_window)
27467 && (!row->reversed_p
27468 ? (hlinfo->mouse_face_beg_col <= hpos
27469 && hpos < hlinfo->mouse_face_end_col)
27470 /* In R2L rows we swap BEG and END, see below. */
27471 : (hlinfo->mouse_face_end_col <= hpos
27472 && hpos < hlinfo->mouse_face_beg_col))
27473 && hlinfo->mouse_face_beg_row == vpos )
27474 return;
27475
27476 if (clear_mouse_face (hlinfo))
27477 cursor = No_Cursor;
27478
27479 if (!row->reversed_p)
27480 {
27481 hlinfo->mouse_face_beg_col = hpos;
27482 hlinfo->mouse_face_beg_x = original_x_pixel
27483 - (total_pixel_width + dx);
27484 hlinfo->mouse_face_end_col = hpos + gseq_length;
27485 hlinfo->mouse_face_end_x = 0;
27486 }
27487 else
27488 {
27489 /* In R2L rows, show_mouse_face expects BEG and END
27490 coordinates to be swapped. */
27491 hlinfo->mouse_face_end_col = hpos;
27492 hlinfo->mouse_face_end_x = original_x_pixel
27493 - (total_pixel_width + dx);
27494 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27495 hlinfo->mouse_face_beg_x = 0;
27496 }
27497
27498 hlinfo->mouse_face_beg_row = vpos;
27499 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27500 hlinfo->mouse_face_beg_y = 0;
27501 hlinfo->mouse_face_end_y = 0;
27502 hlinfo->mouse_face_past_end = 0;
27503 hlinfo->mouse_face_window = window;
27504
27505 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27506 charpos,
27507 0, 0, 0,
27508 &ignore,
27509 glyph->face_id,
27510 1);
27511 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27512
27513 if (NILP (pointer))
27514 pointer = Qhand;
27515 }
27516 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27517 clear_mouse_face (hlinfo);
27518 }
27519 #ifdef HAVE_WINDOW_SYSTEM
27520 if (FRAME_WINDOW_P (f))
27521 define_frame_cursor1 (f, cursor, pointer);
27522 #endif
27523 }
27524
27525
27526 /* EXPORT:
27527 Take proper action when the mouse has moved to position X, Y on
27528 frame F as regards highlighting characters that have mouse-face
27529 properties. Also de-highlighting chars where the mouse was before.
27530 X and Y can be negative or out of range. */
27531
27532 void
27533 note_mouse_highlight (struct frame *f, int x, int y)
27534 {
27535 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27536 enum window_part part = ON_NOTHING;
27537 Lisp_Object window;
27538 struct window *w;
27539 Cursor cursor = No_Cursor;
27540 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
27541 struct buffer *b;
27542
27543 /* When a menu is active, don't highlight because this looks odd. */
27544 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
27545 if (popup_activated ())
27546 return;
27547 #endif
27548
27549 if (NILP (Vmouse_highlight)
27550 || !f->glyphs_initialized_p
27551 || f->pointer_invisible)
27552 return;
27553
27554 hlinfo->mouse_face_mouse_x = x;
27555 hlinfo->mouse_face_mouse_y = y;
27556 hlinfo->mouse_face_mouse_frame = f;
27557
27558 if (hlinfo->mouse_face_defer)
27559 return;
27560
27561 /* Which window is that in? */
27562 window = window_from_coordinates (f, x, y, &part, 1);
27563
27564 /* If displaying active text in another window, clear that. */
27565 if (! EQ (window, hlinfo->mouse_face_window)
27566 /* Also clear if we move out of text area in same window. */
27567 || (!NILP (hlinfo->mouse_face_window)
27568 && !NILP (window)
27569 && part != ON_TEXT
27570 && part != ON_MODE_LINE
27571 && part != ON_HEADER_LINE))
27572 clear_mouse_face (hlinfo);
27573
27574 /* Not on a window -> return. */
27575 if (!WINDOWP (window))
27576 return;
27577
27578 /* Reset help_echo_string. It will get recomputed below. */
27579 help_echo_string = Qnil;
27580
27581 /* Convert to window-relative pixel coordinates. */
27582 w = XWINDOW (window);
27583 frame_to_window_pixel_xy (w, &x, &y);
27584
27585 #ifdef HAVE_WINDOW_SYSTEM
27586 /* Handle tool-bar window differently since it doesn't display a
27587 buffer. */
27588 if (EQ (window, f->tool_bar_window))
27589 {
27590 note_tool_bar_highlight (f, x, y);
27591 return;
27592 }
27593 #endif
27594
27595 /* Mouse is on the mode, header line or margin? */
27596 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
27597 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
27598 {
27599 note_mode_line_or_margin_highlight (window, x, y, part);
27600 return;
27601 }
27602
27603 #ifdef HAVE_WINDOW_SYSTEM
27604 if (part == ON_VERTICAL_BORDER)
27605 {
27606 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27607 help_echo_string = build_string ("drag-mouse-1: resize");
27608 }
27609 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
27610 || part == ON_SCROLL_BAR)
27611 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27612 else
27613 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27614 #endif
27615
27616 /* Are we in a window whose display is up to date?
27617 And verify the buffer's text has not changed. */
27618 b = XBUFFER (w->buffer);
27619 if (part == ON_TEXT
27620 && w->window_end_valid
27621 && w->last_modified == BUF_MODIFF (b)
27622 && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
27623 {
27624 int hpos, vpos, dx, dy, area = LAST_AREA;
27625 ptrdiff_t pos;
27626 struct glyph *glyph;
27627 Lisp_Object object;
27628 Lisp_Object mouse_face = Qnil, position;
27629 Lisp_Object *overlay_vec = NULL;
27630 ptrdiff_t i, noverlays;
27631 struct buffer *obuf;
27632 ptrdiff_t obegv, ozv;
27633 int same_region;
27634
27635 /* Find the glyph under X/Y. */
27636 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
27637
27638 #ifdef HAVE_WINDOW_SYSTEM
27639 /* Look for :pointer property on image. */
27640 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27641 {
27642 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27643 if (img != NULL && IMAGEP (img->spec))
27644 {
27645 Lisp_Object image_map, hotspot;
27646 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
27647 !NILP (image_map))
27648 && (hotspot = find_hot_spot (image_map,
27649 glyph->slice.img.x + dx,
27650 glyph->slice.img.y + dy),
27651 CONSP (hotspot))
27652 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27653 {
27654 Lisp_Object plist;
27655
27656 /* Could check XCAR (hotspot) to see if we enter/leave
27657 this hot-spot.
27658 If so, we could look for mouse-enter, mouse-leave
27659 properties in PLIST (and do something...). */
27660 hotspot = XCDR (hotspot);
27661 if (CONSP (hotspot)
27662 && (plist = XCAR (hotspot), CONSP (plist)))
27663 {
27664 pointer = Fplist_get (plist, Qpointer);
27665 if (NILP (pointer))
27666 pointer = Qhand;
27667 help_echo_string = Fplist_get (plist, Qhelp_echo);
27668 if (!NILP (help_echo_string))
27669 {
27670 help_echo_window = window;
27671 help_echo_object = glyph->object;
27672 help_echo_pos = glyph->charpos;
27673 }
27674 }
27675 }
27676 if (NILP (pointer))
27677 pointer = Fplist_get (XCDR (img->spec), QCpointer);
27678 }
27679 }
27680 #endif /* HAVE_WINDOW_SYSTEM */
27681
27682 /* Clear mouse face if X/Y not over text. */
27683 if (glyph == NULL
27684 || area != TEXT_AREA
27685 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
27686 /* Glyph's OBJECT is an integer for glyphs inserted by the
27687 display engine for its internal purposes, like truncation
27688 and continuation glyphs and blanks beyond the end of
27689 line's text on text terminals. If we are over such a
27690 glyph, we are not over any text. */
27691 || INTEGERP (glyph->object)
27692 /* R2L rows have a stretch glyph at their front, which
27693 stands for no text, whereas L2R rows have no glyphs at
27694 all beyond the end of text. Treat such stretch glyphs
27695 like we do with NULL glyphs in L2R rows. */
27696 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
27697 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
27698 && glyph->type == STRETCH_GLYPH
27699 && glyph->avoid_cursor_p))
27700 {
27701 if (clear_mouse_face (hlinfo))
27702 cursor = No_Cursor;
27703 #ifdef HAVE_WINDOW_SYSTEM
27704 if (FRAME_WINDOW_P (f) && NILP (pointer))
27705 {
27706 if (area != TEXT_AREA)
27707 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27708 else
27709 pointer = Vvoid_text_area_pointer;
27710 }
27711 #endif
27712 goto set_cursor;
27713 }
27714
27715 pos = glyph->charpos;
27716 object = glyph->object;
27717 if (!STRINGP (object) && !BUFFERP (object))
27718 goto set_cursor;
27719
27720 /* If we get an out-of-range value, return now; avoid an error. */
27721 if (BUFFERP (object) && pos > BUF_Z (b))
27722 goto set_cursor;
27723
27724 /* Make the window's buffer temporarily current for
27725 overlays_at and compute_char_face. */
27726 obuf = current_buffer;
27727 current_buffer = b;
27728 obegv = BEGV;
27729 ozv = ZV;
27730 BEGV = BEG;
27731 ZV = Z;
27732
27733 /* Is this char mouse-active or does it have help-echo? */
27734 position = make_number (pos);
27735
27736 if (BUFFERP (object))
27737 {
27738 /* Put all the overlays we want in a vector in overlay_vec. */
27739 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
27740 /* Sort overlays into increasing priority order. */
27741 noverlays = sort_overlays (overlay_vec, noverlays, w);
27742 }
27743 else
27744 noverlays = 0;
27745
27746 same_region = coords_in_mouse_face_p (w, hpos, vpos);
27747
27748 if (same_region)
27749 cursor = No_Cursor;
27750
27751 /* Check mouse-face highlighting. */
27752 if (! same_region
27753 /* If there exists an overlay with mouse-face overlapping
27754 the one we are currently highlighting, we have to
27755 check if we enter the overlapping overlay, and then
27756 highlight only that. */
27757 || (OVERLAYP (hlinfo->mouse_face_overlay)
27758 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
27759 {
27760 /* Find the highest priority overlay with a mouse-face. */
27761 Lisp_Object overlay = Qnil;
27762 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
27763 {
27764 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
27765 if (!NILP (mouse_face))
27766 overlay = overlay_vec[i];
27767 }
27768
27769 /* If we're highlighting the same overlay as before, there's
27770 no need to do that again. */
27771 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
27772 goto check_help_echo;
27773 hlinfo->mouse_face_overlay = overlay;
27774
27775 /* Clear the display of the old active region, if any. */
27776 if (clear_mouse_face (hlinfo))
27777 cursor = No_Cursor;
27778
27779 /* If no overlay applies, get a text property. */
27780 if (NILP (overlay))
27781 mouse_face = Fget_text_property (position, Qmouse_face, object);
27782
27783 /* Next, compute the bounds of the mouse highlighting and
27784 display it. */
27785 if (!NILP (mouse_face) && STRINGP (object))
27786 {
27787 /* The mouse-highlighting comes from a display string
27788 with a mouse-face. */
27789 Lisp_Object s, e;
27790 ptrdiff_t ignore;
27791
27792 s = Fprevious_single_property_change
27793 (make_number (pos + 1), Qmouse_face, object, Qnil);
27794 e = Fnext_single_property_change
27795 (position, Qmouse_face, object, Qnil);
27796 if (NILP (s))
27797 s = make_number (0);
27798 if (NILP (e))
27799 e = make_number (SCHARS (object) - 1);
27800 mouse_face_from_string_pos (w, hlinfo, object,
27801 XINT (s), XINT (e));
27802 hlinfo->mouse_face_past_end = 0;
27803 hlinfo->mouse_face_window = window;
27804 hlinfo->mouse_face_face_id
27805 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
27806 glyph->face_id, 1);
27807 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27808 cursor = No_Cursor;
27809 }
27810 else
27811 {
27812 /* The mouse-highlighting, if any, comes from an overlay
27813 or text property in the buffer. */
27814 Lisp_Object buffer IF_LINT (= Qnil);
27815 Lisp_Object disp_string IF_LINT (= Qnil);
27816
27817 if (STRINGP (object))
27818 {
27819 /* If we are on a display string with no mouse-face,
27820 check if the text under it has one. */
27821 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
27822 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27823 pos = string_buffer_position (object, start);
27824 if (pos > 0)
27825 {
27826 mouse_face = get_char_property_and_overlay
27827 (make_number (pos), Qmouse_face, w->buffer, &overlay);
27828 buffer = w->buffer;
27829 disp_string = object;
27830 }
27831 }
27832 else
27833 {
27834 buffer = object;
27835 disp_string = Qnil;
27836 }
27837
27838 if (!NILP (mouse_face))
27839 {
27840 Lisp_Object before, after;
27841 Lisp_Object before_string, after_string;
27842 /* To correctly find the limits of mouse highlight
27843 in a bidi-reordered buffer, we must not use the
27844 optimization of limiting the search in
27845 previous-single-property-change and
27846 next-single-property-change, because
27847 rows_from_pos_range needs the real start and end
27848 positions to DTRT in this case. That's because
27849 the first row visible in a window does not
27850 necessarily display the character whose position
27851 is the smallest. */
27852 Lisp_Object lim1 =
27853 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27854 ? Fmarker_position (w->start)
27855 : Qnil;
27856 Lisp_Object lim2 =
27857 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27858 ? make_number (BUF_Z (XBUFFER (buffer))
27859 - XFASTINT (w->window_end_pos))
27860 : Qnil;
27861
27862 if (NILP (overlay))
27863 {
27864 /* Handle the text property case. */
27865 before = Fprevious_single_property_change
27866 (make_number (pos + 1), Qmouse_face, buffer, lim1);
27867 after = Fnext_single_property_change
27868 (make_number (pos), Qmouse_face, buffer, lim2);
27869 before_string = after_string = Qnil;
27870 }
27871 else
27872 {
27873 /* Handle the overlay case. */
27874 before = Foverlay_start (overlay);
27875 after = Foverlay_end (overlay);
27876 before_string = Foverlay_get (overlay, Qbefore_string);
27877 after_string = Foverlay_get (overlay, Qafter_string);
27878
27879 if (!STRINGP (before_string)) before_string = Qnil;
27880 if (!STRINGP (after_string)) after_string = Qnil;
27881 }
27882
27883 mouse_face_from_buffer_pos (window, hlinfo, pos,
27884 NILP (before)
27885 ? 1
27886 : XFASTINT (before),
27887 NILP (after)
27888 ? BUF_Z (XBUFFER (buffer))
27889 : XFASTINT (after),
27890 before_string, after_string,
27891 disp_string);
27892 cursor = No_Cursor;
27893 }
27894 }
27895 }
27896
27897 check_help_echo:
27898
27899 /* Look for a `help-echo' property. */
27900 if (NILP (help_echo_string)) {
27901 Lisp_Object help, overlay;
27902
27903 /* Check overlays first. */
27904 help = overlay = Qnil;
27905 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
27906 {
27907 overlay = overlay_vec[i];
27908 help = Foverlay_get (overlay, Qhelp_echo);
27909 }
27910
27911 if (!NILP (help))
27912 {
27913 help_echo_string = help;
27914 help_echo_window = window;
27915 help_echo_object = overlay;
27916 help_echo_pos = pos;
27917 }
27918 else
27919 {
27920 Lisp_Object obj = glyph->object;
27921 ptrdiff_t charpos = glyph->charpos;
27922
27923 /* Try text properties. */
27924 if (STRINGP (obj)
27925 && charpos >= 0
27926 && charpos < SCHARS (obj))
27927 {
27928 help = Fget_text_property (make_number (charpos),
27929 Qhelp_echo, obj);
27930 if (NILP (help))
27931 {
27932 /* If the string itself doesn't specify a help-echo,
27933 see if the buffer text ``under'' it does. */
27934 struct glyph_row *r
27935 = MATRIX_ROW (w->current_matrix, vpos);
27936 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27937 ptrdiff_t p = string_buffer_position (obj, start);
27938 if (p > 0)
27939 {
27940 help = Fget_char_property (make_number (p),
27941 Qhelp_echo, w->buffer);
27942 if (!NILP (help))
27943 {
27944 charpos = p;
27945 obj = w->buffer;
27946 }
27947 }
27948 }
27949 }
27950 else if (BUFFERP (obj)
27951 && charpos >= BEGV
27952 && charpos < ZV)
27953 help = Fget_text_property (make_number (charpos), Qhelp_echo,
27954 obj);
27955
27956 if (!NILP (help))
27957 {
27958 help_echo_string = help;
27959 help_echo_window = window;
27960 help_echo_object = obj;
27961 help_echo_pos = charpos;
27962 }
27963 }
27964 }
27965
27966 #ifdef HAVE_WINDOW_SYSTEM
27967 /* Look for a `pointer' property. */
27968 if (FRAME_WINDOW_P (f) && NILP (pointer))
27969 {
27970 /* Check overlays first. */
27971 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
27972 pointer = Foverlay_get (overlay_vec[i], Qpointer);
27973
27974 if (NILP (pointer))
27975 {
27976 Lisp_Object obj = glyph->object;
27977 ptrdiff_t charpos = glyph->charpos;
27978
27979 /* Try text properties. */
27980 if (STRINGP (obj)
27981 && charpos >= 0
27982 && charpos < SCHARS (obj))
27983 {
27984 pointer = Fget_text_property (make_number (charpos),
27985 Qpointer, obj);
27986 if (NILP (pointer))
27987 {
27988 /* If the string itself doesn't specify a pointer,
27989 see if the buffer text ``under'' it does. */
27990 struct glyph_row *r
27991 = MATRIX_ROW (w->current_matrix, vpos);
27992 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27993 ptrdiff_t p = string_buffer_position (obj, start);
27994 if (p > 0)
27995 pointer = Fget_char_property (make_number (p),
27996 Qpointer, w->buffer);
27997 }
27998 }
27999 else if (BUFFERP (obj)
28000 && charpos >= BEGV
28001 && charpos < ZV)
28002 pointer = Fget_text_property (make_number (charpos),
28003 Qpointer, obj);
28004 }
28005 }
28006 #endif /* HAVE_WINDOW_SYSTEM */
28007
28008 BEGV = obegv;
28009 ZV = ozv;
28010 current_buffer = obuf;
28011 }
28012
28013 set_cursor:
28014
28015 #ifdef HAVE_WINDOW_SYSTEM
28016 if (FRAME_WINDOW_P (f))
28017 define_frame_cursor1 (f, cursor, pointer);
28018 #else
28019 /* This is here to prevent a compiler error, about "label at end of
28020 compound statement". */
28021 return;
28022 #endif
28023 }
28024
28025
28026 /* EXPORT for RIF:
28027 Clear any mouse-face on window W. This function is part of the
28028 redisplay interface, and is called from try_window_id and similar
28029 functions to ensure the mouse-highlight is off. */
28030
28031 void
28032 x_clear_window_mouse_face (struct window *w)
28033 {
28034 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28035 Lisp_Object window;
28036
28037 block_input ();
28038 XSETWINDOW (window, w);
28039 if (EQ (window, hlinfo->mouse_face_window))
28040 clear_mouse_face (hlinfo);
28041 unblock_input ();
28042 }
28043
28044
28045 /* EXPORT:
28046 Just discard the mouse face information for frame F, if any.
28047 This is used when the size of F is changed. */
28048
28049 void
28050 cancel_mouse_face (struct frame *f)
28051 {
28052 Lisp_Object window;
28053 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28054
28055 window = hlinfo->mouse_face_window;
28056 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28057 {
28058 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28059 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28060 hlinfo->mouse_face_window = Qnil;
28061 }
28062 }
28063
28064
28065 \f
28066 /***********************************************************************
28067 Exposure Events
28068 ***********************************************************************/
28069
28070 #ifdef HAVE_WINDOW_SYSTEM
28071
28072 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28073 which intersects rectangle R. R is in window-relative coordinates. */
28074
28075 static void
28076 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28077 enum glyph_row_area area)
28078 {
28079 struct glyph *first = row->glyphs[area];
28080 struct glyph *end = row->glyphs[area] + row->used[area];
28081 struct glyph *last;
28082 int first_x, start_x, x;
28083
28084 if (area == TEXT_AREA && row->fill_line_p)
28085 /* If row extends face to end of line write the whole line. */
28086 draw_glyphs (w, 0, row, area,
28087 0, row->used[area],
28088 DRAW_NORMAL_TEXT, 0);
28089 else
28090 {
28091 /* Set START_X to the window-relative start position for drawing glyphs of
28092 AREA. The first glyph of the text area can be partially visible.
28093 The first glyphs of other areas cannot. */
28094 start_x = window_box_left_offset (w, area);
28095 x = start_x;
28096 if (area == TEXT_AREA)
28097 x += row->x;
28098
28099 /* Find the first glyph that must be redrawn. */
28100 while (first < end
28101 && x + first->pixel_width < r->x)
28102 {
28103 x += first->pixel_width;
28104 ++first;
28105 }
28106
28107 /* Find the last one. */
28108 last = first;
28109 first_x = x;
28110 while (last < end
28111 && x < r->x + r->width)
28112 {
28113 x += last->pixel_width;
28114 ++last;
28115 }
28116
28117 /* Repaint. */
28118 if (last > first)
28119 draw_glyphs (w, first_x - start_x, row, area,
28120 first - row->glyphs[area], last - row->glyphs[area],
28121 DRAW_NORMAL_TEXT, 0);
28122 }
28123 }
28124
28125
28126 /* Redraw the parts of the glyph row ROW on window W intersecting
28127 rectangle R. R is in window-relative coordinates. Value is
28128 non-zero if mouse-face was overwritten. */
28129
28130 static int
28131 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28132 {
28133 eassert (row->enabled_p);
28134
28135 if (row->mode_line_p || w->pseudo_window_p)
28136 draw_glyphs (w, 0, row, TEXT_AREA,
28137 0, row->used[TEXT_AREA],
28138 DRAW_NORMAL_TEXT, 0);
28139 else
28140 {
28141 if (row->used[LEFT_MARGIN_AREA])
28142 expose_area (w, row, r, LEFT_MARGIN_AREA);
28143 if (row->used[TEXT_AREA])
28144 expose_area (w, row, r, TEXT_AREA);
28145 if (row->used[RIGHT_MARGIN_AREA])
28146 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28147 draw_row_fringe_bitmaps (w, row);
28148 }
28149
28150 return row->mouse_face_p;
28151 }
28152
28153
28154 /* Redraw those parts of glyphs rows during expose event handling that
28155 overlap other rows. Redrawing of an exposed line writes over parts
28156 of lines overlapping that exposed line; this function fixes that.
28157
28158 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28159 row in W's current matrix that is exposed and overlaps other rows.
28160 LAST_OVERLAPPING_ROW is the last such row. */
28161
28162 static void
28163 expose_overlaps (struct window *w,
28164 struct glyph_row *first_overlapping_row,
28165 struct glyph_row *last_overlapping_row,
28166 XRectangle *r)
28167 {
28168 struct glyph_row *row;
28169
28170 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28171 if (row->overlapping_p)
28172 {
28173 eassert (row->enabled_p && !row->mode_line_p);
28174
28175 row->clip = r;
28176 if (row->used[LEFT_MARGIN_AREA])
28177 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28178
28179 if (row->used[TEXT_AREA])
28180 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28181
28182 if (row->used[RIGHT_MARGIN_AREA])
28183 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28184 row->clip = NULL;
28185 }
28186 }
28187
28188
28189 /* Return non-zero if W's cursor intersects rectangle R. */
28190
28191 static int
28192 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28193 {
28194 XRectangle cr, result;
28195 struct glyph *cursor_glyph;
28196 struct glyph_row *row;
28197
28198 if (w->phys_cursor.vpos >= 0
28199 && w->phys_cursor.vpos < w->current_matrix->nrows
28200 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28201 row->enabled_p)
28202 && row->cursor_in_fringe_p)
28203 {
28204 /* Cursor is in the fringe. */
28205 cr.x = window_box_right_offset (w,
28206 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28207 ? RIGHT_MARGIN_AREA
28208 : TEXT_AREA));
28209 cr.y = row->y;
28210 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28211 cr.height = row->height;
28212 return x_intersect_rectangles (&cr, r, &result);
28213 }
28214
28215 cursor_glyph = get_phys_cursor_glyph (w);
28216 if (cursor_glyph)
28217 {
28218 /* r is relative to W's box, but w->phys_cursor.x is relative
28219 to left edge of W's TEXT area. Adjust it. */
28220 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28221 cr.y = w->phys_cursor.y;
28222 cr.width = cursor_glyph->pixel_width;
28223 cr.height = w->phys_cursor_height;
28224 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28225 I assume the effect is the same -- and this is portable. */
28226 return x_intersect_rectangles (&cr, r, &result);
28227 }
28228 /* If we don't understand the format, pretend we're not in the hot-spot. */
28229 return 0;
28230 }
28231
28232
28233 /* EXPORT:
28234 Draw a vertical window border to the right of window W if W doesn't
28235 have vertical scroll bars. */
28236
28237 void
28238 x_draw_vertical_border (struct window *w)
28239 {
28240 struct frame *f = XFRAME (WINDOW_FRAME (w));
28241
28242 /* We could do better, if we knew what type of scroll-bar the adjacent
28243 windows (on either side) have... But we don't :-(
28244 However, I think this works ok. ++KFS 2003-04-25 */
28245
28246 /* Redraw borders between horizontally adjacent windows. Don't
28247 do it for frames with vertical scroll bars because either the
28248 right scroll bar of a window, or the left scroll bar of its
28249 neighbor will suffice as a border. */
28250 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28251 return;
28252
28253 if (!WINDOW_RIGHTMOST_P (w)
28254 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28255 {
28256 int x0, x1, y0, y1;
28257
28258 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28259 y1 -= 1;
28260
28261 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28262 x1 -= 1;
28263
28264 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28265 }
28266 else if (!WINDOW_LEFTMOST_P (w)
28267 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28268 {
28269 int x0, x1, y0, y1;
28270
28271 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28272 y1 -= 1;
28273
28274 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28275 x0 -= 1;
28276
28277 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28278 }
28279 }
28280
28281
28282 /* Redraw the part of window W intersection rectangle FR. Pixel
28283 coordinates in FR are frame-relative. Call this function with
28284 input blocked. Value is non-zero if the exposure overwrites
28285 mouse-face. */
28286
28287 static int
28288 expose_window (struct window *w, XRectangle *fr)
28289 {
28290 struct frame *f = XFRAME (w->frame);
28291 XRectangle wr, r;
28292 int mouse_face_overwritten_p = 0;
28293
28294 /* If window is not yet fully initialized, do nothing. This can
28295 happen when toolkit scroll bars are used and a window is split.
28296 Reconfiguring the scroll bar will generate an expose for a newly
28297 created window. */
28298 if (w->current_matrix == NULL)
28299 return 0;
28300
28301 /* When we're currently updating the window, display and current
28302 matrix usually don't agree. Arrange for a thorough display
28303 later. */
28304 if (w == updated_window)
28305 {
28306 SET_FRAME_GARBAGED (f);
28307 return 0;
28308 }
28309
28310 /* Frame-relative pixel rectangle of W. */
28311 wr.x = WINDOW_LEFT_EDGE_X (w);
28312 wr.y = WINDOW_TOP_EDGE_Y (w);
28313 wr.width = WINDOW_TOTAL_WIDTH (w);
28314 wr.height = WINDOW_TOTAL_HEIGHT (w);
28315
28316 if (x_intersect_rectangles (fr, &wr, &r))
28317 {
28318 int yb = window_text_bottom_y (w);
28319 struct glyph_row *row;
28320 int cursor_cleared_p, phys_cursor_on_p;
28321 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28322
28323 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28324 r.x, r.y, r.width, r.height));
28325
28326 /* Convert to window coordinates. */
28327 r.x -= WINDOW_LEFT_EDGE_X (w);
28328 r.y -= WINDOW_TOP_EDGE_Y (w);
28329
28330 /* Turn off the cursor. */
28331 if (!w->pseudo_window_p
28332 && phys_cursor_in_rect_p (w, &r))
28333 {
28334 x_clear_cursor (w);
28335 cursor_cleared_p = 1;
28336 }
28337 else
28338 cursor_cleared_p = 0;
28339
28340 /* If the row containing the cursor extends face to end of line,
28341 then expose_area might overwrite the cursor outside the
28342 rectangle and thus notice_overwritten_cursor might clear
28343 w->phys_cursor_on_p. We remember the original value and
28344 check later if it is changed. */
28345 phys_cursor_on_p = w->phys_cursor_on_p;
28346
28347 /* Update lines intersecting rectangle R. */
28348 first_overlapping_row = last_overlapping_row = NULL;
28349 for (row = w->current_matrix->rows;
28350 row->enabled_p;
28351 ++row)
28352 {
28353 int y0 = row->y;
28354 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28355
28356 if ((y0 >= r.y && y0 < r.y + r.height)
28357 || (y1 > r.y && y1 < r.y + r.height)
28358 || (r.y >= y0 && r.y < y1)
28359 || (r.y + r.height > y0 && r.y + r.height < y1))
28360 {
28361 /* A header line may be overlapping, but there is no need
28362 to fix overlapping areas for them. KFS 2005-02-12 */
28363 if (row->overlapping_p && !row->mode_line_p)
28364 {
28365 if (first_overlapping_row == NULL)
28366 first_overlapping_row = row;
28367 last_overlapping_row = row;
28368 }
28369
28370 row->clip = fr;
28371 if (expose_line (w, row, &r))
28372 mouse_face_overwritten_p = 1;
28373 row->clip = NULL;
28374 }
28375 else if (row->overlapping_p)
28376 {
28377 /* We must redraw a row overlapping the exposed area. */
28378 if (y0 < r.y
28379 ? y0 + row->phys_height > r.y
28380 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28381 {
28382 if (first_overlapping_row == NULL)
28383 first_overlapping_row = row;
28384 last_overlapping_row = row;
28385 }
28386 }
28387
28388 if (y1 >= yb)
28389 break;
28390 }
28391
28392 /* Display the mode line if there is one. */
28393 if (WINDOW_WANTS_MODELINE_P (w)
28394 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28395 row->enabled_p)
28396 && row->y < r.y + r.height)
28397 {
28398 if (expose_line (w, row, &r))
28399 mouse_face_overwritten_p = 1;
28400 }
28401
28402 if (!w->pseudo_window_p)
28403 {
28404 /* Fix the display of overlapping rows. */
28405 if (first_overlapping_row)
28406 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28407 fr);
28408
28409 /* Draw border between windows. */
28410 x_draw_vertical_border (w);
28411
28412 /* Turn the cursor on again. */
28413 if (cursor_cleared_p
28414 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28415 update_window_cursor (w, 1);
28416 }
28417 }
28418
28419 return mouse_face_overwritten_p;
28420 }
28421
28422
28423
28424 /* Redraw (parts) of all windows in the window tree rooted at W that
28425 intersect R. R contains frame pixel coordinates. Value is
28426 non-zero if the exposure overwrites mouse-face. */
28427
28428 static int
28429 expose_window_tree (struct window *w, XRectangle *r)
28430 {
28431 struct frame *f = XFRAME (w->frame);
28432 int mouse_face_overwritten_p = 0;
28433
28434 while (w && !FRAME_GARBAGED_P (f))
28435 {
28436 if (!NILP (w->hchild))
28437 mouse_face_overwritten_p
28438 |= expose_window_tree (XWINDOW (w->hchild), r);
28439 else if (!NILP (w->vchild))
28440 mouse_face_overwritten_p
28441 |= expose_window_tree (XWINDOW (w->vchild), r);
28442 else
28443 mouse_face_overwritten_p |= expose_window (w, r);
28444
28445 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28446 }
28447
28448 return mouse_face_overwritten_p;
28449 }
28450
28451
28452 /* EXPORT:
28453 Redisplay an exposed area of frame F. X and Y are the upper-left
28454 corner of the exposed rectangle. W and H are width and height of
28455 the exposed area. All are pixel values. W or H zero means redraw
28456 the entire frame. */
28457
28458 void
28459 expose_frame (struct frame *f, int x, int y, int w, int h)
28460 {
28461 XRectangle r;
28462 int mouse_face_overwritten_p = 0;
28463
28464 TRACE ((stderr, "expose_frame "));
28465
28466 /* No need to redraw if frame will be redrawn soon. */
28467 if (FRAME_GARBAGED_P (f))
28468 {
28469 TRACE ((stderr, " garbaged\n"));
28470 return;
28471 }
28472
28473 /* If basic faces haven't been realized yet, there is no point in
28474 trying to redraw anything. This can happen when we get an expose
28475 event while Emacs is starting, e.g. by moving another window. */
28476 if (FRAME_FACE_CACHE (f) == NULL
28477 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28478 {
28479 TRACE ((stderr, " no faces\n"));
28480 return;
28481 }
28482
28483 if (w == 0 || h == 0)
28484 {
28485 r.x = r.y = 0;
28486 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28487 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28488 }
28489 else
28490 {
28491 r.x = x;
28492 r.y = y;
28493 r.width = w;
28494 r.height = h;
28495 }
28496
28497 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28498 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28499
28500 if (WINDOWP (f->tool_bar_window))
28501 mouse_face_overwritten_p
28502 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28503
28504 #ifdef HAVE_X_WINDOWS
28505 #ifndef MSDOS
28506 #ifndef USE_X_TOOLKIT
28507 if (WINDOWP (f->menu_bar_window))
28508 mouse_face_overwritten_p
28509 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28510 #endif /* not USE_X_TOOLKIT */
28511 #endif
28512 #endif
28513
28514 /* Some window managers support a focus-follows-mouse style with
28515 delayed raising of frames. Imagine a partially obscured frame,
28516 and moving the mouse into partially obscured mouse-face on that
28517 frame. The visible part of the mouse-face will be highlighted,
28518 then the WM raises the obscured frame. With at least one WM, KDE
28519 2.1, Emacs is not getting any event for the raising of the frame
28520 (even tried with SubstructureRedirectMask), only Expose events.
28521 These expose events will draw text normally, i.e. not
28522 highlighted. Which means we must redo the highlight here.
28523 Subsume it under ``we love X''. --gerd 2001-08-15 */
28524 /* Included in Windows version because Windows most likely does not
28525 do the right thing if any third party tool offers
28526 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28527 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
28528 {
28529 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28530 if (f == hlinfo->mouse_face_mouse_frame)
28531 {
28532 int mouse_x = hlinfo->mouse_face_mouse_x;
28533 int mouse_y = hlinfo->mouse_face_mouse_y;
28534 clear_mouse_face (hlinfo);
28535 note_mouse_highlight (f, mouse_x, mouse_y);
28536 }
28537 }
28538 }
28539
28540
28541 /* EXPORT:
28542 Determine the intersection of two rectangles R1 and R2. Return
28543 the intersection in *RESULT. Value is non-zero if RESULT is not
28544 empty. */
28545
28546 int
28547 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
28548 {
28549 XRectangle *left, *right;
28550 XRectangle *upper, *lower;
28551 int intersection_p = 0;
28552
28553 /* Rearrange so that R1 is the left-most rectangle. */
28554 if (r1->x < r2->x)
28555 left = r1, right = r2;
28556 else
28557 left = r2, right = r1;
28558
28559 /* X0 of the intersection is right.x0, if this is inside R1,
28560 otherwise there is no intersection. */
28561 if (right->x <= left->x + left->width)
28562 {
28563 result->x = right->x;
28564
28565 /* The right end of the intersection is the minimum of
28566 the right ends of left and right. */
28567 result->width = (min (left->x + left->width, right->x + right->width)
28568 - result->x);
28569
28570 /* Same game for Y. */
28571 if (r1->y < r2->y)
28572 upper = r1, lower = r2;
28573 else
28574 upper = r2, lower = r1;
28575
28576 /* The upper end of the intersection is lower.y0, if this is inside
28577 of upper. Otherwise, there is no intersection. */
28578 if (lower->y <= upper->y + upper->height)
28579 {
28580 result->y = lower->y;
28581
28582 /* The lower end of the intersection is the minimum of the lower
28583 ends of upper and lower. */
28584 result->height = (min (lower->y + lower->height,
28585 upper->y + upper->height)
28586 - result->y);
28587 intersection_p = 1;
28588 }
28589 }
28590
28591 return intersection_p;
28592 }
28593
28594 #endif /* HAVE_WINDOW_SYSTEM */
28595
28596 \f
28597 /***********************************************************************
28598 Initialization
28599 ***********************************************************************/
28600
28601 void
28602 syms_of_xdisp (void)
28603 {
28604 Vwith_echo_area_save_vector = Qnil;
28605 staticpro (&Vwith_echo_area_save_vector);
28606
28607 Vmessage_stack = Qnil;
28608 staticpro (&Vmessage_stack);
28609
28610 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
28611 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
28612
28613 message_dolog_marker1 = Fmake_marker ();
28614 staticpro (&message_dolog_marker1);
28615 message_dolog_marker2 = Fmake_marker ();
28616 staticpro (&message_dolog_marker2);
28617 message_dolog_marker3 = Fmake_marker ();
28618 staticpro (&message_dolog_marker3);
28619
28620 #ifdef GLYPH_DEBUG
28621 defsubr (&Sdump_frame_glyph_matrix);
28622 defsubr (&Sdump_glyph_matrix);
28623 defsubr (&Sdump_glyph_row);
28624 defsubr (&Sdump_tool_bar_row);
28625 defsubr (&Strace_redisplay);
28626 defsubr (&Strace_to_stderr);
28627 #endif
28628 #ifdef HAVE_WINDOW_SYSTEM
28629 defsubr (&Stool_bar_lines_needed);
28630 defsubr (&Slookup_image_map);
28631 #endif
28632 defsubr (&Sformat_mode_line);
28633 defsubr (&Sinvisible_p);
28634 defsubr (&Scurrent_bidi_paragraph_direction);
28635
28636 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
28637 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
28638 DEFSYM (Qoverriding_local_map, "overriding-local-map");
28639 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
28640 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
28641 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
28642 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
28643 DEFSYM (Qeval, "eval");
28644 DEFSYM (QCdata, ":data");
28645 DEFSYM (Qdisplay, "display");
28646 DEFSYM (Qspace_width, "space-width");
28647 DEFSYM (Qraise, "raise");
28648 DEFSYM (Qslice, "slice");
28649 DEFSYM (Qspace, "space");
28650 DEFSYM (Qmargin, "margin");
28651 DEFSYM (Qpointer, "pointer");
28652 DEFSYM (Qleft_margin, "left-margin");
28653 DEFSYM (Qright_margin, "right-margin");
28654 DEFSYM (Qcenter, "center");
28655 DEFSYM (Qline_height, "line-height");
28656 DEFSYM (QCalign_to, ":align-to");
28657 DEFSYM (QCrelative_width, ":relative-width");
28658 DEFSYM (QCrelative_height, ":relative-height");
28659 DEFSYM (QCeval, ":eval");
28660 DEFSYM (QCpropertize, ":propertize");
28661 DEFSYM (QCfile, ":file");
28662 DEFSYM (Qfontified, "fontified");
28663 DEFSYM (Qfontification_functions, "fontification-functions");
28664 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
28665 DEFSYM (Qescape_glyph, "escape-glyph");
28666 DEFSYM (Qnobreak_space, "nobreak-space");
28667 DEFSYM (Qimage, "image");
28668 DEFSYM (Qtext, "text");
28669 DEFSYM (Qboth, "both");
28670 DEFSYM (Qboth_horiz, "both-horiz");
28671 DEFSYM (Qtext_image_horiz, "text-image-horiz");
28672 DEFSYM (QCmap, ":map");
28673 DEFSYM (QCpointer, ":pointer");
28674 DEFSYM (Qrect, "rect");
28675 DEFSYM (Qcircle, "circle");
28676 DEFSYM (Qpoly, "poly");
28677 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
28678 DEFSYM (Qgrow_only, "grow-only");
28679 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
28680 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
28681 DEFSYM (Qposition, "position");
28682 DEFSYM (Qbuffer_position, "buffer-position");
28683 DEFSYM (Qobject, "object");
28684 DEFSYM (Qbar, "bar");
28685 DEFSYM (Qhbar, "hbar");
28686 DEFSYM (Qbox, "box");
28687 DEFSYM (Qhollow, "hollow");
28688 DEFSYM (Qhand, "hand");
28689 DEFSYM (Qarrow, "arrow");
28690 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
28691
28692 list_of_error = Fcons (Fcons (intern_c_string ("error"),
28693 Fcons (intern_c_string ("void-variable"), Qnil)),
28694 Qnil);
28695 staticpro (&list_of_error);
28696
28697 DEFSYM (Qlast_arrow_position, "last-arrow-position");
28698 DEFSYM (Qlast_arrow_string, "last-arrow-string");
28699 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
28700 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
28701
28702 echo_buffer[0] = echo_buffer[1] = Qnil;
28703 staticpro (&echo_buffer[0]);
28704 staticpro (&echo_buffer[1]);
28705
28706 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
28707 staticpro (&echo_area_buffer[0]);
28708 staticpro (&echo_area_buffer[1]);
28709
28710 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
28711 staticpro (&Vmessages_buffer_name);
28712
28713 mode_line_proptrans_alist = Qnil;
28714 staticpro (&mode_line_proptrans_alist);
28715 mode_line_string_list = Qnil;
28716 staticpro (&mode_line_string_list);
28717 mode_line_string_face = Qnil;
28718 staticpro (&mode_line_string_face);
28719 mode_line_string_face_prop = Qnil;
28720 staticpro (&mode_line_string_face_prop);
28721 Vmode_line_unwind_vector = Qnil;
28722 staticpro (&Vmode_line_unwind_vector);
28723
28724 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
28725
28726 help_echo_string = Qnil;
28727 staticpro (&help_echo_string);
28728 help_echo_object = Qnil;
28729 staticpro (&help_echo_object);
28730 help_echo_window = Qnil;
28731 staticpro (&help_echo_window);
28732 previous_help_echo_string = Qnil;
28733 staticpro (&previous_help_echo_string);
28734 help_echo_pos = -1;
28735
28736 DEFSYM (Qright_to_left, "right-to-left");
28737 DEFSYM (Qleft_to_right, "left-to-right");
28738
28739 #ifdef HAVE_WINDOW_SYSTEM
28740 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
28741 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
28742 For example, if a block cursor is over a tab, it will be drawn as
28743 wide as that tab on the display. */);
28744 x_stretch_cursor_p = 0;
28745 #endif
28746
28747 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
28748 doc: /* Non-nil means highlight trailing whitespace.
28749 The face used for trailing whitespace is `trailing-whitespace'. */);
28750 Vshow_trailing_whitespace = Qnil;
28751
28752 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
28753 doc: /* Control highlighting of non-ASCII space and hyphen chars.
28754 If the value is t, Emacs highlights non-ASCII chars which have the
28755 same appearance as an ASCII space or hyphen, using the `nobreak-space'
28756 or `escape-glyph' face respectively.
28757
28758 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28759 U+2011 (non-breaking hyphen) are affected.
28760
28761 Any other non-nil value means to display these characters as a escape
28762 glyph followed by an ordinary space or hyphen.
28763
28764 A value of nil means no special handling of these characters. */);
28765 Vnobreak_char_display = Qt;
28766
28767 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
28768 doc: /* The pointer shape to show in void text areas.
28769 A value of nil means to show the text pointer. Other options are `arrow',
28770 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
28771 Vvoid_text_area_pointer = Qarrow;
28772
28773 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
28774 doc: /* Non-nil means don't actually do any redisplay.
28775 This is used for internal purposes. */);
28776 Vinhibit_redisplay = Qnil;
28777
28778 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
28779 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
28780 Vglobal_mode_string = Qnil;
28781
28782 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
28783 doc: /* Marker for where to display an arrow on top of the buffer text.
28784 This must be the beginning of a line in order to work.
28785 See also `overlay-arrow-string'. */);
28786 Voverlay_arrow_position = Qnil;
28787
28788 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
28789 doc: /* String to display as an arrow in non-window frames.
28790 See also `overlay-arrow-position'. */);
28791 Voverlay_arrow_string = build_pure_c_string ("=>");
28792
28793 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
28794 doc: /* List of variables (symbols) which hold markers for overlay arrows.
28795 The symbols on this list are examined during redisplay to determine
28796 where to display overlay arrows. */);
28797 Voverlay_arrow_variable_list
28798 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
28799
28800 DEFVAR_INT ("scroll-step", emacs_scroll_step,
28801 doc: /* The number of lines to try scrolling a window by when point moves out.
28802 If that fails to bring point back on frame, point is centered instead.
28803 If this is zero, point is always centered after it moves off frame.
28804 If you want scrolling to always be a line at a time, you should set
28805 `scroll-conservatively' to a large value rather than set this to 1. */);
28806
28807 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
28808 doc: /* Scroll up to this many lines, to bring point back on screen.
28809 If point moves off-screen, redisplay will scroll by up to
28810 `scroll-conservatively' lines in order to bring point just barely
28811 onto the screen again. If that cannot be done, then redisplay
28812 recenters point as usual.
28813
28814 If the value is greater than 100, redisplay will never recenter point,
28815 but will always scroll just enough text to bring point into view, even
28816 if you move far away.
28817
28818 A value of zero means always recenter point if it moves off screen. */);
28819 scroll_conservatively = 0;
28820
28821 DEFVAR_INT ("scroll-margin", scroll_margin,
28822 doc: /* Number of lines of margin at the top and bottom of a window.
28823 Recenter the window whenever point gets within this many lines
28824 of the top or bottom of the window. */);
28825 scroll_margin = 0;
28826
28827 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
28828 doc: /* Pixels per inch value for non-window system displays.
28829 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
28830 Vdisplay_pixels_per_inch = make_float (72.0);
28831
28832 #ifdef GLYPH_DEBUG
28833 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
28834 #endif
28835
28836 DEFVAR_LISP ("truncate-partial-width-windows",
28837 Vtruncate_partial_width_windows,
28838 doc: /* Non-nil means truncate lines in windows narrower than the frame.
28839 For an integer value, truncate lines in each window narrower than the
28840 full frame width, provided the window width is less than that integer;
28841 otherwise, respect the value of `truncate-lines'.
28842
28843 For any other non-nil value, truncate lines in all windows that do
28844 not span the full frame width.
28845
28846 A value of nil means to respect the value of `truncate-lines'.
28847
28848 If `word-wrap' is enabled, you might want to reduce this. */);
28849 Vtruncate_partial_width_windows = make_number (50);
28850
28851 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
28852 doc: /* Maximum buffer size for which line number should be displayed.
28853 If the buffer is bigger than this, the line number does not appear
28854 in the mode line. A value of nil means no limit. */);
28855 Vline_number_display_limit = Qnil;
28856
28857 DEFVAR_INT ("line-number-display-limit-width",
28858 line_number_display_limit_width,
28859 doc: /* Maximum line width (in characters) for line number display.
28860 If the average length of the lines near point is bigger than this, then the
28861 line number may be omitted from the mode line. */);
28862 line_number_display_limit_width = 200;
28863
28864 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
28865 doc: /* Non-nil means highlight region even in nonselected windows. */);
28866 highlight_nonselected_windows = 0;
28867
28868 DEFVAR_BOOL ("multiple-frames", multiple_frames,
28869 doc: /* Non-nil if more than one frame is visible on this display.
28870 Minibuffer-only frames don't count, but iconified frames do.
28871 This variable is not guaranteed to be accurate except while processing
28872 `frame-title-format' and `icon-title-format'. */);
28873
28874 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
28875 doc: /* Template for displaying the title bar of visible frames.
28876 \(Assuming the window manager supports this feature.)
28877
28878 This variable has the same structure as `mode-line-format', except that
28879 the %c and %l constructs are ignored. It is used only on frames for
28880 which no explicit name has been set \(see `modify-frame-parameters'). */);
28881
28882 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
28883 doc: /* Template for displaying the title bar of an iconified frame.
28884 \(Assuming the window manager supports this feature.)
28885 This variable has the same structure as `mode-line-format' (which see),
28886 and is used only on frames for which no explicit name has been set
28887 \(see `modify-frame-parameters'). */);
28888 Vicon_title_format
28889 = Vframe_title_format
28890 = listn (CONSTYPE_PURE, 3,
28891 intern_c_string ("multiple-frames"),
28892 build_pure_c_string ("%b"),
28893 listn (CONSTYPE_PURE, 4,
28894 empty_unibyte_string,
28895 intern_c_string ("invocation-name"),
28896 build_pure_c_string ("@"),
28897 intern_c_string ("system-name")));
28898
28899 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
28900 doc: /* Maximum number of lines to keep in the message log buffer.
28901 If nil, disable message logging. If t, log messages but don't truncate
28902 the buffer when it becomes large. */);
28903 Vmessage_log_max = make_number (1000);
28904
28905 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
28906 doc: /* Functions called before redisplay, if window sizes have changed.
28907 The value should be a list of functions that take one argument.
28908 Just before redisplay, for each frame, if any of its windows have changed
28909 size since the last redisplay, or have been split or deleted,
28910 all the functions in the list are called, with the frame as argument. */);
28911 Vwindow_size_change_functions = Qnil;
28912
28913 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
28914 doc: /* List of functions to call before redisplaying a window with scrolling.
28915 Each function is called with two arguments, the window and its new
28916 display-start position. Note that these functions are also called by
28917 `set-window-buffer'. Also note that the value of `window-end' is not
28918 valid when these functions are called.
28919
28920 Warning: Do not use this feature to alter the way the window
28921 is scrolled. It is not designed for that, and such use probably won't
28922 work. */);
28923 Vwindow_scroll_functions = Qnil;
28924
28925 DEFVAR_LISP ("window-text-change-functions",
28926 Vwindow_text_change_functions,
28927 doc: /* Functions to call in redisplay when text in the window might change. */);
28928 Vwindow_text_change_functions = Qnil;
28929
28930 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
28931 doc: /* Functions called when redisplay of a window reaches the end trigger.
28932 Each function is called with two arguments, the window and the end trigger value.
28933 See `set-window-redisplay-end-trigger'. */);
28934 Vredisplay_end_trigger_functions = Qnil;
28935
28936 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
28937 doc: /* Non-nil means autoselect window with mouse pointer.
28938 If nil, do not autoselect windows.
28939 A positive number means delay autoselection by that many seconds: a
28940 window is autoselected only after the mouse has remained in that
28941 window for the duration of the delay.
28942 A negative number has a similar effect, but causes windows to be
28943 autoselected only after the mouse has stopped moving. \(Because of
28944 the way Emacs compares mouse events, you will occasionally wait twice
28945 that time before the window gets selected.\)
28946 Any other value means to autoselect window instantaneously when the
28947 mouse pointer enters it.
28948
28949 Autoselection selects the minibuffer only if it is active, and never
28950 unselects the minibuffer if it is active.
28951
28952 When customizing this variable make sure that the actual value of
28953 `focus-follows-mouse' matches the behavior of your window manager. */);
28954 Vmouse_autoselect_window = Qnil;
28955
28956 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
28957 doc: /* Non-nil means automatically resize tool-bars.
28958 This dynamically changes the tool-bar's height to the minimum height
28959 that is needed to make all tool-bar items visible.
28960 If value is `grow-only', the tool-bar's height is only increased
28961 automatically; to decrease the tool-bar height, use \\[recenter]. */);
28962 Vauto_resize_tool_bars = Qt;
28963
28964 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
28965 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
28966 auto_raise_tool_bar_buttons_p = 1;
28967
28968 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
28969 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
28970 make_cursor_line_fully_visible_p = 1;
28971
28972 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
28973 doc: /* Border below tool-bar in pixels.
28974 If an integer, use it as the height of the border.
28975 If it is one of `internal-border-width' or `border-width', use the
28976 value of the corresponding frame parameter.
28977 Otherwise, no border is added below the tool-bar. */);
28978 Vtool_bar_border = Qinternal_border_width;
28979
28980 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
28981 doc: /* Margin around tool-bar buttons in pixels.
28982 If an integer, use that for both horizontal and vertical margins.
28983 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
28984 HORZ specifying the horizontal margin, and VERT specifying the
28985 vertical margin. */);
28986 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
28987
28988 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
28989 doc: /* Relief thickness of tool-bar buttons. */);
28990 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
28991
28992 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
28993 doc: /* Tool bar style to use.
28994 It can be one of
28995 image - show images only
28996 text - show text only
28997 both - show both, text below image
28998 both-horiz - show text to the right of the image
28999 text-image-horiz - show text to the left of the image
29000 any other - use system default or image if no system default.
29001
29002 This variable only affects the GTK+ toolkit version of Emacs. */);
29003 Vtool_bar_style = Qnil;
29004
29005 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29006 doc: /* Maximum number of characters a label can have to be shown.
29007 The tool bar style must also show labels for this to have any effect, see
29008 `tool-bar-style'. */);
29009 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29010
29011 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29012 doc: /* List of functions to call to fontify regions of text.
29013 Each function is called with one argument POS. Functions must
29014 fontify a region starting at POS in the current buffer, and give
29015 fontified regions the property `fontified'. */);
29016 Vfontification_functions = Qnil;
29017 Fmake_variable_buffer_local (Qfontification_functions);
29018
29019 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29020 unibyte_display_via_language_environment,
29021 doc: /* Non-nil means display unibyte text according to language environment.
29022 Specifically, this means that raw bytes in the range 160-255 decimal
29023 are displayed by converting them to the equivalent multibyte characters
29024 according to the current language environment. As a result, they are
29025 displayed according to the current fontset.
29026
29027 Note that this variable affects only how these bytes are displayed,
29028 but does not change the fact they are interpreted as raw bytes. */);
29029 unibyte_display_via_language_environment = 0;
29030
29031 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29032 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29033 If a float, it specifies a fraction of the mini-window frame's height.
29034 If an integer, it specifies a number of lines. */);
29035 Vmax_mini_window_height = make_float (0.25);
29036
29037 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29038 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29039 A value of nil means don't automatically resize mini-windows.
29040 A value of t means resize them to fit the text displayed in them.
29041 A value of `grow-only', the default, means let mini-windows grow only;
29042 they return to their normal size when the minibuffer is closed, or the
29043 echo area becomes empty. */);
29044 Vresize_mini_windows = Qgrow_only;
29045
29046 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29047 doc: /* Alist specifying how to blink the cursor off.
29048 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29049 `cursor-type' frame-parameter or variable equals ON-STATE,
29050 comparing using `equal', Emacs uses OFF-STATE to specify
29051 how to blink it off. ON-STATE and OFF-STATE are values for
29052 the `cursor-type' frame parameter.
29053
29054 If a frame's ON-STATE has no entry in this list,
29055 the frame's other specifications determine how to blink the cursor off. */);
29056 Vblink_cursor_alist = Qnil;
29057
29058 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29059 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29060 If non-nil, windows are automatically scrolled horizontally to make
29061 point visible. */);
29062 automatic_hscrolling_p = 1;
29063 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29064
29065 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29066 doc: /* How many columns away from the window edge point is allowed to get
29067 before automatic hscrolling will horizontally scroll the window. */);
29068 hscroll_margin = 5;
29069
29070 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29071 doc: /* How many columns to scroll the window when point gets too close to the edge.
29072 When point is less than `hscroll-margin' columns from the window
29073 edge, automatic hscrolling will scroll the window by the amount of columns
29074 determined by this variable. If its value is a positive integer, scroll that
29075 many columns. If it's a positive floating-point number, it specifies the
29076 fraction of the window's width to scroll. If it's nil or zero, point will be
29077 centered horizontally after the scroll. Any other value, including negative
29078 numbers, are treated as if the value were zero.
29079
29080 Automatic hscrolling always moves point outside the scroll margin, so if
29081 point was more than scroll step columns inside the margin, the window will
29082 scroll more than the value given by the scroll step.
29083
29084 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29085 and `scroll-right' overrides this variable's effect. */);
29086 Vhscroll_step = make_number (0);
29087
29088 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29089 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29090 Bind this around calls to `message' to let it take effect. */);
29091 message_truncate_lines = 0;
29092
29093 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29094 doc: /* Normal hook run to update the menu bar definitions.
29095 Redisplay runs this hook before it redisplays the menu bar.
29096 This is used to update submenus such as Buffers,
29097 whose contents depend on various data. */);
29098 Vmenu_bar_update_hook = Qnil;
29099
29100 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29101 doc: /* Frame for which we are updating a menu.
29102 The enable predicate for a menu binding should check this variable. */);
29103 Vmenu_updating_frame = Qnil;
29104
29105 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29106 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29107 inhibit_menubar_update = 0;
29108
29109 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29110 doc: /* Prefix prepended to all continuation lines at display time.
29111 The value may be a string, an image, or a stretch-glyph; it is
29112 interpreted in the same way as the value of a `display' text property.
29113
29114 This variable is overridden by any `wrap-prefix' text or overlay
29115 property.
29116
29117 To add a prefix to non-continuation lines, use `line-prefix'. */);
29118 Vwrap_prefix = Qnil;
29119 DEFSYM (Qwrap_prefix, "wrap-prefix");
29120 Fmake_variable_buffer_local (Qwrap_prefix);
29121
29122 DEFVAR_LISP ("line-prefix", Vline_prefix,
29123 doc: /* Prefix prepended to all non-continuation lines at display time.
29124 The value may be a string, an image, or a stretch-glyph; it is
29125 interpreted in the same way as the value of a `display' text property.
29126
29127 This variable is overridden by any `line-prefix' text or overlay
29128 property.
29129
29130 To add a prefix to continuation lines, use `wrap-prefix'. */);
29131 Vline_prefix = Qnil;
29132 DEFSYM (Qline_prefix, "line-prefix");
29133 Fmake_variable_buffer_local (Qline_prefix);
29134
29135 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29136 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29137 inhibit_eval_during_redisplay = 0;
29138
29139 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29140 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29141 inhibit_free_realized_faces = 0;
29142
29143 #ifdef GLYPH_DEBUG
29144 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29145 doc: /* Inhibit try_window_id display optimization. */);
29146 inhibit_try_window_id = 0;
29147
29148 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29149 doc: /* Inhibit try_window_reusing display optimization. */);
29150 inhibit_try_window_reusing = 0;
29151
29152 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29153 doc: /* Inhibit try_cursor_movement display optimization. */);
29154 inhibit_try_cursor_movement = 0;
29155 #endif /* GLYPH_DEBUG */
29156
29157 DEFVAR_INT ("overline-margin", overline_margin,
29158 doc: /* Space between overline and text, in pixels.
29159 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29160 margin to the character height. */);
29161 overline_margin = 2;
29162
29163 DEFVAR_INT ("underline-minimum-offset",
29164 underline_minimum_offset,
29165 doc: /* Minimum distance between baseline and underline.
29166 This can improve legibility of underlined text at small font sizes,
29167 particularly when using variable `x-use-underline-position-properties'
29168 with fonts that specify an UNDERLINE_POSITION relatively close to the
29169 baseline. The default value is 1. */);
29170 underline_minimum_offset = 1;
29171
29172 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29173 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29174 This feature only works when on a window system that can change
29175 cursor shapes. */);
29176 display_hourglass_p = 1;
29177
29178 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29179 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29180 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29181
29182 hourglass_atimer = NULL;
29183 hourglass_shown_p = 0;
29184
29185 DEFSYM (Qglyphless_char, "glyphless-char");
29186 DEFSYM (Qhex_code, "hex-code");
29187 DEFSYM (Qempty_box, "empty-box");
29188 DEFSYM (Qthin_space, "thin-space");
29189 DEFSYM (Qzero_width, "zero-width");
29190
29191 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29192 /* Intern this now in case it isn't already done.
29193 Setting this variable twice is harmless.
29194 But don't staticpro it here--that is done in alloc.c. */
29195 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29196 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29197
29198 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29199 doc: /* Char-table defining glyphless characters.
29200 Each element, if non-nil, should be one of the following:
29201 an ASCII acronym string: display this string in a box
29202 `hex-code': display the hexadecimal code of a character in a box
29203 `empty-box': display as an empty box
29204 `thin-space': display as 1-pixel width space
29205 `zero-width': don't display
29206 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29207 display method for graphical terminals and text terminals respectively.
29208 GRAPHICAL and TEXT should each have one of the values listed above.
29209
29210 The char-table has one extra slot to control the display of a character for
29211 which no font is found. This slot only takes effect on graphical terminals.
29212 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29213 `thin-space'. The default is `empty-box'. */);
29214 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29215 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29216 Qempty_box);
29217
29218 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29219 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29220 Vdebug_on_message = Qnil;
29221 }
29222
29223
29224 /* Initialize this module when Emacs starts. */
29225
29226 void
29227 init_xdisp (void)
29228 {
29229 current_header_line_height = current_mode_line_height = -1;
29230
29231 CHARPOS (this_line_start_pos) = 0;
29232
29233 if (!noninteractive)
29234 {
29235 struct window *m = XWINDOW (minibuf_window);
29236 Lisp_Object frame = m->frame;
29237 struct frame *f = XFRAME (frame);
29238 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29239 struct window *r = XWINDOW (root);
29240 int i;
29241
29242 echo_area_window = minibuf_window;
29243
29244 wset_top_line (r, make_number (FRAME_TOP_MARGIN (f)));
29245 wset_total_lines
29246 (r, make_number (FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f)));
29247 wset_total_cols (r, make_number (FRAME_COLS (f)));
29248 wset_top_line (m, make_number (FRAME_LINES (f) - 1));
29249 wset_total_lines (m, make_number (1));
29250 wset_total_cols (m, make_number (FRAME_COLS (f)));
29251
29252 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29253 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29254 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29255
29256 /* The default ellipsis glyphs `...'. */
29257 for (i = 0; i < 3; ++i)
29258 default_invis_vector[i] = make_number ('.');
29259 }
29260
29261 {
29262 /* Allocate the buffer for frame titles.
29263 Also used for `format-mode-line'. */
29264 int size = 100;
29265 mode_line_noprop_buf = xmalloc (size);
29266 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29267 mode_line_noprop_ptr = mode_line_noprop_buf;
29268 mode_line_target = MODE_LINE_DISPLAY;
29269 }
29270
29271 help_echo_showing_p = 0;
29272 }
29273
29274 /* Platform-independent portion of hourglass implementation. */
29275
29276 /* Cancel a currently active hourglass timer, and start a new one. */
29277 void
29278 start_hourglass (void)
29279 {
29280 #if defined (HAVE_WINDOW_SYSTEM)
29281 EMACS_TIME delay;
29282
29283 cancel_hourglass ();
29284
29285 if (INTEGERP (Vhourglass_delay)
29286 && XINT (Vhourglass_delay) > 0)
29287 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29288 TYPE_MAXIMUM (time_t)),
29289 0);
29290 else if (FLOATP (Vhourglass_delay)
29291 && XFLOAT_DATA (Vhourglass_delay) > 0)
29292 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29293 else
29294 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29295
29296 #ifdef HAVE_NTGUI
29297 {
29298 extern void w32_note_current_window (void);
29299 w32_note_current_window ();
29300 }
29301 #endif /* HAVE_NTGUI */
29302
29303 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29304 show_hourglass, NULL);
29305 #endif
29306 }
29307
29308
29309 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29310 shown. */
29311 void
29312 cancel_hourglass (void)
29313 {
29314 #if defined (HAVE_WINDOW_SYSTEM)
29315 if (hourglass_atimer)
29316 {
29317 cancel_atimer (hourglass_atimer);
29318 hourglass_atimer = NULL;
29319 }
29320
29321 if (hourglass_shown_p)
29322 hide_hourglass ();
29323 #endif
29324 }