Avoid looping over all frame windows to freeze and unfreeze.
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2
3 Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
4 Inc.
5
6 This file is part of GNU Emacs.
7
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
22
23 Redisplay.
24
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
29
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
35
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa. Under window systems
38 like X, some portions of the redisplay code are also called
39 asynchronously during mouse movement or expose events. It is very
40 important that these code parts do NOT use the C library (malloc,
41 free) because many C libraries under Unix are not reentrant. They
42 may also NOT call functions of the Lisp interpreter which could
43 change the interpreter's state. If you don't follow these rules,
44 you will encounter bugs which are very hard to explain.
45
46 +--------------+ redisplay +----------------+
47 | Lisp machine |---------------->| Redisplay code |<--+
48 +--------------+ (xdisp.c) +----------------+ |
49 ^ | |
50 +----------------------------------+ |
51 Don't use this path when called |
52 asynchronously! |
53 |
54 expose_window (asynchronous) |
55 |
56 X expose events -----+
57
58 What does redisplay do? Obviously, it has to figure out somehow what
59 has been changed since the last time the display has been updated,
60 and to make these changes visible. Preferably it would do that in
61 a moderately intelligent way, i.e. fast.
62
63 Changes in buffer text can be deduced from window and buffer
64 structures, and from some global variables like `beg_unchanged' and
65 `end_unchanged'. The contents of the display are additionally
66 recorded in a `glyph matrix', a two-dimensional matrix of glyph
67 structures. Each row in such a matrix corresponds to a line on the
68 display, and each glyph in a row corresponds to a column displaying
69 a character, an image, or what else. This matrix is called the
70 `current glyph matrix' or `current matrix' in redisplay
71 terminology.
72
73 For buffer parts that have been changed since the last update, a
74 second glyph matrix is constructed, the so called `desired glyph
75 matrix' or short `desired matrix'. Current and desired matrix are
76 then compared to find a cheap way to update the display, e.g. by
77 reusing part of the display by scrolling lines.
78
79 You will find a lot of redisplay optimizations when you start
80 looking at the innards of redisplay. The overall goal of all these
81 optimizations is to make redisplay fast because it is done
82 frequently. Some of these optimizations are implemented by the
83 following functions:
84
85 . try_cursor_movement
86
87 This function tries to update the display if the text in the
88 window did not change and did not scroll, only point moved, and
89 it did not move off the displayed portion of the text.
90
91 . try_window_reusing_current_matrix
92
93 This function reuses the current matrix of a window when text
94 has not changed, but the window start changed (e.g., due to
95 scrolling).
96
97 . try_window_id
98
99 This function attempts to redisplay a window by reusing parts of
100 its existing display. It finds and reuses the part that was not
101 changed, and redraws the rest.
102
103 . try_window
104
105 This function performs the full redisplay of a single window
106 assuming that its fonts were not changed and that the cursor
107 will not end up in the scroll margins. (Loading fonts requires
108 re-adjustment of dimensions of glyph matrices, which makes this
109 method impossible to use.)
110
111 These optimizations are tried in sequence (some can be skipped if
112 it is known that they are not applicable). If none of the
113 optimizations were successful, redisplay calls redisplay_windows,
114 which performs a full redisplay of all windows.
115
116 Desired matrices.
117
118 Desired matrices are always built per Emacs window. The function
119 `display_line' is the central function to look at if you are
120 interested. It constructs one row in a desired matrix given an
121 iterator structure containing both a buffer position and a
122 description of the environment in which the text is to be
123 displayed. But this is too early, read on.
124
125 Characters and pixmaps displayed for a range of buffer text depend
126 on various settings of buffers and windows, on overlays and text
127 properties, on display tables, on selective display. The good news
128 is that all this hairy stuff is hidden behind a small set of
129 interface functions taking an iterator structure (struct it)
130 argument.
131
132 Iteration over things to be displayed is then simple. It is
133 started by initializing an iterator with a call to init_iterator,
134 passing it the buffer position where to start iteration. For
135 iteration over strings, pass -1 as the position to init_iterator,
136 and call reseat_to_string when the string is ready, to initialize
137 the iterator for that string. Thereafter, calls to
138 get_next_display_element fill the iterator structure with relevant
139 information about the next thing to display. Calls to
140 set_iterator_to_next move the iterator to the next thing.
141
142 Besides this, an iterator also contains information about the
143 display environment in which glyphs for display elements are to be
144 produced. It has fields for the width and height of the display,
145 the information whether long lines are truncated or continued, a
146 current X and Y position, and lots of other stuff you can better
147 see in dispextern.h.
148
149 Glyphs in a desired matrix are normally constructed in a loop
150 calling get_next_display_element and then PRODUCE_GLYPHS. The call
151 to PRODUCE_GLYPHS will fill the iterator structure with pixel
152 information about the element being displayed and at the same time
153 produce glyphs for it. If the display element fits on the line
154 being displayed, set_iterator_to_next is called next, otherwise the
155 glyphs produced are discarded. The function display_line is the
156 workhorse of filling glyph rows in the desired matrix with glyphs.
157 In addition to producing glyphs, it also handles line truncation
158 and continuation, word wrap, and cursor positioning (for the
159 latter, see also set_cursor_from_row).
160
161 Frame matrices.
162
163 That just couldn't be all, could it? What about terminal types not
164 supporting operations on sub-windows of the screen? To update the
165 display on such a terminal, window-based glyph matrices are not
166 well suited. To be able to reuse part of the display (scrolling
167 lines up and down), we must instead have a view of the whole
168 screen. This is what `frame matrices' are for. They are a trick.
169
170 Frames on terminals like above have a glyph pool. Windows on such
171 a frame sub-allocate their glyph memory from their frame's glyph
172 pool. The frame itself is given its own glyph matrices. By
173 coincidence---or maybe something else---rows in window glyph
174 matrices are slices of corresponding rows in frame matrices. Thus
175 writing to window matrices implicitly updates a frame matrix which
176 provides us with the view of the whole screen that we originally
177 wanted to have without having to move many bytes around. To be
178 honest, there is a little bit more done, but not much more. If you
179 plan to extend that code, take a look at dispnew.c. The function
180 build_frame_matrix is a good starting point.
181
182 Bidirectional display.
183
184 Bidirectional display adds quite some hair to this already complex
185 design. The good news are that a large portion of that hairy stuff
186 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
187 reordering engine which is called by set_iterator_to_next and
188 returns the next character to display in the visual order. See
189 commentary on bidi.c for more details. As far as redisplay is
190 concerned, the effect of calling bidi_move_to_visually_next, the
191 main interface of the reordering engine, is that the iterator gets
192 magically placed on the buffer or string position that is to be
193 displayed next. In other words, a linear iteration through the
194 buffer/string is replaced with a non-linear one. All the rest of
195 the redisplay is oblivious to the bidi reordering.
196
197 Well, almost oblivious---there are still complications, most of
198 them due to the fact that buffer and string positions no longer
199 change monotonously with glyph indices in a glyph row. Moreover,
200 for continued lines, the buffer positions may not even be
201 monotonously changing with vertical positions. Also, accounting
202 for face changes, overlays, etc. becomes more complex because
203 non-linear iteration could potentially skip many positions with
204 changes, and then cross them again on the way back...
205
206 One other prominent effect of bidirectional display is that some
207 paragraphs of text need to be displayed starting at the right
208 margin of the window---the so-called right-to-left, or R2L
209 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
210 which have their reversed_p flag set. The bidi reordering engine
211 produces characters in such rows starting from the character which
212 should be the rightmost on display. PRODUCE_GLYPHS then reverses
213 the order, when it fills up the glyph row whose reversed_p flag is
214 set, by prepending each new glyph to what is already there, instead
215 of appending it. When the glyph row is complete, the function
216 extend_face_to_end_of_line fills the empty space to the left of the
217 leftmost character with special glyphs, which will display as,
218 well, empty. On text terminals, these special glyphs are simply
219 blank characters. On graphics terminals, there's a single stretch
220 glyph of a suitably computed width. Both the blanks and the
221 stretch glyph are given the face of the background of the line.
222 This way, the terminal-specific back-end can still draw the glyphs
223 left to right, even for R2L lines.
224
225 Bidirectional display and character compositions
226
227 Some scripts cannot be displayed by drawing each character
228 individually, because adjacent characters change each other's shape
229 on display. For example, Arabic and Indic scripts belong to this
230 category.
231
232 Emacs display supports this by providing "character compositions",
233 most of which is implemented in composite.c. During the buffer
234 scan that delivers characters to PRODUCE_GLYPHS, if the next
235 character to be delivered is a composed character, the iteration
236 calls composition_reseat_it and next_element_from_composition. If
237 they succeed to compose the character with one or more of the
238 following characters, the whole sequence of characters that where
239 composed is recorded in the `struct composition_it' object that is
240 part of the buffer iterator. The composed sequence could produce
241 one or more font glyphs (called "grapheme clusters") on the screen.
242 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
243 in the direction corresponding to the current bidi scan direction
244 (recorded in the scan_dir member of the `struct bidi_it' object
245 that is part of the buffer iterator). In particular, if the bidi
246 iterator currently scans the buffer backwards, the grapheme
247 clusters are delivered back to front. This reorders the grapheme
248 clusters as appropriate for the current bidi context. Note that
249 this means that the grapheme clusters are always stored in the
250 LGSTRING object (see composite.c) in the logical order.
251
252 Moving an iterator in bidirectional text
253 without producing glyphs
254
255 Note one important detail mentioned above: that the bidi reordering
256 engine, driven by the iterator, produces characters in R2L rows
257 starting at the character that will be the rightmost on display.
258 As far as the iterator is concerned, the geometry of such rows is
259 still left to right, i.e. the iterator "thinks" the first character
260 is at the leftmost pixel position. The iterator does not know that
261 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
262 delivers. This is important when functions from the move_it_*
263 family are used to get to certain screen position or to match
264 screen coordinates with buffer coordinates: these functions use the
265 iterator geometry, which is left to right even in R2L paragraphs.
266 This works well with most callers of move_it_*, because they need
267 to get to a specific column, and columns are still numbered in the
268 reading order, i.e. the rightmost character in a R2L paragraph is
269 still column zero. But some callers do not get well with this; a
270 notable example is mouse clicks that need to find the character
271 that corresponds to certain pixel coordinates. See
272 buffer_posn_from_coords in dispnew.c for how this is handled. */
273
274 #include <config.h>
275 #include <stdio.h>
276 #include <limits.h>
277
278 #include "lisp.h"
279 #include "atimer.h"
280 #include "keyboard.h"
281 #include "frame.h"
282 #include "window.h"
283 #include "termchar.h"
284 #include "dispextern.h"
285 #include "character.h"
286 #include "buffer.h"
287 #include "charset.h"
288 #include "indent.h"
289 #include "commands.h"
290 #include "keymap.h"
291 #include "macros.h"
292 #include "disptab.h"
293 #include "termhooks.h"
294 #include "termopts.h"
295 #include "intervals.h"
296 #include "coding.h"
297 #include "process.h"
298 #include "region-cache.h"
299 #include "font.h"
300 #include "fontset.h"
301 #include "blockinput.h"
302
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 #ifndef FRAME_X_OUTPUT
317 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
318 #endif
319
320 #define INFINITY 10000000
321
322 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
323 Lisp_Object Qwindow_scroll_functions;
324 static Lisp_Object Qwindow_text_change_functions;
325 static Lisp_Object Qredisplay_end_trigger_functions;
326 Lisp_Object Qinhibit_point_motion_hooks;
327 static Lisp_Object QCeval, QCpropertize;
328 Lisp_Object QCfile, QCdata;
329 static Lisp_Object Qfontified;
330 static Lisp_Object Qgrow_only;
331 static Lisp_Object Qinhibit_eval_during_redisplay;
332 static Lisp_Object Qbuffer_position, Qposition, Qobject;
333 static Lisp_Object Qright_to_left, Qleft_to_right;
334
335 /* Cursor shapes. */
336 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
337
338 /* Pointer shapes. */
339 static Lisp_Object Qarrow, Qhand;
340 Lisp_Object Qtext;
341
342 /* Holds the list (error). */
343 static Lisp_Object list_of_error;
344
345 static Lisp_Object Qfontification_functions;
346
347 static Lisp_Object Qwrap_prefix;
348 static Lisp_Object Qline_prefix;
349 static Lisp_Object Qredisplay_internal;
350
351 /* Non-nil means don't actually do any redisplay. */
352
353 Lisp_Object Qinhibit_redisplay;
354
355 /* Names of text properties relevant for redisplay. */
356
357 Lisp_Object Qdisplay;
358
359 Lisp_Object Qspace, QCalign_to;
360 static Lisp_Object QCrelative_width, QCrelative_height;
361 Lisp_Object Qleft_margin, Qright_margin;
362 static Lisp_Object Qspace_width, Qraise;
363 static Lisp_Object Qslice;
364 Lisp_Object Qcenter;
365 static Lisp_Object Qmargin, Qpointer;
366 static Lisp_Object Qline_height;
367
368 #ifdef HAVE_WINDOW_SYSTEM
369
370 /* Test if overflow newline into fringe. Called with iterator IT
371 at or past right window margin, and with IT->current_x set. */
372
373 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
374 (!NILP (Voverflow_newline_into_fringe) \
375 && FRAME_WINDOW_P ((IT)->f) \
376 && ((IT)->bidi_it.paragraph_dir == R2L \
377 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
378 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
379 && (IT)->current_x == (IT)->last_visible_x)
380
381 #else /* !HAVE_WINDOW_SYSTEM */
382 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
383 #endif /* HAVE_WINDOW_SYSTEM */
384
385 /* Test if the display element loaded in IT, or the underlying buffer
386 or string character, is a space or a TAB character. This is used
387 to determine where word wrapping can occur. */
388
389 #define IT_DISPLAYING_WHITESPACE(it) \
390 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
391 || ((STRINGP (it->string) \
392 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
393 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
394 || (it->s \
395 && (it->s[IT_BYTEPOS (*it)] == ' ' \
396 || it->s[IT_BYTEPOS (*it)] == '\t')) \
397 || (IT_BYTEPOS (*it) < ZV_BYTE \
398 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
399 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
400
401 /* Name of the face used to highlight trailing whitespace. */
402
403 static Lisp_Object Qtrailing_whitespace;
404
405 /* Name and number of the face used to highlight escape glyphs. */
406
407 static Lisp_Object Qescape_glyph;
408
409 /* Name and number of the face used to highlight non-breaking spaces. */
410
411 static Lisp_Object Qnobreak_space;
412
413 /* The symbol `image' which is the car of the lists used to represent
414 images in Lisp. Also a tool bar style. */
415
416 Lisp_Object Qimage;
417
418 /* The image map types. */
419 Lisp_Object QCmap;
420 static Lisp_Object QCpointer;
421 static Lisp_Object Qrect, Qcircle, Qpoly;
422
423 /* Tool bar styles */
424 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
425
426 /* Non-zero means print newline to stdout before next mini-buffer
427 message. */
428
429 int noninteractive_need_newline;
430
431 /* Non-zero means print newline to message log before next message. */
432
433 static int message_log_need_newline;
434
435 /* Three markers that message_dolog uses.
436 It could allocate them itself, but that causes trouble
437 in handling memory-full errors. */
438 static Lisp_Object message_dolog_marker1;
439 static Lisp_Object message_dolog_marker2;
440 static Lisp_Object message_dolog_marker3;
441 \f
442 /* The buffer position of the first character appearing entirely or
443 partially on the line of the selected window which contains the
444 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
445 redisplay optimization in redisplay_internal. */
446
447 static struct text_pos this_line_start_pos;
448
449 /* Number of characters past the end of the line above, including the
450 terminating newline. */
451
452 static struct text_pos this_line_end_pos;
453
454 /* The vertical positions and the height of this line. */
455
456 static int this_line_vpos;
457 static int this_line_y;
458 static int this_line_pixel_height;
459
460 /* X position at which this display line starts. Usually zero;
461 negative if first character is partially visible. */
462
463 static int this_line_start_x;
464
465 /* The smallest character position seen by move_it_* functions as they
466 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
467 hscrolled lines, see display_line. */
468
469 static struct text_pos this_line_min_pos;
470
471 /* Buffer that this_line_.* variables are referring to. */
472
473 static struct buffer *this_line_buffer;
474
475
476 /* Values of those variables at last redisplay are stored as
477 properties on `overlay-arrow-position' symbol. However, if
478 Voverlay_arrow_position is a marker, last-arrow-position is its
479 numerical position. */
480
481 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
482
483 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
484 properties on a symbol in overlay-arrow-variable-list. */
485
486 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
487
488 Lisp_Object Qmenu_bar_update_hook;
489
490 /* Nonzero if an overlay arrow has been displayed in this window. */
491
492 static int overlay_arrow_seen;
493
494 /* Vector containing glyphs for an ellipsis `...'. */
495
496 static Lisp_Object default_invis_vector[3];
497
498 /* This is the window where the echo area message was displayed. It
499 is always a mini-buffer window, but it may not be the same window
500 currently active as a mini-buffer. */
501
502 Lisp_Object echo_area_window;
503
504 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
505 pushes the current message and the value of
506 message_enable_multibyte on the stack, the function restore_message
507 pops the stack and displays MESSAGE again. */
508
509 static Lisp_Object Vmessage_stack;
510
511 /* Nonzero means multibyte characters were enabled when the echo area
512 message was specified. */
513
514 static int message_enable_multibyte;
515
516 /* Nonzero if we should redraw the mode lines on the next redisplay. */
517
518 int update_mode_lines;
519
520 /* Nonzero if window sizes or contents have changed since last
521 redisplay that finished. */
522
523 int windows_or_buffers_changed;
524
525 /* Nonzero means a frame's cursor type has been changed. */
526
527 int cursor_type_changed;
528
529 /* Nonzero after display_mode_line if %l was used and it displayed a
530 line number. */
531
532 static int line_number_displayed;
533
534 /* The name of the *Messages* buffer, a string. */
535
536 static Lisp_Object Vmessages_buffer_name;
537
538 /* Current, index 0, and last displayed echo area message. Either
539 buffers from echo_buffers, or nil to indicate no message. */
540
541 Lisp_Object echo_area_buffer[2];
542
543 /* The buffers referenced from echo_area_buffer. */
544
545 static Lisp_Object echo_buffer[2];
546
547 /* A vector saved used in with_area_buffer to reduce consing. */
548
549 static Lisp_Object Vwith_echo_area_save_vector;
550
551 /* Non-zero means display_echo_area should display the last echo area
552 message again. Set by redisplay_preserve_echo_area. */
553
554 static int display_last_displayed_message_p;
555
556 /* Nonzero if echo area is being used by print; zero if being used by
557 message. */
558
559 static int message_buf_print;
560
561 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
562
563 static Lisp_Object Qinhibit_menubar_update;
564 static Lisp_Object Qmessage_truncate_lines;
565
566 /* Set to 1 in clear_message to make redisplay_internal aware
567 of an emptied echo area. */
568
569 static int message_cleared_p;
570
571 /* A scratch glyph row with contents used for generating truncation
572 glyphs. Also used in direct_output_for_insert. */
573
574 #define MAX_SCRATCH_GLYPHS 100
575 static struct glyph_row scratch_glyph_row;
576 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
577
578 /* Ascent and height of the last line processed by move_it_to. */
579
580 static int last_height;
581
582 /* Non-zero if there's a help-echo in the echo area. */
583
584 int help_echo_showing_p;
585
586 /* If >= 0, computed, exact values of mode-line and header-line height
587 to use in the macros CURRENT_MODE_LINE_HEIGHT and
588 CURRENT_HEADER_LINE_HEIGHT. */
589
590 int current_mode_line_height, current_header_line_height;
591
592 /* The maximum distance to look ahead for text properties. Values
593 that are too small let us call compute_char_face and similar
594 functions too often which is expensive. Values that are too large
595 let us call compute_char_face and alike too often because we
596 might not be interested in text properties that far away. */
597
598 #define TEXT_PROP_DISTANCE_LIMIT 100
599
600 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
601 iterator state and later restore it. This is needed because the
602 bidi iterator on bidi.c keeps a stacked cache of its states, which
603 is really a singleton. When we use scratch iterator objects to
604 move around the buffer, we can cause the bidi cache to be pushed or
605 popped, and therefore we need to restore the cache state when we
606 return to the original iterator. */
607 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
608 do { \
609 if (CACHE) \
610 bidi_unshelve_cache (CACHE, 1); \
611 ITCOPY = ITORIG; \
612 CACHE = bidi_shelve_cache (); \
613 } while (0)
614
615 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
616 do { \
617 if (pITORIG != pITCOPY) \
618 *(pITORIG) = *(pITCOPY); \
619 bidi_unshelve_cache (CACHE, 0); \
620 CACHE = NULL; \
621 } while (0)
622
623 #ifdef GLYPH_DEBUG
624
625 /* Non-zero means print traces of redisplay if compiled with
626 GLYPH_DEBUG defined. */
627
628 int trace_redisplay_p;
629
630 #endif /* GLYPH_DEBUG */
631
632 #ifdef DEBUG_TRACE_MOVE
633 /* Non-zero means trace with TRACE_MOVE to stderr. */
634 int trace_move;
635
636 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
637 #else
638 #define TRACE_MOVE(x) (void) 0
639 #endif
640
641 static Lisp_Object Qauto_hscroll_mode;
642
643 /* Buffer being redisplayed -- for redisplay_window_error. */
644
645 static struct buffer *displayed_buffer;
646
647 /* Value returned from text property handlers (see below). */
648
649 enum prop_handled
650 {
651 HANDLED_NORMALLY,
652 HANDLED_RECOMPUTE_PROPS,
653 HANDLED_OVERLAY_STRING_CONSUMED,
654 HANDLED_RETURN
655 };
656
657 /* A description of text properties that redisplay is interested
658 in. */
659
660 struct props
661 {
662 /* The name of the property. */
663 Lisp_Object *name;
664
665 /* A unique index for the property. */
666 enum prop_idx idx;
667
668 /* A handler function called to set up iterator IT from the property
669 at IT's current position. Value is used to steer handle_stop. */
670 enum prop_handled (*handler) (struct it *it);
671 };
672
673 static enum prop_handled handle_face_prop (struct it *);
674 static enum prop_handled handle_invisible_prop (struct it *);
675 static enum prop_handled handle_display_prop (struct it *);
676 static enum prop_handled handle_composition_prop (struct it *);
677 static enum prop_handled handle_overlay_change (struct it *);
678 static enum prop_handled handle_fontified_prop (struct it *);
679
680 /* Properties handled by iterators. */
681
682 static struct props it_props[] =
683 {
684 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
685 /* Handle `face' before `display' because some sub-properties of
686 `display' need to know the face. */
687 {&Qface, FACE_PROP_IDX, handle_face_prop},
688 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
689 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
690 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
691 {NULL, 0, NULL}
692 };
693
694 /* Value is the position described by X. If X is a marker, value is
695 the marker_position of X. Otherwise, value is X. */
696
697 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
698
699 /* Enumeration returned by some move_it_.* functions internally. */
700
701 enum move_it_result
702 {
703 /* Not used. Undefined value. */
704 MOVE_UNDEFINED,
705
706 /* Move ended at the requested buffer position or ZV. */
707 MOVE_POS_MATCH_OR_ZV,
708
709 /* Move ended at the requested X pixel position. */
710 MOVE_X_REACHED,
711
712 /* Move within a line ended at the end of a line that must be
713 continued. */
714 MOVE_LINE_CONTINUED,
715
716 /* Move within a line ended at the end of a line that would
717 be displayed truncated. */
718 MOVE_LINE_TRUNCATED,
719
720 /* Move within a line ended at a line end. */
721 MOVE_NEWLINE_OR_CR
722 };
723
724 /* This counter is used to clear the face cache every once in a while
725 in redisplay_internal. It is incremented for each redisplay.
726 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
727 cleared. */
728
729 #define CLEAR_FACE_CACHE_COUNT 500
730 static int clear_face_cache_count;
731
732 /* Similarly for the image cache. */
733
734 #ifdef HAVE_WINDOW_SYSTEM
735 #define CLEAR_IMAGE_CACHE_COUNT 101
736 static int clear_image_cache_count;
737
738 /* Null glyph slice */
739 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
740 #endif
741
742 /* True while redisplay_internal is in progress. */
743
744 bool redisplaying_p;
745
746 static Lisp_Object Qinhibit_free_realized_faces;
747 static Lisp_Object Qmode_line_default_help_echo;
748
749 /* If a string, XTread_socket generates an event to display that string.
750 (The display is done in read_char.) */
751
752 Lisp_Object help_echo_string;
753 Lisp_Object help_echo_window;
754 Lisp_Object help_echo_object;
755 ptrdiff_t help_echo_pos;
756
757 /* Temporary variable for XTread_socket. */
758
759 Lisp_Object previous_help_echo_string;
760
761 /* Platform-independent portion of hourglass implementation. */
762
763 /* Non-zero means an hourglass cursor is currently shown. */
764 int hourglass_shown_p;
765
766 /* If non-null, an asynchronous timer that, when it expires, displays
767 an hourglass cursor on all frames. */
768 struct atimer *hourglass_atimer;
769
770 /* Name of the face used to display glyphless characters. */
771 Lisp_Object Qglyphless_char;
772
773 /* Symbol for the purpose of Vglyphless_char_display. */
774 static Lisp_Object Qglyphless_char_display;
775
776 /* Method symbols for Vglyphless_char_display. */
777 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
778
779 /* Default pixel width of `thin-space' display method. */
780 #define THIN_SPACE_WIDTH 1
781
782 /* Default number of seconds to wait before displaying an hourglass
783 cursor. */
784 #define DEFAULT_HOURGLASS_DELAY 1
785
786 \f
787 /* Function prototypes. */
788
789 static void setup_for_ellipsis (struct it *, int);
790 static void set_iterator_to_next (struct it *, int);
791 static void mark_window_display_accurate_1 (struct window *, int);
792 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
793 static int display_prop_string_p (Lisp_Object, Lisp_Object);
794 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
795 static int cursor_row_p (struct glyph_row *);
796 static int redisplay_mode_lines (Lisp_Object, int);
797 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
798
799 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
800
801 static void handle_line_prefix (struct it *);
802
803 static void pint2str (char *, int, ptrdiff_t);
804 static void pint2hrstr (char *, int, ptrdiff_t);
805 static struct text_pos run_window_scroll_functions (Lisp_Object,
806 struct text_pos);
807 static int text_outside_line_unchanged_p (struct window *,
808 ptrdiff_t, ptrdiff_t);
809 static void store_mode_line_noprop_char (char);
810 static int store_mode_line_noprop (const char *, int, int);
811 static void handle_stop (struct it *);
812 static void handle_stop_backwards (struct it *, ptrdiff_t);
813 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
814 static void ensure_echo_area_buffers (void);
815 static void unwind_with_echo_area_buffer (Lisp_Object);
816 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
817 static int with_echo_area_buffer (struct window *, int,
818 int (*) (ptrdiff_t, Lisp_Object),
819 ptrdiff_t, Lisp_Object);
820 static void clear_garbaged_frames (void);
821 static int current_message_1 (ptrdiff_t, Lisp_Object);
822 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
823 static void set_message (Lisp_Object);
824 static int set_message_1 (ptrdiff_t, Lisp_Object);
825 static int display_echo_area (struct window *);
826 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
827 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
828 static void unwind_redisplay (void);
829 static int string_char_and_length (const unsigned char *, int *);
830 static struct text_pos display_prop_end (struct it *, Lisp_Object,
831 struct text_pos);
832 static int compute_window_start_on_continuation_line (struct window *);
833 static void insert_left_trunc_glyphs (struct it *);
834 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
835 Lisp_Object);
836 static void extend_face_to_end_of_line (struct it *);
837 static int append_space_for_newline (struct it *, int);
838 static int cursor_row_fully_visible_p (struct window *, int, int);
839 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
840 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
841 static int trailing_whitespace_p (ptrdiff_t);
842 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
843 static void push_it (struct it *, struct text_pos *);
844 static void iterate_out_of_display_property (struct it *);
845 static void pop_it (struct it *);
846 static void sync_frame_with_window_matrix_rows (struct window *);
847 static void redisplay_internal (void);
848 static int echo_area_display (int);
849 static void redisplay_windows (Lisp_Object);
850 static void redisplay_window (Lisp_Object, int);
851 static Lisp_Object redisplay_window_error (Lisp_Object);
852 static Lisp_Object redisplay_window_0 (Lisp_Object);
853 static Lisp_Object redisplay_window_1 (Lisp_Object);
854 static int set_cursor_from_row (struct window *, struct glyph_row *,
855 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
856 int, int);
857 static int update_menu_bar (struct frame *, int, int);
858 static int try_window_reusing_current_matrix (struct window *);
859 static int try_window_id (struct window *);
860 static int display_line (struct it *);
861 static int display_mode_lines (struct window *);
862 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
863 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
864 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
865 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
866 static void display_menu_bar (struct window *);
867 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
868 ptrdiff_t *);
869 static int display_string (const char *, Lisp_Object, Lisp_Object,
870 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
871 static void compute_line_metrics (struct it *);
872 static void run_redisplay_end_trigger_hook (struct it *);
873 static int get_overlay_strings (struct it *, ptrdiff_t);
874 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
875 static void next_overlay_string (struct it *);
876 static void reseat (struct it *, struct text_pos, int);
877 static void reseat_1 (struct it *, struct text_pos, int);
878 static void back_to_previous_visible_line_start (struct it *);
879 static void reseat_at_next_visible_line_start (struct it *, int);
880 static int next_element_from_ellipsis (struct it *);
881 static int next_element_from_display_vector (struct it *);
882 static int next_element_from_string (struct it *);
883 static int next_element_from_c_string (struct it *);
884 static int next_element_from_buffer (struct it *);
885 static int next_element_from_composition (struct it *);
886 static int next_element_from_image (struct it *);
887 static int next_element_from_stretch (struct it *);
888 static void load_overlay_strings (struct it *, ptrdiff_t);
889 static int init_from_display_pos (struct it *, struct window *,
890 struct display_pos *);
891 static void reseat_to_string (struct it *, const char *,
892 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
893 static int get_next_display_element (struct it *);
894 static enum move_it_result
895 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
896 enum move_operation_enum);
897 static void get_visually_first_element (struct it *);
898 static void init_to_row_start (struct it *, struct window *,
899 struct glyph_row *);
900 static int init_to_row_end (struct it *, struct window *,
901 struct glyph_row *);
902 static void back_to_previous_line_start (struct it *);
903 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
904 static struct text_pos string_pos_nchars_ahead (struct text_pos,
905 Lisp_Object, ptrdiff_t);
906 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
907 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
908 static ptrdiff_t number_of_chars (const char *, bool);
909 static void compute_stop_pos (struct it *);
910 static void compute_string_pos (struct text_pos *, struct text_pos,
911 Lisp_Object);
912 static int face_before_or_after_it_pos (struct it *, int);
913 static ptrdiff_t next_overlay_change (ptrdiff_t);
914 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
915 Lisp_Object, struct text_pos *, ptrdiff_t, int);
916 static int handle_single_display_spec (struct it *, Lisp_Object,
917 Lisp_Object, Lisp_Object,
918 struct text_pos *, ptrdiff_t, int, int);
919 static int underlying_face_id (struct it *);
920 static int in_ellipses_for_invisible_text_p (struct display_pos *,
921 struct window *);
922
923 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
924 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
925
926 #ifdef HAVE_WINDOW_SYSTEM
927
928 static void x_consider_frame_title (Lisp_Object);
929 static int tool_bar_lines_needed (struct frame *, int *);
930 static void update_tool_bar (struct frame *, int);
931 static void build_desired_tool_bar_string (struct frame *f);
932 static int redisplay_tool_bar (struct frame *);
933 static void display_tool_bar_line (struct it *, int);
934 static void notice_overwritten_cursor (struct window *,
935 enum glyph_row_area,
936 int, int, int, int);
937 static void append_stretch_glyph (struct it *, Lisp_Object,
938 int, int, int);
939
940
941 #endif /* HAVE_WINDOW_SYSTEM */
942
943 static void produce_special_glyphs (struct it *, enum display_element_type);
944 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
945 static int coords_in_mouse_face_p (struct window *, int, int);
946
947
948 \f
949 /***********************************************************************
950 Window display dimensions
951 ***********************************************************************/
952
953 /* Return the bottom boundary y-position for text lines in window W.
954 This is the first y position at which a line cannot start.
955 It is relative to the top of the window.
956
957 This is the height of W minus the height of a mode line, if any. */
958
959 int
960 window_text_bottom_y (struct window *w)
961 {
962 int height = WINDOW_TOTAL_HEIGHT (w);
963
964 if (WINDOW_WANTS_MODELINE_P (w))
965 height -= CURRENT_MODE_LINE_HEIGHT (w);
966 return height;
967 }
968
969 /* Return the pixel width of display area AREA of window W. AREA < 0
970 means return the total width of W, not including fringes to
971 the left and right of the window. */
972
973 int
974 window_box_width (struct window *w, int area)
975 {
976 int cols = w->total_cols;
977 int pixels = 0;
978
979 if (!w->pseudo_window_p)
980 {
981 cols -= WINDOW_SCROLL_BAR_COLS (w);
982
983 if (area == TEXT_AREA)
984 {
985 if (INTEGERP (w->left_margin_cols))
986 cols -= XFASTINT (w->left_margin_cols);
987 if (INTEGERP (w->right_margin_cols))
988 cols -= XFASTINT (w->right_margin_cols);
989 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
990 }
991 else if (area == LEFT_MARGIN_AREA)
992 {
993 cols = (INTEGERP (w->left_margin_cols)
994 ? XFASTINT (w->left_margin_cols) : 0);
995 pixels = 0;
996 }
997 else if (area == RIGHT_MARGIN_AREA)
998 {
999 cols = (INTEGERP (w->right_margin_cols)
1000 ? XFASTINT (w->right_margin_cols) : 0);
1001 pixels = 0;
1002 }
1003 }
1004
1005 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1006 }
1007
1008
1009 /* Return the pixel height of the display area of window W, not
1010 including mode lines of W, if any. */
1011
1012 int
1013 window_box_height (struct window *w)
1014 {
1015 struct frame *f = XFRAME (w->frame);
1016 int height = WINDOW_TOTAL_HEIGHT (w);
1017
1018 eassert (height >= 0);
1019
1020 /* Note: the code below that determines the mode-line/header-line
1021 height is essentially the same as that contained in the macro
1022 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1023 the appropriate glyph row has its `mode_line_p' flag set,
1024 and if it doesn't, uses estimate_mode_line_height instead. */
1025
1026 if (WINDOW_WANTS_MODELINE_P (w))
1027 {
1028 struct glyph_row *ml_row
1029 = (w->current_matrix && w->current_matrix->rows
1030 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1031 : 0);
1032 if (ml_row && ml_row->mode_line_p)
1033 height -= ml_row->height;
1034 else
1035 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1036 }
1037
1038 if (WINDOW_WANTS_HEADER_LINE_P (w))
1039 {
1040 struct glyph_row *hl_row
1041 = (w->current_matrix && w->current_matrix->rows
1042 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1043 : 0);
1044 if (hl_row && hl_row->mode_line_p)
1045 height -= hl_row->height;
1046 else
1047 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1048 }
1049
1050 /* With a very small font and a mode-line that's taller than
1051 default, we might end up with a negative height. */
1052 return max (0, height);
1053 }
1054
1055 /* Return the window-relative coordinate of the left edge of display
1056 area AREA of window W. AREA < 0 means return the left edge of the
1057 whole window, to the right of the left fringe of W. */
1058
1059 int
1060 window_box_left_offset (struct window *w, int area)
1061 {
1062 int x;
1063
1064 if (w->pseudo_window_p)
1065 return 0;
1066
1067 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1068
1069 if (area == TEXT_AREA)
1070 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1071 + window_box_width (w, LEFT_MARGIN_AREA));
1072 else if (area == RIGHT_MARGIN_AREA)
1073 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1074 + window_box_width (w, LEFT_MARGIN_AREA)
1075 + window_box_width (w, TEXT_AREA)
1076 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1077 ? 0
1078 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1079 else if (area == LEFT_MARGIN_AREA
1080 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1081 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1082
1083 return x;
1084 }
1085
1086
1087 /* Return the window-relative coordinate of the right edge of display
1088 area AREA of window W. AREA < 0 means return the right edge of the
1089 whole window, to the left of the right fringe of W. */
1090
1091 int
1092 window_box_right_offset (struct window *w, int area)
1093 {
1094 return window_box_left_offset (w, area) + window_box_width (w, area);
1095 }
1096
1097 /* Return the frame-relative coordinate of the left edge of display
1098 area AREA of window W. AREA < 0 means return the left edge of the
1099 whole window, to the right of the left fringe of W. */
1100
1101 int
1102 window_box_left (struct window *w, int area)
1103 {
1104 struct frame *f = XFRAME (w->frame);
1105 int x;
1106
1107 if (w->pseudo_window_p)
1108 return FRAME_INTERNAL_BORDER_WIDTH (f);
1109
1110 x = (WINDOW_LEFT_EDGE_X (w)
1111 + window_box_left_offset (w, area));
1112
1113 return x;
1114 }
1115
1116
1117 /* Return the frame-relative coordinate of the right edge of display
1118 area AREA of window W. AREA < 0 means return the right edge of the
1119 whole window, to the left of the right fringe of W. */
1120
1121 int
1122 window_box_right (struct window *w, int area)
1123 {
1124 return window_box_left (w, area) + window_box_width (w, area);
1125 }
1126
1127 /* Get the bounding box of the display area AREA of window W, without
1128 mode lines, in frame-relative coordinates. AREA < 0 means the
1129 whole window, not including the left and right fringes of
1130 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1131 coordinates of the upper-left corner of the box. Return in
1132 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1133
1134 void
1135 window_box (struct window *w, int area, int *box_x, int *box_y,
1136 int *box_width, int *box_height)
1137 {
1138 if (box_width)
1139 *box_width = window_box_width (w, area);
1140 if (box_height)
1141 *box_height = window_box_height (w);
1142 if (box_x)
1143 *box_x = window_box_left (w, area);
1144 if (box_y)
1145 {
1146 *box_y = WINDOW_TOP_EDGE_Y (w);
1147 if (WINDOW_WANTS_HEADER_LINE_P (w))
1148 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1149 }
1150 }
1151
1152
1153 /* Get the bounding box of the display area AREA of window W, without
1154 mode lines. AREA < 0 means the whole window, not including the
1155 left and right fringe of the window. Return in *TOP_LEFT_X
1156 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1157 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1158 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1159 box. */
1160
1161 static void
1162 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1163 int *bottom_right_x, int *bottom_right_y)
1164 {
1165 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1166 bottom_right_y);
1167 *bottom_right_x += *top_left_x;
1168 *bottom_right_y += *top_left_y;
1169 }
1170
1171
1172 \f
1173 /***********************************************************************
1174 Utilities
1175 ***********************************************************************/
1176
1177 /* Return the bottom y-position of the line the iterator IT is in.
1178 This can modify IT's settings. */
1179
1180 int
1181 line_bottom_y (struct it *it)
1182 {
1183 int line_height = it->max_ascent + it->max_descent;
1184 int line_top_y = it->current_y;
1185
1186 if (line_height == 0)
1187 {
1188 if (last_height)
1189 line_height = last_height;
1190 else if (IT_CHARPOS (*it) < ZV)
1191 {
1192 move_it_by_lines (it, 1);
1193 line_height = (it->max_ascent || it->max_descent
1194 ? it->max_ascent + it->max_descent
1195 : last_height);
1196 }
1197 else
1198 {
1199 struct glyph_row *row = it->glyph_row;
1200
1201 /* Use the default character height. */
1202 it->glyph_row = NULL;
1203 it->what = IT_CHARACTER;
1204 it->c = ' ';
1205 it->len = 1;
1206 PRODUCE_GLYPHS (it);
1207 line_height = it->ascent + it->descent;
1208 it->glyph_row = row;
1209 }
1210 }
1211
1212 return line_top_y + line_height;
1213 }
1214
1215 DEFUN ("line-pixel-height", Fline_pixel_height,
1216 Sline_pixel_height, 0, 0, 0,
1217 doc: /* Return height in pixels of text line in the selected window.
1218
1219 Value is the height in pixels of the line at point. */)
1220 (void)
1221 {
1222 struct it it;
1223 struct text_pos pt;
1224 struct window *w = XWINDOW (selected_window);
1225
1226 SET_TEXT_POS (pt, PT, PT_BYTE);
1227 start_display (&it, w, pt);
1228 it.vpos = it.current_y = 0;
1229 last_height = 0;
1230 return make_number (line_bottom_y (&it));
1231 }
1232
1233 /* Return the default pixel height of text lines in window W. The
1234 value is the canonical height of the W frame's default font, plus
1235 any extra space required by the line-spacing variable or frame
1236 parameter.
1237
1238 Implementation note: this ignores any line-spacing text properties
1239 put on the newline characters. This is because those properties
1240 only affect the _screen_ line ending in the newline (i.e., in a
1241 continued line, only the last screen line will be affected), which
1242 means only a small number of lines in a buffer can ever use this
1243 feature. Since this function is used to compute the default pixel
1244 equivalent of text lines in a window, we can safely ignore those
1245 few lines. For the same reasons, we ignore the line-height
1246 properties. */
1247 int
1248 default_line_pixel_height (struct window *w)
1249 {
1250 struct frame *f = WINDOW_XFRAME (w);
1251 int height = FRAME_LINE_HEIGHT (f);
1252
1253 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1254 {
1255 struct buffer *b = XBUFFER (w->contents);
1256 Lisp_Object val = BVAR (b, extra_line_spacing);
1257
1258 if (NILP (val))
1259 val = BVAR (&buffer_defaults, extra_line_spacing);
1260 if (!NILP (val))
1261 {
1262 if (RANGED_INTEGERP (0, val, INT_MAX))
1263 height += XFASTINT (val);
1264 else if (FLOATP (val))
1265 {
1266 int addon = XFLOAT_DATA (val) * height + 0.5;
1267
1268 if (addon >= 0)
1269 height += addon;
1270 }
1271 }
1272 else
1273 height += f->extra_line_spacing;
1274 }
1275
1276 return height;
1277 }
1278
1279 /* Subroutine of pos_visible_p below. Extracts a display string, if
1280 any, from the display spec given as its argument. */
1281 static Lisp_Object
1282 string_from_display_spec (Lisp_Object spec)
1283 {
1284 if (CONSP (spec))
1285 {
1286 while (CONSP (spec))
1287 {
1288 if (STRINGP (XCAR (spec)))
1289 return XCAR (spec);
1290 spec = XCDR (spec);
1291 }
1292 }
1293 else if (VECTORP (spec))
1294 {
1295 ptrdiff_t i;
1296
1297 for (i = 0; i < ASIZE (spec); i++)
1298 {
1299 if (STRINGP (AREF (spec, i)))
1300 return AREF (spec, i);
1301 }
1302 return Qnil;
1303 }
1304
1305 return spec;
1306 }
1307
1308
1309 /* Limit insanely large values of W->hscroll on frame F to the largest
1310 value that will still prevent first_visible_x and last_visible_x of
1311 'struct it' from overflowing an int. */
1312 static int
1313 window_hscroll_limited (struct window *w, struct frame *f)
1314 {
1315 ptrdiff_t window_hscroll = w->hscroll;
1316 int window_text_width = window_box_width (w, TEXT_AREA);
1317 int colwidth = FRAME_COLUMN_WIDTH (f);
1318
1319 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1320 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1321
1322 return window_hscroll;
1323 }
1324
1325 /* Return 1 if position CHARPOS is visible in window W.
1326 CHARPOS < 0 means return info about WINDOW_END position.
1327 If visible, set *X and *Y to pixel coordinates of top left corner.
1328 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1329 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1330
1331 int
1332 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1333 int *rtop, int *rbot, int *rowh, int *vpos)
1334 {
1335 struct it it;
1336 void *itdata = bidi_shelve_cache ();
1337 struct text_pos top;
1338 int visible_p = 0;
1339 struct buffer *old_buffer = NULL;
1340
1341 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1342 return visible_p;
1343
1344 if (XBUFFER (w->contents) != current_buffer)
1345 {
1346 old_buffer = current_buffer;
1347 set_buffer_internal_1 (XBUFFER (w->contents));
1348 }
1349
1350 SET_TEXT_POS_FROM_MARKER (top, w->start);
1351 /* Scrolling a minibuffer window via scroll bar when the echo area
1352 shows long text sometimes resets the minibuffer contents behind
1353 our backs. */
1354 if (CHARPOS (top) > ZV)
1355 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1356
1357 /* Compute exact mode line heights. */
1358 if (WINDOW_WANTS_MODELINE_P (w))
1359 current_mode_line_height
1360 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1361 BVAR (current_buffer, mode_line_format));
1362
1363 if (WINDOW_WANTS_HEADER_LINE_P (w))
1364 current_header_line_height
1365 = display_mode_line (w, HEADER_LINE_FACE_ID,
1366 BVAR (current_buffer, header_line_format));
1367
1368 start_display (&it, w, top);
1369 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1370 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1371
1372 if (charpos >= 0
1373 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1374 && IT_CHARPOS (it) >= charpos)
1375 /* When scanning backwards under bidi iteration, move_it_to
1376 stops at or _before_ CHARPOS, because it stops at or to
1377 the _right_ of the character at CHARPOS. */
1378 || (it.bidi_p && it.bidi_it.scan_dir == -1
1379 && IT_CHARPOS (it) <= charpos)))
1380 {
1381 /* We have reached CHARPOS, or passed it. How the call to
1382 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1383 or covered by a display property, move_it_to stops at the end
1384 of the invisible text, to the right of CHARPOS. (ii) If
1385 CHARPOS is in a display vector, move_it_to stops on its last
1386 glyph. */
1387 int top_x = it.current_x;
1388 int top_y = it.current_y;
1389 /* Calling line_bottom_y may change it.method, it.position, etc. */
1390 enum it_method it_method = it.method;
1391 int bottom_y = (last_height = 0, line_bottom_y (&it));
1392 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1393
1394 if (top_y < window_top_y)
1395 visible_p = bottom_y > window_top_y;
1396 else if (top_y < it.last_visible_y)
1397 visible_p = 1;
1398 if (bottom_y >= it.last_visible_y
1399 && it.bidi_p && it.bidi_it.scan_dir == -1
1400 && IT_CHARPOS (it) < charpos)
1401 {
1402 /* When the last line of the window is scanned backwards
1403 under bidi iteration, we could be duped into thinking
1404 that we have passed CHARPOS, when in fact move_it_to
1405 simply stopped short of CHARPOS because it reached
1406 last_visible_y. To see if that's what happened, we call
1407 move_it_to again with a slightly larger vertical limit,
1408 and see if it actually moved vertically; if it did, we
1409 didn't really reach CHARPOS, which is beyond window end. */
1410 struct it save_it = it;
1411 /* Why 10? because we don't know how many canonical lines
1412 will the height of the next line(s) be. So we guess. */
1413 int ten_more_lines = 10 * default_line_pixel_height (w);
1414
1415 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1416 MOVE_TO_POS | MOVE_TO_Y);
1417 if (it.current_y > top_y)
1418 visible_p = 0;
1419
1420 it = save_it;
1421 }
1422 if (visible_p)
1423 {
1424 if (it_method == GET_FROM_DISPLAY_VECTOR)
1425 {
1426 /* We stopped on the last glyph of a display vector.
1427 Try and recompute. Hack alert! */
1428 if (charpos < 2 || top.charpos >= charpos)
1429 top_x = it.glyph_row->x;
1430 else
1431 {
1432 struct it it2, it2_prev;
1433 /* The idea is to get to the previous buffer
1434 position, consume the character there, and use
1435 the pixel coordinates we get after that. But if
1436 the previous buffer position is also displayed
1437 from a display vector, we need to consume all of
1438 the glyphs from that display vector. */
1439 start_display (&it2, w, top);
1440 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1441 /* If we didn't get to CHARPOS - 1, there's some
1442 replacing display property at that position, and
1443 we stopped after it. That is exactly the place
1444 whose coordinates we want. */
1445 if (IT_CHARPOS (it2) != charpos - 1)
1446 it2_prev = it2;
1447 else
1448 {
1449 /* Iterate until we get out of the display
1450 vector that displays the character at
1451 CHARPOS - 1. */
1452 do {
1453 get_next_display_element (&it2);
1454 PRODUCE_GLYPHS (&it2);
1455 it2_prev = it2;
1456 set_iterator_to_next (&it2, 1);
1457 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1458 && IT_CHARPOS (it2) < charpos);
1459 }
1460 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1461 || it2_prev.current_x > it2_prev.last_visible_x)
1462 top_x = it.glyph_row->x;
1463 else
1464 {
1465 top_x = it2_prev.current_x;
1466 top_y = it2_prev.current_y;
1467 }
1468 }
1469 }
1470 else if (IT_CHARPOS (it) != charpos)
1471 {
1472 Lisp_Object cpos = make_number (charpos);
1473 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1474 Lisp_Object string = string_from_display_spec (spec);
1475 struct text_pos tpos;
1476 int replacing_spec_p;
1477 bool newline_in_string
1478 = (STRINGP (string)
1479 && memchr (SDATA (string), '\n', SBYTES (string)));
1480
1481 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1482 replacing_spec_p
1483 = (!NILP (spec)
1484 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1485 charpos, FRAME_WINDOW_P (it.f)));
1486 /* The tricky code below is needed because there's a
1487 discrepancy between move_it_to and how we set cursor
1488 when PT is at the beginning of a portion of text
1489 covered by a display property or an overlay with a
1490 display property, or the display line ends in a
1491 newline from a display string. move_it_to will stop
1492 _after_ such display strings, whereas
1493 set_cursor_from_row conspires with cursor_row_p to
1494 place the cursor on the first glyph produced from the
1495 display string. */
1496
1497 /* We have overshoot PT because it is covered by a
1498 display property that replaces the text it covers.
1499 If the string includes embedded newlines, we are also
1500 in the wrong display line. Backtrack to the correct
1501 line, where the display property begins. */
1502 if (replacing_spec_p)
1503 {
1504 Lisp_Object startpos, endpos;
1505 EMACS_INT start, end;
1506 struct it it3;
1507 int it3_moved;
1508
1509 /* Find the first and the last buffer positions
1510 covered by the display string. */
1511 endpos =
1512 Fnext_single_char_property_change (cpos, Qdisplay,
1513 Qnil, Qnil);
1514 startpos =
1515 Fprevious_single_char_property_change (endpos, Qdisplay,
1516 Qnil, Qnil);
1517 start = XFASTINT (startpos);
1518 end = XFASTINT (endpos);
1519 /* Move to the last buffer position before the
1520 display property. */
1521 start_display (&it3, w, top);
1522 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1523 /* Move forward one more line if the position before
1524 the display string is a newline or if it is the
1525 rightmost character on a line that is
1526 continued or word-wrapped. */
1527 if (it3.method == GET_FROM_BUFFER
1528 && (it3.c == '\n'
1529 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1530 move_it_by_lines (&it3, 1);
1531 else if (move_it_in_display_line_to (&it3, -1,
1532 it3.current_x
1533 + it3.pixel_width,
1534 MOVE_TO_X)
1535 == MOVE_LINE_CONTINUED)
1536 {
1537 move_it_by_lines (&it3, 1);
1538 /* When we are under word-wrap, the #$@%!
1539 move_it_by_lines moves 2 lines, so we need to
1540 fix that up. */
1541 if (it3.line_wrap == WORD_WRAP)
1542 move_it_by_lines (&it3, -1);
1543 }
1544
1545 /* Record the vertical coordinate of the display
1546 line where we wound up. */
1547 top_y = it3.current_y;
1548 if (it3.bidi_p)
1549 {
1550 /* When characters are reordered for display,
1551 the character displayed to the left of the
1552 display string could be _after_ the display
1553 property in the logical order. Use the
1554 smallest vertical position of these two. */
1555 start_display (&it3, w, top);
1556 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1557 if (it3.current_y < top_y)
1558 top_y = it3.current_y;
1559 }
1560 /* Move from the top of the window to the beginning
1561 of the display line where the display string
1562 begins. */
1563 start_display (&it3, w, top);
1564 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1565 /* If it3_moved stays zero after the 'while' loop
1566 below, that means we already were at a newline
1567 before the loop (e.g., the display string begins
1568 with a newline), so we don't need to (and cannot)
1569 inspect the glyphs of it3.glyph_row, because
1570 PRODUCE_GLYPHS will not produce anything for a
1571 newline, and thus it3.glyph_row stays at its
1572 stale content it got at top of the window. */
1573 it3_moved = 0;
1574 /* Finally, advance the iterator until we hit the
1575 first display element whose character position is
1576 CHARPOS, or until the first newline from the
1577 display string, which signals the end of the
1578 display line. */
1579 while (get_next_display_element (&it3))
1580 {
1581 PRODUCE_GLYPHS (&it3);
1582 if (IT_CHARPOS (it3) == charpos
1583 || ITERATOR_AT_END_OF_LINE_P (&it3))
1584 break;
1585 it3_moved = 1;
1586 set_iterator_to_next (&it3, 0);
1587 }
1588 top_x = it3.current_x - it3.pixel_width;
1589 /* Normally, we would exit the above loop because we
1590 found the display element whose character
1591 position is CHARPOS. For the contingency that we
1592 didn't, and stopped at the first newline from the
1593 display string, move back over the glyphs
1594 produced from the string, until we find the
1595 rightmost glyph not from the string. */
1596 if (it3_moved
1597 && newline_in_string
1598 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1599 {
1600 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1601 + it3.glyph_row->used[TEXT_AREA];
1602
1603 while (EQ ((g - 1)->object, string))
1604 {
1605 --g;
1606 top_x -= g->pixel_width;
1607 }
1608 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1609 + it3.glyph_row->used[TEXT_AREA]);
1610 }
1611 }
1612 }
1613
1614 *x = top_x;
1615 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1616 *rtop = max (0, window_top_y - top_y);
1617 *rbot = max (0, bottom_y - it.last_visible_y);
1618 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1619 - max (top_y, window_top_y)));
1620 *vpos = it.vpos;
1621 }
1622 }
1623 else
1624 {
1625 /* We were asked to provide info about WINDOW_END. */
1626 struct it it2;
1627 void *it2data = NULL;
1628
1629 SAVE_IT (it2, it, it2data);
1630 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1631 move_it_by_lines (&it, 1);
1632 if (charpos < IT_CHARPOS (it)
1633 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1634 {
1635 visible_p = 1;
1636 RESTORE_IT (&it2, &it2, it2data);
1637 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1638 *x = it2.current_x;
1639 *y = it2.current_y + it2.max_ascent - it2.ascent;
1640 *rtop = max (0, -it2.current_y);
1641 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1642 - it.last_visible_y));
1643 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1644 it.last_visible_y)
1645 - max (it2.current_y,
1646 WINDOW_HEADER_LINE_HEIGHT (w))));
1647 *vpos = it2.vpos;
1648 }
1649 else
1650 bidi_unshelve_cache (it2data, 1);
1651 }
1652 bidi_unshelve_cache (itdata, 0);
1653
1654 if (old_buffer)
1655 set_buffer_internal_1 (old_buffer);
1656
1657 current_header_line_height = current_mode_line_height = -1;
1658
1659 if (visible_p && w->hscroll > 0)
1660 *x -=
1661 window_hscroll_limited (w, WINDOW_XFRAME (w))
1662 * WINDOW_FRAME_COLUMN_WIDTH (w);
1663
1664 #if 0
1665 /* Debugging code. */
1666 if (visible_p)
1667 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1668 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1669 else
1670 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1671 #endif
1672
1673 return visible_p;
1674 }
1675
1676
1677 /* Return the next character from STR. Return in *LEN the length of
1678 the character. This is like STRING_CHAR_AND_LENGTH but never
1679 returns an invalid character. If we find one, we return a `?', but
1680 with the length of the invalid character. */
1681
1682 static int
1683 string_char_and_length (const unsigned char *str, int *len)
1684 {
1685 int c;
1686
1687 c = STRING_CHAR_AND_LENGTH (str, *len);
1688 if (!CHAR_VALID_P (c))
1689 /* We may not change the length here because other places in Emacs
1690 don't use this function, i.e. they silently accept invalid
1691 characters. */
1692 c = '?';
1693
1694 return c;
1695 }
1696
1697
1698
1699 /* Given a position POS containing a valid character and byte position
1700 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1701
1702 static struct text_pos
1703 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1704 {
1705 eassert (STRINGP (string) && nchars >= 0);
1706
1707 if (STRING_MULTIBYTE (string))
1708 {
1709 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1710 int len;
1711
1712 while (nchars--)
1713 {
1714 string_char_and_length (p, &len);
1715 p += len;
1716 CHARPOS (pos) += 1;
1717 BYTEPOS (pos) += len;
1718 }
1719 }
1720 else
1721 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1722
1723 return pos;
1724 }
1725
1726
1727 /* Value is the text position, i.e. character and byte position,
1728 for character position CHARPOS in STRING. */
1729
1730 static struct text_pos
1731 string_pos (ptrdiff_t charpos, Lisp_Object string)
1732 {
1733 struct text_pos pos;
1734 eassert (STRINGP (string));
1735 eassert (charpos >= 0);
1736 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1737 return pos;
1738 }
1739
1740
1741 /* Value is a text position, i.e. character and byte position, for
1742 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1743 means recognize multibyte characters. */
1744
1745 static struct text_pos
1746 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1747 {
1748 struct text_pos pos;
1749
1750 eassert (s != NULL);
1751 eassert (charpos >= 0);
1752
1753 if (multibyte_p)
1754 {
1755 int len;
1756
1757 SET_TEXT_POS (pos, 0, 0);
1758 while (charpos--)
1759 {
1760 string_char_and_length ((const unsigned char *) s, &len);
1761 s += len;
1762 CHARPOS (pos) += 1;
1763 BYTEPOS (pos) += len;
1764 }
1765 }
1766 else
1767 SET_TEXT_POS (pos, charpos, charpos);
1768
1769 return pos;
1770 }
1771
1772
1773 /* Value is the number of characters in C string S. MULTIBYTE_P
1774 non-zero means recognize multibyte characters. */
1775
1776 static ptrdiff_t
1777 number_of_chars (const char *s, bool multibyte_p)
1778 {
1779 ptrdiff_t nchars;
1780
1781 if (multibyte_p)
1782 {
1783 ptrdiff_t rest = strlen (s);
1784 int len;
1785 const unsigned char *p = (const unsigned char *) s;
1786
1787 for (nchars = 0; rest > 0; ++nchars)
1788 {
1789 string_char_and_length (p, &len);
1790 rest -= len, p += len;
1791 }
1792 }
1793 else
1794 nchars = strlen (s);
1795
1796 return nchars;
1797 }
1798
1799
1800 /* Compute byte position NEWPOS->bytepos corresponding to
1801 NEWPOS->charpos. POS is a known position in string STRING.
1802 NEWPOS->charpos must be >= POS.charpos. */
1803
1804 static void
1805 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1806 {
1807 eassert (STRINGP (string));
1808 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1809
1810 if (STRING_MULTIBYTE (string))
1811 *newpos = string_pos_nchars_ahead (pos, string,
1812 CHARPOS (*newpos) - CHARPOS (pos));
1813 else
1814 BYTEPOS (*newpos) = CHARPOS (*newpos);
1815 }
1816
1817 /* EXPORT:
1818 Return an estimation of the pixel height of mode or header lines on
1819 frame F. FACE_ID specifies what line's height to estimate. */
1820
1821 int
1822 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1823 {
1824 #ifdef HAVE_WINDOW_SYSTEM
1825 if (FRAME_WINDOW_P (f))
1826 {
1827 int height = FONT_HEIGHT (FRAME_FONT (f));
1828
1829 /* This function is called so early when Emacs starts that the face
1830 cache and mode line face are not yet initialized. */
1831 if (FRAME_FACE_CACHE (f))
1832 {
1833 struct face *face = FACE_FROM_ID (f, face_id);
1834 if (face)
1835 {
1836 if (face->font)
1837 height = FONT_HEIGHT (face->font);
1838 if (face->box_line_width > 0)
1839 height += 2 * face->box_line_width;
1840 }
1841 }
1842
1843 return height;
1844 }
1845 #endif
1846
1847 return 1;
1848 }
1849
1850 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1851 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1852 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1853 not force the value into range. */
1854
1855 void
1856 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1857 int *x, int *y, NativeRectangle *bounds, int noclip)
1858 {
1859
1860 #ifdef HAVE_WINDOW_SYSTEM
1861 if (FRAME_WINDOW_P (f))
1862 {
1863 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1864 even for negative values. */
1865 if (pix_x < 0)
1866 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1867 if (pix_y < 0)
1868 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1869
1870 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1871 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1872
1873 if (bounds)
1874 STORE_NATIVE_RECT (*bounds,
1875 FRAME_COL_TO_PIXEL_X (f, pix_x),
1876 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1877 FRAME_COLUMN_WIDTH (f) - 1,
1878 FRAME_LINE_HEIGHT (f) - 1);
1879
1880 if (!noclip)
1881 {
1882 if (pix_x < 0)
1883 pix_x = 0;
1884 else if (pix_x > FRAME_TOTAL_COLS (f))
1885 pix_x = FRAME_TOTAL_COLS (f);
1886
1887 if (pix_y < 0)
1888 pix_y = 0;
1889 else if (pix_y > FRAME_LINES (f))
1890 pix_y = FRAME_LINES (f);
1891 }
1892 }
1893 #endif
1894
1895 *x = pix_x;
1896 *y = pix_y;
1897 }
1898
1899
1900 /* Find the glyph under window-relative coordinates X/Y in window W.
1901 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1902 strings. Return in *HPOS and *VPOS the row and column number of
1903 the glyph found. Return in *AREA the glyph area containing X.
1904 Value is a pointer to the glyph found or null if X/Y is not on
1905 text, or we can't tell because W's current matrix is not up to
1906 date. */
1907
1908 static
1909 struct glyph *
1910 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1911 int *dx, int *dy, int *area)
1912 {
1913 struct glyph *glyph, *end;
1914 struct glyph_row *row = NULL;
1915 int x0, i;
1916
1917 /* Find row containing Y. Give up if some row is not enabled. */
1918 for (i = 0; i < w->current_matrix->nrows; ++i)
1919 {
1920 row = MATRIX_ROW (w->current_matrix, i);
1921 if (!row->enabled_p)
1922 return NULL;
1923 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1924 break;
1925 }
1926
1927 *vpos = i;
1928 *hpos = 0;
1929
1930 /* Give up if Y is not in the window. */
1931 if (i == w->current_matrix->nrows)
1932 return NULL;
1933
1934 /* Get the glyph area containing X. */
1935 if (w->pseudo_window_p)
1936 {
1937 *area = TEXT_AREA;
1938 x0 = 0;
1939 }
1940 else
1941 {
1942 if (x < window_box_left_offset (w, TEXT_AREA))
1943 {
1944 *area = LEFT_MARGIN_AREA;
1945 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1946 }
1947 else if (x < window_box_right_offset (w, TEXT_AREA))
1948 {
1949 *area = TEXT_AREA;
1950 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1951 }
1952 else
1953 {
1954 *area = RIGHT_MARGIN_AREA;
1955 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1956 }
1957 }
1958
1959 /* Find glyph containing X. */
1960 glyph = row->glyphs[*area];
1961 end = glyph + row->used[*area];
1962 x -= x0;
1963 while (glyph < end && x >= glyph->pixel_width)
1964 {
1965 x -= glyph->pixel_width;
1966 ++glyph;
1967 }
1968
1969 if (glyph == end)
1970 return NULL;
1971
1972 if (dx)
1973 {
1974 *dx = x;
1975 *dy = y - (row->y + row->ascent - glyph->ascent);
1976 }
1977
1978 *hpos = glyph - row->glyphs[*area];
1979 return glyph;
1980 }
1981
1982 /* Convert frame-relative x/y to coordinates relative to window W.
1983 Takes pseudo-windows into account. */
1984
1985 static void
1986 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1987 {
1988 if (w->pseudo_window_p)
1989 {
1990 /* A pseudo-window is always full-width, and starts at the
1991 left edge of the frame, plus a frame border. */
1992 struct frame *f = XFRAME (w->frame);
1993 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1994 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1995 }
1996 else
1997 {
1998 *x -= WINDOW_LEFT_EDGE_X (w);
1999 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2000 }
2001 }
2002
2003 #ifdef HAVE_WINDOW_SYSTEM
2004
2005 /* EXPORT:
2006 Return in RECTS[] at most N clipping rectangles for glyph string S.
2007 Return the number of stored rectangles. */
2008
2009 int
2010 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2011 {
2012 XRectangle r;
2013
2014 if (n <= 0)
2015 return 0;
2016
2017 if (s->row->full_width_p)
2018 {
2019 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2020 r.x = WINDOW_LEFT_EDGE_X (s->w);
2021 r.width = WINDOW_TOTAL_WIDTH (s->w);
2022
2023 /* Unless displaying a mode or menu bar line, which are always
2024 fully visible, clip to the visible part of the row. */
2025 if (s->w->pseudo_window_p)
2026 r.height = s->row->visible_height;
2027 else
2028 r.height = s->height;
2029 }
2030 else
2031 {
2032 /* This is a text line that may be partially visible. */
2033 r.x = window_box_left (s->w, s->area);
2034 r.width = window_box_width (s->w, s->area);
2035 r.height = s->row->visible_height;
2036 }
2037
2038 if (s->clip_head)
2039 if (r.x < s->clip_head->x)
2040 {
2041 if (r.width >= s->clip_head->x - r.x)
2042 r.width -= s->clip_head->x - r.x;
2043 else
2044 r.width = 0;
2045 r.x = s->clip_head->x;
2046 }
2047 if (s->clip_tail)
2048 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2049 {
2050 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2051 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2052 else
2053 r.width = 0;
2054 }
2055
2056 /* If S draws overlapping rows, it's sufficient to use the top and
2057 bottom of the window for clipping because this glyph string
2058 intentionally draws over other lines. */
2059 if (s->for_overlaps)
2060 {
2061 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2062 r.height = window_text_bottom_y (s->w) - r.y;
2063
2064 /* Alas, the above simple strategy does not work for the
2065 environments with anti-aliased text: if the same text is
2066 drawn onto the same place multiple times, it gets thicker.
2067 If the overlap we are processing is for the erased cursor, we
2068 take the intersection with the rectangle of the cursor. */
2069 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2070 {
2071 XRectangle rc, r_save = r;
2072
2073 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2074 rc.y = s->w->phys_cursor.y;
2075 rc.width = s->w->phys_cursor_width;
2076 rc.height = s->w->phys_cursor_height;
2077
2078 x_intersect_rectangles (&r_save, &rc, &r);
2079 }
2080 }
2081 else
2082 {
2083 /* Don't use S->y for clipping because it doesn't take partially
2084 visible lines into account. For example, it can be negative for
2085 partially visible lines at the top of a window. */
2086 if (!s->row->full_width_p
2087 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2088 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2089 else
2090 r.y = max (0, s->row->y);
2091 }
2092
2093 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2094
2095 /* If drawing the cursor, don't let glyph draw outside its
2096 advertised boundaries. Cleartype does this under some circumstances. */
2097 if (s->hl == DRAW_CURSOR)
2098 {
2099 struct glyph *glyph = s->first_glyph;
2100 int height, max_y;
2101
2102 if (s->x > r.x)
2103 {
2104 r.width -= s->x - r.x;
2105 r.x = s->x;
2106 }
2107 r.width = min (r.width, glyph->pixel_width);
2108
2109 /* If r.y is below window bottom, ensure that we still see a cursor. */
2110 height = min (glyph->ascent + glyph->descent,
2111 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2112 max_y = window_text_bottom_y (s->w) - height;
2113 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2114 if (s->ybase - glyph->ascent > max_y)
2115 {
2116 r.y = max_y;
2117 r.height = height;
2118 }
2119 else
2120 {
2121 /* Don't draw cursor glyph taller than our actual glyph. */
2122 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2123 if (height < r.height)
2124 {
2125 max_y = r.y + r.height;
2126 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2127 r.height = min (max_y - r.y, height);
2128 }
2129 }
2130 }
2131
2132 if (s->row->clip)
2133 {
2134 XRectangle r_save = r;
2135
2136 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2137 r.width = 0;
2138 }
2139
2140 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2141 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2142 {
2143 #ifdef CONVERT_FROM_XRECT
2144 CONVERT_FROM_XRECT (r, *rects);
2145 #else
2146 *rects = r;
2147 #endif
2148 return 1;
2149 }
2150 else
2151 {
2152 /* If we are processing overlapping and allowed to return
2153 multiple clipping rectangles, we exclude the row of the glyph
2154 string from the clipping rectangle. This is to avoid drawing
2155 the same text on the environment with anti-aliasing. */
2156 #ifdef CONVERT_FROM_XRECT
2157 XRectangle rs[2];
2158 #else
2159 XRectangle *rs = rects;
2160 #endif
2161 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2162
2163 if (s->for_overlaps & OVERLAPS_PRED)
2164 {
2165 rs[i] = r;
2166 if (r.y + r.height > row_y)
2167 {
2168 if (r.y < row_y)
2169 rs[i].height = row_y - r.y;
2170 else
2171 rs[i].height = 0;
2172 }
2173 i++;
2174 }
2175 if (s->for_overlaps & OVERLAPS_SUCC)
2176 {
2177 rs[i] = r;
2178 if (r.y < row_y + s->row->visible_height)
2179 {
2180 if (r.y + r.height > row_y + s->row->visible_height)
2181 {
2182 rs[i].y = row_y + s->row->visible_height;
2183 rs[i].height = r.y + r.height - rs[i].y;
2184 }
2185 else
2186 rs[i].height = 0;
2187 }
2188 i++;
2189 }
2190
2191 n = i;
2192 #ifdef CONVERT_FROM_XRECT
2193 for (i = 0; i < n; i++)
2194 CONVERT_FROM_XRECT (rs[i], rects[i]);
2195 #endif
2196 return n;
2197 }
2198 }
2199
2200 /* EXPORT:
2201 Return in *NR the clipping rectangle for glyph string S. */
2202
2203 void
2204 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2205 {
2206 get_glyph_string_clip_rects (s, nr, 1);
2207 }
2208
2209
2210 /* EXPORT:
2211 Return the position and height of the phys cursor in window W.
2212 Set w->phys_cursor_width to width of phys cursor.
2213 */
2214
2215 void
2216 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2217 struct glyph *glyph, int *xp, int *yp, int *heightp)
2218 {
2219 struct frame *f = XFRAME (WINDOW_FRAME (w));
2220 int x, y, wd, h, h0, y0;
2221
2222 /* Compute the width of the rectangle to draw. If on a stretch
2223 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2224 rectangle as wide as the glyph, but use a canonical character
2225 width instead. */
2226 wd = glyph->pixel_width - 1;
2227 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2228 wd++; /* Why? */
2229 #endif
2230
2231 x = w->phys_cursor.x;
2232 if (x < 0)
2233 {
2234 wd += x;
2235 x = 0;
2236 }
2237
2238 if (glyph->type == STRETCH_GLYPH
2239 && !x_stretch_cursor_p)
2240 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2241 w->phys_cursor_width = wd;
2242
2243 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2244
2245 /* If y is below window bottom, ensure that we still see a cursor. */
2246 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2247
2248 h = max (h0, glyph->ascent + glyph->descent);
2249 h0 = min (h0, glyph->ascent + glyph->descent);
2250
2251 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2252 if (y < y0)
2253 {
2254 h = max (h - (y0 - y) + 1, h0);
2255 y = y0 - 1;
2256 }
2257 else
2258 {
2259 y0 = window_text_bottom_y (w) - h0;
2260 if (y > y0)
2261 {
2262 h += y - y0;
2263 y = y0;
2264 }
2265 }
2266
2267 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2268 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2269 *heightp = h;
2270 }
2271
2272 /*
2273 * Remember which glyph the mouse is over.
2274 */
2275
2276 void
2277 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2278 {
2279 Lisp_Object window;
2280 struct window *w;
2281 struct glyph_row *r, *gr, *end_row;
2282 enum window_part part;
2283 enum glyph_row_area area;
2284 int x, y, width, height;
2285
2286 /* Try to determine frame pixel position and size of the glyph under
2287 frame pixel coordinates X/Y on frame F. */
2288
2289 if (!f->glyphs_initialized_p
2290 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2291 NILP (window)))
2292 {
2293 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2294 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2295 goto virtual_glyph;
2296 }
2297
2298 w = XWINDOW (window);
2299 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2300 height = WINDOW_FRAME_LINE_HEIGHT (w);
2301
2302 x = window_relative_x_coord (w, part, gx);
2303 y = gy - WINDOW_TOP_EDGE_Y (w);
2304
2305 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2306 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2307
2308 if (w->pseudo_window_p)
2309 {
2310 area = TEXT_AREA;
2311 part = ON_MODE_LINE; /* Don't adjust margin. */
2312 goto text_glyph;
2313 }
2314
2315 switch (part)
2316 {
2317 case ON_LEFT_MARGIN:
2318 area = LEFT_MARGIN_AREA;
2319 goto text_glyph;
2320
2321 case ON_RIGHT_MARGIN:
2322 area = RIGHT_MARGIN_AREA;
2323 goto text_glyph;
2324
2325 case ON_HEADER_LINE:
2326 case ON_MODE_LINE:
2327 gr = (part == ON_HEADER_LINE
2328 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2329 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2330 gy = gr->y;
2331 area = TEXT_AREA;
2332 goto text_glyph_row_found;
2333
2334 case ON_TEXT:
2335 area = TEXT_AREA;
2336
2337 text_glyph:
2338 gr = 0; gy = 0;
2339 for (; r <= end_row && r->enabled_p; ++r)
2340 if (r->y + r->height > y)
2341 {
2342 gr = r; gy = r->y;
2343 break;
2344 }
2345
2346 text_glyph_row_found:
2347 if (gr && gy <= y)
2348 {
2349 struct glyph *g = gr->glyphs[area];
2350 struct glyph *end = g + gr->used[area];
2351
2352 height = gr->height;
2353 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2354 if (gx + g->pixel_width > x)
2355 break;
2356
2357 if (g < end)
2358 {
2359 if (g->type == IMAGE_GLYPH)
2360 {
2361 /* Don't remember when mouse is over image, as
2362 image may have hot-spots. */
2363 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2364 return;
2365 }
2366 width = g->pixel_width;
2367 }
2368 else
2369 {
2370 /* Use nominal char spacing at end of line. */
2371 x -= gx;
2372 gx += (x / width) * width;
2373 }
2374
2375 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2376 gx += window_box_left_offset (w, area);
2377 }
2378 else
2379 {
2380 /* Use nominal line height at end of window. */
2381 gx = (x / width) * width;
2382 y -= gy;
2383 gy += (y / height) * height;
2384 }
2385 break;
2386
2387 case ON_LEFT_FRINGE:
2388 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2389 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2390 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2391 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2392 goto row_glyph;
2393
2394 case ON_RIGHT_FRINGE:
2395 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2396 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2397 : window_box_right_offset (w, TEXT_AREA));
2398 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2399 goto row_glyph;
2400
2401 case ON_SCROLL_BAR:
2402 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2403 ? 0
2404 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2405 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2406 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2407 : 0)));
2408 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2409
2410 row_glyph:
2411 gr = 0, gy = 0;
2412 for (; r <= end_row && r->enabled_p; ++r)
2413 if (r->y + r->height > y)
2414 {
2415 gr = r; gy = r->y;
2416 break;
2417 }
2418
2419 if (gr && gy <= y)
2420 height = gr->height;
2421 else
2422 {
2423 /* Use nominal line height at end of window. */
2424 y -= gy;
2425 gy += (y / height) * height;
2426 }
2427 break;
2428
2429 default:
2430 ;
2431 virtual_glyph:
2432 /* If there is no glyph under the mouse, then we divide the screen
2433 into a grid of the smallest glyph in the frame, and use that
2434 as our "glyph". */
2435
2436 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2437 round down even for negative values. */
2438 if (gx < 0)
2439 gx -= width - 1;
2440 if (gy < 0)
2441 gy -= height - 1;
2442
2443 gx = (gx / width) * width;
2444 gy = (gy / height) * height;
2445
2446 goto store_rect;
2447 }
2448
2449 gx += WINDOW_LEFT_EDGE_X (w);
2450 gy += WINDOW_TOP_EDGE_Y (w);
2451
2452 store_rect:
2453 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2454
2455 /* Visible feedback for debugging. */
2456 #if 0
2457 #if HAVE_X_WINDOWS
2458 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2459 f->output_data.x->normal_gc,
2460 gx, gy, width, height);
2461 #endif
2462 #endif
2463 }
2464
2465
2466 #endif /* HAVE_WINDOW_SYSTEM */
2467
2468 \f
2469 /***********************************************************************
2470 Lisp form evaluation
2471 ***********************************************************************/
2472
2473 /* Error handler for safe_eval and safe_call. */
2474
2475 static Lisp_Object
2476 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2477 {
2478 add_to_log ("Error during redisplay: %S signaled %S",
2479 Flist (nargs, args), arg);
2480 return Qnil;
2481 }
2482
2483 /* Call function FUNC with the rest of NARGS - 1 arguments
2484 following. Return the result, or nil if something went
2485 wrong. Prevent redisplay during the evaluation. */
2486
2487 Lisp_Object
2488 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2489 {
2490 Lisp_Object val;
2491
2492 if (inhibit_eval_during_redisplay)
2493 val = Qnil;
2494 else
2495 {
2496 va_list ap;
2497 ptrdiff_t i;
2498 ptrdiff_t count = SPECPDL_INDEX ();
2499 struct gcpro gcpro1;
2500 Lisp_Object *args = alloca (nargs * word_size);
2501
2502 args[0] = func;
2503 va_start (ap, func);
2504 for (i = 1; i < nargs; i++)
2505 args[i] = va_arg (ap, Lisp_Object);
2506 va_end (ap);
2507
2508 GCPRO1 (args[0]);
2509 gcpro1.nvars = nargs;
2510 specbind (Qinhibit_redisplay, Qt);
2511 /* Use Qt to ensure debugger does not run,
2512 so there is no possibility of wanting to redisplay. */
2513 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2514 safe_eval_handler);
2515 UNGCPRO;
2516 val = unbind_to (count, val);
2517 }
2518
2519 return val;
2520 }
2521
2522
2523 /* Call function FN with one argument ARG.
2524 Return the result, or nil if something went wrong. */
2525
2526 Lisp_Object
2527 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2528 {
2529 return safe_call (2, fn, arg);
2530 }
2531
2532 static Lisp_Object Qeval;
2533
2534 Lisp_Object
2535 safe_eval (Lisp_Object sexpr)
2536 {
2537 return safe_call1 (Qeval, sexpr);
2538 }
2539
2540 /* Call function FN with two arguments ARG1 and ARG2.
2541 Return the result, or nil if something went wrong. */
2542
2543 Lisp_Object
2544 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2545 {
2546 return safe_call (3, fn, arg1, arg2);
2547 }
2548
2549
2550 \f
2551 /***********************************************************************
2552 Debugging
2553 ***********************************************************************/
2554
2555 #if 0
2556
2557 /* Define CHECK_IT to perform sanity checks on iterators.
2558 This is for debugging. It is too slow to do unconditionally. */
2559
2560 static void
2561 check_it (struct it *it)
2562 {
2563 if (it->method == GET_FROM_STRING)
2564 {
2565 eassert (STRINGP (it->string));
2566 eassert (IT_STRING_CHARPOS (*it) >= 0);
2567 }
2568 else
2569 {
2570 eassert (IT_STRING_CHARPOS (*it) < 0);
2571 if (it->method == GET_FROM_BUFFER)
2572 {
2573 /* Check that character and byte positions agree. */
2574 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2575 }
2576 }
2577
2578 if (it->dpvec)
2579 eassert (it->current.dpvec_index >= 0);
2580 else
2581 eassert (it->current.dpvec_index < 0);
2582 }
2583
2584 #define CHECK_IT(IT) check_it ((IT))
2585
2586 #else /* not 0 */
2587
2588 #define CHECK_IT(IT) (void) 0
2589
2590 #endif /* not 0 */
2591
2592
2593 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2594
2595 /* Check that the window end of window W is what we expect it
2596 to be---the last row in the current matrix displaying text. */
2597
2598 static void
2599 check_window_end (struct window *w)
2600 {
2601 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2602 {
2603 struct glyph_row *row;
2604 eassert ((row = MATRIX_ROW (w->current_matrix,
2605 XFASTINT (w->window_end_vpos)),
2606 !row->enabled_p
2607 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2608 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2609 }
2610 }
2611
2612 #define CHECK_WINDOW_END(W) check_window_end ((W))
2613
2614 #else
2615
2616 #define CHECK_WINDOW_END(W) (void) 0
2617
2618 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2619
2620 /* Return mark position if current buffer has the region of non-zero length,
2621 or -1 otherwise. */
2622
2623 static ptrdiff_t
2624 markpos_of_region (void)
2625 {
2626 if (!NILP (Vtransient_mark_mode)
2627 && !NILP (BVAR (current_buffer, mark_active))
2628 && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
2629 {
2630 ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
2631
2632 if (markpos != PT)
2633 return markpos;
2634 }
2635 return -1;
2636 }
2637
2638 /***********************************************************************
2639 Iterator initialization
2640 ***********************************************************************/
2641
2642 /* Initialize IT for displaying current_buffer in window W, starting
2643 at character position CHARPOS. CHARPOS < 0 means that no buffer
2644 position is specified which is useful when the iterator is assigned
2645 a position later. BYTEPOS is the byte position corresponding to
2646 CHARPOS.
2647
2648 If ROW is not null, calls to produce_glyphs with IT as parameter
2649 will produce glyphs in that row.
2650
2651 BASE_FACE_ID is the id of a base face to use. It must be one of
2652 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2653 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2654 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2655
2656 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2657 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2658 will be initialized to use the corresponding mode line glyph row of
2659 the desired matrix of W. */
2660
2661 void
2662 init_iterator (struct it *it, struct window *w,
2663 ptrdiff_t charpos, ptrdiff_t bytepos,
2664 struct glyph_row *row, enum face_id base_face_id)
2665 {
2666 ptrdiff_t markpos;
2667 enum face_id remapped_base_face_id = base_face_id;
2668
2669 /* Some precondition checks. */
2670 eassert (w != NULL && it != NULL);
2671 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2672 && charpos <= ZV));
2673
2674 /* If face attributes have been changed since the last redisplay,
2675 free realized faces now because they depend on face definitions
2676 that might have changed. Don't free faces while there might be
2677 desired matrices pending which reference these faces. */
2678 if (face_change_count && !inhibit_free_realized_faces)
2679 {
2680 face_change_count = 0;
2681 free_all_realized_faces (Qnil);
2682 }
2683
2684 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2685 if (! NILP (Vface_remapping_alist))
2686 remapped_base_face_id
2687 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2688
2689 /* Use one of the mode line rows of W's desired matrix if
2690 appropriate. */
2691 if (row == NULL)
2692 {
2693 if (base_face_id == MODE_LINE_FACE_ID
2694 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2695 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2696 else if (base_face_id == HEADER_LINE_FACE_ID)
2697 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2698 }
2699
2700 /* Clear IT. */
2701 memset (it, 0, sizeof *it);
2702 it->current.overlay_string_index = -1;
2703 it->current.dpvec_index = -1;
2704 it->base_face_id = remapped_base_face_id;
2705 it->string = Qnil;
2706 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2707 it->paragraph_embedding = L2R;
2708 it->bidi_it.string.lstring = Qnil;
2709 it->bidi_it.string.s = NULL;
2710 it->bidi_it.string.bufpos = 0;
2711 it->bidi_it.w = w;
2712
2713 /* The window in which we iterate over current_buffer: */
2714 XSETWINDOW (it->window, w);
2715 it->w = w;
2716 it->f = XFRAME (w->frame);
2717
2718 it->cmp_it.id = -1;
2719
2720 /* Extra space between lines (on window systems only). */
2721 if (base_face_id == DEFAULT_FACE_ID
2722 && FRAME_WINDOW_P (it->f))
2723 {
2724 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2725 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2726 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2727 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2728 * FRAME_LINE_HEIGHT (it->f));
2729 else if (it->f->extra_line_spacing > 0)
2730 it->extra_line_spacing = it->f->extra_line_spacing;
2731 it->max_extra_line_spacing = 0;
2732 }
2733
2734 /* If realized faces have been removed, e.g. because of face
2735 attribute changes of named faces, recompute them. When running
2736 in batch mode, the face cache of the initial frame is null. If
2737 we happen to get called, make a dummy face cache. */
2738 if (FRAME_FACE_CACHE (it->f) == NULL)
2739 init_frame_faces (it->f);
2740 if (FRAME_FACE_CACHE (it->f)->used == 0)
2741 recompute_basic_faces (it->f);
2742
2743 /* Current value of the `slice', `space-width', and 'height' properties. */
2744 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2745 it->space_width = Qnil;
2746 it->font_height = Qnil;
2747 it->override_ascent = -1;
2748
2749 /* Are control characters displayed as `^C'? */
2750 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2751
2752 /* -1 means everything between a CR and the following line end
2753 is invisible. >0 means lines indented more than this value are
2754 invisible. */
2755 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2756 ? (clip_to_bounds
2757 (-1, XINT (BVAR (current_buffer, selective_display)),
2758 PTRDIFF_MAX))
2759 : (!NILP (BVAR (current_buffer, selective_display))
2760 ? -1 : 0));
2761 it->selective_display_ellipsis_p
2762 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2763
2764 /* Display table to use. */
2765 it->dp = window_display_table (w);
2766
2767 /* Are multibyte characters enabled in current_buffer? */
2768 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2769
2770 /* If visible region is of non-zero length, set IT->region_beg_charpos
2771 and IT->region_end_charpos to the start and end of a visible region
2772 in window IT->w. Set both to -1 to indicate no region. */
2773 markpos = markpos_of_region ();
2774 if (markpos >= 0
2775 /* Maybe highlight only in selected window. */
2776 && (/* Either show region everywhere. */
2777 highlight_nonselected_windows
2778 /* Or show region in the selected window. */
2779 || w == XWINDOW (selected_window)
2780 /* Or show the region if we are in the mini-buffer and W is
2781 the window the mini-buffer refers to. */
2782 || (MINI_WINDOW_P (XWINDOW (selected_window))
2783 && WINDOWP (minibuf_selected_window)
2784 && w == XWINDOW (minibuf_selected_window))))
2785 {
2786 it->region_beg_charpos = min (PT, markpos);
2787 it->region_end_charpos = max (PT, markpos);
2788 }
2789 else
2790 it->region_beg_charpos = it->region_end_charpos = -1;
2791
2792 /* Get the position at which the redisplay_end_trigger hook should
2793 be run, if it is to be run at all. */
2794 if (MARKERP (w->redisplay_end_trigger)
2795 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2796 it->redisplay_end_trigger_charpos
2797 = marker_position (w->redisplay_end_trigger);
2798 else if (INTEGERP (w->redisplay_end_trigger))
2799 it->redisplay_end_trigger_charpos =
2800 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2801
2802 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2803
2804 /* Are lines in the display truncated? */
2805 if (base_face_id != DEFAULT_FACE_ID
2806 || it->w->hscroll
2807 || (! WINDOW_FULL_WIDTH_P (it->w)
2808 && ((!NILP (Vtruncate_partial_width_windows)
2809 && !INTEGERP (Vtruncate_partial_width_windows))
2810 || (INTEGERP (Vtruncate_partial_width_windows)
2811 && (WINDOW_TOTAL_COLS (it->w)
2812 < XINT (Vtruncate_partial_width_windows))))))
2813 it->line_wrap = TRUNCATE;
2814 else if (NILP (BVAR (current_buffer, truncate_lines)))
2815 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2816 ? WINDOW_WRAP : WORD_WRAP;
2817 else
2818 it->line_wrap = TRUNCATE;
2819
2820 /* Get dimensions of truncation and continuation glyphs. These are
2821 displayed as fringe bitmaps under X, but we need them for such
2822 frames when the fringes are turned off. But leave the dimensions
2823 zero for tooltip frames, as these glyphs look ugly there and also
2824 sabotage calculations of tooltip dimensions in x-show-tip. */
2825 #ifdef HAVE_WINDOW_SYSTEM
2826 if (!(FRAME_WINDOW_P (it->f)
2827 && FRAMEP (tip_frame)
2828 && it->f == XFRAME (tip_frame)))
2829 #endif
2830 {
2831 if (it->line_wrap == TRUNCATE)
2832 {
2833 /* We will need the truncation glyph. */
2834 eassert (it->glyph_row == NULL);
2835 produce_special_glyphs (it, IT_TRUNCATION);
2836 it->truncation_pixel_width = it->pixel_width;
2837 }
2838 else
2839 {
2840 /* We will need the continuation glyph. */
2841 eassert (it->glyph_row == NULL);
2842 produce_special_glyphs (it, IT_CONTINUATION);
2843 it->continuation_pixel_width = it->pixel_width;
2844 }
2845 }
2846
2847 /* Reset these values to zero because the produce_special_glyphs
2848 above has changed them. */
2849 it->pixel_width = it->ascent = it->descent = 0;
2850 it->phys_ascent = it->phys_descent = 0;
2851
2852 /* Set this after getting the dimensions of truncation and
2853 continuation glyphs, so that we don't produce glyphs when calling
2854 produce_special_glyphs, above. */
2855 it->glyph_row = row;
2856 it->area = TEXT_AREA;
2857
2858 /* Forget any previous info about this row being reversed. */
2859 if (it->glyph_row)
2860 it->glyph_row->reversed_p = 0;
2861
2862 /* Get the dimensions of the display area. The display area
2863 consists of the visible window area plus a horizontally scrolled
2864 part to the left of the window. All x-values are relative to the
2865 start of this total display area. */
2866 if (base_face_id != DEFAULT_FACE_ID)
2867 {
2868 /* Mode lines, menu bar in terminal frames. */
2869 it->first_visible_x = 0;
2870 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2871 }
2872 else
2873 {
2874 it->first_visible_x =
2875 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2876 it->last_visible_x = (it->first_visible_x
2877 + window_box_width (w, TEXT_AREA));
2878
2879 /* If we truncate lines, leave room for the truncation glyph(s) at
2880 the right margin. Otherwise, leave room for the continuation
2881 glyph(s). Done only if the window has no fringes. Since we
2882 don't know at this point whether there will be any R2L lines in
2883 the window, we reserve space for truncation/continuation glyphs
2884 even if only one of the fringes is absent. */
2885 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2886 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2887 {
2888 if (it->line_wrap == TRUNCATE)
2889 it->last_visible_x -= it->truncation_pixel_width;
2890 else
2891 it->last_visible_x -= it->continuation_pixel_width;
2892 }
2893
2894 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2895 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2896 }
2897
2898 /* Leave room for a border glyph. */
2899 if (!FRAME_WINDOW_P (it->f)
2900 && !WINDOW_RIGHTMOST_P (it->w))
2901 it->last_visible_x -= 1;
2902
2903 it->last_visible_y = window_text_bottom_y (w);
2904
2905 /* For mode lines and alike, arrange for the first glyph having a
2906 left box line if the face specifies a box. */
2907 if (base_face_id != DEFAULT_FACE_ID)
2908 {
2909 struct face *face;
2910
2911 it->face_id = remapped_base_face_id;
2912
2913 /* If we have a boxed mode line, make the first character appear
2914 with a left box line. */
2915 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2916 if (face->box != FACE_NO_BOX)
2917 it->start_of_box_run_p = 1;
2918 }
2919
2920 /* If a buffer position was specified, set the iterator there,
2921 getting overlays and face properties from that position. */
2922 if (charpos >= BUF_BEG (current_buffer))
2923 {
2924 it->end_charpos = ZV;
2925 eassert (charpos == BYTE_TO_CHAR (bytepos));
2926 IT_CHARPOS (*it) = charpos;
2927 IT_BYTEPOS (*it) = bytepos;
2928
2929 /* We will rely on `reseat' to set this up properly, via
2930 handle_face_prop. */
2931 it->face_id = it->base_face_id;
2932
2933 it->start = it->current;
2934 /* Do we need to reorder bidirectional text? Not if this is a
2935 unibyte buffer: by definition, none of the single-byte
2936 characters are strong R2L, so no reordering is needed. And
2937 bidi.c doesn't support unibyte buffers anyway. Also, don't
2938 reorder while we are loading loadup.el, since the tables of
2939 character properties needed for reordering are not yet
2940 available. */
2941 it->bidi_p =
2942 NILP (Vpurify_flag)
2943 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2944 && it->multibyte_p;
2945
2946 /* If we are to reorder bidirectional text, init the bidi
2947 iterator. */
2948 if (it->bidi_p)
2949 {
2950 /* Note the paragraph direction that this buffer wants to
2951 use. */
2952 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2953 Qleft_to_right))
2954 it->paragraph_embedding = L2R;
2955 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2956 Qright_to_left))
2957 it->paragraph_embedding = R2L;
2958 else
2959 it->paragraph_embedding = NEUTRAL_DIR;
2960 bidi_unshelve_cache (NULL, 0);
2961 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2962 &it->bidi_it);
2963 }
2964
2965 /* Compute faces etc. */
2966 reseat (it, it->current.pos, 1);
2967 }
2968
2969 CHECK_IT (it);
2970 }
2971
2972
2973 /* Initialize IT for the display of window W with window start POS. */
2974
2975 void
2976 start_display (struct it *it, struct window *w, struct text_pos pos)
2977 {
2978 struct glyph_row *row;
2979 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2980
2981 row = w->desired_matrix->rows + first_vpos;
2982 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2983 it->first_vpos = first_vpos;
2984
2985 /* Don't reseat to previous visible line start if current start
2986 position is in a string or image. */
2987 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2988 {
2989 int start_at_line_beg_p;
2990 int first_y = it->current_y;
2991
2992 /* If window start is not at a line start, skip forward to POS to
2993 get the correct continuation lines width. */
2994 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2995 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2996 if (!start_at_line_beg_p)
2997 {
2998 int new_x;
2999
3000 reseat_at_previous_visible_line_start (it);
3001 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3002
3003 new_x = it->current_x + it->pixel_width;
3004
3005 /* If lines are continued, this line may end in the middle
3006 of a multi-glyph character (e.g. a control character
3007 displayed as \003, or in the middle of an overlay
3008 string). In this case move_it_to above will not have
3009 taken us to the start of the continuation line but to the
3010 end of the continued line. */
3011 if (it->current_x > 0
3012 && it->line_wrap != TRUNCATE /* Lines are continued. */
3013 && (/* And glyph doesn't fit on the line. */
3014 new_x > it->last_visible_x
3015 /* Or it fits exactly and we're on a window
3016 system frame. */
3017 || (new_x == it->last_visible_x
3018 && FRAME_WINDOW_P (it->f)
3019 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3020 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3021 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3022 {
3023 if ((it->current.dpvec_index >= 0
3024 || it->current.overlay_string_index >= 0)
3025 /* If we are on a newline from a display vector or
3026 overlay string, then we are already at the end of
3027 a screen line; no need to go to the next line in
3028 that case, as this line is not really continued.
3029 (If we do go to the next line, C-e will not DTRT.) */
3030 && it->c != '\n')
3031 {
3032 set_iterator_to_next (it, 1);
3033 move_it_in_display_line_to (it, -1, -1, 0);
3034 }
3035
3036 it->continuation_lines_width += it->current_x;
3037 }
3038 /* If the character at POS is displayed via a display
3039 vector, move_it_to above stops at the final glyph of
3040 IT->dpvec. To make the caller redisplay that character
3041 again (a.k.a. start at POS), we need to reset the
3042 dpvec_index to the beginning of IT->dpvec. */
3043 else if (it->current.dpvec_index >= 0)
3044 it->current.dpvec_index = 0;
3045
3046 /* We're starting a new display line, not affected by the
3047 height of the continued line, so clear the appropriate
3048 fields in the iterator structure. */
3049 it->max_ascent = it->max_descent = 0;
3050 it->max_phys_ascent = it->max_phys_descent = 0;
3051
3052 it->current_y = first_y;
3053 it->vpos = 0;
3054 it->current_x = it->hpos = 0;
3055 }
3056 }
3057 }
3058
3059
3060 /* Return 1 if POS is a position in ellipses displayed for invisible
3061 text. W is the window we display, for text property lookup. */
3062
3063 static int
3064 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3065 {
3066 Lisp_Object prop, window;
3067 int ellipses_p = 0;
3068 ptrdiff_t charpos = CHARPOS (pos->pos);
3069
3070 /* If POS specifies a position in a display vector, this might
3071 be for an ellipsis displayed for invisible text. We won't
3072 get the iterator set up for delivering that ellipsis unless
3073 we make sure that it gets aware of the invisible text. */
3074 if (pos->dpvec_index >= 0
3075 && pos->overlay_string_index < 0
3076 && CHARPOS (pos->string_pos) < 0
3077 && charpos > BEGV
3078 && (XSETWINDOW (window, w),
3079 prop = Fget_char_property (make_number (charpos),
3080 Qinvisible, window),
3081 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3082 {
3083 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3084 window);
3085 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3086 }
3087
3088 return ellipses_p;
3089 }
3090
3091
3092 /* Initialize IT for stepping through current_buffer in window W,
3093 starting at position POS that includes overlay string and display
3094 vector/ control character translation position information. Value
3095 is zero if there are overlay strings with newlines at POS. */
3096
3097 static int
3098 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3099 {
3100 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3101 int i, overlay_strings_with_newlines = 0;
3102
3103 /* If POS specifies a position in a display vector, this might
3104 be for an ellipsis displayed for invisible text. We won't
3105 get the iterator set up for delivering that ellipsis unless
3106 we make sure that it gets aware of the invisible text. */
3107 if (in_ellipses_for_invisible_text_p (pos, w))
3108 {
3109 --charpos;
3110 bytepos = 0;
3111 }
3112
3113 /* Keep in mind: the call to reseat in init_iterator skips invisible
3114 text, so we might end up at a position different from POS. This
3115 is only a problem when POS is a row start after a newline and an
3116 overlay starts there with an after-string, and the overlay has an
3117 invisible property. Since we don't skip invisible text in
3118 display_line and elsewhere immediately after consuming the
3119 newline before the row start, such a POS will not be in a string,
3120 but the call to init_iterator below will move us to the
3121 after-string. */
3122 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3123
3124 /* This only scans the current chunk -- it should scan all chunks.
3125 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3126 to 16 in 22.1 to make this a lesser problem. */
3127 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3128 {
3129 const char *s = SSDATA (it->overlay_strings[i]);
3130 const char *e = s + SBYTES (it->overlay_strings[i]);
3131
3132 while (s < e && *s != '\n')
3133 ++s;
3134
3135 if (s < e)
3136 {
3137 overlay_strings_with_newlines = 1;
3138 break;
3139 }
3140 }
3141
3142 /* If position is within an overlay string, set up IT to the right
3143 overlay string. */
3144 if (pos->overlay_string_index >= 0)
3145 {
3146 int relative_index;
3147
3148 /* If the first overlay string happens to have a `display'
3149 property for an image, the iterator will be set up for that
3150 image, and we have to undo that setup first before we can
3151 correct the overlay string index. */
3152 if (it->method == GET_FROM_IMAGE)
3153 pop_it (it);
3154
3155 /* We already have the first chunk of overlay strings in
3156 IT->overlay_strings. Load more until the one for
3157 pos->overlay_string_index is in IT->overlay_strings. */
3158 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3159 {
3160 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3161 it->current.overlay_string_index = 0;
3162 while (n--)
3163 {
3164 load_overlay_strings (it, 0);
3165 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3166 }
3167 }
3168
3169 it->current.overlay_string_index = pos->overlay_string_index;
3170 relative_index = (it->current.overlay_string_index
3171 % OVERLAY_STRING_CHUNK_SIZE);
3172 it->string = it->overlay_strings[relative_index];
3173 eassert (STRINGP (it->string));
3174 it->current.string_pos = pos->string_pos;
3175 it->method = GET_FROM_STRING;
3176 it->end_charpos = SCHARS (it->string);
3177 /* Set up the bidi iterator for this overlay string. */
3178 if (it->bidi_p)
3179 {
3180 it->bidi_it.string.lstring = it->string;
3181 it->bidi_it.string.s = NULL;
3182 it->bidi_it.string.schars = SCHARS (it->string);
3183 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3184 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3185 it->bidi_it.string.unibyte = !it->multibyte_p;
3186 it->bidi_it.w = it->w;
3187 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3188 FRAME_WINDOW_P (it->f), &it->bidi_it);
3189
3190 /* Synchronize the state of the bidi iterator with
3191 pos->string_pos. For any string position other than
3192 zero, this will be done automagically when we resume
3193 iteration over the string and get_visually_first_element
3194 is called. But if string_pos is zero, and the string is
3195 to be reordered for display, we need to resync manually,
3196 since it could be that the iteration state recorded in
3197 pos ended at string_pos of 0 moving backwards in string. */
3198 if (CHARPOS (pos->string_pos) == 0)
3199 {
3200 get_visually_first_element (it);
3201 if (IT_STRING_CHARPOS (*it) != 0)
3202 do {
3203 /* Paranoia. */
3204 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3205 bidi_move_to_visually_next (&it->bidi_it);
3206 } while (it->bidi_it.charpos != 0);
3207 }
3208 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3209 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3210 }
3211 }
3212
3213 if (CHARPOS (pos->string_pos) >= 0)
3214 {
3215 /* Recorded position is not in an overlay string, but in another
3216 string. This can only be a string from a `display' property.
3217 IT should already be filled with that string. */
3218 it->current.string_pos = pos->string_pos;
3219 eassert (STRINGP (it->string));
3220 if (it->bidi_p)
3221 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3222 FRAME_WINDOW_P (it->f), &it->bidi_it);
3223 }
3224
3225 /* Restore position in display vector translations, control
3226 character translations or ellipses. */
3227 if (pos->dpvec_index >= 0)
3228 {
3229 if (it->dpvec == NULL)
3230 get_next_display_element (it);
3231 eassert (it->dpvec && it->current.dpvec_index == 0);
3232 it->current.dpvec_index = pos->dpvec_index;
3233 }
3234
3235 CHECK_IT (it);
3236 return !overlay_strings_with_newlines;
3237 }
3238
3239
3240 /* Initialize IT for stepping through current_buffer in window W
3241 starting at ROW->start. */
3242
3243 static void
3244 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3245 {
3246 init_from_display_pos (it, w, &row->start);
3247 it->start = row->start;
3248 it->continuation_lines_width = row->continuation_lines_width;
3249 CHECK_IT (it);
3250 }
3251
3252
3253 /* Initialize IT for stepping through current_buffer in window W
3254 starting in the line following ROW, i.e. starting at ROW->end.
3255 Value is zero if there are overlay strings with newlines at ROW's
3256 end position. */
3257
3258 static int
3259 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3260 {
3261 int success = 0;
3262
3263 if (init_from_display_pos (it, w, &row->end))
3264 {
3265 if (row->continued_p)
3266 it->continuation_lines_width
3267 = row->continuation_lines_width + row->pixel_width;
3268 CHECK_IT (it);
3269 success = 1;
3270 }
3271
3272 return success;
3273 }
3274
3275
3276
3277 \f
3278 /***********************************************************************
3279 Text properties
3280 ***********************************************************************/
3281
3282 /* Called when IT reaches IT->stop_charpos. Handle text property and
3283 overlay changes. Set IT->stop_charpos to the next position where
3284 to stop. */
3285
3286 static void
3287 handle_stop (struct it *it)
3288 {
3289 enum prop_handled handled;
3290 int handle_overlay_change_p;
3291 struct props *p;
3292
3293 it->dpvec = NULL;
3294 it->current.dpvec_index = -1;
3295 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3296 it->ignore_overlay_strings_at_pos_p = 0;
3297 it->ellipsis_p = 0;
3298
3299 /* Use face of preceding text for ellipsis (if invisible) */
3300 if (it->selective_display_ellipsis_p)
3301 it->saved_face_id = it->face_id;
3302
3303 do
3304 {
3305 handled = HANDLED_NORMALLY;
3306
3307 /* Call text property handlers. */
3308 for (p = it_props; p->handler; ++p)
3309 {
3310 handled = p->handler (it);
3311
3312 if (handled == HANDLED_RECOMPUTE_PROPS)
3313 break;
3314 else if (handled == HANDLED_RETURN)
3315 {
3316 /* We still want to show before and after strings from
3317 overlays even if the actual buffer text is replaced. */
3318 if (!handle_overlay_change_p
3319 || it->sp > 1
3320 /* Don't call get_overlay_strings_1 if we already
3321 have overlay strings loaded, because doing so
3322 will load them again and push the iterator state
3323 onto the stack one more time, which is not
3324 expected by the rest of the code that processes
3325 overlay strings. */
3326 || (it->current.overlay_string_index < 0
3327 ? !get_overlay_strings_1 (it, 0, 0)
3328 : 0))
3329 {
3330 if (it->ellipsis_p)
3331 setup_for_ellipsis (it, 0);
3332 /* When handling a display spec, we might load an
3333 empty string. In that case, discard it here. We
3334 used to discard it in handle_single_display_spec,
3335 but that causes get_overlay_strings_1, above, to
3336 ignore overlay strings that we must check. */
3337 if (STRINGP (it->string) && !SCHARS (it->string))
3338 pop_it (it);
3339 return;
3340 }
3341 else if (STRINGP (it->string) && !SCHARS (it->string))
3342 pop_it (it);
3343 else
3344 {
3345 it->ignore_overlay_strings_at_pos_p = 1;
3346 it->string_from_display_prop_p = 0;
3347 it->from_disp_prop_p = 0;
3348 handle_overlay_change_p = 0;
3349 }
3350 handled = HANDLED_RECOMPUTE_PROPS;
3351 break;
3352 }
3353 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3354 handle_overlay_change_p = 0;
3355 }
3356
3357 if (handled != HANDLED_RECOMPUTE_PROPS)
3358 {
3359 /* Don't check for overlay strings below when set to deliver
3360 characters from a display vector. */
3361 if (it->method == GET_FROM_DISPLAY_VECTOR)
3362 handle_overlay_change_p = 0;
3363
3364 /* Handle overlay changes.
3365 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3366 if it finds overlays. */
3367 if (handle_overlay_change_p)
3368 handled = handle_overlay_change (it);
3369 }
3370
3371 if (it->ellipsis_p)
3372 {
3373 setup_for_ellipsis (it, 0);
3374 break;
3375 }
3376 }
3377 while (handled == HANDLED_RECOMPUTE_PROPS);
3378
3379 /* Determine where to stop next. */
3380 if (handled == HANDLED_NORMALLY)
3381 compute_stop_pos (it);
3382 }
3383
3384
3385 /* Compute IT->stop_charpos from text property and overlay change
3386 information for IT's current position. */
3387
3388 static void
3389 compute_stop_pos (struct it *it)
3390 {
3391 register INTERVAL iv, next_iv;
3392 Lisp_Object object, limit, position;
3393 ptrdiff_t charpos, bytepos;
3394
3395 if (STRINGP (it->string))
3396 {
3397 /* Strings are usually short, so don't limit the search for
3398 properties. */
3399 it->stop_charpos = it->end_charpos;
3400 object = it->string;
3401 limit = Qnil;
3402 charpos = IT_STRING_CHARPOS (*it);
3403 bytepos = IT_STRING_BYTEPOS (*it);
3404 }
3405 else
3406 {
3407 ptrdiff_t pos;
3408
3409 /* If end_charpos is out of range for some reason, such as a
3410 misbehaving display function, rationalize it (Bug#5984). */
3411 if (it->end_charpos > ZV)
3412 it->end_charpos = ZV;
3413 it->stop_charpos = it->end_charpos;
3414
3415 /* If next overlay change is in front of the current stop pos
3416 (which is IT->end_charpos), stop there. Note: value of
3417 next_overlay_change is point-max if no overlay change
3418 follows. */
3419 charpos = IT_CHARPOS (*it);
3420 bytepos = IT_BYTEPOS (*it);
3421 pos = next_overlay_change (charpos);
3422 if (pos < it->stop_charpos)
3423 it->stop_charpos = pos;
3424
3425 /* If showing the region, we have to stop at the region
3426 start or end because the face might change there. */
3427 if (it->region_beg_charpos > 0)
3428 {
3429 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3430 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3431 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3432 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3433 }
3434
3435 /* Set up variables for computing the stop position from text
3436 property changes. */
3437 XSETBUFFER (object, current_buffer);
3438 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3439 }
3440
3441 /* Get the interval containing IT's position. Value is a null
3442 interval if there isn't such an interval. */
3443 position = make_number (charpos);
3444 iv = validate_interval_range (object, &position, &position, 0);
3445 if (iv)
3446 {
3447 Lisp_Object values_here[LAST_PROP_IDX];
3448 struct props *p;
3449
3450 /* Get properties here. */
3451 for (p = it_props; p->handler; ++p)
3452 values_here[p->idx] = textget (iv->plist, *p->name);
3453
3454 /* Look for an interval following iv that has different
3455 properties. */
3456 for (next_iv = next_interval (iv);
3457 (next_iv
3458 && (NILP (limit)
3459 || XFASTINT (limit) > next_iv->position));
3460 next_iv = next_interval (next_iv))
3461 {
3462 for (p = it_props; p->handler; ++p)
3463 {
3464 Lisp_Object new_value;
3465
3466 new_value = textget (next_iv->plist, *p->name);
3467 if (!EQ (values_here[p->idx], new_value))
3468 break;
3469 }
3470
3471 if (p->handler)
3472 break;
3473 }
3474
3475 if (next_iv)
3476 {
3477 if (INTEGERP (limit)
3478 && next_iv->position >= XFASTINT (limit))
3479 /* No text property change up to limit. */
3480 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3481 else
3482 /* Text properties change in next_iv. */
3483 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3484 }
3485 }
3486
3487 if (it->cmp_it.id < 0)
3488 {
3489 ptrdiff_t stoppos = it->end_charpos;
3490
3491 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3492 stoppos = -1;
3493 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3494 stoppos, it->string);
3495 }
3496
3497 eassert (STRINGP (it->string)
3498 || (it->stop_charpos >= BEGV
3499 && it->stop_charpos >= IT_CHARPOS (*it)));
3500 }
3501
3502
3503 /* Return the position of the next overlay change after POS in
3504 current_buffer. Value is point-max if no overlay change
3505 follows. This is like `next-overlay-change' but doesn't use
3506 xmalloc. */
3507
3508 static ptrdiff_t
3509 next_overlay_change (ptrdiff_t pos)
3510 {
3511 ptrdiff_t i, noverlays;
3512 ptrdiff_t endpos;
3513 Lisp_Object *overlays;
3514
3515 /* Get all overlays at the given position. */
3516 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3517
3518 /* If any of these overlays ends before endpos,
3519 use its ending point instead. */
3520 for (i = 0; i < noverlays; ++i)
3521 {
3522 Lisp_Object oend;
3523 ptrdiff_t oendpos;
3524
3525 oend = OVERLAY_END (overlays[i]);
3526 oendpos = OVERLAY_POSITION (oend);
3527 endpos = min (endpos, oendpos);
3528 }
3529
3530 return endpos;
3531 }
3532
3533 /* How many characters forward to search for a display property or
3534 display string. Searching too far forward makes the bidi display
3535 sluggish, especially in small windows. */
3536 #define MAX_DISP_SCAN 250
3537
3538 /* Return the character position of a display string at or after
3539 position specified by POSITION. If no display string exists at or
3540 after POSITION, return ZV. A display string is either an overlay
3541 with `display' property whose value is a string, or a `display'
3542 text property whose value is a string. STRING is data about the
3543 string to iterate; if STRING->lstring is nil, we are iterating a
3544 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3545 on a GUI frame. DISP_PROP is set to zero if we searched
3546 MAX_DISP_SCAN characters forward without finding any display
3547 strings, non-zero otherwise. It is set to 2 if the display string
3548 uses any kind of `(space ...)' spec that will produce a stretch of
3549 white space in the text area. */
3550 ptrdiff_t
3551 compute_display_string_pos (struct text_pos *position,
3552 struct bidi_string_data *string,
3553 struct window *w,
3554 int frame_window_p, int *disp_prop)
3555 {
3556 /* OBJECT = nil means current buffer. */
3557 Lisp_Object object, object1;
3558 Lisp_Object pos, spec, limpos;
3559 int string_p = (string && (STRINGP (string->lstring) || string->s));
3560 ptrdiff_t eob = string_p ? string->schars : ZV;
3561 ptrdiff_t begb = string_p ? 0 : BEGV;
3562 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3563 ptrdiff_t lim =
3564 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3565 struct text_pos tpos;
3566 int rv = 0;
3567
3568 if (string && STRINGP (string->lstring))
3569 object1 = object = string->lstring;
3570 else if (w && !string_p)
3571 {
3572 XSETWINDOW (object, w);
3573 object1 = Qnil;
3574 }
3575 else
3576 object1 = object = Qnil;
3577
3578 *disp_prop = 1;
3579
3580 if (charpos >= eob
3581 /* We don't support display properties whose values are strings
3582 that have display string properties. */
3583 || string->from_disp_str
3584 /* C strings cannot have display properties. */
3585 || (string->s && !STRINGP (object)))
3586 {
3587 *disp_prop = 0;
3588 return eob;
3589 }
3590
3591 /* If the character at CHARPOS is where the display string begins,
3592 return CHARPOS. */
3593 pos = make_number (charpos);
3594 if (STRINGP (object))
3595 bufpos = string->bufpos;
3596 else
3597 bufpos = charpos;
3598 tpos = *position;
3599 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3600 && (charpos <= begb
3601 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3602 object),
3603 spec))
3604 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3605 frame_window_p)))
3606 {
3607 if (rv == 2)
3608 *disp_prop = 2;
3609 return charpos;
3610 }
3611
3612 /* Look forward for the first character with a `display' property
3613 that will replace the underlying text when displayed. */
3614 limpos = make_number (lim);
3615 do {
3616 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3617 CHARPOS (tpos) = XFASTINT (pos);
3618 if (CHARPOS (tpos) >= lim)
3619 {
3620 *disp_prop = 0;
3621 break;
3622 }
3623 if (STRINGP (object))
3624 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3625 else
3626 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3627 spec = Fget_char_property (pos, Qdisplay, object);
3628 if (!STRINGP (object))
3629 bufpos = CHARPOS (tpos);
3630 } while (NILP (spec)
3631 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3632 bufpos, frame_window_p)));
3633 if (rv == 2)
3634 *disp_prop = 2;
3635
3636 return CHARPOS (tpos);
3637 }
3638
3639 /* Return the character position of the end of the display string that
3640 started at CHARPOS. If there's no display string at CHARPOS,
3641 return -1. A display string is either an overlay with `display'
3642 property whose value is a string or a `display' text property whose
3643 value is a string. */
3644 ptrdiff_t
3645 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3646 {
3647 /* OBJECT = nil means current buffer. */
3648 Lisp_Object object =
3649 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3650 Lisp_Object pos = make_number (charpos);
3651 ptrdiff_t eob =
3652 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3653
3654 if (charpos >= eob || (string->s && !STRINGP (object)))
3655 return eob;
3656
3657 /* It could happen that the display property or overlay was removed
3658 since we found it in compute_display_string_pos above. One way
3659 this can happen is if JIT font-lock was called (through
3660 handle_fontified_prop), and jit-lock-functions remove text
3661 properties or overlays from the portion of buffer that includes
3662 CHARPOS. Muse mode is known to do that, for example. In this
3663 case, we return -1 to the caller, to signal that no display
3664 string is actually present at CHARPOS. See bidi_fetch_char for
3665 how this is handled.
3666
3667 An alternative would be to never look for display properties past
3668 it->stop_charpos. But neither compute_display_string_pos nor
3669 bidi_fetch_char that calls it know or care where the next
3670 stop_charpos is. */
3671 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3672 return -1;
3673
3674 /* Look forward for the first character where the `display' property
3675 changes. */
3676 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3677
3678 return XFASTINT (pos);
3679 }
3680
3681
3682 \f
3683 /***********************************************************************
3684 Fontification
3685 ***********************************************************************/
3686
3687 /* Handle changes in the `fontified' property of the current buffer by
3688 calling hook functions from Qfontification_functions to fontify
3689 regions of text. */
3690
3691 static enum prop_handled
3692 handle_fontified_prop (struct it *it)
3693 {
3694 Lisp_Object prop, pos;
3695 enum prop_handled handled = HANDLED_NORMALLY;
3696
3697 if (!NILP (Vmemory_full))
3698 return handled;
3699
3700 /* Get the value of the `fontified' property at IT's current buffer
3701 position. (The `fontified' property doesn't have a special
3702 meaning in strings.) If the value is nil, call functions from
3703 Qfontification_functions. */
3704 if (!STRINGP (it->string)
3705 && it->s == NULL
3706 && !NILP (Vfontification_functions)
3707 && !NILP (Vrun_hooks)
3708 && (pos = make_number (IT_CHARPOS (*it)),
3709 prop = Fget_char_property (pos, Qfontified, Qnil),
3710 /* Ignore the special cased nil value always present at EOB since
3711 no amount of fontifying will be able to change it. */
3712 NILP (prop) && IT_CHARPOS (*it) < Z))
3713 {
3714 ptrdiff_t count = SPECPDL_INDEX ();
3715 Lisp_Object val;
3716 struct buffer *obuf = current_buffer;
3717 int begv = BEGV, zv = ZV;
3718 int old_clip_changed = current_buffer->clip_changed;
3719
3720 val = Vfontification_functions;
3721 specbind (Qfontification_functions, Qnil);
3722
3723 eassert (it->end_charpos == ZV);
3724
3725 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3726 safe_call1 (val, pos);
3727 else
3728 {
3729 Lisp_Object fns, fn;
3730 struct gcpro gcpro1, gcpro2;
3731
3732 fns = Qnil;
3733 GCPRO2 (val, fns);
3734
3735 for (; CONSP (val); val = XCDR (val))
3736 {
3737 fn = XCAR (val);
3738
3739 if (EQ (fn, Qt))
3740 {
3741 /* A value of t indicates this hook has a local
3742 binding; it means to run the global binding too.
3743 In a global value, t should not occur. If it
3744 does, we must ignore it to avoid an endless
3745 loop. */
3746 for (fns = Fdefault_value (Qfontification_functions);
3747 CONSP (fns);
3748 fns = XCDR (fns))
3749 {
3750 fn = XCAR (fns);
3751 if (!EQ (fn, Qt))
3752 safe_call1 (fn, pos);
3753 }
3754 }
3755 else
3756 safe_call1 (fn, pos);
3757 }
3758
3759 UNGCPRO;
3760 }
3761
3762 unbind_to (count, Qnil);
3763
3764 /* Fontification functions routinely call `save-restriction'.
3765 Normally, this tags clip_changed, which can confuse redisplay
3766 (see discussion in Bug#6671). Since we don't perform any
3767 special handling of fontification changes in the case where
3768 `save-restriction' isn't called, there's no point doing so in
3769 this case either. So, if the buffer's restrictions are
3770 actually left unchanged, reset clip_changed. */
3771 if (obuf == current_buffer)
3772 {
3773 if (begv == BEGV && zv == ZV)
3774 current_buffer->clip_changed = old_clip_changed;
3775 }
3776 /* There isn't much we can reasonably do to protect against
3777 misbehaving fontification, but here's a fig leaf. */
3778 else if (BUFFER_LIVE_P (obuf))
3779 set_buffer_internal_1 (obuf);
3780
3781 /* The fontification code may have added/removed text.
3782 It could do even a lot worse, but let's at least protect against
3783 the most obvious case where only the text past `pos' gets changed',
3784 as is/was done in grep.el where some escapes sequences are turned
3785 into face properties (bug#7876). */
3786 it->end_charpos = ZV;
3787
3788 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3789 something. This avoids an endless loop if they failed to
3790 fontify the text for which reason ever. */
3791 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3792 handled = HANDLED_RECOMPUTE_PROPS;
3793 }
3794
3795 return handled;
3796 }
3797
3798
3799 \f
3800 /***********************************************************************
3801 Faces
3802 ***********************************************************************/
3803
3804 /* Set up iterator IT from face properties at its current position.
3805 Called from handle_stop. */
3806
3807 static enum prop_handled
3808 handle_face_prop (struct it *it)
3809 {
3810 int new_face_id;
3811 ptrdiff_t next_stop;
3812
3813 if (!STRINGP (it->string))
3814 {
3815 new_face_id
3816 = face_at_buffer_position (it->w,
3817 IT_CHARPOS (*it),
3818 it->region_beg_charpos,
3819 it->region_end_charpos,
3820 &next_stop,
3821 (IT_CHARPOS (*it)
3822 + TEXT_PROP_DISTANCE_LIMIT),
3823 0, it->base_face_id);
3824
3825 /* Is this a start of a run of characters with box face?
3826 Caveat: this can be called for a freshly initialized
3827 iterator; face_id is -1 in this case. We know that the new
3828 face will not change until limit, i.e. if the new face has a
3829 box, all characters up to limit will have one. But, as
3830 usual, we don't know whether limit is really the end. */
3831 if (new_face_id != it->face_id)
3832 {
3833 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3834 /* If it->face_id is -1, old_face below will be NULL, see
3835 the definition of FACE_FROM_ID. This will happen if this
3836 is the initial call that gets the face. */
3837 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3838
3839 /* If the value of face_id of the iterator is -1, we have to
3840 look in front of IT's position and see whether there is a
3841 face there that's different from new_face_id. */
3842 if (!old_face && IT_CHARPOS (*it) > BEG)
3843 {
3844 int prev_face_id = face_before_it_pos (it);
3845
3846 old_face = FACE_FROM_ID (it->f, prev_face_id);
3847 }
3848
3849 /* If the new face has a box, but the old face does not,
3850 this is the start of a run of characters with box face,
3851 i.e. this character has a shadow on the left side. */
3852 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3853 && (old_face == NULL || !old_face->box));
3854 it->face_box_p = new_face->box != FACE_NO_BOX;
3855 }
3856 }
3857 else
3858 {
3859 int base_face_id;
3860 ptrdiff_t bufpos;
3861 int i;
3862 Lisp_Object from_overlay
3863 = (it->current.overlay_string_index >= 0
3864 ? it->string_overlays[it->current.overlay_string_index
3865 % OVERLAY_STRING_CHUNK_SIZE]
3866 : Qnil);
3867
3868 /* See if we got to this string directly or indirectly from
3869 an overlay property. That includes the before-string or
3870 after-string of an overlay, strings in display properties
3871 provided by an overlay, their text properties, etc.
3872
3873 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3874 if (! NILP (from_overlay))
3875 for (i = it->sp - 1; i >= 0; i--)
3876 {
3877 if (it->stack[i].current.overlay_string_index >= 0)
3878 from_overlay
3879 = it->string_overlays[it->stack[i].current.overlay_string_index
3880 % OVERLAY_STRING_CHUNK_SIZE];
3881 else if (! NILP (it->stack[i].from_overlay))
3882 from_overlay = it->stack[i].from_overlay;
3883
3884 if (!NILP (from_overlay))
3885 break;
3886 }
3887
3888 if (! NILP (from_overlay))
3889 {
3890 bufpos = IT_CHARPOS (*it);
3891 /* For a string from an overlay, the base face depends
3892 only on text properties and ignores overlays. */
3893 base_face_id
3894 = face_for_overlay_string (it->w,
3895 IT_CHARPOS (*it),
3896 it->region_beg_charpos,
3897 it->region_end_charpos,
3898 &next_stop,
3899 (IT_CHARPOS (*it)
3900 + TEXT_PROP_DISTANCE_LIMIT),
3901 0,
3902 from_overlay);
3903 }
3904 else
3905 {
3906 bufpos = 0;
3907
3908 /* For strings from a `display' property, use the face at
3909 IT's current buffer position as the base face to merge
3910 with, so that overlay strings appear in the same face as
3911 surrounding text, unless they specify their own
3912 faces. */
3913 base_face_id = it->string_from_prefix_prop_p
3914 ? DEFAULT_FACE_ID
3915 : underlying_face_id (it);
3916 }
3917
3918 new_face_id = face_at_string_position (it->w,
3919 it->string,
3920 IT_STRING_CHARPOS (*it),
3921 bufpos,
3922 it->region_beg_charpos,
3923 it->region_end_charpos,
3924 &next_stop,
3925 base_face_id, 0);
3926
3927 /* Is this a start of a run of characters with box? Caveat:
3928 this can be called for a freshly allocated iterator; face_id
3929 is -1 is this case. We know that the new face will not
3930 change until the next check pos, i.e. if the new face has a
3931 box, all characters up to that position will have a
3932 box. But, as usual, we don't know whether that position
3933 is really the end. */
3934 if (new_face_id != it->face_id)
3935 {
3936 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3937 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3938
3939 /* If new face has a box but old face hasn't, this is the
3940 start of a run of characters with box, i.e. it has a
3941 shadow on the left side. */
3942 it->start_of_box_run_p
3943 = new_face->box && (old_face == NULL || !old_face->box);
3944 it->face_box_p = new_face->box != FACE_NO_BOX;
3945 }
3946 }
3947
3948 it->face_id = new_face_id;
3949 return HANDLED_NORMALLY;
3950 }
3951
3952
3953 /* Return the ID of the face ``underlying'' IT's current position,
3954 which is in a string. If the iterator is associated with a
3955 buffer, return the face at IT's current buffer position.
3956 Otherwise, use the iterator's base_face_id. */
3957
3958 static int
3959 underlying_face_id (struct it *it)
3960 {
3961 int face_id = it->base_face_id, i;
3962
3963 eassert (STRINGP (it->string));
3964
3965 for (i = it->sp - 1; i >= 0; --i)
3966 if (NILP (it->stack[i].string))
3967 face_id = it->stack[i].face_id;
3968
3969 return face_id;
3970 }
3971
3972
3973 /* Compute the face one character before or after the current position
3974 of IT, in the visual order. BEFORE_P non-zero means get the face
3975 in front (to the left in L2R paragraphs, to the right in R2L
3976 paragraphs) of IT's screen position. Value is the ID of the face. */
3977
3978 static int
3979 face_before_or_after_it_pos (struct it *it, int before_p)
3980 {
3981 int face_id, limit;
3982 ptrdiff_t next_check_charpos;
3983 struct it it_copy;
3984 void *it_copy_data = NULL;
3985
3986 eassert (it->s == NULL);
3987
3988 if (STRINGP (it->string))
3989 {
3990 ptrdiff_t bufpos, charpos;
3991 int base_face_id;
3992
3993 /* No face change past the end of the string (for the case
3994 we are padding with spaces). No face change before the
3995 string start. */
3996 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3997 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3998 return it->face_id;
3999
4000 if (!it->bidi_p)
4001 {
4002 /* Set charpos to the position before or after IT's current
4003 position, in the logical order, which in the non-bidi
4004 case is the same as the visual order. */
4005 if (before_p)
4006 charpos = IT_STRING_CHARPOS (*it) - 1;
4007 else if (it->what == IT_COMPOSITION)
4008 /* For composition, we must check the character after the
4009 composition. */
4010 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4011 else
4012 charpos = IT_STRING_CHARPOS (*it) + 1;
4013 }
4014 else
4015 {
4016 if (before_p)
4017 {
4018 /* With bidi iteration, the character before the current
4019 in the visual order cannot be found by simple
4020 iteration, because "reverse" reordering is not
4021 supported. Instead, we need to use the move_it_*
4022 family of functions. */
4023 /* Ignore face changes before the first visible
4024 character on this display line. */
4025 if (it->current_x <= it->first_visible_x)
4026 return it->face_id;
4027 SAVE_IT (it_copy, *it, it_copy_data);
4028 /* Implementation note: Since move_it_in_display_line
4029 works in the iterator geometry, and thinks the first
4030 character is always the leftmost, even in R2L lines,
4031 we don't need to distinguish between the R2L and L2R
4032 cases here. */
4033 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4034 it_copy.current_x - 1, MOVE_TO_X);
4035 charpos = IT_STRING_CHARPOS (it_copy);
4036 RESTORE_IT (it, it, it_copy_data);
4037 }
4038 else
4039 {
4040 /* Set charpos to the string position of the character
4041 that comes after IT's current position in the visual
4042 order. */
4043 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4044
4045 it_copy = *it;
4046 while (n--)
4047 bidi_move_to_visually_next (&it_copy.bidi_it);
4048
4049 charpos = it_copy.bidi_it.charpos;
4050 }
4051 }
4052 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4053
4054 if (it->current.overlay_string_index >= 0)
4055 bufpos = IT_CHARPOS (*it);
4056 else
4057 bufpos = 0;
4058
4059 base_face_id = underlying_face_id (it);
4060
4061 /* Get the face for ASCII, or unibyte. */
4062 face_id = face_at_string_position (it->w,
4063 it->string,
4064 charpos,
4065 bufpos,
4066 it->region_beg_charpos,
4067 it->region_end_charpos,
4068 &next_check_charpos,
4069 base_face_id, 0);
4070
4071 /* Correct the face for charsets different from ASCII. Do it
4072 for the multibyte case only. The face returned above is
4073 suitable for unibyte text if IT->string is unibyte. */
4074 if (STRING_MULTIBYTE (it->string))
4075 {
4076 struct text_pos pos1 = string_pos (charpos, it->string);
4077 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4078 int c, len;
4079 struct face *face = FACE_FROM_ID (it->f, face_id);
4080
4081 c = string_char_and_length (p, &len);
4082 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4083 }
4084 }
4085 else
4086 {
4087 struct text_pos pos;
4088
4089 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4090 || (IT_CHARPOS (*it) <= BEGV && before_p))
4091 return it->face_id;
4092
4093 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4094 pos = it->current.pos;
4095
4096 if (!it->bidi_p)
4097 {
4098 if (before_p)
4099 DEC_TEXT_POS (pos, it->multibyte_p);
4100 else
4101 {
4102 if (it->what == IT_COMPOSITION)
4103 {
4104 /* For composition, we must check the position after
4105 the composition. */
4106 pos.charpos += it->cmp_it.nchars;
4107 pos.bytepos += it->len;
4108 }
4109 else
4110 INC_TEXT_POS (pos, it->multibyte_p);
4111 }
4112 }
4113 else
4114 {
4115 if (before_p)
4116 {
4117 /* With bidi iteration, the character before the current
4118 in the visual order cannot be found by simple
4119 iteration, because "reverse" reordering is not
4120 supported. Instead, we need to use the move_it_*
4121 family of functions. */
4122 /* Ignore face changes before the first visible
4123 character on this display line. */
4124 if (it->current_x <= it->first_visible_x)
4125 return it->face_id;
4126 SAVE_IT (it_copy, *it, it_copy_data);
4127 /* Implementation note: Since move_it_in_display_line
4128 works in the iterator geometry, and thinks the first
4129 character is always the leftmost, even in R2L lines,
4130 we don't need to distinguish between the R2L and L2R
4131 cases here. */
4132 move_it_in_display_line (&it_copy, ZV,
4133 it_copy.current_x - 1, MOVE_TO_X);
4134 pos = it_copy.current.pos;
4135 RESTORE_IT (it, it, it_copy_data);
4136 }
4137 else
4138 {
4139 /* Set charpos to the buffer position of the character
4140 that comes after IT's current position in the visual
4141 order. */
4142 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4143
4144 it_copy = *it;
4145 while (n--)
4146 bidi_move_to_visually_next (&it_copy.bidi_it);
4147
4148 SET_TEXT_POS (pos,
4149 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4150 }
4151 }
4152 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4153
4154 /* Determine face for CHARSET_ASCII, or unibyte. */
4155 face_id = face_at_buffer_position (it->w,
4156 CHARPOS (pos),
4157 it->region_beg_charpos,
4158 it->region_end_charpos,
4159 &next_check_charpos,
4160 limit, 0, -1);
4161
4162 /* Correct the face for charsets different from ASCII. Do it
4163 for the multibyte case only. The face returned above is
4164 suitable for unibyte text if current_buffer is unibyte. */
4165 if (it->multibyte_p)
4166 {
4167 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4168 struct face *face = FACE_FROM_ID (it->f, face_id);
4169 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4170 }
4171 }
4172
4173 return face_id;
4174 }
4175
4176
4177 \f
4178 /***********************************************************************
4179 Invisible text
4180 ***********************************************************************/
4181
4182 /* Set up iterator IT from invisible properties at its current
4183 position. Called from handle_stop. */
4184
4185 static enum prop_handled
4186 handle_invisible_prop (struct it *it)
4187 {
4188 enum prop_handled handled = HANDLED_NORMALLY;
4189 int invis_p;
4190 Lisp_Object prop;
4191
4192 if (STRINGP (it->string))
4193 {
4194 Lisp_Object end_charpos, limit, charpos;
4195
4196 /* Get the value of the invisible text property at the
4197 current position. Value will be nil if there is no such
4198 property. */
4199 charpos = make_number (IT_STRING_CHARPOS (*it));
4200 prop = Fget_text_property (charpos, Qinvisible, it->string);
4201 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4202
4203 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4204 {
4205 /* Record whether we have to display an ellipsis for the
4206 invisible text. */
4207 int display_ellipsis_p = (invis_p == 2);
4208 ptrdiff_t len, endpos;
4209
4210 handled = HANDLED_RECOMPUTE_PROPS;
4211
4212 /* Get the position at which the next visible text can be
4213 found in IT->string, if any. */
4214 endpos = len = SCHARS (it->string);
4215 XSETINT (limit, len);
4216 do
4217 {
4218 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4219 it->string, limit);
4220 if (INTEGERP (end_charpos))
4221 {
4222 endpos = XFASTINT (end_charpos);
4223 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4224 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4225 if (invis_p == 2)
4226 display_ellipsis_p = 1;
4227 }
4228 }
4229 while (invis_p && endpos < len);
4230
4231 if (display_ellipsis_p)
4232 it->ellipsis_p = 1;
4233
4234 if (endpos < len)
4235 {
4236 /* Text at END_CHARPOS is visible. Move IT there. */
4237 struct text_pos old;
4238 ptrdiff_t oldpos;
4239
4240 old = it->current.string_pos;
4241 oldpos = CHARPOS (old);
4242 if (it->bidi_p)
4243 {
4244 if (it->bidi_it.first_elt
4245 && it->bidi_it.charpos < SCHARS (it->string))
4246 bidi_paragraph_init (it->paragraph_embedding,
4247 &it->bidi_it, 1);
4248 /* Bidi-iterate out of the invisible text. */
4249 do
4250 {
4251 bidi_move_to_visually_next (&it->bidi_it);
4252 }
4253 while (oldpos <= it->bidi_it.charpos
4254 && it->bidi_it.charpos < endpos);
4255
4256 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4257 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4258 if (IT_CHARPOS (*it) >= endpos)
4259 it->prev_stop = endpos;
4260 }
4261 else
4262 {
4263 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4264 compute_string_pos (&it->current.string_pos, old, it->string);
4265 }
4266 }
4267 else
4268 {
4269 /* The rest of the string is invisible. If this is an
4270 overlay string, proceed with the next overlay string
4271 or whatever comes and return a character from there. */
4272 if (it->current.overlay_string_index >= 0
4273 && !display_ellipsis_p)
4274 {
4275 next_overlay_string (it);
4276 /* Don't check for overlay strings when we just
4277 finished processing them. */
4278 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4279 }
4280 else
4281 {
4282 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4283 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4284 }
4285 }
4286 }
4287 }
4288 else
4289 {
4290 ptrdiff_t newpos, next_stop, start_charpos, tem;
4291 Lisp_Object pos, overlay;
4292
4293 /* First of all, is there invisible text at this position? */
4294 tem = start_charpos = IT_CHARPOS (*it);
4295 pos = make_number (tem);
4296 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4297 &overlay);
4298 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4299
4300 /* If we are on invisible text, skip over it. */
4301 if (invis_p && start_charpos < it->end_charpos)
4302 {
4303 /* Record whether we have to display an ellipsis for the
4304 invisible text. */
4305 int display_ellipsis_p = invis_p == 2;
4306
4307 handled = HANDLED_RECOMPUTE_PROPS;
4308
4309 /* Loop skipping over invisible text. The loop is left at
4310 ZV or with IT on the first char being visible again. */
4311 do
4312 {
4313 /* Try to skip some invisible text. Return value is the
4314 position reached which can be equal to where we start
4315 if there is nothing invisible there. This skips both
4316 over invisible text properties and overlays with
4317 invisible property. */
4318 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4319
4320 /* If we skipped nothing at all we weren't at invisible
4321 text in the first place. If everything to the end of
4322 the buffer was skipped, end the loop. */
4323 if (newpos == tem || newpos >= ZV)
4324 invis_p = 0;
4325 else
4326 {
4327 /* We skipped some characters but not necessarily
4328 all there are. Check if we ended up on visible
4329 text. Fget_char_property returns the property of
4330 the char before the given position, i.e. if we
4331 get invis_p = 0, this means that the char at
4332 newpos is visible. */
4333 pos = make_number (newpos);
4334 prop = Fget_char_property (pos, Qinvisible, it->window);
4335 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4336 }
4337
4338 /* If we ended up on invisible text, proceed to
4339 skip starting with next_stop. */
4340 if (invis_p)
4341 tem = next_stop;
4342
4343 /* If there are adjacent invisible texts, don't lose the
4344 second one's ellipsis. */
4345 if (invis_p == 2)
4346 display_ellipsis_p = 1;
4347 }
4348 while (invis_p);
4349
4350 /* The position newpos is now either ZV or on visible text. */
4351 if (it->bidi_p)
4352 {
4353 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4354 int on_newline =
4355 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4356 int after_newline =
4357 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4358
4359 /* If the invisible text ends on a newline or on a
4360 character after a newline, we can avoid the costly,
4361 character by character, bidi iteration to NEWPOS, and
4362 instead simply reseat the iterator there. That's
4363 because all bidi reordering information is tossed at
4364 the newline. This is a big win for modes that hide
4365 complete lines, like Outline, Org, etc. */
4366 if (on_newline || after_newline)
4367 {
4368 struct text_pos tpos;
4369 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4370
4371 SET_TEXT_POS (tpos, newpos, bpos);
4372 reseat_1 (it, tpos, 0);
4373 /* If we reseat on a newline/ZV, we need to prep the
4374 bidi iterator for advancing to the next character
4375 after the newline/EOB, keeping the current paragraph
4376 direction (so that PRODUCE_GLYPHS does TRT wrt
4377 prepending/appending glyphs to a glyph row). */
4378 if (on_newline)
4379 {
4380 it->bidi_it.first_elt = 0;
4381 it->bidi_it.paragraph_dir = pdir;
4382 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4383 it->bidi_it.nchars = 1;
4384 it->bidi_it.ch_len = 1;
4385 }
4386 }
4387 else /* Must use the slow method. */
4388 {
4389 /* With bidi iteration, the region of invisible text
4390 could start and/or end in the middle of a
4391 non-base embedding level. Therefore, we need to
4392 skip invisible text using the bidi iterator,
4393 starting at IT's current position, until we find
4394 ourselves outside of the invisible text.
4395 Skipping invisible text _after_ bidi iteration
4396 avoids affecting the visual order of the
4397 displayed text when invisible properties are
4398 added or removed. */
4399 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4400 {
4401 /* If we were `reseat'ed to a new paragraph,
4402 determine the paragraph base direction. We
4403 need to do it now because
4404 next_element_from_buffer may not have a
4405 chance to do it, if we are going to skip any
4406 text at the beginning, which resets the
4407 FIRST_ELT flag. */
4408 bidi_paragraph_init (it->paragraph_embedding,
4409 &it->bidi_it, 1);
4410 }
4411 do
4412 {
4413 bidi_move_to_visually_next (&it->bidi_it);
4414 }
4415 while (it->stop_charpos <= it->bidi_it.charpos
4416 && it->bidi_it.charpos < newpos);
4417 IT_CHARPOS (*it) = it->bidi_it.charpos;
4418 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4419 /* If we overstepped NEWPOS, record its position in
4420 the iterator, so that we skip invisible text if
4421 later the bidi iteration lands us in the
4422 invisible region again. */
4423 if (IT_CHARPOS (*it) >= newpos)
4424 it->prev_stop = newpos;
4425 }
4426 }
4427 else
4428 {
4429 IT_CHARPOS (*it) = newpos;
4430 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4431 }
4432
4433 /* If there are before-strings at the start of invisible
4434 text, and the text is invisible because of a text
4435 property, arrange to show before-strings because 20.x did
4436 it that way. (If the text is invisible because of an
4437 overlay property instead of a text property, this is
4438 already handled in the overlay code.) */
4439 if (NILP (overlay)
4440 && get_overlay_strings (it, it->stop_charpos))
4441 {
4442 handled = HANDLED_RECOMPUTE_PROPS;
4443 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4444 }
4445 else if (display_ellipsis_p)
4446 {
4447 /* Make sure that the glyphs of the ellipsis will get
4448 correct `charpos' values. If we would not update
4449 it->position here, the glyphs would belong to the
4450 last visible character _before_ the invisible
4451 text, which confuses `set_cursor_from_row'.
4452
4453 We use the last invisible position instead of the
4454 first because this way the cursor is always drawn on
4455 the first "." of the ellipsis, whenever PT is inside
4456 the invisible text. Otherwise the cursor would be
4457 placed _after_ the ellipsis when the point is after the
4458 first invisible character. */
4459 if (!STRINGP (it->object))
4460 {
4461 it->position.charpos = newpos - 1;
4462 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4463 }
4464 it->ellipsis_p = 1;
4465 /* Let the ellipsis display before
4466 considering any properties of the following char.
4467 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4468 handled = HANDLED_RETURN;
4469 }
4470 }
4471 }
4472
4473 return handled;
4474 }
4475
4476
4477 /* Make iterator IT return `...' next.
4478 Replaces LEN characters from buffer. */
4479
4480 static void
4481 setup_for_ellipsis (struct it *it, int len)
4482 {
4483 /* Use the display table definition for `...'. Invalid glyphs
4484 will be handled by the method returning elements from dpvec. */
4485 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4486 {
4487 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4488 it->dpvec = v->contents;
4489 it->dpend = v->contents + v->header.size;
4490 }
4491 else
4492 {
4493 /* Default `...'. */
4494 it->dpvec = default_invis_vector;
4495 it->dpend = default_invis_vector + 3;
4496 }
4497
4498 it->dpvec_char_len = len;
4499 it->current.dpvec_index = 0;
4500 it->dpvec_face_id = -1;
4501
4502 /* Remember the current face id in case glyphs specify faces.
4503 IT's face is restored in set_iterator_to_next.
4504 saved_face_id was set to preceding char's face in handle_stop. */
4505 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4506 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4507
4508 it->method = GET_FROM_DISPLAY_VECTOR;
4509 it->ellipsis_p = 1;
4510 }
4511
4512
4513 \f
4514 /***********************************************************************
4515 'display' property
4516 ***********************************************************************/
4517
4518 /* Set up iterator IT from `display' property at its current position.
4519 Called from handle_stop.
4520 We return HANDLED_RETURN if some part of the display property
4521 overrides the display of the buffer text itself.
4522 Otherwise we return HANDLED_NORMALLY. */
4523
4524 static enum prop_handled
4525 handle_display_prop (struct it *it)
4526 {
4527 Lisp_Object propval, object, overlay;
4528 struct text_pos *position;
4529 ptrdiff_t bufpos;
4530 /* Nonzero if some property replaces the display of the text itself. */
4531 int display_replaced_p = 0;
4532
4533 if (STRINGP (it->string))
4534 {
4535 object = it->string;
4536 position = &it->current.string_pos;
4537 bufpos = CHARPOS (it->current.pos);
4538 }
4539 else
4540 {
4541 XSETWINDOW (object, it->w);
4542 position = &it->current.pos;
4543 bufpos = CHARPOS (*position);
4544 }
4545
4546 /* Reset those iterator values set from display property values. */
4547 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4548 it->space_width = Qnil;
4549 it->font_height = Qnil;
4550 it->voffset = 0;
4551
4552 /* We don't support recursive `display' properties, i.e. string
4553 values that have a string `display' property, that have a string
4554 `display' property etc. */
4555 if (!it->string_from_display_prop_p)
4556 it->area = TEXT_AREA;
4557
4558 propval = get_char_property_and_overlay (make_number (position->charpos),
4559 Qdisplay, object, &overlay);
4560 if (NILP (propval))
4561 return HANDLED_NORMALLY;
4562 /* Now OVERLAY is the overlay that gave us this property, or nil
4563 if it was a text property. */
4564
4565 if (!STRINGP (it->string))
4566 object = it->w->contents;
4567
4568 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4569 position, bufpos,
4570 FRAME_WINDOW_P (it->f));
4571
4572 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4573 }
4574
4575 /* Subroutine of handle_display_prop. Returns non-zero if the display
4576 specification in SPEC is a replacing specification, i.e. it would
4577 replace the text covered by `display' property with something else,
4578 such as an image or a display string. If SPEC includes any kind or
4579 `(space ...) specification, the value is 2; this is used by
4580 compute_display_string_pos, which see.
4581
4582 See handle_single_display_spec for documentation of arguments.
4583 frame_window_p is non-zero if the window being redisplayed is on a
4584 GUI frame; this argument is used only if IT is NULL, see below.
4585
4586 IT can be NULL, if this is called by the bidi reordering code
4587 through compute_display_string_pos, which see. In that case, this
4588 function only examines SPEC, but does not otherwise "handle" it, in
4589 the sense that it doesn't set up members of IT from the display
4590 spec. */
4591 static int
4592 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4593 Lisp_Object overlay, struct text_pos *position,
4594 ptrdiff_t bufpos, int frame_window_p)
4595 {
4596 int replacing_p = 0;
4597 int rv;
4598
4599 if (CONSP (spec)
4600 /* Simple specifications. */
4601 && !EQ (XCAR (spec), Qimage)
4602 && !EQ (XCAR (spec), Qspace)
4603 && !EQ (XCAR (spec), Qwhen)
4604 && !EQ (XCAR (spec), Qslice)
4605 && !EQ (XCAR (spec), Qspace_width)
4606 && !EQ (XCAR (spec), Qheight)
4607 && !EQ (XCAR (spec), Qraise)
4608 /* Marginal area specifications. */
4609 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4610 && !EQ (XCAR (spec), Qleft_fringe)
4611 && !EQ (XCAR (spec), Qright_fringe)
4612 && !NILP (XCAR (spec)))
4613 {
4614 for (; CONSP (spec); spec = XCDR (spec))
4615 {
4616 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4617 overlay, position, bufpos,
4618 replacing_p, frame_window_p)))
4619 {
4620 replacing_p = rv;
4621 /* If some text in a string is replaced, `position' no
4622 longer points to the position of `object'. */
4623 if (!it || STRINGP (object))
4624 break;
4625 }
4626 }
4627 }
4628 else if (VECTORP (spec))
4629 {
4630 ptrdiff_t i;
4631 for (i = 0; i < ASIZE (spec); ++i)
4632 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4633 overlay, position, bufpos,
4634 replacing_p, frame_window_p)))
4635 {
4636 replacing_p = rv;
4637 /* If some text in a string is replaced, `position' no
4638 longer points to the position of `object'. */
4639 if (!it || STRINGP (object))
4640 break;
4641 }
4642 }
4643 else
4644 {
4645 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4646 position, bufpos, 0,
4647 frame_window_p)))
4648 replacing_p = rv;
4649 }
4650
4651 return replacing_p;
4652 }
4653
4654 /* Value is the position of the end of the `display' property starting
4655 at START_POS in OBJECT. */
4656
4657 static struct text_pos
4658 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4659 {
4660 Lisp_Object end;
4661 struct text_pos end_pos;
4662
4663 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4664 Qdisplay, object, Qnil);
4665 CHARPOS (end_pos) = XFASTINT (end);
4666 if (STRINGP (object))
4667 compute_string_pos (&end_pos, start_pos, it->string);
4668 else
4669 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4670
4671 return end_pos;
4672 }
4673
4674
4675 /* Set up IT from a single `display' property specification SPEC. OBJECT
4676 is the object in which the `display' property was found. *POSITION
4677 is the position in OBJECT at which the `display' property was found.
4678 BUFPOS is the buffer position of OBJECT (different from POSITION if
4679 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4680 previously saw a display specification which already replaced text
4681 display with something else, for example an image; we ignore such
4682 properties after the first one has been processed.
4683
4684 OVERLAY is the overlay this `display' property came from,
4685 or nil if it was a text property.
4686
4687 If SPEC is a `space' or `image' specification, and in some other
4688 cases too, set *POSITION to the position where the `display'
4689 property ends.
4690
4691 If IT is NULL, only examine the property specification in SPEC, but
4692 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4693 is intended to be displayed in a window on a GUI frame.
4694
4695 Value is non-zero if something was found which replaces the display
4696 of buffer or string text. */
4697
4698 static int
4699 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4700 Lisp_Object overlay, struct text_pos *position,
4701 ptrdiff_t bufpos, int display_replaced_p,
4702 int frame_window_p)
4703 {
4704 Lisp_Object form;
4705 Lisp_Object location, value;
4706 struct text_pos start_pos = *position;
4707 int valid_p;
4708
4709 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4710 If the result is non-nil, use VALUE instead of SPEC. */
4711 form = Qt;
4712 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4713 {
4714 spec = XCDR (spec);
4715 if (!CONSP (spec))
4716 return 0;
4717 form = XCAR (spec);
4718 spec = XCDR (spec);
4719 }
4720
4721 if (!NILP (form) && !EQ (form, Qt))
4722 {
4723 ptrdiff_t count = SPECPDL_INDEX ();
4724 struct gcpro gcpro1;
4725
4726 /* Bind `object' to the object having the `display' property, a
4727 buffer or string. Bind `position' to the position in the
4728 object where the property was found, and `buffer-position'
4729 to the current position in the buffer. */
4730
4731 if (NILP (object))
4732 XSETBUFFER (object, current_buffer);
4733 specbind (Qobject, object);
4734 specbind (Qposition, make_number (CHARPOS (*position)));
4735 specbind (Qbuffer_position, make_number (bufpos));
4736 GCPRO1 (form);
4737 form = safe_eval (form);
4738 UNGCPRO;
4739 unbind_to (count, Qnil);
4740 }
4741
4742 if (NILP (form))
4743 return 0;
4744
4745 /* Handle `(height HEIGHT)' specifications. */
4746 if (CONSP (spec)
4747 && EQ (XCAR (spec), Qheight)
4748 && CONSP (XCDR (spec)))
4749 {
4750 if (it)
4751 {
4752 if (!FRAME_WINDOW_P (it->f))
4753 return 0;
4754
4755 it->font_height = XCAR (XCDR (spec));
4756 if (!NILP (it->font_height))
4757 {
4758 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4759 int new_height = -1;
4760
4761 if (CONSP (it->font_height)
4762 && (EQ (XCAR (it->font_height), Qplus)
4763 || EQ (XCAR (it->font_height), Qminus))
4764 && CONSP (XCDR (it->font_height))
4765 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4766 {
4767 /* `(+ N)' or `(- N)' where N is an integer. */
4768 int steps = XINT (XCAR (XCDR (it->font_height)));
4769 if (EQ (XCAR (it->font_height), Qplus))
4770 steps = - steps;
4771 it->face_id = smaller_face (it->f, it->face_id, steps);
4772 }
4773 else if (FUNCTIONP (it->font_height))
4774 {
4775 /* Call function with current height as argument.
4776 Value is the new height. */
4777 Lisp_Object height;
4778 height = safe_call1 (it->font_height,
4779 face->lface[LFACE_HEIGHT_INDEX]);
4780 if (NUMBERP (height))
4781 new_height = XFLOATINT (height);
4782 }
4783 else if (NUMBERP (it->font_height))
4784 {
4785 /* Value is a multiple of the canonical char height. */
4786 struct face *f;
4787
4788 f = FACE_FROM_ID (it->f,
4789 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4790 new_height = (XFLOATINT (it->font_height)
4791 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4792 }
4793 else
4794 {
4795 /* Evaluate IT->font_height with `height' bound to the
4796 current specified height to get the new height. */
4797 ptrdiff_t count = SPECPDL_INDEX ();
4798
4799 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4800 value = safe_eval (it->font_height);
4801 unbind_to (count, Qnil);
4802
4803 if (NUMBERP (value))
4804 new_height = XFLOATINT (value);
4805 }
4806
4807 if (new_height > 0)
4808 it->face_id = face_with_height (it->f, it->face_id, new_height);
4809 }
4810 }
4811
4812 return 0;
4813 }
4814
4815 /* Handle `(space-width WIDTH)'. */
4816 if (CONSP (spec)
4817 && EQ (XCAR (spec), Qspace_width)
4818 && CONSP (XCDR (spec)))
4819 {
4820 if (it)
4821 {
4822 if (!FRAME_WINDOW_P (it->f))
4823 return 0;
4824
4825 value = XCAR (XCDR (spec));
4826 if (NUMBERP (value) && XFLOATINT (value) > 0)
4827 it->space_width = value;
4828 }
4829
4830 return 0;
4831 }
4832
4833 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4834 if (CONSP (spec)
4835 && EQ (XCAR (spec), Qslice))
4836 {
4837 Lisp_Object tem;
4838
4839 if (it)
4840 {
4841 if (!FRAME_WINDOW_P (it->f))
4842 return 0;
4843
4844 if (tem = XCDR (spec), CONSP (tem))
4845 {
4846 it->slice.x = XCAR (tem);
4847 if (tem = XCDR (tem), CONSP (tem))
4848 {
4849 it->slice.y = XCAR (tem);
4850 if (tem = XCDR (tem), CONSP (tem))
4851 {
4852 it->slice.width = XCAR (tem);
4853 if (tem = XCDR (tem), CONSP (tem))
4854 it->slice.height = XCAR (tem);
4855 }
4856 }
4857 }
4858 }
4859
4860 return 0;
4861 }
4862
4863 /* Handle `(raise FACTOR)'. */
4864 if (CONSP (spec)
4865 && EQ (XCAR (spec), Qraise)
4866 && CONSP (XCDR (spec)))
4867 {
4868 if (it)
4869 {
4870 if (!FRAME_WINDOW_P (it->f))
4871 return 0;
4872
4873 #ifdef HAVE_WINDOW_SYSTEM
4874 value = XCAR (XCDR (spec));
4875 if (NUMBERP (value))
4876 {
4877 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4878 it->voffset = - (XFLOATINT (value)
4879 * (FONT_HEIGHT (face->font)));
4880 }
4881 #endif /* HAVE_WINDOW_SYSTEM */
4882 }
4883
4884 return 0;
4885 }
4886
4887 /* Don't handle the other kinds of display specifications
4888 inside a string that we got from a `display' property. */
4889 if (it && it->string_from_display_prop_p)
4890 return 0;
4891
4892 /* Characters having this form of property are not displayed, so
4893 we have to find the end of the property. */
4894 if (it)
4895 {
4896 start_pos = *position;
4897 *position = display_prop_end (it, object, start_pos);
4898 }
4899 value = Qnil;
4900
4901 /* Stop the scan at that end position--we assume that all
4902 text properties change there. */
4903 if (it)
4904 it->stop_charpos = position->charpos;
4905
4906 /* Handle `(left-fringe BITMAP [FACE])'
4907 and `(right-fringe BITMAP [FACE])'. */
4908 if (CONSP (spec)
4909 && (EQ (XCAR (spec), Qleft_fringe)
4910 || EQ (XCAR (spec), Qright_fringe))
4911 && CONSP (XCDR (spec)))
4912 {
4913 int fringe_bitmap;
4914
4915 if (it)
4916 {
4917 if (!FRAME_WINDOW_P (it->f))
4918 /* If we return here, POSITION has been advanced
4919 across the text with this property. */
4920 {
4921 /* Synchronize the bidi iterator with POSITION. This is
4922 needed because we are not going to push the iterator
4923 on behalf of this display property, so there will be
4924 no pop_it call to do this synchronization for us. */
4925 if (it->bidi_p)
4926 {
4927 it->position = *position;
4928 iterate_out_of_display_property (it);
4929 *position = it->position;
4930 }
4931 return 1;
4932 }
4933 }
4934 else if (!frame_window_p)
4935 return 1;
4936
4937 #ifdef HAVE_WINDOW_SYSTEM
4938 value = XCAR (XCDR (spec));
4939 if (!SYMBOLP (value)
4940 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4941 /* If we return here, POSITION has been advanced
4942 across the text with this property. */
4943 {
4944 if (it && it->bidi_p)
4945 {
4946 it->position = *position;
4947 iterate_out_of_display_property (it);
4948 *position = it->position;
4949 }
4950 return 1;
4951 }
4952
4953 if (it)
4954 {
4955 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4956
4957 if (CONSP (XCDR (XCDR (spec))))
4958 {
4959 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4960 int face_id2 = lookup_derived_face (it->f, face_name,
4961 FRINGE_FACE_ID, 0);
4962 if (face_id2 >= 0)
4963 face_id = face_id2;
4964 }
4965
4966 /* Save current settings of IT so that we can restore them
4967 when we are finished with the glyph property value. */
4968 push_it (it, position);
4969
4970 it->area = TEXT_AREA;
4971 it->what = IT_IMAGE;
4972 it->image_id = -1; /* no image */
4973 it->position = start_pos;
4974 it->object = NILP (object) ? it->w->contents : object;
4975 it->method = GET_FROM_IMAGE;
4976 it->from_overlay = Qnil;
4977 it->face_id = face_id;
4978 it->from_disp_prop_p = 1;
4979
4980 /* Say that we haven't consumed the characters with
4981 `display' property yet. The call to pop_it in
4982 set_iterator_to_next will clean this up. */
4983 *position = start_pos;
4984
4985 if (EQ (XCAR (spec), Qleft_fringe))
4986 {
4987 it->left_user_fringe_bitmap = fringe_bitmap;
4988 it->left_user_fringe_face_id = face_id;
4989 }
4990 else
4991 {
4992 it->right_user_fringe_bitmap = fringe_bitmap;
4993 it->right_user_fringe_face_id = face_id;
4994 }
4995 }
4996 #endif /* HAVE_WINDOW_SYSTEM */
4997 return 1;
4998 }
4999
5000 /* Prepare to handle `((margin left-margin) ...)',
5001 `((margin right-margin) ...)' and `((margin nil) ...)'
5002 prefixes for display specifications. */
5003 location = Qunbound;
5004 if (CONSP (spec) && CONSP (XCAR (spec)))
5005 {
5006 Lisp_Object tem;
5007
5008 value = XCDR (spec);
5009 if (CONSP (value))
5010 value = XCAR (value);
5011
5012 tem = XCAR (spec);
5013 if (EQ (XCAR (tem), Qmargin)
5014 && (tem = XCDR (tem),
5015 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5016 (NILP (tem)
5017 || EQ (tem, Qleft_margin)
5018 || EQ (tem, Qright_margin))))
5019 location = tem;
5020 }
5021
5022 if (EQ (location, Qunbound))
5023 {
5024 location = Qnil;
5025 value = spec;
5026 }
5027
5028 /* After this point, VALUE is the property after any
5029 margin prefix has been stripped. It must be a string,
5030 an image specification, or `(space ...)'.
5031
5032 LOCATION specifies where to display: `left-margin',
5033 `right-margin' or nil. */
5034
5035 valid_p = (STRINGP (value)
5036 #ifdef HAVE_WINDOW_SYSTEM
5037 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5038 && valid_image_p (value))
5039 #endif /* not HAVE_WINDOW_SYSTEM */
5040 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5041
5042 if (valid_p && !display_replaced_p)
5043 {
5044 int retval = 1;
5045
5046 if (!it)
5047 {
5048 /* Callers need to know whether the display spec is any kind
5049 of `(space ...)' spec that is about to affect text-area
5050 display. */
5051 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5052 retval = 2;
5053 return retval;
5054 }
5055
5056 /* Save current settings of IT so that we can restore them
5057 when we are finished with the glyph property value. */
5058 push_it (it, position);
5059 it->from_overlay = overlay;
5060 it->from_disp_prop_p = 1;
5061
5062 if (NILP (location))
5063 it->area = TEXT_AREA;
5064 else if (EQ (location, Qleft_margin))
5065 it->area = LEFT_MARGIN_AREA;
5066 else
5067 it->area = RIGHT_MARGIN_AREA;
5068
5069 if (STRINGP (value))
5070 {
5071 it->string = value;
5072 it->multibyte_p = STRING_MULTIBYTE (it->string);
5073 it->current.overlay_string_index = -1;
5074 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5075 it->end_charpos = it->string_nchars = SCHARS (it->string);
5076 it->method = GET_FROM_STRING;
5077 it->stop_charpos = 0;
5078 it->prev_stop = 0;
5079 it->base_level_stop = 0;
5080 it->string_from_display_prop_p = 1;
5081 /* Say that we haven't consumed the characters with
5082 `display' property yet. The call to pop_it in
5083 set_iterator_to_next will clean this up. */
5084 if (BUFFERP (object))
5085 *position = start_pos;
5086
5087 /* Force paragraph direction to be that of the parent
5088 object. If the parent object's paragraph direction is
5089 not yet determined, default to L2R. */
5090 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5091 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5092 else
5093 it->paragraph_embedding = L2R;
5094
5095 /* Set up the bidi iterator for this display string. */
5096 if (it->bidi_p)
5097 {
5098 it->bidi_it.string.lstring = it->string;
5099 it->bidi_it.string.s = NULL;
5100 it->bidi_it.string.schars = it->end_charpos;
5101 it->bidi_it.string.bufpos = bufpos;
5102 it->bidi_it.string.from_disp_str = 1;
5103 it->bidi_it.string.unibyte = !it->multibyte_p;
5104 it->bidi_it.w = it->w;
5105 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5106 }
5107 }
5108 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5109 {
5110 it->method = GET_FROM_STRETCH;
5111 it->object = value;
5112 *position = it->position = start_pos;
5113 retval = 1 + (it->area == TEXT_AREA);
5114 }
5115 #ifdef HAVE_WINDOW_SYSTEM
5116 else
5117 {
5118 it->what = IT_IMAGE;
5119 it->image_id = lookup_image (it->f, value);
5120 it->position = start_pos;
5121 it->object = NILP (object) ? it->w->contents : object;
5122 it->method = GET_FROM_IMAGE;
5123
5124 /* Say that we haven't consumed the characters with
5125 `display' property yet. The call to pop_it in
5126 set_iterator_to_next will clean this up. */
5127 *position = start_pos;
5128 }
5129 #endif /* HAVE_WINDOW_SYSTEM */
5130
5131 return retval;
5132 }
5133
5134 /* Invalid property or property not supported. Restore
5135 POSITION to what it was before. */
5136 *position = start_pos;
5137 return 0;
5138 }
5139
5140 /* Check if PROP is a display property value whose text should be
5141 treated as intangible. OVERLAY is the overlay from which PROP
5142 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5143 specify the buffer position covered by PROP. */
5144
5145 int
5146 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5147 ptrdiff_t charpos, ptrdiff_t bytepos)
5148 {
5149 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5150 struct text_pos position;
5151
5152 SET_TEXT_POS (position, charpos, bytepos);
5153 return handle_display_spec (NULL, prop, Qnil, overlay,
5154 &position, charpos, frame_window_p);
5155 }
5156
5157
5158 /* Return 1 if PROP is a display sub-property value containing STRING.
5159
5160 Implementation note: this and the following function are really
5161 special cases of handle_display_spec and
5162 handle_single_display_spec, and should ideally use the same code.
5163 Until they do, these two pairs must be consistent and must be
5164 modified in sync. */
5165
5166 static int
5167 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5168 {
5169 if (EQ (string, prop))
5170 return 1;
5171
5172 /* Skip over `when FORM'. */
5173 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5174 {
5175 prop = XCDR (prop);
5176 if (!CONSP (prop))
5177 return 0;
5178 /* Actually, the condition following `when' should be eval'ed,
5179 like handle_single_display_spec does, and we should return
5180 zero if it evaluates to nil. However, this function is
5181 called only when the buffer was already displayed and some
5182 glyph in the glyph matrix was found to come from a display
5183 string. Therefore, the condition was already evaluated, and
5184 the result was non-nil, otherwise the display string wouldn't
5185 have been displayed and we would have never been called for
5186 this property. Thus, we can skip the evaluation and assume
5187 its result is non-nil. */
5188 prop = XCDR (prop);
5189 }
5190
5191 if (CONSP (prop))
5192 /* Skip over `margin LOCATION'. */
5193 if (EQ (XCAR (prop), Qmargin))
5194 {
5195 prop = XCDR (prop);
5196 if (!CONSP (prop))
5197 return 0;
5198
5199 prop = XCDR (prop);
5200 if (!CONSP (prop))
5201 return 0;
5202 }
5203
5204 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5205 }
5206
5207
5208 /* Return 1 if STRING appears in the `display' property PROP. */
5209
5210 static int
5211 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5212 {
5213 if (CONSP (prop)
5214 && !EQ (XCAR (prop), Qwhen)
5215 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5216 {
5217 /* A list of sub-properties. */
5218 while (CONSP (prop))
5219 {
5220 if (single_display_spec_string_p (XCAR (prop), string))
5221 return 1;
5222 prop = XCDR (prop);
5223 }
5224 }
5225 else if (VECTORP (prop))
5226 {
5227 /* A vector of sub-properties. */
5228 ptrdiff_t i;
5229 for (i = 0; i < ASIZE (prop); ++i)
5230 if (single_display_spec_string_p (AREF (prop, i), string))
5231 return 1;
5232 }
5233 else
5234 return single_display_spec_string_p (prop, string);
5235
5236 return 0;
5237 }
5238
5239 /* Look for STRING in overlays and text properties in the current
5240 buffer, between character positions FROM and TO (excluding TO).
5241 BACK_P non-zero means look back (in this case, TO is supposed to be
5242 less than FROM).
5243 Value is the first character position where STRING was found, or
5244 zero if it wasn't found before hitting TO.
5245
5246 This function may only use code that doesn't eval because it is
5247 called asynchronously from note_mouse_highlight. */
5248
5249 static ptrdiff_t
5250 string_buffer_position_lim (Lisp_Object string,
5251 ptrdiff_t from, ptrdiff_t to, int back_p)
5252 {
5253 Lisp_Object limit, prop, pos;
5254 int found = 0;
5255
5256 pos = make_number (max (from, BEGV));
5257
5258 if (!back_p) /* looking forward */
5259 {
5260 limit = make_number (min (to, ZV));
5261 while (!found && !EQ (pos, limit))
5262 {
5263 prop = Fget_char_property (pos, Qdisplay, Qnil);
5264 if (!NILP (prop) && display_prop_string_p (prop, string))
5265 found = 1;
5266 else
5267 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5268 limit);
5269 }
5270 }
5271 else /* looking back */
5272 {
5273 limit = make_number (max (to, BEGV));
5274 while (!found && !EQ (pos, limit))
5275 {
5276 prop = Fget_char_property (pos, Qdisplay, Qnil);
5277 if (!NILP (prop) && display_prop_string_p (prop, string))
5278 found = 1;
5279 else
5280 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5281 limit);
5282 }
5283 }
5284
5285 return found ? XINT (pos) : 0;
5286 }
5287
5288 /* Determine which buffer position in current buffer STRING comes from.
5289 AROUND_CHARPOS is an approximate position where it could come from.
5290 Value is the buffer position or 0 if it couldn't be determined.
5291
5292 This function is necessary because we don't record buffer positions
5293 in glyphs generated from strings (to keep struct glyph small).
5294 This function may only use code that doesn't eval because it is
5295 called asynchronously from note_mouse_highlight. */
5296
5297 static ptrdiff_t
5298 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5299 {
5300 const int MAX_DISTANCE = 1000;
5301 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5302 around_charpos + MAX_DISTANCE,
5303 0);
5304
5305 if (!found)
5306 found = string_buffer_position_lim (string, around_charpos,
5307 around_charpos - MAX_DISTANCE, 1);
5308 return found;
5309 }
5310
5311
5312 \f
5313 /***********************************************************************
5314 `composition' property
5315 ***********************************************************************/
5316
5317 /* Set up iterator IT from `composition' property at its current
5318 position. Called from handle_stop. */
5319
5320 static enum prop_handled
5321 handle_composition_prop (struct it *it)
5322 {
5323 Lisp_Object prop, string;
5324 ptrdiff_t pos, pos_byte, start, end;
5325
5326 if (STRINGP (it->string))
5327 {
5328 unsigned char *s;
5329
5330 pos = IT_STRING_CHARPOS (*it);
5331 pos_byte = IT_STRING_BYTEPOS (*it);
5332 string = it->string;
5333 s = SDATA (string) + pos_byte;
5334 it->c = STRING_CHAR (s);
5335 }
5336 else
5337 {
5338 pos = IT_CHARPOS (*it);
5339 pos_byte = IT_BYTEPOS (*it);
5340 string = Qnil;
5341 it->c = FETCH_CHAR (pos_byte);
5342 }
5343
5344 /* If there's a valid composition and point is not inside of the
5345 composition (in the case that the composition is from the current
5346 buffer), draw a glyph composed from the composition components. */
5347 if (find_composition (pos, -1, &start, &end, &prop, string)
5348 && composition_valid_p (start, end, prop)
5349 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5350 {
5351 if (start < pos)
5352 /* As we can't handle this situation (perhaps font-lock added
5353 a new composition), we just return here hoping that next
5354 redisplay will detect this composition much earlier. */
5355 return HANDLED_NORMALLY;
5356 if (start != pos)
5357 {
5358 if (STRINGP (it->string))
5359 pos_byte = string_char_to_byte (it->string, start);
5360 else
5361 pos_byte = CHAR_TO_BYTE (start);
5362 }
5363 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5364 prop, string);
5365
5366 if (it->cmp_it.id >= 0)
5367 {
5368 it->cmp_it.ch = -1;
5369 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5370 it->cmp_it.nglyphs = -1;
5371 }
5372 }
5373
5374 return HANDLED_NORMALLY;
5375 }
5376
5377
5378 \f
5379 /***********************************************************************
5380 Overlay strings
5381 ***********************************************************************/
5382
5383 /* The following structure is used to record overlay strings for
5384 later sorting in load_overlay_strings. */
5385
5386 struct overlay_entry
5387 {
5388 Lisp_Object overlay;
5389 Lisp_Object string;
5390 EMACS_INT priority;
5391 int after_string_p;
5392 };
5393
5394
5395 /* Set up iterator IT from overlay strings at its current position.
5396 Called from handle_stop. */
5397
5398 static enum prop_handled
5399 handle_overlay_change (struct it *it)
5400 {
5401 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5402 return HANDLED_RECOMPUTE_PROPS;
5403 else
5404 return HANDLED_NORMALLY;
5405 }
5406
5407
5408 /* Set up the next overlay string for delivery by IT, if there is an
5409 overlay string to deliver. Called by set_iterator_to_next when the
5410 end of the current overlay string is reached. If there are more
5411 overlay strings to display, IT->string and
5412 IT->current.overlay_string_index are set appropriately here.
5413 Otherwise IT->string is set to nil. */
5414
5415 static void
5416 next_overlay_string (struct it *it)
5417 {
5418 ++it->current.overlay_string_index;
5419 if (it->current.overlay_string_index == it->n_overlay_strings)
5420 {
5421 /* No more overlay strings. Restore IT's settings to what
5422 they were before overlay strings were processed, and
5423 continue to deliver from current_buffer. */
5424
5425 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5426 pop_it (it);
5427 eassert (it->sp > 0
5428 || (NILP (it->string)
5429 && it->method == GET_FROM_BUFFER
5430 && it->stop_charpos >= BEGV
5431 && it->stop_charpos <= it->end_charpos));
5432 it->current.overlay_string_index = -1;
5433 it->n_overlay_strings = 0;
5434 it->overlay_strings_charpos = -1;
5435 /* If there's an empty display string on the stack, pop the
5436 stack, to resync the bidi iterator with IT's position. Such
5437 empty strings are pushed onto the stack in
5438 get_overlay_strings_1. */
5439 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5440 pop_it (it);
5441
5442 /* If we're at the end of the buffer, record that we have
5443 processed the overlay strings there already, so that
5444 next_element_from_buffer doesn't try it again. */
5445 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5446 it->overlay_strings_at_end_processed_p = 1;
5447 }
5448 else
5449 {
5450 /* There are more overlay strings to process. If
5451 IT->current.overlay_string_index has advanced to a position
5452 where we must load IT->overlay_strings with more strings, do
5453 it. We must load at the IT->overlay_strings_charpos where
5454 IT->n_overlay_strings was originally computed; when invisible
5455 text is present, this might not be IT_CHARPOS (Bug#7016). */
5456 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5457
5458 if (it->current.overlay_string_index && i == 0)
5459 load_overlay_strings (it, it->overlay_strings_charpos);
5460
5461 /* Initialize IT to deliver display elements from the overlay
5462 string. */
5463 it->string = it->overlay_strings[i];
5464 it->multibyte_p = STRING_MULTIBYTE (it->string);
5465 SET_TEXT_POS (it->current.string_pos, 0, 0);
5466 it->method = GET_FROM_STRING;
5467 it->stop_charpos = 0;
5468 it->end_charpos = SCHARS (it->string);
5469 if (it->cmp_it.stop_pos >= 0)
5470 it->cmp_it.stop_pos = 0;
5471 it->prev_stop = 0;
5472 it->base_level_stop = 0;
5473
5474 /* Set up the bidi iterator for this overlay string. */
5475 if (it->bidi_p)
5476 {
5477 it->bidi_it.string.lstring = it->string;
5478 it->bidi_it.string.s = NULL;
5479 it->bidi_it.string.schars = SCHARS (it->string);
5480 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5481 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5482 it->bidi_it.string.unibyte = !it->multibyte_p;
5483 it->bidi_it.w = it->w;
5484 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5485 }
5486 }
5487
5488 CHECK_IT (it);
5489 }
5490
5491
5492 /* Compare two overlay_entry structures E1 and E2. Used as a
5493 comparison function for qsort in load_overlay_strings. Overlay
5494 strings for the same position are sorted so that
5495
5496 1. All after-strings come in front of before-strings, except
5497 when they come from the same overlay.
5498
5499 2. Within after-strings, strings are sorted so that overlay strings
5500 from overlays with higher priorities come first.
5501
5502 2. Within before-strings, strings are sorted so that overlay
5503 strings from overlays with higher priorities come last.
5504
5505 Value is analogous to strcmp. */
5506
5507
5508 static int
5509 compare_overlay_entries (const void *e1, const void *e2)
5510 {
5511 struct overlay_entry const *entry1 = e1;
5512 struct overlay_entry const *entry2 = e2;
5513 int result;
5514
5515 if (entry1->after_string_p != entry2->after_string_p)
5516 {
5517 /* Let after-strings appear in front of before-strings if
5518 they come from different overlays. */
5519 if (EQ (entry1->overlay, entry2->overlay))
5520 result = entry1->after_string_p ? 1 : -1;
5521 else
5522 result = entry1->after_string_p ? -1 : 1;
5523 }
5524 else if (entry1->priority != entry2->priority)
5525 {
5526 if (entry1->after_string_p)
5527 /* After-strings sorted in order of decreasing priority. */
5528 result = entry2->priority < entry1->priority ? -1 : 1;
5529 else
5530 /* Before-strings sorted in order of increasing priority. */
5531 result = entry1->priority < entry2->priority ? -1 : 1;
5532 }
5533 else
5534 result = 0;
5535
5536 return result;
5537 }
5538
5539
5540 /* Load the vector IT->overlay_strings with overlay strings from IT's
5541 current buffer position, or from CHARPOS if that is > 0. Set
5542 IT->n_overlays to the total number of overlay strings found.
5543
5544 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5545 a time. On entry into load_overlay_strings,
5546 IT->current.overlay_string_index gives the number of overlay
5547 strings that have already been loaded by previous calls to this
5548 function.
5549
5550 IT->add_overlay_start contains an additional overlay start
5551 position to consider for taking overlay strings from, if non-zero.
5552 This position comes into play when the overlay has an `invisible'
5553 property, and both before and after-strings. When we've skipped to
5554 the end of the overlay, because of its `invisible' property, we
5555 nevertheless want its before-string to appear.
5556 IT->add_overlay_start will contain the overlay start position
5557 in this case.
5558
5559 Overlay strings are sorted so that after-string strings come in
5560 front of before-string strings. Within before and after-strings,
5561 strings are sorted by overlay priority. See also function
5562 compare_overlay_entries. */
5563
5564 static void
5565 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5566 {
5567 Lisp_Object overlay, window, str, invisible;
5568 struct Lisp_Overlay *ov;
5569 ptrdiff_t start, end;
5570 ptrdiff_t size = 20;
5571 ptrdiff_t n = 0, i, j;
5572 int invis_p;
5573 struct overlay_entry *entries = alloca (size * sizeof *entries);
5574 USE_SAFE_ALLOCA;
5575
5576 if (charpos <= 0)
5577 charpos = IT_CHARPOS (*it);
5578
5579 /* Append the overlay string STRING of overlay OVERLAY to vector
5580 `entries' which has size `size' and currently contains `n'
5581 elements. AFTER_P non-zero means STRING is an after-string of
5582 OVERLAY. */
5583 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5584 do \
5585 { \
5586 Lisp_Object priority; \
5587 \
5588 if (n == size) \
5589 { \
5590 struct overlay_entry *old = entries; \
5591 SAFE_NALLOCA (entries, 2, size); \
5592 memcpy (entries, old, size * sizeof *entries); \
5593 size *= 2; \
5594 } \
5595 \
5596 entries[n].string = (STRING); \
5597 entries[n].overlay = (OVERLAY); \
5598 priority = Foverlay_get ((OVERLAY), Qpriority); \
5599 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5600 entries[n].after_string_p = (AFTER_P); \
5601 ++n; \
5602 } \
5603 while (0)
5604
5605 /* Process overlay before the overlay center. */
5606 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5607 {
5608 XSETMISC (overlay, ov);
5609 eassert (OVERLAYP (overlay));
5610 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5611 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5612
5613 if (end < charpos)
5614 break;
5615
5616 /* Skip this overlay if it doesn't start or end at IT's current
5617 position. */
5618 if (end != charpos && start != charpos)
5619 continue;
5620
5621 /* Skip this overlay if it doesn't apply to IT->w. */
5622 window = Foverlay_get (overlay, Qwindow);
5623 if (WINDOWP (window) && XWINDOW (window) != it->w)
5624 continue;
5625
5626 /* If the text ``under'' the overlay is invisible, both before-
5627 and after-strings from this overlay are visible; start and
5628 end position are indistinguishable. */
5629 invisible = Foverlay_get (overlay, Qinvisible);
5630 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5631
5632 /* If overlay has a non-empty before-string, record it. */
5633 if ((start == charpos || (end == charpos && invis_p))
5634 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5635 && SCHARS (str))
5636 RECORD_OVERLAY_STRING (overlay, str, 0);
5637
5638 /* If overlay has a non-empty after-string, record it. */
5639 if ((end == charpos || (start == charpos && invis_p))
5640 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5641 && SCHARS (str))
5642 RECORD_OVERLAY_STRING (overlay, str, 1);
5643 }
5644
5645 /* Process overlays after the overlay center. */
5646 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5647 {
5648 XSETMISC (overlay, ov);
5649 eassert (OVERLAYP (overlay));
5650 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5651 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5652
5653 if (start > charpos)
5654 break;
5655
5656 /* Skip this overlay if it doesn't start or end at IT's current
5657 position. */
5658 if (end != charpos && start != charpos)
5659 continue;
5660
5661 /* Skip this overlay if it doesn't apply to IT->w. */
5662 window = Foverlay_get (overlay, Qwindow);
5663 if (WINDOWP (window) && XWINDOW (window) != it->w)
5664 continue;
5665
5666 /* If the text ``under'' the overlay is invisible, it has a zero
5667 dimension, and both before- and after-strings apply. */
5668 invisible = Foverlay_get (overlay, Qinvisible);
5669 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5670
5671 /* If overlay has a non-empty before-string, record it. */
5672 if ((start == charpos || (end == charpos && invis_p))
5673 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5674 && SCHARS (str))
5675 RECORD_OVERLAY_STRING (overlay, str, 0);
5676
5677 /* If overlay has a non-empty after-string, record it. */
5678 if ((end == charpos || (start == charpos && invis_p))
5679 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5680 && SCHARS (str))
5681 RECORD_OVERLAY_STRING (overlay, str, 1);
5682 }
5683
5684 #undef RECORD_OVERLAY_STRING
5685
5686 /* Sort entries. */
5687 if (n > 1)
5688 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5689
5690 /* Record number of overlay strings, and where we computed it. */
5691 it->n_overlay_strings = n;
5692 it->overlay_strings_charpos = charpos;
5693
5694 /* IT->current.overlay_string_index is the number of overlay strings
5695 that have already been consumed by IT. Copy some of the
5696 remaining overlay strings to IT->overlay_strings. */
5697 i = 0;
5698 j = it->current.overlay_string_index;
5699 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5700 {
5701 it->overlay_strings[i] = entries[j].string;
5702 it->string_overlays[i++] = entries[j++].overlay;
5703 }
5704
5705 CHECK_IT (it);
5706 SAFE_FREE ();
5707 }
5708
5709
5710 /* Get the first chunk of overlay strings at IT's current buffer
5711 position, or at CHARPOS if that is > 0. Value is non-zero if at
5712 least one overlay string was found. */
5713
5714 static int
5715 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5716 {
5717 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5718 process. This fills IT->overlay_strings with strings, and sets
5719 IT->n_overlay_strings to the total number of strings to process.
5720 IT->pos.overlay_string_index has to be set temporarily to zero
5721 because load_overlay_strings needs this; it must be set to -1
5722 when no overlay strings are found because a zero value would
5723 indicate a position in the first overlay string. */
5724 it->current.overlay_string_index = 0;
5725 load_overlay_strings (it, charpos);
5726
5727 /* If we found overlay strings, set up IT to deliver display
5728 elements from the first one. Otherwise set up IT to deliver
5729 from current_buffer. */
5730 if (it->n_overlay_strings)
5731 {
5732 /* Make sure we know settings in current_buffer, so that we can
5733 restore meaningful values when we're done with the overlay
5734 strings. */
5735 if (compute_stop_p)
5736 compute_stop_pos (it);
5737 eassert (it->face_id >= 0);
5738
5739 /* Save IT's settings. They are restored after all overlay
5740 strings have been processed. */
5741 eassert (!compute_stop_p || it->sp == 0);
5742
5743 /* When called from handle_stop, there might be an empty display
5744 string loaded. In that case, don't bother saving it. But
5745 don't use this optimization with the bidi iterator, since we
5746 need the corresponding pop_it call to resync the bidi
5747 iterator's position with IT's position, after we are done
5748 with the overlay strings. (The corresponding call to pop_it
5749 in case of an empty display string is in
5750 next_overlay_string.) */
5751 if (!(!it->bidi_p
5752 && STRINGP (it->string) && !SCHARS (it->string)))
5753 push_it (it, NULL);
5754
5755 /* Set up IT to deliver display elements from the first overlay
5756 string. */
5757 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5758 it->string = it->overlay_strings[0];
5759 it->from_overlay = Qnil;
5760 it->stop_charpos = 0;
5761 eassert (STRINGP (it->string));
5762 it->end_charpos = SCHARS (it->string);
5763 it->prev_stop = 0;
5764 it->base_level_stop = 0;
5765 it->multibyte_p = STRING_MULTIBYTE (it->string);
5766 it->method = GET_FROM_STRING;
5767 it->from_disp_prop_p = 0;
5768
5769 /* Force paragraph direction to be that of the parent
5770 buffer. */
5771 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5772 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5773 else
5774 it->paragraph_embedding = L2R;
5775
5776 /* Set up the bidi iterator for this overlay string. */
5777 if (it->bidi_p)
5778 {
5779 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5780
5781 it->bidi_it.string.lstring = it->string;
5782 it->bidi_it.string.s = NULL;
5783 it->bidi_it.string.schars = SCHARS (it->string);
5784 it->bidi_it.string.bufpos = pos;
5785 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5786 it->bidi_it.string.unibyte = !it->multibyte_p;
5787 it->bidi_it.w = it->w;
5788 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5789 }
5790 return 1;
5791 }
5792
5793 it->current.overlay_string_index = -1;
5794 return 0;
5795 }
5796
5797 static int
5798 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5799 {
5800 it->string = Qnil;
5801 it->method = GET_FROM_BUFFER;
5802
5803 (void) get_overlay_strings_1 (it, charpos, 1);
5804
5805 CHECK_IT (it);
5806
5807 /* Value is non-zero if we found at least one overlay string. */
5808 return STRINGP (it->string);
5809 }
5810
5811
5812 \f
5813 /***********************************************************************
5814 Saving and restoring state
5815 ***********************************************************************/
5816
5817 /* Save current settings of IT on IT->stack. Called, for example,
5818 before setting up IT for an overlay string, to be able to restore
5819 IT's settings to what they were after the overlay string has been
5820 processed. If POSITION is non-NULL, it is the position to save on
5821 the stack instead of IT->position. */
5822
5823 static void
5824 push_it (struct it *it, struct text_pos *position)
5825 {
5826 struct iterator_stack_entry *p;
5827
5828 eassert (it->sp < IT_STACK_SIZE);
5829 p = it->stack + it->sp;
5830
5831 p->stop_charpos = it->stop_charpos;
5832 p->prev_stop = it->prev_stop;
5833 p->base_level_stop = it->base_level_stop;
5834 p->cmp_it = it->cmp_it;
5835 eassert (it->face_id >= 0);
5836 p->face_id = it->face_id;
5837 p->string = it->string;
5838 p->method = it->method;
5839 p->from_overlay = it->from_overlay;
5840 switch (p->method)
5841 {
5842 case GET_FROM_IMAGE:
5843 p->u.image.object = it->object;
5844 p->u.image.image_id = it->image_id;
5845 p->u.image.slice = it->slice;
5846 break;
5847 case GET_FROM_STRETCH:
5848 p->u.stretch.object = it->object;
5849 break;
5850 }
5851 p->position = position ? *position : it->position;
5852 p->current = it->current;
5853 p->end_charpos = it->end_charpos;
5854 p->string_nchars = it->string_nchars;
5855 p->area = it->area;
5856 p->multibyte_p = it->multibyte_p;
5857 p->avoid_cursor_p = it->avoid_cursor_p;
5858 p->space_width = it->space_width;
5859 p->font_height = it->font_height;
5860 p->voffset = it->voffset;
5861 p->string_from_display_prop_p = it->string_from_display_prop_p;
5862 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5863 p->display_ellipsis_p = 0;
5864 p->line_wrap = it->line_wrap;
5865 p->bidi_p = it->bidi_p;
5866 p->paragraph_embedding = it->paragraph_embedding;
5867 p->from_disp_prop_p = it->from_disp_prop_p;
5868 ++it->sp;
5869
5870 /* Save the state of the bidi iterator as well. */
5871 if (it->bidi_p)
5872 bidi_push_it (&it->bidi_it);
5873 }
5874
5875 static void
5876 iterate_out_of_display_property (struct it *it)
5877 {
5878 int buffer_p = !STRINGP (it->string);
5879 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5880 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5881
5882 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5883
5884 /* Maybe initialize paragraph direction. If we are at the beginning
5885 of a new paragraph, next_element_from_buffer may not have a
5886 chance to do that. */
5887 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5888 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5889 /* prev_stop can be zero, so check against BEGV as well. */
5890 while (it->bidi_it.charpos >= bob
5891 && it->prev_stop <= it->bidi_it.charpos
5892 && it->bidi_it.charpos < CHARPOS (it->position)
5893 && it->bidi_it.charpos < eob)
5894 bidi_move_to_visually_next (&it->bidi_it);
5895 /* Record the stop_pos we just crossed, for when we cross it
5896 back, maybe. */
5897 if (it->bidi_it.charpos > CHARPOS (it->position))
5898 it->prev_stop = CHARPOS (it->position);
5899 /* If we ended up not where pop_it put us, resync IT's
5900 positional members with the bidi iterator. */
5901 if (it->bidi_it.charpos != CHARPOS (it->position))
5902 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5903 if (buffer_p)
5904 it->current.pos = it->position;
5905 else
5906 it->current.string_pos = it->position;
5907 }
5908
5909 /* Restore IT's settings from IT->stack. Called, for example, when no
5910 more overlay strings must be processed, and we return to delivering
5911 display elements from a buffer, or when the end of a string from a
5912 `display' property is reached and we return to delivering display
5913 elements from an overlay string, or from a buffer. */
5914
5915 static void
5916 pop_it (struct it *it)
5917 {
5918 struct iterator_stack_entry *p;
5919 int from_display_prop = it->from_disp_prop_p;
5920
5921 eassert (it->sp > 0);
5922 --it->sp;
5923 p = it->stack + it->sp;
5924 it->stop_charpos = p->stop_charpos;
5925 it->prev_stop = p->prev_stop;
5926 it->base_level_stop = p->base_level_stop;
5927 it->cmp_it = p->cmp_it;
5928 it->face_id = p->face_id;
5929 it->current = p->current;
5930 it->position = p->position;
5931 it->string = p->string;
5932 it->from_overlay = p->from_overlay;
5933 if (NILP (it->string))
5934 SET_TEXT_POS (it->current.string_pos, -1, -1);
5935 it->method = p->method;
5936 switch (it->method)
5937 {
5938 case GET_FROM_IMAGE:
5939 it->image_id = p->u.image.image_id;
5940 it->object = p->u.image.object;
5941 it->slice = p->u.image.slice;
5942 break;
5943 case GET_FROM_STRETCH:
5944 it->object = p->u.stretch.object;
5945 break;
5946 case GET_FROM_BUFFER:
5947 it->object = it->w->contents;
5948 break;
5949 case GET_FROM_STRING:
5950 it->object = it->string;
5951 break;
5952 case GET_FROM_DISPLAY_VECTOR:
5953 if (it->s)
5954 it->method = GET_FROM_C_STRING;
5955 else if (STRINGP (it->string))
5956 it->method = GET_FROM_STRING;
5957 else
5958 {
5959 it->method = GET_FROM_BUFFER;
5960 it->object = it->w->contents;
5961 }
5962 }
5963 it->end_charpos = p->end_charpos;
5964 it->string_nchars = p->string_nchars;
5965 it->area = p->area;
5966 it->multibyte_p = p->multibyte_p;
5967 it->avoid_cursor_p = p->avoid_cursor_p;
5968 it->space_width = p->space_width;
5969 it->font_height = p->font_height;
5970 it->voffset = p->voffset;
5971 it->string_from_display_prop_p = p->string_from_display_prop_p;
5972 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5973 it->line_wrap = p->line_wrap;
5974 it->bidi_p = p->bidi_p;
5975 it->paragraph_embedding = p->paragraph_embedding;
5976 it->from_disp_prop_p = p->from_disp_prop_p;
5977 if (it->bidi_p)
5978 {
5979 bidi_pop_it (&it->bidi_it);
5980 /* Bidi-iterate until we get out of the portion of text, if any,
5981 covered by a `display' text property or by an overlay with
5982 `display' property. (We cannot just jump there, because the
5983 internal coherency of the bidi iterator state can not be
5984 preserved across such jumps.) We also must determine the
5985 paragraph base direction if the overlay we just processed is
5986 at the beginning of a new paragraph. */
5987 if (from_display_prop
5988 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5989 iterate_out_of_display_property (it);
5990
5991 eassert ((BUFFERP (it->object)
5992 && IT_CHARPOS (*it) == it->bidi_it.charpos
5993 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5994 || (STRINGP (it->object)
5995 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5996 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5997 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5998 }
5999 }
6000
6001
6002 \f
6003 /***********************************************************************
6004 Moving over lines
6005 ***********************************************************************/
6006
6007 /* Set IT's current position to the previous line start. */
6008
6009 static void
6010 back_to_previous_line_start (struct it *it)
6011 {
6012 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6013
6014 DEC_BOTH (cp, bp);
6015 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6016 }
6017
6018
6019 /* Move IT to the next line start.
6020
6021 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6022 we skipped over part of the text (as opposed to moving the iterator
6023 continuously over the text). Otherwise, don't change the value
6024 of *SKIPPED_P.
6025
6026 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6027 iterator on the newline, if it was found.
6028
6029 Newlines may come from buffer text, overlay strings, or strings
6030 displayed via the `display' property. That's the reason we can't
6031 simply use find_newline_no_quit.
6032
6033 Note that this function may not skip over invisible text that is so
6034 because of text properties and immediately follows a newline. If
6035 it would, function reseat_at_next_visible_line_start, when called
6036 from set_iterator_to_next, would effectively make invisible
6037 characters following a newline part of the wrong glyph row, which
6038 leads to wrong cursor motion. */
6039
6040 static int
6041 forward_to_next_line_start (struct it *it, int *skipped_p,
6042 struct bidi_it *bidi_it_prev)
6043 {
6044 ptrdiff_t old_selective;
6045 int newline_found_p, n;
6046 const int MAX_NEWLINE_DISTANCE = 500;
6047
6048 /* If already on a newline, just consume it to avoid unintended
6049 skipping over invisible text below. */
6050 if (it->what == IT_CHARACTER
6051 && it->c == '\n'
6052 && CHARPOS (it->position) == IT_CHARPOS (*it))
6053 {
6054 if (it->bidi_p && bidi_it_prev)
6055 *bidi_it_prev = it->bidi_it;
6056 set_iterator_to_next (it, 0);
6057 it->c = 0;
6058 return 1;
6059 }
6060
6061 /* Don't handle selective display in the following. It's (a)
6062 unnecessary because it's done by the caller, and (b) leads to an
6063 infinite recursion because next_element_from_ellipsis indirectly
6064 calls this function. */
6065 old_selective = it->selective;
6066 it->selective = 0;
6067
6068 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6069 from buffer text. */
6070 for (n = newline_found_p = 0;
6071 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6072 n += STRINGP (it->string) ? 0 : 1)
6073 {
6074 if (!get_next_display_element (it))
6075 return 0;
6076 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6077 if (newline_found_p && it->bidi_p && bidi_it_prev)
6078 *bidi_it_prev = it->bidi_it;
6079 set_iterator_to_next (it, 0);
6080 }
6081
6082 /* If we didn't find a newline near enough, see if we can use a
6083 short-cut. */
6084 if (!newline_found_p)
6085 {
6086 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6087 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6088 1, &bytepos);
6089 Lisp_Object pos;
6090
6091 eassert (!STRINGP (it->string));
6092
6093 /* If there isn't any `display' property in sight, and no
6094 overlays, we can just use the position of the newline in
6095 buffer text. */
6096 if (it->stop_charpos >= limit
6097 || ((pos = Fnext_single_property_change (make_number (start),
6098 Qdisplay, Qnil,
6099 make_number (limit)),
6100 NILP (pos))
6101 && next_overlay_change (start) == ZV))
6102 {
6103 if (!it->bidi_p)
6104 {
6105 IT_CHARPOS (*it) = limit;
6106 IT_BYTEPOS (*it) = bytepos;
6107 }
6108 else
6109 {
6110 struct bidi_it bprev;
6111
6112 /* Help bidi.c avoid expensive searches for display
6113 properties and overlays, by telling it that there are
6114 none up to `limit'. */
6115 if (it->bidi_it.disp_pos < limit)
6116 {
6117 it->bidi_it.disp_pos = limit;
6118 it->bidi_it.disp_prop = 0;
6119 }
6120 do {
6121 bprev = it->bidi_it;
6122 bidi_move_to_visually_next (&it->bidi_it);
6123 } while (it->bidi_it.charpos != limit);
6124 IT_CHARPOS (*it) = limit;
6125 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6126 if (bidi_it_prev)
6127 *bidi_it_prev = bprev;
6128 }
6129 *skipped_p = newline_found_p = 1;
6130 }
6131 else
6132 {
6133 while (get_next_display_element (it)
6134 && !newline_found_p)
6135 {
6136 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6137 if (newline_found_p && it->bidi_p && bidi_it_prev)
6138 *bidi_it_prev = it->bidi_it;
6139 set_iterator_to_next (it, 0);
6140 }
6141 }
6142 }
6143
6144 it->selective = old_selective;
6145 return newline_found_p;
6146 }
6147
6148
6149 /* Set IT's current position to the previous visible line start. Skip
6150 invisible text that is so either due to text properties or due to
6151 selective display. Caution: this does not change IT->current_x and
6152 IT->hpos. */
6153
6154 static void
6155 back_to_previous_visible_line_start (struct it *it)
6156 {
6157 while (IT_CHARPOS (*it) > BEGV)
6158 {
6159 back_to_previous_line_start (it);
6160
6161 if (IT_CHARPOS (*it) <= BEGV)
6162 break;
6163
6164 /* If selective > 0, then lines indented more than its value are
6165 invisible. */
6166 if (it->selective > 0
6167 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6168 it->selective))
6169 continue;
6170
6171 /* Check the newline before point for invisibility. */
6172 {
6173 Lisp_Object prop;
6174 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6175 Qinvisible, it->window);
6176 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6177 continue;
6178 }
6179
6180 if (IT_CHARPOS (*it) <= BEGV)
6181 break;
6182
6183 {
6184 struct it it2;
6185 void *it2data = NULL;
6186 ptrdiff_t pos;
6187 ptrdiff_t beg, end;
6188 Lisp_Object val, overlay;
6189
6190 SAVE_IT (it2, *it, it2data);
6191
6192 /* If newline is part of a composition, continue from start of composition */
6193 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6194 && beg < IT_CHARPOS (*it))
6195 goto replaced;
6196
6197 /* If newline is replaced by a display property, find start of overlay
6198 or interval and continue search from that point. */
6199 pos = --IT_CHARPOS (it2);
6200 --IT_BYTEPOS (it2);
6201 it2.sp = 0;
6202 bidi_unshelve_cache (NULL, 0);
6203 it2.string_from_display_prop_p = 0;
6204 it2.from_disp_prop_p = 0;
6205 if (handle_display_prop (&it2) == HANDLED_RETURN
6206 && !NILP (val = get_char_property_and_overlay
6207 (make_number (pos), Qdisplay, Qnil, &overlay))
6208 && (OVERLAYP (overlay)
6209 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6210 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6211 {
6212 RESTORE_IT (it, it, it2data);
6213 goto replaced;
6214 }
6215
6216 /* Newline is not replaced by anything -- so we are done. */
6217 RESTORE_IT (it, it, it2data);
6218 break;
6219
6220 replaced:
6221 if (beg < BEGV)
6222 beg = BEGV;
6223 IT_CHARPOS (*it) = beg;
6224 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6225 }
6226 }
6227
6228 it->continuation_lines_width = 0;
6229
6230 eassert (IT_CHARPOS (*it) >= BEGV);
6231 eassert (IT_CHARPOS (*it) == BEGV
6232 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6233 CHECK_IT (it);
6234 }
6235
6236
6237 /* Reseat iterator IT at the previous visible line start. Skip
6238 invisible text that is so either due to text properties or due to
6239 selective display. At the end, update IT's overlay information,
6240 face information etc. */
6241
6242 void
6243 reseat_at_previous_visible_line_start (struct it *it)
6244 {
6245 back_to_previous_visible_line_start (it);
6246 reseat (it, it->current.pos, 1);
6247 CHECK_IT (it);
6248 }
6249
6250
6251 /* Reseat iterator IT on the next visible line start in the current
6252 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6253 preceding the line start. Skip over invisible text that is so
6254 because of selective display. Compute faces, overlays etc at the
6255 new position. Note that this function does not skip over text that
6256 is invisible because of text properties. */
6257
6258 static void
6259 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6260 {
6261 int newline_found_p, skipped_p = 0;
6262 struct bidi_it bidi_it_prev;
6263
6264 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6265
6266 /* Skip over lines that are invisible because they are indented
6267 more than the value of IT->selective. */
6268 if (it->selective > 0)
6269 while (IT_CHARPOS (*it) < ZV
6270 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6271 it->selective))
6272 {
6273 eassert (IT_BYTEPOS (*it) == BEGV
6274 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6275 newline_found_p =
6276 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6277 }
6278
6279 /* Position on the newline if that's what's requested. */
6280 if (on_newline_p && newline_found_p)
6281 {
6282 if (STRINGP (it->string))
6283 {
6284 if (IT_STRING_CHARPOS (*it) > 0)
6285 {
6286 if (!it->bidi_p)
6287 {
6288 --IT_STRING_CHARPOS (*it);
6289 --IT_STRING_BYTEPOS (*it);
6290 }
6291 else
6292 {
6293 /* We need to restore the bidi iterator to the state
6294 it had on the newline, and resync the IT's
6295 position with that. */
6296 it->bidi_it = bidi_it_prev;
6297 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6298 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6299 }
6300 }
6301 }
6302 else if (IT_CHARPOS (*it) > BEGV)
6303 {
6304 if (!it->bidi_p)
6305 {
6306 --IT_CHARPOS (*it);
6307 --IT_BYTEPOS (*it);
6308 }
6309 else
6310 {
6311 /* We need to restore the bidi iterator to the state it
6312 had on the newline and resync IT with that. */
6313 it->bidi_it = bidi_it_prev;
6314 IT_CHARPOS (*it) = it->bidi_it.charpos;
6315 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6316 }
6317 reseat (it, it->current.pos, 0);
6318 }
6319 }
6320 else if (skipped_p)
6321 reseat (it, it->current.pos, 0);
6322
6323 CHECK_IT (it);
6324 }
6325
6326
6327 \f
6328 /***********************************************************************
6329 Changing an iterator's position
6330 ***********************************************************************/
6331
6332 /* Change IT's current position to POS in current_buffer. If FORCE_P
6333 is non-zero, always check for text properties at the new position.
6334 Otherwise, text properties are only looked up if POS >=
6335 IT->check_charpos of a property. */
6336
6337 static void
6338 reseat (struct it *it, struct text_pos pos, int force_p)
6339 {
6340 ptrdiff_t original_pos = IT_CHARPOS (*it);
6341
6342 reseat_1 (it, pos, 0);
6343
6344 /* Determine where to check text properties. Avoid doing it
6345 where possible because text property lookup is very expensive. */
6346 if (force_p
6347 || CHARPOS (pos) > it->stop_charpos
6348 || CHARPOS (pos) < original_pos)
6349 {
6350 if (it->bidi_p)
6351 {
6352 /* For bidi iteration, we need to prime prev_stop and
6353 base_level_stop with our best estimations. */
6354 /* Implementation note: Of course, POS is not necessarily a
6355 stop position, so assigning prev_pos to it is a lie; we
6356 should have called compute_stop_backwards. However, if
6357 the current buffer does not include any R2L characters,
6358 that call would be a waste of cycles, because the
6359 iterator will never move back, and thus never cross this
6360 "fake" stop position. So we delay that backward search
6361 until the time we really need it, in next_element_from_buffer. */
6362 if (CHARPOS (pos) != it->prev_stop)
6363 it->prev_stop = CHARPOS (pos);
6364 if (CHARPOS (pos) < it->base_level_stop)
6365 it->base_level_stop = 0; /* meaning it's unknown */
6366 handle_stop (it);
6367 }
6368 else
6369 {
6370 handle_stop (it);
6371 it->prev_stop = it->base_level_stop = 0;
6372 }
6373
6374 }
6375
6376 CHECK_IT (it);
6377 }
6378
6379
6380 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6381 IT->stop_pos to POS, also. */
6382
6383 static void
6384 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6385 {
6386 /* Don't call this function when scanning a C string. */
6387 eassert (it->s == NULL);
6388
6389 /* POS must be a reasonable value. */
6390 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6391
6392 it->current.pos = it->position = pos;
6393 it->end_charpos = ZV;
6394 it->dpvec = NULL;
6395 it->current.dpvec_index = -1;
6396 it->current.overlay_string_index = -1;
6397 IT_STRING_CHARPOS (*it) = -1;
6398 IT_STRING_BYTEPOS (*it) = -1;
6399 it->string = Qnil;
6400 it->method = GET_FROM_BUFFER;
6401 it->object = it->w->contents;
6402 it->area = TEXT_AREA;
6403 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6404 it->sp = 0;
6405 it->string_from_display_prop_p = 0;
6406 it->string_from_prefix_prop_p = 0;
6407
6408 it->from_disp_prop_p = 0;
6409 it->face_before_selective_p = 0;
6410 if (it->bidi_p)
6411 {
6412 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6413 &it->bidi_it);
6414 bidi_unshelve_cache (NULL, 0);
6415 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6416 it->bidi_it.string.s = NULL;
6417 it->bidi_it.string.lstring = Qnil;
6418 it->bidi_it.string.bufpos = 0;
6419 it->bidi_it.string.unibyte = 0;
6420 it->bidi_it.w = it->w;
6421 }
6422
6423 if (set_stop_p)
6424 {
6425 it->stop_charpos = CHARPOS (pos);
6426 it->base_level_stop = CHARPOS (pos);
6427 }
6428 /* This make the information stored in it->cmp_it invalidate. */
6429 it->cmp_it.id = -1;
6430 }
6431
6432
6433 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6434 If S is non-null, it is a C string to iterate over. Otherwise,
6435 STRING gives a Lisp string to iterate over.
6436
6437 If PRECISION > 0, don't return more then PRECISION number of
6438 characters from the string.
6439
6440 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6441 characters have been returned. FIELD_WIDTH < 0 means an infinite
6442 field width.
6443
6444 MULTIBYTE = 0 means disable processing of multibyte characters,
6445 MULTIBYTE > 0 means enable it,
6446 MULTIBYTE < 0 means use IT->multibyte_p.
6447
6448 IT must be initialized via a prior call to init_iterator before
6449 calling this function. */
6450
6451 static void
6452 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6453 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6454 int multibyte)
6455 {
6456 /* No region in strings. */
6457 it->region_beg_charpos = it->region_end_charpos = -1;
6458
6459 /* No text property checks performed by default, but see below. */
6460 it->stop_charpos = -1;
6461
6462 /* Set iterator position and end position. */
6463 memset (&it->current, 0, sizeof it->current);
6464 it->current.overlay_string_index = -1;
6465 it->current.dpvec_index = -1;
6466 eassert (charpos >= 0);
6467
6468 /* If STRING is specified, use its multibyteness, otherwise use the
6469 setting of MULTIBYTE, if specified. */
6470 if (multibyte >= 0)
6471 it->multibyte_p = multibyte > 0;
6472
6473 /* Bidirectional reordering of strings is controlled by the default
6474 value of bidi-display-reordering. Don't try to reorder while
6475 loading loadup.el, as the necessary character property tables are
6476 not yet available. */
6477 it->bidi_p =
6478 NILP (Vpurify_flag)
6479 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6480
6481 if (s == NULL)
6482 {
6483 eassert (STRINGP (string));
6484 it->string = string;
6485 it->s = NULL;
6486 it->end_charpos = it->string_nchars = SCHARS (string);
6487 it->method = GET_FROM_STRING;
6488 it->current.string_pos = string_pos (charpos, string);
6489
6490 if (it->bidi_p)
6491 {
6492 it->bidi_it.string.lstring = string;
6493 it->bidi_it.string.s = NULL;
6494 it->bidi_it.string.schars = it->end_charpos;
6495 it->bidi_it.string.bufpos = 0;
6496 it->bidi_it.string.from_disp_str = 0;
6497 it->bidi_it.string.unibyte = !it->multibyte_p;
6498 it->bidi_it.w = it->w;
6499 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6500 FRAME_WINDOW_P (it->f), &it->bidi_it);
6501 }
6502 }
6503 else
6504 {
6505 it->s = (const unsigned char *) s;
6506 it->string = Qnil;
6507
6508 /* Note that we use IT->current.pos, not it->current.string_pos,
6509 for displaying C strings. */
6510 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6511 if (it->multibyte_p)
6512 {
6513 it->current.pos = c_string_pos (charpos, s, 1);
6514 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6515 }
6516 else
6517 {
6518 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6519 it->end_charpos = it->string_nchars = strlen (s);
6520 }
6521
6522 if (it->bidi_p)
6523 {
6524 it->bidi_it.string.lstring = Qnil;
6525 it->bidi_it.string.s = (const unsigned char *) s;
6526 it->bidi_it.string.schars = it->end_charpos;
6527 it->bidi_it.string.bufpos = 0;
6528 it->bidi_it.string.from_disp_str = 0;
6529 it->bidi_it.string.unibyte = !it->multibyte_p;
6530 it->bidi_it.w = it->w;
6531 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6532 &it->bidi_it);
6533 }
6534 it->method = GET_FROM_C_STRING;
6535 }
6536
6537 /* PRECISION > 0 means don't return more than PRECISION characters
6538 from the string. */
6539 if (precision > 0 && it->end_charpos - charpos > precision)
6540 {
6541 it->end_charpos = it->string_nchars = charpos + precision;
6542 if (it->bidi_p)
6543 it->bidi_it.string.schars = it->end_charpos;
6544 }
6545
6546 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6547 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6548 FIELD_WIDTH < 0 means infinite field width. This is useful for
6549 padding with `-' at the end of a mode line. */
6550 if (field_width < 0)
6551 field_width = INFINITY;
6552 /* Implementation note: We deliberately don't enlarge
6553 it->bidi_it.string.schars here to fit it->end_charpos, because
6554 the bidi iterator cannot produce characters out of thin air. */
6555 if (field_width > it->end_charpos - charpos)
6556 it->end_charpos = charpos + field_width;
6557
6558 /* Use the standard display table for displaying strings. */
6559 if (DISP_TABLE_P (Vstandard_display_table))
6560 it->dp = XCHAR_TABLE (Vstandard_display_table);
6561
6562 it->stop_charpos = charpos;
6563 it->prev_stop = charpos;
6564 it->base_level_stop = 0;
6565 if (it->bidi_p)
6566 {
6567 it->bidi_it.first_elt = 1;
6568 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6569 it->bidi_it.disp_pos = -1;
6570 }
6571 if (s == NULL && it->multibyte_p)
6572 {
6573 ptrdiff_t endpos = SCHARS (it->string);
6574 if (endpos > it->end_charpos)
6575 endpos = it->end_charpos;
6576 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6577 it->string);
6578 }
6579 CHECK_IT (it);
6580 }
6581
6582
6583 \f
6584 /***********************************************************************
6585 Iteration
6586 ***********************************************************************/
6587
6588 /* Map enum it_method value to corresponding next_element_from_* function. */
6589
6590 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6591 {
6592 next_element_from_buffer,
6593 next_element_from_display_vector,
6594 next_element_from_string,
6595 next_element_from_c_string,
6596 next_element_from_image,
6597 next_element_from_stretch
6598 };
6599
6600 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6601
6602
6603 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6604 (possibly with the following characters). */
6605
6606 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6607 ((IT)->cmp_it.id >= 0 \
6608 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6609 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6610 END_CHARPOS, (IT)->w, \
6611 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6612 (IT)->string)))
6613
6614
6615 /* Lookup the char-table Vglyphless_char_display for character C (-1
6616 if we want information for no-font case), and return the display
6617 method symbol. By side-effect, update it->what and
6618 it->glyphless_method. This function is called from
6619 get_next_display_element for each character element, and from
6620 x_produce_glyphs when no suitable font was found. */
6621
6622 Lisp_Object
6623 lookup_glyphless_char_display (int c, struct it *it)
6624 {
6625 Lisp_Object glyphless_method = Qnil;
6626
6627 if (CHAR_TABLE_P (Vglyphless_char_display)
6628 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6629 {
6630 if (c >= 0)
6631 {
6632 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6633 if (CONSP (glyphless_method))
6634 glyphless_method = FRAME_WINDOW_P (it->f)
6635 ? XCAR (glyphless_method)
6636 : XCDR (glyphless_method);
6637 }
6638 else
6639 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6640 }
6641
6642 retry:
6643 if (NILP (glyphless_method))
6644 {
6645 if (c >= 0)
6646 /* The default is to display the character by a proper font. */
6647 return Qnil;
6648 /* The default for the no-font case is to display an empty box. */
6649 glyphless_method = Qempty_box;
6650 }
6651 if (EQ (glyphless_method, Qzero_width))
6652 {
6653 if (c >= 0)
6654 return glyphless_method;
6655 /* This method can't be used for the no-font case. */
6656 glyphless_method = Qempty_box;
6657 }
6658 if (EQ (glyphless_method, Qthin_space))
6659 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6660 else if (EQ (glyphless_method, Qempty_box))
6661 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6662 else if (EQ (glyphless_method, Qhex_code))
6663 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6664 else if (STRINGP (glyphless_method))
6665 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6666 else
6667 {
6668 /* Invalid value. We use the default method. */
6669 glyphless_method = Qnil;
6670 goto retry;
6671 }
6672 it->what = IT_GLYPHLESS;
6673 return glyphless_method;
6674 }
6675
6676 /* Load IT's display element fields with information about the next
6677 display element from the current position of IT. Value is zero if
6678 end of buffer (or C string) is reached. */
6679
6680 static struct frame *last_escape_glyph_frame = NULL;
6681 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6682 static int last_escape_glyph_merged_face_id = 0;
6683
6684 struct frame *last_glyphless_glyph_frame = NULL;
6685 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6686 int last_glyphless_glyph_merged_face_id = 0;
6687
6688 static int
6689 get_next_display_element (struct it *it)
6690 {
6691 /* Non-zero means that we found a display element. Zero means that
6692 we hit the end of what we iterate over. Performance note: the
6693 function pointer `method' used here turns out to be faster than
6694 using a sequence of if-statements. */
6695 int success_p;
6696
6697 get_next:
6698 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6699
6700 if (it->what == IT_CHARACTER)
6701 {
6702 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6703 and only if (a) the resolved directionality of that character
6704 is R..." */
6705 /* FIXME: Do we need an exception for characters from display
6706 tables? */
6707 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6708 it->c = bidi_mirror_char (it->c);
6709 /* Map via display table or translate control characters.
6710 IT->c, IT->len etc. have been set to the next character by
6711 the function call above. If we have a display table, and it
6712 contains an entry for IT->c, translate it. Don't do this if
6713 IT->c itself comes from a display table, otherwise we could
6714 end up in an infinite recursion. (An alternative could be to
6715 count the recursion depth of this function and signal an
6716 error when a certain maximum depth is reached.) Is it worth
6717 it? */
6718 if (success_p && it->dpvec == NULL)
6719 {
6720 Lisp_Object dv;
6721 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6722 int nonascii_space_p = 0;
6723 int nonascii_hyphen_p = 0;
6724 int c = it->c; /* This is the character to display. */
6725
6726 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6727 {
6728 eassert (SINGLE_BYTE_CHAR_P (c));
6729 if (unibyte_display_via_language_environment)
6730 {
6731 c = DECODE_CHAR (unibyte, c);
6732 if (c < 0)
6733 c = BYTE8_TO_CHAR (it->c);
6734 }
6735 else
6736 c = BYTE8_TO_CHAR (it->c);
6737 }
6738
6739 if (it->dp
6740 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6741 VECTORP (dv)))
6742 {
6743 struct Lisp_Vector *v = XVECTOR (dv);
6744
6745 /* Return the first character from the display table
6746 entry, if not empty. If empty, don't display the
6747 current character. */
6748 if (v->header.size)
6749 {
6750 it->dpvec_char_len = it->len;
6751 it->dpvec = v->contents;
6752 it->dpend = v->contents + v->header.size;
6753 it->current.dpvec_index = 0;
6754 it->dpvec_face_id = -1;
6755 it->saved_face_id = it->face_id;
6756 it->method = GET_FROM_DISPLAY_VECTOR;
6757 it->ellipsis_p = 0;
6758 }
6759 else
6760 {
6761 set_iterator_to_next (it, 0);
6762 }
6763 goto get_next;
6764 }
6765
6766 if (! NILP (lookup_glyphless_char_display (c, it)))
6767 {
6768 if (it->what == IT_GLYPHLESS)
6769 goto done;
6770 /* Don't display this character. */
6771 set_iterator_to_next (it, 0);
6772 goto get_next;
6773 }
6774
6775 /* If `nobreak-char-display' is non-nil, we display
6776 non-ASCII spaces and hyphens specially. */
6777 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6778 {
6779 if (c == 0xA0)
6780 nonascii_space_p = 1;
6781 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6782 nonascii_hyphen_p = 1;
6783 }
6784
6785 /* Translate control characters into `\003' or `^C' form.
6786 Control characters coming from a display table entry are
6787 currently not translated because we use IT->dpvec to hold
6788 the translation. This could easily be changed but I
6789 don't believe that it is worth doing.
6790
6791 The characters handled by `nobreak-char-display' must be
6792 translated too.
6793
6794 Non-printable characters and raw-byte characters are also
6795 translated to octal form. */
6796 if (((c < ' ' || c == 127) /* ASCII control chars */
6797 ? (it->area != TEXT_AREA
6798 /* In mode line, treat \n, \t like other crl chars. */
6799 || (c != '\t'
6800 && it->glyph_row
6801 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6802 || (c != '\n' && c != '\t'))
6803 : (nonascii_space_p
6804 || nonascii_hyphen_p
6805 || CHAR_BYTE8_P (c)
6806 || ! CHAR_PRINTABLE_P (c))))
6807 {
6808 /* C is a control character, non-ASCII space/hyphen,
6809 raw-byte, or a non-printable character which must be
6810 displayed either as '\003' or as `^C' where the '\\'
6811 and '^' can be defined in the display table. Fill
6812 IT->ctl_chars with glyphs for what we have to
6813 display. Then, set IT->dpvec to these glyphs. */
6814 Lisp_Object gc;
6815 int ctl_len;
6816 int face_id;
6817 int lface_id = 0;
6818 int escape_glyph;
6819
6820 /* Handle control characters with ^. */
6821
6822 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6823 {
6824 int g;
6825
6826 g = '^'; /* default glyph for Control */
6827 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6828 if (it->dp
6829 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6830 {
6831 g = GLYPH_CODE_CHAR (gc);
6832 lface_id = GLYPH_CODE_FACE (gc);
6833 }
6834 if (lface_id)
6835 {
6836 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6837 }
6838 else if (it->f == last_escape_glyph_frame
6839 && it->face_id == last_escape_glyph_face_id)
6840 {
6841 face_id = last_escape_glyph_merged_face_id;
6842 }
6843 else
6844 {
6845 /* Merge the escape-glyph face into the current face. */
6846 face_id = merge_faces (it->f, Qescape_glyph, 0,
6847 it->face_id);
6848 last_escape_glyph_frame = it->f;
6849 last_escape_glyph_face_id = it->face_id;
6850 last_escape_glyph_merged_face_id = face_id;
6851 }
6852
6853 XSETINT (it->ctl_chars[0], g);
6854 XSETINT (it->ctl_chars[1], c ^ 0100);
6855 ctl_len = 2;
6856 goto display_control;
6857 }
6858
6859 /* Handle non-ascii space in the mode where it only gets
6860 highlighting. */
6861
6862 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6863 {
6864 /* Merge `nobreak-space' into the current face. */
6865 face_id = merge_faces (it->f, Qnobreak_space, 0,
6866 it->face_id);
6867 XSETINT (it->ctl_chars[0], ' ');
6868 ctl_len = 1;
6869 goto display_control;
6870 }
6871
6872 /* Handle sequences that start with the "escape glyph". */
6873
6874 /* the default escape glyph is \. */
6875 escape_glyph = '\\';
6876
6877 if (it->dp
6878 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6879 {
6880 escape_glyph = GLYPH_CODE_CHAR (gc);
6881 lface_id = GLYPH_CODE_FACE (gc);
6882 }
6883 if (lface_id)
6884 {
6885 /* The display table specified a face.
6886 Merge it into face_id and also into escape_glyph. */
6887 face_id = merge_faces (it->f, Qt, lface_id,
6888 it->face_id);
6889 }
6890 else if (it->f == last_escape_glyph_frame
6891 && it->face_id == last_escape_glyph_face_id)
6892 {
6893 face_id = last_escape_glyph_merged_face_id;
6894 }
6895 else
6896 {
6897 /* Merge the escape-glyph face into the current face. */
6898 face_id = merge_faces (it->f, Qescape_glyph, 0,
6899 it->face_id);
6900 last_escape_glyph_frame = it->f;
6901 last_escape_glyph_face_id = it->face_id;
6902 last_escape_glyph_merged_face_id = face_id;
6903 }
6904
6905 /* Draw non-ASCII hyphen with just highlighting: */
6906
6907 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6908 {
6909 XSETINT (it->ctl_chars[0], '-');
6910 ctl_len = 1;
6911 goto display_control;
6912 }
6913
6914 /* Draw non-ASCII space/hyphen with escape glyph: */
6915
6916 if (nonascii_space_p || nonascii_hyphen_p)
6917 {
6918 XSETINT (it->ctl_chars[0], escape_glyph);
6919 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6920 ctl_len = 2;
6921 goto display_control;
6922 }
6923
6924 {
6925 char str[10];
6926 int len, i;
6927
6928 if (CHAR_BYTE8_P (c))
6929 /* Display \200 instead of \17777600. */
6930 c = CHAR_TO_BYTE8 (c);
6931 len = sprintf (str, "%03o", c);
6932
6933 XSETINT (it->ctl_chars[0], escape_glyph);
6934 for (i = 0; i < len; i++)
6935 XSETINT (it->ctl_chars[i + 1], str[i]);
6936 ctl_len = len + 1;
6937 }
6938
6939 display_control:
6940 /* Set up IT->dpvec and return first character from it. */
6941 it->dpvec_char_len = it->len;
6942 it->dpvec = it->ctl_chars;
6943 it->dpend = it->dpvec + ctl_len;
6944 it->current.dpvec_index = 0;
6945 it->dpvec_face_id = face_id;
6946 it->saved_face_id = it->face_id;
6947 it->method = GET_FROM_DISPLAY_VECTOR;
6948 it->ellipsis_p = 0;
6949 goto get_next;
6950 }
6951 it->char_to_display = c;
6952 }
6953 else if (success_p)
6954 {
6955 it->char_to_display = it->c;
6956 }
6957 }
6958
6959 /* Adjust face id for a multibyte character. There are no multibyte
6960 character in unibyte text. */
6961 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6962 && it->multibyte_p
6963 && success_p
6964 && FRAME_WINDOW_P (it->f))
6965 {
6966 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6967
6968 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6969 {
6970 /* Automatic composition with glyph-string. */
6971 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6972
6973 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6974 }
6975 else
6976 {
6977 ptrdiff_t pos = (it->s ? -1
6978 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6979 : IT_CHARPOS (*it));
6980 int c;
6981
6982 if (it->what == IT_CHARACTER)
6983 c = it->char_to_display;
6984 else
6985 {
6986 struct composition *cmp = composition_table[it->cmp_it.id];
6987 int i;
6988
6989 c = ' ';
6990 for (i = 0; i < cmp->glyph_len; i++)
6991 /* TAB in a composition means display glyphs with
6992 padding space on the left or right. */
6993 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6994 break;
6995 }
6996 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6997 }
6998 }
6999
7000 done:
7001 /* Is this character the last one of a run of characters with
7002 box? If yes, set IT->end_of_box_run_p to 1. */
7003 if (it->face_box_p
7004 && it->s == NULL)
7005 {
7006 if (it->method == GET_FROM_STRING && it->sp)
7007 {
7008 int face_id = underlying_face_id (it);
7009 struct face *face = FACE_FROM_ID (it->f, face_id);
7010
7011 if (face)
7012 {
7013 if (face->box == FACE_NO_BOX)
7014 {
7015 /* If the box comes from face properties in a
7016 display string, check faces in that string. */
7017 int string_face_id = face_after_it_pos (it);
7018 it->end_of_box_run_p
7019 = (FACE_FROM_ID (it->f, string_face_id)->box
7020 == FACE_NO_BOX);
7021 }
7022 /* Otherwise, the box comes from the underlying face.
7023 If this is the last string character displayed, check
7024 the next buffer location. */
7025 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7026 && (it->current.overlay_string_index
7027 == it->n_overlay_strings - 1))
7028 {
7029 ptrdiff_t ignore;
7030 int next_face_id;
7031 struct text_pos pos = it->current.pos;
7032 INC_TEXT_POS (pos, it->multibyte_p);
7033
7034 next_face_id = face_at_buffer_position
7035 (it->w, CHARPOS (pos), it->region_beg_charpos,
7036 it->region_end_charpos, &ignore,
7037 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
7038 -1);
7039 it->end_of_box_run_p
7040 = (FACE_FROM_ID (it->f, next_face_id)->box
7041 == FACE_NO_BOX);
7042 }
7043 }
7044 }
7045 else
7046 {
7047 int face_id = face_after_it_pos (it);
7048 it->end_of_box_run_p
7049 = (face_id != it->face_id
7050 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7051 }
7052 }
7053 /* If we reached the end of the object we've been iterating (e.g., a
7054 display string or an overlay string), and there's something on
7055 IT->stack, proceed with what's on the stack. It doesn't make
7056 sense to return zero if there's unprocessed stuff on the stack,
7057 because otherwise that stuff will never be displayed. */
7058 if (!success_p && it->sp > 0)
7059 {
7060 set_iterator_to_next (it, 0);
7061 success_p = get_next_display_element (it);
7062 }
7063
7064 /* Value is 0 if end of buffer or string reached. */
7065 return success_p;
7066 }
7067
7068
7069 /* Move IT to the next display element.
7070
7071 RESEAT_P non-zero means if called on a newline in buffer text,
7072 skip to the next visible line start.
7073
7074 Functions get_next_display_element and set_iterator_to_next are
7075 separate because I find this arrangement easier to handle than a
7076 get_next_display_element function that also increments IT's
7077 position. The way it is we can first look at an iterator's current
7078 display element, decide whether it fits on a line, and if it does,
7079 increment the iterator position. The other way around we probably
7080 would either need a flag indicating whether the iterator has to be
7081 incremented the next time, or we would have to implement a
7082 decrement position function which would not be easy to write. */
7083
7084 void
7085 set_iterator_to_next (struct it *it, int reseat_p)
7086 {
7087 /* Reset flags indicating start and end of a sequence of characters
7088 with box. Reset them at the start of this function because
7089 moving the iterator to a new position might set them. */
7090 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7091
7092 switch (it->method)
7093 {
7094 case GET_FROM_BUFFER:
7095 /* The current display element of IT is a character from
7096 current_buffer. Advance in the buffer, and maybe skip over
7097 invisible lines that are so because of selective display. */
7098 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7099 reseat_at_next_visible_line_start (it, 0);
7100 else if (it->cmp_it.id >= 0)
7101 {
7102 /* We are currently getting glyphs from a composition. */
7103 int i;
7104
7105 if (! it->bidi_p)
7106 {
7107 IT_CHARPOS (*it) += it->cmp_it.nchars;
7108 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7109 if (it->cmp_it.to < it->cmp_it.nglyphs)
7110 {
7111 it->cmp_it.from = it->cmp_it.to;
7112 }
7113 else
7114 {
7115 it->cmp_it.id = -1;
7116 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7117 IT_BYTEPOS (*it),
7118 it->end_charpos, Qnil);
7119 }
7120 }
7121 else if (! it->cmp_it.reversed_p)
7122 {
7123 /* Composition created while scanning forward. */
7124 /* Update IT's char/byte positions to point to the first
7125 character of the next grapheme cluster, or to the
7126 character visually after the current composition. */
7127 for (i = 0; i < it->cmp_it.nchars; i++)
7128 bidi_move_to_visually_next (&it->bidi_it);
7129 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7130 IT_CHARPOS (*it) = it->bidi_it.charpos;
7131
7132 if (it->cmp_it.to < it->cmp_it.nglyphs)
7133 {
7134 /* Proceed to the next grapheme cluster. */
7135 it->cmp_it.from = it->cmp_it.to;
7136 }
7137 else
7138 {
7139 /* No more grapheme clusters in this composition.
7140 Find the next stop position. */
7141 ptrdiff_t stop = it->end_charpos;
7142 if (it->bidi_it.scan_dir < 0)
7143 /* Now we are scanning backward and don't know
7144 where to stop. */
7145 stop = -1;
7146 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7147 IT_BYTEPOS (*it), stop, Qnil);
7148 }
7149 }
7150 else
7151 {
7152 /* Composition created while scanning backward. */
7153 /* Update IT's char/byte positions to point to the last
7154 character of the previous grapheme cluster, or the
7155 character visually after the current composition. */
7156 for (i = 0; i < it->cmp_it.nchars; i++)
7157 bidi_move_to_visually_next (&it->bidi_it);
7158 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7159 IT_CHARPOS (*it) = it->bidi_it.charpos;
7160 if (it->cmp_it.from > 0)
7161 {
7162 /* Proceed to the previous grapheme cluster. */
7163 it->cmp_it.to = it->cmp_it.from;
7164 }
7165 else
7166 {
7167 /* No more grapheme clusters in this composition.
7168 Find the next stop position. */
7169 ptrdiff_t stop = it->end_charpos;
7170 if (it->bidi_it.scan_dir < 0)
7171 /* Now we are scanning backward and don't know
7172 where to stop. */
7173 stop = -1;
7174 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7175 IT_BYTEPOS (*it), stop, Qnil);
7176 }
7177 }
7178 }
7179 else
7180 {
7181 eassert (it->len != 0);
7182
7183 if (!it->bidi_p)
7184 {
7185 IT_BYTEPOS (*it) += it->len;
7186 IT_CHARPOS (*it) += 1;
7187 }
7188 else
7189 {
7190 int prev_scan_dir = it->bidi_it.scan_dir;
7191 /* If this is a new paragraph, determine its base
7192 direction (a.k.a. its base embedding level). */
7193 if (it->bidi_it.new_paragraph)
7194 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7195 bidi_move_to_visually_next (&it->bidi_it);
7196 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7197 IT_CHARPOS (*it) = it->bidi_it.charpos;
7198 if (prev_scan_dir != it->bidi_it.scan_dir)
7199 {
7200 /* As the scan direction was changed, we must
7201 re-compute the stop position for composition. */
7202 ptrdiff_t stop = it->end_charpos;
7203 if (it->bidi_it.scan_dir < 0)
7204 stop = -1;
7205 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7206 IT_BYTEPOS (*it), stop, Qnil);
7207 }
7208 }
7209 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7210 }
7211 break;
7212
7213 case GET_FROM_C_STRING:
7214 /* Current display element of IT is from a C string. */
7215 if (!it->bidi_p
7216 /* If the string position is beyond string's end, it means
7217 next_element_from_c_string is padding the string with
7218 blanks, in which case we bypass the bidi iterator,
7219 because it cannot deal with such virtual characters. */
7220 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7221 {
7222 IT_BYTEPOS (*it) += it->len;
7223 IT_CHARPOS (*it) += 1;
7224 }
7225 else
7226 {
7227 bidi_move_to_visually_next (&it->bidi_it);
7228 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7229 IT_CHARPOS (*it) = it->bidi_it.charpos;
7230 }
7231 break;
7232
7233 case GET_FROM_DISPLAY_VECTOR:
7234 /* Current display element of IT is from a display table entry.
7235 Advance in the display table definition. Reset it to null if
7236 end reached, and continue with characters from buffers/
7237 strings. */
7238 ++it->current.dpvec_index;
7239
7240 /* Restore face of the iterator to what they were before the
7241 display vector entry (these entries may contain faces). */
7242 it->face_id = it->saved_face_id;
7243
7244 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7245 {
7246 int recheck_faces = it->ellipsis_p;
7247
7248 if (it->s)
7249 it->method = GET_FROM_C_STRING;
7250 else if (STRINGP (it->string))
7251 it->method = GET_FROM_STRING;
7252 else
7253 {
7254 it->method = GET_FROM_BUFFER;
7255 it->object = it->w->contents;
7256 }
7257
7258 it->dpvec = NULL;
7259 it->current.dpvec_index = -1;
7260
7261 /* Skip over characters which were displayed via IT->dpvec. */
7262 if (it->dpvec_char_len < 0)
7263 reseat_at_next_visible_line_start (it, 1);
7264 else if (it->dpvec_char_len > 0)
7265 {
7266 if (it->method == GET_FROM_STRING
7267 && it->current.overlay_string_index >= 0
7268 && it->n_overlay_strings > 0)
7269 it->ignore_overlay_strings_at_pos_p = 1;
7270 it->len = it->dpvec_char_len;
7271 set_iterator_to_next (it, reseat_p);
7272 }
7273
7274 /* Maybe recheck faces after display vector */
7275 if (recheck_faces)
7276 it->stop_charpos = IT_CHARPOS (*it);
7277 }
7278 break;
7279
7280 case GET_FROM_STRING:
7281 /* Current display element is a character from a Lisp string. */
7282 eassert (it->s == NULL && STRINGP (it->string));
7283 /* Don't advance past string end. These conditions are true
7284 when set_iterator_to_next is called at the end of
7285 get_next_display_element, in which case the Lisp string is
7286 already exhausted, and all we want is pop the iterator
7287 stack. */
7288 if (it->current.overlay_string_index >= 0)
7289 {
7290 /* This is an overlay string, so there's no padding with
7291 spaces, and the number of characters in the string is
7292 where the string ends. */
7293 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7294 goto consider_string_end;
7295 }
7296 else
7297 {
7298 /* Not an overlay string. There could be padding, so test
7299 against it->end_charpos . */
7300 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7301 goto consider_string_end;
7302 }
7303 if (it->cmp_it.id >= 0)
7304 {
7305 int i;
7306
7307 if (! it->bidi_p)
7308 {
7309 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7310 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7311 if (it->cmp_it.to < it->cmp_it.nglyphs)
7312 it->cmp_it.from = it->cmp_it.to;
7313 else
7314 {
7315 it->cmp_it.id = -1;
7316 composition_compute_stop_pos (&it->cmp_it,
7317 IT_STRING_CHARPOS (*it),
7318 IT_STRING_BYTEPOS (*it),
7319 it->end_charpos, it->string);
7320 }
7321 }
7322 else if (! it->cmp_it.reversed_p)
7323 {
7324 for (i = 0; i < it->cmp_it.nchars; i++)
7325 bidi_move_to_visually_next (&it->bidi_it);
7326 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7327 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7328
7329 if (it->cmp_it.to < it->cmp_it.nglyphs)
7330 it->cmp_it.from = it->cmp_it.to;
7331 else
7332 {
7333 ptrdiff_t stop = it->end_charpos;
7334 if (it->bidi_it.scan_dir < 0)
7335 stop = -1;
7336 composition_compute_stop_pos (&it->cmp_it,
7337 IT_STRING_CHARPOS (*it),
7338 IT_STRING_BYTEPOS (*it), stop,
7339 it->string);
7340 }
7341 }
7342 else
7343 {
7344 for (i = 0; i < it->cmp_it.nchars; i++)
7345 bidi_move_to_visually_next (&it->bidi_it);
7346 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7347 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7348 if (it->cmp_it.from > 0)
7349 it->cmp_it.to = it->cmp_it.from;
7350 else
7351 {
7352 ptrdiff_t stop = it->end_charpos;
7353 if (it->bidi_it.scan_dir < 0)
7354 stop = -1;
7355 composition_compute_stop_pos (&it->cmp_it,
7356 IT_STRING_CHARPOS (*it),
7357 IT_STRING_BYTEPOS (*it), stop,
7358 it->string);
7359 }
7360 }
7361 }
7362 else
7363 {
7364 if (!it->bidi_p
7365 /* If the string position is beyond string's end, it
7366 means next_element_from_string is padding the string
7367 with blanks, in which case we bypass the bidi
7368 iterator, because it cannot deal with such virtual
7369 characters. */
7370 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7371 {
7372 IT_STRING_BYTEPOS (*it) += it->len;
7373 IT_STRING_CHARPOS (*it) += 1;
7374 }
7375 else
7376 {
7377 int prev_scan_dir = it->bidi_it.scan_dir;
7378
7379 bidi_move_to_visually_next (&it->bidi_it);
7380 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7381 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7382 if (prev_scan_dir != it->bidi_it.scan_dir)
7383 {
7384 ptrdiff_t stop = it->end_charpos;
7385
7386 if (it->bidi_it.scan_dir < 0)
7387 stop = -1;
7388 composition_compute_stop_pos (&it->cmp_it,
7389 IT_STRING_CHARPOS (*it),
7390 IT_STRING_BYTEPOS (*it), stop,
7391 it->string);
7392 }
7393 }
7394 }
7395
7396 consider_string_end:
7397
7398 if (it->current.overlay_string_index >= 0)
7399 {
7400 /* IT->string is an overlay string. Advance to the
7401 next, if there is one. */
7402 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7403 {
7404 it->ellipsis_p = 0;
7405 next_overlay_string (it);
7406 if (it->ellipsis_p)
7407 setup_for_ellipsis (it, 0);
7408 }
7409 }
7410 else
7411 {
7412 /* IT->string is not an overlay string. If we reached
7413 its end, and there is something on IT->stack, proceed
7414 with what is on the stack. This can be either another
7415 string, this time an overlay string, or a buffer. */
7416 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7417 && it->sp > 0)
7418 {
7419 pop_it (it);
7420 if (it->method == GET_FROM_STRING)
7421 goto consider_string_end;
7422 }
7423 }
7424 break;
7425
7426 case GET_FROM_IMAGE:
7427 case GET_FROM_STRETCH:
7428 /* The position etc with which we have to proceed are on
7429 the stack. The position may be at the end of a string,
7430 if the `display' property takes up the whole string. */
7431 eassert (it->sp > 0);
7432 pop_it (it);
7433 if (it->method == GET_FROM_STRING)
7434 goto consider_string_end;
7435 break;
7436
7437 default:
7438 /* There are no other methods defined, so this should be a bug. */
7439 emacs_abort ();
7440 }
7441
7442 eassert (it->method != GET_FROM_STRING
7443 || (STRINGP (it->string)
7444 && IT_STRING_CHARPOS (*it) >= 0));
7445 }
7446
7447 /* Load IT's display element fields with information about the next
7448 display element which comes from a display table entry or from the
7449 result of translating a control character to one of the forms `^C'
7450 or `\003'.
7451
7452 IT->dpvec holds the glyphs to return as characters.
7453 IT->saved_face_id holds the face id before the display vector--it
7454 is restored into IT->face_id in set_iterator_to_next. */
7455
7456 static int
7457 next_element_from_display_vector (struct it *it)
7458 {
7459 Lisp_Object gc;
7460
7461 /* Precondition. */
7462 eassert (it->dpvec && it->current.dpvec_index >= 0);
7463
7464 it->face_id = it->saved_face_id;
7465
7466 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7467 That seemed totally bogus - so I changed it... */
7468 gc = it->dpvec[it->current.dpvec_index];
7469
7470 if (GLYPH_CODE_P (gc))
7471 {
7472 it->c = GLYPH_CODE_CHAR (gc);
7473 it->len = CHAR_BYTES (it->c);
7474
7475 /* The entry may contain a face id to use. Such a face id is
7476 the id of a Lisp face, not a realized face. A face id of
7477 zero means no face is specified. */
7478 if (it->dpvec_face_id >= 0)
7479 it->face_id = it->dpvec_face_id;
7480 else
7481 {
7482 int lface_id = GLYPH_CODE_FACE (gc);
7483 if (lface_id > 0)
7484 it->face_id = merge_faces (it->f, Qt, lface_id,
7485 it->saved_face_id);
7486 }
7487 }
7488 else
7489 /* Display table entry is invalid. Return a space. */
7490 it->c = ' ', it->len = 1;
7491
7492 /* Don't change position and object of the iterator here. They are
7493 still the values of the character that had this display table
7494 entry or was translated, and that's what we want. */
7495 it->what = IT_CHARACTER;
7496 return 1;
7497 }
7498
7499 /* Get the first element of string/buffer in the visual order, after
7500 being reseated to a new position in a string or a buffer. */
7501 static void
7502 get_visually_first_element (struct it *it)
7503 {
7504 int string_p = STRINGP (it->string) || it->s;
7505 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7506 ptrdiff_t bob = (string_p ? 0 : BEGV);
7507
7508 if (STRINGP (it->string))
7509 {
7510 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7511 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7512 }
7513 else
7514 {
7515 it->bidi_it.charpos = IT_CHARPOS (*it);
7516 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7517 }
7518
7519 if (it->bidi_it.charpos == eob)
7520 {
7521 /* Nothing to do, but reset the FIRST_ELT flag, like
7522 bidi_paragraph_init does, because we are not going to
7523 call it. */
7524 it->bidi_it.first_elt = 0;
7525 }
7526 else if (it->bidi_it.charpos == bob
7527 || (!string_p
7528 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7529 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7530 {
7531 /* If we are at the beginning of a line/string, we can produce
7532 the next element right away. */
7533 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7534 bidi_move_to_visually_next (&it->bidi_it);
7535 }
7536 else
7537 {
7538 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7539
7540 /* We need to prime the bidi iterator starting at the line's or
7541 string's beginning, before we will be able to produce the
7542 next element. */
7543 if (string_p)
7544 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7545 else
7546 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7547 IT_BYTEPOS (*it), -1,
7548 &it->bidi_it.bytepos);
7549 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7550 do
7551 {
7552 /* Now return to buffer/string position where we were asked
7553 to get the next display element, and produce that. */
7554 bidi_move_to_visually_next (&it->bidi_it);
7555 }
7556 while (it->bidi_it.bytepos != orig_bytepos
7557 && it->bidi_it.charpos < eob);
7558 }
7559
7560 /* Adjust IT's position information to where we ended up. */
7561 if (STRINGP (it->string))
7562 {
7563 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7564 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7565 }
7566 else
7567 {
7568 IT_CHARPOS (*it) = it->bidi_it.charpos;
7569 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7570 }
7571
7572 if (STRINGP (it->string) || !it->s)
7573 {
7574 ptrdiff_t stop, charpos, bytepos;
7575
7576 if (STRINGP (it->string))
7577 {
7578 eassert (!it->s);
7579 stop = SCHARS (it->string);
7580 if (stop > it->end_charpos)
7581 stop = it->end_charpos;
7582 charpos = IT_STRING_CHARPOS (*it);
7583 bytepos = IT_STRING_BYTEPOS (*it);
7584 }
7585 else
7586 {
7587 stop = it->end_charpos;
7588 charpos = IT_CHARPOS (*it);
7589 bytepos = IT_BYTEPOS (*it);
7590 }
7591 if (it->bidi_it.scan_dir < 0)
7592 stop = -1;
7593 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7594 it->string);
7595 }
7596 }
7597
7598 /* Load IT with the next display element from Lisp string IT->string.
7599 IT->current.string_pos is the current position within the string.
7600 If IT->current.overlay_string_index >= 0, the Lisp string is an
7601 overlay string. */
7602
7603 static int
7604 next_element_from_string (struct it *it)
7605 {
7606 struct text_pos position;
7607
7608 eassert (STRINGP (it->string));
7609 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7610 eassert (IT_STRING_CHARPOS (*it) >= 0);
7611 position = it->current.string_pos;
7612
7613 /* With bidi reordering, the character to display might not be the
7614 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7615 that we were reseat()ed to a new string, whose paragraph
7616 direction is not known. */
7617 if (it->bidi_p && it->bidi_it.first_elt)
7618 {
7619 get_visually_first_element (it);
7620 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7621 }
7622
7623 /* Time to check for invisible text? */
7624 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7625 {
7626 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7627 {
7628 if (!(!it->bidi_p
7629 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7630 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7631 {
7632 /* With bidi non-linear iteration, we could find
7633 ourselves far beyond the last computed stop_charpos,
7634 with several other stop positions in between that we
7635 missed. Scan them all now, in buffer's logical
7636 order, until we find and handle the last stop_charpos
7637 that precedes our current position. */
7638 handle_stop_backwards (it, it->stop_charpos);
7639 return GET_NEXT_DISPLAY_ELEMENT (it);
7640 }
7641 else
7642 {
7643 if (it->bidi_p)
7644 {
7645 /* Take note of the stop position we just moved
7646 across, for when we will move back across it. */
7647 it->prev_stop = it->stop_charpos;
7648 /* If we are at base paragraph embedding level, take
7649 note of the last stop position seen at this
7650 level. */
7651 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7652 it->base_level_stop = it->stop_charpos;
7653 }
7654 handle_stop (it);
7655
7656 /* Since a handler may have changed IT->method, we must
7657 recurse here. */
7658 return GET_NEXT_DISPLAY_ELEMENT (it);
7659 }
7660 }
7661 else if (it->bidi_p
7662 /* If we are before prev_stop, we may have overstepped
7663 on our way backwards a stop_pos, and if so, we need
7664 to handle that stop_pos. */
7665 && IT_STRING_CHARPOS (*it) < it->prev_stop
7666 /* We can sometimes back up for reasons that have nothing
7667 to do with bidi reordering. E.g., compositions. The
7668 code below is only needed when we are above the base
7669 embedding level, so test for that explicitly. */
7670 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7671 {
7672 /* If we lost track of base_level_stop, we have no better
7673 place for handle_stop_backwards to start from than string
7674 beginning. This happens, e.g., when we were reseated to
7675 the previous screenful of text by vertical-motion. */
7676 if (it->base_level_stop <= 0
7677 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7678 it->base_level_stop = 0;
7679 handle_stop_backwards (it, it->base_level_stop);
7680 return GET_NEXT_DISPLAY_ELEMENT (it);
7681 }
7682 }
7683
7684 if (it->current.overlay_string_index >= 0)
7685 {
7686 /* Get the next character from an overlay string. In overlay
7687 strings, there is no field width or padding with spaces to
7688 do. */
7689 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7690 {
7691 it->what = IT_EOB;
7692 return 0;
7693 }
7694 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7695 IT_STRING_BYTEPOS (*it),
7696 it->bidi_it.scan_dir < 0
7697 ? -1
7698 : SCHARS (it->string))
7699 && next_element_from_composition (it))
7700 {
7701 return 1;
7702 }
7703 else if (STRING_MULTIBYTE (it->string))
7704 {
7705 const unsigned char *s = (SDATA (it->string)
7706 + IT_STRING_BYTEPOS (*it));
7707 it->c = string_char_and_length (s, &it->len);
7708 }
7709 else
7710 {
7711 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7712 it->len = 1;
7713 }
7714 }
7715 else
7716 {
7717 /* Get the next character from a Lisp string that is not an
7718 overlay string. Such strings come from the mode line, for
7719 example. We may have to pad with spaces, or truncate the
7720 string. See also next_element_from_c_string. */
7721 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7722 {
7723 it->what = IT_EOB;
7724 return 0;
7725 }
7726 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7727 {
7728 /* Pad with spaces. */
7729 it->c = ' ', it->len = 1;
7730 CHARPOS (position) = BYTEPOS (position) = -1;
7731 }
7732 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7733 IT_STRING_BYTEPOS (*it),
7734 it->bidi_it.scan_dir < 0
7735 ? -1
7736 : it->string_nchars)
7737 && next_element_from_composition (it))
7738 {
7739 return 1;
7740 }
7741 else if (STRING_MULTIBYTE (it->string))
7742 {
7743 const unsigned char *s = (SDATA (it->string)
7744 + IT_STRING_BYTEPOS (*it));
7745 it->c = string_char_and_length (s, &it->len);
7746 }
7747 else
7748 {
7749 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7750 it->len = 1;
7751 }
7752 }
7753
7754 /* Record what we have and where it came from. */
7755 it->what = IT_CHARACTER;
7756 it->object = it->string;
7757 it->position = position;
7758 return 1;
7759 }
7760
7761
7762 /* Load IT with next display element from C string IT->s.
7763 IT->string_nchars is the maximum number of characters to return
7764 from the string. IT->end_charpos may be greater than
7765 IT->string_nchars when this function is called, in which case we
7766 may have to return padding spaces. Value is zero if end of string
7767 reached, including padding spaces. */
7768
7769 static int
7770 next_element_from_c_string (struct it *it)
7771 {
7772 int success_p = 1;
7773
7774 eassert (it->s);
7775 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7776 it->what = IT_CHARACTER;
7777 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7778 it->object = Qnil;
7779
7780 /* With bidi reordering, the character to display might not be the
7781 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7782 we were reseated to a new string, whose paragraph direction is
7783 not known. */
7784 if (it->bidi_p && it->bidi_it.first_elt)
7785 get_visually_first_element (it);
7786
7787 /* IT's position can be greater than IT->string_nchars in case a
7788 field width or precision has been specified when the iterator was
7789 initialized. */
7790 if (IT_CHARPOS (*it) >= it->end_charpos)
7791 {
7792 /* End of the game. */
7793 it->what = IT_EOB;
7794 success_p = 0;
7795 }
7796 else if (IT_CHARPOS (*it) >= it->string_nchars)
7797 {
7798 /* Pad with spaces. */
7799 it->c = ' ', it->len = 1;
7800 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7801 }
7802 else if (it->multibyte_p)
7803 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7804 else
7805 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7806
7807 return success_p;
7808 }
7809
7810
7811 /* Set up IT to return characters from an ellipsis, if appropriate.
7812 The definition of the ellipsis glyphs may come from a display table
7813 entry. This function fills IT with the first glyph from the
7814 ellipsis if an ellipsis is to be displayed. */
7815
7816 static int
7817 next_element_from_ellipsis (struct it *it)
7818 {
7819 if (it->selective_display_ellipsis_p)
7820 setup_for_ellipsis (it, it->len);
7821 else
7822 {
7823 /* The face at the current position may be different from the
7824 face we find after the invisible text. Remember what it
7825 was in IT->saved_face_id, and signal that it's there by
7826 setting face_before_selective_p. */
7827 it->saved_face_id = it->face_id;
7828 it->method = GET_FROM_BUFFER;
7829 it->object = it->w->contents;
7830 reseat_at_next_visible_line_start (it, 1);
7831 it->face_before_selective_p = 1;
7832 }
7833
7834 return GET_NEXT_DISPLAY_ELEMENT (it);
7835 }
7836
7837
7838 /* Deliver an image display element. The iterator IT is already
7839 filled with image information (done in handle_display_prop). Value
7840 is always 1. */
7841
7842
7843 static int
7844 next_element_from_image (struct it *it)
7845 {
7846 it->what = IT_IMAGE;
7847 it->ignore_overlay_strings_at_pos_p = 0;
7848 return 1;
7849 }
7850
7851
7852 /* Fill iterator IT with next display element from a stretch glyph
7853 property. IT->object is the value of the text property. Value is
7854 always 1. */
7855
7856 static int
7857 next_element_from_stretch (struct it *it)
7858 {
7859 it->what = IT_STRETCH;
7860 return 1;
7861 }
7862
7863 /* Scan backwards from IT's current position until we find a stop
7864 position, or until BEGV. This is called when we find ourself
7865 before both the last known prev_stop and base_level_stop while
7866 reordering bidirectional text. */
7867
7868 static void
7869 compute_stop_pos_backwards (struct it *it)
7870 {
7871 const int SCAN_BACK_LIMIT = 1000;
7872 struct text_pos pos;
7873 struct display_pos save_current = it->current;
7874 struct text_pos save_position = it->position;
7875 ptrdiff_t charpos = IT_CHARPOS (*it);
7876 ptrdiff_t where_we_are = charpos;
7877 ptrdiff_t save_stop_pos = it->stop_charpos;
7878 ptrdiff_t save_end_pos = it->end_charpos;
7879
7880 eassert (NILP (it->string) && !it->s);
7881 eassert (it->bidi_p);
7882 it->bidi_p = 0;
7883 do
7884 {
7885 it->end_charpos = min (charpos + 1, ZV);
7886 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7887 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7888 reseat_1 (it, pos, 0);
7889 compute_stop_pos (it);
7890 /* We must advance forward, right? */
7891 if (it->stop_charpos <= charpos)
7892 emacs_abort ();
7893 }
7894 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7895
7896 if (it->stop_charpos <= where_we_are)
7897 it->prev_stop = it->stop_charpos;
7898 else
7899 it->prev_stop = BEGV;
7900 it->bidi_p = 1;
7901 it->current = save_current;
7902 it->position = save_position;
7903 it->stop_charpos = save_stop_pos;
7904 it->end_charpos = save_end_pos;
7905 }
7906
7907 /* Scan forward from CHARPOS in the current buffer/string, until we
7908 find a stop position > current IT's position. Then handle the stop
7909 position before that. This is called when we bump into a stop
7910 position while reordering bidirectional text. CHARPOS should be
7911 the last previously processed stop_pos (or BEGV/0, if none were
7912 processed yet) whose position is less that IT's current
7913 position. */
7914
7915 static void
7916 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7917 {
7918 int bufp = !STRINGP (it->string);
7919 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7920 struct display_pos save_current = it->current;
7921 struct text_pos save_position = it->position;
7922 struct text_pos pos1;
7923 ptrdiff_t next_stop;
7924
7925 /* Scan in strict logical order. */
7926 eassert (it->bidi_p);
7927 it->bidi_p = 0;
7928 do
7929 {
7930 it->prev_stop = charpos;
7931 if (bufp)
7932 {
7933 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7934 reseat_1 (it, pos1, 0);
7935 }
7936 else
7937 it->current.string_pos = string_pos (charpos, it->string);
7938 compute_stop_pos (it);
7939 /* We must advance forward, right? */
7940 if (it->stop_charpos <= it->prev_stop)
7941 emacs_abort ();
7942 charpos = it->stop_charpos;
7943 }
7944 while (charpos <= where_we_are);
7945
7946 it->bidi_p = 1;
7947 it->current = save_current;
7948 it->position = save_position;
7949 next_stop = it->stop_charpos;
7950 it->stop_charpos = it->prev_stop;
7951 handle_stop (it);
7952 it->stop_charpos = next_stop;
7953 }
7954
7955 /* Load IT with the next display element from current_buffer. Value
7956 is zero if end of buffer reached. IT->stop_charpos is the next
7957 position at which to stop and check for text properties or buffer
7958 end. */
7959
7960 static int
7961 next_element_from_buffer (struct it *it)
7962 {
7963 int success_p = 1;
7964
7965 eassert (IT_CHARPOS (*it) >= BEGV);
7966 eassert (NILP (it->string) && !it->s);
7967 eassert (!it->bidi_p
7968 || (EQ (it->bidi_it.string.lstring, Qnil)
7969 && it->bidi_it.string.s == NULL));
7970
7971 /* With bidi reordering, the character to display might not be the
7972 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7973 we were reseat()ed to a new buffer position, which is potentially
7974 a different paragraph. */
7975 if (it->bidi_p && it->bidi_it.first_elt)
7976 {
7977 get_visually_first_element (it);
7978 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7979 }
7980
7981 if (IT_CHARPOS (*it) >= it->stop_charpos)
7982 {
7983 if (IT_CHARPOS (*it) >= it->end_charpos)
7984 {
7985 int overlay_strings_follow_p;
7986
7987 /* End of the game, except when overlay strings follow that
7988 haven't been returned yet. */
7989 if (it->overlay_strings_at_end_processed_p)
7990 overlay_strings_follow_p = 0;
7991 else
7992 {
7993 it->overlay_strings_at_end_processed_p = 1;
7994 overlay_strings_follow_p = get_overlay_strings (it, 0);
7995 }
7996
7997 if (overlay_strings_follow_p)
7998 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7999 else
8000 {
8001 it->what = IT_EOB;
8002 it->position = it->current.pos;
8003 success_p = 0;
8004 }
8005 }
8006 else if (!(!it->bidi_p
8007 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8008 || IT_CHARPOS (*it) == it->stop_charpos))
8009 {
8010 /* With bidi non-linear iteration, we could find ourselves
8011 far beyond the last computed stop_charpos, with several
8012 other stop positions in between that we missed. Scan
8013 them all now, in buffer's logical order, until we find
8014 and handle the last stop_charpos that precedes our
8015 current position. */
8016 handle_stop_backwards (it, it->stop_charpos);
8017 return GET_NEXT_DISPLAY_ELEMENT (it);
8018 }
8019 else
8020 {
8021 if (it->bidi_p)
8022 {
8023 /* Take note of the stop position we just moved across,
8024 for when we will move back across it. */
8025 it->prev_stop = it->stop_charpos;
8026 /* If we are at base paragraph embedding level, take
8027 note of the last stop position seen at this
8028 level. */
8029 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8030 it->base_level_stop = it->stop_charpos;
8031 }
8032 handle_stop (it);
8033 return GET_NEXT_DISPLAY_ELEMENT (it);
8034 }
8035 }
8036 else if (it->bidi_p
8037 /* If we are before prev_stop, we may have overstepped on
8038 our way backwards a stop_pos, and if so, we need to
8039 handle that stop_pos. */
8040 && IT_CHARPOS (*it) < it->prev_stop
8041 /* We can sometimes back up for reasons that have nothing
8042 to do with bidi reordering. E.g., compositions. The
8043 code below is only needed when we are above the base
8044 embedding level, so test for that explicitly. */
8045 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8046 {
8047 if (it->base_level_stop <= 0
8048 || IT_CHARPOS (*it) < it->base_level_stop)
8049 {
8050 /* If we lost track of base_level_stop, we need to find
8051 prev_stop by looking backwards. This happens, e.g., when
8052 we were reseated to the previous screenful of text by
8053 vertical-motion. */
8054 it->base_level_stop = BEGV;
8055 compute_stop_pos_backwards (it);
8056 handle_stop_backwards (it, it->prev_stop);
8057 }
8058 else
8059 handle_stop_backwards (it, it->base_level_stop);
8060 return GET_NEXT_DISPLAY_ELEMENT (it);
8061 }
8062 else
8063 {
8064 /* No face changes, overlays etc. in sight, so just return a
8065 character from current_buffer. */
8066 unsigned char *p;
8067 ptrdiff_t stop;
8068
8069 /* Maybe run the redisplay end trigger hook. Performance note:
8070 This doesn't seem to cost measurable time. */
8071 if (it->redisplay_end_trigger_charpos
8072 && it->glyph_row
8073 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8074 run_redisplay_end_trigger_hook (it);
8075
8076 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8077 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8078 stop)
8079 && next_element_from_composition (it))
8080 {
8081 return 1;
8082 }
8083
8084 /* Get the next character, maybe multibyte. */
8085 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8086 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8087 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8088 else
8089 it->c = *p, it->len = 1;
8090
8091 /* Record what we have and where it came from. */
8092 it->what = IT_CHARACTER;
8093 it->object = it->w->contents;
8094 it->position = it->current.pos;
8095
8096 /* Normally we return the character found above, except when we
8097 really want to return an ellipsis for selective display. */
8098 if (it->selective)
8099 {
8100 if (it->c == '\n')
8101 {
8102 /* A value of selective > 0 means hide lines indented more
8103 than that number of columns. */
8104 if (it->selective > 0
8105 && IT_CHARPOS (*it) + 1 < ZV
8106 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8107 IT_BYTEPOS (*it) + 1,
8108 it->selective))
8109 {
8110 success_p = next_element_from_ellipsis (it);
8111 it->dpvec_char_len = -1;
8112 }
8113 }
8114 else if (it->c == '\r' && it->selective == -1)
8115 {
8116 /* A value of selective == -1 means that everything from the
8117 CR to the end of the line is invisible, with maybe an
8118 ellipsis displayed for it. */
8119 success_p = next_element_from_ellipsis (it);
8120 it->dpvec_char_len = -1;
8121 }
8122 }
8123 }
8124
8125 /* Value is zero if end of buffer reached. */
8126 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8127 return success_p;
8128 }
8129
8130
8131 /* Run the redisplay end trigger hook for IT. */
8132
8133 static void
8134 run_redisplay_end_trigger_hook (struct it *it)
8135 {
8136 Lisp_Object args[3];
8137
8138 /* IT->glyph_row should be non-null, i.e. we should be actually
8139 displaying something, or otherwise we should not run the hook. */
8140 eassert (it->glyph_row);
8141
8142 /* Set up hook arguments. */
8143 args[0] = Qredisplay_end_trigger_functions;
8144 args[1] = it->window;
8145 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8146 it->redisplay_end_trigger_charpos = 0;
8147
8148 /* Since we are *trying* to run these functions, don't try to run
8149 them again, even if they get an error. */
8150 wset_redisplay_end_trigger (it->w, Qnil);
8151 Frun_hook_with_args (3, args);
8152
8153 /* Notice if it changed the face of the character we are on. */
8154 handle_face_prop (it);
8155 }
8156
8157
8158 /* Deliver a composition display element. Unlike the other
8159 next_element_from_XXX, this function is not registered in the array
8160 get_next_element[]. It is called from next_element_from_buffer and
8161 next_element_from_string when necessary. */
8162
8163 static int
8164 next_element_from_composition (struct it *it)
8165 {
8166 it->what = IT_COMPOSITION;
8167 it->len = it->cmp_it.nbytes;
8168 if (STRINGP (it->string))
8169 {
8170 if (it->c < 0)
8171 {
8172 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8173 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8174 return 0;
8175 }
8176 it->position = it->current.string_pos;
8177 it->object = it->string;
8178 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8179 IT_STRING_BYTEPOS (*it), it->string);
8180 }
8181 else
8182 {
8183 if (it->c < 0)
8184 {
8185 IT_CHARPOS (*it) += it->cmp_it.nchars;
8186 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8187 if (it->bidi_p)
8188 {
8189 if (it->bidi_it.new_paragraph)
8190 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8191 /* Resync the bidi iterator with IT's new position.
8192 FIXME: this doesn't support bidirectional text. */
8193 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8194 bidi_move_to_visually_next (&it->bidi_it);
8195 }
8196 return 0;
8197 }
8198 it->position = it->current.pos;
8199 it->object = it->w->contents;
8200 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8201 IT_BYTEPOS (*it), Qnil);
8202 }
8203 return 1;
8204 }
8205
8206
8207 \f
8208 /***********************************************************************
8209 Moving an iterator without producing glyphs
8210 ***********************************************************************/
8211
8212 /* Check if iterator is at a position corresponding to a valid buffer
8213 position after some move_it_ call. */
8214
8215 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8216 ((it)->method == GET_FROM_STRING \
8217 ? IT_STRING_CHARPOS (*it) == 0 \
8218 : 1)
8219
8220
8221 /* Move iterator IT to a specified buffer or X position within one
8222 line on the display without producing glyphs.
8223
8224 OP should be a bit mask including some or all of these bits:
8225 MOVE_TO_X: Stop upon reaching x-position TO_X.
8226 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8227 Regardless of OP's value, stop upon reaching the end of the display line.
8228
8229 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8230 This means, in particular, that TO_X includes window's horizontal
8231 scroll amount.
8232
8233 The return value has several possible values that
8234 say what condition caused the scan to stop:
8235
8236 MOVE_POS_MATCH_OR_ZV
8237 - when TO_POS or ZV was reached.
8238
8239 MOVE_X_REACHED
8240 -when TO_X was reached before TO_POS or ZV were reached.
8241
8242 MOVE_LINE_CONTINUED
8243 - when we reached the end of the display area and the line must
8244 be continued.
8245
8246 MOVE_LINE_TRUNCATED
8247 - when we reached the end of the display area and the line is
8248 truncated.
8249
8250 MOVE_NEWLINE_OR_CR
8251 - when we stopped at a line end, i.e. a newline or a CR and selective
8252 display is on. */
8253
8254 static enum move_it_result
8255 move_it_in_display_line_to (struct it *it,
8256 ptrdiff_t to_charpos, int to_x,
8257 enum move_operation_enum op)
8258 {
8259 enum move_it_result result = MOVE_UNDEFINED;
8260 struct glyph_row *saved_glyph_row;
8261 struct it wrap_it, atpos_it, atx_it, ppos_it;
8262 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8263 void *ppos_data = NULL;
8264 int may_wrap = 0;
8265 enum it_method prev_method = it->method;
8266 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8267 int saw_smaller_pos = prev_pos < to_charpos;
8268
8269 /* Don't produce glyphs in produce_glyphs. */
8270 saved_glyph_row = it->glyph_row;
8271 it->glyph_row = NULL;
8272
8273 /* Use wrap_it to save a copy of IT wherever a word wrap could
8274 occur. Use atpos_it to save a copy of IT at the desired buffer
8275 position, if found, so that we can scan ahead and check if the
8276 word later overshoots the window edge. Use atx_it similarly, for
8277 pixel positions. */
8278 wrap_it.sp = -1;
8279 atpos_it.sp = -1;
8280 atx_it.sp = -1;
8281
8282 /* Use ppos_it under bidi reordering to save a copy of IT for the
8283 position > CHARPOS that is the closest to CHARPOS. We restore
8284 that position in IT when we have scanned the entire display line
8285 without finding a match for CHARPOS and all the character
8286 positions are greater than CHARPOS. */
8287 if (it->bidi_p)
8288 {
8289 SAVE_IT (ppos_it, *it, ppos_data);
8290 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8291 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8292 SAVE_IT (ppos_it, *it, ppos_data);
8293 }
8294
8295 #define BUFFER_POS_REACHED_P() \
8296 ((op & MOVE_TO_POS) != 0 \
8297 && BUFFERP (it->object) \
8298 && (IT_CHARPOS (*it) == to_charpos \
8299 || ((!it->bidi_p \
8300 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8301 && IT_CHARPOS (*it) > to_charpos) \
8302 || (it->what == IT_COMPOSITION \
8303 && ((IT_CHARPOS (*it) > to_charpos \
8304 && to_charpos >= it->cmp_it.charpos) \
8305 || (IT_CHARPOS (*it) < to_charpos \
8306 && to_charpos <= it->cmp_it.charpos)))) \
8307 && (it->method == GET_FROM_BUFFER \
8308 || (it->method == GET_FROM_DISPLAY_VECTOR \
8309 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8310
8311 /* If there's a line-/wrap-prefix, handle it. */
8312 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8313 && it->current_y < it->last_visible_y)
8314 handle_line_prefix (it);
8315
8316 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8317 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8318
8319 while (1)
8320 {
8321 int x, i, ascent = 0, descent = 0;
8322
8323 /* Utility macro to reset an iterator with x, ascent, and descent. */
8324 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8325 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8326 (IT)->max_descent = descent)
8327
8328 /* Stop if we move beyond TO_CHARPOS (after an image or a
8329 display string or stretch glyph). */
8330 if ((op & MOVE_TO_POS) != 0
8331 && BUFFERP (it->object)
8332 && it->method == GET_FROM_BUFFER
8333 && (((!it->bidi_p
8334 /* When the iterator is at base embedding level, we
8335 are guaranteed that characters are delivered for
8336 display in strictly increasing order of their
8337 buffer positions. */
8338 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8339 && IT_CHARPOS (*it) > to_charpos)
8340 || (it->bidi_p
8341 && (prev_method == GET_FROM_IMAGE
8342 || prev_method == GET_FROM_STRETCH
8343 || prev_method == GET_FROM_STRING)
8344 /* Passed TO_CHARPOS from left to right. */
8345 && ((prev_pos < to_charpos
8346 && IT_CHARPOS (*it) > to_charpos)
8347 /* Passed TO_CHARPOS from right to left. */
8348 || (prev_pos > to_charpos
8349 && IT_CHARPOS (*it) < to_charpos)))))
8350 {
8351 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8352 {
8353 result = MOVE_POS_MATCH_OR_ZV;
8354 break;
8355 }
8356 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8357 /* If wrap_it is valid, the current position might be in a
8358 word that is wrapped. So, save the iterator in
8359 atpos_it and continue to see if wrapping happens. */
8360 SAVE_IT (atpos_it, *it, atpos_data);
8361 }
8362
8363 /* Stop when ZV reached.
8364 We used to stop here when TO_CHARPOS reached as well, but that is
8365 too soon if this glyph does not fit on this line. So we handle it
8366 explicitly below. */
8367 if (!get_next_display_element (it))
8368 {
8369 result = MOVE_POS_MATCH_OR_ZV;
8370 break;
8371 }
8372
8373 if (it->line_wrap == TRUNCATE)
8374 {
8375 if (BUFFER_POS_REACHED_P ())
8376 {
8377 result = MOVE_POS_MATCH_OR_ZV;
8378 break;
8379 }
8380 }
8381 else
8382 {
8383 if (it->line_wrap == WORD_WRAP)
8384 {
8385 if (IT_DISPLAYING_WHITESPACE (it))
8386 may_wrap = 1;
8387 else if (may_wrap)
8388 {
8389 /* We have reached a glyph that follows one or more
8390 whitespace characters. If the position is
8391 already found, we are done. */
8392 if (atpos_it.sp >= 0)
8393 {
8394 RESTORE_IT (it, &atpos_it, atpos_data);
8395 result = MOVE_POS_MATCH_OR_ZV;
8396 goto done;
8397 }
8398 if (atx_it.sp >= 0)
8399 {
8400 RESTORE_IT (it, &atx_it, atx_data);
8401 result = MOVE_X_REACHED;
8402 goto done;
8403 }
8404 /* Otherwise, we can wrap here. */
8405 SAVE_IT (wrap_it, *it, wrap_data);
8406 may_wrap = 0;
8407 }
8408 }
8409 }
8410
8411 /* Remember the line height for the current line, in case
8412 the next element doesn't fit on the line. */
8413 ascent = it->max_ascent;
8414 descent = it->max_descent;
8415
8416 /* The call to produce_glyphs will get the metrics of the
8417 display element IT is loaded with. Record the x-position
8418 before this display element, in case it doesn't fit on the
8419 line. */
8420 x = it->current_x;
8421
8422 PRODUCE_GLYPHS (it);
8423
8424 if (it->area != TEXT_AREA)
8425 {
8426 prev_method = it->method;
8427 if (it->method == GET_FROM_BUFFER)
8428 prev_pos = IT_CHARPOS (*it);
8429 set_iterator_to_next (it, 1);
8430 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8431 SET_TEXT_POS (this_line_min_pos,
8432 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8433 if (it->bidi_p
8434 && (op & MOVE_TO_POS)
8435 && IT_CHARPOS (*it) > to_charpos
8436 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8437 SAVE_IT (ppos_it, *it, ppos_data);
8438 continue;
8439 }
8440
8441 /* The number of glyphs we get back in IT->nglyphs will normally
8442 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8443 character on a terminal frame, or (iii) a line end. For the
8444 second case, IT->nglyphs - 1 padding glyphs will be present.
8445 (On X frames, there is only one glyph produced for a
8446 composite character.)
8447
8448 The behavior implemented below means, for continuation lines,
8449 that as many spaces of a TAB as fit on the current line are
8450 displayed there. For terminal frames, as many glyphs of a
8451 multi-glyph character are displayed in the current line, too.
8452 This is what the old redisplay code did, and we keep it that
8453 way. Under X, the whole shape of a complex character must
8454 fit on the line or it will be completely displayed in the
8455 next line.
8456
8457 Note that both for tabs and padding glyphs, all glyphs have
8458 the same width. */
8459 if (it->nglyphs)
8460 {
8461 /* More than one glyph or glyph doesn't fit on line. All
8462 glyphs have the same width. */
8463 int single_glyph_width = it->pixel_width / it->nglyphs;
8464 int new_x;
8465 int x_before_this_char = x;
8466 int hpos_before_this_char = it->hpos;
8467
8468 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8469 {
8470 new_x = x + single_glyph_width;
8471
8472 /* We want to leave anything reaching TO_X to the caller. */
8473 if ((op & MOVE_TO_X) && new_x > to_x)
8474 {
8475 if (BUFFER_POS_REACHED_P ())
8476 {
8477 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8478 goto buffer_pos_reached;
8479 if (atpos_it.sp < 0)
8480 {
8481 SAVE_IT (atpos_it, *it, atpos_data);
8482 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8483 }
8484 }
8485 else
8486 {
8487 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8488 {
8489 it->current_x = x;
8490 result = MOVE_X_REACHED;
8491 break;
8492 }
8493 if (atx_it.sp < 0)
8494 {
8495 SAVE_IT (atx_it, *it, atx_data);
8496 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8497 }
8498 }
8499 }
8500
8501 if (/* Lines are continued. */
8502 it->line_wrap != TRUNCATE
8503 && (/* And glyph doesn't fit on the line. */
8504 new_x > it->last_visible_x
8505 /* Or it fits exactly and we're on a window
8506 system frame. */
8507 || (new_x == it->last_visible_x
8508 && FRAME_WINDOW_P (it->f)
8509 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8510 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8511 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8512 {
8513 if (/* IT->hpos == 0 means the very first glyph
8514 doesn't fit on the line, e.g. a wide image. */
8515 it->hpos == 0
8516 || (new_x == it->last_visible_x
8517 && FRAME_WINDOW_P (it->f)))
8518 {
8519 ++it->hpos;
8520 it->current_x = new_x;
8521
8522 /* The character's last glyph just barely fits
8523 in this row. */
8524 if (i == it->nglyphs - 1)
8525 {
8526 /* If this is the destination position,
8527 return a position *before* it in this row,
8528 now that we know it fits in this row. */
8529 if (BUFFER_POS_REACHED_P ())
8530 {
8531 if (it->line_wrap != WORD_WRAP
8532 || wrap_it.sp < 0)
8533 {
8534 it->hpos = hpos_before_this_char;
8535 it->current_x = x_before_this_char;
8536 result = MOVE_POS_MATCH_OR_ZV;
8537 break;
8538 }
8539 if (it->line_wrap == WORD_WRAP
8540 && atpos_it.sp < 0)
8541 {
8542 SAVE_IT (atpos_it, *it, atpos_data);
8543 atpos_it.current_x = x_before_this_char;
8544 atpos_it.hpos = hpos_before_this_char;
8545 }
8546 }
8547
8548 prev_method = it->method;
8549 if (it->method == GET_FROM_BUFFER)
8550 prev_pos = IT_CHARPOS (*it);
8551 set_iterator_to_next (it, 1);
8552 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8553 SET_TEXT_POS (this_line_min_pos,
8554 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8555 /* On graphical terminals, newlines may
8556 "overflow" into the fringe if
8557 overflow-newline-into-fringe is non-nil.
8558 On text terminals, and on graphical
8559 terminals with no right margin, newlines
8560 may overflow into the last glyph on the
8561 display line.*/
8562 if (!FRAME_WINDOW_P (it->f)
8563 || ((it->bidi_p
8564 && it->bidi_it.paragraph_dir == R2L)
8565 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8566 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8567 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8568 {
8569 if (!get_next_display_element (it))
8570 {
8571 result = MOVE_POS_MATCH_OR_ZV;
8572 break;
8573 }
8574 if (BUFFER_POS_REACHED_P ())
8575 {
8576 if (ITERATOR_AT_END_OF_LINE_P (it))
8577 result = MOVE_POS_MATCH_OR_ZV;
8578 else
8579 result = MOVE_LINE_CONTINUED;
8580 break;
8581 }
8582 if (ITERATOR_AT_END_OF_LINE_P (it)
8583 && (it->line_wrap != WORD_WRAP
8584 || wrap_it.sp < 0))
8585 {
8586 result = MOVE_NEWLINE_OR_CR;
8587 break;
8588 }
8589 }
8590 }
8591 }
8592 else
8593 IT_RESET_X_ASCENT_DESCENT (it);
8594
8595 if (wrap_it.sp >= 0)
8596 {
8597 RESTORE_IT (it, &wrap_it, wrap_data);
8598 atpos_it.sp = -1;
8599 atx_it.sp = -1;
8600 }
8601
8602 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8603 IT_CHARPOS (*it)));
8604 result = MOVE_LINE_CONTINUED;
8605 break;
8606 }
8607
8608 if (BUFFER_POS_REACHED_P ())
8609 {
8610 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8611 goto buffer_pos_reached;
8612 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8613 {
8614 SAVE_IT (atpos_it, *it, atpos_data);
8615 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8616 }
8617 }
8618
8619 if (new_x > it->first_visible_x)
8620 {
8621 /* Glyph is visible. Increment number of glyphs that
8622 would be displayed. */
8623 ++it->hpos;
8624 }
8625 }
8626
8627 if (result != MOVE_UNDEFINED)
8628 break;
8629 }
8630 else if (BUFFER_POS_REACHED_P ())
8631 {
8632 buffer_pos_reached:
8633 IT_RESET_X_ASCENT_DESCENT (it);
8634 result = MOVE_POS_MATCH_OR_ZV;
8635 break;
8636 }
8637 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8638 {
8639 /* Stop when TO_X specified and reached. This check is
8640 necessary here because of lines consisting of a line end,
8641 only. The line end will not produce any glyphs and we
8642 would never get MOVE_X_REACHED. */
8643 eassert (it->nglyphs == 0);
8644 result = MOVE_X_REACHED;
8645 break;
8646 }
8647
8648 /* Is this a line end? If yes, we're done. */
8649 if (ITERATOR_AT_END_OF_LINE_P (it))
8650 {
8651 /* If we are past TO_CHARPOS, but never saw any character
8652 positions smaller than TO_CHARPOS, return
8653 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8654 did. */
8655 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8656 {
8657 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8658 {
8659 if (IT_CHARPOS (ppos_it) < ZV)
8660 {
8661 RESTORE_IT (it, &ppos_it, ppos_data);
8662 result = MOVE_POS_MATCH_OR_ZV;
8663 }
8664 else
8665 goto buffer_pos_reached;
8666 }
8667 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8668 && IT_CHARPOS (*it) > to_charpos)
8669 goto buffer_pos_reached;
8670 else
8671 result = MOVE_NEWLINE_OR_CR;
8672 }
8673 else
8674 result = MOVE_NEWLINE_OR_CR;
8675 break;
8676 }
8677
8678 prev_method = it->method;
8679 if (it->method == GET_FROM_BUFFER)
8680 prev_pos = IT_CHARPOS (*it);
8681 /* The current display element has been consumed. Advance
8682 to the next. */
8683 set_iterator_to_next (it, 1);
8684 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8685 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8686 if (IT_CHARPOS (*it) < to_charpos)
8687 saw_smaller_pos = 1;
8688 if (it->bidi_p
8689 && (op & MOVE_TO_POS)
8690 && IT_CHARPOS (*it) >= to_charpos
8691 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8692 SAVE_IT (ppos_it, *it, ppos_data);
8693
8694 /* Stop if lines are truncated and IT's current x-position is
8695 past the right edge of the window now. */
8696 if (it->line_wrap == TRUNCATE
8697 && it->current_x >= it->last_visible_x)
8698 {
8699 if (!FRAME_WINDOW_P (it->f)
8700 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8701 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8702 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8703 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8704 {
8705 int at_eob_p = 0;
8706
8707 if ((at_eob_p = !get_next_display_element (it))
8708 || BUFFER_POS_REACHED_P ()
8709 /* If we are past TO_CHARPOS, but never saw any
8710 character positions smaller than TO_CHARPOS,
8711 return MOVE_POS_MATCH_OR_ZV, like the
8712 unidirectional display did. */
8713 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8714 && !saw_smaller_pos
8715 && IT_CHARPOS (*it) > to_charpos))
8716 {
8717 if (it->bidi_p
8718 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8719 RESTORE_IT (it, &ppos_it, ppos_data);
8720 result = MOVE_POS_MATCH_OR_ZV;
8721 break;
8722 }
8723 if (ITERATOR_AT_END_OF_LINE_P (it))
8724 {
8725 result = MOVE_NEWLINE_OR_CR;
8726 break;
8727 }
8728 }
8729 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8730 && !saw_smaller_pos
8731 && IT_CHARPOS (*it) > to_charpos)
8732 {
8733 if (IT_CHARPOS (ppos_it) < ZV)
8734 RESTORE_IT (it, &ppos_it, ppos_data);
8735 result = MOVE_POS_MATCH_OR_ZV;
8736 break;
8737 }
8738 result = MOVE_LINE_TRUNCATED;
8739 break;
8740 }
8741 #undef IT_RESET_X_ASCENT_DESCENT
8742 }
8743
8744 #undef BUFFER_POS_REACHED_P
8745
8746 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8747 restore the saved iterator. */
8748 if (atpos_it.sp >= 0)
8749 RESTORE_IT (it, &atpos_it, atpos_data);
8750 else if (atx_it.sp >= 0)
8751 RESTORE_IT (it, &atx_it, atx_data);
8752
8753 done:
8754
8755 if (atpos_data)
8756 bidi_unshelve_cache (atpos_data, 1);
8757 if (atx_data)
8758 bidi_unshelve_cache (atx_data, 1);
8759 if (wrap_data)
8760 bidi_unshelve_cache (wrap_data, 1);
8761 if (ppos_data)
8762 bidi_unshelve_cache (ppos_data, 1);
8763
8764 /* Restore the iterator settings altered at the beginning of this
8765 function. */
8766 it->glyph_row = saved_glyph_row;
8767 return result;
8768 }
8769
8770 /* For external use. */
8771 void
8772 move_it_in_display_line (struct it *it,
8773 ptrdiff_t to_charpos, int to_x,
8774 enum move_operation_enum op)
8775 {
8776 if (it->line_wrap == WORD_WRAP
8777 && (op & MOVE_TO_X))
8778 {
8779 struct it save_it;
8780 void *save_data = NULL;
8781 int skip;
8782
8783 SAVE_IT (save_it, *it, save_data);
8784 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8785 /* When word-wrap is on, TO_X may lie past the end
8786 of a wrapped line. Then it->current is the
8787 character on the next line, so backtrack to the
8788 space before the wrap point. */
8789 if (skip == MOVE_LINE_CONTINUED)
8790 {
8791 int prev_x = max (it->current_x - 1, 0);
8792 RESTORE_IT (it, &save_it, save_data);
8793 move_it_in_display_line_to
8794 (it, -1, prev_x, MOVE_TO_X);
8795 }
8796 else
8797 bidi_unshelve_cache (save_data, 1);
8798 }
8799 else
8800 move_it_in_display_line_to (it, to_charpos, to_x, op);
8801 }
8802
8803
8804 /* Move IT forward until it satisfies one or more of the criteria in
8805 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8806
8807 OP is a bit-mask that specifies where to stop, and in particular,
8808 which of those four position arguments makes a difference. See the
8809 description of enum move_operation_enum.
8810
8811 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8812 screen line, this function will set IT to the next position that is
8813 displayed to the right of TO_CHARPOS on the screen. */
8814
8815 void
8816 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8817 {
8818 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8819 int line_height, line_start_x = 0, reached = 0;
8820 void *backup_data = NULL;
8821
8822 for (;;)
8823 {
8824 if (op & MOVE_TO_VPOS)
8825 {
8826 /* If no TO_CHARPOS and no TO_X specified, stop at the
8827 start of the line TO_VPOS. */
8828 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8829 {
8830 if (it->vpos == to_vpos)
8831 {
8832 reached = 1;
8833 break;
8834 }
8835 else
8836 skip = move_it_in_display_line_to (it, -1, -1, 0);
8837 }
8838 else
8839 {
8840 /* TO_VPOS >= 0 means stop at TO_X in the line at
8841 TO_VPOS, or at TO_POS, whichever comes first. */
8842 if (it->vpos == to_vpos)
8843 {
8844 reached = 2;
8845 break;
8846 }
8847
8848 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8849
8850 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8851 {
8852 reached = 3;
8853 break;
8854 }
8855 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8856 {
8857 /* We have reached TO_X but not in the line we want. */
8858 skip = move_it_in_display_line_to (it, to_charpos,
8859 -1, MOVE_TO_POS);
8860 if (skip == MOVE_POS_MATCH_OR_ZV)
8861 {
8862 reached = 4;
8863 break;
8864 }
8865 }
8866 }
8867 }
8868 else if (op & MOVE_TO_Y)
8869 {
8870 struct it it_backup;
8871
8872 if (it->line_wrap == WORD_WRAP)
8873 SAVE_IT (it_backup, *it, backup_data);
8874
8875 /* TO_Y specified means stop at TO_X in the line containing
8876 TO_Y---or at TO_CHARPOS if this is reached first. The
8877 problem is that we can't really tell whether the line
8878 contains TO_Y before we have completely scanned it, and
8879 this may skip past TO_X. What we do is to first scan to
8880 TO_X.
8881
8882 If TO_X is not specified, use a TO_X of zero. The reason
8883 is to make the outcome of this function more predictable.
8884 If we didn't use TO_X == 0, we would stop at the end of
8885 the line which is probably not what a caller would expect
8886 to happen. */
8887 skip = move_it_in_display_line_to
8888 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8889 (MOVE_TO_X | (op & MOVE_TO_POS)));
8890
8891 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8892 if (skip == MOVE_POS_MATCH_OR_ZV)
8893 reached = 5;
8894 else if (skip == MOVE_X_REACHED)
8895 {
8896 /* If TO_X was reached, we want to know whether TO_Y is
8897 in the line. We know this is the case if the already
8898 scanned glyphs make the line tall enough. Otherwise,
8899 we must check by scanning the rest of the line. */
8900 line_height = it->max_ascent + it->max_descent;
8901 if (to_y >= it->current_y
8902 && to_y < it->current_y + line_height)
8903 {
8904 reached = 6;
8905 break;
8906 }
8907 SAVE_IT (it_backup, *it, backup_data);
8908 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8909 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8910 op & MOVE_TO_POS);
8911 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8912 line_height = it->max_ascent + it->max_descent;
8913 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8914
8915 if (to_y >= it->current_y
8916 && to_y < it->current_y + line_height)
8917 {
8918 /* If TO_Y is in this line and TO_X was reached
8919 above, we scanned too far. We have to restore
8920 IT's settings to the ones before skipping. But
8921 keep the more accurate values of max_ascent and
8922 max_descent we've found while skipping the rest
8923 of the line, for the sake of callers, such as
8924 pos_visible_p, that need to know the line
8925 height. */
8926 int max_ascent = it->max_ascent;
8927 int max_descent = it->max_descent;
8928
8929 RESTORE_IT (it, &it_backup, backup_data);
8930 it->max_ascent = max_ascent;
8931 it->max_descent = max_descent;
8932 reached = 6;
8933 }
8934 else
8935 {
8936 skip = skip2;
8937 if (skip == MOVE_POS_MATCH_OR_ZV)
8938 reached = 7;
8939 }
8940 }
8941 else
8942 {
8943 /* Check whether TO_Y is in this line. */
8944 line_height = it->max_ascent + it->max_descent;
8945 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8946
8947 if (to_y >= it->current_y
8948 && to_y < it->current_y + line_height)
8949 {
8950 /* When word-wrap is on, TO_X may lie past the end
8951 of a wrapped line. Then it->current is the
8952 character on the next line, so backtrack to the
8953 space before the wrap point. */
8954 if (skip == MOVE_LINE_CONTINUED
8955 && it->line_wrap == WORD_WRAP)
8956 {
8957 int prev_x = max (it->current_x - 1, 0);
8958 RESTORE_IT (it, &it_backup, backup_data);
8959 skip = move_it_in_display_line_to
8960 (it, -1, prev_x, MOVE_TO_X);
8961 }
8962 reached = 6;
8963 }
8964 }
8965
8966 if (reached)
8967 break;
8968 }
8969 else if (BUFFERP (it->object)
8970 && (it->method == GET_FROM_BUFFER
8971 || it->method == GET_FROM_STRETCH)
8972 && IT_CHARPOS (*it) >= to_charpos
8973 /* Under bidi iteration, a call to set_iterator_to_next
8974 can scan far beyond to_charpos if the initial
8975 portion of the next line needs to be reordered. In
8976 that case, give move_it_in_display_line_to another
8977 chance below. */
8978 && !(it->bidi_p
8979 && it->bidi_it.scan_dir == -1))
8980 skip = MOVE_POS_MATCH_OR_ZV;
8981 else
8982 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8983
8984 switch (skip)
8985 {
8986 case MOVE_POS_MATCH_OR_ZV:
8987 reached = 8;
8988 goto out;
8989
8990 case MOVE_NEWLINE_OR_CR:
8991 set_iterator_to_next (it, 1);
8992 it->continuation_lines_width = 0;
8993 break;
8994
8995 case MOVE_LINE_TRUNCATED:
8996 it->continuation_lines_width = 0;
8997 reseat_at_next_visible_line_start (it, 0);
8998 if ((op & MOVE_TO_POS) != 0
8999 && IT_CHARPOS (*it) > to_charpos)
9000 {
9001 reached = 9;
9002 goto out;
9003 }
9004 break;
9005
9006 case MOVE_LINE_CONTINUED:
9007 /* For continued lines ending in a tab, some of the glyphs
9008 associated with the tab are displayed on the current
9009 line. Since it->current_x does not include these glyphs,
9010 we use it->last_visible_x instead. */
9011 if (it->c == '\t')
9012 {
9013 it->continuation_lines_width += it->last_visible_x;
9014 /* When moving by vpos, ensure that the iterator really
9015 advances to the next line (bug#847, bug#969). Fixme:
9016 do we need to do this in other circumstances? */
9017 if (it->current_x != it->last_visible_x
9018 && (op & MOVE_TO_VPOS)
9019 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9020 {
9021 line_start_x = it->current_x + it->pixel_width
9022 - it->last_visible_x;
9023 set_iterator_to_next (it, 0);
9024 }
9025 }
9026 else
9027 it->continuation_lines_width += it->current_x;
9028 break;
9029
9030 default:
9031 emacs_abort ();
9032 }
9033
9034 /* Reset/increment for the next run. */
9035 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9036 it->current_x = line_start_x;
9037 line_start_x = 0;
9038 it->hpos = 0;
9039 it->current_y += it->max_ascent + it->max_descent;
9040 ++it->vpos;
9041 last_height = it->max_ascent + it->max_descent;
9042 it->max_ascent = it->max_descent = 0;
9043 }
9044
9045 out:
9046
9047 /* On text terminals, we may stop at the end of a line in the middle
9048 of a multi-character glyph. If the glyph itself is continued,
9049 i.e. it is actually displayed on the next line, don't treat this
9050 stopping point as valid; move to the next line instead (unless
9051 that brings us offscreen). */
9052 if (!FRAME_WINDOW_P (it->f)
9053 && op & MOVE_TO_POS
9054 && IT_CHARPOS (*it) == to_charpos
9055 && it->what == IT_CHARACTER
9056 && it->nglyphs > 1
9057 && it->line_wrap == WINDOW_WRAP
9058 && it->current_x == it->last_visible_x - 1
9059 && it->c != '\n'
9060 && it->c != '\t'
9061 && it->vpos < XFASTINT (it->w->window_end_vpos))
9062 {
9063 it->continuation_lines_width += it->current_x;
9064 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9065 it->current_y += it->max_ascent + it->max_descent;
9066 ++it->vpos;
9067 last_height = it->max_ascent + it->max_descent;
9068 }
9069
9070 if (backup_data)
9071 bidi_unshelve_cache (backup_data, 1);
9072
9073 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9074 }
9075
9076
9077 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9078
9079 If DY > 0, move IT backward at least that many pixels. DY = 0
9080 means move IT backward to the preceding line start or BEGV. This
9081 function may move over more than DY pixels if IT->current_y - DY
9082 ends up in the middle of a line; in this case IT->current_y will be
9083 set to the top of the line moved to. */
9084
9085 void
9086 move_it_vertically_backward (struct it *it, int dy)
9087 {
9088 int nlines, h;
9089 struct it it2, it3;
9090 void *it2data = NULL, *it3data = NULL;
9091 ptrdiff_t start_pos;
9092 int nchars_per_row
9093 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9094 ptrdiff_t pos_limit;
9095
9096 move_further_back:
9097 eassert (dy >= 0);
9098
9099 start_pos = IT_CHARPOS (*it);
9100
9101 /* Estimate how many newlines we must move back. */
9102 nlines = max (1, dy / default_line_pixel_height (it->w));
9103 if (it->line_wrap == TRUNCATE)
9104 pos_limit = BEGV;
9105 else
9106 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9107
9108 /* Set the iterator's position that many lines back. But don't go
9109 back more than NLINES full screen lines -- this wins a day with
9110 buffers which have very long lines. */
9111 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9112 back_to_previous_visible_line_start (it);
9113
9114 /* Reseat the iterator here. When moving backward, we don't want
9115 reseat to skip forward over invisible text, set up the iterator
9116 to deliver from overlay strings at the new position etc. So,
9117 use reseat_1 here. */
9118 reseat_1 (it, it->current.pos, 1);
9119
9120 /* We are now surely at a line start. */
9121 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9122 reordering is in effect. */
9123 it->continuation_lines_width = 0;
9124
9125 /* Move forward and see what y-distance we moved. First move to the
9126 start of the next line so that we get its height. We need this
9127 height to be able to tell whether we reached the specified
9128 y-distance. */
9129 SAVE_IT (it2, *it, it2data);
9130 it2.max_ascent = it2.max_descent = 0;
9131 do
9132 {
9133 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9134 MOVE_TO_POS | MOVE_TO_VPOS);
9135 }
9136 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9137 /* If we are in a display string which starts at START_POS,
9138 and that display string includes a newline, and we are
9139 right after that newline (i.e. at the beginning of a
9140 display line), exit the loop, because otherwise we will
9141 infloop, since move_it_to will see that it is already at
9142 START_POS and will not move. */
9143 || (it2.method == GET_FROM_STRING
9144 && IT_CHARPOS (it2) == start_pos
9145 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9146 eassert (IT_CHARPOS (*it) >= BEGV);
9147 SAVE_IT (it3, it2, it3data);
9148
9149 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9150 eassert (IT_CHARPOS (*it) >= BEGV);
9151 /* H is the actual vertical distance from the position in *IT
9152 and the starting position. */
9153 h = it2.current_y - it->current_y;
9154 /* NLINES is the distance in number of lines. */
9155 nlines = it2.vpos - it->vpos;
9156
9157 /* Correct IT's y and vpos position
9158 so that they are relative to the starting point. */
9159 it->vpos -= nlines;
9160 it->current_y -= h;
9161
9162 if (dy == 0)
9163 {
9164 /* DY == 0 means move to the start of the screen line. The
9165 value of nlines is > 0 if continuation lines were involved,
9166 or if the original IT position was at start of a line. */
9167 RESTORE_IT (it, it, it2data);
9168 if (nlines > 0)
9169 move_it_by_lines (it, nlines);
9170 /* The above code moves us to some position NLINES down,
9171 usually to its first glyph (leftmost in an L2R line), but
9172 that's not necessarily the start of the line, under bidi
9173 reordering. We want to get to the character position
9174 that is immediately after the newline of the previous
9175 line. */
9176 if (it->bidi_p
9177 && !it->continuation_lines_width
9178 && !STRINGP (it->string)
9179 && IT_CHARPOS (*it) > BEGV
9180 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9181 {
9182 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9183
9184 DEC_BOTH (cp, bp);
9185 cp = find_newline_no_quit (cp, bp, -1, NULL);
9186 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9187 }
9188 bidi_unshelve_cache (it3data, 1);
9189 }
9190 else
9191 {
9192 /* The y-position we try to reach, relative to *IT.
9193 Note that H has been subtracted in front of the if-statement. */
9194 int target_y = it->current_y + h - dy;
9195 int y0 = it3.current_y;
9196 int y1;
9197 int line_height;
9198
9199 RESTORE_IT (&it3, &it3, it3data);
9200 y1 = line_bottom_y (&it3);
9201 line_height = y1 - y0;
9202 RESTORE_IT (it, it, it2data);
9203 /* If we did not reach target_y, try to move further backward if
9204 we can. If we moved too far backward, try to move forward. */
9205 if (target_y < it->current_y
9206 /* This is heuristic. In a window that's 3 lines high, with
9207 a line height of 13 pixels each, recentering with point
9208 on the bottom line will try to move -39/2 = 19 pixels
9209 backward. Try to avoid moving into the first line. */
9210 && (it->current_y - target_y
9211 > min (window_box_height (it->w), line_height * 2 / 3))
9212 && IT_CHARPOS (*it) > BEGV)
9213 {
9214 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9215 target_y - it->current_y));
9216 dy = it->current_y - target_y;
9217 goto move_further_back;
9218 }
9219 else if (target_y >= it->current_y + line_height
9220 && IT_CHARPOS (*it) < ZV)
9221 {
9222 /* Should move forward by at least one line, maybe more.
9223
9224 Note: Calling move_it_by_lines can be expensive on
9225 terminal frames, where compute_motion is used (via
9226 vmotion) to do the job, when there are very long lines
9227 and truncate-lines is nil. That's the reason for
9228 treating terminal frames specially here. */
9229
9230 if (!FRAME_WINDOW_P (it->f))
9231 move_it_vertically (it, target_y - (it->current_y + line_height));
9232 else
9233 {
9234 do
9235 {
9236 move_it_by_lines (it, 1);
9237 }
9238 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9239 }
9240 }
9241 }
9242 }
9243
9244
9245 /* Move IT by a specified amount of pixel lines DY. DY negative means
9246 move backwards. DY = 0 means move to start of screen line. At the
9247 end, IT will be on the start of a screen line. */
9248
9249 void
9250 move_it_vertically (struct it *it, int dy)
9251 {
9252 if (dy <= 0)
9253 move_it_vertically_backward (it, -dy);
9254 else
9255 {
9256 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9257 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9258 MOVE_TO_POS | MOVE_TO_Y);
9259 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9260
9261 /* If buffer ends in ZV without a newline, move to the start of
9262 the line to satisfy the post-condition. */
9263 if (IT_CHARPOS (*it) == ZV
9264 && ZV > BEGV
9265 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9266 move_it_by_lines (it, 0);
9267 }
9268 }
9269
9270
9271 /* Move iterator IT past the end of the text line it is in. */
9272
9273 void
9274 move_it_past_eol (struct it *it)
9275 {
9276 enum move_it_result rc;
9277
9278 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9279 if (rc == MOVE_NEWLINE_OR_CR)
9280 set_iterator_to_next (it, 0);
9281 }
9282
9283
9284 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9285 negative means move up. DVPOS == 0 means move to the start of the
9286 screen line.
9287
9288 Optimization idea: If we would know that IT->f doesn't use
9289 a face with proportional font, we could be faster for
9290 truncate-lines nil. */
9291
9292 void
9293 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9294 {
9295
9296 /* The commented-out optimization uses vmotion on terminals. This
9297 gives bad results, because elements like it->what, on which
9298 callers such as pos_visible_p rely, aren't updated. */
9299 /* struct position pos;
9300 if (!FRAME_WINDOW_P (it->f))
9301 {
9302 struct text_pos textpos;
9303
9304 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9305 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9306 reseat (it, textpos, 1);
9307 it->vpos += pos.vpos;
9308 it->current_y += pos.vpos;
9309 }
9310 else */
9311
9312 if (dvpos == 0)
9313 {
9314 /* DVPOS == 0 means move to the start of the screen line. */
9315 move_it_vertically_backward (it, 0);
9316 /* Let next call to line_bottom_y calculate real line height */
9317 last_height = 0;
9318 }
9319 else if (dvpos > 0)
9320 {
9321 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9322 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9323 {
9324 /* Only move to the next buffer position if we ended up in a
9325 string from display property, not in an overlay string
9326 (before-string or after-string). That is because the
9327 latter don't conceal the underlying buffer position, so
9328 we can ask to move the iterator to the exact position we
9329 are interested in. Note that, even if we are already at
9330 IT_CHARPOS (*it), the call below is not a no-op, as it
9331 will detect that we are at the end of the string, pop the
9332 iterator, and compute it->current_x and it->hpos
9333 correctly. */
9334 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9335 -1, -1, -1, MOVE_TO_POS);
9336 }
9337 }
9338 else
9339 {
9340 struct it it2;
9341 void *it2data = NULL;
9342 ptrdiff_t start_charpos, i;
9343 int nchars_per_row
9344 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9345 ptrdiff_t pos_limit;
9346
9347 /* Start at the beginning of the screen line containing IT's
9348 position. This may actually move vertically backwards,
9349 in case of overlays, so adjust dvpos accordingly. */
9350 dvpos += it->vpos;
9351 move_it_vertically_backward (it, 0);
9352 dvpos -= it->vpos;
9353
9354 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9355 screen lines, and reseat the iterator there. */
9356 start_charpos = IT_CHARPOS (*it);
9357 if (it->line_wrap == TRUNCATE)
9358 pos_limit = BEGV;
9359 else
9360 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9361 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9362 back_to_previous_visible_line_start (it);
9363 reseat (it, it->current.pos, 1);
9364
9365 /* Move further back if we end up in a string or an image. */
9366 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9367 {
9368 /* First try to move to start of display line. */
9369 dvpos += it->vpos;
9370 move_it_vertically_backward (it, 0);
9371 dvpos -= it->vpos;
9372 if (IT_POS_VALID_AFTER_MOVE_P (it))
9373 break;
9374 /* If start of line is still in string or image,
9375 move further back. */
9376 back_to_previous_visible_line_start (it);
9377 reseat (it, it->current.pos, 1);
9378 dvpos--;
9379 }
9380
9381 it->current_x = it->hpos = 0;
9382
9383 /* Above call may have moved too far if continuation lines
9384 are involved. Scan forward and see if it did. */
9385 SAVE_IT (it2, *it, it2data);
9386 it2.vpos = it2.current_y = 0;
9387 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9388 it->vpos -= it2.vpos;
9389 it->current_y -= it2.current_y;
9390 it->current_x = it->hpos = 0;
9391
9392 /* If we moved too far back, move IT some lines forward. */
9393 if (it2.vpos > -dvpos)
9394 {
9395 int delta = it2.vpos + dvpos;
9396
9397 RESTORE_IT (&it2, &it2, it2data);
9398 SAVE_IT (it2, *it, it2data);
9399 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9400 /* Move back again if we got too far ahead. */
9401 if (IT_CHARPOS (*it) >= start_charpos)
9402 RESTORE_IT (it, &it2, it2data);
9403 else
9404 bidi_unshelve_cache (it2data, 1);
9405 }
9406 else
9407 RESTORE_IT (it, it, it2data);
9408 }
9409 }
9410
9411 /* Return 1 if IT points into the middle of a display vector. */
9412
9413 int
9414 in_display_vector_p (struct it *it)
9415 {
9416 return (it->method == GET_FROM_DISPLAY_VECTOR
9417 && it->current.dpvec_index > 0
9418 && it->dpvec + it->current.dpvec_index != it->dpend);
9419 }
9420
9421 \f
9422 /***********************************************************************
9423 Messages
9424 ***********************************************************************/
9425
9426
9427 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9428 to *Messages*. */
9429
9430 void
9431 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9432 {
9433 Lisp_Object args[3];
9434 Lisp_Object msg, fmt;
9435 char *buffer;
9436 ptrdiff_t len;
9437 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9438 USE_SAFE_ALLOCA;
9439
9440 fmt = msg = Qnil;
9441 GCPRO4 (fmt, msg, arg1, arg2);
9442
9443 args[0] = fmt = build_string (format);
9444 args[1] = arg1;
9445 args[2] = arg2;
9446 msg = Fformat (3, args);
9447
9448 len = SBYTES (msg) + 1;
9449 buffer = SAFE_ALLOCA (len);
9450 memcpy (buffer, SDATA (msg), len);
9451
9452 message_dolog (buffer, len - 1, 1, 0);
9453 SAFE_FREE ();
9454
9455 UNGCPRO;
9456 }
9457
9458
9459 /* Output a newline in the *Messages* buffer if "needs" one. */
9460
9461 void
9462 message_log_maybe_newline (void)
9463 {
9464 if (message_log_need_newline)
9465 message_dolog ("", 0, 1, 0);
9466 }
9467
9468
9469 /* Add a string M of length NBYTES to the message log, optionally
9470 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9471 true, means interpret the contents of M as multibyte. This
9472 function calls low-level routines in order to bypass text property
9473 hooks, etc. which might not be safe to run.
9474
9475 This may GC (insert may run before/after change hooks),
9476 so the buffer M must NOT point to a Lisp string. */
9477
9478 void
9479 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9480 {
9481 const unsigned char *msg = (const unsigned char *) m;
9482
9483 if (!NILP (Vmemory_full))
9484 return;
9485
9486 if (!NILP (Vmessage_log_max))
9487 {
9488 struct buffer *oldbuf;
9489 Lisp_Object oldpoint, oldbegv, oldzv;
9490 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9491 ptrdiff_t point_at_end = 0;
9492 ptrdiff_t zv_at_end = 0;
9493 Lisp_Object old_deactivate_mark;
9494 bool shown;
9495 struct gcpro gcpro1;
9496
9497 old_deactivate_mark = Vdeactivate_mark;
9498 oldbuf = current_buffer;
9499 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9500 bset_undo_list (current_buffer, Qt);
9501
9502 oldpoint = message_dolog_marker1;
9503 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9504 oldbegv = message_dolog_marker2;
9505 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9506 oldzv = message_dolog_marker3;
9507 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9508 GCPRO1 (old_deactivate_mark);
9509
9510 if (PT == Z)
9511 point_at_end = 1;
9512 if (ZV == Z)
9513 zv_at_end = 1;
9514
9515 BEGV = BEG;
9516 BEGV_BYTE = BEG_BYTE;
9517 ZV = Z;
9518 ZV_BYTE = Z_BYTE;
9519 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9520
9521 /* Insert the string--maybe converting multibyte to single byte
9522 or vice versa, so that all the text fits the buffer. */
9523 if (multibyte
9524 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9525 {
9526 ptrdiff_t i;
9527 int c, char_bytes;
9528 char work[1];
9529
9530 /* Convert a multibyte string to single-byte
9531 for the *Message* buffer. */
9532 for (i = 0; i < nbytes; i += char_bytes)
9533 {
9534 c = string_char_and_length (msg + i, &char_bytes);
9535 work[0] = (ASCII_CHAR_P (c)
9536 ? c
9537 : multibyte_char_to_unibyte (c));
9538 insert_1_both (work, 1, 1, 1, 0, 0);
9539 }
9540 }
9541 else if (! multibyte
9542 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9543 {
9544 ptrdiff_t i;
9545 int c, char_bytes;
9546 unsigned char str[MAX_MULTIBYTE_LENGTH];
9547 /* Convert a single-byte string to multibyte
9548 for the *Message* buffer. */
9549 for (i = 0; i < nbytes; i++)
9550 {
9551 c = msg[i];
9552 MAKE_CHAR_MULTIBYTE (c);
9553 char_bytes = CHAR_STRING (c, str);
9554 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9555 }
9556 }
9557 else if (nbytes)
9558 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9559
9560 if (nlflag)
9561 {
9562 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9563 printmax_t dups;
9564
9565 insert_1_both ("\n", 1, 1, 1, 0, 0);
9566
9567 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9568 this_bol = PT;
9569 this_bol_byte = PT_BYTE;
9570
9571 /* See if this line duplicates the previous one.
9572 If so, combine duplicates. */
9573 if (this_bol > BEG)
9574 {
9575 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9576 prev_bol = PT;
9577 prev_bol_byte = PT_BYTE;
9578
9579 dups = message_log_check_duplicate (prev_bol_byte,
9580 this_bol_byte);
9581 if (dups)
9582 {
9583 del_range_both (prev_bol, prev_bol_byte,
9584 this_bol, this_bol_byte, 0);
9585 if (dups > 1)
9586 {
9587 char dupstr[sizeof " [ times]"
9588 + INT_STRLEN_BOUND (printmax_t)];
9589
9590 /* If you change this format, don't forget to also
9591 change message_log_check_duplicate. */
9592 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9593 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9594 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9595 }
9596 }
9597 }
9598
9599 /* If we have more than the desired maximum number of lines
9600 in the *Messages* buffer now, delete the oldest ones.
9601 This is safe because we don't have undo in this buffer. */
9602
9603 if (NATNUMP (Vmessage_log_max))
9604 {
9605 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9606 -XFASTINT (Vmessage_log_max) - 1, 0);
9607 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9608 }
9609 }
9610 BEGV = marker_position (oldbegv);
9611 BEGV_BYTE = marker_byte_position (oldbegv);
9612
9613 if (zv_at_end)
9614 {
9615 ZV = Z;
9616 ZV_BYTE = Z_BYTE;
9617 }
9618 else
9619 {
9620 ZV = marker_position (oldzv);
9621 ZV_BYTE = marker_byte_position (oldzv);
9622 }
9623
9624 if (point_at_end)
9625 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9626 else
9627 /* We can't do Fgoto_char (oldpoint) because it will run some
9628 Lisp code. */
9629 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9630 marker_byte_position (oldpoint));
9631
9632 UNGCPRO;
9633 unchain_marker (XMARKER (oldpoint));
9634 unchain_marker (XMARKER (oldbegv));
9635 unchain_marker (XMARKER (oldzv));
9636
9637 shown = buffer_window_count (current_buffer) > 0;
9638 set_buffer_internal (oldbuf);
9639 /* We called insert_1_both above with its 5th argument (PREPARE)
9640 zero, which prevents insert_1_both from calling
9641 prepare_to_modify_buffer, which in turns prevents us from
9642 incrementing windows_or_buffers_changed even if *Messages* is
9643 shown in some window. So we must manually incrementing
9644 windows_or_buffers_changed here to make up for that. */
9645 if (shown)
9646 windows_or_buffers_changed++;
9647 else
9648 windows_or_buffers_changed = old_windows_or_buffers_changed;
9649 message_log_need_newline = !nlflag;
9650 Vdeactivate_mark = old_deactivate_mark;
9651 }
9652 }
9653
9654
9655 /* We are at the end of the buffer after just having inserted a newline.
9656 (Note: We depend on the fact we won't be crossing the gap.)
9657 Check to see if the most recent message looks a lot like the previous one.
9658 Return 0 if different, 1 if the new one should just replace it, or a
9659 value N > 1 if we should also append " [N times]". */
9660
9661 static intmax_t
9662 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9663 {
9664 ptrdiff_t i;
9665 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9666 int seen_dots = 0;
9667 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9668 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9669
9670 for (i = 0; i < len; i++)
9671 {
9672 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9673 seen_dots = 1;
9674 if (p1[i] != p2[i])
9675 return seen_dots;
9676 }
9677 p1 += len;
9678 if (*p1 == '\n')
9679 return 2;
9680 if (*p1++ == ' ' && *p1++ == '[')
9681 {
9682 char *pend;
9683 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9684 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9685 return n + 1;
9686 }
9687 return 0;
9688 }
9689 \f
9690
9691 /* Display an echo area message M with a specified length of NBYTES
9692 bytes. The string may include null characters. If M is not a
9693 string, clear out any existing message, and let the mini-buffer
9694 text show through.
9695
9696 This function cancels echoing. */
9697
9698 void
9699 message3 (Lisp_Object m)
9700 {
9701 struct gcpro gcpro1;
9702
9703 GCPRO1 (m);
9704 clear_message (1,1);
9705 cancel_echoing ();
9706
9707 /* First flush out any partial line written with print. */
9708 message_log_maybe_newline ();
9709 if (STRINGP (m))
9710 {
9711 ptrdiff_t nbytes = SBYTES (m);
9712 bool multibyte = STRING_MULTIBYTE (m);
9713 USE_SAFE_ALLOCA;
9714 char *buffer = SAFE_ALLOCA (nbytes);
9715 memcpy (buffer, SDATA (m), nbytes);
9716 message_dolog (buffer, nbytes, 1, multibyte);
9717 SAFE_FREE ();
9718 }
9719 message3_nolog (m);
9720
9721 UNGCPRO;
9722 }
9723
9724
9725 /* The non-logging version of message3.
9726 This does not cancel echoing, because it is used for echoing.
9727 Perhaps we need to make a separate function for echoing
9728 and make this cancel echoing. */
9729
9730 void
9731 message3_nolog (Lisp_Object m)
9732 {
9733 struct frame *sf = SELECTED_FRAME ();
9734
9735 if (FRAME_INITIAL_P (sf))
9736 {
9737 if (noninteractive_need_newline)
9738 putc ('\n', stderr);
9739 noninteractive_need_newline = 0;
9740 if (STRINGP (m))
9741 fwrite (SDATA (m), SBYTES (m), 1, stderr);
9742 if (cursor_in_echo_area == 0)
9743 fprintf (stderr, "\n");
9744 fflush (stderr);
9745 }
9746 /* Error messages get reported properly by cmd_error, so this must be just an
9747 informative message; if the frame hasn't really been initialized yet, just
9748 toss it. */
9749 else if (INTERACTIVE && sf->glyphs_initialized_p)
9750 {
9751 /* Get the frame containing the mini-buffer
9752 that the selected frame is using. */
9753 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9754 Lisp_Object frame = XWINDOW (mini_window)->frame;
9755 struct frame *f = XFRAME (frame);
9756
9757 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9758 Fmake_frame_visible (frame);
9759
9760 if (STRINGP (m) && SCHARS (m) > 0)
9761 {
9762 set_message (m);
9763 if (minibuffer_auto_raise)
9764 Fraise_frame (frame);
9765 /* Assume we are not echoing.
9766 (If we are, echo_now will override this.) */
9767 echo_message_buffer = Qnil;
9768 }
9769 else
9770 clear_message (1, 1);
9771
9772 do_pending_window_change (0);
9773 echo_area_display (1);
9774 do_pending_window_change (0);
9775 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9776 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9777 }
9778 }
9779
9780
9781 /* Display a null-terminated echo area message M. If M is 0, clear
9782 out any existing message, and let the mini-buffer text show through.
9783
9784 The buffer M must continue to exist until after the echo area gets
9785 cleared or some other message gets displayed there. Do not pass
9786 text that is stored in a Lisp string. Do not pass text in a buffer
9787 that was alloca'd. */
9788
9789 void
9790 message1 (const char *m)
9791 {
9792 message3 (m ? build_unibyte_string (m) : Qnil);
9793 }
9794
9795
9796 /* The non-logging counterpart of message1. */
9797
9798 void
9799 message1_nolog (const char *m)
9800 {
9801 message3_nolog (m ? build_unibyte_string (m) : Qnil);
9802 }
9803
9804 /* Display a message M which contains a single %s
9805 which gets replaced with STRING. */
9806
9807 void
9808 message_with_string (const char *m, Lisp_Object string, int log)
9809 {
9810 CHECK_STRING (string);
9811
9812 if (noninteractive)
9813 {
9814 if (m)
9815 {
9816 if (noninteractive_need_newline)
9817 putc ('\n', stderr);
9818 noninteractive_need_newline = 0;
9819 fprintf (stderr, m, SDATA (string));
9820 if (!cursor_in_echo_area)
9821 fprintf (stderr, "\n");
9822 fflush (stderr);
9823 }
9824 }
9825 else if (INTERACTIVE)
9826 {
9827 /* The frame whose minibuffer we're going to display the message on.
9828 It may be larger than the selected frame, so we need
9829 to use its buffer, not the selected frame's buffer. */
9830 Lisp_Object mini_window;
9831 struct frame *f, *sf = SELECTED_FRAME ();
9832
9833 /* Get the frame containing the minibuffer
9834 that the selected frame is using. */
9835 mini_window = FRAME_MINIBUF_WINDOW (sf);
9836 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9837
9838 /* Error messages get reported properly by cmd_error, so this must be
9839 just an informative message; if the frame hasn't really been
9840 initialized yet, just toss it. */
9841 if (f->glyphs_initialized_p)
9842 {
9843 Lisp_Object args[2], msg;
9844 struct gcpro gcpro1, gcpro2;
9845
9846 args[0] = build_string (m);
9847 args[1] = msg = string;
9848 GCPRO2 (args[0], msg);
9849 gcpro1.nvars = 2;
9850
9851 msg = Fformat (2, args);
9852
9853 if (log)
9854 message3 (msg);
9855 else
9856 message3_nolog (msg);
9857
9858 UNGCPRO;
9859
9860 /* Print should start at the beginning of the message
9861 buffer next time. */
9862 message_buf_print = 0;
9863 }
9864 }
9865 }
9866
9867
9868 /* Dump an informative message to the minibuf. If M is 0, clear out
9869 any existing message, and let the mini-buffer text show through. */
9870
9871 static void
9872 vmessage (const char *m, va_list ap)
9873 {
9874 if (noninteractive)
9875 {
9876 if (m)
9877 {
9878 if (noninteractive_need_newline)
9879 putc ('\n', stderr);
9880 noninteractive_need_newline = 0;
9881 vfprintf (stderr, m, ap);
9882 if (cursor_in_echo_area == 0)
9883 fprintf (stderr, "\n");
9884 fflush (stderr);
9885 }
9886 }
9887 else if (INTERACTIVE)
9888 {
9889 /* The frame whose mini-buffer we're going to display the message
9890 on. It may be larger than the selected frame, so we need to
9891 use its buffer, not the selected frame's buffer. */
9892 Lisp_Object mini_window;
9893 struct frame *f, *sf = SELECTED_FRAME ();
9894
9895 /* Get the frame containing the mini-buffer
9896 that the selected frame is using. */
9897 mini_window = FRAME_MINIBUF_WINDOW (sf);
9898 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9899
9900 /* Error messages get reported properly by cmd_error, so this must be
9901 just an informative message; if the frame hasn't really been
9902 initialized yet, just toss it. */
9903 if (f->glyphs_initialized_p)
9904 {
9905 if (m)
9906 {
9907 ptrdiff_t len;
9908 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9909 char *message_buf = alloca (maxsize + 1);
9910
9911 len = doprnt (message_buf, maxsize, m, 0, ap);
9912
9913 message3 (make_string (message_buf, len));
9914 }
9915 else
9916 message1 (0);
9917
9918 /* Print should start at the beginning of the message
9919 buffer next time. */
9920 message_buf_print = 0;
9921 }
9922 }
9923 }
9924
9925 void
9926 message (const char *m, ...)
9927 {
9928 va_list ap;
9929 va_start (ap, m);
9930 vmessage (m, ap);
9931 va_end (ap);
9932 }
9933
9934
9935 #if 0
9936 /* The non-logging version of message. */
9937
9938 void
9939 message_nolog (const char *m, ...)
9940 {
9941 Lisp_Object old_log_max;
9942 va_list ap;
9943 va_start (ap, m);
9944 old_log_max = Vmessage_log_max;
9945 Vmessage_log_max = Qnil;
9946 vmessage (m, ap);
9947 Vmessage_log_max = old_log_max;
9948 va_end (ap);
9949 }
9950 #endif
9951
9952
9953 /* Display the current message in the current mini-buffer. This is
9954 only called from error handlers in process.c, and is not time
9955 critical. */
9956
9957 void
9958 update_echo_area (void)
9959 {
9960 if (!NILP (echo_area_buffer[0]))
9961 {
9962 Lisp_Object string;
9963 string = Fcurrent_message ();
9964 message3 (string);
9965 }
9966 }
9967
9968
9969 /* Make sure echo area buffers in `echo_buffers' are live.
9970 If they aren't, make new ones. */
9971
9972 static void
9973 ensure_echo_area_buffers (void)
9974 {
9975 int i;
9976
9977 for (i = 0; i < 2; ++i)
9978 if (!BUFFERP (echo_buffer[i])
9979 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
9980 {
9981 char name[30];
9982 Lisp_Object old_buffer;
9983 int j;
9984
9985 old_buffer = echo_buffer[i];
9986 echo_buffer[i] = Fget_buffer_create
9987 (make_formatted_string (name, " *Echo Area %d*", i));
9988 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
9989 /* to force word wrap in echo area -
9990 it was decided to postpone this*/
9991 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9992
9993 for (j = 0; j < 2; ++j)
9994 if (EQ (old_buffer, echo_area_buffer[j]))
9995 echo_area_buffer[j] = echo_buffer[i];
9996 }
9997 }
9998
9999
10000 /* Call FN with args A1..A2 with either the current or last displayed
10001 echo_area_buffer as current buffer.
10002
10003 WHICH zero means use the current message buffer
10004 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10005 from echo_buffer[] and clear it.
10006
10007 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10008 suitable buffer from echo_buffer[] and clear it.
10009
10010 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10011 that the current message becomes the last displayed one, make
10012 choose a suitable buffer for echo_area_buffer[0], and clear it.
10013
10014 Value is what FN returns. */
10015
10016 static int
10017 with_echo_area_buffer (struct window *w, int which,
10018 int (*fn) (ptrdiff_t, Lisp_Object),
10019 ptrdiff_t a1, Lisp_Object a2)
10020 {
10021 Lisp_Object buffer;
10022 int this_one, the_other, clear_buffer_p, rc;
10023 ptrdiff_t count = SPECPDL_INDEX ();
10024
10025 /* If buffers aren't live, make new ones. */
10026 ensure_echo_area_buffers ();
10027
10028 clear_buffer_p = 0;
10029
10030 if (which == 0)
10031 this_one = 0, the_other = 1;
10032 else if (which > 0)
10033 this_one = 1, the_other = 0;
10034 else
10035 {
10036 this_one = 0, the_other = 1;
10037 clear_buffer_p = 1;
10038
10039 /* We need a fresh one in case the current echo buffer equals
10040 the one containing the last displayed echo area message. */
10041 if (!NILP (echo_area_buffer[this_one])
10042 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10043 echo_area_buffer[this_one] = Qnil;
10044 }
10045
10046 /* Choose a suitable buffer from echo_buffer[] is we don't
10047 have one. */
10048 if (NILP (echo_area_buffer[this_one]))
10049 {
10050 echo_area_buffer[this_one]
10051 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10052 ? echo_buffer[the_other]
10053 : echo_buffer[this_one]);
10054 clear_buffer_p = 1;
10055 }
10056
10057 buffer = echo_area_buffer[this_one];
10058
10059 /* Don't get confused by reusing the buffer used for echoing
10060 for a different purpose. */
10061 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10062 cancel_echoing ();
10063
10064 record_unwind_protect (unwind_with_echo_area_buffer,
10065 with_echo_area_buffer_unwind_data (w));
10066
10067 /* Make the echo area buffer current. Note that for display
10068 purposes, it is not necessary that the displayed window's buffer
10069 == current_buffer, except for text property lookup. So, let's
10070 only set that buffer temporarily here without doing a full
10071 Fset_window_buffer. We must also change w->pointm, though,
10072 because otherwise an assertions in unshow_buffer fails, and Emacs
10073 aborts. */
10074 set_buffer_internal_1 (XBUFFER (buffer));
10075 if (w)
10076 {
10077 wset_buffer (w, buffer);
10078 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10079 }
10080
10081 bset_undo_list (current_buffer, Qt);
10082 bset_read_only (current_buffer, Qnil);
10083 specbind (Qinhibit_read_only, Qt);
10084 specbind (Qinhibit_modification_hooks, Qt);
10085
10086 if (clear_buffer_p && Z > BEG)
10087 del_range (BEG, Z);
10088
10089 eassert (BEGV >= BEG);
10090 eassert (ZV <= Z && ZV >= BEGV);
10091
10092 rc = fn (a1, a2);
10093
10094 eassert (BEGV >= BEG);
10095 eassert (ZV <= Z && ZV >= BEGV);
10096
10097 unbind_to (count, Qnil);
10098 return rc;
10099 }
10100
10101
10102 /* Save state that should be preserved around the call to the function
10103 FN called in with_echo_area_buffer. */
10104
10105 static Lisp_Object
10106 with_echo_area_buffer_unwind_data (struct window *w)
10107 {
10108 int i = 0;
10109 Lisp_Object vector, tmp;
10110
10111 /* Reduce consing by keeping one vector in
10112 Vwith_echo_area_save_vector. */
10113 vector = Vwith_echo_area_save_vector;
10114 Vwith_echo_area_save_vector = Qnil;
10115
10116 if (NILP (vector))
10117 vector = Fmake_vector (make_number (9), Qnil);
10118
10119 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10120 ASET (vector, i, Vdeactivate_mark); ++i;
10121 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10122
10123 if (w)
10124 {
10125 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10126 ASET (vector, i, w->contents); ++i;
10127 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10128 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10129 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10130 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10131 }
10132 else
10133 {
10134 int end = i + 6;
10135 for (; i < end; ++i)
10136 ASET (vector, i, Qnil);
10137 }
10138
10139 eassert (i == ASIZE (vector));
10140 return vector;
10141 }
10142
10143
10144 /* Restore global state from VECTOR which was created by
10145 with_echo_area_buffer_unwind_data. */
10146
10147 static void
10148 unwind_with_echo_area_buffer (Lisp_Object vector)
10149 {
10150 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10151 Vdeactivate_mark = AREF (vector, 1);
10152 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10153
10154 if (WINDOWP (AREF (vector, 3)))
10155 {
10156 struct window *w;
10157 Lisp_Object buffer;
10158
10159 w = XWINDOW (AREF (vector, 3));
10160 buffer = AREF (vector, 4);
10161
10162 wset_buffer (w, buffer);
10163 set_marker_both (w->pointm, buffer,
10164 XFASTINT (AREF (vector, 5)),
10165 XFASTINT (AREF (vector, 6)));
10166 set_marker_both (w->start, buffer,
10167 XFASTINT (AREF (vector, 7)),
10168 XFASTINT (AREF (vector, 8)));
10169 }
10170
10171 Vwith_echo_area_save_vector = vector;
10172 }
10173
10174
10175 /* Set up the echo area for use by print functions. MULTIBYTE_P
10176 non-zero means we will print multibyte. */
10177
10178 void
10179 setup_echo_area_for_printing (int multibyte_p)
10180 {
10181 /* If we can't find an echo area any more, exit. */
10182 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10183 Fkill_emacs (Qnil);
10184
10185 ensure_echo_area_buffers ();
10186
10187 if (!message_buf_print)
10188 {
10189 /* A message has been output since the last time we printed.
10190 Choose a fresh echo area buffer. */
10191 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10192 echo_area_buffer[0] = echo_buffer[1];
10193 else
10194 echo_area_buffer[0] = echo_buffer[0];
10195
10196 /* Switch to that buffer and clear it. */
10197 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10198 bset_truncate_lines (current_buffer, Qnil);
10199
10200 if (Z > BEG)
10201 {
10202 ptrdiff_t count = SPECPDL_INDEX ();
10203 specbind (Qinhibit_read_only, Qt);
10204 /* Note that undo recording is always disabled. */
10205 del_range (BEG, Z);
10206 unbind_to (count, Qnil);
10207 }
10208 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10209
10210 /* Set up the buffer for the multibyteness we need. */
10211 if (multibyte_p
10212 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10213 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10214
10215 /* Raise the frame containing the echo area. */
10216 if (minibuffer_auto_raise)
10217 {
10218 struct frame *sf = SELECTED_FRAME ();
10219 Lisp_Object mini_window;
10220 mini_window = FRAME_MINIBUF_WINDOW (sf);
10221 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10222 }
10223
10224 message_log_maybe_newline ();
10225 message_buf_print = 1;
10226 }
10227 else
10228 {
10229 if (NILP (echo_area_buffer[0]))
10230 {
10231 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10232 echo_area_buffer[0] = echo_buffer[1];
10233 else
10234 echo_area_buffer[0] = echo_buffer[0];
10235 }
10236
10237 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10238 {
10239 /* Someone switched buffers between print requests. */
10240 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10241 bset_truncate_lines (current_buffer, Qnil);
10242 }
10243 }
10244 }
10245
10246
10247 /* Display an echo area message in window W. Value is non-zero if W's
10248 height is changed. If display_last_displayed_message_p is
10249 non-zero, display the message that was last displayed, otherwise
10250 display the current message. */
10251
10252 static int
10253 display_echo_area (struct window *w)
10254 {
10255 int i, no_message_p, window_height_changed_p;
10256
10257 /* Temporarily disable garbage collections while displaying the echo
10258 area. This is done because a GC can print a message itself.
10259 That message would modify the echo area buffer's contents while a
10260 redisplay of the buffer is going on, and seriously confuse
10261 redisplay. */
10262 ptrdiff_t count = inhibit_garbage_collection ();
10263
10264 /* If there is no message, we must call display_echo_area_1
10265 nevertheless because it resizes the window. But we will have to
10266 reset the echo_area_buffer in question to nil at the end because
10267 with_echo_area_buffer will sets it to an empty buffer. */
10268 i = display_last_displayed_message_p ? 1 : 0;
10269 no_message_p = NILP (echo_area_buffer[i]);
10270
10271 window_height_changed_p
10272 = with_echo_area_buffer (w, display_last_displayed_message_p,
10273 display_echo_area_1,
10274 (intptr_t) w, Qnil);
10275
10276 if (no_message_p)
10277 echo_area_buffer[i] = Qnil;
10278
10279 unbind_to (count, Qnil);
10280 return window_height_changed_p;
10281 }
10282
10283
10284 /* Helper for display_echo_area. Display the current buffer which
10285 contains the current echo area message in window W, a mini-window,
10286 a pointer to which is passed in A1. A2..A4 are currently not used.
10287 Change the height of W so that all of the message is displayed.
10288 Value is non-zero if height of W was changed. */
10289
10290 static int
10291 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10292 {
10293 intptr_t i1 = a1;
10294 struct window *w = (struct window *) i1;
10295 Lisp_Object window;
10296 struct text_pos start;
10297 int window_height_changed_p = 0;
10298
10299 /* Do this before displaying, so that we have a large enough glyph
10300 matrix for the display. If we can't get enough space for the
10301 whole text, display the last N lines. That works by setting w->start. */
10302 window_height_changed_p = resize_mini_window (w, 0);
10303
10304 /* Use the starting position chosen by resize_mini_window. */
10305 SET_TEXT_POS_FROM_MARKER (start, w->start);
10306
10307 /* Display. */
10308 clear_glyph_matrix (w->desired_matrix);
10309 XSETWINDOW (window, w);
10310 try_window (window, start, 0);
10311
10312 return window_height_changed_p;
10313 }
10314
10315
10316 /* Resize the echo area window to exactly the size needed for the
10317 currently displayed message, if there is one. If a mini-buffer
10318 is active, don't shrink it. */
10319
10320 void
10321 resize_echo_area_exactly (void)
10322 {
10323 if (BUFFERP (echo_area_buffer[0])
10324 && WINDOWP (echo_area_window))
10325 {
10326 struct window *w = XWINDOW (echo_area_window);
10327 int resized_p;
10328 Lisp_Object resize_exactly;
10329
10330 if (minibuf_level == 0)
10331 resize_exactly = Qt;
10332 else
10333 resize_exactly = Qnil;
10334
10335 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10336 (intptr_t) w, resize_exactly);
10337 if (resized_p)
10338 {
10339 ++windows_or_buffers_changed;
10340 ++update_mode_lines;
10341 redisplay_internal ();
10342 }
10343 }
10344 }
10345
10346
10347 /* Callback function for with_echo_area_buffer, when used from
10348 resize_echo_area_exactly. A1 contains a pointer to the window to
10349 resize, EXACTLY non-nil means resize the mini-window exactly to the
10350 size of the text displayed. A3 and A4 are not used. Value is what
10351 resize_mini_window returns. */
10352
10353 static int
10354 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10355 {
10356 intptr_t i1 = a1;
10357 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10358 }
10359
10360
10361 /* Resize mini-window W to fit the size of its contents. EXACT_P
10362 means size the window exactly to the size needed. Otherwise, it's
10363 only enlarged until W's buffer is empty.
10364
10365 Set W->start to the right place to begin display. If the whole
10366 contents fit, start at the beginning. Otherwise, start so as
10367 to make the end of the contents appear. This is particularly
10368 important for y-or-n-p, but seems desirable generally.
10369
10370 Value is non-zero if the window height has been changed. */
10371
10372 int
10373 resize_mini_window (struct window *w, int exact_p)
10374 {
10375 struct frame *f = XFRAME (w->frame);
10376 int window_height_changed_p = 0;
10377
10378 eassert (MINI_WINDOW_P (w));
10379
10380 /* By default, start display at the beginning. */
10381 set_marker_both (w->start, w->contents,
10382 BUF_BEGV (XBUFFER (w->contents)),
10383 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10384
10385 /* Don't resize windows while redisplaying a window; it would
10386 confuse redisplay functions when the size of the window they are
10387 displaying changes from under them. Such a resizing can happen,
10388 for instance, when which-func prints a long message while
10389 we are running fontification-functions. We're running these
10390 functions with safe_call which binds inhibit-redisplay to t. */
10391 if (!NILP (Vinhibit_redisplay))
10392 return 0;
10393
10394 /* Nil means don't try to resize. */
10395 if (NILP (Vresize_mini_windows)
10396 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10397 return 0;
10398
10399 if (!FRAME_MINIBUF_ONLY_P (f))
10400 {
10401 struct it it;
10402 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10403 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10404 int height;
10405 EMACS_INT max_height;
10406 int unit = FRAME_LINE_HEIGHT (f);
10407 struct text_pos start;
10408 struct buffer *old_current_buffer = NULL;
10409
10410 if (current_buffer != XBUFFER (w->contents))
10411 {
10412 old_current_buffer = current_buffer;
10413 set_buffer_internal (XBUFFER (w->contents));
10414 }
10415
10416 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10417
10418 /* Compute the max. number of lines specified by the user. */
10419 if (FLOATP (Vmax_mini_window_height))
10420 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10421 else if (INTEGERP (Vmax_mini_window_height))
10422 max_height = XINT (Vmax_mini_window_height);
10423 else
10424 max_height = total_height / 4;
10425
10426 /* Correct that max. height if it's bogus. */
10427 max_height = clip_to_bounds (1, max_height, total_height);
10428
10429 /* Find out the height of the text in the window. */
10430 if (it.line_wrap == TRUNCATE)
10431 height = 1;
10432 else
10433 {
10434 last_height = 0;
10435 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10436 if (it.max_ascent == 0 && it.max_descent == 0)
10437 height = it.current_y + last_height;
10438 else
10439 height = it.current_y + it.max_ascent + it.max_descent;
10440 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10441 height = (height + unit - 1) / unit;
10442 }
10443
10444 /* Compute a suitable window start. */
10445 if (height > max_height)
10446 {
10447 height = max_height;
10448 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10449 move_it_vertically_backward (&it, (height - 1) * unit);
10450 start = it.current.pos;
10451 }
10452 else
10453 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10454 SET_MARKER_FROM_TEXT_POS (w->start, start);
10455
10456 if (EQ (Vresize_mini_windows, Qgrow_only))
10457 {
10458 /* Let it grow only, until we display an empty message, in which
10459 case the window shrinks again. */
10460 if (height > WINDOW_TOTAL_LINES (w))
10461 {
10462 int old_height = WINDOW_TOTAL_LINES (w);
10463
10464 FRAME_WINDOWS_FROZEN (f) = 1;
10465 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10466 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10467 }
10468 else if (height < WINDOW_TOTAL_LINES (w)
10469 && (exact_p || BEGV == ZV))
10470 {
10471 int old_height = WINDOW_TOTAL_LINES (w);
10472
10473 FRAME_WINDOWS_FROZEN (f) = 0;
10474 shrink_mini_window (w);
10475 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10476 }
10477 }
10478 else
10479 {
10480 /* Always resize to exact size needed. */
10481 if (height > WINDOW_TOTAL_LINES (w))
10482 {
10483 int old_height = WINDOW_TOTAL_LINES (w);
10484
10485 FRAME_WINDOWS_FROZEN (f) = 1;
10486 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10487 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10488 }
10489 else if (height < WINDOW_TOTAL_LINES (w))
10490 {
10491 int old_height = WINDOW_TOTAL_LINES (w);
10492
10493 FRAME_WINDOWS_FROZEN (f) = 0;
10494 shrink_mini_window (w);
10495
10496 if (height)
10497 {
10498 FRAME_WINDOWS_FROZEN (f) = 1;
10499 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10500 }
10501
10502 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10503 }
10504 }
10505
10506 if (old_current_buffer)
10507 set_buffer_internal (old_current_buffer);
10508 }
10509
10510 return window_height_changed_p;
10511 }
10512
10513
10514 /* Value is the current message, a string, or nil if there is no
10515 current message. */
10516
10517 Lisp_Object
10518 current_message (void)
10519 {
10520 Lisp_Object msg;
10521
10522 if (!BUFFERP (echo_area_buffer[0]))
10523 msg = Qnil;
10524 else
10525 {
10526 with_echo_area_buffer (0, 0, current_message_1,
10527 (intptr_t) &msg, Qnil);
10528 if (NILP (msg))
10529 echo_area_buffer[0] = Qnil;
10530 }
10531
10532 return msg;
10533 }
10534
10535
10536 static int
10537 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10538 {
10539 intptr_t i1 = a1;
10540 Lisp_Object *msg = (Lisp_Object *) i1;
10541
10542 if (Z > BEG)
10543 *msg = make_buffer_string (BEG, Z, 1);
10544 else
10545 *msg = Qnil;
10546 return 0;
10547 }
10548
10549
10550 /* Push the current message on Vmessage_stack for later restoration
10551 by restore_message. Value is non-zero if the current message isn't
10552 empty. This is a relatively infrequent operation, so it's not
10553 worth optimizing. */
10554
10555 bool
10556 push_message (void)
10557 {
10558 Lisp_Object msg = current_message ();
10559 Vmessage_stack = Fcons (msg, Vmessage_stack);
10560 return STRINGP (msg);
10561 }
10562
10563
10564 /* Restore message display from the top of Vmessage_stack. */
10565
10566 void
10567 restore_message (void)
10568 {
10569 eassert (CONSP (Vmessage_stack));
10570 message3_nolog (XCAR (Vmessage_stack));
10571 }
10572
10573
10574 /* Handler for unwind-protect calling pop_message. */
10575
10576 void
10577 pop_message_unwind (void)
10578 {
10579 /* Pop the top-most entry off Vmessage_stack. */
10580 eassert (CONSP (Vmessage_stack));
10581 Vmessage_stack = XCDR (Vmessage_stack);
10582 }
10583
10584
10585 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10586 exits. If the stack is not empty, we have a missing pop_message
10587 somewhere. */
10588
10589 void
10590 check_message_stack (void)
10591 {
10592 if (!NILP (Vmessage_stack))
10593 emacs_abort ();
10594 }
10595
10596
10597 /* Truncate to NCHARS what will be displayed in the echo area the next
10598 time we display it---but don't redisplay it now. */
10599
10600 void
10601 truncate_echo_area (ptrdiff_t nchars)
10602 {
10603 if (nchars == 0)
10604 echo_area_buffer[0] = Qnil;
10605 else if (!noninteractive
10606 && INTERACTIVE
10607 && !NILP (echo_area_buffer[0]))
10608 {
10609 struct frame *sf = SELECTED_FRAME ();
10610 /* Error messages get reported properly by cmd_error, so this must be
10611 just an informative message; if the frame hasn't really been
10612 initialized yet, just toss it. */
10613 if (sf->glyphs_initialized_p)
10614 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10615 }
10616 }
10617
10618
10619 /* Helper function for truncate_echo_area. Truncate the current
10620 message to at most NCHARS characters. */
10621
10622 static int
10623 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10624 {
10625 if (BEG + nchars < Z)
10626 del_range (BEG + nchars, Z);
10627 if (Z == BEG)
10628 echo_area_buffer[0] = Qnil;
10629 return 0;
10630 }
10631
10632 /* Set the current message to STRING. */
10633
10634 static void
10635 set_message (Lisp_Object string)
10636 {
10637 eassert (STRINGP (string));
10638
10639 message_enable_multibyte = STRING_MULTIBYTE (string);
10640
10641 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10642 message_buf_print = 0;
10643 help_echo_showing_p = 0;
10644
10645 if (STRINGP (Vdebug_on_message)
10646 && STRINGP (string)
10647 && fast_string_match (Vdebug_on_message, string) >= 0)
10648 call_debugger (list2 (Qerror, string));
10649 }
10650
10651
10652 /* Helper function for set_message. First argument is ignored and second
10653 argument has the same meaning as for set_message.
10654 This function is called with the echo area buffer being current. */
10655
10656 static int
10657 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10658 {
10659 eassert (STRINGP (string));
10660
10661 /* Change multibyteness of the echo buffer appropriately. */
10662 if (message_enable_multibyte
10663 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10664 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10665
10666 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10667 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10668 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10669
10670 /* Insert new message at BEG. */
10671 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10672
10673 /* This function takes care of single/multibyte conversion.
10674 We just have to ensure that the echo area buffer has the right
10675 setting of enable_multibyte_characters. */
10676 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10677
10678 return 0;
10679 }
10680
10681
10682 /* Clear messages. CURRENT_P non-zero means clear the current
10683 message. LAST_DISPLAYED_P non-zero means clear the message
10684 last displayed. */
10685
10686 void
10687 clear_message (int current_p, int last_displayed_p)
10688 {
10689 if (current_p)
10690 {
10691 echo_area_buffer[0] = Qnil;
10692 message_cleared_p = 1;
10693 }
10694
10695 if (last_displayed_p)
10696 echo_area_buffer[1] = Qnil;
10697
10698 message_buf_print = 0;
10699 }
10700
10701 /* Clear garbaged frames.
10702
10703 This function is used where the old redisplay called
10704 redraw_garbaged_frames which in turn called redraw_frame which in
10705 turn called clear_frame. The call to clear_frame was a source of
10706 flickering. I believe a clear_frame is not necessary. It should
10707 suffice in the new redisplay to invalidate all current matrices,
10708 and ensure a complete redisplay of all windows. */
10709
10710 static void
10711 clear_garbaged_frames (void)
10712 {
10713 if (frame_garbaged)
10714 {
10715 Lisp_Object tail, frame;
10716 int changed_count = 0;
10717
10718 FOR_EACH_FRAME (tail, frame)
10719 {
10720 struct frame *f = XFRAME (frame);
10721
10722 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10723 {
10724 if (f->resized_p)
10725 {
10726 redraw_frame (f);
10727 f->force_flush_display_p = 1;
10728 }
10729 clear_current_matrices (f);
10730 changed_count++;
10731 f->garbaged = 0;
10732 f->resized_p = 0;
10733 }
10734 }
10735
10736 frame_garbaged = 0;
10737 if (changed_count)
10738 ++windows_or_buffers_changed;
10739 }
10740 }
10741
10742
10743 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10744 is non-zero update selected_frame. Value is non-zero if the
10745 mini-windows height has been changed. */
10746
10747 static int
10748 echo_area_display (int update_frame_p)
10749 {
10750 Lisp_Object mini_window;
10751 struct window *w;
10752 struct frame *f;
10753 int window_height_changed_p = 0;
10754 struct frame *sf = SELECTED_FRAME ();
10755
10756 mini_window = FRAME_MINIBUF_WINDOW (sf);
10757 w = XWINDOW (mini_window);
10758 f = XFRAME (WINDOW_FRAME (w));
10759
10760 /* Don't display if frame is invisible or not yet initialized. */
10761 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10762 return 0;
10763
10764 #ifdef HAVE_WINDOW_SYSTEM
10765 /* When Emacs starts, selected_frame may be the initial terminal
10766 frame. If we let this through, a message would be displayed on
10767 the terminal. */
10768 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10769 return 0;
10770 #endif /* HAVE_WINDOW_SYSTEM */
10771
10772 /* Redraw garbaged frames. */
10773 clear_garbaged_frames ();
10774
10775 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10776 {
10777 echo_area_window = mini_window;
10778 window_height_changed_p = display_echo_area (w);
10779 w->must_be_updated_p = 1;
10780
10781 /* Update the display, unless called from redisplay_internal.
10782 Also don't update the screen during redisplay itself. The
10783 update will happen at the end of redisplay, and an update
10784 here could cause confusion. */
10785 if (update_frame_p && !redisplaying_p)
10786 {
10787 int n = 0;
10788
10789 /* If the display update has been interrupted by pending
10790 input, update mode lines in the frame. Due to the
10791 pending input, it might have been that redisplay hasn't
10792 been called, so that mode lines above the echo area are
10793 garbaged. This looks odd, so we prevent it here. */
10794 if (!display_completed)
10795 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10796
10797 if (window_height_changed_p
10798 /* Don't do this if Emacs is shutting down. Redisplay
10799 needs to run hooks. */
10800 && !NILP (Vrun_hooks))
10801 {
10802 /* Must update other windows. Likewise as in other
10803 cases, don't let this update be interrupted by
10804 pending input. */
10805 ptrdiff_t count = SPECPDL_INDEX ();
10806 specbind (Qredisplay_dont_pause, Qt);
10807 windows_or_buffers_changed = 1;
10808 redisplay_internal ();
10809 unbind_to (count, Qnil);
10810 }
10811 else if (FRAME_WINDOW_P (f) && n == 0)
10812 {
10813 /* Window configuration is the same as before.
10814 Can do with a display update of the echo area,
10815 unless we displayed some mode lines. */
10816 update_single_window (w, 1);
10817 FRAME_RIF (f)->flush_display (f);
10818 }
10819 else
10820 update_frame (f, 1, 1);
10821
10822 /* If cursor is in the echo area, make sure that the next
10823 redisplay displays the minibuffer, so that the cursor will
10824 be replaced with what the minibuffer wants. */
10825 if (cursor_in_echo_area)
10826 ++windows_or_buffers_changed;
10827 }
10828 }
10829 else if (!EQ (mini_window, selected_window))
10830 windows_or_buffers_changed++;
10831
10832 /* Last displayed message is now the current message. */
10833 echo_area_buffer[1] = echo_area_buffer[0];
10834 /* Inform read_char that we're not echoing. */
10835 echo_message_buffer = Qnil;
10836
10837 /* Prevent redisplay optimization in redisplay_internal by resetting
10838 this_line_start_pos. This is done because the mini-buffer now
10839 displays the message instead of its buffer text. */
10840 if (EQ (mini_window, selected_window))
10841 CHARPOS (this_line_start_pos) = 0;
10842
10843 return window_height_changed_p;
10844 }
10845
10846 /* Nonzero if the current window's buffer is shown in more than one
10847 window and was modified since last redisplay. */
10848
10849 static int
10850 buffer_shared_and_changed (void)
10851 {
10852 return (buffer_window_count (current_buffer) > 1
10853 && UNCHANGED_MODIFIED < MODIFF);
10854 }
10855
10856 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10857 is enabled and mark of W's buffer was changed since last W's update. */
10858
10859 static int
10860 window_buffer_changed (struct window *w)
10861 {
10862 struct buffer *b = XBUFFER (w->contents);
10863
10864 eassert (BUFFER_LIVE_P (b));
10865
10866 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10867 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10868 != (w->region_showing != 0)));
10869 }
10870
10871 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10872
10873 static int
10874 mode_line_update_needed (struct window *w)
10875 {
10876 return (w->column_number_displayed != -1
10877 && !(PT == w->last_point && !window_outdated (w))
10878 && (w->column_number_displayed != current_column ()));
10879 }
10880
10881 /* Nonzero if window start of W is frozen and may not be changed during
10882 redisplay. */
10883
10884 static bool
10885 window_frozen_p (struct window *w)
10886 {
10887 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
10888 {
10889 Lisp_Object window;
10890
10891 XSETWINDOW (window, w);
10892 if (MINI_WINDOW_P (w))
10893 return 0;
10894 else if (EQ (window, selected_window))
10895 return 0;
10896 else if (MINI_WINDOW_P (XWINDOW (selected_window))
10897 && EQ (window, Vminibuf_scroll_window))
10898 /* This special window can't be frozen too. */
10899 return 0;
10900 else
10901 return 1;
10902 }
10903 return 0;
10904 }
10905
10906 /***********************************************************************
10907 Mode Lines and Frame Titles
10908 ***********************************************************************/
10909
10910 /* A buffer for constructing non-propertized mode-line strings and
10911 frame titles in it; allocated from the heap in init_xdisp and
10912 resized as needed in store_mode_line_noprop_char. */
10913
10914 static char *mode_line_noprop_buf;
10915
10916 /* The buffer's end, and a current output position in it. */
10917
10918 static char *mode_line_noprop_buf_end;
10919 static char *mode_line_noprop_ptr;
10920
10921 #define MODE_LINE_NOPROP_LEN(start) \
10922 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10923
10924 static enum {
10925 MODE_LINE_DISPLAY = 0,
10926 MODE_LINE_TITLE,
10927 MODE_LINE_NOPROP,
10928 MODE_LINE_STRING
10929 } mode_line_target;
10930
10931 /* Alist that caches the results of :propertize.
10932 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10933 static Lisp_Object mode_line_proptrans_alist;
10934
10935 /* List of strings making up the mode-line. */
10936 static Lisp_Object mode_line_string_list;
10937
10938 /* Base face property when building propertized mode line string. */
10939 static Lisp_Object mode_line_string_face;
10940 static Lisp_Object mode_line_string_face_prop;
10941
10942
10943 /* Unwind data for mode line strings */
10944
10945 static Lisp_Object Vmode_line_unwind_vector;
10946
10947 static Lisp_Object
10948 format_mode_line_unwind_data (struct frame *target_frame,
10949 struct buffer *obuf,
10950 Lisp_Object owin,
10951 int save_proptrans)
10952 {
10953 Lisp_Object vector, tmp;
10954
10955 /* Reduce consing by keeping one vector in
10956 Vwith_echo_area_save_vector. */
10957 vector = Vmode_line_unwind_vector;
10958 Vmode_line_unwind_vector = Qnil;
10959
10960 if (NILP (vector))
10961 vector = Fmake_vector (make_number (10), Qnil);
10962
10963 ASET (vector, 0, make_number (mode_line_target));
10964 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10965 ASET (vector, 2, mode_line_string_list);
10966 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10967 ASET (vector, 4, mode_line_string_face);
10968 ASET (vector, 5, mode_line_string_face_prop);
10969
10970 if (obuf)
10971 XSETBUFFER (tmp, obuf);
10972 else
10973 tmp = Qnil;
10974 ASET (vector, 6, tmp);
10975 ASET (vector, 7, owin);
10976 if (target_frame)
10977 {
10978 /* Similarly to `with-selected-window', if the operation selects
10979 a window on another frame, we must restore that frame's
10980 selected window, and (for a tty) the top-frame. */
10981 ASET (vector, 8, target_frame->selected_window);
10982 if (FRAME_TERMCAP_P (target_frame))
10983 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
10984 }
10985
10986 return vector;
10987 }
10988
10989 static void
10990 unwind_format_mode_line (Lisp_Object vector)
10991 {
10992 Lisp_Object old_window = AREF (vector, 7);
10993 Lisp_Object target_frame_window = AREF (vector, 8);
10994 Lisp_Object old_top_frame = AREF (vector, 9);
10995
10996 mode_line_target = XINT (AREF (vector, 0));
10997 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10998 mode_line_string_list = AREF (vector, 2);
10999 if (! EQ (AREF (vector, 3), Qt))
11000 mode_line_proptrans_alist = AREF (vector, 3);
11001 mode_line_string_face = AREF (vector, 4);
11002 mode_line_string_face_prop = AREF (vector, 5);
11003
11004 /* Select window before buffer, since it may change the buffer. */
11005 if (!NILP (old_window))
11006 {
11007 /* If the operation that we are unwinding had selected a window
11008 on a different frame, reset its frame-selected-window. For a
11009 text terminal, reset its top-frame if necessary. */
11010 if (!NILP (target_frame_window))
11011 {
11012 Lisp_Object frame
11013 = WINDOW_FRAME (XWINDOW (target_frame_window));
11014
11015 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11016 Fselect_window (target_frame_window, Qt);
11017
11018 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11019 Fselect_frame (old_top_frame, Qt);
11020 }
11021
11022 Fselect_window (old_window, Qt);
11023 }
11024
11025 if (!NILP (AREF (vector, 6)))
11026 {
11027 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11028 ASET (vector, 6, Qnil);
11029 }
11030
11031 Vmode_line_unwind_vector = vector;
11032 }
11033
11034
11035 /* Store a single character C for the frame title in mode_line_noprop_buf.
11036 Re-allocate mode_line_noprop_buf if necessary. */
11037
11038 static void
11039 store_mode_line_noprop_char (char c)
11040 {
11041 /* If output position has reached the end of the allocated buffer,
11042 increase the buffer's size. */
11043 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11044 {
11045 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11046 ptrdiff_t size = len;
11047 mode_line_noprop_buf =
11048 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11049 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11050 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11051 }
11052
11053 *mode_line_noprop_ptr++ = c;
11054 }
11055
11056
11057 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11058 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11059 characters that yield more columns than PRECISION; PRECISION <= 0
11060 means copy the whole string. Pad with spaces until FIELD_WIDTH
11061 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11062 pad. Called from display_mode_element when it is used to build a
11063 frame title. */
11064
11065 static int
11066 store_mode_line_noprop (const char *string, int field_width, int precision)
11067 {
11068 const unsigned char *str = (const unsigned char *) string;
11069 int n = 0;
11070 ptrdiff_t dummy, nbytes;
11071
11072 /* Copy at most PRECISION chars from STR. */
11073 nbytes = strlen (string);
11074 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11075 while (nbytes--)
11076 store_mode_line_noprop_char (*str++);
11077
11078 /* Fill up with spaces until FIELD_WIDTH reached. */
11079 while (field_width > 0
11080 && n < field_width)
11081 {
11082 store_mode_line_noprop_char (' ');
11083 ++n;
11084 }
11085
11086 return n;
11087 }
11088
11089 /***********************************************************************
11090 Frame Titles
11091 ***********************************************************************/
11092
11093 #ifdef HAVE_WINDOW_SYSTEM
11094
11095 /* Set the title of FRAME, if it has changed. The title format is
11096 Vicon_title_format if FRAME is iconified, otherwise it is
11097 frame_title_format. */
11098
11099 static void
11100 x_consider_frame_title (Lisp_Object frame)
11101 {
11102 struct frame *f = XFRAME (frame);
11103
11104 if (FRAME_WINDOW_P (f)
11105 || FRAME_MINIBUF_ONLY_P (f)
11106 || f->explicit_name)
11107 {
11108 /* Do we have more than one visible frame on this X display? */
11109 Lisp_Object tail, other_frame, fmt;
11110 ptrdiff_t title_start;
11111 char *title;
11112 ptrdiff_t len;
11113 struct it it;
11114 ptrdiff_t count = SPECPDL_INDEX ();
11115
11116 FOR_EACH_FRAME (tail, other_frame)
11117 {
11118 struct frame *tf = XFRAME (other_frame);
11119
11120 if (tf != f
11121 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11122 && !FRAME_MINIBUF_ONLY_P (tf)
11123 && !EQ (other_frame, tip_frame)
11124 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11125 break;
11126 }
11127
11128 /* Set global variable indicating that multiple frames exist. */
11129 multiple_frames = CONSP (tail);
11130
11131 /* Switch to the buffer of selected window of the frame. Set up
11132 mode_line_target so that display_mode_element will output into
11133 mode_line_noprop_buf; then display the title. */
11134 record_unwind_protect (unwind_format_mode_line,
11135 format_mode_line_unwind_data
11136 (f, current_buffer, selected_window, 0));
11137
11138 Fselect_window (f->selected_window, Qt);
11139 set_buffer_internal_1
11140 (XBUFFER (XWINDOW (f->selected_window)->contents));
11141 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11142
11143 mode_line_target = MODE_LINE_TITLE;
11144 title_start = MODE_LINE_NOPROP_LEN (0);
11145 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11146 NULL, DEFAULT_FACE_ID);
11147 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11148 len = MODE_LINE_NOPROP_LEN (title_start);
11149 title = mode_line_noprop_buf + title_start;
11150 unbind_to (count, Qnil);
11151
11152 /* Set the title only if it's changed. This avoids consing in
11153 the common case where it hasn't. (If it turns out that we've
11154 already wasted too much time by walking through the list with
11155 display_mode_element, then we might need to optimize at a
11156 higher level than this.) */
11157 if (! STRINGP (f->name)
11158 || SBYTES (f->name) != len
11159 || memcmp (title, SDATA (f->name), len) != 0)
11160 x_implicitly_set_name (f, make_string (title, len), Qnil);
11161 }
11162 }
11163
11164 #endif /* not HAVE_WINDOW_SYSTEM */
11165
11166 \f
11167 /***********************************************************************
11168 Menu Bars
11169 ***********************************************************************/
11170
11171
11172 /* Prepare for redisplay by updating menu-bar item lists when
11173 appropriate. This can call eval. */
11174
11175 void
11176 prepare_menu_bars (void)
11177 {
11178 int all_windows;
11179 struct gcpro gcpro1, gcpro2;
11180 struct frame *f;
11181 Lisp_Object tooltip_frame;
11182
11183 #ifdef HAVE_WINDOW_SYSTEM
11184 tooltip_frame = tip_frame;
11185 #else
11186 tooltip_frame = Qnil;
11187 #endif
11188
11189 /* Update all frame titles based on their buffer names, etc. We do
11190 this before the menu bars so that the buffer-menu will show the
11191 up-to-date frame titles. */
11192 #ifdef HAVE_WINDOW_SYSTEM
11193 if (windows_or_buffers_changed || update_mode_lines)
11194 {
11195 Lisp_Object tail, frame;
11196
11197 FOR_EACH_FRAME (tail, frame)
11198 {
11199 f = XFRAME (frame);
11200 if (!EQ (frame, tooltip_frame)
11201 && (FRAME_ICONIFIED_P (f)
11202 || FRAME_VISIBLE_P (f) == 1
11203 /* Exclude TTY frames that are obscured because they
11204 are not the top frame on their console. This is
11205 because x_consider_frame_title actually switches
11206 to the frame, which for TTY frames means it is
11207 marked as garbaged, and will be completely
11208 redrawn on the next redisplay cycle. This causes
11209 TTY frames to be completely redrawn, when there
11210 are more than one of them, even though nothing
11211 should be changed on display. */
11212 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11213 x_consider_frame_title (frame);
11214 }
11215 }
11216 #endif /* HAVE_WINDOW_SYSTEM */
11217
11218 /* Update the menu bar item lists, if appropriate. This has to be
11219 done before any actual redisplay or generation of display lines. */
11220 all_windows = (update_mode_lines
11221 || buffer_shared_and_changed ()
11222 || windows_or_buffers_changed);
11223 if (all_windows)
11224 {
11225 Lisp_Object tail, frame;
11226 ptrdiff_t count = SPECPDL_INDEX ();
11227 /* 1 means that update_menu_bar has run its hooks
11228 so any further calls to update_menu_bar shouldn't do so again. */
11229 int menu_bar_hooks_run = 0;
11230
11231 record_unwind_save_match_data ();
11232
11233 FOR_EACH_FRAME (tail, frame)
11234 {
11235 f = XFRAME (frame);
11236
11237 /* Ignore tooltip frame. */
11238 if (EQ (frame, tooltip_frame))
11239 continue;
11240
11241 /* If a window on this frame changed size, report that to
11242 the user and clear the size-change flag. */
11243 if (FRAME_WINDOW_SIZES_CHANGED (f))
11244 {
11245 Lisp_Object functions;
11246
11247 /* Clear flag first in case we get an error below. */
11248 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11249 functions = Vwindow_size_change_functions;
11250 GCPRO2 (tail, functions);
11251
11252 while (CONSP (functions))
11253 {
11254 if (!EQ (XCAR (functions), Qt))
11255 call1 (XCAR (functions), frame);
11256 functions = XCDR (functions);
11257 }
11258 UNGCPRO;
11259 }
11260
11261 GCPRO1 (tail);
11262 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11263 #ifdef HAVE_WINDOW_SYSTEM
11264 update_tool_bar (f, 0);
11265 #endif
11266 #ifdef HAVE_NS
11267 if (windows_or_buffers_changed
11268 && FRAME_NS_P (f))
11269 ns_set_doc_edited
11270 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11271 #endif
11272 UNGCPRO;
11273 }
11274
11275 unbind_to (count, Qnil);
11276 }
11277 else
11278 {
11279 struct frame *sf = SELECTED_FRAME ();
11280 update_menu_bar (sf, 1, 0);
11281 #ifdef HAVE_WINDOW_SYSTEM
11282 update_tool_bar (sf, 1);
11283 #endif
11284 }
11285 }
11286
11287
11288 /* Update the menu bar item list for frame F. This has to be done
11289 before we start to fill in any display lines, because it can call
11290 eval.
11291
11292 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11293
11294 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11295 already ran the menu bar hooks for this redisplay, so there
11296 is no need to run them again. The return value is the
11297 updated value of this flag, to pass to the next call. */
11298
11299 static int
11300 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11301 {
11302 Lisp_Object window;
11303 register struct window *w;
11304
11305 /* If called recursively during a menu update, do nothing. This can
11306 happen when, for instance, an activate-menubar-hook causes a
11307 redisplay. */
11308 if (inhibit_menubar_update)
11309 return hooks_run;
11310
11311 window = FRAME_SELECTED_WINDOW (f);
11312 w = XWINDOW (window);
11313
11314 if (FRAME_WINDOW_P (f)
11315 ?
11316 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11317 || defined (HAVE_NS) || defined (USE_GTK)
11318 FRAME_EXTERNAL_MENU_BAR (f)
11319 #else
11320 FRAME_MENU_BAR_LINES (f) > 0
11321 #endif
11322 : FRAME_MENU_BAR_LINES (f) > 0)
11323 {
11324 /* If the user has switched buffers or windows, we need to
11325 recompute to reflect the new bindings. But we'll
11326 recompute when update_mode_lines is set too; that means
11327 that people can use force-mode-line-update to request
11328 that the menu bar be recomputed. The adverse effect on
11329 the rest of the redisplay algorithm is about the same as
11330 windows_or_buffers_changed anyway. */
11331 if (windows_or_buffers_changed
11332 /* This used to test w->update_mode_line, but we believe
11333 there is no need to recompute the menu in that case. */
11334 || update_mode_lines
11335 || window_buffer_changed (w))
11336 {
11337 struct buffer *prev = current_buffer;
11338 ptrdiff_t count = SPECPDL_INDEX ();
11339
11340 specbind (Qinhibit_menubar_update, Qt);
11341
11342 set_buffer_internal_1 (XBUFFER (w->contents));
11343 if (save_match_data)
11344 record_unwind_save_match_data ();
11345 if (NILP (Voverriding_local_map_menu_flag))
11346 {
11347 specbind (Qoverriding_terminal_local_map, Qnil);
11348 specbind (Qoverriding_local_map, Qnil);
11349 }
11350
11351 if (!hooks_run)
11352 {
11353 /* Run the Lucid hook. */
11354 safe_run_hooks (Qactivate_menubar_hook);
11355
11356 /* If it has changed current-menubar from previous value,
11357 really recompute the menu-bar from the value. */
11358 if (! NILP (Vlucid_menu_bar_dirty_flag))
11359 call0 (Qrecompute_lucid_menubar);
11360
11361 safe_run_hooks (Qmenu_bar_update_hook);
11362
11363 hooks_run = 1;
11364 }
11365
11366 XSETFRAME (Vmenu_updating_frame, f);
11367 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11368
11369 /* Redisplay the menu bar in case we changed it. */
11370 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11371 || defined (HAVE_NS) || defined (USE_GTK)
11372 if (FRAME_WINDOW_P (f))
11373 {
11374 #if defined (HAVE_NS)
11375 /* All frames on Mac OS share the same menubar. So only
11376 the selected frame should be allowed to set it. */
11377 if (f == SELECTED_FRAME ())
11378 #endif
11379 set_frame_menubar (f, 0, 0);
11380 }
11381 else
11382 /* On a terminal screen, the menu bar is an ordinary screen
11383 line, and this makes it get updated. */
11384 w->update_mode_line = 1;
11385 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11386 /* In the non-toolkit version, the menu bar is an ordinary screen
11387 line, and this makes it get updated. */
11388 w->update_mode_line = 1;
11389 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11390
11391 unbind_to (count, Qnil);
11392 set_buffer_internal_1 (prev);
11393 }
11394 }
11395
11396 return hooks_run;
11397 }
11398
11399
11400 \f
11401 /***********************************************************************
11402 Output Cursor
11403 ***********************************************************************/
11404
11405 #ifdef HAVE_WINDOW_SYSTEM
11406
11407 /* EXPORT:
11408 Nominal cursor position -- where to draw output.
11409 HPOS and VPOS are window relative glyph matrix coordinates.
11410 X and Y are window relative pixel coordinates. */
11411
11412 struct cursor_pos output_cursor;
11413
11414
11415 /* EXPORT:
11416 Set the global variable output_cursor to CURSOR. All cursor
11417 positions are relative to currently updated window. */
11418
11419 void
11420 set_output_cursor (struct cursor_pos *cursor)
11421 {
11422 output_cursor.hpos = cursor->hpos;
11423 output_cursor.vpos = cursor->vpos;
11424 output_cursor.x = cursor->x;
11425 output_cursor.y = cursor->y;
11426 }
11427
11428
11429 /* EXPORT for RIF:
11430 Set a nominal cursor position.
11431
11432 HPOS and VPOS are column/row positions in a window glyph matrix.
11433 X and Y are window text area relative pixel positions.
11434
11435 This is always done during window update, so the position is the
11436 future output cursor position for currently updated window W.
11437 NOTE: W is used only to check whether this function is called
11438 in a consistent manner via the redisplay interface. */
11439
11440 void
11441 x_cursor_to (struct window *w, int vpos, int hpos, int y, int x)
11442 {
11443 eassert (w);
11444
11445 /* Set the output cursor. */
11446 output_cursor.hpos = hpos;
11447 output_cursor.vpos = vpos;
11448 output_cursor.x = x;
11449 output_cursor.y = y;
11450 }
11451
11452 #endif /* HAVE_WINDOW_SYSTEM */
11453
11454 \f
11455 /***********************************************************************
11456 Tool-bars
11457 ***********************************************************************/
11458
11459 #ifdef HAVE_WINDOW_SYSTEM
11460
11461 /* Where the mouse was last time we reported a mouse event. */
11462
11463 struct frame *last_mouse_frame;
11464
11465 /* Tool-bar item index of the item on which a mouse button was pressed
11466 or -1. */
11467
11468 int last_tool_bar_item;
11469
11470 /* Select `frame' temporarily without running all the code in
11471 do_switch_frame.
11472 FIXME: Maybe do_switch_frame should be trimmed down similarly
11473 when `norecord' is set. */
11474 static void
11475 fast_set_selected_frame (Lisp_Object frame)
11476 {
11477 if (!EQ (selected_frame, frame))
11478 {
11479 selected_frame = frame;
11480 selected_window = XFRAME (frame)->selected_window;
11481 }
11482 }
11483
11484 /* Update the tool-bar item list for frame F. This has to be done
11485 before we start to fill in any display lines. Called from
11486 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11487 and restore it here. */
11488
11489 static void
11490 update_tool_bar (struct frame *f, int save_match_data)
11491 {
11492 #if defined (USE_GTK) || defined (HAVE_NS)
11493 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11494 #else
11495 int do_update = WINDOWP (f->tool_bar_window)
11496 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11497 #endif
11498
11499 if (do_update)
11500 {
11501 Lisp_Object window;
11502 struct window *w;
11503
11504 window = FRAME_SELECTED_WINDOW (f);
11505 w = XWINDOW (window);
11506
11507 /* If the user has switched buffers or windows, we need to
11508 recompute to reflect the new bindings. But we'll
11509 recompute when update_mode_lines is set too; that means
11510 that people can use force-mode-line-update to request
11511 that the menu bar be recomputed. The adverse effect on
11512 the rest of the redisplay algorithm is about the same as
11513 windows_or_buffers_changed anyway. */
11514 if (windows_or_buffers_changed
11515 || w->update_mode_line
11516 || update_mode_lines
11517 || window_buffer_changed (w))
11518 {
11519 struct buffer *prev = current_buffer;
11520 ptrdiff_t count = SPECPDL_INDEX ();
11521 Lisp_Object frame, new_tool_bar;
11522 int new_n_tool_bar;
11523 struct gcpro gcpro1;
11524
11525 /* Set current_buffer to the buffer of the selected
11526 window of the frame, so that we get the right local
11527 keymaps. */
11528 set_buffer_internal_1 (XBUFFER (w->contents));
11529
11530 /* Save match data, if we must. */
11531 if (save_match_data)
11532 record_unwind_save_match_data ();
11533
11534 /* Make sure that we don't accidentally use bogus keymaps. */
11535 if (NILP (Voverriding_local_map_menu_flag))
11536 {
11537 specbind (Qoverriding_terminal_local_map, Qnil);
11538 specbind (Qoverriding_local_map, Qnil);
11539 }
11540
11541 GCPRO1 (new_tool_bar);
11542
11543 /* We must temporarily set the selected frame to this frame
11544 before calling tool_bar_items, because the calculation of
11545 the tool-bar keymap uses the selected frame (see
11546 `tool-bar-make-keymap' in tool-bar.el). */
11547 eassert (EQ (selected_window,
11548 /* Since we only explicitly preserve selected_frame,
11549 check that selected_window would be redundant. */
11550 XFRAME (selected_frame)->selected_window));
11551 record_unwind_protect (fast_set_selected_frame, selected_frame);
11552 XSETFRAME (frame, f);
11553 fast_set_selected_frame (frame);
11554
11555 /* Build desired tool-bar items from keymaps. */
11556 new_tool_bar
11557 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11558 &new_n_tool_bar);
11559
11560 /* Redisplay the tool-bar if we changed it. */
11561 if (new_n_tool_bar != f->n_tool_bar_items
11562 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11563 {
11564 /* Redisplay that happens asynchronously due to an expose event
11565 may access f->tool_bar_items. Make sure we update both
11566 variables within BLOCK_INPUT so no such event interrupts. */
11567 block_input ();
11568 fset_tool_bar_items (f, new_tool_bar);
11569 f->n_tool_bar_items = new_n_tool_bar;
11570 w->update_mode_line = 1;
11571 unblock_input ();
11572 }
11573
11574 UNGCPRO;
11575
11576 unbind_to (count, Qnil);
11577 set_buffer_internal_1 (prev);
11578 }
11579 }
11580 }
11581
11582
11583 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11584 F's desired tool-bar contents. F->tool_bar_items must have
11585 been set up previously by calling prepare_menu_bars. */
11586
11587 static void
11588 build_desired_tool_bar_string (struct frame *f)
11589 {
11590 int i, size, size_needed;
11591 struct gcpro gcpro1, gcpro2, gcpro3;
11592 Lisp_Object image, plist, props;
11593
11594 image = plist = props = Qnil;
11595 GCPRO3 (image, plist, props);
11596
11597 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11598 Otherwise, make a new string. */
11599
11600 /* The size of the string we might be able to reuse. */
11601 size = (STRINGP (f->desired_tool_bar_string)
11602 ? SCHARS (f->desired_tool_bar_string)
11603 : 0);
11604
11605 /* We need one space in the string for each image. */
11606 size_needed = f->n_tool_bar_items;
11607
11608 /* Reuse f->desired_tool_bar_string, if possible. */
11609 if (size < size_needed || NILP (f->desired_tool_bar_string))
11610 fset_desired_tool_bar_string
11611 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11612 else
11613 {
11614 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11615 Fremove_text_properties (make_number (0), make_number (size),
11616 props, f->desired_tool_bar_string);
11617 }
11618
11619 /* Put a `display' property on the string for the images to display,
11620 put a `menu_item' property on tool-bar items with a value that
11621 is the index of the item in F's tool-bar item vector. */
11622 for (i = 0; i < f->n_tool_bar_items; ++i)
11623 {
11624 #define PROP(IDX) \
11625 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11626
11627 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11628 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11629 int hmargin, vmargin, relief, idx, end;
11630
11631 /* If image is a vector, choose the image according to the
11632 button state. */
11633 image = PROP (TOOL_BAR_ITEM_IMAGES);
11634 if (VECTORP (image))
11635 {
11636 if (enabled_p)
11637 idx = (selected_p
11638 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11639 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11640 else
11641 idx = (selected_p
11642 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11643 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11644
11645 eassert (ASIZE (image) >= idx);
11646 image = AREF (image, idx);
11647 }
11648 else
11649 idx = -1;
11650
11651 /* Ignore invalid image specifications. */
11652 if (!valid_image_p (image))
11653 continue;
11654
11655 /* Display the tool-bar button pressed, or depressed. */
11656 plist = Fcopy_sequence (XCDR (image));
11657
11658 /* Compute margin and relief to draw. */
11659 relief = (tool_bar_button_relief >= 0
11660 ? tool_bar_button_relief
11661 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11662 hmargin = vmargin = relief;
11663
11664 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11665 INT_MAX - max (hmargin, vmargin)))
11666 {
11667 hmargin += XFASTINT (Vtool_bar_button_margin);
11668 vmargin += XFASTINT (Vtool_bar_button_margin);
11669 }
11670 else if (CONSP (Vtool_bar_button_margin))
11671 {
11672 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11673 INT_MAX - hmargin))
11674 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11675
11676 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11677 INT_MAX - vmargin))
11678 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11679 }
11680
11681 if (auto_raise_tool_bar_buttons_p)
11682 {
11683 /* Add a `:relief' property to the image spec if the item is
11684 selected. */
11685 if (selected_p)
11686 {
11687 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11688 hmargin -= relief;
11689 vmargin -= relief;
11690 }
11691 }
11692 else
11693 {
11694 /* If image is selected, display it pressed, i.e. with a
11695 negative relief. If it's not selected, display it with a
11696 raised relief. */
11697 plist = Fplist_put (plist, QCrelief,
11698 (selected_p
11699 ? make_number (-relief)
11700 : make_number (relief)));
11701 hmargin -= relief;
11702 vmargin -= relief;
11703 }
11704
11705 /* Put a margin around the image. */
11706 if (hmargin || vmargin)
11707 {
11708 if (hmargin == vmargin)
11709 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11710 else
11711 plist = Fplist_put (plist, QCmargin,
11712 Fcons (make_number (hmargin),
11713 make_number (vmargin)));
11714 }
11715
11716 /* If button is not enabled, and we don't have special images
11717 for the disabled state, make the image appear disabled by
11718 applying an appropriate algorithm to it. */
11719 if (!enabled_p && idx < 0)
11720 plist = Fplist_put (plist, QCconversion, Qdisabled);
11721
11722 /* Put a `display' text property on the string for the image to
11723 display. Put a `menu-item' property on the string that gives
11724 the start of this item's properties in the tool-bar items
11725 vector. */
11726 image = Fcons (Qimage, plist);
11727 props = list4 (Qdisplay, image,
11728 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11729
11730 /* Let the last image hide all remaining spaces in the tool bar
11731 string. The string can be longer than needed when we reuse a
11732 previous string. */
11733 if (i + 1 == f->n_tool_bar_items)
11734 end = SCHARS (f->desired_tool_bar_string);
11735 else
11736 end = i + 1;
11737 Fadd_text_properties (make_number (i), make_number (end),
11738 props, f->desired_tool_bar_string);
11739 #undef PROP
11740 }
11741
11742 UNGCPRO;
11743 }
11744
11745
11746 /* Display one line of the tool-bar of frame IT->f.
11747
11748 HEIGHT specifies the desired height of the tool-bar line.
11749 If the actual height of the glyph row is less than HEIGHT, the
11750 row's height is increased to HEIGHT, and the icons are centered
11751 vertically in the new height.
11752
11753 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11754 count a final empty row in case the tool-bar width exactly matches
11755 the window width.
11756 */
11757
11758 static void
11759 display_tool_bar_line (struct it *it, int height)
11760 {
11761 struct glyph_row *row = it->glyph_row;
11762 int max_x = it->last_visible_x;
11763 struct glyph *last;
11764
11765 prepare_desired_row (row);
11766 row->y = it->current_y;
11767
11768 /* Note that this isn't made use of if the face hasn't a box,
11769 so there's no need to check the face here. */
11770 it->start_of_box_run_p = 1;
11771
11772 while (it->current_x < max_x)
11773 {
11774 int x, n_glyphs_before, i, nglyphs;
11775 struct it it_before;
11776
11777 /* Get the next display element. */
11778 if (!get_next_display_element (it))
11779 {
11780 /* Don't count empty row if we are counting needed tool-bar lines. */
11781 if (height < 0 && !it->hpos)
11782 return;
11783 break;
11784 }
11785
11786 /* Produce glyphs. */
11787 n_glyphs_before = row->used[TEXT_AREA];
11788 it_before = *it;
11789
11790 PRODUCE_GLYPHS (it);
11791
11792 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11793 i = 0;
11794 x = it_before.current_x;
11795 while (i < nglyphs)
11796 {
11797 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11798
11799 if (x + glyph->pixel_width > max_x)
11800 {
11801 /* Glyph doesn't fit on line. Backtrack. */
11802 row->used[TEXT_AREA] = n_glyphs_before;
11803 *it = it_before;
11804 /* If this is the only glyph on this line, it will never fit on the
11805 tool-bar, so skip it. But ensure there is at least one glyph,
11806 so we don't accidentally disable the tool-bar. */
11807 if (n_glyphs_before == 0
11808 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11809 break;
11810 goto out;
11811 }
11812
11813 ++it->hpos;
11814 x += glyph->pixel_width;
11815 ++i;
11816 }
11817
11818 /* Stop at line end. */
11819 if (ITERATOR_AT_END_OF_LINE_P (it))
11820 break;
11821
11822 set_iterator_to_next (it, 1);
11823 }
11824
11825 out:;
11826
11827 row->displays_text_p = row->used[TEXT_AREA] != 0;
11828
11829 /* Use default face for the border below the tool bar.
11830
11831 FIXME: When auto-resize-tool-bars is grow-only, there is
11832 no additional border below the possibly empty tool-bar lines.
11833 So to make the extra empty lines look "normal", we have to
11834 use the tool-bar face for the border too. */
11835 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11836 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11837 it->face_id = DEFAULT_FACE_ID;
11838
11839 extend_face_to_end_of_line (it);
11840 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11841 last->right_box_line_p = 1;
11842 if (last == row->glyphs[TEXT_AREA])
11843 last->left_box_line_p = 1;
11844
11845 /* Make line the desired height and center it vertically. */
11846 if ((height -= it->max_ascent + it->max_descent) > 0)
11847 {
11848 /* Don't add more than one line height. */
11849 height %= FRAME_LINE_HEIGHT (it->f);
11850 it->max_ascent += height / 2;
11851 it->max_descent += (height + 1) / 2;
11852 }
11853
11854 compute_line_metrics (it);
11855
11856 /* If line is empty, make it occupy the rest of the tool-bar. */
11857 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11858 {
11859 row->height = row->phys_height = it->last_visible_y - row->y;
11860 row->visible_height = row->height;
11861 row->ascent = row->phys_ascent = 0;
11862 row->extra_line_spacing = 0;
11863 }
11864
11865 row->full_width_p = 1;
11866 row->continued_p = 0;
11867 row->truncated_on_left_p = 0;
11868 row->truncated_on_right_p = 0;
11869
11870 it->current_x = it->hpos = 0;
11871 it->current_y += row->height;
11872 ++it->vpos;
11873 ++it->glyph_row;
11874 }
11875
11876
11877 /* Max tool-bar height. */
11878
11879 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11880 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11881
11882 /* Value is the number of screen lines needed to make all tool-bar
11883 items of frame F visible. The number of actual rows needed is
11884 returned in *N_ROWS if non-NULL. */
11885
11886 static int
11887 tool_bar_lines_needed (struct frame *f, int *n_rows)
11888 {
11889 struct window *w = XWINDOW (f->tool_bar_window);
11890 struct it it;
11891 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11892 the desired matrix, so use (unused) mode-line row as temporary row to
11893 avoid destroying the first tool-bar row. */
11894 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11895
11896 /* Initialize an iterator for iteration over
11897 F->desired_tool_bar_string in the tool-bar window of frame F. */
11898 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11899 it.first_visible_x = 0;
11900 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11901 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11902 it.paragraph_embedding = L2R;
11903
11904 while (!ITERATOR_AT_END_P (&it))
11905 {
11906 clear_glyph_row (temp_row);
11907 it.glyph_row = temp_row;
11908 display_tool_bar_line (&it, -1);
11909 }
11910 clear_glyph_row (temp_row);
11911
11912 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11913 if (n_rows)
11914 *n_rows = it.vpos > 0 ? it.vpos : -1;
11915
11916 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11917 }
11918
11919
11920 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11921 0, 1, 0,
11922 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11923 If FRAME is nil or omitted, use the selected frame. */)
11924 (Lisp_Object frame)
11925 {
11926 struct frame *f = decode_any_frame (frame);
11927 struct window *w;
11928 int nlines = 0;
11929
11930 if (WINDOWP (f->tool_bar_window)
11931 && (w = XWINDOW (f->tool_bar_window),
11932 WINDOW_TOTAL_LINES (w) > 0))
11933 {
11934 update_tool_bar (f, 1);
11935 if (f->n_tool_bar_items)
11936 {
11937 build_desired_tool_bar_string (f);
11938 nlines = tool_bar_lines_needed (f, NULL);
11939 }
11940 }
11941
11942 return make_number (nlines);
11943 }
11944
11945
11946 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11947 height should be changed. */
11948
11949 static int
11950 redisplay_tool_bar (struct frame *f)
11951 {
11952 struct window *w;
11953 struct it it;
11954 struct glyph_row *row;
11955
11956 #if defined (USE_GTK) || defined (HAVE_NS)
11957 if (FRAME_EXTERNAL_TOOL_BAR (f))
11958 update_frame_tool_bar (f);
11959 return 0;
11960 #endif
11961
11962 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11963 do anything. This means you must start with tool-bar-lines
11964 non-zero to get the auto-sizing effect. Or in other words, you
11965 can turn off tool-bars by specifying tool-bar-lines zero. */
11966 if (!WINDOWP (f->tool_bar_window)
11967 || (w = XWINDOW (f->tool_bar_window),
11968 WINDOW_TOTAL_LINES (w) == 0))
11969 return 0;
11970
11971 /* Set up an iterator for the tool-bar window. */
11972 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11973 it.first_visible_x = 0;
11974 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11975 row = it.glyph_row;
11976
11977 /* Build a string that represents the contents of the tool-bar. */
11978 build_desired_tool_bar_string (f);
11979 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11980 /* FIXME: This should be controlled by a user option. But it
11981 doesn't make sense to have an R2L tool bar if the menu bar cannot
11982 be drawn also R2L, and making the menu bar R2L is tricky due
11983 toolkit-specific code that implements it. If an R2L tool bar is
11984 ever supported, display_tool_bar_line should also be augmented to
11985 call unproduce_glyphs like display_line and display_string
11986 do. */
11987 it.paragraph_embedding = L2R;
11988
11989 if (f->n_tool_bar_rows == 0)
11990 {
11991 int nlines;
11992
11993 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11994 nlines != WINDOW_TOTAL_LINES (w)))
11995 {
11996 Lisp_Object frame;
11997 int old_height = WINDOW_TOTAL_LINES (w);
11998
11999 XSETFRAME (frame, f);
12000 Fmodify_frame_parameters (frame,
12001 list1 (Fcons (Qtool_bar_lines,
12002 make_number (nlines))));
12003 if (WINDOW_TOTAL_LINES (w) != old_height)
12004 {
12005 clear_glyph_matrix (w->desired_matrix);
12006 fonts_changed_p = 1;
12007 return 1;
12008 }
12009 }
12010 }
12011
12012 /* Display as many lines as needed to display all tool-bar items. */
12013
12014 if (f->n_tool_bar_rows > 0)
12015 {
12016 int border, rows, height, extra;
12017
12018 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12019 border = XINT (Vtool_bar_border);
12020 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12021 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12022 else if (EQ (Vtool_bar_border, Qborder_width))
12023 border = f->border_width;
12024 else
12025 border = 0;
12026 if (border < 0)
12027 border = 0;
12028
12029 rows = f->n_tool_bar_rows;
12030 height = max (1, (it.last_visible_y - border) / rows);
12031 extra = it.last_visible_y - border - height * rows;
12032
12033 while (it.current_y < it.last_visible_y)
12034 {
12035 int h = 0;
12036 if (extra > 0 && rows-- > 0)
12037 {
12038 h = (extra + rows - 1) / rows;
12039 extra -= h;
12040 }
12041 display_tool_bar_line (&it, height + h);
12042 }
12043 }
12044 else
12045 {
12046 while (it.current_y < it.last_visible_y)
12047 display_tool_bar_line (&it, 0);
12048 }
12049
12050 /* It doesn't make much sense to try scrolling in the tool-bar
12051 window, so don't do it. */
12052 w->desired_matrix->no_scrolling_p = 1;
12053 w->must_be_updated_p = 1;
12054
12055 if (!NILP (Vauto_resize_tool_bars))
12056 {
12057 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12058 int change_height_p = 0;
12059
12060 /* If we couldn't display everything, change the tool-bar's
12061 height if there is room for more. */
12062 if (IT_STRING_CHARPOS (it) < it.end_charpos
12063 && it.current_y < max_tool_bar_height)
12064 change_height_p = 1;
12065
12066 row = it.glyph_row - 1;
12067
12068 /* If there are blank lines at the end, except for a partially
12069 visible blank line at the end that is smaller than
12070 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12071 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12072 && row->height >= FRAME_LINE_HEIGHT (f))
12073 change_height_p = 1;
12074
12075 /* If row displays tool-bar items, but is partially visible,
12076 change the tool-bar's height. */
12077 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12078 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12079 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12080 change_height_p = 1;
12081
12082 /* Resize windows as needed by changing the `tool-bar-lines'
12083 frame parameter. */
12084 if (change_height_p)
12085 {
12086 Lisp_Object frame;
12087 int old_height = WINDOW_TOTAL_LINES (w);
12088 int nrows;
12089 int nlines = tool_bar_lines_needed (f, &nrows);
12090
12091 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12092 && !f->minimize_tool_bar_window_p)
12093 ? (nlines > old_height)
12094 : (nlines != old_height));
12095 f->minimize_tool_bar_window_p = 0;
12096
12097 if (change_height_p)
12098 {
12099 XSETFRAME (frame, f);
12100 Fmodify_frame_parameters (frame,
12101 list1 (Fcons (Qtool_bar_lines,
12102 make_number (nlines))));
12103 if (WINDOW_TOTAL_LINES (w) != old_height)
12104 {
12105 clear_glyph_matrix (w->desired_matrix);
12106 f->n_tool_bar_rows = nrows;
12107 fonts_changed_p = 1;
12108 return 1;
12109 }
12110 }
12111 }
12112 }
12113
12114 f->minimize_tool_bar_window_p = 0;
12115 return 0;
12116 }
12117
12118
12119 /* Get information about the tool-bar item which is displayed in GLYPH
12120 on frame F. Return in *PROP_IDX the index where tool-bar item
12121 properties start in F->tool_bar_items. Value is zero if
12122 GLYPH doesn't display a tool-bar item. */
12123
12124 static int
12125 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12126 {
12127 Lisp_Object prop;
12128 int success_p;
12129 int charpos;
12130
12131 /* This function can be called asynchronously, which means we must
12132 exclude any possibility that Fget_text_property signals an
12133 error. */
12134 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12135 charpos = max (0, charpos);
12136
12137 /* Get the text property `menu-item' at pos. The value of that
12138 property is the start index of this item's properties in
12139 F->tool_bar_items. */
12140 prop = Fget_text_property (make_number (charpos),
12141 Qmenu_item, f->current_tool_bar_string);
12142 if (INTEGERP (prop))
12143 {
12144 *prop_idx = XINT (prop);
12145 success_p = 1;
12146 }
12147 else
12148 success_p = 0;
12149
12150 return success_p;
12151 }
12152
12153 \f
12154 /* Get information about the tool-bar item at position X/Y on frame F.
12155 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12156 the current matrix of the tool-bar window of F, or NULL if not
12157 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12158 item in F->tool_bar_items. Value is
12159
12160 -1 if X/Y is not on a tool-bar item
12161 0 if X/Y is on the same item that was highlighted before.
12162 1 otherwise. */
12163
12164 static int
12165 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12166 int *hpos, int *vpos, int *prop_idx)
12167 {
12168 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12169 struct window *w = XWINDOW (f->tool_bar_window);
12170 int area;
12171
12172 /* Find the glyph under X/Y. */
12173 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12174 if (*glyph == NULL)
12175 return -1;
12176
12177 /* Get the start of this tool-bar item's properties in
12178 f->tool_bar_items. */
12179 if (!tool_bar_item_info (f, *glyph, prop_idx))
12180 return -1;
12181
12182 /* Is mouse on the highlighted item? */
12183 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12184 && *vpos >= hlinfo->mouse_face_beg_row
12185 && *vpos <= hlinfo->mouse_face_end_row
12186 && (*vpos > hlinfo->mouse_face_beg_row
12187 || *hpos >= hlinfo->mouse_face_beg_col)
12188 && (*vpos < hlinfo->mouse_face_end_row
12189 || *hpos < hlinfo->mouse_face_end_col
12190 || hlinfo->mouse_face_past_end))
12191 return 0;
12192
12193 return 1;
12194 }
12195
12196
12197 /* EXPORT:
12198 Handle mouse button event on the tool-bar of frame F, at
12199 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12200 0 for button release. MODIFIERS is event modifiers for button
12201 release. */
12202
12203 void
12204 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12205 int modifiers)
12206 {
12207 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12208 struct window *w = XWINDOW (f->tool_bar_window);
12209 int hpos, vpos, prop_idx;
12210 struct glyph *glyph;
12211 Lisp_Object enabled_p;
12212 int ts;
12213
12214 /* If not on the highlighted tool-bar item, and mouse-highlight is
12215 non-nil, return. This is so we generate the tool-bar button
12216 click only when the mouse button is released on the same item as
12217 where it was pressed. However, when mouse-highlight is disabled,
12218 generate the click when the button is released regardless of the
12219 highlight, since tool-bar items are not highlighted in that
12220 case. */
12221 frame_to_window_pixel_xy (w, &x, &y);
12222 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12223 if (ts == -1
12224 || (ts != 0 && !NILP (Vmouse_highlight)))
12225 return;
12226
12227 /* When mouse-highlight is off, generate the click for the item
12228 where the button was pressed, disregarding where it was
12229 released. */
12230 if (NILP (Vmouse_highlight) && !down_p)
12231 prop_idx = last_tool_bar_item;
12232
12233 /* If item is disabled, do nothing. */
12234 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12235 if (NILP (enabled_p))
12236 return;
12237
12238 if (down_p)
12239 {
12240 /* Show item in pressed state. */
12241 if (!NILP (Vmouse_highlight))
12242 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12243 last_tool_bar_item = prop_idx;
12244 }
12245 else
12246 {
12247 Lisp_Object key, frame;
12248 struct input_event event;
12249 EVENT_INIT (event);
12250
12251 /* Show item in released state. */
12252 if (!NILP (Vmouse_highlight))
12253 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12254
12255 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12256
12257 XSETFRAME (frame, f);
12258 event.kind = TOOL_BAR_EVENT;
12259 event.frame_or_window = frame;
12260 event.arg = frame;
12261 kbd_buffer_store_event (&event);
12262
12263 event.kind = TOOL_BAR_EVENT;
12264 event.frame_or_window = frame;
12265 event.arg = key;
12266 event.modifiers = modifiers;
12267 kbd_buffer_store_event (&event);
12268 last_tool_bar_item = -1;
12269 }
12270 }
12271
12272
12273 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12274 tool-bar window-relative coordinates X/Y. Called from
12275 note_mouse_highlight. */
12276
12277 static void
12278 note_tool_bar_highlight (struct frame *f, int x, int y)
12279 {
12280 Lisp_Object window = f->tool_bar_window;
12281 struct window *w = XWINDOW (window);
12282 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12283 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12284 int hpos, vpos;
12285 struct glyph *glyph;
12286 struct glyph_row *row;
12287 int i;
12288 Lisp_Object enabled_p;
12289 int prop_idx;
12290 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12291 int mouse_down_p, rc;
12292
12293 /* Function note_mouse_highlight is called with negative X/Y
12294 values when mouse moves outside of the frame. */
12295 if (x <= 0 || y <= 0)
12296 {
12297 clear_mouse_face (hlinfo);
12298 return;
12299 }
12300
12301 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12302 if (rc < 0)
12303 {
12304 /* Not on tool-bar item. */
12305 clear_mouse_face (hlinfo);
12306 return;
12307 }
12308 else if (rc == 0)
12309 /* On same tool-bar item as before. */
12310 goto set_help_echo;
12311
12312 clear_mouse_face (hlinfo);
12313
12314 /* Mouse is down, but on different tool-bar item? */
12315 mouse_down_p = (dpyinfo->grabbed
12316 && f == last_mouse_frame
12317 && FRAME_LIVE_P (f));
12318 if (mouse_down_p
12319 && last_tool_bar_item != prop_idx)
12320 return;
12321
12322 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12323
12324 /* If tool-bar item is not enabled, don't highlight it. */
12325 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12326 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12327 {
12328 /* Compute the x-position of the glyph. In front and past the
12329 image is a space. We include this in the highlighted area. */
12330 row = MATRIX_ROW (w->current_matrix, vpos);
12331 for (i = x = 0; i < hpos; ++i)
12332 x += row->glyphs[TEXT_AREA][i].pixel_width;
12333
12334 /* Record this as the current active region. */
12335 hlinfo->mouse_face_beg_col = hpos;
12336 hlinfo->mouse_face_beg_row = vpos;
12337 hlinfo->mouse_face_beg_x = x;
12338 hlinfo->mouse_face_beg_y = row->y;
12339 hlinfo->mouse_face_past_end = 0;
12340
12341 hlinfo->mouse_face_end_col = hpos + 1;
12342 hlinfo->mouse_face_end_row = vpos;
12343 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12344 hlinfo->mouse_face_end_y = row->y;
12345 hlinfo->mouse_face_window = window;
12346 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12347
12348 /* Display it as active. */
12349 show_mouse_face (hlinfo, draw);
12350 }
12351
12352 set_help_echo:
12353
12354 /* Set help_echo_string to a help string to display for this tool-bar item.
12355 XTread_socket does the rest. */
12356 help_echo_object = help_echo_window = Qnil;
12357 help_echo_pos = -1;
12358 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12359 if (NILP (help_echo_string))
12360 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12361 }
12362
12363 #endif /* HAVE_WINDOW_SYSTEM */
12364
12365
12366 \f
12367 /************************************************************************
12368 Horizontal scrolling
12369 ************************************************************************/
12370
12371 static int hscroll_window_tree (Lisp_Object);
12372 static int hscroll_windows (Lisp_Object);
12373
12374 /* For all leaf windows in the window tree rooted at WINDOW, set their
12375 hscroll value so that PT is (i) visible in the window, and (ii) so
12376 that it is not within a certain margin at the window's left and
12377 right border. Value is non-zero if any window's hscroll has been
12378 changed. */
12379
12380 static int
12381 hscroll_window_tree (Lisp_Object window)
12382 {
12383 int hscrolled_p = 0;
12384 int hscroll_relative_p = FLOATP (Vhscroll_step);
12385 int hscroll_step_abs = 0;
12386 double hscroll_step_rel = 0;
12387
12388 if (hscroll_relative_p)
12389 {
12390 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12391 if (hscroll_step_rel < 0)
12392 {
12393 hscroll_relative_p = 0;
12394 hscroll_step_abs = 0;
12395 }
12396 }
12397 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12398 {
12399 hscroll_step_abs = XINT (Vhscroll_step);
12400 if (hscroll_step_abs < 0)
12401 hscroll_step_abs = 0;
12402 }
12403 else
12404 hscroll_step_abs = 0;
12405
12406 while (WINDOWP (window))
12407 {
12408 struct window *w = XWINDOW (window);
12409
12410 if (WINDOWP (w->contents))
12411 hscrolled_p |= hscroll_window_tree (w->contents);
12412 else if (w->cursor.vpos >= 0)
12413 {
12414 int h_margin;
12415 int text_area_width;
12416 struct glyph_row *current_cursor_row
12417 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12418 struct glyph_row *desired_cursor_row
12419 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12420 struct glyph_row *cursor_row
12421 = (desired_cursor_row->enabled_p
12422 ? desired_cursor_row
12423 : current_cursor_row);
12424 int row_r2l_p = cursor_row->reversed_p;
12425
12426 text_area_width = window_box_width (w, TEXT_AREA);
12427
12428 /* Scroll when cursor is inside this scroll margin. */
12429 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12430
12431 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12432 /* For left-to-right rows, hscroll when cursor is either
12433 (i) inside the right hscroll margin, or (ii) if it is
12434 inside the left margin and the window is already
12435 hscrolled. */
12436 && ((!row_r2l_p
12437 && ((w->hscroll
12438 && w->cursor.x <= h_margin)
12439 || (cursor_row->enabled_p
12440 && cursor_row->truncated_on_right_p
12441 && (w->cursor.x >= text_area_width - h_margin))))
12442 /* For right-to-left rows, the logic is similar,
12443 except that rules for scrolling to left and right
12444 are reversed. E.g., if cursor.x <= h_margin, we
12445 need to hscroll "to the right" unconditionally,
12446 and that will scroll the screen to the left so as
12447 to reveal the next portion of the row. */
12448 || (row_r2l_p
12449 && ((cursor_row->enabled_p
12450 /* FIXME: It is confusing to set the
12451 truncated_on_right_p flag when R2L rows
12452 are actually truncated on the left. */
12453 && cursor_row->truncated_on_right_p
12454 && w->cursor.x <= h_margin)
12455 || (w->hscroll
12456 && (w->cursor.x >= text_area_width - h_margin))))))
12457 {
12458 struct it it;
12459 ptrdiff_t hscroll;
12460 struct buffer *saved_current_buffer;
12461 ptrdiff_t pt;
12462 int wanted_x;
12463
12464 /* Find point in a display of infinite width. */
12465 saved_current_buffer = current_buffer;
12466 current_buffer = XBUFFER (w->contents);
12467
12468 if (w == XWINDOW (selected_window))
12469 pt = PT;
12470 else
12471 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12472
12473 /* Move iterator to pt starting at cursor_row->start in
12474 a line with infinite width. */
12475 init_to_row_start (&it, w, cursor_row);
12476 it.last_visible_x = INFINITY;
12477 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12478 current_buffer = saved_current_buffer;
12479
12480 /* Position cursor in window. */
12481 if (!hscroll_relative_p && hscroll_step_abs == 0)
12482 hscroll = max (0, (it.current_x
12483 - (ITERATOR_AT_END_OF_LINE_P (&it)
12484 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12485 : (text_area_width / 2))))
12486 / FRAME_COLUMN_WIDTH (it.f);
12487 else if ((!row_r2l_p
12488 && w->cursor.x >= text_area_width - h_margin)
12489 || (row_r2l_p && w->cursor.x <= h_margin))
12490 {
12491 if (hscroll_relative_p)
12492 wanted_x = text_area_width * (1 - hscroll_step_rel)
12493 - h_margin;
12494 else
12495 wanted_x = text_area_width
12496 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12497 - h_margin;
12498 hscroll
12499 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12500 }
12501 else
12502 {
12503 if (hscroll_relative_p)
12504 wanted_x = text_area_width * hscroll_step_rel
12505 + h_margin;
12506 else
12507 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12508 + h_margin;
12509 hscroll
12510 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12511 }
12512 hscroll = max (hscroll, w->min_hscroll);
12513
12514 /* Don't prevent redisplay optimizations if hscroll
12515 hasn't changed, as it will unnecessarily slow down
12516 redisplay. */
12517 if (w->hscroll != hscroll)
12518 {
12519 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12520 w->hscroll = hscroll;
12521 hscrolled_p = 1;
12522 }
12523 }
12524 }
12525
12526 window = w->next;
12527 }
12528
12529 /* Value is non-zero if hscroll of any leaf window has been changed. */
12530 return hscrolled_p;
12531 }
12532
12533
12534 /* Set hscroll so that cursor is visible and not inside horizontal
12535 scroll margins for all windows in the tree rooted at WINDOW. See
12536 also hscroll_window_tree above. Value is non-zero if any window's
12537 hscroll has been changed. If it has, desired matrices on the frame
12538 of WINDOW are cleared. */
12539
12540 static int
12541 hscroll_windows (Lisp_Object window)
12542 {
12543 int hscrolled_p = hscroll_window_tree (window);
12544 if (hscrolled_p)
12545 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12546 return hscrolled_p;
12547 }
12548
12549
12550 \f
12551 /************************************************************************
12552 Redisplay
12553 ************************************************************************/
12554
12555 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12556 to a non-zero value. This is sometimes handy to have in a debugger
12557 session. */
12558
12559 #ifdef GLYPH_DEBUG
12560
12561 /* First and last unchanged row for try_window_id. */
12562
12563 static int debug_first_unchanged_at_end_vpos;
12564 static int debug_last_unchanged_at_beg_vpos;
12565
12566 /* Delta vpos and y. */
12567
12568 static int debug_dvpos, debug_dy;
12569
12570 /* Delta in characters and bytes for try_window_id. */
12571
12572 static ptrdiff_t debug_delta, debug_delta_bytes;
12573
12574 /* Values of window_end_pos and window_end_vpos at the end of
12575 try_window_id. */
12576
12577 static ptrdiff_t debug_end_vpos;
12578
12579 /* Append a string to W->desired_matrix->method. FMT is a printf
12580 format string. If trace_redisplay_p is non-zero also printf the
12581 resulting string to stderr. */
12582
12583 static void debug_method_add (struct window *, char const *, ...)
12584 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12585
12586 static void
12587 debug_method_add (struct window *w, char const *fmt, ...)
12588 {
12589 void *ptr = w;
12590 char *method = w->desired_matrix->method;
12591 int len = strlen (method);
12592 int size = sizeof w->desired_matrix->method;
12593 int remaining = size - len - 1;
12594 va_list ap;
12595
12596 if (len && remaining)
12597 {
12598 method[len] = '|';
12599 --remaining, ++len;
12600 }
12601
12602 va_start (ap, fmt);
12603 vsnprintf (method + len, remaining + 1, fmt, ap);
12604 va_end (ap);
12605
12606 if (trace_redisplay_p)
12607 fprintf (stderr, "%p (%s): %s\n",
12608 ptr,
12609 ((BUFFERP (w->contents)
12610 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12611 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12612 : "no buffer"),
12613 method + len);
12614 }
12615
12616 #endif /* GLYPH_DEBUG */
12617
12618
12619 /* Value is non-zero if all changes in window W, which displays
12620 current_buffer, are in the text between START and END. START is a
12621 buffer position, END is given as a distance from Z. Used in
12622 redisplay_internal for display optimization. */
12623
12624 static int
12625 text_outside_line_unchanged_p (struct window *w,
12626 ptrdiff_t start, ptrdiff_t end)
12627 {
12628 int unchanged_p = 1;
12629
12630 /* If text or overlays have changed, see where. */
12631 if (window_outdated (w))
12632 {
12633 /* Gap in the line? */
12634 if (GPT < start || Z - GPT < end)
12635 unchanged_p = 0;
12636
12637 /* Changes start in front of the line, or end after it? */
12638 if (unchanged_p
12639 && (BEG_UNCHANGED < start - 1
12640 || END_UNCHANGED < end))
12641 unchanged_p = 0;
12642
12643 /* If selective display, can't optimize if changes start at the
12644 beginning of the line. */
12645 if (unchanged_p
12646 && INTEGERP (BVAR (current_buffer, selective_display))
12647 && XINT (BVAR (current_buffer, selective_display)) > 0
12648 && (BEG_UNCHANGED < start || GPT <= start))
12649 unchanged_p = 0;
12650
12651 /* If there are overlays at the start or end of the line, these
12652 may have overlay strings with newlines in them. A change at
12653 START, for instance, may actually concern the display of such
12654 overlay strings as well, and they are displayed on different
12655 lines. So, quickly rule out this case. (For the future, it
12656 might be desirable to implement something more telling than
12657 just BEG/END_UNCHANGED.) */
12658 if (unchanged_p)
12659 {
12660 if (BEG + BEG_UNCHANGED == start
12661 && overlay_touches_p (start))
12662 unchanged_p = 0;
12663 if (END_UNCHANGED == end
12664 && overlay_touches_p (Z - end))
12665 unchanged_p = 0;
12666 }
12667
12668 /* Under bidi reordering, adding or deleting a character in the
12669 beginning of a paragraph, before the first strong directional
12670 character, can change the base direction of the paragraph (unless
12671 the buffer specifies a fixed paragraph direction), which will
12672 require to redisplay the whole paragraph. It might be worthwhile
12673 to find the paragraph limits and widen the range of redisplayed
12674 lines to that, but for now just give up this optimization. */
12675 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12676 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12677 unchanged_p = 0;
12678 }
12679
12680 return unchanged_p;
12681 }
12682
12683
12684 /* Do a frame update, taking possible shortcuts into account. This is
12685 the main external entry point for redisplay.
12686
12687 If the last redisplay displayed an echo area message and that message
12688 is no longer requested, we clear the echo area or bring back the
12689 mini-buffer if that is in use. */
12690
12691 void
12692 redisplay (void)
12693 {
12694 redisplay_internal ();
12695 }
12696
12697
12698 static Lisp_Object
12699 overlay_arrow_string_or_property (Lisp_Object var)
12700 {
12701 Lisp_Object val;
12702
12703 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12704 return val;
12705
12706 return Voverlay_arrow_string;
12707 }
12708
12709 /* Return 1 if there are any overlay-arrows in current_buffer. */
12710 static int
12711 overlay_arrow_in_current_buffer_p (void)
12712 {
12713 Lisp_Object vlist;
12714
12715 for (vlist = Voverlay_arrow_variable_list;
12716 CONSP (vlist);
12717 vlist = XCDR (vlist))
12718 {
12719 Lisp_Object var = XCAR (vlist);
12720 Lisp_Object val;
12721
12722 if (!SYMBOLP (var))
12723 continue;
12724 val = find_symbol_value (var);
12725 if (MARKERP (val)
12726 && current_buffer == XMARKER (val)->buffer)
12727 return 1;
12728 }
12729 return 0;
12730 }
12731
12732
12733 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12734 has changed. */
12735
12736 static int
12737 overlay_arrows_changed_p (void)
12738 {
12739 Lisp_Object vlist;
12740
12741 for (vlist = Voverlay_arrow_variable_list;
12742 CONSP (vlist);
12743 vlist = XCDR (vlist))
12744 {
12745 Lisp_Object var = XCAR (vlist);
12746 Lisp_Object val, pstr;
12747
12748 if (!SYMBOLP (var))
12749 continue;
12750 val = find_symbol_value (var);
12751 if (!MARKERP (val))
12752 continue;
12753 if (! EQ (COERCE_MARKER (val),
12754 Fget (var, Qlast_arrow_position))
12755 || ! (pstr = overlay_arrow_string_or_property (var),
12756 EQ (pstr, Fget (var, Qlast_arrow_string))))
12757 return 1;
12758 }
12759 return 0;
12760 }
12761
12762 /* Mark overlay arrows to be updated on next redisplay. */
12763
12764 static void
12765 update_overlay_arrows (int up_to_date)
12766 {
12767 Lisp_Object vlist;
12768
12769 for (vlist = Voverlay_arrow_variable_list;
12770 CONSP (vlist);
12771 vlist = XCDR (vlist))
12772 {
12773 Lisp_Object var = XCAR (vlist);
12774
12775 if (!SYMBOLP (var))
12776 continue;
12777
12778 if (up_to_date > 0)
12779 {
12780 Lisp_Object val = find_symbol_value (var);
12781 Fput (var, Qlast_arrow_position,
12782 COERCE_MARKER (val));
12783 Fput (var, Qlast_arrow_string,
12784 overlay_arrow_string_or_property (var));
12785 }
12786 else if (up_to_date < 0
12787 || !NILP (Fget (var, Qlast_arrow_position)))
12788 {
12789 Fput (var, Qlast_arrow_position, Qt);
12790 Fput (var, Qlast_arrow_string, Qt);
12791 }
12792 }
12793 }
12794
12795
12796 /* Return overlay arrow string to display at row.
12797 Return integer (bitmap number) for arrow bitmap in left fringe.
12798 Return nil if no overlay arrow. */
12799
12800 static Lisp_Object
12801 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12802 {
12803 Lisp_Object vlist;
12804
12805 for (vlist = Voverlay_arrow_variable_list;
12806 CONSP (vlist);
12807 vlist = XCDR (vlist))
12808 {
12809 Lisp_Object var = XCAR (vlist);
12810 Lisp_Object val;
12811
12812 if (!SYMBOLP (var))
12813 continue;
12814
12815 val = find_symbol_value (var);
12816
12817 if (MARKERP (val)
12818 && current_buffer == XMARKER (val)->buffer
12819 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12820 {
12821 if (FRAME_WINDOW_P (it->f)
12822 /* FIXME: if ROW->reversed_p is set, this should test
12823 the right fringe, not the left one. */
12824 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12825 {
12826 #ifdef HAVE_WINDOW_SYSTEM
12827 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12828 {
12829 int fringe_bitmap;
12830 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12831 return make_number (fringe_bitmap);
12832 }
12833 #endif
12834 return make_number (-1); /* Use default arrow bitmap. */
12835 }
12836 return overlay_arrow_string_or_property (var);
12837 }
12838 }
12839
12840 return Qnil;
12841 }
12842
12843 /* Return 1 if point moved out of or into a composition. Otherwise
12844 return 0. PREV_BUF and PREV_PT are the last point buffer and
12845 position. BUF and PT are the current point buffer and position. */
12846
12847 static int
12848 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12849 struct buffer *buf, ptrdiff_t pt)
12850 {
12851 ptrdiff_t start, end;
12852 Lisp_Object prop;
12853 Lisp_Object buffer;
12854
12855 XSETBUFFER (buffer, buf);
12856 /* Check a composition at the last point if point moved within the
12857 same buffer. */
12858 if (prev_buf == buf)
12859 {
12860 if (prev_pt == pt)
12861 /* Point didn't move. */
12862 return 0;
12863
12864 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12865 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12866 && composition_valid_p (start, end, prop)
12867 && start < prev_pt && end > prev_pt)
12868 /* The last point was within the composition. Return 1 iff
12869 point moved out of the composition. */
12870 return (pt <= start || pt >= end);
12871 }
12872
12873 /* Check a composition at the current point. */
12874 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12875 && find_composition (pt, -1, &start, &end, &prop, buffer)
12876 && composition_valid_p (start, end, prop)
12877 && start < pt && end > pt);
12878 }
12879
12880 /* Reconsider the clip changes of buffer which is displayed in W. */
12881
12882 static void
12883 reconsider_clip_changes (struct window *w)
12884 {
12885 struct buffer *b = XBUFFER (w->contents);
12886
12887 if (b->clip_changed
12888 && w->window_end_valid
12889 && w->current_matrix->buffer == b
12890 && w->current_matrix->zv == BUF_ZV (b)
12891 && w->current_matrix->begv == BUF_BEGV (b))
12892 b->clip_changed = 0;
12893
12894 /* If display wasn't paused, and W is not a tool bar window, see if
12895 point has been moved into or out of a composition. In that case,
12896 we set b->clip_changed to 1 to force updating the screen. If
12897 b->clip_changed has already been set to 1, we can skip this
12898 check. */
12899 if (!b->clip_changed && w->window_end_valid)
12900 {
12901 ptrdiff_t pt = (w == XWINDOW (selected_window)
12902 ? PT : marker_position (w->pointm));
12903
12904 if ((w->current_matrix->buffer != b || pt != w->last_point)
12905 && check_point_in_composition (w->current_matrix->buffer,
12906 w->last_point, b, pt))
12907 b->clip_changed = 1;
12908 }
12909 }
12910
12911 #define STOP_POLLING \
12912 do { if (! polling_stopped_here) stop_polling (); \
12913 polling_stopped_here = 1; } while (0)
12914
12915 #define RESUME_POLLING \
12916 do { if (polling_stopped_here) start_polling (); \
12917 polling_stopped_here = 0; } while (0)
12918
12919
12920 /* Perhaps in the future avoid recentering windows if it
12921 is not necessary; currently that causes some problems. */
12922
12923 static void
12924 redisplay_internal (void)
12925 {
12926 struct window *w = XWINDOW (selected_window);
12927 struct window *sw;
12928 struct frame *fr;
12929 int pending;
12930 bool must_finish = 0, match_p;
12931 struct text_pos tlbufpos, tlendpos;
12932 int number_of_visible_frames;
12933 ptrdiff_t count;
12934 struct frame *sf;
12935 int polling_stopped_here = 0;
12936 Lisp_Object tail, frame;
12937
12938 /* Non-zero means redisplay has to consider all windows on all
12939 frames. Zero means, only selected_window is considered. */
12940 int consider_all_windows_p;
12941
12942 /* Non-zero means redisplay has to redisplay the miniwindow. */
12943 int update_miniwindow_p = 0;
12944
12945 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12946
12947 /* No redisplay if running in batch mode or frame is not yet fully
12948 initialized, or redisplay is explicitly turned off by setting
12949 Vinhibit_redisplay. */
12950 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12951 || !NILP (Vinhibit_redisplay))
12952 return;
12953
12954 /* Don't examine these until after testing Vinhibit_redisplay.
12955 When Emacs is shutting down, perhaps because its connection to
12956 X has dropped, we should not look at them at all. */
12957 fr = XFRAME (w->frame);
12958 sf = SELECTED_FRAME ();
12959
12960 if (!fr->glyphs_initialized_p)
12961 return;
12962
12963 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12964 if (popup_activated ())
12965 return;
12966 #endif
12967
12968 /* I don't think this happens but let's be paranoid. */
12969 if (redisplaying_p)
12970 return;
12971
12972 /* Record a function that clears redisplaying_p
12973 when we leave this function. */
12974 count = SPECPDL_INDEX ();
12975 record_unwind_protect_void (unwind_redisplay);
12976 redisplaying_p = 1;
12977 specbind (Qinhibit_free_realized_faces, Qnil);
12978
12979 /* Record this function, so it appears on the profiler's backtraces. */
12980 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
12981
12982 FOR_EACH_FRAME (tail, frame)
12983 XFRAME (frame)->already_hscrolled_p = 0;
12984
12985 retry:
12986 /* Remember the currently selected window. */
12987 sw = w;
12988
12989 pending = 0;
12990 last_escape_glyph_frame = NULL;
12991 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12992 last_glyphless_glyph_frame = NULL;
12993 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12994
12995 /* If new fonts have been loaded that make a glyph matrix adjustment
12996 necessary, do it. */
12997 if (fonts_changed_p)
12998 {
12999 adjust_glyphs (NULL);
13000 ++windows_or_buffers_changed;
13001 fonts_changed_p = 0;
13002 }
13003
13004 /* If face_change_count is non-zero, init_iterator will free all
13005 realized faces, which includes the faces referenced from current
13006 matrices. So, we can't reuse current matrices in this case. */
13007 if (face_change_count)
13008 ++windows_or_buffers_changed;
13009
13010 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13011 && FRAME_TTY (sf)->previous_frame != sf)
13012 {
13013 /* Since frames on a single ASCII terminal share the same
13014 display area, displaying a different frame means redisplay
13015 the whole thing. */
13016 windows_or_buffers_changed++;
13017 SET_FRAME_GARBAGED (sf);
13018 #ifndef DOS_NT
13019 set_tty_color_mode (FRAME_TTY (sf), sf);
13020 #endif
13021 FRAME_TTY (sf)->previous_frame = sf;
13022 }
13023
13024 /* Set the visible flags for all frames. Do this before checking for
13025 resized or garbaged frames; they want to know if their frames are
13026 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13027 number_of_visible_frames = 0;
13028
13029 FOR_EACH_FRAME (tail, frame)
13030 {
13031 struct frame *f = XFRAME (frame);
13032
13033 if (FRAME_VISIBLE_P (f))
13034 ++number_of_visible_frames;
13035 clear_desired_matrices (f);
13036 }
13037
13038 /* Notice any pending interrupt request to change frame size. */
13039 do_pending_window_change (1);
13040
13041 /* do_pending_window_change could change the selected_window due to
13042 frame resizing which makes the selected window too small. */
13043 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13044 sw = w;
13045
13046 /* Clear frames marked as garbaged. */
13047 clear_garbaged_frames ();
13048
13049 /* Build menubar and tool-bar items. */
13050 if (NILP (Vmemory_full))
13051 prepare_menu_bars ();
13052
13053 if (windows_or_buffers_changed)
13054 update_mode_lines++;
13055
13056 reconsider_clip_changes (w);
13057
13058 /* In most cases selected window displays current buffer. */
13059 match_p = XBUFFER (w->contents) == current_buffer;
13060 if (match_p)
13061 {
13062 ptrdiff_t count1;
13063
13064 /* Detect case that we need to write or remove a star in the mode line. */
13065 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13066 {
13067 w->update_mode_line = 1;
13068 if (buffer_shared_and_changed ())
13069 update_mode_lines++;
13070 }
13071
13072 /* Avoid invocation of point motion hooks by `current_column' below. */
13073 count1 = SPECPDL_INDEX ();
13074 specbind (Qinhibit_point_motion_hooks, Qt);
13075
13076 if (mode_line_update_needed (w))
13077 w->update_mode_line = 1;
13078
13079 unbind_to (count1, Qnil);
13080 }
13081
13082 consider_all_windows_p = (update_mode_lines
13083 || buffer_shared_and_changed ()
13084 || cursor_type_changed);
13085
13086 /* If specs for an arrow have changed, do thorough redisplay
13087 to ensure we remove any arrow that should no longer exist. */
13088 if (overlay_arrows_changed_p ())
13089 consider_all_windows_p = windows_or_buffers_changed = 1;
13090
13091 /* Normally the message* functions will have already displayed and
13092 updated the echo area, but the frame may have been trashed, or
13093 the update may have been preempted, so display the echo area
13094 again here. Checking message_cleared_p captures the case that
13095 the echo area should be cleared. */
13096 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13097 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13098 || (message_cleared_p
13099 && minibuf_level == 0
13100 /* If the mini-window is currently selected, this means the
13101 echo-area doesn't show through. */
13102 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13103 {
13104 int window_height_changed_p = echo_area_display (0);
13105
13106 if (message_cleared_p)
13107 update_miniwindow_p = 1;
13108
13109 must_finish = 1;
13110
13111 /* If we don't display the current message, don't clear the
13112 message_cleared_p flag, because, if we did, we wouldn't clear
13113 the echo area in the next redisplay which doesn't preserve
13114 the echo area. */
13115 if (!display_last_displayed_message_p)
13116 message_cleared_p = 0;
13117
13118 if (fonts_changed_p)
13119 goto retry;
13120 else if (window_height_changed_p)
13121 {
13122 consider_all_windows_p = 1;
13123 ++update_mode_lines;
13124 ++windows_or_buffers_changed;
13125
13126 /* If window configuration was changed, frames may have been
13127 marked garbaged. Clear them or we will experience
13128 surprises wrt scrolling. */
13129 clear_garbaged_frames ();
13130 }
13131 }
13132 else if (EQ (selected_window, minibuf_window)
13133 && (current_buffer->clip_changed || window_outdated (w))
13134 && resize_mini_window (w, 0))
13135 {
13136 /* Resized active mini-window to fit the size of what it is
13137 showing if its contents might have changed. */
13138 must_finish = 1;
13139 /* FIXME: this causes all frames to be updated, which seems unnecessary
13140 since only the current frame needs to be considered. This function
13141 needs to be rewritten with two variables, consider_all_windows and
13142 consider_all_frames. */
13143 consider_all_windows_p = 1;
13144 ++windows_or_buffers_changed;
13145 ++update_mode_lines;
13146
13147 /* If window configuration was changed, frames may have been
13148 marked garbaged. Clear them or we will experience
13149 surprises wrt scrolling. */
13150 clear_garbaged_frames ();
13151 }
13152
13153 /* If showing the region, and mark has changed, we must redisplay
13154 the whole window. The assignment to this_line_start_pos prevents
13155 the optimization directly below this if-statement. */
13156 if (((!NILP (Vtransient_mark_mode)
13157 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13158 != (w->region_showing > 0))
13159 || (w->region_showing
13160 && w->region_showing
13161 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13162 CHARPOS (this_line_start_pos) = 0;
13163
13164 /* Optimize the case that only the line containing the cursor in the
13165 selected window has changed. Variables starting with this_ are
13166 set in display_line and record information about the line
13167 containing the cursor. */
13168 tlbufpos = this_line_start_pos;
13169 tlendpos = this_line_end_pos;
13170 if (!consider_all_windows_p
13171 && CHARPOS (tlbufpos) > 0
13172 && !w->update_mode_line
13173 && !current_buffer->clip_changed
13174 && !current_buffer->prevent_redisplay_optimizations_p
13175 && FRAME_VISIBLE_P (XFRAME (w->frame))
13176 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13177 /* Make sure recorded data applies to current buffer, etc. */
13178 && this_line_buffer == current_buffer
13179 && match_p
13180 && !w->force_start
13181 && !w->optional_new_start
13182 /* Point must be on the line that we have info recorded about. */
13183 && PT >= CHARPOS (tlbufpos)
13184 && PT <= Z - CHARPOS (tlendpos)
13185 /* All text outside that line, including its final newline,
13186 must be unchanged. */
13187 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13188 CHARPOS (tlendpos)))
13189 {
13190 if (CHARPOS (tlbufpos) > BEGV
13191 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13192 && (CHARPOS (tlbufpos) == ZV
13193 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13194 /* Former continuation line has disappeared by becoming empty. */
13195 goto cancel;
13196 else if (window_outdated (w) || MINI_WINDOW_P (w))
13197 {
13198 /* We have to handle the case of continuation around a
13199 wide-column character (see the comment in indent.c around
13200 line 1340).
13201
13202 For instance, in the following case:
13203
13204 -------- Insert --------
13205 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13206 J_I_ ==> J_I_ `^^' are cursors.
13207 ^^ ^^
13208 -------- --------
13209
13210 As we have to redraw the line above, we cannot use this
13211 optimization. */
13212
13213 struct it it;
13214 int line_height_before = this_line_pixel_height;
13215
13216 /* Note that start_display will handle the case that the
13217 line starting at tlbufpos is a continuation line. */
13218 start_display (&it, w, tlbufpos);
13219
13220 /* Implementation note: It this still necessary? */
13221 if (it.current_x != this_line_start_x)
13222 goto cancel;
13223
13224 TRACE ((stderr, "trying display optimization 1\n"));
13225 w->cursor.vpos = -1;
13226 overlay_arrow_seen = 0;
13227 it.vpos = this_line_vpos;
13228 it.current_y = this_line_y;
13229 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13230 display_line (&it);
13231
13232 /* If line contains point, is not continued,
13233 and ends at same distance from eob as before, we win. */
13234 if (w->cursor.vpos >= 0
13235 /* Line is not continued, otherwise this_line_start_pos
13236 would have been set to 0 in display_line. */
13237 && CHARPOS (this_line_start_pos)
13238 /* Line ends as before. */
13239 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13240 /* Line has same height as before. Otherwise other lines
13241 would have to be shifted up or down. */
13242 && this_line_pixel_height == line_height_before)
13243 {
13244 /* If this is not the window's last line, we must adjust
13245 the charstarts of the lines below. */
13246 if (it.current_y < it.last_visible_y)
13247 {
13248 struct glyph_row *row
13249 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13250 ptrdiff_t delta, delta_bytes;
13251
13252 /* We used to distinguish between two cases here,
13253 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13254 when the line ends in a newline or the end of the
13255 buffer's accessible portion. But both cases did
13256 the same, so they were collapsed. */
13257 delta = (Z
13258 - CHARPOS (tlendpos)
13259 - MATRIX_ROW_START_CHARPOS (row));
13260 delta_bytes = (Z_BYTE
13261 - BYTEPOS (tlendpos)
13262 - MATRIX_ROW_START_BYTEPOS (row));
13263
13264 increment_matrix_positions (w->current_matrix,
13265 this_line_vpos + 1,
13266 w->current_matrix->nrows,
13267 delta, delta_bytes);
13268 }
13269
13270 /* If this row displays text now but previously didn't,
13271 or vice versa, w->window_end_vpos may have to be
13272 adjusted. */
13273 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13274 {
13275 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
13276 wset_window_end_vpos (w, make_number (this_line_vpos));
13277 }
13278 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13279 && this_line_vpos > 0)
13280 wset_window_end_vpos (w, make_number (this_line_vpos - 1));
13281 w->window_end_valid = 0;
13282
13283 /* Update hint: No need to try to scroll in update_window. */
13284 w->desired_matrix->no_scrolling_p = 1;
13285
13286 #ifdef GLYPH_DEBUG
13287 *w->desired_matrix->method = 0;
13288 debug_method_add (w, "optimization 1");
13289 #endif
13290 #ifdef HAVE_WINDOW_SYSTEM
13291 update_window_fringes (w, 0);
13292 #endif
13293 goto update;
13294 }
13295 else
13296 goto cancel;
13297 }
13298 else if (/* Cursor position hasn't changed. */
13299 PT == w->last_point
13300 /* Make sure the cursor was last displayed
13301 in this window. Otherwise we have to reposition it. */
13302 && 0 <= w->cursor.vpos
13303 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13304 {
13305 if (!must_finish)
13306 {
13307 do_pending_window_change (1);
13308 /* If selected_window changed, redisplay again. */
13309 if (WINDOWP (selected_window)
13310 && (w = XWINDOW (selected_window)) != sw)
13311 goto retry;
13312
13313 /* We used to always goto end_of_redisplay here, but this
13314 isn't enough if we have a blinking cursor. */
13315 if (w->cursor_off_p == w->last_cursor_off_p)
13316 goto end_of_redisplay;
13317 }
13318 goto update;
13319 }
13320 /* If highlighting the region, or if the cursor is in the echo area,
13321 then we can't just move the cursor. */
13322 else if (! (!NILP (Vtransient_mark_mode)
13323 && !NILP (BVAR (current_buffer, mark_active)))
13324 && (EQ (selected_window,
13325 BVAR (current_buffer, last_selected_window))
13326 || highlight_nonselected_windows)
13327 && !w->region_showing
13328 && NILP (Vshow_trailing_whitespace)
13329 && !cursor_in_echo_area)
13330 {
13331 struct it it;
13332 struct glyph_row *row;
13333
13334 /* Skip from tlbufpos to PT and see where it is. Note that
13335 PT may be in invisible text. If so, we will end at the
13336 next visible position. */
13337 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13338 NULL, DEFAULT_FACE_ID);
13339 it.current_x = this_line_start_x;
13340 it.current_y = this_line_y;
13341 it.vpos = this_line_vpos;
13342
13343 /* The call to move_it_to stops in front of PT, but
13344 moves over before-strings. */
13345 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13346
13347 if (it.vpos == this_line_vpos
13348 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13349 row->enabled_p))
13350 {
13351 eassert (this_line_vpos == it.vpos);
13352 eassert (this_line_y == it.current_y);
13353 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13354 #ifdef GLYPH_DEBUG
13355 *w->desired_matrix->method = 0;
13356 debug_method_add (w, "optimization 3");
13357 #endif
13358 goto update;
13359 }
13360 else
13361 goto cancel;
13362 }
13363
13364 cancel:
13365 /* Text changed drastically or point moved off of line. */
13366 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13367 }
13368
13369 CHARPOS (this_line_start_pos) = 0;
13370 consider_all_windows_p |= buffer_shared_and_changed ();
13371 ++clear_face_cache_count;
13372 #ifdef HAVE_WINDOW_SYSTEM
13373 ++clear_image_cache_count;
13374 #endif
13375
13376 /* Build desired matrices, and update the display. If
13377 consider_all_windows_p is non-zero, do it for all windows on all
13378 frames. Otherwise do it for selected_window, only. */
13379
13380 if (consider_all_windows_p)
13381 {
13382 FOR_EACH_FRAME (tail, frame)
13383 XFRAME (frame)->updated_p = 0;
13384
13385 FOR_EACH_FRAME (tail, frame)
13386 {
13387 struct frame *f = XFRAME (frame);
13388
13389 /* We don't have to do anything for unselected terminal
13390 frames. */
13391 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13392 && !EQ (FRAME_TTY (f)->top_frame, frame))
13393 continue;
13394
13395 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13396 {
13397 /* Mark all the scroll bars to be removed; we'll redeem
13398 the ones we want when we redisplay their windows. */
13399 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13400 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13401
13402 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13403 redisplay_windows (FRAME_ROOT_WINDOW (f));
13404
13405 /* The X error handler may have deleted that frame. */
13406 if (!FRAME_LIVE_P (f))
13407 continue;
13408
13409 /* Any scroll bars which redisplay_windows should have
13410 nuked should now go away. */
13411 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13412 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13413
13414 /* If fonts changed, display again. */
13415 /* ??? rms: I suspect it is a mistake to jump all the way
13416 back to retry here. It should just retry this frame. */
13417 if (fonts_changed_p)
13418 goto retry;
13419
13420 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13421 {
13422 /* See if we have to hscroll. */
13423 if (!f->already_hscrolled_p)
13424 {
13425 f->already_hscrolled_p = 1;
13426 if (hscroll_windows (f->root_window))
13427 goto retry;
13428 }
13429
13430 /* Prevent various kinds of signals during display
13431 update. stdio is not robust about handling
13432 signals, which can cause an apparent I/O
13433 error. */
13434 if (interrupt_input)
13435 unrequest_sigio ();
13436 STOP_POLLING;
13437
13438 /* Update the display. */
13439 set_window_update_flags (XWINDOW (f->root_window), 1);
13440 pending |= update_frame (f, 0, 0);
13441 f->updated_p = 1;
13442 }
13443 }
13444 }
13445
13446 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13447
13448 if (!pending)
13449 {
13450 /* Do the mark_window_display_accurate after all windows have
13451 been redisplayed because this call resets flags in buffers
13452 which are needed for proper redisplay. */
13453 FOR_EACH_FRAME (tail, frame)
13454 {
13455 struct frame *f = XFRAME (frame);
13456 if (f->updated_p)
13457 {
13458 mark_window_display_accurate (f->root_window, 1);
13459 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13460 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13461 }
13462 }
13463 }
13464 }
13465 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13466 {
13467 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13468 struct frame *mini_frame;
13469
13470 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13471 /* Use list_of_error, not Qerror, so that
13472 we catch only errors and don't run the debugger. */
13473 internal_condition_case_1 (redisplay_window_1, selected_window,
13474 list_of_error,
13475 redisplay_window_error);
13476 if (update_miniwindow_p)
13477 internal_condition_case_1 (redisplay_window_1, mini_window,
13478 list_of_error,
13479 redisplay_window_error);
13480
13481 /* Compare desired and current matrices, perform output. */
13482
13483 update:
13484 /* If fonts changed, display again. */
13485 if (fonts_changed_p)
13486 goto retry;
13487
13488 /* Prevent various kinds of signals during display update.
13489 stdio is not robust about handling signals,
13490 which can cause an apparent I/O error. */
13491 if (interrupt_input)
13492 unrequest_sigio ();
13493 STOP_POLLING;
13494
13495 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13496 {
13497 if (hscroll_windows (selected_window))
13498 goto retry;
13499
13500 XWINDOW (selected_window)->must_be_updated_p = 1;
13501 pending = update_frame (sf, 0, 0);
13502 }
13503
13504 /* We may have called echo_area_display at the top of this
13505 function. If the echo area is on another frame, that may
13506 have put text on a frame other than the selected one, so the
13507 above call to update_frame would not have caught it. Catch
13508 it here. */
13509 mini_window = FRAME_MINIBUF_WINDOW (sf);
13510 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13511
13512 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13513 {
13514 XWINDOW (mini_window)->must_be_updated_p = 1;
13515 pending |= update_frame (mini_frame, 0, 0);
13516 if (!pending && hscroll_windows (mini_window))
13517 goto retry;
13518 }
13519 }
13520
13521 /* If display was paused because of pending input, make sure we do a
13522 thorough update the next time. */
13523 if (pending)
13524 {
13525 /* Prevent the optimization at the beginning of
13526 redisplay_internal that tries a single-line update of the
13527 line containing the cursor in the selected window. */
13528 CHARPOS (this_line_start_pos) = 0;
13529
13530 /* Let the overlay arrow be updated the next time. */
13531 update_overlay_arrows (0);
13532
13533 /* If we pause after scrolling, some rows in the current
13534 matrices of some windows are not valid. */
13535 if (!WINDOW_FULL_WIDTH_P (w)
13536 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13537 update_mode_lines = 1;
13538 }
13539 else
13540 {
13541 if (!consider_all_windows_p)
13542 {
13543 /* This has already been done above if
13544 consider_all_windows_p is set. */
13545 mark_window_display_accurate_1 (w, 1);
13546
13547 /* Say overlay arrows are up to date. */
13548 update_overlay_arrows (1);
13549
13550 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13551 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13552 }
13553
13554 update_mode_lines = 0;
13555 windows_or_buffers_changed = 0;
13556 cursor_type_changed = 0;
13557 }
13558
13559 /* Start SIGIO interrupts coming again. Having them off during the
13560 code above makes it less likely one will discard output, but not
13561 impossible, since there might be stuff in the system buffer here.
13562 But it is much hairier to try to do anything about that. */
13563 if (interrupt_input)
13564 request_sigio ();
13565 RESUME_POLLING;
13566
13567 /* If a frame has become visible which was not before, redisplay
13568 again, so that we display it. Expose events for such a frame
13569 (which it gets when becoming visible) don't call the parts of
13570 redisplay constructing glyphs, so simply exposing a frame won't
13571 display anything in this case. So, we have to display these
13572 frames here explicitly. */
13573 if (!pending)
13574 {
13575 int new_count = 0;
13576
13577 FOR_EACH_FRAME (tail, frame)
13578 {
13579 int this_is_visible = 0;
13580
13581 if (XFRAME (frame)->visible)
13582 this_is_visible = 1;
13583
13584 if (this_is_visible)
13585 new_count++;
13586 }
13587
13588 if (new_count != number_of_visible_frames)
13589 windows_or_buffers_changed++;
13590 }
13591
13592 /* Change frame size now if a change is pending. */
13593 do_pending_window_change (1);
13594
13595 /* If we just did a pending size change, or have additional
13596 visible frames, or selected_window changed, redisplay again. */
13597 if ((windows_or_buffers_changed && !pending)
13598 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13599 goto retry;
13600
13601 /* Clear the face and image caches.
13602
13603 We used to do this only if consider_all_windows_p. But the cache
13604 needs to be cleared if a timer creates images in the current
13605 buffer (e.g. the test case in Bug#6230). */
13606
13607 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13608 {
13609 clear_face_cache (0);
13610 clear_face_cache_count = 0;
13611 }
13612
13613 #ifdef HAVE_WINDOW_SYSTEM
13614 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13615 {
13616 clear_image_caches (Qnil);
13617 clear_image_cache_count = 0;
13618 }
13619 #endif /* HAVE_WINDOW_SYSTEM */
13620
13621 end_of_redisplay:
13622 unbind_to (count, Qnil);
13623 RESUME_POLLING;
13624 }
13625
13626
13627 /* Redisplay, but leave alone any recent echo area message unless
13628 another message has been requested in its place.
13629
13630 This is useful in situations where you need to redisplay but no
13631 user action has occurred, making it inappropriate for the message
13632 area to be cleared. See tracking_off and
13633 wait_reading_process_output for examples of these situations.
13634
13635 FROM_WHERE is an integer saying from where this function was
13636 called. This is useful for debugging. */
13637
13638 void
13639 redisplay_preserve_echo_area (int from_where)
13640 {
13641 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13642
13643 if (!NILP (echo_area_buffer[1]))
13644 {
13645 /* We have a previously displayed message, but no current
13646 message. Redisplay the previous message. */
13647 display_last_displayed_message_p = 1;
13648 redisplay_internal ();
13649 display_last_displayed_message_p = 0;
13650 }
13651 else
13652 redisplay_internal ();
13653
13654 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13655 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13656 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13657 }
13658
13659
13660 /* Function registered with record_unwind_protect in redisplay_internal. */
13661
13662 static void
13663 unwind_redisplay (void)
13664 {
13665 redisplaying_p = 0;
13666 }
13667
13668
13669 /* Mark the display of leaf window W as accurate or inaccurate.
13670 If ACCURATE_P is non-zero mark display of W as accurate. If
13671 ACCURATE_P is zero, arrange for W to be redisplayed the next
13672 time redisplay_internal is called. */
13673
13674 static void
13675 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13676 {
13677 struct buffer *b = XBUFFER (w->contents);
13678
13679 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13680 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13681 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13682
13683 if (accurate_p)
13684 {
13685 b->clip_changed = 0;
13686 b->prevent_redisplay_optimizations_p = 0;
13687
13688 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13689 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13690 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13691 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13692
13693 w->current_matrix->buffer = b;
13694 w->current_matrix->begv = BUF_BEGV (b);
13695 w->current_matrix->zv = BUF_ZV (b);
13696
13697 w->last_cursor = w->cursor;
13698 w->last_cursor_off_p = w->cursor_off_p;
13699
13700 if (w == XWINDOW (selected_window))
13701 w->last_point = BUF_PT (b);
13702 else
13703 w->last_point = marker_position (w->pointm);
13704
13705 w->window_end_valid = 1;
13706 w->update_mode_line = 0;
13707 }
13708 }
13709
13710
13711 /* Mark the display of windows in the window tree rooted at WINDOW as
13712 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13713 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13714 be redisplayed the next time redisplay_internal is called. */
13715
13716 void
13717 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13718 {
13719 struct window *w;
13720
13721 for (; !NILP (window); window = w->next)
13722 {
13723 w = XWINDOW (window);
13724 if (WINDOWP (w->contents))
13725 mark_window_display_accurate (w->contents, accurate_p);
13726 else
13727 mark_window_display_accurate_1 (w, accurate_p);
13728 }
13729
13730 if (accurate_p)
13731 update_overlay_arrows (1);
13732 else
13733 /* Force a thorough redisplay the next time by setting
13734 last_arrow_position and last_arrow_string to t, which is
13735 unequal to any useful value of Voverlay_arrow_... */
13736 update_overlay_arrows (-1);
13737 }
13738
13739
13740 /* Return value in display table DP (Lisp_Char_Table *) for character
13741 C. Since a display table doesn't have any parent, we don't have to
13742 follow parent. Do not call this function directly but use the
13743 macro DISP_CHAR_VECTOR. */
13744
13745 Lisp_Object
13746 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13747 {
13748 Lisp_Object val;
13749
13750 if (ASCII_CHAR_P (c))
13751 {
13752 val = dp->ascii;
13753 if (SUB_CHAR_TABLE_P (val))
13754 val = XSUB_CHAR_TABLE (val)->contents[c];
13755 }
13756 else
13757 {
13758 Lisp_Object table;
13759
13760 XSETCHAR_TABLE (table, dp);
13761 val = char_table_ref (table, c);
13762 }
13763 if (NILP (val))
13764 val = dp->defalt;
13765 return val;
13766 }
13767
13768
13769 \f
13770 /***********************************************************************
13771 Window Redisplay
13772 ***********************************************************************/
13773
13774 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13775
13776 static void
13777 redisplay_windows (Lisp_Object window)
13778 {
13779 while (!NILP (window))
13780 {
13781 struct window *w = XWINDOW (window);
13782
13783 if (WINDOWP (w->contents))
13784 redisplay_windows (w->contents);
13785 else if (BUFFERP (w->contents))
13786 {
13787 displayed_buffer = XBUFFER (w->contents);
13788 /* Use list_of_error, not Qerror, so that
13789 we catch only errors and don't run the debugger. */
13790 internal_condition_case_1 (redisplay_window_0, window,
13791 list_of_error,
13792 redisplay_window_error);
13793 }
13794
13795 window = w->next;
13796 }
13797 }
13798
13799 static Lisp_Object
13800 redisplay_window_error (Lisp_Object ignore)
13801 {
13802 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13803 return Qnil;
13804 }
13805
13806 static Lisp_Object
13807 redisplay_window_0 (Lisp_Object window)
13808 {
13809 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13810 redisplay_window (window, 0);
13811 return Qnil;
13812 }
13813
13814 static Lisp_Object
13815 redisplay_window_1 (Lisp_Object window)
13816 {
13817 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13818 redisplay_window (window, 1);
13819 return Qnil;
13820 }
13821 \f
13822
13823 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13824 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13825 which positions recorded in ROW differ from current buffer
13826 positions.
13827
13828 Return 0 if cursor is not on this row, 1 otherwise. */
13829
13830 static int
13831 set_cursor_from_row (struct window *w, struct glyph_row *row,
13832 struct glyph_matrix *matrix,
13833 ptrdiff_t delta, ptrdiff_t delta_bytes,
13834 int dy, int dvpos)
13835 {
13836 struct glyph *glyph = row->glyphs[TEXT_AREA];
13837 struct glyph *end = glyph + row->used[TEXT_AREA];
13838 struct glyph *cursor = NULL;
13839 /* The last known character position in row. */
13840 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13841 int x = row->x;
13842 ptrdiff_t pt_old = PT - delta;
13843 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13844 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13845 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13846 /* A glyph beyond the edge of TEXT_AREA which we should never
13847 touch. */
13848 struct glyph *glyphs_end = end;
13849 /* Non-zero means we've found a match for cursor position, but that
13850 glyph has the avoid_cursor_p flag set. */
13851 int match_with_avoid_cursor = 0;
13852 /* Non-zero means we've seen at least one glyph that came from a
13853 display string. */
13854 int string_seen = 0;
13855 /* Largest and smallest buffer positions seen so far during scan of
13856 glyph row. */
13857 ptrdiff_t bpos_max = pos_before;
13858 ptrdiff_t bpos_min = pos_after;
13859 /* Last buffer position covered by an overlay string with an integer
13860 `cursor' property. */
13861 ptrdiff_t bpos_covered = 0;
13862 /* Non-zero means the display string on which to display the cursor
13863 comes from a text property, not from an overlay. */
13864 int string_from_text_prop = 0;
13865
13866 /* Don't even try doing anything if called for a mode-line or
13867 header-line row, since the rest of the code isn't prepared to
13868 deal with such calamities. */
13869 eassert (!row->mode_line_p);
13870 if (row->mode_line_p)
13871 return 0;
13872
13873 /* Skip over glyphs not having an object at the start and the end of
13874 the row. These are special glyphs like truncation marks on
13875 terminal frames. */
13876 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13877 {
13878 if (!row->reversed_p)
13879 {
13880 while (glyph < end
13881 && INTEGERP (glyph->object)
13882 && glyph->charpos < 0)
13883 {
13884 x += glyph->pixel_width;
13885 ++glyph;
13886 }
13887 while (end > glyph
13888 && INTEGERP ((end - 1)->object)
13889 /* CHARPOS is zero for blanks and stretch glyphs
13890 inserted by extend_face_to_end_of_line. */
13891 && (end - 1)->charpos <= 0)
13892 --end;
13893 glyph_before = glyph - 1;
13894 glyph_after = end;
13895 }
13896 else
13897 {
13898 struct glyph *g;
13899
13900 /* If the glyph row is reversed, we need to process it from back
13901 to front, so swap the edge pointers. */
13902 glyphs_end = end = glyph - 1;
13903 glyph += row->used[TEXT_AREA] - 1;
13904
13905 while (glyph > end + 1
13906 && INTEGERP (glyph->object)
13907 && glyph->charpos < 0)
13908 {
13909 --glyph;
13910 x -= glyph->pixel_width;
13911 }
13912 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13913 --glyph;
13914 /* By default, in reversed rows we put the cursor on the
13915 rightmost (first in the reading order) glyph. */
13916 for (g = end + 1; g < glyph; g++)
13917 x += g->pixel_width;
13918 while (end < glyph
13919 && INTEGERP ((end + 1)->object)
13920 && (end + 1)->charpos <= 0)
13921 ++end;
13922 glyph_before = glyph + 1;
13923 glyph_after = end;
13924 }
13925 }
13926 else if (row->reversed_p)
13927 {
13928 /* In R2L rows that don't display text, put the cursor on the
13929 rightmost glyph. Case in point: an empty last line that is
13930 part of an R2L paragraph. */
13931 cursor = end - 1;
13932 /* Avoid placing the cursor on the last glyph of the row, where
13933 on terminal frames we hold the vertical border between
13934 adjacent windows. */
13935 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13936 && !WINDOW_RIGHTMOST_P (w)
13937 && cursor == row->glyphs[LAST_AREA] - 1)
13938 cursor--;
13939 x = -1; /* will be computed below, at label compute_x */
13940 }
13941
13942 /* Step 1: Try to find the glyph whose character position
13943 corresponds to point. If that's not possible, find 2 glyphs
13944 whose character positions are the closest to point, one before
13945 point, the other after it. */
13946 if (!row->reversed_p)
13947 while (/* not marched to end of glyph row */
13948 glyph < end
13949 /* glyph was not inserted by redisplay for internal purposes */
13950 && !INTEGERP (glyph->object))
13951 {
13952 if (BUFFERP (glyph->object))
13953 {
13954 ptrdiff_t dpos = glyph->charpos - pt_old;
13955
13956 if (glyph->charpos > bpos_max)
13957 bpos_max = glyph->charpos;
13958 if (glyph->charpos < bpos_min)
13959 bpos_min = glyph->charpos;
13960 if (!glyph->avoid_cursor_p)
13961 {
13962 /* If we hit point, we've found the glyph on which to
13963 display the cursor. */
13964 if (dpos == 0)
13965 {
13966 match_with_avoid_cursor = 0;
13967 break;
13968 }
13969 /* See if we've found a better approximation to
13970 POS_BEFORE or to POS_AFTER. */
13971 if (0 > dpos && dpos > pos_before - pt_old)
13972 {
13973 pos_before = glyph->charpos;
13974 glyph_before = glyph;
13975 }
13976 else if (0 < dpos && dpos < pos_after - pt_old)
13977 {
13978 pos_after = glyph->charpos;
13979 glyph_after = glyph;
13980 }
13981 }
13982 else if (dpos == 0)
13983 match_with_avoid_cursor = 1;
13984 }
13985 else if (STRINGP (glyph->object))
13986 {
13987 Lisp_Object chprop;
13988 ptrdiff_t glyph_pos = glyph->charpos;
13989
13990 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13991 glyph->object);
13992 if (!NILP (chprop))
13993 {
13994 /* If the string came from a `display' text property,
13995 look up the buffer position of that property and
13996 use that position to update bpos_max, as if we
13997 actually saw such a position in one of the row's
13998 glyphs. This helps with supporting integer values
13999 of `cursor' property on the display string in
14000 situations where most or all of the row's buffer
14001 text is completely covered by display properties,
14002 so that no glyph with valid buffer positions is
14003 ever seen in the row. */
14004 ptrdiff_t prop_pos =
14005 string_buffer_position_lim (glyph->object, pos_before,
14006 pos_after, 0);
14007
14008 if (prop_pos >= pos_before)
14009 bpos_max = prop_pos - 1;
14010 }
14011 if (INTEGERP (chprop))
14012 {
14013 bpos_covered = bpos_max + XINT (chprop);
14014 /* If the `cursor' property covers buffer positions up
14015 to and including point, we should display cursor on
14016 this glyph. Note that, if a `cursor' property on one
14017 of the string's characters has an integer value, we
14018 will break out of the loop below _before_ we get to
14019 the position match above. IOW, integer values of
14020 the `cursor' property override the "exact match for
14021 point" strategy of positioning the cursor. */
14022 /* Implementation note: bpos_max == pt_old when, e.g.,
14023 we are in an empty line, where bpos_max is set to
14024 MATRIX_ROW_START_CHARPOS, see above. */
14025 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14026 {
14027 cursor = glyph;
14028 break;
14029 }
14030 }
14031
14032 string_seen = 1;
14033 }
14034 x += glyph->pixel_width;
14035 ++glyph;
14036 }
14037 else if (glyph > end) /* row is reversed */
14038 while (!INTEGERP (glyph->object))
14039 {
14040 if (BUFFERP (glyph->object))
14041 {
14042 ptrdiff_t dpos = glyph->charpos - pt_old;
14043
14044 if (glyph->charpos > bpos_max)
14045 bpos_max = glyph->charpos;
14046 if (glyph->charpos < bpos_min)
14047 bpos_min = glyph->charpos;
14048 if (!glyph->avoid_cursor_p)
14049 {
14050 if (dpos == 0)
14051 {
14052 match_with_avoid_cursor = 0;
14053 break;
14054 }
14055 if (0 > dpos && dpos > pos_before - pt_old)
14056 {
14057 pos_before = glyph->charpos;
14058 glyph_before = glyph;
14059 }
14060 else if (0 < dpos && dpos < pos_after - pt_old)
14061 {
14062 pos_after = glyph->charpos;
14063 glyph_after = glyph;
14064 }
14065 }
14066 else if (dpos == 0)
14067 match_with_avoid_cursor = 1;
14068 }
14069 else if (STRINGP (glyph->object))
14070 {
14071 Lisp_Object chprop;
14072 ptrdiff_t glyph_pos = glyph->charpos;
14073
14074 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14075 glyph->object);
14076 if (!NILP (chprop))
14077 {
14078 ptrdiff_t prop_pos =
14079 string_buffer_position_lim (glyph->object, pos_before,
14080 pos_after, 0);
14081
14082 if (prop_pos >= pos_before)
14083 bpos_max = prop_pos - 1;
14084 }
14085 if (INTEGERP (chprop))
14086 {
14087 bpos_covered = bpos_max + XINT (chprop);
14088 /* If the `cursor' property covers buffer positions up
14089 to and including point, we should display cursor on
14090 this glyph. */
14091 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14092 {
14093 cursor = glyph;
14094 break;
14095 }
14096 }
14097 string_seen = 1;
14098 }
14099 --glyph;
14100 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14101 {
14102 x--; /* can't use any pixel_width */
14103 break;
14104 }
14105 x -= glyph->pixel_width;
14106 }
14107
14108 /* Step 2: If we didn't find an exact match for point, we need to
14109 look for a proper place to put the cursor among glyphs between
14110 GLYPH_BEFORE and GLYPH_AFTER. */
14111 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14112 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14113 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14114 {
14115 /* An empty line has a single glyph whose OBJECT is zero and
14116 whose CHARPOS is the position of a newline on that line.
14117 Note that on a TTY, there are more glyphs after that, which
14118 were produced by extend_face_to_end_of_line, but their
14119 CHARPOS is zero or negative. */
14120 int empty_line_p =
14121 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14122 && INTEGERP (glyph->object) && glyph->charpos > 0
14123 /* On a TTY, continued and truncated rows also have a glyph at
14124 their end whose OBJECT is zero and whose CHARPOS is
14125 positive (the continuation and truncation glyphs), but such
14126 rows are obviously not "empty". */
14127 && !(row->continued_p || row->truncated_on_right_p);
14128
14129 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14130 {
14131 ptrdiff_t ellipsis_pos;
14132
14133 /* Scan back over the ellipsis glyphs. */
14134 if (!row->reversed_p)
14135 {
14136 ellipsis_pos = (glyph - 1)->charpos;
14137 while (glyph > row->glyphs[TEXT_AREA]
14138 && (glyph - 1)->charpos == ellipsis_pos)
14139 glyph--, x -= glyph->pixel_width;
14140 /* That loop always goes one position too far, including
14141 the glyph before the ellipsis. So scan forward over
14142 that one. */
14143 x += glyph->pixel_width;
14144 glyph++;
14145 }
14146 else /* row is reversed */
14147 {
14148 ellipsis_pos = (glyph + 1)->charpos;
14149 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14150 && (glyph + 1)->charpos == ellipsis_pos)
14151 glyph++, x += glyph->pixel_width;
14152 x -= glyph->pixel_width;
14153 glyph--;
14154 }
14155 }
14156 else if (match_with_avoid_cursor)
14157 {
14158 cursor = glyph_after;
14159 x = -1;
14160 }
14161 else if (string_seen)
14162 {
14163 int incr = row->reversed_p ? -1 : +1;
14164
14165 /* Need to find the glyph that came out of a string which is
14166 present at point. That glyph is somewhere between
14167 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14168 positioned between POS_BEFORE and POS_AFTER in the
14169 buffer. */
14170 struct glyph *start, *stop;
14171 ptrdiff_t pos = pos_before;
14172
14173 x = -1;
14174
14175 /* If the row ends in a newline from a display string,
14176 reordering could have moved the glyphs belonging to the
14177 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14178 in this case we extend the search to the last glyph in
14179 the row that was not inserted by redisplay. */
14180 if (row->ends_in_newline_from_string_p)
14181 {
14182 glyph_after = end;
14183 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14184 }
14185
14186 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14187 correspond to POS_BEFORE and POS_AFTER, respectively. We
14188 need START and STOP in the order that corresponds to the
14189 row's direction as given by its reversed_p flag. If the
14190 directionality of characters between POS_BEFORE and
14191 POS_AFTER is the opposite of the row's base direction,
14192 these characters will have been reordered for display,
14193 and we need to reverse START and STOP. */
14194 if (!row->reversed_p)
14195 {
14196 start = min (glyph_before, glyph_after);
14197 stop = max (glyph_before, glyph_after);
14198 }
14199 else
14200 {
14201 start = max (glyph_before, glyph_after);
14202 stop = min (glyph_before, glyph_after);
14203 }
14204 for (glyph = start + incr;
14205 row->reversed_p ? glyph > stop : glyph < stop; )
14206 {
14207
14208 /* Any glyphs that come from the buffer are here because
14209 of bidi reordering. Skip them, and only pay
14210 attention to glyphs that came from some string. */
14211 if (STRINGP (glyph->object))
14212 {
14213 Lisp_Object str;
14214 ptrdiff_t tem;
14215 /* If the display property covers the newline, we
14216 need to search for it one position farther. */
14217 ptrdiff_t lim = pos_after
14218 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14219
14220 string_from_text_prop = 0;
14221 str = glyph->object;
14222 tem = string_buffer_position_lim (str, pos, lim, 0);
14223 if (tem == 0 /* from overlay */
14224 || pos <= tem)
14225 {
14226 /* If the string from which this glyph came is
14227 found in the buffer at point, or at position
14228 that is closer to point than pos_after, then
14229 we've found the glyph we've been looking for.
14230 If it comes from an overlay (tem == 0), and
14231 it has the `cursor' property on one of its
14232 glyphs, record that glyph as a candidate for
14233 displaying the cursor. (As in the
14234 unidirectional version, we will display the
14235 cursor on the last candidate we find.) */
14236 if (tem == 0
14237 || tem == pt_old
14238 || (tem - pt_old > 0 && tem < pos_after))
14239 {
14240 /* The glyphs from this string could have
14241 been reordered. Find the one with the
14242 smallest string position. Or there could
14243 be a character in the string with the
14244 `cursor' property, which means display
14245 cursor on that character's glyph. */
14246 ptrdiff_t strpos = glyph->charpos;
14247
14248 if (tem)
14249 {
14250 cursor = glyph;
14251 string_from_text_prop = 1;
14252 }
14253 for ( ;
14254 (row->reversed_p ? glyph > stop : glyph < stop)
14255 && EQ (glyph->object, str);
14256 glyph += incr)
14257 {
14258 Lisp_Object cprop;
14259 ptrdiff_t gpos = glyph->charpos;
14260
14261 cprop = Fget_char_property (make_number (gpos),
14262 Qcursor,
14263 glyph->object);
14264 if (!NILP (cprop))
14265 {
14266 cursor = glyph;
14267 break;
14268 }
14269 if (tem && glyph->charpos < strpos)
14270 {
14271 strpos = glyph->charpos;
14272 cursor = glyph;
14273 }
14274 }
14275
14276 if (tem == pt_old
14277 || (tem - pt_old > 0 && tem < pos_after))
14278 goto compute_x;
14279 }
14280 if (tem)
14281 pos = tem + 1; /* don't find previous instances */
14282 }
14283 /* This string is not what we want; skip all of the
14284 glyphs that came from it. */
14285 while ((row->reversed_p ? glyph > stop : glyph < stop)
14286 && EQ (glyph->object, str))
14287 glyph += incr;
14288 }
14289 else
14290 glyph += incr;
14291 }
14292
14293 /* If we reached the end of the line, and END was from a string,
14294 the cursor is not on this line. */
14295 if (cursor == NULL
14296 && (row->reversed_p ? glyph <= end : glyph >= end)
14297 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14298 && STRINGP (end->object)
14299 && row->continued_p)
14300 return 0;
14301 }
14302 /* A truncated row may not include PT among its character positions.
14303 Setting the cursor inside the scroll margin will trigger
14304 recalculation of hscroll in hscroll_window_tree. But if a
14305 display string covers point, defer to the string-handling
14306 code below to figure this out. */
14307 else if (row->truncated_on_left_p && pt_old < bpos_min)
14308 {
14309 cursor = glyph_before;
14310 x = -1;
14311 }
14312 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14313 /* Zero-width characters produce no glyphs. */
14314 || (!empty_line_p
14315 && (row->reversed_p
14316 ? glyph_after > glyphs_end
14317 : glyph_after < glyphs_end)))
14318 {
14319 cursor = glyph_after;
14320 x = -1;
14321 }
14322 }
14323
14324 compute_x:
14325 if (cursor != NULL)
14326 glyph = cursor;
14327 else if (glyph == glyphs_end
14328 && pos_before == pos_after
14329 && STRINGP ((row->reversed_p
14330 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14331 : row->glyphs[TEXT_AREA])->object))
14332 {
14333 /* If all the glyphs of this row came from strings, put the
14334 cursor on the first glyph of the row. This avoids having the
14335 cursor outside of the text area in this very rare and hard
14336 use case. */
14337 glyph =
14338 row->reversed_p
14339 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14340 : row->glyphs[TEXT_AREA];
14341 }
14342 if (x < 0)
14343 {
14344 struct glyph *g;
14345
14346 /* Need to compute x that corresponds to GLYPH. */
14347 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14348 {
14349 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14350 emacs_abort ();
14351 x += g->pixel_width;
14352 }
14353 }
14354
14355 /* ROW could be part of a continued line, which, under bidi
14356 reordering, might have other rows whose start and end charpos
14357 occlude point. Only set w->cursor if we found a better
14358 approximation to the cursor position than we have from previously
14359 examined candidate rows belonging to the same continued line. */
14360 if (/* we already have a candidate row */
14361 w->cursor.vpos >= 0
14362 /* that candidate is not the row we are processing */
14363 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14364 /* Make sure cursor.vpos specifies a row whose start and end
14365 charpos occlude point, and it is valid candidate for being a
14366 cursor-row. This is because some callers of this function
14367 leave cursor.vpos at the row where the cursor was displayed
14368 during the last redisplay cycle. */
14369 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14370 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14371 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14372 {
14373 struct glyph *g1 =
14374 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14375
14376 /* Don't consider glyphs that are outside TEXT_AREA. */
14377 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14378 return 0;
14379 /* Keep the candidate whose buffer position is the closest to
14380 point or has the `cursor' property. */
14381 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14382 w->cursor.hpos >= 0
14383 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14384 && ((BUFFERP (g1->object)
14385 && (g1->charpos == pt_old /* an exact match always wins */
14386 || (BUFFERP (glyph->object)
14387 && eabs (g1->charpos - pt_old)
14388 < eabs (glyph->charpos - pt_old))))
14389 /* previous candidate is a glyph from a string that has
14390 a non-nil `cursor' property */
14391 || (STRINGP (g1->object)
14392 && (!NILP (Fget_char_property (make_number (g1->charpos),
14393 Qcursor, g1->object))
14394 /* previous candidate is from the same display
14395 string as this one, and the display string
14396 came from a text property */
14397 || (EQ (g1->object, glyph->object)
14398 && string_from_text_prop)
14399 /* this candidate is from newline and its
14400 position is not an exact match */
14401 || (INTEGERP (glyph->object)
14402 && glyph->charpos != pt_old)))))
14403 return 0;
14404 /* If this candidate gives an exact match, use that. */
14405 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14406 /* If this candidate is a glyph created for the
14407 terminating newline of a line, and point is on that
14408 newline, it wins because it's an exact match. */
14409 || (!row->continued_p
14410 && INTEGERP (glyph->object)
14411 && glyph->charpos == 0
14412 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14413 /* Otherwise, keep the candidate that comes from a row
14414 spanning less buffer positions. This may win when one or
14415 both candidate positions are on glyphs that came from
14416 display strings, for which we cannot compare buffer
14417 positions. */
14418 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14419 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14420 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14421 return 0;
14422 }
14423 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14424 w->cursor.x = x;
14425 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14426 w->cursor.y = row->y + dy;
14427
14428 if (w == XWINDOW (selected_window))
14429 {
14430 if (!row->continued_p
14431 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14432 && row->x == 0)
14433 {
14434 this_line_buffer = XBUFFER (w->contents);
14435
14436 CHARPOS (this_line_start_pos)
14437 = MATRIX_ROW_START_CHARPOS (row) + delta;
14438 BYTEPOS (this_line_start_pos)
14439 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14440
14441 CHARPOS (this_line_end_pos)
14442 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14443 BYTEPOS (this_line_end_pos)
14444 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14445
14446 this_line_y = w->cursor.y;
14447 this_line_pixel_height = row->height;
14448 this_line_vpos = w->cursor.vpos;
14449 this_line_start_x = row->x;
14450 }
14451 else
14452 CHARPOS (this_line_start_pos) = 0;
14453 }
14454
14455 return 1;
14456 }
14457
14458
14459 /* Run window scroll functions, if any, for WINDOW with new window
14460 start STARTP. Sets the window start of WINDOW to that position.
14461
14462 We assume that the window's buffer is really current. */
14463
14464 static struct text_pos
14465 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14466 {
14467 struct window *w = XWINDOW (window);
14468 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14469
14470 eassert (current_buffer == XBUFFER (w->contents));
14471
14472 if (!NILP (Vwindow_scroll_functions))
14473 {
14474 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14475 make_number (CHARPOS (startp)));
14476 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14477 /* In case the hook functions switch buffers. */
14478 set_buffer_internal (XBUFFER (w->contents));
14479 }
14480
14481 return startp;
14482 }
14483
14484
14485 /* Make sure the line containing the cursor is fully visible.
14486 A value of 1 means there is nothing to be done.
14487 (Either the line is fully visible, or it cannot be made so,
14488 or we cannot tell.)
14489
14490 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14491 is higher than window.
14492
14493 A value of 0 means the caller should do scrolling
14494 as if point had gone off the screen. */
14495
14496 static int
14497 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14498 {
14499 struct glyph_matrix *matrix;
14500 struct glyph_row *row;
14501 int window_height;
14502
14503 if (!make_cursor_line_fully_visible_p)
14504 return 1;
14505
14506 /* It's not always possible to find the cursor, e.g, when a window
14507 is full of overlay strings. Don't do anything in that case. */
14508 if (w->cursor.vpos < 0)
14509 return 1;
14510
14511 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14512 row = MATRIX_ROW (matrix, w->cursor.vpos);
14513
14514 /* If the cursor row is not partially visible, there's nothing to do. */
14515 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14516 return 1;
14517
14518 /* If the row the cursor is in is taller than the window's height,
14519 it's not clear what to do, so do nothing. */
14520 window_height = window_box_height (w);
14521 if (row->height >= window_height)
14522 {
14523 if (!force_p || MINI_WINDOW_P (w)
14524 || w->vscroll || w->cursor.vpos == 0)
14525 return 1;
14526 }
14527 return 0;
14528 }
14529
14530
14531 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14532 non-zero means only WINDOW is redisplayed in redisplay_internal.
14533 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14534 in redisplay_window to bring a partially visible line into view in
14535 the case that only the cursor has moved.
14536
14537 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14538 last screen line's vertical height extends past the end of the screen.
14539
14540 Value is
14541
14542 1 if scrolling succeeded
14543
14544 0 if scrolling didn't find point.
14545
14546 -1 if new fonts have been loaded so that we must interrupt
14547 redisplay, adjust glyph matrices, and try again. */
14548
14549 enum
14550 {
14551 SCROLLING_SUCCESS,
14552 SCROLLING_FAILED,
14553 SCROLLING_NEED_LARGER_MATRICES
14554 };
14555
14556 /* If scroll-conservatively is more than this, never recenter.
14557
14558 If you change this, don't forget to update the doc string of
14559 `scroll-conservatively' and the Emacs manual. */
14560 #define SCROLL_LIMIT 100
14561
14562 static int
14563 try_scrolling (Lisp_Object window, int just_this_one_p,
14564 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14565 int temp_scroll_step, int last_line_misfit)
14566 {
14567 struct window *w = XWINDOW (window);
14568 struct frame *f = XFRAME (w->frame);
14569 struct text_pos pos, startp;
14570 struct it it;
14571 int this_scroll_margin, scroll_max, rc, height;
14572 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14573 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14574 Lisp_Object aggressive;
14575 /* We will never try scrolling more than this number of lines. */
14576 int scroll_limit = SCROLL_LIMIT;
14577 int frame_line_height = default_line_pixel_height (w);
14578 int window_total_lines
14579 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
14580
14581 #ifdef GLYPH_DEBUG
14582 debug_method_add (w, "try_scrolling");
14583 #endif
14584
14585 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14586
14587 /* Compute scroll margin height in pixels. We scroll when point is
14588 within this distance from the top or bottom of the window. */
14589 if (scroll_margin > 0)
14590 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
14591 * frame_line_height;
14592 else
14593 this_scroll_margin = 0;
14594
14595 /* Force arg_scroll_conservatively to have a reasonable value, to
14596 avoid scrolling too far away with slow move_it_* functions. Note
14597 that the user can supply scroll-conservatively equal to
14598 `most-positive-fixnum', which can be larger than INT_MAX. */
14599 if (arg_scroll_conservatively > scroll_limit)
14600 {
14601 arg_scroll_conservatively = scroll_limit + 1;
14602 scroll_max = scroll_limit * frame_line_height;
14603 }
14604 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14605 /* Compute how much we should try to scroll maximally to bring
14606 point into view. */
14607 scroll_max = (max (scroll_step,
14608 max (arg_scroll_conservatively, temp_scroll_step))
14609 * frame_line_height);
14610 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14611 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14612 /* We're trying to scroll because of aggressive scrolling but no
14613 scroll_step is set. Choose an arbitrary one. */
14614 scroll_max = 10 * frame_line_height;
14615 else
14616 scroll_max = 0;
14617
14618 too_near_end:
14619
14620 /* Decide whether to scroll down. */
14621 if (PT > CHARPOS (startp))
14622 {
14623 int scroll_margin_y;
14624
14625 /* Compute the pixel ypos of the scroll margin, then move IT to
14626 either that ypos or PT, whichever comes first. */
14627 start_display (&it, w, startp);
14628 scroll_margin_y = it.last_visible_y - this_scroll_margin
14629 - frame_line_height * extra_scroll_margin_lines;
14630 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14631 (MOVE_TO_POS | MOVE_TO_Y));
14632
14633 if (PT > CHARPOS (it.current.pos))
14634 {
14635 int y0 = line_bottom_y (&it);
14636 /* Compute how many pixels below window bottom to stop searching
14637 for PT. This avoids costly search for PT that is far away if
14638 the user limited scrolling by a small number of lines, but
14639 always finds PT if scroll_conservatively is set to a large
14640 number, such as most-positive-fixnum. */
14641 int slack = max (scroll_max, 10 * frame_line_height);
14642 int y_to_move = it.last_visible_y + slack;
14643
14644 /* Compute the distance from the scroll margin to PT or to
14645 the scroll limit, whichever comes first. This should
14646 include the height of the cursor line, to make that line
14647 fully visible. */
14648 move_it_to (&it, PT, -1, y_to_move,
14649 -1, MOVE_TO_POS | MOVE_TO_Y);
14650 dy = line_bottom_y (&it) - y0;
14651
14652 if (dy > scroll_max)
14653 return SCROLLING_FAILED;
14654
14655 if (dy > 0)
14656 scroll_down_p = 1;
14657 }
14658 }
14659
14660 if (scroll_down_p)
14661 {
14662 /* Point is in or below the bottom scroll margin, so move the
14663 window start down. If scrolling conservatively, move it just
14664 enough down to make point visible. If scroll_step is set,
14665 move it down by scroll_step. */
14666 if (arg_scroll_conservatively)
14667 amount_to_scroll
14668 = min (max (dy, frame_line_height),
14669 frame_line_height * arg_scroll_conservatively);
14670 else if (scroll_step || temp_scroll_step)
14671 amount_to_scroll = scroll_max;
14672 else
14673 {
14674 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14675 height = WINDOW_BOX_TEXT_HEIGHT (w);
14676 if (NUMBERP (aggressive))
14677 {
14678 double float_amount = XFLOATINT (aggressive) * height;
14679 int aggressive_scroll = float_amount;
14680 if (aggressive_scroll == 0 && float_amount > 0)
14681 aggressive_scroll = 1;
14682 /* Don't let point enter the scroll margin near top of
14683 the window. This could happen if the value of
14684 scroll_up_aggressively is too large and there are
14685 non-zero margins, because scroll_up_aggressively
14686 means put point that fraction of window height
14687 _from_the_bottom_margin_. */
14688 if (aggressive_scroll + 2*this_scroll_margin > height)
14689 aggressive_scroll = height - 2*this_scroll_margin;
14690 amount_to_scroll = dy + aggressive_scroll;
14691 }
14692 }
14693
14694 if (amount_to_scroll <= 0)
14695 return SCROLLING_FAILED;
14696
14697 start_display (&it, w, startp);
14698 if (arg_scroll_conservatively <= scroll_limit)
14699 move_it_vertically (&it, amount_to_scroll);
14700 else
14701 {
14702 /* Extra precision for users who set scroll-conservatively
14703 to a large number: make sure the amount we scroll
14704 the window start is never less than amount_to_scroll,
14705 which was computed as distance from window bottom to
14706 point. This matters when lines at window top and lines
14707 below window bottom have different height. */
14708 struct it it1;
14709 void *it1data = NULL;
14710 /* We use a temporary it1 because line_bottom_y can modify
14711 its argument, if it moves one line down; see there. */
14712 int start_y;
14713
14714 SAVE_IT (it1, it, it1data);
14715 start_y = line_bottom_y (&it1);
14716 do {
14717 RESTORE_IT (&it, &it, it1data);
14718 move_it_by_lines (&it, 1);
14719 SAVE_IT (it1, it, it1data);
14720 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14721 }
14722
14723 /* If STARTP is unchanged, move it down another screen line. */
14724 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14725 move_it_by_lines (&it, 1);
14726 startp = it.current.pos;
14727 }
14728 else
14729 {
14730 struct text_pos scroll_margin_pos = startp;
14731 int y_offset = 0;
14732
14733 /* See if point is inside the scroll margin at the top of the
14734 window. */
14735 if (this_scroll_margin)
14736 {
14737 int y_start;
14738
14739 start_display (&it, w, startp);
14740 y_start = it.current_y;
14741 move_it_vertically (&it, this_scroll_margin);
14742 scroll_margin_pos = it.current.pos;
14743 /* If we didn't move enough before hitting ZV, request
14744 additional amount of scroll, to move point out of the
14745 scroll margin. */
14746 if (IT_CHARPOS (it) == ZV
14747 && it.current_y - y_start < this_scroll_margin)
14748 y_offset = this_scroll_margin - (it.current_y - y_start);
14749 }
14750
14751 if (PT < CHARPOS (scroll_margin_pos))
14752 {
14753 /* Point is in the scroll margin at the top of the window or
14754 above what is displayed in the window. */
14755 int y0, y_to_move;
14756
14757 /* Compute the vertical distance from PT to the scroll
14758 margin position. Move as far as scroll_max allows, or
14759 one screenful, or 10 screen lines, whichever is largest.
14760 Give up if distance is greater than scroll_max or if we
14761 didn't reach the scroll margin position. */
14762 SET_TEXT_POS (pos, PT, PT_BYTE);
14763 start_display (&it, w, pos);
14764 y0 = it.current_y;
14765 y_to_move = max (it.last_visible_y,
14766 max (scroll_max, 10 * frame_line_height));
14767 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14768 y_to_move, -1,
14769 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14770 dy = it.current_y - y0;
14771 if (dy > scroll_max
14772 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14773 return SCROLLING_FAILED;
14774
14775 /* Additional scroll for when ZV was too close to point. */
14776 dy += y_offset;
14777
14778 /* Compute new window start. */
14779 start_display (&it, w, startp);
14780
14781 if (arg_scroll_conservatively)
14782 amount_to_scroll = max (dy, frame_line_height *
14783 max (scroll_step, temp_scroll_step));
14784 else if (scroll_step || temp_scroll_step)
14785 amount_to_scroll = scroll_max;
14786 else
14787 {
14788 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14789 height = WINDOW_BOX_TEXT_HEIGHT (w);
14790 if (NUMBERP (aggressive))
14791 {
14792 double float_amount = XFLOATINT (aggressive) * height;
14793 int aggressive_scroll = float_amount;
14794 if (aggressive_scroll == 0 && float_amount > 0)
14795 aggressive_scroll = 1;
14796 /* Don't let point enter the scroll margin near
14797 bottom of the window, if the value of
14798 scroll_down_aggressively happens to be too
14799 large. */
14800 if (aggressive_scroll + 2*this_scroll_margin > height)
14801 aggressive_scroll = height - 2*this_scroll_margin;
14802 amount_to_scroll = dy + aggressive_scroll;
14803 }
14804 }
14805
14806 if (amount_to_scroll <= 0)
14807 return SCROLLING_FAILED;
14808
14809 move_it_vertically_backward (&it, amount_to_scroll);
14810 startp = it.current.pos;
14811 }
14812 }
14813
14814 /* Run window scroll functions. */
14815 startp = run_window_scroll_functions (window, startp);
14816
14817 /* Display the window. Give up if new fonts are loaded, or if point
14818 doesn't appear. */
14819 if (!try_window (window, startp, 0))
14820 rc = SCROLLING_NEED_LARGER_MATRICES;
14821 else if (w->cursor.vpos < 0)
14822 {
14823 clear_glyph_matrix (w->desired_matrix);
14824 rc = SCROLLING_FAILED;
14825 }
14826 else
14827 {
14828 /* Maybe forget recorded base line for line number display. */
14829 if (!just_this_one_p
14830 || current_buffer->clip_changed
14831 || BEG_UNCHANGED < CHARPOS (startp))
14832 w->base_line_number = 0;
14833
14834 /* If cursor ends up on a partially visible line,
14835 treat that as being off the bottom of the screen. */
14836 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14837 /* It's possible that the cursor is on the first line of the
14838 buffer, which is partially obscured due to a vscroll
14839 (Bug#7537). In that case, avoid looping forever . */
14840 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14841 {
14842 clear_glyph_matrix (w->desired_matrix);
14843 ++extra_scroll_margin_lines;
14844 goto too_near_end;
14845 }
14846 rc = SCROLLING_SUCCESS;
14847 }
14848
14849 return rc;
14850 }
14851
14852
14853 /* Compute a suitable window start for window W if display of W starts
14854 on a continuation line. Value is non-zero if a new window start
14855 was computed.
14856
14857 The new window start will be computed, based on W's width, starting
14858 from the start of the continued line. It is the start of the
14859 screen line with the minimum distance from the old start W->start. */
14860
14861 static int
14862 compute_window_start_on_continuation_line (struct window *w)
14863 {
14864 struct text_pos pos, start_pos;
14865 int window_start_changed_p = 0;
14866
14867 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14868
14869 /* If window start is on a continuation line... Window start may be
14870 < BEGV in case there's invisible text at the start of the
14871 buffer (M-x rmail, for example). */
14872 if (CHARPOS (start_pos) > BEGV
14873 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14874 {
14875 struct it it;
14876 struct glyph_row *row;
14877
14878 /* Handle the case that the window start is out of range. */
14879 if (CHARPOS (start_pos) < BEGV)
14880 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14881 else if (CHARPOS (start_pos) > ZV)
14882 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14883
14884 /* Find the start of the continued line. This should be fast
14885 because find_newline is fast (newline cache). */
14886 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14887 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14888 row, DEFAULT_FACE_ID);
14889 reseat_at_previous_visible_line_start (&it);
14890
14891 /* If the line start is "too far" away from the window start,
14892 say it takes too much time to compute a new window start. */
14893 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14894 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14895 {
14896 int min_distance, distance;
14897
14898 /* Move forward by display lines to find the new window
14899 start. If window width was enlarged, the new start can
14900 be expected to be > the old start. If window width was
14901 decreased, the new window start will be < the old start.
14902 So, we're looking for the display line start with the
14903 minimum distance from the old window start. */
14904 pos = it.current.pos;
14905 min_distance = INFINITY;
14906 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14907 distance < min_distance)
14908 {
14909 min_distance = distance;
14910 pos = it.current.pos;
14911 move_it_by_lines (&it, 1);
14912 }
14913
14914 /* Set the window start there. */
14915 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14916 window_start_changed_p = 1;
14917 }
14918 }
14919
14920 return window_start_changed_p;
14921 }
14922
14923
14924 /* Try cursor movement in case text has not changed in window WINDOW,
14925 with window start STARTP. Value is
14926
14927 CURSOR_MOVEMENT_SUCCESS if successful
14928
14929 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14930
14931 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14932 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14933 we want to scroll as if scroll-step were set to 1. See the code.
14934
14935 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14936 which case we have to abort this redisplay, and adjust matrices
14937 first. */
14938
14939 enum
14940 {
14941 CURSOR_MOVEMENT_SUCCESS,
14942 CURSOR_MOVEMENT_CANNOT_BE_USED,
14943 CURSOR_MOVEMENT_MUST_SCROLL,
14944 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14945 };
14946
14947 static int
14948 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14949 {
14950 struct window *w = XWINDOW (window);
14951 struct frame *f = XFRAME (w->frame);
14952 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14953
14954 #ifdef GLYPH_DEBUG
14955 if (inhibit_try_cursor_movement)
14956 return rc;
14957 #endif
14958
14959 /* Previously, there was a check for Lisp integer in the
14960 if-statement below. Now, this field is converted to
14961 ptrdiff_t, thus zero means invalid position in a buffer. */
14962 eassert (w->last_point > 0);
14963
14964 /* Handle case where text has not changed, only point, and it has
14965 not moved off the frame. */
14966 if (/* Point may be in this window. */
14967 PT >= CHARPOS (startp)
14968 /* Selective display hasn't changed. */
14969 && !current_buffer->clip_changed
14970 /* Function force-mode-line-update is used to force a thorough
14971 redisplay. It sets either windows_or_buffers_changed or
14972 update_mode_lines. So don't take a shortcut here for these
14973 cases. */
14974 && !update_mode_lines
14975 && !windows_or_buffers_changed
14976 && !cursor_type_changed
14977 /* Can't use this case if highlighting a region. When a
14978 region exists, cursor movement has to do more than just
14979 set the cursor. */
14980 && markpos_of_region () < 0
14981 && !w->region_showing
14982 && NILP (Vshow_trailing_whitespace)
14983 /* This code is not used for mini-buffer for the sake of the case
14984 of redisplaying to replace an echo area message; since in
14985 that case the mini-buffer contents per se are usually
14986 unchanged. This code is of no real use in the mini-buffer
14987 since the handling of this_line_start_pos, etc., in redisplay
14988 handles the same cases. */
14989 && !EQ (window, minibuf_window)
14990 /* When splitting windows or for new windows, it happens that
14991 redisplay is called with a nil window_end_vpos or one being
14992 larger than the window. This should really be fixed in
14993 window.c. I don't have this on my list, now, so we do
14994 approximately the same as the old redisplay code. --gerd. */
14995 && INTEGERP (w->window_end_vpos)
14996 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14997 && (FRAME_WINDOW_P (f)
14998 || !overlay_arrow_in_current_buffer_p ()))
14999 {
15000 int this_scroll_margin, top_scroll_margin;
15001 struct glyph_row *row = NULL;
15002 int frame_line_height = default_line_pixel_height (w);
15003 int window_total_lines
15004 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15005
15006 #ifdef GLYPH_DEBUG
15007 debug_method_add (w, "cursor movement");
15008 #endif
15009
15010 /* Scroll if point within this distance from the top or bottom
15011 of the window. This is a pixel value. */
15012 if (scroll_margin > 0)
15013 {
15014 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15015 this_scroll_margin *= frame_line_height;
15016 }
15017 else
15018 this_scroll_margin = 0;
15019
15020 top_scroll_margin = this_scroll_margin;
15021 if (WINDOW_WANTS_HEADER_LINE_P (w))
15022 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15023
15024 /* Start with the row the cursor was displayed during the last
15025 not paused redisplay. Give up if that row is not valid. */
15026 if (w->last_cursor.vpos < 0
15027 || w->last_cursor.vpos >= w->current_matrix->nrows)
15028 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15029 else
15030 {
15031 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
15032 if (row->mode_line_p)
15033 ++row;
15034 if (!row->enabled_p)
15035 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15036 }
15037
15038 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15039 {
15040 int scroll_p = 0, must_scroll = 0;
15041 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15042
15043 if (PT > w->last_point)
15044 {
15045 /* Point has moved forward. */
15046 while (MATRIX_ROW_END_CHARPOS (row) < PT
15047 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15048 {
15049 eassert (row->enabled_p);
15050 ++row;
15051 }
15052
15053 /* If the end position of a row equals the start
15054 position of the next row, and PT is at that position,
15055 we would rather display cursor in the next line. */
15056 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15057 && MATRIX_ROW_END_CHARPOS (row) == PT
15058 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15059 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15060 && !cursor_row_p (row))
15061 ++row;
15062
15063 /* If within the scroll margin, scroll. Note that
15064 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15065 the next line would be drawn, and that
15066 this_scroll_margin can be zero. */
15067 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15068 || PT > MATRIX_ROW_END_CHARPOS (row)
15069 /* Line is completely visible last line in window
15070 and PT is to be set in the next line. */
15071 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15072 && PT == MATRIX_ROW_END_CHARPOS (row)
15073 && !row->ends_at_zv_p
15074 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15075 scroll_p = 1;
15076 }
15077 else if (PT < w->last_point)
15078 {
15079 /* Cursor has to be moved backward. Note that PT >=
15080 CHARPOS (startp) because of the outer if-statement. */
15081 while (!row->mode_line_p
15082 && (MATRIX_ROW_START_CHARPOS (row) > PT
15083 || (MATRIX_ROW_START_CHARPOS (row) == PT
15084 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15085 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15086 row > w->current_matrix->rows
15087 && (row-1)->ends_in_newline_from_string_p))))
15088 && (row->y > top_scroll_margin
15089 || CHARPOS (startp) == BEGV))
15090 {
15091 eassert (row->enabled_p);
15092 --row;
15093 }
15094
15095 /* Consider the following case: Window starts at BEGV,
15096 there is invisible, intangible text at BEGV, so that
15097 display starts at some point START > BEGV. It can
15098 happen that we are called with PT somewhere between
15099 BEGV and START. Try to handle that case. */
15100 if (row < w->current_matrix->rows
15101 || row->mode_line_p)
15102 {
15103 row = w->current_matrix->rows;
15104 if (row->mode_line_p)
15105 ++row;
15106 }
15107
15108 /* Due to newlines in overlay strings, we may have to
15109 skip forward over overlay strings. */
15110 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15111 && MATRIX_ROW_END_CHARPOS (row) == PT
15112 && !cursor_row_p (row))
15113 ++row;
15114
15115 /* If within the scroll margin, scroll. */
15116 if (row->y < top_scroll_margin
15117 && CHARPOS (startp) != BEGV)
15118 scroll_p = 1;
15119 }
15120 else
15121 {
15122 /* Cursor did not move. So don't scroll even if cursor line
15123 is partially visible, as it was so before. */
15124 rc = CURSOR_MOVEMENT_SUCCESS;
15125 }
15126
15127 if (PT < MATRIX_ROW_START_CHARPOS (row)
15128 || PT > MATRIX_ROW_END_CHARPOS (row))
15129 {
15130 /* if PT is not in the glyph row, give up. */
15131 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15132 must_scroll = 1;
15133 }
15134 else if (rc != CURSOR_MOVEMENT_SUCCESS
15135 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15136 {
15137 struct glyph_row *row1;
15138
15139 /* If rows are bidi-reordered and point moved, back up
15140 until we find a row that does not belong to a
15141 continuation line. This is because we must consider
15142 all rows of a continued line as candidates for the
15143 new cursor positioning, since row start and end
15144 positions change non-linearly with vertical position
15145 in such rows. */
15146 /* FIXME: Revisit this when glyph ``spilling'' in
15147 continuation lines' rows is implemented for
15148 bidi-reordered rows. */
15149 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15150 MATRIX_ROW_CONTINUATION_LINE_P (row);
15151 --row)
15152 {
15153 /* If we hit the beginning of the displayed portion
15154 without finding the first row of a continued
15155 line, give up. */
15156 if (row <= row1)
15157 {
15158 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15159 break;
15160 }
15161 eassert (row->enabled_p);
15162 }
15163 }
15164 if (must_scroll)
15165 ;
15166 else if (rc != CURSOR_MOVEMENT_SUCCESS
15167 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15168 /* Make sure this isn't a header line by any chance, since
15169 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15170 && !row->mode_line_p
15171 && make_cursor_line_fully_visible_p)
15172 {
15173 if (PT == MATRIX_ROW_END_CHARPOS (row)
15174 && !row->ends_at_zv_p
15175 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15176 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15177 else if (row->height > window_box_height (w))
15178 {
15179 /* If we end up in a partially visible line, let's
15180 make it fully visible, except when it's taller
15181 than the window, in which case we can't do much
15182 about it. */
15183 *scroll_step = 1;
15184 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15185 }
15186 else
15187 {
15188 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15189 if (!cursor_row_fully_visible_p (w, 0, 1))
15190 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15191 else
15192 rc = CURSOR_MOVEMENT_SUCCESS;
15193 }
15194 }
15195 else if (scroll_p)
15196 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15197 else if (rc != CURSOR_MOVEMENT_SUCCESS
15198 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15199 {
15200 /* With bidi-reordered rows, there could be more than
15201 one candidate row whose start and end positions
15202 occlude point. We need to let set_cursor_from_row
15203 find the best candidate. */
15204 /* FIXME: Revisit this when glyph ``spilling'' in
15205 continuation lines' rows is implemented for
15206 bidi-reordered rows. */
15207 int rv = 0;
15208
15209 do
15210 {
15211 int at_zv_p = 0, exact_match_p = 0;
15212
15213 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15214 && PT <= MATRIX_ROW_END_CHARPOS (row)
15215 && cursor_row_p (row))
15216 rv |= set_cursor_from_row (w, row, w->current_matrix,
15217 0, 0, 0, 0);
15218 /* As soon as we've found the exact match for point,
15219 or the first suitable row whose ends_at_zv_p flag
15220 is set, we are done. */
15221 at_zv_p =
15222 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15223 if (rv && !at_zv_p
15224 && w->cursor.hpos >= 0
15225 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15226 w->cursor.vpos))
15227 {
15228 struct glyph_row *candidate =
15229 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15230 struct glyph *g =
15231 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15232 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15233
15234 exact_match_p =
15235 (BUFFERP (g->object) && g->charpos == PT)
15236 || (INTEGERP (g->object)
15237 && (g->charpos == PT
15238 || (g->charpos == 0 && endpos - 1 == PT)));
15239 }
15240 if (rv && (at_zv_p || exact_match_p))
15241 {
15242 rc = CURSOR_MOVEMENT_SUCCESS;
15243 break;
15244 }
15245 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15246 break;
15247 ++row;
15248 }
15249 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15250 || row->continued_p)
15251 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15252 || (MATRIX_ROW_START_CHARPOS (row) == PT
15253 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15254 /* If we didn't find any candidate rows, or exited the
15255 loop before all the candidates were examined, signal
15256 to the caller that this method failed. */
15257 if (rc != CURSOR_MOVEMENT_SUCCESS
15258 && !(rv
15259 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15260 && !row->continued_p))
15261 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15262 else if (rv)
15263 rc = CURSOR_MOVEMENT_SUCCESS;
15264 }
15265 else
15266 {
15267 do
15268 {
15269 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15270 {
15271 rc = CURSOR_MOVEMENT_SUCCESS;
15272 break;
15273 }
15274 ++row;
15275 }
15276 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15277 && MATRIX_ROW_START_CHARPOS (row) == PT
15278 && cursor_row_p (row));
15279 }
15280 }
15281 }
15282
15283 return rc;
15284 }
15285
15286 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15287 static
15288 #endif
15289 void
15290 set_vertical_scroll_bar (struct window *w)
15291 {
15292 ptrdiff_t start, end, whole;
15293
15294 /* Calculate the start and end positions for the current window.
15295 At some point, it would be nice to choose between scrollbars
15296 which reflect the whole buffer size, with special markers
15297 indicating narrowing, and scrollbars which reflect only the
15298 visible region.
15299
15300 Note that mini-buffers sometimes aren't displaying any text. */
15301 if (!MINI_WINDOW_P (w)
15302 || (w == XWINDOW (minibuf_window)
15303 && NILP (echo_area_buffer[0])))
15304 {
15305 struct buffer *buf = XBUFFER (w->contents);
15306 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15307 start = marker_position (w->start) - BUF_BEGV (buf);
15308 /* I don't think this is guaranteed to be right. For the
15309 moment, we'll pretend it is. */
15310 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
15311
15312 if (end < start)
15313 end = start;
15314 if (whole < (end - start))
15315 whole = end - start;
15316 }
15317 else
15318 start = end = whole = 0;
15319
15320 /* Indicate what this scroll bar ought to be displaying now. */
15321 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15322 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15323 (w, end - start, whole, start);
15324 }
15325
15326
15327 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15328 selected_window is redisplayed.
15329
15330 We can return without actually redisplaying the window if
15331 fonts_changed_p. In that case, redisplay_internal will
15332 retry. */
15333
15334 static void
15335 redisplay_window (Lisp_Object window, int just_this_one_p)
15336 {
15337 struct window *w = XWINDOW (window);
15338 struct frame *f = XFRAME (w->frame);
15339 struct buffer *buffer = XBUFFER (w->contents);
15340 struct buffer *old = current_buffer;
15341 struct text_pos lpoint, opoint, startp;
15342 int update_mode_line;
15343 int tem;
15344 struct it it;
15345 /* Record it now because it's overwritten. */
15346 int current_matrix_up_to_date_p = 0;
15347 int used_current_matrix_p = 0;
15348 /* This is less strict than current_matrix_up_to_date_p.
15349 It indicates that the buffer contents and narrowing are unchanged. */
15350 int buffer_unchanged_p = 0;
15351 int temp_scroll_step = 0;
15352 ptrdiff_t count = SPECPDL_INDEX ();
15353 int rc;
15354 int centering_position = -1;
15355 int last_line_misfit = 0;
15356 ptrdiff_t beg_unchanged, end_unchanged;
15357 int frame_line_height;
15358
15359 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15360 opoint = lpoint;
15361
15362 #ifdef GLYPH_DEBUG
15363 *w->desired_matrix->method = 0;
15364 #endif
15365
15366 /* Make sure that both W's markers are valid. */
15367 eassert (XMARKER (w->start)->buffer == buffer);
15368 eassert (XMARKER (w->pointm)->buffer == buffer);
15369
15370 restart:
15371 reconsider_clip_changes (w);
15372 frame_line_height = default_line_pixel_height (w);
15373
15374 /* Has the mode line to be updated? */
15375 update_mode_line = (w->update_mode_line
15376 || update_mode_lines
15377 || buffer->clip_changed
15378 || buffer->prevent_redisplay_optimizations_p);
15379
15380 if (MINI_WINDOW_P (w))
15381 {
15382 if (w == XWINDOW (echo_area_window)
15383 && !NILP (echo_area_buffer[0]))
15384 {
15385 if (update_mode_line)
15386 /* We may have to update a tty frame's menu bar or a
15387 tool-bar. Example `M-x C-h C-h C-g'. */
15388 goto finish_menu_bars;
15389 else
15390 /* We've already displayed the echo area glyphs in this window. */
15391 goto finish_scroll_bars;
15392 }
15393 else if ((w != XWINDOW (minibuf_window)
15394 || minibuf_level == 0)
15395 /* When buffer is nonempty, redisplay window normally. */
15396 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15397 /* Quail displays non-mini buffers in minibuffer window.
15398 In that case, redisplay the window normally. */
15399 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15400 {
15401 /* W is a mini-buffer window, but it's not active, so clear
15402 it. */
15403 int yb = window_text_bottom_y (w);
15404 struct glyph_row *row;
15405 int y;
15406
15407 for (y = 0, row = w->desired_matrix->rows;
15408 y < yb;
15409 y += row->height, ++row)
15410 blank_row (w, row, y);
15411 goto finish_scroll_bars;
15412 }
15413
15414 clear_glyph_matrix (w->desired_matrix);
15415 }
15416
15417 /* Otherwise set up data on this window; select its buffer and point
15418 value. */
15419 /* Really select the buffer, for the sake of buffer-local
15420 variables. */
15421 set_buffer_internal_1 (XBUFFER (w->contents));
15422
15423 current_matrix_up_to_date_p
15424 = (w->window_end_valid
15425 && !current_buffer->clip_changed
15426 && !current_buffer->prevent_redisplay_optimizations_p
15427 && !window_outdated (w));
15428
15429 /* Run the window-bottom-change-functions
15430 if it is possible that the text on the screen has changed
15431 (either due to modification of the text, or any other reason). */
15432 if (!current_matrix_up_to_date_p
15433 && !NILP (Vwindow_text_change_functions))
15434 {
15435 safe_run_hooks (Qwindow_text_change_functions);
15436 goto restart;
15437 }
15438
15439 beg_unchanged = BEG_UNCHANGED;
15440 end_unchanged = END_UNCHANGED;
15441
15442 SET_TEXT_POS (opoint, PT, PT_BYTE);
15443
15444 specbind (Qinhibit_point_motion_hooks, Qt);
15445
15446 buffer_unchanged_p
15447 = (w->window_end_valid
15448 && !current_buffer->clip_changed
15449 && !window_outdated (w));
15450
15451 /* When windows_or_buffers_changed is non-zero, we can't rely on
15452 the window end being valid, so set it to nil there. */
15453 if (windows_or_buffers_changed)
15454 {
15455 /* If window starts on a continuation line, maybe adjust the
15456 window start in case the window's width changed. */
15457 if (XMARKER (w->start)->buffer == current_buffer)
15458 compute_window_start_on_continuation_line (w);
15459
15460 w->window_end_valid = 0;
15461 }
15462
15463 /* Some sanity checks. */
15464 CHECK_WINDOW_END (w);
15465 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15466 emacs_abort ();
15467 if (BYTEPOS (opoint) < CHARPOS (opoint))
15468 emacs_abort ();
15469
15470 if (mode_line_update_needed (w))
15471 update_mode_line = 1;
15472
15473 /* Point refers normally to the selected window. For any other
15474 window, set up appropriate value. */
15475 if (!EQ (window, selected_window))
15476 {
15477 ptrdiff_t new_pt = marker_position (w->pointm);
15478 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15479 if (new_pt < BEGV)
15480 {
15481 new_pt = BEGV;
15482 new_pt_byte = BEGV_BYTE;
15483 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15484 }
15485 else if (new_pt > (ZV - 1))
15486 {
15487 new_pt = ZV;
15488 new_pt_byte = ZV_BYTE;
15489 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15490 }
15491
15492 /* We don't use SET_PT so that the point-motion hooks don't run. */
15493 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15494 }
15495
15496 /* If any of the character widths specified in the display table
15497 have changed, invalidate the width run cache. It's true that
15498 this may be a bit late to catch such changes, but the rest of
15499 redisplay goes (non-fatally) haywire when the display table is
15500 changed, so why should we worry about doing any better? */
15501 if (current_buffer->width_run_cache)
15502 {
15503 struct Lisp_Char_Table *disptab = buffer_display_table ();
15504
15505 if (! disptab_matches_widthtab
15506 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15507 {
15508 invalidate_region_cache (current_buffer,
15509 current_buffer->width_run_cache,
15510 BEG, Z);
15511 recompute_width_table (current_buffer, disptab);
15512 }
15513 }
15514
15515 /* If window-start is screwed up, choose a new one. */
15516 if (XMARKER (w->start)->buffer != current_buffer)
15517 goto recenter;
15518
15519 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15520
15521 /* If someone specified a new starting point but did not insist,
15522 check whether it can be used. */
15523 if (w->optional_new_start
15524 && CHARPOS (startp) >= BEGV
15525 && CHARPOS (startp) <= ZV)
15526 {
15527 w->optional_new_start = 0;
15528 start_display (&it, w, startp);
15529 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15530 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15531 if (IT_CHARPOS (it) == PT)
15532 w->force_start = 1;
15533 /* IT may overshoot PT if text at PT is invisible. */
15534 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15535 w->force_start = 1;
15536 }
15537
15538 force_start:
15539
15540 /* Handle case where place to start displaying has been specified,
15541 unless the specified location is outside the accessible range. */
15542 if (w->force_start || window_frozen_p (w))
15543 {
15544 /* We set this later on if we have to adjust point. */
15545 int new_vpos = -1;
15546
15547 w->force_start = 0;
15548 w->vscroll = 0;
15549 w->window_end_valid = 0;
15550
15551 /* Forget any recorded base line for line number display. */
15552 if (!buffer_unchanged_p)
15553 w->base_line_number = 0;
15554
15555 /* Redisplay the mode line. Select the buffer properly for that.
15556 Also, run the hook window-scroll-functions
15557 because we have scrolled. */
15558 /* Note, we do this after clearing force_start because
15559 if there's an error, it is better to forget about force_start
15560 than to get into an infinite loop calling the hook functions
15561 and having them get more errors. */
15562 if (!update_mode_line
15563 || ! NILP (Vwindow_scroll_functions))
15564 {
15565 update_mode_line = 1;
15566 w->update_mode_line = 1;
15567 startp = run_window_scroll_functions (window, startp);
15568 }
15569
15570 if (CHARPOS (startp) < BEGV)
15571 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15572 else if (CHARPOS (startp) > ZV)
15573 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15574
15575 /* Redisplay, then check if cursor has been set during the
15576 redisplay. Give up if new fonts were loaded. */
15577 /* We used to issue a CHECK_MARGINS argument to try_window here,
15578 but this causes scrolling to fail when point begins inside
15579 the scroll margin (bug#148) -- cyd */
15580 if (!try_window (window, startp, 0))
15581 {
15582 w->force_start = 1;
15583 clear_glyph_matrix (w->desired_matrix);
15584 goto need_larger_matrices;
15585 }
15586
15587 if (w->cursor.vpos < 0 && !window_frozen_p (w))
15588 {
15589 /* If point does not appear, try to move point so it does
15590 appear. The desired matrix has been built above, so we
15591 can use it here. */
15592 new_vpos = window_box_height (w) / 2;
15593 }
15594
15595 if (!cursor_row_fully_visible_p (w, 0, 0))
15596 {
15597 /* Point does appear, but on a line partly visible at end of window.
15598 Move it back to a fully-visible line. */
15599 new_vpos = window_box_height (w);
15600 }
15601 else if (w->cursor.vpos >=0)
15602 {
15603 /* Some people insist on not letting point enter the scroll
15604 margin, even though this part handles windows that didn't
15605 scroll at all. */
15606 int window_total_lines
15607 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15608 int margin = min (scroll_margin, window_total_lines / 4);
15609 int pixel_margin = margin * frame_line_height;
15610 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15611
15612 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15613 below, which finds the row to move point to, advances by
15614 the Y coordinate of the _next_ row, see the definition of
15615 MATRIX_ROW_BOTTOM_Y. */
15616 if (w->cursor.vpos < margin + header_line)
15617 {
15618 w->cursor.vpos = -1;
15619 clear_glyph_matrix (w->desired_matrix);
15620 goto try_to_scroll;
15621 }
15622 else
15623 {
15624 int window_height = window_box_height (w);
15625
15626 if (header_line)
15627 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15628 if (w->cursor.y >= window_height - pixel_margin)
15629 {
15630 w->cursor.vpos = -1;
15631 clear_glyph_matrix (w->desired_matrix);
15632 goto try_to_scroll;
15633 }
15634 }
15635 }
15636
15637 /* If we need to move point for either of the above reasons,
15638 now actually do it. */
15639 if (new_vpos >= 0)
15640 {
15641 struct glyph_row *row;
15642
15643 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15644 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15645 ++row;
15646
15647 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15648 MATRIX_ROW_START_BYTEPOS (row));
15649
15650 if (w != XWINDOW (selected_window))
15651 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15652 else if (current_buffer == old)
15653 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15654
15655 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15656
15657 /* If we are highlighting the region, then we just changed
15658 the region, so redisplay to show it. */
15659 if (markpos_of_region () >= 0)
15660 {
15661 clear_glyph_matrix (w->desired_matrix);
15662 if (!try_window (window, startp, 0))
15663 goto need_larger_matrices;
15664 }
15665 }
15666
15667 #ifdef GLYPH_DEBUG
15668 debug_method_add (w, "forced window start");
15669 #endif
15670 goto done;
15671 }
15672
15673 /* Handle case where text has not changed, only point, and it has
15674 not moved off the frame, and we are not retrying after hscroll.
15675 (current_matrix_up_to_date_p is nonzero when retrying.) */
15676 if (current_matrix_up_to_date_p
15677 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15678 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15679 {
15680 switch (rc)
15681 {
15682 case CURSOR_MOVEMENT_SUCCESS:
15683 used_current_matrix_p = 1;
15684 goto done;
15685
15686 case CURSOR_MOVEMENT_MUST_SCROLL:
15687 goto try_to_scroll;
15688
15689 default:
15690 emacs_abort ();
15691 }
15692 }
15693 /* If current starting point was originally the beginning of a line
15694 but no longer is, find a new starting point. */
15695 else if (w->start_at_line_beg
15696 && !(CHARPOS (startp) <= BEGV
15697 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15698 {
15699 #ifdef GLYPH_DEBUG
15700 debug_method_add (w, "recenter 1");
15701 #endif
15702 goto recenter;
15703 }
15704
15705 /* Try scrolling with try_window_id. Value is > 0 if update has
15706 been done, it is -1 if we know that the same window start will
15707 not work. It is 0 if unsuccessful for some other reason. */
15708 else if ((tem = try_window_id (w)) != 0)
15709 {
15710 #ifdef GLYPH_DEBUG
15711 debug_method_add (w, "try_window_id %d", tem);
15712 #endif
15713
15714 if (fonts_changed_p)
15715 goto need_larger_matrices;
15716 if (tem > 0)
15717 goto done;
15718
15719 /* Otherwise try_window_id has returned -1 which means that we
15720 don't want the alternative below this comment to execute. */
15721 }
15722 else if (CHARPOS (startp) >= BEGV
15723 && CHARPOS (startp) <= ZV
15724 && PT >= CHARPOS (startp)
15725 && (CHARPOS (startp) < ZV
15726 /* Avoid starting at end of buffer. */
15727 || CHARPOS (startp) == BEGV
15728 || !window_outdated (w)))
15729 {
15730 int d1, d2, d3, d4, d5, d6;
15731
15732 /* If first window line is a continuation line, and window start
15733 is inside the modified region, but the first change is before
15734 current window start, we must select a new window start.
15735
15736 However, if this is the result of a down-mouse event (e.g. by
15737 extending the mouse-drag-overlay), we don't want to select a
15738 new window start, since that would change the position under
15739 the mouse, resulting in an unwanted mouse-movement rather
15740 than a simple mouse-click. */
15741 if (!w->start_at_line_beg
15742 && NILP (do_mouse_tracking)
15743 && CHARPOS (startp) > BEGV
15744 && CHARPOS (startp) > BEG + beg_unchanged
15745 && CHARPOS (startp) <= Z - end_unchanged
15746 /* Even if w->start_at_line_beg is nil, a new window may
15747 start at a line_beg, since that's how set_buffer_window
15748 sets it. So, we need to check the return value of
15749 compute_window_start_on_continuation_line. (See also
15750 bug#197). */
15751 && XMARKER (w->start)->buffer == current_buffer
15752 && compute_window_start_on_continuation_line (w)
15753 /* It doesn't make sense to force the window start like we
15754 do at label force_start if it is already known that point
15755 will not be visible in the resulting window, because
15756 doing so will move point from its correct position
15757 instead of scrolling the window to bring point into view.
15758 See bug#9324. */
15759 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15760 {
15761 w->force_start = 1;
15762 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15763 goto force_start;
15764 }
15765
15766 #ifdef GLYPH_DEBUG
15767 debug_method_add (w, "same window start");
15768 #endif
15769
15770 /* Try to redisplay starting at same place as before.
15771 If point has not moved off frame, accept the results. */
15772 if (!current_matrix_up_to_date_p
15773 /* Don't use try_window_reusing_current_matrix in this case
15774 because a window scroll function can have changed the
15775 buffer. */
15776 || !NILP (Vwindow_scroll_functions)
15777 || MINI_WINDOW_P (w)
15778 || !(used_current_matrix_p
15779 = try_window_reusing_current_matrix (w)))
15780 {
15781 IF_DEBUG (debug_method_add (w, "1"));
15782 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15783 /* -1 means we need to scroll.
15784 0 means we need new matrices, but fonts_changed_p
15785 is set in that case, so we will detect it below. */
15786 goto try_to_scroll;
15787 }
15788
15789 if (fonts_changed_p)
15790 goto need_larger_matrices;
15791
15792 if (w->cursor.vpos >= 0)
15793 {
15794 if (!just_this_one_p
15795 || current_buffer->clip_changed
15796 || BEG_UNCHANGED < CHARPOS (startp))
15797 /* Forget any recorded base line for line number display. */
15798 w->base_line_number = 0;
15799
15800 if (!cursor_row_fully_visible_p (w, 1, 0))
15801 {
15802 clear_glyph_matrix (w->desired_matrix);
15803 last_line_misfit = 1;
15804 }
15805 /* Drop through and scroll. */
15806 else
15807 goto done;
15808 }
15809 else
15810 clear_glyph_matrix (w->desired_matrix);
15811 }
15812
15813 try_to_scroll:
15814
15815 /* Redisplay the mode line. Select the buffer properly for that. */
15816 if (!update_mode_line)
15817 {
15818 update_mode_line = 1;
15819 w->update_mode_line = 1;
15820 }
15821
15822 /* Try to scroll by specified few lines. */
15823 if ((scroll_conservatively
15824 || emacs_scroll_step
15825 || temp_scroll_step
15826 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15827 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15828 && CHARPOS (startp) >= BEGV
15829 && CHARPOS (startp) <= ZV)
15830 {
15831 /* The function returns -1 if new fonts were loaded, 1 if
15832 successful, 0 if not successful. */
15833 int ss = try_scrolling (window, just_this_one_p,
15834 scroll_conservatively,
15835 emacs_scroll_step,
15836 temp_scroll_step, last_line_misfit);
15837 switch (ss)
15838 {
15839 case SCROLLING_SUCCESS:
15840 goto done;
15841
15842 case SCROLLING_NEED_LARGER_MATRICES:
15843 goto need_larger_matrices;
15844
15845 case SCROLLING_FAILED:
15846 break;
15847
15848 default:
15849 emacs_abort ();
15850 }
15851 }
15852
15853 /* Finally, just choose a place to start which positions point
15854 according to user preferences. */
15855
15856 recenter:
15857
15858 #ifdef GLYPH_DEBUG
15859 debug_method_add (w, "recenter");
15860 #endif
15861
15862 /* Forget any previously recorded base line for line number display. */
15863 if (!buffer_unchanged_p)
15864 w->base_line_number = 0;
15865
15866 /* Determine the window start relative to point. */
15867 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15868 it.current_y = it.last_visible_y;
15869 if (centering_position < 0)
15870 {
15871 int window_total_lines
15872 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15873 int margin =
15874 scroll_margin > 0
15875 ? min (scroll_margin, window_total_lines / 4)
15876 : 0;
15877 ptrdiff_t margin_pos = CHARPOS (startp);
15878 Lisp_Object aggressive;
15879 int scrolling_up;
15880
15881 /* If there is a scroll margin at the top of the window, find
15882 its character position. */
15883 if (margin
15884 /* Cannot call start_display if startp is not in the
15885 accessible region of the buffer. This can happen when we
15886 have just switched to a different buffer and/or changed
15887 its restriction. In that case, startp is initialized to
15888 the character position 1 (BEGV) because we did not yet
15889 have chance to display the buffer even once. */
15890 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15891 {
15892 struct it it1;
15893 void *it1data = NULL;
15894
15895 SAVE_IT (it1, it, it1data);
15896 start_display (&it1, w, startp);
15897 move_it_vertically (&it1, margin * frame_line_height);
15898 margin_pos = IT_CHARPOS (it1);
15899 RESTORE_IT (&it, &it, it1data);
15900 }
15901 scrolling_up = PT > margin_pos;
15902 aggressive =
15903 scrolling_up
15904 ? BVAR (current_buffer, scroll_up_aggressively)
15905 : BVAR (current_buffer, scroll_down_aggressively);
15906
15907 if (!MINI_WINDOW_P (w)
15908 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15909 {
15910 int pt_offset = 0;
15911
15912 /* Setting scroll-conservatively overrides
15913 scroll-*-aggressively. */
15914 if (!scroll_conservatively && NUMBERP (aggressive))
15915 {
15916 double float_amount = XFLOATINT (aggressive);
15917
15918 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15919 if (pt_offset == 0 && float_amount > 0)
15920 pt_offset = 1;
15921 if (pt_offset && margin > 0)
15922 margin -= 1;
15923 }
15924 /* Compute how much to move the window start backward from
15925 point so that point will be displayed where the user
15926 wants it. */
15927 if (scrolling_up)
15928 {
15929 centering_position = it.last_visible_y;
15930 if (pt_offset)
15931 centering_position -= pt_offset;
15932 centering_position -=
15933 frame_line_height * (1 + margin + (last_line_misfit != 0))
15934 + WINDOW_HEADER_LINE_HEIGHT (w);
15935 /* Don't let point enter the scroll margin near top of
15936 the window. */
15937 if (centering_position < margin * frame_line_height)
15938 centering_position = margin * frame_line_height;
15939 }
15940 else
15941 centering_position = margin * frame_line_height + pt_offset;
15942 }
15943 else
15944 /* Set the window start half the height of the window backward
15945 from point. */
15946 centering_position = window_box_height (w) / 2;
15947 }
15948 move_it_vertically_backward (&it, centering_position);
15949
15950 eassert (IT_CHARPOS (it) >= BEGV);
15951
15952 /* The function move_it_vertically_backward may move over more
15953 than the specified y-distance. If it->w is small, e.g. a
15954 mini-buffer window, we may end up in front of the window's
15955 display area. Start displaying at the start of the line
15956 containing PT in this case. */
15957 if (it.current_y <= 0)
15958 {
15959 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15960 move_it_vertically_backward (&it, 0);
15961 it.current_y = 0;
15962 }
15963
15964 it.current_x = it.hpos = 0;
15965
15966 /* Set the window start position here explicitly, to avoid an
15967 infinite loop in case the functions in window-scroll-functions
15968 get errors. */
15969 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15970
15971 /* Run scroll hooks. */
15972 startp = run_window_scroll_functions (window, it.current.pos);
15973
15974 /* Redisplay the window. */
15975 if (!current_matrix_up_to_date_p
15976 || windows_or_buffers_changed
15977 || cursor_type_changed
15978 /* Don't use try_window_reusing_current_matrix in this case
15979 because it can have changed the buffer. */
15980 || !NILP (Vwindow_scroll_functions)
15981 || !just_this_one_p
15982 || MINI_WINDOW_P (w)
15983 || !(used_current_matrix_p
15984 = try_window_reusing_current_matrix (w)))
15985 try_window (window, startp, 0);
15986
15987 /* If new fonts have been loaded (due to fontsets), give up. We
15988 have to start a new redisplay since we need to re-adjust glyph
15989 matrices. */
15990 if (fonts_changed_p)
15991 goto need_larger_matrices;
15992
15993 /* If cursor did not appear assume that the middle of the window is
15994 in the first line of the window. Do it again with the next line.
15995 (Imagine a window of height 100, displaying two lines of height
15996 60. Moving back 50 from it->last_visible_y will end in the first
15997 line.) */
15998 if (w->cursor.vpos < 0)
15999 {
16000 if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos))
16001 {
16002 clear_glyph_matrix (w->desired_matrix);
16003 move_it_by_lines (&it, 1);
16004 try_window (window, it.current.pos, 0);
16005 }
16006 else if (PT < IT_CHARPOS (it))
16007 {
16008 clear_glyph_matrix (w->desired_matrix);
16009 move_it_by_lines (&it, -1);
16010 try_window (window, it.current.pos, 0);
16011 }
16012 else
16013 {
16014 /* Not much we can do about it. */
16015 }
16016 }
16017
16018 /* Consider the following case: Window starts at BEGV, there is
16019 invisible, intangible text at BEGV, so that display starts at
16020 some point START > BEGV. It can happen that we are called with
16021 PT somewhere between BEGV and START. Try to handle that case. */
16022 if (w->cursor.vpos < 0)
16023 {
16024 struct glyph_row *row = w->current_matrix->rows;
16025 if (row->mode_line_p)
16026 ++row;
16027 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16028 }
16029
16030 if (!cursor_row_fully_visible_p (w, 0, 0))
16031 {
16032 /* If vscroll is enabled, disable it and try again. */
16033 if (w->vscroll)
16034 {
16035 w->vscroll = 0;
16036 clear_glyph_matrix (w->desired_matrix);
16037 goto recenter;
16038 }
16039
16040 /* Users who set scroll-conservatively to a large number want
16041 point just above/below the scroll margin. If we ended up
16042 with point's row partially visible, move the window start to
16043 make that row fully visible and out of the margin. */
16044 if (scroll_conservatively > SCROLL_LIMIT)
16045 {
16046 int window_total_lines
16047 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16048 int margin =
16049 scroll_margin > 0
16050 ? min (scroll_margin, window_total_lines / 4)
16051 : 0;
16052 int move_down = w->cursor.vpos >= window_total_lines / 2;
16053
16054 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16055 clear_glyph_matrix (w->desired_matrix);
16056 if (1 == try_window (window, it.current.pos,
16057 TRY_WINDOW_CHECK_MARGINS))
16058 goto done;
16059 }
16060
16061 /* If centering point failed to make the whole line visible,
16062 put point at the top instead. That has to make the whole line
16063 visible, if it can be done. */
16064 if (centering_position == 0)
16065 goto done;
16066
16067 clear_glyph_matrix (w->desired_matrix);
16068 centering_position = 0;
16069 goto recenter;
16070 }
16071
16072 done:
16073
16074 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16075 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16076 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16077
16078 /* Display the mode line, if we must. */
16079 if ((update_mode_line
16080 /* If window not full width, must redo its mode line
16081 if (a) the window to its side is being redone and
16082 (b) we do a frame-based redisplay. This is a consequence
16083 of how inverted lines are drawn in frame-based redisplay. */
16084 || (!just_this_one_p
16085 && !FRAME_WINDOW_P (f)
16086 && !WINDOW_FULL_WIDTH_P (w))
16087 /* Line number to display. */
16088 || w->base_line_pos > 0
16089 /* Column number is displayed and different from the one displayed. */
16090 || (w->column_number_displayed != -1
16091 && (w->column_number_displayed != current_column ())))
16092 /* This means that the window has a mode line. */
16093 && (WINDOW_WANTS_MODELINE_P (w)
16094 || WINDOW_WANTS_HEADER_LINE_P (w)))
16095 {
16096 display_mode_lines (w);
16097
16098 /* If mode line height has changed, arrange for a thorough
16099 immediate redisplay using the correct mode line height. */
16100 if (WINDOW_WANTS_MODELINE_P (w)
16101 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16102 {
16103 fonts_changed_p = 1;
16104 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16105 = DESIRED_MODE_LINE_HEIGHT (w);
16106 }
16107
16108 /* If header line height has changed, arrange for a thorough
16109 immediate redisplay using the correct header line height. */
16110 if (WINDOW_WANTS_HEADER_LINE_P (w)
16111 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16112 {
16113 fonts_changed_p = 1;
16114 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16115 = DESIRED_HEADER_LINE_HEIGHT (w);
16116 }
16117
16118 if (fonts_changed_p)
16119 goto need_larger_matrices;
16120 }
16121
16122 if (!line_number_displayed && w->base_line_pos != -1)
16123 {
16124 w->base_line_pos = 0;
16125 w->base_line_number = 0;
16126 }
16127
16128 finish_menu_bars:
16129
16130 /* When we reach a frame's selected window, redo the frame's menu bar. */
16131 if (update_mode_line
16132 && EQ (FRAME_SELECTED_WINDOW (f), window))
16133 {
16134 int redisplay_menu_p = 0;
16135
16136 if (FRAME_WINDOW_P (f))
16137 {
16138 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16139 || defined (HAVE_NS) || defined (USE_GTK)
16140 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16141 #else
16142 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16143 #endif
16144 }
16145 else
16146 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16147
16148 if (redisplay_menu_p)
16149 display_menu_bar (w);
16150
16151 #ifdef HAVE_WINDOW_SYSTEM
16152 if (FRAME_WINDOW_P (f))
16153 {
16154 #if defined (USE_GTK) || defined (HAVE_NS)
16155 if (FRAME_EXTERNAL_TOOL_BAR (f))
16156 redisplay_tool_bar (f);
16157 #else
16158 if (WINDOWP (f->tool_bar_window)
16159 && (FRAME_TOOL_BAR_LINES (f) > 0
16160 || !NILP (Vauto_resize_tool_bars))
16161 && redisplay_tool_bar (f))
16162 ignore_mouse_drag_p = 1;
16163 #endif
16164 }
16165 #endif
16166 }
16167
16168 #ifdef HAVE_WINDOW_SYSTEM
16169 if (FRAME_WINDOW_P (f)
16170 && update_window_fringes (w, (just_this_one_p
16171 || (!used_current_matrix_p && !overlay_arrow_seen)
16172 || w->pseudo_window_p)))
16173 {
16174 update_begin (f);
16175 block_input ();
16176 if (draw_window_fringes (w, 1))
16177 x_draw_vertical_border (w);
16178 unblock_input ();
16179 update_end (f);
16180 }
16181 #endif /* HAVE_WINDOW_SYSTEM */
16182
16183 /* We go to this label, with fonts_changed_p set,
16184 if it is necessary to try again using larger glyph matrices.
16185 We have to redeem the scroll bar even in this case,
16186 because the loop in redisplay_internal expects that. */
16187 need_larger_matrices:
16188 ;
16189 finish_scroll_bars:
16190
16191 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16192 {
16193 /* Set the thumb's position and size. */
16194 set_vertical_scroll_bar (w);
16195
16196 /* Note that we actually used the scroll bar attached to this
16197 window, so it shouldn't be deleted at the end of redisplay. */
16198 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16199 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16200 }
16201
16202 /* Restore current_buffer and value of point in it. The window
16203 update may have changed the buffer, so first make sure `opoint'
16204 is still valid (Bug#6177). */
16205 if (CHARPOS (opoint) < BEGV)
16206 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16207 else if (CHARPOS (opoint) > ZV)
16208 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16209 else
16210 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16211
16212 set_buffer_internal_1 (old);
16213 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16214 shorter. This can be caused by log truncation in *Messages*. */
16215 if (CHARPOS (lpoint) <= ZV)
16216 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16217
16218 unbind_to (count, Qnil);
16219 }
16220
16221
16222 /* Build the complete desired matrix of WINDOW with a window start
16223 buffer position POS.
16224
16225 Value is 1 if successful. It is zero if fonts were loaded during
16226 redisplay which makes re-adjusting glyph matrices necessary, and -1
16227 if point would appear in the scroll margins.
16228 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16229 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16230 set in FLAGS.) */
16231
16232 int
16233 try_window (Lisp_Object window, struct text_pos pos, int flags)
16234 {
16235 struct window *w = XWINDOW (window);
16236 struct it it;
16237 struct glyph_row *last_text_row = NULL;
16238 struct frame *f = XFRAME (w->frame);
16239 int frame_line_height = default_line_pixel_height (w);
16240
16241 /* Make POS the new window start. */
16242 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16243
16244 /* Mark cursor position as unknown. No overlay arrow seen. */
16245 w->cursor.vpos = -1;
16246 overlay_arrow_seen = 0;
16247
16248 /* Initialize iterator and info to start at POS. */
16249 start_display (&it, w, pos);
16250
16251 /* Display all lines of W. */
16252 while (it.current_y < it.last_visible_y)
16253 {
16254 if (display_line (&it))
16255 last_text_row = it.glyph_row - 1;
16256 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16257 return 0;
16258 }
16259
16260 /* Don't let the cursor end in the scroll margins. */
16261 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16262 && !MINI_WINDOW_P (w))
16263 {
16264 int this_scroll_margin;
16265 int window_total_lines
16266 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16267
16268 if (scroll_margin > 0)
16269 {
16270 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16271 this_scroll_margin *= frame_line_height;
16272 }
16273 else
16274 this_scroll_margin = 0;
16275
16276 if ((w->cursor.y >= 0 /* not vscrolled */
16277 && w->cursor.y < this_scroll_margin
16278 && CHARPOS (pos) > BEGV
16279 && IT_CHARPOS (it) < ZV)
16280 /* rms: considering make_cursor_line_fully_visible_p here
16281 seems to give wrong results. We don't want to recenter
16282 when the last line is partly visible, we want to allow
16283 that case to be handled in the usual way. */
16284 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16285 {
16286 w->cursor.vpos = -1;
16287 clear_glyph_matrix (w->desired_matrix);
16288 return -1;
16289 }
16290 }
16291
16292 /* If bottom moved off end of frame, change mode line percentage. */
16293 if (XFASTINT (w->window_end_pos) <= 0
16294 && Z != IT_CHARPOS (it))
16295 w->update_mode_line = 1;
16296
16297 /* Set window_end_pos to the offset of the last character displayed
16298 on the window from the end of current_buffer. Set
16299 window_end_vpos to its row number. */
16300 if (last_text_row)
16301 {
16302 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16303 w->window_end_bytepos
16304 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16305 wset_window_end_pos
16306 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16307 wset_window_end_vpos
16308 (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
16309 eassert
16310 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16311 XFASTINT (w->window_end_vpos))));
16312 }
16313 else
16314 {
16315 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16316 wset_window_end_pos (w, make_number (Z - ZV));
16317 wset_window_end_vpos (w, make_number (0));
16318 }
16319
16320 /* But that is not valid info until redisplay finishes. */
16321 w->window_end_valid = 0;
16322 return 1;
16323 }
16324
16325
16326 \f
16327 /************************************************************************
16328 Window redisplay reusing current matrix when buffer has not changed
16329 ************************************************************************/
16330
16331 /* Try redisplay of window W showing an unchanged buffer with a
16332 different window start than the last time it was displayed by
16333 reusing its current matrix. Value is non-zero if successful.
16334 W->start is the new window start. */
16335
16336 static int
16337 try_window_reusing_current_matrix (struct window *w)
16338 {
16339 struct frame *f = XFRAME (w->frame);
16340 struct glyph_row *bottom_row;
16341 struct it it;
16342 struct run run;
16343 struct text_pos start, new_start;
16344 int nrows_scrolled, i;
16345 struct glyph_row *last_text_row;
16346 struct glyph_row *last_reused_text_row;
16347 struct glyph_row *start_row;
16348 int start_vpos, min_y, max_y;
16349
16350 #ifdef GLYPH_DEBUG
16351 if (inhibit_try_window_reusing)
16352 return 0;
16353 #endif
16354
16355 if (/* This function doesn't handle terminal frames. */
16356 !FRAME_WINDOW_P (f)
16357 /* Don't try to reuse the display if windows have been split
16358 or such. */
16359 || windows_or_buffers_changed
16360 || cursor_type_changed)
16361 return 0;
16362
16363 /* Can't do this if region may have changed. */
16364 if (markpos_of_region () >= 0
16365 || w->region_showing
16366 || !NILP (Vshow_trailing_whitespace))
16367 return 0;
16368
16369 /* If top-line visibility has changed, give up. */
16370 if (WINDOW_WANTS_HEADER_LINE_P (w)
16371 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16372 return 0;
16373
16374 /* Give up if old or new display is scrolled vertically. We could
16375 make this function handle this, but right now it doesn't. */
16376 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16377 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16378 return 0;
16379
16380 /* The variable new_start now holds the new window start. The old
16381 start `start' can be determined from the current matrix. */
16382 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16383 start = start_row->minpos;
16384 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16385
16386 /* Clear the desired matrix for the display below. */
16387 clear_glyph_matrix (w->desired_matrix);
16388
16389 if (CHARPOS (new_start) <= CHARPOS (start))
16390 {
16391 /* Don't use this method if the display starts with an ellipsis
16392 displayed for invisible text. It's not easy to handle that case
16393 below, and it's certainly not worth the effort since this is
16394 not a frequent case. */
16395 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16396 return 0;
16397
16398 IF_DEBUG (debug_method_add (w, "twu1"));
16399
16400 /* Display up to a row that can be reused. The variable
16401 last_text_row is set to the last row displayed that displays
16402 text. Note that it.vpos == 0 if or if not there is a
16403 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16404 start_display (&it, w, new_start);
16405 w->cursor.vpos = -1;
16406 last_text_row = last_reused_text_row = NULL;
16407
16408 while (it.current_y < it.last_visible_y
16409 && !fonts_changed_p)
16410 {
16411 /* If we have reached into the characters in the START row,
16412 that means the line boundaries have changed. So we
16413 can't start copying with the row START. Maybe it will
16414 work to start copying with the following row. */
16415 while (IT_CHARPOS (it) > CHARPOS (start))
16416 {
16417 /* Advance to the next row as the "start". */
16418 start_row++;
16419 start = start_row->minpos;
16420 /* If there are no more rows to try, or just one, give up. */
16421 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16422 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16423 || CHARPOS (start) == ZV)
16424 {
16425 clear_glyph_matrix (w->desired_matrix);
16426 return 0;
16427 }
16428
16429 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16430 }
16431 /* If we have reached alignment, we can copy the rest of the
16432 rows. */
16433 if (IT_CHARPOS (it) == CHARPOS (start)
16434 /* Don't accept "alignment" inside a display vector,
16435 since start_row could have started in the middle of
16436 that same display vector (thus their character
16437 positions match), and we have no way of telling if
16438 that is the case. */
16439 && it.current.dpvec_index < 0)
16440 break;
16441
16442 if (display_line (&it))
16443 last_text_row = it.glyph_row - 1;
16444
16445 }
16446
16447 /* A value of current_y < last_visible_y means that we stopped
16448 at the previous window start, which in turn means that we
16449 have at least one reusable row. */
16450 if (it.current_y < it.last_visible_y)
16451 {
16452 struct glyph_row *row;
16453
16454 /* IT.vpos always starts from 0; it counts text lines. */
16455 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16456
16457 /* Find PT if not already found in the lines displayed. */
16458 if (w->cursor.vpos < 0)
16459 {
16460 int dy = it.current_y - start_row->y;
16461
16462 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16463 row = row_containing_pos (w, PT, row, NULL, dy);
16464 if (row)
16465 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16466 dy, nrows_scrolled);
16467 else
16468 {
16469 clear_glyph_matrix (w->desired_matrix);
16470 return 0;
16471 }
16472 }
16473
16474 /* Scroll the display. Do it before the current matrix is
16475 changed. The problem here is that update has not yet
16476 run, i.e. part of the current matrix is not up to date.
16477 scroll_run_hook will clear the cursor, and use the
16478 current matrix to get the height of the row the cursor is
16479 in. */
16480 run.current_y = start_row->y;
16481 run.desired_y = it.current_y;
16482 run.height = it.last_visible_y - it.current_y;
16483
16484 if (run.height > 0 && run.current_y != run.desired_y)
16485 {
16486 update_begin (f);
16487 FRAME_RIF (f)->update_window_begin_hook (w);
16488 FRAME_RIF (f)->clear_window_mouse_face (w);
16489 FRAME_RIF (f)->scroll_run_hook (w, &run);
16490 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16491 update_end (f);
16492 }
16493
16494 /* Shift current matrix down by nrows_scrolled lines. */
16495 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16496 rotate_matrix (w->current_matrix,
16497 start_vpos,
16498 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16499 nrows_scrolled);
16500
16501 /* Disable lines that must be updated. */
16502 for (i = 0; i < nrows_scrolled; ++i)
16503 (start_row + i)->enabled_p = 0;
16504
16505 /* Re-compute Y positions. */
16506 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16507 max_y = it.last_visible_y;
16508 for (row = start_row + nrows_scrolled;
16509 row < bottom_row;
16510 ++row)
16511 {
16512 row->y = it.current_y;
16513 row->visible_height = row->height;
16514
16515 if (row->y < min_y)
16516 row->visible_height -= min_y - row->y;
16517 if (row->y + row->height > max_y)
16518 row->visible_height -= row->y + row->height - max_y;
16519 if (row->fringe_bitmap_periodic_p)
16520 row->redraw_fringe_bitmaps_p = 1;
16521
16522 it.current_y += row->height;
16523
16524 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16525 last_reused_text_row = row;
16526 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16527 break;
16528 }
16529
16530 /* Disable lines in the current matrix which are now
16531 below the window. */
16532 for (++row; row < bottom_row; ++row)
16533 row->enabled_p = row->mode_line_p = 0;
16534 }
16535
16536 /* Update window_end_pos etc.; last_reused_text_row is the last
16537 reused row from the current matrix containing text, if any.
16538 The value of last_text_row is the last displayed line
16539 containing text. */
16540 if (last_reused_text_row)
16541 {
16542 w->window_end_bytepos
16543 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16544 wset_window_end_pos
16545 (w, make_number (Z
16546 - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
16547 wset_window_end_vpos
16548 (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16549 w->current_matrix)));
16550 }
16551 else if (last_text_row)
16552 {
16553 w->window_end_bytepos
16554 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16555 wset_window_end_pos
16556 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16557 wset_window_end_vpos
16558 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16559 w->desired_matrix)));
16560 }
16561 else
16562 {
16563 /* This window must be completely empty. */
16564 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16565 wset_window_end_pos (w, make_number (Z - ZV));
16566 wset_window_end_vpos (w, make_number (0));
16567 }
16568 w->window_end_valid = 0;
16569
16570 /* Update hint: don't try scrolling again in update_window. */
16571 w->desired_matrix->no_scrolling_p = 1;
16572
16573 #ifdef GLYPH_DEBUG
16574 debug_method_add (w, "try_window_reusing_current_matrix 1");
16575 #endif
16576 return 1;
16577 }
16578 else if (CHARPOS (new_start) > CHARPOS (start))
16579 {
16580 struct glyph_row *pt_row, *row;
16581 struct glyph_row *first_reusable_row;
16582 struct glyph_row *first_row_to_display;
16583 int dy;
16584 int yb = window_text_bottom_y (w);
16585
16586 /* Find the row starting at new_start, if there is one. Don't
16587 reuse a partially visible line at the end. */
16588 first_reusable_row = start_row;
16589 while (first_reusable_row->enabled_p
16590 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16591 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16592 < CHARPOS (new_start)))
16593 ++first_reusable_row;
16594
16595 /* Give up if there is no row to reuse. */
16596 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16597 || !first_reusable_row->enabled_p
16598 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16599 != CHARPOS (new_start)))
16600 return 0;
16601
16602 /* We can reuse fully visible rows beginning with
16603 first_reusable_row to the end of the window. Set
16604 first_row_to_display to the first row that cannot be reused.
16605 Set pt_row to the row containing point, if there is any. */
16606 pt_row = NULL;
16607 for (first_row_to_display = first_reusable_row;
16608 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16609 ++first_row_to_display)
16610 {
16611 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16612 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16613 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16614 && first_row_to_display->ends_at_zv_p
16615 && pt_row == NULL)))
16616 pt_row = first_row_to_display;
16617 }
16618
16619 /* Start displaying at the start of first_row_to_display. */
16620 eassert (first_row_to_display->y < yb);
16621 init_to_row_start (&it, w, first_row_to_display);
16622
16623 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16624 - start_vpos);
16625 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16626 - nrows_scrolled);
16627 it.current_y = (first_row_to_display->y - first_reusable_row->y
16628 + WINDOW_HEADER_LINE_HEIGHT (w));
16629
16630 /* Display lines beginning with first_row_to_display in the
16631 desired matrix. Set last_text_row to the last row displayed
16632 that displays text. */
16633 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16634 if (pt_row == NULL)
16635 w->cursor.vpos = -1;
16636 last_text_row = NULL;
16637 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16638 if (display_line (&it))
16639 last_text_row = it.glyph_row - 1;
16640
16641 /* If point is in a reused row, adjust y and vpos of the cursor
16642 position. */
16643 if (pt_row)
16644 {
16645 w->cursor.vpos -= nrows_scrolled;
16646 w->cursor.y -= first_reusable_row->y - start_row->y;
16647 }
16648
16649 /* Give up if point isn't in a row displayed or reused. (This
16650 also handles the case where w->cursor.vpos < nrows_scrolled
16651 after the calls to display_line, which can happen with scroll
16652 margins. See bug#1295.) */
16653 if (w->cursor.vpos < 0)
16654 {
16655 clear_glyph_matrix (w->desired_matrix);
16656 return 0;
16657 }
16658
16659 /* Scroll the display. */
16660 run.current_y = first_reusable_row->y;
16661 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16662 run.height = it.last_visible_y - run.current_y;
16663 dy = run.current_y - run.desired_y;
16664
16665 if (run.height)
16666 {
16667 update_begin (f);
16668 FRAME_RIF (f)->update_window_begin_hook (w);
16669 FRAME_RIF (f)->clear_window_mouse_face (w);
16670 FRAME_RIF (f)->scroll_run_hook (w, &run);
16671 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16672 update_end (f);
16673 }
16674
16675 /* Adjust Y positions of reused rows. */
16676 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16677 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16678 max_y = it.last_visible_y;
16679 for (row = first_reusable_row; row < first_row_to_display; ++row)
16680 {
16681 row->y -= dy;
16682 row->visible_height = row->height;
16683 if (row->y < min_y)
16684 row->visible_height -= min_y - row->y;
16685 if (row->y + row->height > max_y)
16686 row->visible_height -= row->y + row->height - max_y;
16687 if (row->fringe_bitmap_periodic_p)
16688 row->redraw_fringe_bitmaps_p = 1;
16689 }
16690
16691 /* Scroll the current matrix. */
16692 eassert (nrows_scrolled > 0);
16693 rotate_matrix (w->current_matrix,
16694 start_vpos,
16695 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16696 -nrows_scrolled);
16697
16698 /* Disable rows not reused. */
16699 for (row -= nrows_scrolled; row < bottom_row; ++row)
16700 row->enabled_p = 0;
16701
16702 /* Point may have moved to a different line, so we cannot assume that
16703 the previous cursor position is valid; locate the correct row. */
16704 if (pt_row)
16705 {
16706 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16707 row < bottom_row
16708 && PT >= MATRIX_ROW_END_CHARPOS (row)
16709 && !row->ends_at_zv_p;
16710 row++)
16711 {
16712 w->cursor.vpos++;
16713 w->cursor.y = row->y;
16714 }
16715 if (row < bottom_row)
16716 {
16717 /* Can't simply scan the row for point with
16718 bidi-reordered glyph rows. Let set_cursor_from_row
16719 figure out where to put the cursor, and if it fails,
16720 give up. */
16721 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16722 {
16723 if (!set_cursor_from_row (w, row, w->current_matrix,
16724 0, 0, 0, 0))
16725 {
16726 clear_glyph_matrix (w->desired_matrix);
16727 return 0;
16728 }
16729 }
16730 else
16731 {
16732 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16733 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16734
16735 for (; glyph < end
16736 && (!BUFFERP (glyph->object)
16737 || glyph->charpos < PT);
16738 glyph++)
16739 {
16740 w->cursor.hpos++;
16741 w->cursor.x += glyph->pixel_width;
16742 }
16743 }
16744 }
16745 }
16746
16747 /* Adjust window end. A null value of last_text_row means that
16748 the window end is in reused rows which in turn means that
16749 only its vpos can have changed. */
16750 if (last_text_row)
16751 {
16752 w->window_end_bytepos
16753 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16754 wset_window_end_pos
16755 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16756 wset_window_end_vpos
16757 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16758 w->desired_matrix)));
16759 }
16760 else
16761 {
16762 wset_window_end_vpos
16763 (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
16764 }
16765
16766 w->window_end_valid = 0;
16767 w->desired_matrix->no_scrolling_p = 1;
16768
16769 #ifdef GLYPH_DEBUG
16770 debug_method_add (w, "try_window_reusing_current_matrix 2");
16771 #endif
16772 return 1;
16773 }
16774
16775 return 0;
16776 }
16777
16778
16779 \f
16780 /************************************************************************
16781 Window redisplay reusing current matrix when buffer has changed
16782 ************************************************************************/
16783
16784 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16785 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16786 ptrdiff_t *, ptrdiff_t *);
16787 static struct glyph_row *
16788 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16789 struct glyph_row *);
16790
16791
16792 /* Return the last row in MATRIX displaying text. If row START is
16793 non-null, start searching with that row. IT gives the dimensions
16794 of the display. Value is null if matrix is empty; otherwise it is
16795 a pointer to the row found. */
16796
16797 static struct glyph_row *
16798 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16799 struct glyph_row *start)
16800 {
16801 struct glyph_row *row, *row_found;
16802
16803 /* Set row_found to the last row in IT->w's current matrix
16804 displaying text. The loop looks funny but think of partially
16805 visible lines. */
16806 row_found = NULL;
16807 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16808 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16809 {
16810 eassert (row->enabled_p);
16811 row_found = row;
16812 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16813 break;
16814 ++row;
16815 }
16816
16817 return row_found;
16818 }
16819
16820
16821 /* Return the last row in the current matrix of W that is not affected
16822 by changes at the start of current_buffer that occurred since W's
16823 current matrix was built. Value is null if no such row exists.
16824
16825 BEG_UNCHANGED us the number of characters unchanged at the start of
16826 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16827 first changed character in current_buffer. Characters at positions <
16828 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16829 when the current matrix was built. */
16830
16831 static struct glyph_row *
16832 find_last_unchanged_at_beg_row (struct window *w)
16833 {
16834 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16835 struct glyph_row *row;
16836 struct glyph_row *row_found = NULL;
16837 int yb = window_text_bottom_y (w);
16838
16839 /* Find the last row displaying unchanged text. */
16840 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16841 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16842 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16843 ++row)
16844 {
16845 if (/* If row ends before first_changed_pos, it is unchanged,
16846 except in some case. */
16847 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16848 /* When row ends in ZV and we write at ZV it is not
16849 unchanged. */
16850 && !row->ends_at_zv_p
16851 /* When first_changed_pos is the end of a continued line,
16852 row is not unchanged because it may be no longer
16853 continued. */
16854 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16855 && (row->continued_p
16856 || row->exact_window_width_line_p))
16857 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16858 needs to be recomputed, so don't consider this row as
16859 unchanged. This happens when the last line was
16860 bidi-reordered and was killed immediately before this
16861 redisplay cycle. In that case, ROW->end stores the
16862 buffer position of the first visual-order character of
16863 the killed text, which is now beyond ZV. */
16864 && CHARPOS (row->end.pos) <= ZV)
16865 row_found = row;
16866
16867 /* Stop if last visible row. */
16868 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16869 break;
16870 }
16871
16872 return row_found;
16873 }
16874
16875
16876 /* Find the first glyph row in the current matrix of W that is not
16877 affected by changes at the end of current_buffer since the
16878 time W's current matrix was built.
16879
16880 Return in *DELTA the number of chars by which buffer positions in
16881 unchanged text at the end of current_buffer must be adjusted.
16882
16883 Return in *DELTA_BYTES the corresponding number of bytes.
16884
16885 Value is null if no such row exists, i.e. all rows are affected by
16886 changes. */
16887
16888 static struct glyph_row *
16889 find_first_unchanged_at_end_row (struct window *w,
16890 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16891 {
16892 struct glyph_row *row;
16893 struct glyph_row *row_found = NULL;
16894
16895 *delta = *delta_bytes = 0;
16896
16897 /* Display must not have been paused, otherwise the current matrix
16898 is not up to date. */
16899 eassert (w->window_end_valid);
16900
16901 /* A value of window_end_pos >= END_UNCHANGED means that the window
16902 end is in the range of changed text. If so, there is no
16903 unchanged row at the end of W's current matrix. */
16904 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16905 return NULL;
16906
16907 /* Set row to the last row in W's current matrix displaying text. */
16908 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16909
16910 /* If matrix is entirely empty, no unchanged row exists. */
16911 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16912 {
16913 /* The value of row is the last glyph row in the matrix having a
16914 meaningful buffer position in it. The end position of row
16915 corresponds to window_end_pos. This allows us to translate
16916 buffer positions in the current matrix to current buffer
16917 positions for characters not in changed text. */
16918 ptrdiff_t Z_old =
16919 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16920 ptrdiff_t Z_BYTE_old =
16921 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16922 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16923 struct glyph_row *first_text_row
16924 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16925
16926 *delta = Z - Z_old;
16927 *delta_bytes = Z_BYTE - Z_BYTE_old;
16928
16929 /* Set last_unchanged_pos to the buffer position of the last
16930 character in the buffer that has not been changed. Z is the
16931 index + 1 of the last character in current_buffer, i.e. by
16932 subtracting END_UNCHANGED we get the index of the last
16933 unchanged character, and we have to add BEG to get its buffer
16934 position. */
16935 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16936 last_unchanged_pos_old = last_unchanged_pos - *delta;
16937
16938 /* Search backward from ROW for a row displaying a line that
16939 starts at a minimum position >= last_unchanged_pos_old. */
16940 for (; row > first_text_row; --row)
16941 {
16942 /* This used to abort, but it can happen.
16943 It is ok to just stop the search instead here. KFS. */
16944 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16945 break;
16946
16947 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16948 row_found = row;
16949 }
16950 }
16951
16952 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16953
16954 return row_found;
16955 }
16956
16957
16958 /* Make sure that glyph rows in the current matrix of window W
16959 reference the same glyph memory as corresponding rows in the
16960 frame's frame matrix. This function is called after scrolling W's
16961 current matrix on a terminal frame in try_window_id and
16962 try_window_reusing_current_matrix. */
16963
16964 static void
16965 sync_frame_with_window_matrix_rows (struct window *w)
16966 {
16967 struct frame *f = XFRAME (w->frame);
16968 struct glyph_row *window_row, *window_row_end, *frame_row;
16969
16970 /* Preconditions: W must be a leaf window and full-width. Its frame
16971 must have a frame matrix. */
16972 eassert (BUFFERP (w->contents));
16973 eassert (WINDOW_FULL_WIDTH_P (w));
16974 eassert (!FRAME_WINDOW_P (f));
16975
16976 /* If W is a full-width window, glyph pointers in W's current matrix
16977 have, by definition, to be the same as glyph pointers in the
16978 corresponding frame matrix. Note that frame matrices have no
16979 marginal areas (see build_frame_matrix). */
16980 window_row = w->current_matrix->rows;
16981 window_row_end = window_row + w->current_matrix->nrows;
16982 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16983 while (window_row < window_row_end)
16984 {
16985 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16986 struct glyph *end = window_row->glyphs[LAST_AREA];
16987
16988 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16989 frame_row->glyphs[TEXT_AREA] = start;
16990 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16991 frame_row->glyphs[LAST_AREA] = end;
16992
16993 /* Disable frame rows whose corresponding window rows have
16994 been disabled in try_window_id. */
16995 if (!window_row->enabled_p)
16996 frame_row->enabled_p = 0;
16997
16998 ++window_row, ++frame_row;
16999 }
17000 }
17001
17002
17003 /* Find the glyph row in window W containing CHARPOS. Consider all
17004 rows between START and END (not inclusive). END null means search
17005 all rows to the end of the display area of W. Value is the row
17006 containing CHARPOS or null. */
17007
17008 struct glyph_row *
17009 row_containing_pos (struct window *w, ptrdiff_t charpos,
17010 struct glyph_row *start, struct glyph_row *end, int dy)
17011 {
17012 struct glyph_row *row = start;
17013 struct glyph_row *best_row = NULL;
17014 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17015 int last_y;
17016
17017 /* If we happen to start on a header-line, skip that. */
17018 if (row->mode_line_p)
17019 ++row;
17020
17021 if ((end && row >= end) || !row->enabled_p)
17022 return NULL;
17023
17024 last_y = window_text_bottom_y (w) - dy;
17025
17026 while (1)
17027 {
17028 /* Give up if we have gone too far. */
17029 if (end && row >= end)
17030 return NULL;
17031 /* This formerly returned if they were equal.
17032 I think that both quantities are of a "last plus one" type;
17033 if so, when they are equal, the row is within the screen. -- rms. */
17034 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17035 return NULL;
17036
17037 /* If it is in this row, return this row. */
17038 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17039 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17040 /* The end position of a row equals the start
17041 position of the next row. If CHARPOS is there, we
17042 would rather consider it displayed in the next
17043 line, except when this line ends in ZV. */
17044 && !row_for_charpos_p (row, charpos)))
17045 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17046 {
17047 struct glyph *g;
17048
17049 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17050 || (!best_row && !row->continued_p))
17051 return row;
17052 /* In bidi-reordered rows, there could be several rows whose
17053 edges surround CHARPOS, all of these rows belonging to
17054 the same continued line. We need to find the row which
17055 fits CHARPOS the best. */
17056 for (g = row->glyphs[TEXT_AREA];
17057 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17058 g++)
17059 {
17060 if (!STRINGP (g->object))
17061 {
17062 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17063 {
17064 mindif = eabs (g->charpos - charpos);
17065 best_row = row;
17066 /* Exact match always wins. */
17067 if (mindif == 0)
17068 return best_row;
17069 }
17070 }
17071 }
17072 }
17073 else if (best_row && !row->continued_p)
17074 return best_row;
17075 ++row;
17076 }
17077 }
17078
17079
17080 /* Try to redisplay window W by reusing its existing display. W's
17081 current matrix must be up to date when this function is called,
17082 i.e. window_end_valid must be nonzero.
17083
17084 Value is
17085
17086 1 if display has been updated
17087 0 if otherwise unsuccessful
17088 -1 if redisplay with same window start is known not to succeed
17089
17090 The following steps are performed:
17091
17092 1. Find the last row in the current matrix of W that is not
17093 affected by changes at the start of current_buffer. If no such row
17094 is found, give up.
17095
17096 2. Find the first row in W's current matrix that is not affected by
17097 changes at the end of current_buffer. Maybe there is no such row.
17098
17099 3. Display lines beginning with the row + 1 found in step 1 to the
17100 row found in step 2 or, if step 2 didn't find a row, to the end of
17101 the window.
17102
17103 4. If cursor is not known to appear on the window, give up.
17104
17105 5. If display stopped at the row found in step 2, scroll the
17106 display and current matrix as needed.
17107
17108 6. Maybe display some lines at the end of W, if we must. This can
17109 happen under various circumstances, like a partially visible line
17110 becoming fully visible, or because newly displayed lines are displayed
17111 in smaller font sizes.
17112
17113 7. Update W's window end information. */
17114
17115 static int
17116 try_window_id (struct window *w)
17117 {
17118 struct frame *f = XFRAME (w->frame);
17119 struct glyph_matrix *current_matrix = w->current_matrix;
17120 struct glyph_matrix *desired_matrix = w->desired_matrix;
17121 struct glyph_row *last_unchanged_at_beg_row;
17122 struct glyph_row *first_unchanged_at_end_row;
17123 struct glyph_row *row;
17124 struct glyph_row *bottom_row;
17125 int bottom_vpos;
17126 struct it it;
17127 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17128 int dvpos, dy;
17129 struct text_pos start_pos;
17130 struct run run;
17131 int first_unchanged_at_end_vpos = 0;
17132 struct glyph_row *last_text_row, *last_text_row_at_end;
17133 struct text_pos start;
17134 ptrdiff_t first_changed_charpos, last_changed_charpos;
17135
17136 #ifdef GLYPH_DEBUG
17137 if (inhibit_try_window_id)
17138 return 0;
17139 #endif
17140
17141 /* This is handy for debugging. */
17142 #if 0
17143 #define GIVE_UP(X) \
17144 do { \
17145 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17146 return 0; \
17147 } while (0)
17148 #else
17149 #define GIVE_UP(X) return 0
17150 #endif
17151
17152 SET_TEXT_POS_FROM_MARKER (start, w->start);
17153
17154 /* Don't use this for mini-windows because these can show
17155 messages and mini-buffers, and we don't handle that here. */
17156 if (MINI_WINDOW_P (w))
17157 GIVE_UP (1);
17158
17159 /* This flag is used to prevent redisplay optimizations. */
17160 if (windows_or_buffers_changed || cursor_type_changed)
17161 GIVE_UP (2);
17162
17163 /* Verify that narrowing has not changed.
17164 Also verify that we were not told to prevent redisplay optimizations.
17165 It would be nice to further
17166 reduce the number of cases where this prevents try_window_id. */
17167 if (current_buffer->clip_changed
17168 || current_buffer->prevent_redisplay_optimizations_p)
17169 GIVE_UP (3);
17170
17171 /* Window must either use window-based redisplay or be full width. */
17172 if (!FRAME_WINDOW_P (f)
17173 && (!FRAME_LINE_INS_DEL_OK (f)
17174 || !WINDOW_FULL_WIDTH_P (w)))
17175 GIVE_UP (4);
17176
17177 /* Give up if point is known NOT to appear in W. */
17178 if (PT < CHARPOS (start))
17179 GIVE_UP (5);
17180
17181 /* Another way to prevent redisplay optimizations. */
17182 if (w->last_modified == 0)
17183 GIVE_UP (6);
17184
17185 /* Verify that window is not hscrolled. */
17186 if (w->hscroll != 0)
17187 GIVE_UP (7);
17188
17189 /* Verify that display wasn't paused. */
17190 if (!w->window_end_valid)
17191 GIVE_UP (8);
17192
17193 /* Can't use this if highlighting a region because a cursor movement
17194 will do more than just set the cursor. */
17195 if (markpos_of_region () >= 0)
17196 GIVE_UP (9);
17197
17198 /* Likewise if highlighting trailing whitespace. */
17199 if (!NILP (Vshow_trailing_whitespace))
17200 GIVE_UP (11);
17201
17202 /* Likewise if showing a region. */
17203 if (w->region_showing)
17204 GIVE_UP (10);
17205
17206 /* Can't use this if overlay arrow position and/or string have
17207 changed. */
17208 if (overlay_arrows_changed_p ())
17209 GIVE_UP (12);
17210
17211 /* When word-wrap is on, adding a space to the first word of a
17212 wrapped line can change the wrap position, altering the line
17213 above it. It might be worthwhile to handle this more
17214 intelligently, but for now just redisplay from scratch. */
17215 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17216 GIVE_UP (21);
17217
17218 /* Under bidi reordering, adding or deleting a character in the
17219 beginning of a paragraph, before the first strong directional
17220 character, can change the base direction of the paragraph (unless
17221 the buffer specifies a fixed paragraph direction), which will
17222 require to redisplay the whole paragraph. It might be worthwhile
17223 to find the paragraph limits and widen the range of redisplayed
17224 lines to that, but for now just give up this optimization and
17225 redisplay from scratch. */
17226 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17227 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17228 GIVE_UP (22);
17229
17230 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17231 only if buffer has really changed. The reason is that the gap is
17232 initially at Z for freshly visited files. The code below would
17233 set end_unchanged to 0 in that case. */
17234 if (MODIFF > SAVE_MODIFF
17235 /* This seems to happen sometimes after saving a buffer. */
17236 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17237 {
17238 if (GPT - BEG < BEG_UNCHANGED)
17239 BEG_UNCHANGED = GPT - BEG;
17240 if (Z - GPT < END_UNCHANGED)
17241 END_UNCHANGED = Z - GPT;
17242 }
17243
17244 /* The position of the first and last character that has been changed. */
17245 first_changed_charpos = BEG + BEG_UNCHANGED;
17246 last_changed_charpos = Z - END_UNCHANGED;
17247
17248 /* If window starts after a line end, and the last change is in
17249 front of that newline, then changes don't affect the display.
17250 This case happens with stealth-fontification. Note that although
17251 the display is unchanged, glyph positions in the matrix have to
17252 be adjusted, of course. */
17253 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17254 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17255 && ((last_changed_charpos < CHARPOS (start)
17256 && CHARPOS (start) == BEGV)
17257 || (last_changed_charpos < CHARPOS (start) - 1
17258 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17259 {
17260 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17261 struct glyph_row *r0;
17262
17263 /* Compute how many chars/bytes have been added to or removed
17264 from the buffer. */
17265 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17266 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17267 Z_delta = Z - Z_old;
17268 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17269
17270 /* Give up if PT is not in the window. Note that it already has
17271 been checked at the start of try_window_id that PT is not in
17272 front of the window start. */
17273 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17274 GIVE_UP (13);
17275
17276 /* If window start is unchanged, we can reuse the whole matrix
17277 as is, after adjusting glyph positions. No need to compute
17278 the window end again, since its offset from Z hasn't changed. */
17279 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17280 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17281 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17282 /* PT must not be in a partially visible line. */
17283 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17284 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17285 {
17286 /* Adjust positions in the glyph matrix. */
17287 if (Z_delta || Z_delta_bytes)
17288 {
17289 struct glyph_row *r1
17290 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17291 increment_matrix_positions (w->current_matrix,
17292 MATRIX_ROW_VPOS (r0, current_matrix),
17293 MATRIX_ROW_VPOS (r1, current_matrix),
17294 Z_delta, Z_delta_bytes);
17295 }
17296
17297 /* Set the cursor. */
17298 row = row_containing_pos (w, PT, r0, NULL, 0);
17299 if (row)
17300 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17301 else
17302 emacs_abort ();
17303 return 1;
17304 }
17305 }
17306
17307 /* Handle the case that changes are all below what is displayed in
17308 the window, and that PT is in the window. This shortcut cannot
17309 be taken if ZV is visible in the window, and text has been added
17310 there that is visible in the window. */
17311 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17312 /* ZV is not visible in the window, or there are no
17313 changes at ZV, actually. */
17314 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17315 || first_changed_charpos == last_changed_charpos))
17316 {
17317 struct glyph_row *r0;
17318
17319 /* Give up if PT is not in the window. Note that it already has
17320 been checked at the start of try_window_id that PT is not in
17321 front of the window start. */
17322 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17323 GIVE_UP (14);
17324
17325 /* If window start is unchanged, we can reuse the whole matrix
17326 as is, without changing glyph positions since no text has
17327 been added/removed in front of the window end. */
17328 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17329 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17330 /* PT must not be in a partially visible line. */
17331 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17332 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17333 {
17334 /* We have to compute the window end anew since text
17335 could have been added/removed after it. */
17336 wset_window_end_pos
17337 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17338 w->window_end_bytepos
17339 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17340
17341 /* Set the cursor. */
17342 row = row_containing_pos (w, PT, r0, NULL, 0);
17343 if (row)
17344 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17345 else
17346 emacs_abort ();
17347 return 2;
17348 }
17349 }
17350
17351 /* Give up if window start is in the changed area.
17352
17353 The condition used to read
17354
17355 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17356
17357 but why that was tested escapes me at the moment. */
17358 if (CHARPOS (start) >= first_changed_charpos
17359 && CHARPOS (start) <= last_changed_charpos)
17360 GIVE_UP (15);
17361
17362 /* Check that window start agrees with the start of the first glyph
17363 row in its current matrix. Check this after we know the window
17364 start is not in changed text, otherwise positions would not be
17365 comparable. */
17366 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17367 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17368 GIVE_UP (16);
17369
17370 /* Give up if the window ends in strings. Overlay strings
17371 at the end are difficult to handle, so don't try. */
17372 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17373 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17374 GIVE_UP (20);
17375
17376 /* Compute the position at which we have to start displaying new
17377 lines. Some of the lines at the top of the window might be
17378 reusable because they are not displaying changed text. Find the
17379 last row in W's current matrix not affected by changes at the
17380 start of current_buffer. Value is null if changes start in the
17381 first line of window. */
17382 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17383 if (last_unchanged_at_beg_row)
17384 {
17385 /* Avoid starting to display in the middle of a character, a TAB
17386 for instance. This is easier than to set up the iterator
17387 exactly, and it's not a frequent case, so the additional
17388 effort wouldn't really pay off. */
17389 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17390 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17391 && last_unchanged_at_beg_row > w->current_matrix->rows)
17392 --last_unchanged_at_beg_row;
17393
17394 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17395 GIVE_UP (17);
17396
17397 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17398 GIVE_UP (18);
17399 start_pos = it.current.pos;
17400
17401 /* Start displaying new lines in the desired matrix at the same
17402 vpos we would use in the current matrix, i.e. below
17403 last_unchanged_at_beg_row. */
17404 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17405 current_matrix);
17406 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17407 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17408
17409 eassert (it.hpos == 0 && it.current_x == 0);
17410 }
17411 else
17412 {
17413 /* There are no reusable lines at the start of the window.
17414 Start displaying in the first text line. */
17415 start_display (&it, w, start);
17416 it.vpos = it.first_vpos;
17417 start_pos = it.current.pos;
17418 }
17419
17420 /* Find the first row that is not affected by changes at the end of
17421 the buffer. Value will be null if there is no unchanged row, in
17422 which case we must redisplay to the end of the window. delta
17423 will be set to the value by which buffer positions beginning with
17424 first_unchanged_at_end_row have to be adjusted due to text
17425 changes. */
17426 first_unchanged_at_end_row
17427 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17428 IF_DEBUG (debug_delta = delta);
17429 IF_DEBUG (debug_delta_bytes = delta_bytes);
17430
17431 /* Set stop_pos to the buffer position up to which we will have to
17432 display new lines. If first_unchanged_at_end_row != NULL, this
17433 is the buffer position of the start of the line displayed in that
17434 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17435 that we don't stop at a buffer position. */
17436 stop_pos = 0;
17437 if (first_unchanged_at_end_row)
17438 {
17439 eassert (last_unchanged_at_beg_row == NULL
17440 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17441
17442 /* If this is a continuation line, move forward to the next one
17443 that isn't. Changes in lines above affect this line.
17444 Caution: this may move first_unchanged_at_end_row to a row
17445 not displaying text. */
17446 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17447 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17448 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17449 < it.last_visible_y))
17450 ++first_unchanged_at_end_row;
17451
17452 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17453 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17454 >= it.last_visible_y))
17455 first_unchanged_at_end_row = NULL;
17456 else
17457 {
17458 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17459 + delta);
17460 first_unchanged_at_end_vpos
17461 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17462 eassert (stop_pos >= Z - END_UNCHANGED);
17463 }
17464 }
17465 else if (last_unchanged_at_beg_row == NULL)
17466 GIVE_UP (19);
17467
17468
17469 #ifdef GLYPH_DEBUG
17470
17471 /* Either there is no unchanged row at the end, or the one we have
17472 now displays text. This is a necessary condition for the window
17473 end pos calculation at the end of this function. */
17474 eassert (first_unchanged_at_end_row == NULL
17475 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17476
17477 debug_last_unchanged_at_beg_vpos
17478 = (last_unchanged_at_beg_row
17479 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17480 : -1);
17481 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17482
17483 #endif /* GLYPH_DEBUG */
17484
17485
17486 /* Display new lines. Set last_text_row to the last new line
17487 displayed which has text on it, i.e. might end up as being the
17488 line where the window_end_vpos is. */
17489 w->cursor.vpos = -1;
17490 last_text_row = NULL;
17491 overlay_arrow_seen = 0;
17492 while (it.current_y < it.last_visible_y
17493 && !fonts_changed_p
17494 && (first_unchanged_at_end_row == NULL
17495 || IT_CHARPOS (it) < stop_pos))
17496 {
17497 if (display_line (&it))
17498 last_text_row = it.glyph_row - 1;
17499 }
17500
17501 if (fonts_changed_p)
17502 return -1;
17503
17504
17505 /* Compute differences in buffer positions, y-positions etc. for
17506 lines reused at the bottom of the window. Compute what we can
17507 scroll. */
17508 if (first_unchanged_at_end_row
17509 /* No lines reused because we displayed everything up to the
17510 bottom of the window. */
17511 && it.current_y < it.last_visible_y)
17512 {
17513 dvpos = (it.vpos
17514 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17515 current_matrix));
17516 dy = it.current_y - first_unchanged_at_end_row->y;
17517 run.current_y = first_unchanged_at_end_row->y;
17518 run.desired_y = run.current_y + dy;
17519 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17520 }
17521 else
17522 {
17523 delta = delta_bytes = dvpos = dy
17524 = run.current_y = run.desired_y = run.height = 0;
17525 first_unchanged_at_end_row = NULL;
17526 }
17527 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17528
17529
17530 /* Find the cursor if not already found. We have to decide whether
17531 PT will appear on this window (it sometimes doesn't, but this is
17532 not a very frequent case.) This decision has to be made before
17533 the current matrix is altered. A value of cursor.vpos < 0 means
17534 that PT is either in one of the lines beginning at
17535 first_unchanged_at_end_row or below the window. Don't care for
17536 lines that might be displayed later at the window end; as
17537 mentioned, this is not a frequent case. */
17538 if (w->cursor.vpos < 0)
17539 {
17540 /* Cursor in unchanged rows at the top? */
17541 if (PT < CHARPOS (start_pos)
17542 && last_unchanged_at_beg_row)
17543 {
17544 row = row_containing_pos (w, PT,
17545 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17546 last_unchanged_at_beg_row + 1, 0);
17547 if (row)
17548 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17549 }
17550
17551 /* Start from first_unchanged_at_end_row looking for PT. */
17552 else if (first_unchanged_at_end_row)
17553 {
17554 row = row_containing_pos (w, PT - delta,
17555 first_unchanged_at_end_row, NULL, 0);
17556 if (row)
17557 set_cursor_from_row (w, row, w->current_matrix, delta,
17558 delta_bytes, dy, dvpos);
17559 }
17560
17561 /* Give up if cursor was not found. */
17562 if (w->cursor.vpos < 0)
17563 {
17564 clear_glyph_matrix (w->desired_matrix);
17565 return -1;
17566 }
17567 }
17568
17569 /* Don't let the cursor end in the scroll margins. */
17570 {
17571 int this_scroll_margin, cursor_height;
17572 int frame_line_height = default_line_pixel_height (w);
17573 int window_total_lines
17574 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
17575
17576 this_scroll_margin =
17577 max (0, min (scroll_margin, window_total_lines / 4));
17578 this_scroll_margin *= frame_line_height;
17579 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17580
17581 if ((w->cursor.y < this_scroll_margin
17582 && CHARPOS (start) > BEGV)
17583 /* Old redisplay didn't take scroll margin into account at the bottom,
17584 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17585 || (w->cursor.y + (make_cursor_line_fully_visible_p
17586 ? cursor_height + this_scroll_margin
17587 : 1)) > it.last_visible_y)
17588 {
17589 w->cursor.vpos = -1;
17590 clear_glyph_matrix (w->desired_matrix);
17591 return -1;
17592 }
17593 }
17594
17595 /* Scroll the display. Do it before changing the current matrix so
17596 that xterm.c doesn't get confused about where the cursor glyph is
17597 found. */
17598 if (dy && run.height)
17599 {
17600 update_begin (f);
17601
17602 if (FRAME_WINDOW_P (f))
17603 {
17604 FRAME_RIF (f)->update_window_begin_hook (w);
17605 FRAME_RIF (f)->clear_window_mouse_face (w);
17606 FRAME_RIF (f)->scroll_run_hook (w, &run);
17607 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17608 }
17609 else
17610 {
17611 /* Terminal frame. In this case, dvpos gives the number of
17612 lines to scroll by; dvpos < 0 means scroll up. */
17613 int from_vpos
17614 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17615 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17616 int end = (WINDOW_TOP_EDGE_LINE (w)
17617 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17618 + window_internal_height (w));
17619
17620 #if defined (HAVE_GPM) || defined (MSDOS)
17621 x_clear_window_mouse_face (w);
17622 #endif
17623 /* Perform the operation on the screen. */
17624 if (dvpos > 0)
17625 {
17626 /* Scroll last_unchanged_at_beg_row to the end of the
17627 window down dvpos lines. */
17628 set_terminal_window (f, end);
17629
17630 /* On dumb terminals delete dvpos lines at the end
17631 before inserting dvpos empty lines. */
17632 if (!FRAME_SCROLL_REGION_OK (f))
17633 ins_del_lines (f, end - dvpos, -dvpos);
17634
17635 /* Insert dvpos empty lines in front of
17636 last_unchanged_at_beg_row. */
17637 ins_del_lines (f, from, dvpos);
17638 }
17639 else if (dvpos < 0)
17640 {
17641 /* Scroll up last_unchanged_at_beg_vpos to the end of
17642 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17643 set_terminal_window (f, end);
17644
17645 /* Delete dvpos lines in front of
17646 last_unchanged_at_beg_vpos. ins_del_lines will set
17647 the cursor to the given vpos and emit |dvpos| delete
17648 line sequences. */
17649 ins_del_lines (f, from + dvpos, dvpos);
17650
17651 /* On a dumb terminal insert dvpos empty lines at the
17652 end. */
17653 if (!FRAME_SCROLL_REGION_OK (f))
17654 ins_del_lines (f, end + dvpos, -dvpos);
17655 }
17656
17657 set_terminal_window (f, 0);
17658 }
17659
17660 update_end (f);
17661 }
17662
17663 /* Shift reused rows of the current matrix to the right position.
17664 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17665 text. */
17666 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17667 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17668 if (dvpos < 0)
17669 {
17670 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17671 bottom_vpos, dvpos);
17672 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17673 bottom_vpos);
17674 }
17675 else if (dvpos > 0)
17676 {
17677 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17678 bottom_vpos, dvpos);
17679 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17680 first_unchanged_at_end_vpos + dvpos);
17681 }
17682
17683 /* For frame-based redisplay, make sure that current frame and window
17684 matrix are in sync with respect to glyph memory. */
17685 if (!FRAME_WINDOW_P (f))
17686 sync_frame_with_window_matrix_rows (w);
17687
17688 /* Adjust buffer positions in reused rows. */
17689 if (delta || delta_bytes)
17690 increment_matrix_positions (current_matrix,
17691 first_unchanged_at_end_vpos + dvpos,
17692 bottom_vpos, delta, delta_bytes);
17693
17694 /* Adjust Y positions. */
17695 if (dy)
17696 shift_glyph_matrix (w, current_matrix,
17697 first_unchanged_at_end_vpos + dvpos,
17698 bottom_vpos, dy);
17699
17700 if (first_unchanged_at_end_row)
17701 {
17702 first_unchanged_at_end_row += dvpos;
17703 if (first_unchanged_at_end_row->y >= it.last_visible_y
17704 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17705 first_unchanged_at_end_row = NULL;
17706 }
17707
17708 /* If scrolling up, there may be some lines to display at the end of
17709 the window. */
17710 last_text_row_at_end = NULL;
17711 if (dy < 0)
17712 {
17713 /* Scrolling up can leave for example a partially visible line
17714 at the end of the window to be redisplayed. */
17715 /* Set last_row to the glyph row in the current matrix where the
17716 window end line is found. It has been moved up or down in
17717 the matrix by dvpos. */
17718 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17719 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17720
17721 /* If last_row is the window end line, it should display text. */
17722 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17723
17724 /* If window end line was partially visible before, begin
17725 displaying at that line. Otherwise begin displaying with the
17726 line following it. */
17727 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17728 {
17729 init_to_row_start (&it, w, last_row);
17730 it.vpos = last_vpos;
17731 it.current_y = last_row->y;
17732 }
17733 else
17734 {
17735 init_to_row_end (&it, w, last_row);
17736 it.vpos = 1 + last_vpos;
17737 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17738 ++last_row;
17739 }
17740
17741 /* We may start in a continuation line. If so, we have to
17742 get the right continuation_lines_width and current_x. */
17743 it.continuation_lines_width = last_row->continuation_lines_width;
17744 it.hpos = it.current_x = 0;
17745
17746 /* Display the rest of the lines at the window end. */
17747 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17748 while (it.current_y < it.last_visible_y
17749 && !fonts_changed_p)
17750 {
17751 /* Is it always sure that the display agrees with lines in
17752 the current matrix? I don't think so, so we mark rows
17753 displayed invalid in the current matrix by setting their
17754 enabled_p flag to zero. */
17755 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17756 if (display_line (&it))
17757 last_text_row_at_end = it.glyph_row - 1;
17758 }
17759 }
17760
17761 /* Update window_end_pos and window_end_vpos. */
17762 if (first_unchanged_at_end_row
17763 && !last_text_row_at_end)
17764 {
17765 /* Window end line if one of the preserved rows from the current
17766 matrix. Set row to the last row displaying text in current
17767 matrix starting at first_unchanged_at_end_row, after
17768 scrolling. */
17769 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17770 row = find_last_row_displaying_text (w->current_matrix, &it,
17771 first_unchanged_at_end_row);
17772 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17773
17774 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17775 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17776 wset_window_end_vpos
17777 (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
17778 eassert (w->window_end_bytepos >= 0);
17779 IF_DEBUG (debug_method_add (w, "A"));
17780 }
17781 else if (last_text_row_at_end)
17782 {
17783 wset_window_end_pos
17784 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
17785 w->window_end_bytepos
17786 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17787 wset_window_end_vpos
17788 (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
17789 desired_matrix)));
17790 eassert (w->window_end_bytepos >= 0);
17791 IF_DEBUG (debug_method_add (w, "B"));
17792 }
17793 else if (last_text_row)
17794 {
17795 /* We have displayed either to the end of the window or at the
17796 end of the window, i.e. the last row with text is to be found
17797 in the desired matrix. */
17798 wset_window_end_pos
17799 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
17800 w->window_end_bytepos
17801 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17802 wset_window_end_vpos
17803 (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
17804 eassert (w->window_end_bytepos >= 0);
17805 }
17806 else if (first_unchanged_at_end_row == NULL
17807 && last_text_row == NULL
17808 && last_text_row_at_end == NULL)
17809 {
17810 /* Displayed to end of window, but no line containing text was
17811 displayed. Lines were deleted at the end of the window. */
17812 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17813 int vpos = XFASTINT (w->window_end_vpos);
17814 struct glyph_row *current_row = current_matrix->rows + vpos;
17815 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17816
17817 for (row = NULL;
17818 row == NULL && vpos >= first_vpos;
17819 --vpos, --current_row, --desired_row)
17820 {
17821 if (desired_row->enabled_p)
17822 {
17823 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17824 row = desired_row;
17825 }
17826 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17827 row = current_row;
17828 }
17829
17830 eassert (row != NULL);
17831 wset_window_end_vpos (w, make_number (vpos + 1));
17832 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17833 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17834 eassert (w->window_end_bytepos >= 0);
17835 IF_DEBUG (debug_method_add (w, "C"));
17836 }
17837 else
17838 emacs_abort ();
17839
17840 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17841 debug_end_vpos = XFASTINT (w->window_end_vpos));
17842
17843 /* Record that display has not been completed. */
17844 w->window_end_valid = 0;
17845 w->desired_matrix->no_scrolling_p = 1;
17846 return 3;
17847
17848 #undef GIVE_UP
17849 }
17850
17851
17852 \f
17853 /***********************************************************************
17854 More debugging support
17855 ***********************************************************************/
17856
17857 #ifdef GLYPH_DEBUG
17858
17859 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17860 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17861 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17862
17863
17864 /* Dump the contents of glyph matrix MATRIX on stderr.
17865
17866 GLYPHS 0 means don't show glyph contents.
17867 GLYPHS 1 means show glyphs in short form
17868 GLYPHS > 1 means show glyphs in long form. */
17869
17870 void
17871 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17872 {
17873 int i;
17874 for (i = 0; i < matrix->nrows; ++i)
17875 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17876 }
17877
17878
17879 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17880 the glyph row and area where the glyph comes from. */
17881
17882 void
17883 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17884 {
17885 if (glyph->type == CHAR_GLYPH
17886 || glyph->type == GLYPHLESS_GLYPH)
17887 {
17888 fprintf (stderr,
17889 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17890 glyph - row->glyphs[TEXT_AREA],
17891 (glyph->type == CHAR_GLYPH
17892 ? 'C'
17893 : 'G'),
17894 glyph->charpos,
17895 (BUFFERP (glyph->object)
17896 ? 'B'
17897 : (STRINGP (glyph->object)
17898 ? 'S'
17899 : (INTEGERP (glyph->object)
17900 ? '0'
17901 : '-'))),
17902 glyph->pixel_width,
17903 glyph->u.ch,
17904 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17905 ? glyph->u.ch
17906 : '.'),
17907 glyph->face_id,
17908 glyph->left_box_line_p,
17909 glyph->right_box_line_p);
17910 }
17911 else if (glyph->type == STRETCH_GLYPH)
17912 {
17913 fprintf (stderr,
17914 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17915 glyph - row->glyphs[TEXT_AREA],
17916 'S',
17917 glyph->charpos,
17918 (BUFFERP (glyph->object)
17919 ? 'B'
17920 : (STRINGP (glyph->object)
17921 ? 'S'
17922 : (INTEGERP (glyph->object)
17923 ? '0'
17924 : '-'))),
17925 glyph->pixel_width,
17926 0,
17927 ' ',
17928 glyph->face_id,
17929 glyph->left_box_line_p,
17930 glyph->right_box_line_p);
17931 }
17932 else if (glyph->type == IMAGE_GLYPH)
17933 {
17934 fprintf (stderr,
17935 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17936 glyph - row->glyphs[TEXT_AREA],
17937 'I',
17938 glyph->charpos,
17939 (BUFFERP (glyph->object)
17940 ? 'B'
17941 : (STRINGP (glyph->object)
17942 ? 'S'
17943 : (INTEGERP (glyph->object)
17944 ? '0'
17945 : '-'))),
17946 glyph->pixel_width,
17947 glyph->u.img_id,
17948 '.',
17949 glyph->face_id,
17950 glyph->left_box_line_p,
17951 glyph->right_box_line_p);
17952 }
17953 else if (glyph->type == COMPOSITE_GLYPH)
17954 {
17955 fprintf (stderr,
17956 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17957 glyph - row->glyphs[TEXT_AREA],
17958 '+',
17959 glyph->charpos,
17960 (BUFFERP (glyph->object)
17961 ? 'B'
17962 : (STRINGP (glyph->object)
17963 ? 'S'
17964 : (INTEGERP (glyph->object)
17965 ? '0'
17966 : '-'))),
17967 glyph->pixel_width,
17968 glyph->u.cmp.id);
17969 if (glyph->u.cmp.automatic)
17970 fprintf (stderr,
17971 "[%d-%d]",
17972 glyph->slice.cmp.from, glyph->slice.cmp.to);
17973 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17974 glyph->face_id,
17975 glyph->left_box_line_p,
17976 glyph->right_box_line_p);
17977 }
17978 }
17979
17980
17981 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17982 GLYPHS 0 means don't show glyph contents.
17983 GLYPHS 1 means show glyphs in short form
17984 GLYPHS > 1 means show glyphs in long form. */
17985
17986 void
17987 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17988 {
17989 if (glyphs != 1)
17990 {
17991 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17992 fprintf (stderr, "==============================================================================\n");
17993
17994 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17995 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17996 vpos,
17997 MATRIX_ROW_START_CHARPOS (row),
17998 MATRIX_ROW_END_CHARPOS (row),
17999 row->used[TEXT_AREA],
18000 row->contains_overlapping_glyphs_p,
18001 row->enabled_p,
18002 row->truncated_on_left_p,
18003 row->truncated_on_right_p,
18004 row->continued_p,
18005 MATRIX_ROW_CONTINUATION_LINE_P (row),
18006 MATRIX_ROW_DISPLAYS_TEXT_P (row),
18007 row->ends_at_zv_p,
18008 row->fill_line_p,
18009 row->ends_in_middle_of_char_p,
18010 row->starts_in_middle_of_char_p,
18011 row->mouse_face_p,
18012 row->x,
18013 row->y,
18014 row->pixel_width,
18015 row->height,
18016 row->visible_height,
18017 row->ascent,
18018 row->phys_ascent);
18019 /* The next 3 lines should align to "Start" in the header. */
18020 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18021 row->end.overlay_string_index,
18022 row->continuation_lines_width);
18023 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18024 CHARPOS (row->start.string_pos),
18025 CHARPOS (row->end.string_pos));
18026 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18027 row->end.dpvec_index);
18028 }
18029
18030 if (glyphs > 1)
18031 {
18032 int area;
18033
18034 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18035 {
18036 struct glyph *glyph = row->glyphs[area];
18037 struct glyph *glyph_end = glyph + row->used[area];
18038
18039 /* Glyph for a line end in text. */
18040 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18041 ++glyph_end;
18042
18043 if (glyph < glyph_end)
18044 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18045
18046 for (; glyph < glyph_end; ++glyph)
18047 dump_glyph (row, glyph, area);
18048 }
18049 }
18050 else if (glyphs == 1)
18051 {
18052 int area;
18053
18054 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18055 {
18056 char *s = alloca (row->used[area] + 4);
18057 int i;
18058
18059 for (i = 0; i < row->used[area]; ++i)
18060 {
18061 struct glyph *glyph = row->glyphs[area] + i;
18062 if (i == row->used[area] - 1
18063 && area == TEXT_AREA
18064 && INTEGERP (glyph->object)
18065 && glyph->type == CHAR_GLYPH
18066 && glyph->u.ch == ' ')
18067 {
18068 strcpy (&s[i], "[\\n]");
18069 i += 4;
18070 }
18071 else if (glyph->type == CHAR_GLYPH
18072 && glyph->u.ch < 0x80
18073 && glyph->u.ch >= ' ')
18074 s[i] = glyph->u.ch;
18075 else
18076 s[i] = '.';
18077 }
18078
18079 s[i] = '\0';
18080 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18081 }
18082 }
18083 }
18084
18085
18086 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18087 Sdump_glyph_matrix, 0, 1, "p",
18088 doc: /* Dump the current matrix of the selected window to stderr.
18089 Shows contents of glyph row structures. With non-nil
18090 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18091 glyphs in short form, otherwise show glyphs in long form. */)
18092 (Lisp_Object glyphs)
18093 {
18094 struct window *w = XWINDOW (selected_window);
18095 struct buffer *buffer = XBUFFER (w->contents);
18096
18097 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18098 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18099 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18100 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18101 fprintf (stderr, "=============================================\n");
18102 dump_glyph_matrix (w->current_matrix,
18103 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18104 return Qnil;
18105 }
18106
18107
18108 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18109 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18110 (void)
18111 {
18112 struct frame *f = XFRAME (selected_frame);
18113 dump_glyph_matrix (f->current_matrix, 1);
18114 return Qnil;
18115 }
18116
18117
18118 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18119 doc: /* Dump glyph row ROW to stderr.
18120 GLYPH 0 means don't dump glyphs.
18121 GLYPH 1 means dump glyphs in short form.
18122 GLYPH > 1 or omitted means dump glyphs in long form. */)
18123 (Lisp_Object row, Lisp_Object glyphs)
18124 {
18125 struct glyph_matrix *matrix;
18126 EMACS_INT vpos;
18127
18128 CHECK_NUMBER (row);
18129 matrix = XWINDOW (selected_window)->current_matrix;
18130 vpos = XINT (row);
18131 if (vpos >= 0 && vpos < matrix->nrows)
18132 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18133 vpos,
18134 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18135 return Qnil;
18136 }
18137
18138
18139 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18140 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18141 GLYPH 0 means don't dump glyphs.
18142 GLYPH 1 means dump glyphs in short form.
18143 GLYPH > 1 or omitted means dump glyphs in long form. */)
18144 (Lisp_Object row, Lisp_Object glyphs)
18145 {
18146 struct frame *sf = SELECTED_FRAME ();
18147 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18148 EMACS_INT vpos;
18149
18150 CHECK_NUMBER (row);
18151 vpos = XINT (row);
18152 if (vpos >= 0 && vpos < m->nrows)
18153 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18154 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18155 return Qnil;
18156 }
18157
18158
18159 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18160 doc: /* Toggle tracing of redisplay.
18161 With ARG, turn tracing on if and only if ARG is positive. */)
18162 (Lisp_Object arg)
18163 {
18164 if (NILP (arg))
18165 trace_redisplay_p = !trace_redisplay_p;
18166 else
18167 {
18168 arg = Fprefix_numeric_value (arg);
18169 trace_redisplay_p = XINT (arg) > 0;
18170 }
18171
18172 return Qnil;
18173 }
18174
18175
18176 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18177 doc: /* Like `format', but print result to stderr.
18178 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18179 (ptrdiff_t nargs, Lisp_Object *args)
18180 {
18181 Lisp_Object s = Fformat (nargs, args);
18182 fprintf (stderr, "%s", SDATA (s));
18183 return Qnil;
18184 }
18185
18186 #endif /* GLYPH_DEBUG */
18187
18188
18189 \f
18190 /***********************************************************************
18191 Building Desired Matrix Rows
18192 ***********************************************************************/
18193
18194 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18195 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18196
18197 static struct glyph_row *
18198 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18199 {
18200 struct frame *f = XFRAME (WINDOW_FRAME (w));
18201 struct buffer *buffer = XBUFFER (w->contents);
18202 struct buffer *old = current_buffer;
18203 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18204 int arrow_len = SCHARS (overlay_arrow_string);
18205 const unsigned char *arrow_end = arrow_string + arrow_len;
18206 const unsigned char *p;
18207 struct it it;
18208 bool multibyte_p;
18209 int n_glyphs_before;
18210
18211 set_buffer_temp (buffer);
18212 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18213 it.glyph_row->used[TEXT_AREA] = 0;
18214 SET_TEXT_POS (it.position, 0, 0);
18215
18216 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18217 p = arrow_string;
18218 while (p < arrow_end)
18219 {
18220 Lisp_Object face, ilisp;
18221
18222 /* Get the next character. */
18223 if (multibyte_p)
18224 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18225 else
18226 {
18227 it.c = it.char_to_display = *p, it.len = 1;
18228 if (! ASCII_CHAR_P (it.c))
18229 it.char_to_display = BYTE8_TO_CHAR (it.c);
18230 }
18231 p += it.len;
18232
18233 /* Get its face. */
18234 ilisp = make_number (p - arrow_string);
18235 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18236 it.face_id = compute_char_face (f, it.char_to_display, face);
18237
18238 /* Compute its width, get its glyphs. */
18239 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18240 SET_TEXT_POS (it.position, -1, -1);
18241 PRODUCE_GLYPHS (&it);
18242
18243 /* If this character doesn't fit any more in the line, we have
18244 to remove some glyphs. */
18245 if (it.current_x > it.last_visible_x)
18246 {
18247 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18248 break;
18249 }
18250 }
18251
18252 set_buffer_temp (old);
18253 return it.glyph_row;
18254 }
18255
18256
18257 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18258 glyphs to insert is determined by produce_special_glyphs. */
18259
18260 static void
18261 insert_left_trunc_glyphs (struct it *it)
18262 {
18263 struct it truncate_it;
18264 struct glyph *from, *end, *to, *toend;
18265
18266 eassert (!FRAME_WINDOW_P (it->f)
18267 || (!it->glyph_row->reversed_p
18268 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18269 || (it->glyph_row->reversed_p
18270 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18271
18272 /* Get the truncation glyphs. */
18273 truncate_it = *it;
18274 truncate_it.current_x = 0;
18275 truncate_it.face_id = DEFAULT_FACE_ID;
18276 truncate_it.glyph_row = &scratch_glyph_row;
18277 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18278 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18279 truncate_it.object = make_number (0);
18280 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18281
18282 /* Overwrite glyphs from IT with truncation glyphs. */
18283 if (!it->glyph_row->reversed_p)
18284 {
18285 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18286
18287 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18288 end = from + tused;
18289 to = it->glyph_row->glyphs[TEXT_AREA];
18290 toend = to + it->glyph_row->used[TEXT_AREA];
18291 if (FRAME_WINDOW_P (it->f))
18292 {
18293 /* On GUI frames, when variable-size fonts are displayed,
18294 the truncation glyphs may need more pixels than the row's
18295 glyphs they overwrite. We overwrite more glyphs to free
18296 enough screen real estate, and enlarge the stretch glyph
18297 on the right (see display_line), if there is one, to
18298 preserve the screen position of the truncation glyphs on
18299 the right. */
18300 int w = 0;
18301 struct glyph *g = to;
18302 short used;
18303
18304 /* The first glyph could be partially visible, in which case
18305 it->glyph_row->x will be negative. But we want the left
18306 truncation glyphs to be aligned at the left margin of the
18307 window, so we override the x coordinate at which the row
18308 will begin. */
18309 it->glyph_row->x = 0;
18310 while (g < toend && w < it->truncation_pixel_width)
18311 {
18312 w += g->pixel_width;
18313 ++g;
18314 }
18315 if (g - to - tused > 0)
18316 {
18317 memmove (to + tused, g, (toend - g) * sizeof(*g));
18318 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18319 }
18320 used = it->glyph_row->used[TEXT_AREA];
18321 if (it->glyph_row->truncated_on_right_p
18322 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18323 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18324 == STRETCH_GLYPH)
18325 {
18326 int extra = w - it->truncation_pixel_width;
18327
18328 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18329 }
18330 }
18331
18332 while (from < end)
18333 *to++ = *from++;
18334
18335 /* There may be padding glyphs left over. Overwrite them too. */
18336 if (!FRAME_WINDOW_P (it->f))
18337 {
18338 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18339 {
18340 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18341 while (from < end)
18342 *to++ = *from++;
18343 }
18344 }
18345
18346 if (to > toend)
18347 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18348 }
18349 else
18350 {
18351 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18352
18353 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18354 that back to front. */
18355 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18356 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18357 toend = it->glyph_row->glyphs[TEXT_AREA];
18358 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18359 if (FRAME_WINDOW_P (it->f))
18360 {
18361 int w = 0;
18362 struct glyph *g = to;
18363
18364 while (g >= toend && w < it->truncation_pixel_width)
18365 {
18366 w += g->pixel_width;
18367 --g;
18368 }
18369 if (to - g - tused > 0)
18370 to = g + tused;
18371 if (it->glyph_row->truncated_on_right_p
18372 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18373 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18374 {
18375 int extra = w - it->truncation_pixel_width;
18376
18377 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18378 }
18379 }
18380
18381 while (from >= end && to >= toend)
18382 *to-- = *from--;
18383 if (!FRAME_WINDOW_P (it->f))
18384 {
18385 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18386 {
18387 from =
18388 truncate_it.glyph_row->glyphs[TEXT_AREA]
18389 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18390 while (from >= end && to >= toend)
18391 *to-- = *from--;
18392 }
18393 }
18394 if (from >= end)
18395 {
18396 /* Need to free some room before prepending additional
18397 glyphs. */
18398 int move_by = from - end + 1;
18399 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18400 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18401
18402 for ( ; g >= g0; g--)
18403 g[move_by] = *g;
18404 while (from >= end)
18405 *to-- = *from--;
18406 it->glyph_row->used[TEXT_AREA] += move_by;
18407 }
18408 }
18409 }
18410
18411 /* Compute the hash code for ROW. */
18412 unsigned
18413 row_hash (struct glyph_row *row)
18414 {
18415 int area, k;
18416 unsigned hashval = 0;
18417
18418 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18419 for (k = 0; k < row->used[area]; ++k)
18420 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18421 + row->glyphs[area][k].u.val
18422 + row->glyphs[area][k].face_id
18423 + row->glyphs[area][k].padding_p
18424 + (row->glyphs[area][k].type << 2));
18425
18426 return hashval;
18427 }
18428
18429 /* Compute the pixel height and width of IT->glyph_row.
18430
18431 Most of the time, ascent and height of a display line will be equal
18432 to the max_ascent and max_height values of the display iterator
18433 structure. This is not the case if
18434
18435 1. We hit ZV without displaying anything. In this case, max_ascent
18436 and max_height will be zero.
18437
18438 2. We have some glyphs that don't contribute to the line height.
18439 (The glyph row flag contributes_to_line_height_p is for future
18440 pixmap extensions).
18441
18442 The first case is easily covered by using default values because in
18443 these cases, the line height does not really matter, except that it
18444 must not be zero. */
18445
18446 static void
18447 compute_line_metrics (struct it *it)
18448 {
18449 struct glyph_row *row = it->glyph_row;
18450
18451 if (FRAME_WINDOW_P (it->f))
18452 {
18453 int i, min_y, max_y;
18454
18455 /* The line may consist of one space only, that was added to
18456 place the cursor on it. If so, the row's height hasn't been
18457 computed yet. */
18458 if (row->height == 0)
18459 {
18460 if (it->max_ascent + it->max_descent == 0)
18461 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18462 row->ascent = it->max_ascent;
18463 row->height = it->max_ascent + it->max_descent;
18464 row->phys_ascent = it->max_phys_ascent;
18465 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18466 row->extra_line_spacing = it->max_extra_line_spacing;
18467 }
18468
18469 /* Compute the width of this line. */
18470 row->pixel_width = row->x;
18471 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18472 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18473
18474 eassert (row->pixel_width >= 0);
18475 eassert (row->ascent >= 0 && row->height > 0);
18476
18477 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18478 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18479
18480 /* If first line's physical ascent is larger than its logical
18481 ascent, use the physical ascent, and make the row taller.
18482 This makes accented characters fully visible. */
18483 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18484 && row->phys_ascent > row->ascent)
18485 {
18486 row->height += row->phys_ascent - row->ascent;
18487 row->ascent = row->phys_ascent;
18488 }
18489
18490 /* Compute how much of the line is visible. */
18491 row->visible_height = row->height;
18492
18493 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18494 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18495
18496 if (row->y < min_y)
18497 row->visible_height -= min_y - row->y;
18498 if (row->y + row->height > max_y)
18499 row->visible_height -= row->y + row->height - max_y;
18500 }
18501 else
18502 {
18503 row->pixel_width = row->used[TEXT_AREA];
18504 if (row->continued_p)
18505 row->pixel_width -= it->continuation_pixel_width;
18506 else if (row->truncated_on_right_p)
18507 row->pixel_width -= it->truncation_pixel_width;
18508 row->ascent = row->phys_ascent = 0;
18509 row->height = row->phys_height = row->visible_height = 1;
18510 row->extra_line_spacing = 0;
18511 }
18512
18513 /* Compute a hash code for this row. */
18514 row->hash = row_hash (row);
18515
18516 it->max_ascent = it->max_descent = 0;
18517 it->max_phys_ascent = it->max_phys_descent = 0;
18518 }
18519
18520
18521 /* Append one space to the glyph row of iterator IT if doing a
18522 window-based redisplay. The space has the same face as
18523 IT->face_id. Value is non-zero if a space was added.
18524
18525 This function is called to make sure that there is always one glyph
18526 at the end of a glyph row that the cursor can be set on under
18527 window-systems. (If there weren't such a glyph we would not know
18528 how wide and tall a box cursor should be displayed).
18529
18530 At the same time this space let's a nicely handle clearing to the
18531 end of the line if the row ends in italic text. */
18532
18533 static int
18534 append_space_for_newline (struct it *it, int default_face_p)
18535 {
18536 if (FRAME_WINDOW_P (it->f))
18537 {
18538 int n = it->glyph_row->used[TEXT_AREA];
18539
18540 if (it->glyph_row->glyphs[TEXT_AREA] + n
18541 < it->glyph_row->glyphs[1 + TEXT_AREA])
18542 {
18543 /* Save some values that must not be changed.
18544 Must save IT->c and IT->len because otherwise
18545 ITERATOR_AT_END_P wouldn't work anymore after
18546 append_space_for_newline has been called. */
18547 enum display_element_type saved_what = it->what;
18548 int saved_c = it->c, saved_len = it->len;
18549 int saved_char_to_display = it->char_to_display;
18550 int saved_x = it->current_x;
18551 int saved_face_id = it->face_id;
18552 int saved_box_end = it->end_of_box_run_p;
18553 struct text_pos saved_pos;
18554 Lisp_Object saved_object;
18555 struct face *face;
18556
18557 saved_object = it->object;
18558 saved_pos = it->position;
18559
18560 it->what = IT_CHARACTER;
18561 memset (&it->position, 0, sizeof it->position);
18562 it->object = make_number (0);
18563 it->c = it->char_to_display = ' ';
18564 it->len = 1;
18565
18566 /* If the default face was remapped, be sure to use the
18567 remapped face for the appended newline. */
18568 if (default_face_p)
18569 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18570 else if (it->face_before_selective_p)
18571 it->face_id = it->saved_face_id;
18572 face = FACE_FROM_ID (it->f, it->face_id);
18573 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18574 /* In R2L rows, we will prepend a stretch glyph that will
18575 have the end_of_box_run_p flag set for it, so there's no
18576 need for the appended newline glyph to have that flag
18577 set. */
18578 if (it->glyph_row->reversed_p
18579 /* But if the appended newline glyph goes all the way to
18580 the end of the row, there will be no stretch glyph,
18581 so leave the box flag set. */
18582 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18583 it->end_of_box_run_p = 0;
18584
18585 PRODUCE_GLYPHS (it);
18586
18587 it->override_ascent = -1;
18588 it->constrain_row_ascent_descent_p = 0;
18589 it->current_x = saved_x;
18590 it->object = saved_object;
18591 it->position = saved_pos;
18592 it->what = saved_what;
18593 it->face_id = saved_face_id;
18594 it->len = saved_len;
18595 it->c = saved_c;
18596 it->char_to_display = saved_char_to_display;
18597 it->end_of_box_run_p = saved_box_end;
18598 return 1;
18599 }
18600 }
18601
18602 return 0;
18603 }
18604
18605
18606 /* Extend the face of the last glyph in the text area of IT->glyph_row
18607 to the end of the display line. Called from display_line. If the
18608 glyph row is empty, add a space glyph to it so that we know the
18609 face to draw. Set the glyph row flag fill_line_p. If the glyph
18610 row is R2L, prepend a stretch glyph to cover the empty space to the
18611 left of the leftmost glyph. */
18612
18613 static void
18614 extend_face_to_end_of_line (struct it *it)
18615 {
18616 struct face *face, *default_face;
18617 struct frame *f = it->f;
18618
18619 /* If line is already filled, do nothing. Non window-system frames
18620 get a grace of one more ``pixel'' because their characters are
18621 1-``pixel'' wide, so they hit the equality too early. This grace
18622 is needed only for R2L rows that are not continued, to produce
18623 one extra blank where we could display the cursor. */
18624 if (it->current_x >= it->last_visible_x
18625 + (!FRAME_WINDOW_P (f)
18626 && it->glyph_row->reversed_p
18627 && !it->glyph_row->continued_p))
18628 return;
18629
18630 /* The default face, possibly remapped. */
18631 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18632
18633 /* Face extension extends the background and box of IT->face_id
18634 to the end of the line. If the background equals the background
18635 of the frame, we don't have to do anything. */
18636 if (it->face_before_selective_p)
18637 face = FACE_FROM_ID (f, it->saved_face_id);
18638 else
18639 face = FACE_FROM_ID (f, it->face_id);
18640
18641 if (FRAME_WINDOW_P (f)
18642 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18643 && face->box == FACE_NO_BOX
18644 && face->background == FRAME_BACKGROUND_PIXEL (f)
18645 && !face->stipple
18646 && !it->glyph_row->reversed_p)
18647 return;
18648
18649 /* Set the glyph row flag indicating that the face of the last glyph
18650 in the text area has to be drawn to the end of the text area. */
18651 it->glyph_row->fill_line_p = 1;
18652
18653 /* If current character of IT is not ASCII, make sure we have the
18654 ASCII face. This will be automatically undone the next time
18655 get_next_display_element returns a multibyte character. Note
18656 that the character will always be single byte in unibyte
18657 text. */
18658 if (!ASCII_CHAR_P (it->c))
18659 {
18660 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18661 }
18662
18663 if (FRAME_WINDOW_P (f))
18664 {
18665 /* If the row is empty, add a space with the current face of IT,
18666 so that we know which face to draw. */
18667 if (it->glyph_row->used[TEXT_AREA] == 0)
18668 {
18669 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18670 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18671 it->glyph_row->used[TEXT_AREA] = 1;
18672 }
18673 #ifdef HAVE_WINDOW_SYSTEM
18674 if (it->glyph_row->reversed_p)
18675 {
18676 /* Prepend a stretch glyph to the row, such that the
18677 rightmost glyph will be drawn flushed all the way to the
18678 right margin of the window. The stretch glyph that will
18679 occupy the empty space, if any, to the left of the
18680 glyphs. */
18681 struct font *font = face->font ? face->font : FRAME_FONT (f);
18682 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18683 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18684 struct glyph *g;
18685 int row_width, stretch_ascent, stretch_width;
18686 struct text_pos saved_pos;
18687 int saved_face_id, saved_avoid_cursor, saved_box_start;
18688
18689 for (row_width = 0, g = row_start; g < row_end; g++)
18690 row_width += g->pixel_width;
18691 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18692 if (stretch_width > 0)
18693 {
18694 stretch_ascent =
18695 (((it->ascent + it->descent)
18696 * FONT_BASE (font)) / FONT_HEIGHT (font));
18697 saved_pos = it->position;
18698 memset (&it->position, 0, sizeof it->position);
18699 saved_avoid_cursor = it->avoid_cursor_p;
18700 it->avoid_cursor_p = 1;
18701 saved_face_id = it->face_id;
18702 saved_box_start = it->start_of_box_run_p;
18703 /* The last row's stretch glyph should get the default
18704 face, to avoid painting the rest of the window with
18705 the region face, if the region ends at ZV. */
18706 if (it->glyph_row->ends_at_zv_p)
18707 it->face_id = default_face->id;
18708 else
18709 it->face_id = face->id;
18710 it->start_of_box_run_p = 0;
18711 append_stretch_glyph (it, make_number (0), stretch_width,
18712 it->ascent + it->descent, stretch_ascent);
18713 it->position = saved_pos;
18714 it->avoid_cursor_p = saved_avoid_cursor;
18715 it->face_id = saved_face_id;
18716 it->start_of_box_run_p = saved_box_start;
18717 }
18718 }
18719 #endif /* HAVE_WINDOW_SYSTEM */
18720 }
18721 else
18722 {
18723 /* Save some values that must not be changed. */
18724 int saved_x = it->current_x;
18725 struct text_pos saved_pos;
18726 Lisp_Object saved_object;
18727 enum display_element_type saved_what = it->what;
18728 int saved_face_id = it->face_id;
18729
18730 saved_object = it->object;
18731 saved_pos = it->position;
18732
18733 it->what = IT_CHARACTER;
18734 memset (&it->position, 0, sizeof it->position);
18735 it->object = make_number (0);
18736 it->c = it->char_to_display = ' ';
18737 it->len = 1;
18738 /* The last row's blank glyphs should get the default face, to
18739 avoid painting the rest of the window with the region face,
18740 if the region ends at ZV. */
18741 if (it->glyph_row->ends_at_zv_p)
18742 it->face_id = default_face->id;
18743 else
18744 it->face_id = face->id;
18745
18746 PRODUCE_GLYPHS (it);
18747
18748 while (it->current_x <= it->last_visible_x)
18749 PRODUCE_GLYPHS (it);
18750
18751 /* Don't count these blanks really. It would let us insert a left
18752 truncation glyph below and make us set the cursor on them, maybe. */
18753 it->current_x = saved_x;
18754 it->object = saved_object;
18755 it->position = saved_pos;
18756 it->what = saved_what;
18757 it->face_id = saved_face_id;
18758 }
18759 }
18760
18761
18762 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18763 trailing whitespace. */
18764
18765 static int
18766 trailing_whitespace_p (ptrdiff_t charpos)
18767 {
18768 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18769 int c = 0;
18770
18771 while (bytepos < ZV_BYTE
18772 && (c = FETCH_CHAR (bytepos),
18773 c == ' ' || c == '\t'))
18774 ++bytepos;
18775
18776 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18777 {
18778 if (bytepos != PT_BYTE)
18779 return 1;
18780 }
18781 return 0;
18782 }
18783
18784
18785 /* Highlight trailing whitespace, if any, in ROW. */
18786
18787 static void
18788 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18789 {
18790 int used = row->used[TEXT_AREA];
18791
18792 if (used)
18793 {
18794 struct glyph *start = row->glyphs[TEXT_AREA];
18795 struct glyph *glyph = start + used - 1;
18796
18797 if (row->reversed_p)
18798 {
18799 /* Right-to-left rows need to be processed in the opposite
18800 direction, so swap the edge pointers. */
18801 glyph = start;
18802 start = row->glyphs[TEXT_AREA] + used - 1;
18803 }
18804
18805 /* Skip over glyphs inserted to display the cursor at the
18806 end of a line, for extending the face of the last glyph
18807 to the end of the line on terminals, and for truncation
18808 and continuation glyphs. */
18809 if (!row->reversed_p)
18810 {
18811 while (glyph >= start
18812 && glyph->type == CHAR_GLYPH
18813 && INTEGERP (glyph->object))
18814 --glyph;
18815 }
18816 else
18817 {
18818 while (glyph <= start
18819 && glyph->type == CHAR_GLYPH
18820 && INTEGERP (glyph->object))
18821 ++glyph;
18822 }
18823
18824 /* If last glyph is a space or stretch, and it's trailing
18825 whitespace, set the face of all trailing whitespace glyphs in
18826 IT->glyph_row to `trailing-whitespace'. */
18827 if ((row->reversed_p ? glyph <= start : glyph >= start)
18828 && BUFFERP (glyph->object)
18829 && (glyph->type == STRETCH_GLYPH
18830 || (glyph->type == CHAR_GLYPH
18831 && glyph->u.ch == ' '))
18832 && trailing_whitespace_p (glyph->charpos))
18833 {
18834 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18835 if (face_id < 0)
18836 return;
18837
18838 if (!row->reversed_p)
18839 {
18840 while (glyph >= start
18841 && BUFFERP (glyph->object)
18842 && (glyph->type == STRETCH_GLYPH
18843 || (glyph->type == CHAR_GLYPH
18844 && glyph->u.ch == ' ')))
18845 (glyph--)->face_id = face_id;
18846 }
18847 else
18848 {
18849 while (glyph <= start
18850 && BUFFERP (glyph->object)
18851 && (glyph->type == STRETCH_GLYPH
18852 || (glyph->type == CHAR_GLYPH
18853 && glyph->u.ch == ' ')))
18854 (glyph++)->face_id = face_id;
18855 }
18856 }
18857 }
18858 }
18859
18860
18861 /* Value is non-zero if glyph row ROW should be
18862 considered to hold the buffer position CHARPOS. */
18863
18864 static int
18865 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18866 {
18867 int result = 1;
18868
18869 if (charpos == CHARPOS (row->end.pos)
18870 || charpos == MATRIX_ROW_END_CHARPOS (row))
18871 {
18872 /* Suppose the row ends on a string.
18873 Unless the row is continued, that means it ends on a newline
18874 in the string. If it's anything other than a display string
18875 (e.g., a before-string from an overlay), we don't want the
18876 cursor there. (This heuristic seems to give the optimal
18877 behavior for the various types of multi-line strings.)
18878 One exception: if the string has `cursor' property on one of
18879 its characters, we _do_ want the cursor there. */
18880 if (CHARPOS (row->end.string_pos) >= 0)
18881 {
18882 if (row->continued_p)
18883 result = 1;
18884 else
18885 {
18886 /* Check for `display' property. */
18887 struct glyph *beg = row->glyphs[TEXT_AREA];
18888 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18889 struct glyph *glyph;
18890
18891 result = 0;
18892 for (glyph = end; glyph >= beg; --glyph)
18893 if (STRINGP (glyph->object))
18894 {
18895 Lisp_Object prop
18896 = Fget_char_property (make_number (charpos),
18897 Qdisplay, Qnil);
18898 result =
18899 (!NILP (prop)
18900 && display_prop_string_p (prop, glyph->object));
18901 /* If there's a `cursor' property on one of the
18902 string's characters, this row is a cursor row,
18903 even though this is not a display string. */
18904 if (!result)
18905 {
18906 Lisp_Object s = glyph->object;
18907
18908 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18909 {
18910 ptrdiff_t gpos = glyph->charpos;
18911
18912 if (!NILP (Fget_char_property (make_number (gpos),
18913 Qcursor, s)))
18914 {
18915 result = 1;
18916 break;
18917 }
18918 }
18919 }
18920 break;
18921 }
18922 }
18923 }
18924 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18925 {
18926 /* If the row ends in middle of a real character,
18927 and the line is continued, we want the cursor here.
18928 That's because CHARPOS (ROW->end.pos) would equal
18929 PT if PT is before the character. */
18930 if (!row->ends_in_ellipsis_p)
18931 result = row->continued_p;
18932 else
18933 /* If the row ends in an ellipsis, then
18934 CHARPOS (ROW->end.pos) will equal point after the
18935 invisible text. We want that position to be displayed
18936 after the ellipsis. */
18937 result = 0;
18938 }
18939 /* If the row ends at ZV, display the cursor at the end of that
18940 row instead of at the start of the row below. */
18941 else if (row->ends_at_zv_p)
18942 result = 1;
18943 else
18944 result = 0;
18945 }
18946
18947 return result;
18948 }
18949
18950 /* Value is non-zero if glyph row ROW should be
18951 used to hold the cursor. */
18952
18953 static int
18954 cursor_row_p (struct glyph_row *row)
18955 {
18956 return row_for_charpos_p (row, PT);
18957 }
18958
18959 \f
18960
18961 /* Push the property PROP so that it will be rendered at the current
18962 position in IT. Return 1 if PROP was successfully pushed, 0
18963 otherwise. Called from handle_line_prefix to handle the
18964 `line-prefix' and `wrap-prefix' properties. */
18965
18966 static int
18967 push_prefix_prop (struct it *it, Lisp_Object prop)
18968 {
18969 struct text_pos pos =
18970 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18971
18972 eassert (it->method == GET_FROM_BUFFER
18973 || it->method == GET_FROM_DISPLAY_VECTOR
18974 || it->method == GET_FROM_STRING);
18975
18976 /* We need to save the current buffer/string position, so it will be
18977 restored by pop_it, because iterate_out_of_display_property
18978 depends on that being set correctly, but some situations leave
18979 it->position not yet set when this function is called. */
18980 push_it (it, &pos);
18981
18982 if (STRINGP (prop))
18983 {
18984 if (SCHARS (prop) == 0)
18985 {
18986 pop_it (it);
18987 return 0;
18988 }
18989
18990 it->string = prop;
18991 it->string_from_prefix_prop_p = 1;
18992 it->multibyte_p = STRING_MULTIBYTE (it->string);
18993 it->current.overlay_string_index = -1;
18994 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18995 it->end_charpos = it->string_nchars = SCHARS (it->string);
18996 it->method = GET_FROM_STRING;
18997 it->stop_charpos = 0;
18998 it->prev_stop = 0;
18999 it->base_level_stop = 0;
19000
19001 /* Force paragraph direction to be that of the parent
19002 buffer/string. */
19003 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19004 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19005 else
19006 it->paragraph_embedding = L2R;
19007
19008 /* Set up the bidi iterator for this display string. */
19009 if (it->bidi_p)
19010 {
19011 it->bidi_it.string.lstring = it->string;
19012 it->bidi_it.string.s = NULL;
19013 it->bidi_it.string.schars = it->end_charpos;
19014 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19015 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19016 it->bidi_it.string.unibyte = !it->multibyte_p;
19017 it->bidi_it.w = it->w;
19018 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19019 }
19020 }
19021 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19022 {
19023 it->method = GET_FROM_STRETCH;
19024 it->object = prop;
19025 }
19026 #ifdef HAVE_WINDOW_SYSTEM
19027 else if (IMAGEP (prop))
19028 {
19029 it->what = IT_IMAGE;
19030 it->image_id = lookup_image (it->f, prop);
19031 it->method = GET_FROM_IMAGE;
19032 }
19033 #endif /* HAVE_WINDOW_SYSTEM */
19034 else
19035 {
19036 pop_it (it); /* bogus display property, give up */
19037 return 0;
19038 }
19039
19040 return 1;
19041 }
19042
19043 /* Return the character-property PROP at the current position in IT. */
19044
19045 static Lisp_Object
19046 get_it_property (struct it *it, Lisp_Object prop)
19047 {
19048 Lisp_Object position, object = it->object;
19049
19050 if (STRINGP (object))
19051 position = make_number (IT_STRING_CHARPOS (*it));
19052 else if (BUFFERP (object))
19053 {
19054 position = make_number (IT_CHARPOS (*it));
19055 object = it->window;
19056 }
19057 else
19058 return Qnil;
19059
19060 return Fget_char_property (position, prop, object);
19061 }
19062
19063 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19064
19065 static void
19066 handle_line_prefix (struct it *it)
19067 {
19068 Lisp_Object prefix;
19069
19070 if (it->continuation_lines_width > 0)
19071 {
19072 prefix = get_it_property (it, Qwrap_prefix);
19073 if (NILP (prefix))
19074 prefix = Vwrap_prefix;
19075 }
19076 else
19077 {
19078 prefix = get_it_property (it, Qline_prefix);
19079 if (NILP (prefix))
19080 prefix = Vline_prefix;
19081 }
19082 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19083 {
19084 /* If the prefix is wider than the window, and we try to wrap
19085 it, it would acquire its own wrap prefix, and so on till the
19086 iterator stack overflows. So, don't wrap the prefix. */
19087 it->line_wrap = TRUNCATE;
19088 it->avoid_cursor_p = 1;
19089 }
19090 }
19091
19092 \f
19093
19094 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19095 only for R2L lines from display_line and display_string, when they
19096 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19097 the line/string needs to be continued on the next glyph row. */
19098 static void
19099 unproduce_glyphs (struct it *it, int n)
19100 {
19101 struct glyph *glyph, *end;
19102
19103 eassert (it->glyph_row);
19104 eassert (it->glyph_row->reversed_p);
19105 eassert (it->area == TEXT_AREA);
19106 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19107
19108 if (n > it->glyph_row->used[TEXT_AREA])
19109 n = it->glyph_row->used[TEXT_AREA];
19110 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19111 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19112 for ( ; glyph < end; glyph++)
19113 glyph[-n] = *glyph;
19114 }
19115
19116 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19117 and ROW->maxpos. */
19118 static void
19119 find_row_edges (struct it *it, struct glyph_row *row,
19120 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19121 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19122 {
19123 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19124 lines' rows is implemented for bidi-reordered rows. */
19125
19126 /* ROW->minpos is the value of min_pos, the minimal buffer position
19127 we have in ROW, or ROW->start.pos if that is smaller. */
19128 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19129 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19130 else
19131 /* We didn't find buffer positions smaller than ROW->start, or
19132 didn't find _any_ valid buffer positions in any of the glyphs,
19133 so we must trust the iterator's computed positions. */
19134 row->minpos = row->start.pos;
19135 if (max_pos <= 0)
19136 {
19137 max_pos = CHARPOS (it->current.pos);
19138 max_bpos = BYTEPOS (it->current.pos);
19139 }
19140
19141 /* Here are the various use-cases for ending the row, and the
19142 corresponding values for ROW->maxpos:
19143
19144 Line ends in a newline from buffer eol_pos + 1
19145 Line is continued from buffer max_pos + 1
19146 Line is truncated on right it->current.pos
19147 Line ends in a newline from string max_pos + 1(*)
19148 (*) + 1 only when line ends in a forward scan
19149 Line is continued from string max_pos
19150 Line is continued from display vector max_pos
19151 Line is entirely from a string min_pos == max_pos
19152 Line is entirely from a display vector min_pos == max_pos
19153 Line that ends at ZV ZV
19154
19155 If you discover other use-cases, please add them here as
19156 appropriate. */
19157 if (row->ends_at_zv_p)
19158 row->maxpos = it->current.pos;
19159 else if (row->used[TEXT_AREA])
19160 {
19161 int seen_this_string = 0;
19162 struct glyph_row *r1 = row - 1;
19163
19164 /* Did we see the same display string on the previous row? */
19165 if (STRINGP (it->object)
19166 /* this is not the first row */
19167 && row > it->w->desired_matrix->rows
19168 /* previous row is not the header line */
19169 && !r1->mode_line_p
19170 /* previous row also ends in a newline from a string */
19171 && r1->ends_in_newline_from_string_p)
19172 {
19173 struct glyph *start, *end;
19174
19175 /* Search for the last glyph of the previous row that came
19176 from buffer or string. Depending on whether the row is
19177 L2R or R2L, we need to process it front to back or the
19178 other way round. */
19179 if (!r1->reversed_p)
19180 {
19181 start = r1->glyphs[TEXT_AREA];
19182 end = start + r1->used[TEXT_AREA];
19183 /* Glyphs inserted by redisplay have an integer (zero)
19184 as their object. */
19185 while (end > start
19186 && INTEGERP ((end - 1)->object)
19187 && (end - 1)->charpos <= 0)
19188 --end;
19189 if (end > start)
19190 {
19191 if (EQ ((end - 1)->object, it->object))
19192 seen_this_string = 1;
19193 }
19194 else
19195 /* If all the glyphs of the previous row were inserted
19196 by redisplay, it means the previous row was
19197 produced from a single newline, which is only
19198 possible if that newline came from the same string
19199 as the one which produced this ROW. */
19200 seen_this_string = 1;
19201 }
19202 else
19203 {
19204 end = r1->glyphs[TEXT_AREA] - 1;
19205 start = end + r1->used[TEXT_AREA];
19206 while (end < start
19207 && INTEGERP ((end + 1)->object)
19208 && (end + 1)->charpos <= 0)
19209 ++end;
19210 if (end < start)
19211 {
19212 if (EQ ((end + 1)->object, it->object))
19213 seen_this_string = 1;
19214 }
19215 else
19216 seen_this_string = 1;
19217 }
19218 }
19219 /* Take note of each display string that covers a newline only
19220 once, the first time we see it. This is for when a display
19221 string includes more than one newline in it. */
19222 if (row->ends_in_newline_from_string_p && !seen_this_string)
19223 {
19224 /* If we were scanning the buffer forward when we displayed
19225 the string, we want to account for at least one buffer
19226 position that belongs to this row (position covered by
19227 the display string), so that cursor positioning will
19228 consider this row as a candidate when point is at the end
19229 of the visual line represented by this row. This is not
19230 required when scanning back, because max_pos will already
19231 have a much larger value. */
19232 if (CHARPOS (row->end.pos) > max_pos)
19233 INC_BOTH (max_pos, max_bpos);
19234 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19235 }
19236 else if (CHARPOS (it->eol_pos) > 0)
19237 SET_TEXT_POS (row->maxpos,
19238 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19239 else if (row->continued_p)
19240 {
19241 /* If max_pos is different from IT's current position, it
19242 means IT->method does not belong to the display element
19243 at max_pos. However, it also means that the display
19244 element at max_pos was displayed in its entirety on this
19245 line, which is equivalent to saying that the next line
19246 starts at the next buffer position. */
19247 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19248 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19249 else
19250 {
19251 INC_BOTH (max_pos, max_bpos);
19252 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19253 }
19254 }
19255 else if (row->truncated_on_right_p)
19256 /* display_line already called reseat_at_next_visible_line_start,
19257 which puts the iterator at the beginning of the next line, in
19258 the logical order. */
19259 row->maxpos = it->current.pos;
19260 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19261 /* A line that is entirely from a string/image/stretch... */
19262 row->maxpos = row->minpos;
19263 else
19264 emacs_abort ();
19265 }
19266 else
19267 row->maxpos = it->current.pos;
19268 }
19269
19270 /* Construct the glyph row IT->glyph_row in the desired matrix of
19271 IT->w from text at the current position of IT. See dispextern.h
19272 for an overview of struct it. Value is non-zero if
19273 IT->glyph_row displays text, as opposed to a line displaying ZV
19274 only. */
19275
19276 static int
19277 display_line (struct it *it)
19278 {
19279 struct glyph_row *row = it->glyph_row;
19280 Lisp_Object overlay_arrow_string;
19281 struct it wrap_it;
19282 void *wrap_data = NULL;
19283 int may_wrap = 0, wrap_x IF_LINT (= 0);
19284 int wrap_row_used = -1;
19285 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19286 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19287 int wrap_row_extra_line_spacing IF_LINT (= 0);
19288 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19289 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19290 int cvpos;
19291 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19292 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19293
19294 /* We always start displaying at hpos zero even if hscrolled. */
19295 eassert (it->hpos == 0 && it->current_x == 0);
19296
19297 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19298 >= it->w->desired_matrix->nrows)
19299 {
19300 it->w->nrows_scale_factor++;
19301 fonts_changed_p = 1;
19302 return 0;
19303 }
19304
19305 /* Is IT->w showing the region? */
19306 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19307
19308 /* Clear the result glyph row and enable it. */
19309 prepare_desired_row (row);
19310
19311 row->y = it->current_y;
19312 row->start = it->start;
19313 row->continuation_lines_width = it->continuation_lines_width;
19314 row->displays_text_p = 1;
19315 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19316 it->starts_in_middle_of_char_p = 0;
19317
19318 /* Arrange the overlays nicely for our purposes. Usually, we call
19319 display_line on only one line at a time, in which case this
19320 can't really hurt too much, or we call it on lines which appear
19321 one after another in the buffer, in which case all calls to
19322 recenter_overlay_lists but the first will be pretty cheap. */
19323 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19324
19325 /* Move over display elements that are not visible because we are
19326 hscrolled. This may stop at an x-position < IT->first_visible_x
19327 if the first glyph is partially visible or if we hit a line end. */
19328 if (it->current_x < it->first_visible_x)
19329 {
19330 enum move_it_result move_result;
19331
19332 this_line_min_pos = row->start.pos;
19333 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19334 MOVE_TO_POS | MOVE_TO_X);
19335 /* If we are under a large hscroll, move_it_in_display_line_to
19336 could hit the end of the line without reaching
19337 it->first_visible_x. Pretend that we did reach it. This is
19338 especially important on a TTY, where we will call
19339 extend_face_to_end_of_line, which needs to know how many
19340 blank glyphs to produce. */
19341 if (it->current_x < it->first_visible_x
19342 && (move_result == MOVE_NEWLINE_OR_CR
19343 || move_result == MOVE_POS_MATCH_OR_ZV))
19344 it->current_x = it->first_visible_x;
19345
19346 /* Record the smallest positions seen while we moved over
19347 display elements that are not visible. This is needed by
19348 redisplay_internal for optimizing the case where the cursor
19349 stays inside the same line. The rest of this function only
19350 considers positions that are actually displayed, so
19351 RECORD_MAX_MIN_POS will not otherwise record positions that
19352 are hscrolled to the left of the left edge of the window. */
19353 min_pos = CHARPOS (this_line_min_pos);
19354 min_bpos = BYTEPOS (this_line_min_pos);
19355 }
19356 else
19357 {
19358 /* We only do this when not calling `move_it_in_display_line_to'
19359 above, because move_it_in_display_line_to calls
19360 handle_line_prefix itself. */
19361 handle_line_prefix (it);
19362 }
19363
19364 /* Get the initial row height. This is either the height of the
19365 text hscrolled, if there is any, or zero. */
19366 row->ascent = it->max_ascent;
19367 row->height = it->max_ascent + it->max_descent;
19368 row->phys_ascent = it->max_phys_ascent;
19369 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19370 row->extra_line_spacing = it->max_extra_line_spacing;
19371
19372 /* Utility macro to record max and min buffer positions seen until now. */
19373 #define RECORD_MAX_MIN_POS(IT) \
19374 do \
19375 { \
19376 int composition_p = !STRINGP ((IT)->string) \
19377 && ((IT)->what == IT_COMPOSITION); \
19378 ptrdiff_t current_pos = \
19379 composition_p ? (IT)->cmp_it.charpos \
19380 : IT_CHARPOS (*(IT)); \
19381 ptrdiff_t current_bpos = \
19382 composition_p ? CHAR_TO_BYTE (current_pos) \
19383 : IT_BYTEPOS (*(IT)); \
19384 if (current_pos < min_pos) \
19385 { \
19386 min_pos = current_pos; \
19387 min_bpos = current_bpos; \
19388 } \
19389 if (IT_CHARPOS (*it) > max_pos) \
19390 { \
19391 max_pos = IT_CHARPOS (*it); \
19392 max_bpos = IT_BYTEPOS (*it); \
19393 } \
19394 } \
19395 while (0)
19396
19397 /* Loop generating characters. The loop is left with IT on the next
19398 character to display. */
19399 while (1)
19400 {
19401 int n_glyphs_before, hpos_before, x_before;
19402 int x, nglyphs;
19403 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19404
19405 /* Retrieve the next thing to display. Value is zero if end of
19406 buffer reached. */
19407 if (!get_next_display_element (it))
19408 {
19409 /* Maybe add a space at the end of this line that is used to
19410 display the cursor there under X. Set the charpos of the
19411 first glyph of blank lines not corresponding to any text
19412 to -1. */
19413 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19414 row->exact_window_width_line_p = 1;
19415 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19416 || row->used[TEXT_AREA] == 0)
19417 {
19418 row->glyphs[TEXT_AREA]->charpos = -1;
19419 row->displays_text_p = 0;
19420
19421 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19422 && (!MINI_WINDOW_P (it->w)
19423 || (minibuf_level && EQ (it->window, minibuf_window))))
19424 row->indicate_empty_line_p = 1;
19425 }
19426
19427 it->continuation_lines_width = 0;
19428 row->ends_at_zv_p = 1;
19429 /* A row that displays right-to-left text must always have
19430 its last face extended all the way to the end of line,
19431 even if this row ends in ZV, because we still write to
19432 the screen left to right. We also need to extend the
19433 last face if the default face is remapped to some
19434 different face, otherwise the functions that clear
19435 portions of the screen will clear with the default face's
19436 background color. */
19437 if (row->reversed_p
19438 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19439 extend_face_to_end_of_line (it);
19440 break;
19441 }
19442
19443 /* Now, get the metrics of what we want to display. This also
19444 generates glyphs in `row' (which is IT->glyph_row). */
19445 n_glyphs_before = row->used[TEXT_AREA];
19446 x = it->current_x;
19447
19448 /* Remember the line height so far in case the next element doesn't
19449 fit on the line. */
19450 if (it->line_wrap != TRUNCATE)
19451 {
19452 ascent = it->max_ascent;
19453 descent = it->max_descent;
19454 phys_ascent = it->max_phys_ascent;
19455 phys_descent = it->max_phys_descent;
19456
19457 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19458 {
19459 if (IT_DISPLAYING_WHITESPACE (it))
19460 may_wrap = 1;
19461 else if (may_wrap)
19462 {
19463 SAVE_IT (wrap_it, *it, wrap_data);
19464 wrap_x = x;
19465 wrap_row_used = row->used[TEXT_AREA];
19466 wrap_row_ascent = row->ascent;
19467 wrap_row_height = row->height;
19468 wrap_row_phys_ascent = row->phys_ascent;
19469 wrap_row_phys_height = row->phys_height;
19470 wrap_row_extra_line_spacing = row->extra_line_spacing;
19471 wrap_row_min_pos = min_pos;
19472 wrap_row_min_bpos = min_bpos;
19473 wrap_row_max_pos = max_pos;
19474 wrap_row_max_bpos = max_bpos;
19475 may_wrap = 0;
19476 }
19477 }
19478 }
19479
19480 PRODUCE_GLYPHS (it);
19481
19482 /* If this display element was in marginal areas, continue with
19483 the next one. */
19484 if (it->area != TEXT_AREA)
19485 {
19486 row->ascent = max (row->ascent, it->max_ascent);
19487 row->height = max (row->height, it->max_ascent + it->max_descent);
19488 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19489 row->phys_height = max (row->phys_height,
19490 it->max_phys_ascent + it->max_phys_descent);
19491 row->extra_line_spacing = max (row->extra_line_spacing,
19492 it->max_extra_line_spacing);
19493 set_iterator_to_next (it, 1);
19494 continue;
19495 }
19496
19497 /* Does the display element fit on the line? If we truncate
19498 lines, we should draw past the right edge of the window. If
19499 we don't truncate, we want to stop so that we can display the
19500 continuation glyph before the right margin. If lines are
19501 continued, there are two possible strategies for characters
19502 resulting in more than 1 glyph (e.g. tabs): Display as many
19503 glyphs as possible in this line and leave the rest for the
19504 continuation line, or display the whole element in the next
19505 line. Original redisplay did the former, so we do it also. */
19506 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19507 hpos_before = it->hpos;
19508 x_before = x;
19509
19510 if (/* Not a newline. */
19511 nglyphs > 0
19512 /* Glyphs produced fit entirely in the line. */
19513 && it->current_x < it->last_visible_x)
19514 {
19515 it->hpos += nglyphs;
19516 row->ascent = max (row->ascent, it->max_ascent);
19517 row->height = max (row->height, it->max_ascent + it->max_descent);
19518 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19519 row->phys_height = max (row->phys_height,
19520 it->max_phys_ascent + it->max_phys_descent);
19521 row->extra_line_spacing = max (row->extra_line_spacing,
19522 it->max_extra_line_spacing);
19523 if (it->current_x - it->pixel_width < it->first_visible_x)
19524 row->x = x - it->first_visible_x;
19525 /* Record the maximum and minimum buffer positions seen so
19526 far in glyphs that will be displayed by this row. */
19527 if (it->bidi_p)
19528 RECORD_MAX_MIN_POS (it);
19529 }
19530 else
19531 {
19532 int i, new_x;
19533 struct glyph *glyph;
19534
19535 for (i = 0; i < nglyphs; ++i, x = new_x)
19536 {
19537 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19538 new_x = x + glyph->pixel_width;
19539
19540 if (/* Lines are continued. */
19541 it->line_wrap != TRUNCATE
19542 && (/* Glyph doesn't fit on the line. */
19543 new_x > it->last_visible_x
19544 /* Or it fits exactly on a window system frame. */
19545 || (new_x == it->last_visible_x
19546 && FRAME_WINDOW_P (it->f)
19547 && (row->reversed_p
19548 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19549 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19550 {
19551 /* End of a continued line. */
19552
19553 if (it->hpos == 0
19554 || (new_x == it->last_visible_x
19555 && FRAME_WINDOW_P (it->f)
19556 && (row->reversed_p
19557 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19558 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19559 {
19560 /* Current glyph is the only one on the line or
19561 fits exactly on the line. We must continue
19562 the line because we can't draw the cursor
19563 after the glyph. */
19564 row->continued_p = 1;
19565 it->current_x = new_x;
19566 it->continuation_lines_width += new_x;
19567 ++it->hpos;
19568 if (i == nglyphs - 1)
19569 {
19570 /* If line-wrap is on, check if a previous
19571 wrap point was found. */
19572 if (wrap_row_used > 0
19573 /* Even if there is a previous wrap
19574 point, continue the line here as
19575 usual, if (i) the previous character
19576 was a space or tab AND (ii) the
19577 current character is not. */
19578 && (!may_wrap
19579 || IT_DISPLAYING_WHITESPACE (it)))
19580 goto back_to_wrap;
19581
19582 /* Record the maximum and minimum buffer
19583 positions seen so far in glyphs that will be
19584 displayed by this row. */
19585 if (it->bidi_p)
19586 RECORD_MAX_MIN_POS (it);
19587 set_iterator_to_next (it, 1);
19588 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19589 {
19590 if (!get_next_display_element (it))
19591 {
19592 row->exact_window_width_line_p = 1;
19593 it->continuation_lines_width = 0;
19594 row->continued_p = 0;
19595 row->ends_at_zv_p = 1;
19596 }
19597 else if (ITERATOR_AT_END_OF_LINE_P (it))
19598 {
19599 row->continued_p = 0;
19600 row->exact_window_width_line_p = 1;
19601 }
19602 }
19603 }
19604 else if (it->bidi_p)
19605 RECORD_MAX_MIN_POS (it);
19606 }
19607 else if (CHAR_GLYPH_PADDING_P (*glyph)
19608 && !FRAME_WINDOW_P (it->f))
19609 {
19610 /* A padding glyph that doesn't fit on this line.
19611 This means the whole character doesn't fit
19612 on the line. */
19613 if (row->reversed_p)
19614 unproduce_glyphs (it, row->used[TEXT_AREA]
19615 - n_glyphs_before);
19616 row->used[TEXT_AREA] = n_glyphs_before;
19617
19618 /* Fill the rest of the row with continuation
19619 glyphs like in 20.x. */
19620 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19621 < row->glyphs[1 + TEXT_AREA])
19622 produce_special_glyphs (it, IT_CONTINUATION);
19623
19624 row->continued_p = 1;
19625 it->current_x = x_before;
19626 it->continuation_lines_width += x_before;
19627
19628 /* Restore the height to what it was before the
19629 element not fitting on the line. */
19630 it->max_ascent = ascent;
19631 it->max_descent = descent;
19632 it->max_phys_ascent = phys_ascent;
19633 it->max_phys_descent = phys_descent;
19634 }
19635 else if (wrap_row_used > 0)
19636 {
19637 back_to_wrap:
19638 if (row->reversed_p)
19639 unproduce_glyphs (it,
19640 row->used[TEXT_AREA] - wrap_row_used);
19641 RESTORE_IT (it, &wrap_it, wrap_data);
19642 it->continuation_lines_width += wrap_x;
19643 row->used[TEXT_AREA] = wrap_row_used;
19644 row->ascent = wrap_row_ascent;
19645 row->height = wrap_row_height;
19646 row->phys_ascent = wrap_row_phys_ascent;
19647 row->phys_height = wrap_row_phys_height;
19648 row->extra_line_spacing = wrap_row_extra_line_spacing;
19649 min_pos = wrap_row_min_pos;
19650 min_bpos = wrap_row_min_bpos;
19651 max_pos = wrap_row_max_pos;
19652 max_bpos = wrap_row_max_bpos;
19653 row->continued_p = 1;
19654 row->ends_at_zv_p = 0;
19655 row->exact_window_width_line_p = 0;
19656 it->continuation_lines_width += x;
19657
19658 /* Make sure that a non-default face is extended
19659 up to the right margin of the window. */
19660 extend_face_to_end_of_line (it);
19661 }
19662 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19663 {
19664 /* A TAB that extends past the right edge of the
19665 window. This produces a single glyph on
19666 window system frames. We leave the glyph in
19667 this row and let it fill the row, but don't
19668 consume the TAB. */
19669 if ((row->reversed_p
19670 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19671 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19672 produce_special_glyphs (it, IT_CONTINUATION);
19673 it->continuation_lines_width += it->last_visible_x;
19674 row->ends_in_middle_of_char_p = 1;
19675 row->continued_p = 1;
19676 glyph->pixel_width = it->last_visible_x - x;
19677 it->starts_in_middle_of_char_p = 1;
19678 }
19679 else
19680 {
19681 /* Something other than a TAB that draws past
19682 the right edge of the window. Restore
19683 positions to values before the element. */
19684 if (row->reversed_p)
19685 unproduce_glyphs (it, row->used[TEXT_AREA]
19686 - (n_glyphs_before + i));
19687 row->used[TEXT_AREA] = n_glyphs_before + i;
19688
19689 /* Display continuation glyphs. */
19690 it->current_x = x_before;
19691 it->continuation_lines_width += x;
19692 if (!FRAME_WINDOW_P (it->f)
19693 || (row->reversed_p
19694 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19695 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19696 produce_special_glyphs (it, IT_CONTINUATION);
19697 row->continued_p = 1;
19698
19699 extend_face_to_end_of_line (it);
19700
19701 if (nglyphs > 1 && i > 0)
19702 {
19703 row->ends_in_middle_of_char_p = 1;
19704 it->starts_in_middle_of_char_p = 1;
19705 }
19706
19707 /* Restore the height to what it was before the
19708 element not fitting on the line. */
19709 it->max_ascent = ascent;
19710 it->max_descent = descent;
19711 it->max_phys_ascent = phys_ascent;
19712 it->max_phys_descent = phys_descent;
19713 }
19714
19715 break;
19716 }
19717 else if (new_x > it->first_visible_x)
19718 {
19719 /* Increment number of glyphs actually displayed. */
19720 ++it->hpos;
19721
19722 /* Record the maximum and minimum buffer positions
19723 seen so far in glyphs that will be displayed by
19724 this row. */
19725 if (it->bidi_p)
19726 RECORD_MAX_MIN_POS (it);
19727
19728 if (x < it->first_visible_x)
19729 /* Glyph is partially visible, i.e. row starts at
19730 negative X position. */
19731 row->x = x - it->first_visible_x;
19732 }
19733 else
19734 {
19735 /* Glyph is completely off the left margin of the
19736 window. This should not happen because of the
19737 move_it_in_display_line at the start of this
19738 function, unless the text display area of the
19739 window is empty. */
19740 eassert (it->first_visible_x <= it->last_visible_x);
19741 }
19742 }
19743 /* Even if this display element produced no glyphs at all,
19744 we want to record its position. */
19745 if (it->bidi_p && nglyphs == 0)
19746 RECORD_MAX_MIN_POS (it);
19747
19748 row->ascent = max (row->ascent, it->max_ascent);
19749 row->height = max (row->height, it->max_ascent + it->max_descent);
19750 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19751 row->phys_height = max (row->phys_height,
19752 it->max_phys_ascent + it->max_phys_descent);
19753 row->extra_line_spacing = max (row->extra_line_spacing,
19754 it->max_extra_line_spacing);
19755
19756 /* End of this display line if row is continued. */
19757 if (row->continued_p || row->ends_at_zv_p)
19758 break;
19759 }
19760
19761 at_end_of_line:
19762 /* Is this a line end? If yes, we're also done, after making
19763 sure that a non-default face is extended up to the right
19764 margin of the window. */
19765 if (ITERATOR_AT_END_OF_LINE_P (it))
19766 {
19767 int used_before = row->used[TEXT_AREA];
19768
19769 row->ends_in_newline_from_string_p = STRINGP (it->object);
19770
19771 /* Add a space at the end of the line that is used to
19772 display the cursor there. */
19773 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19774 append_space_for_newline (it, 0);
19775
19776 /* Extend the face to the end of the line. */
19777 extend_face_to_end_of_line (it);
19778
19779 /* Make sure we have the position. */
19780 if (used_before == 0)
19781 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19782
19783 /* Record the position of the newline, for use in
19784 find_row_edges. */
19785 it->eol_pos = it->current.pos;
19786
19787 /* Consume the line end. This skips over invisible lines. */
19788 set_iterator_to_next (it, 1);
19789 it->continuation_lines_width = 0;
19790 break;
19791 }
19792
19793 /* Proceed with next display element. Note that this skips
19794 over lines invisible because of selective display. */
19795 set_iterator_to_next (it, 1);
19796
19797 /* If we truncate lines, we are done when the last displayed
19798 glyphs reach past the right margin of the window. */
19799 if (it->line_wrap == TRUNCATE
19800 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19801 ? (it->current_x >= it->last_visible_x)
19802 : (it->current_x > it->last_visible_x)))
19803 {
19804 /* Maybe add truncation glyphs. */
19805 if (!FRAME_WINDOW_P (it->f)
19806 || (row->reversed_p
19807 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19808 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19809 {
19810 int i, n;
19811
19812 if (!row->reversed_p)
19813 {
19814 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19815 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19816 break;
19817 }
19818 else
19819 {
19820 for (i = 0; i < row->used[TEXT_AREA]; i++)
19821 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19822 break;
19823 /* Remove any padding glyphs at the front of ROW, to
19824 make room for the truncation glyphs we will be
19825 adding below. The loop below always inserts at
19826 least one truncation glyph, so also remove the
19827 last glyph added to ROW. */
19828 unproduce_glyphs (it, i + 1);
19829 /* Adjust i for the loop below. */
19830 i = row->used[TEXT_AREA] - (i + 1);
19831 }
19832
19833 it->current_x = x_before;
19834 if (!FRAME_WINDOW_P (it->f))
19835 {
19836 for (n = row->used[TEXT_AREA]; i < n; ++i)
19837 {
19838 row->used[TEXT_AREA] = i;
19839 produce_special_glyphs (it, IT_TRUNCATION);
19840 }
19841 }
19842 else
19843 {
19844 row->used[TEXT_AREA] = i;
19845 produce_special_glyphs (it, IT_TRUNCATION);
19846 }
19847 }
19848 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19849 {
19850 /* Don't truncate if we can overflow newline into fringe. */
19851 if (!get_next_display_element (it))
19852 {
19853 it->continuation_lines_width = 0;
19854 row->ends_at_zv_p = 1;
19855 row->exact_window_width_line_p = 1;
19856 break;
19857 }
19858 if (ITERATOR_AT_END_OF_LINE_P (it))
19859 {
19860 row->exact_window_width_line_p = 1;
19861 goto at_end_of_line;
19862 }
19863 it->current_x = x_before;
19864 }
19865
19866 row->truncated_on_right_p = 1;
19867 it->continuation_lines_width = 0;
19868 reseat_at_next_visible_line_start (it, 0);
19869 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19870 it->hpos = hpos_before;
19871 break;
19872 }
19873 }
19874
19875 if (wrap_data)
19876 bidi_unshelve_cache (wrap_data, 1);
19877
19878 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19879 at the left window margin. */
19880 if (it->first_visible_x
19881 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19882 {
19883 if (!FRAME_WINDOW_P (it->f)
19884 || (row->reversed_p
19885 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19886 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19887 insert_left_trunc_glyphs (it);
19888 row->truncated_on_left_p = 1;
19889 }
19890
19891 /* Remember the position at which this line ends.
19892
19893 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19894 cannot be before the call to find_row_edges below, since that is
19895 where these positions are determined. */
19896 row->end = it->current;
19897 if (!it->bidi_p)
19898 {
19899 row->minpos = row->start.pos;
19900 row->maxpos = row->end.pos;
19901 }
19902 else
19903 {
19904 /* ROW->minpos and ROW->maxpos must be the smallest and
19905 `1 + the largest' buffer positions in ROW. But if ROW was
19906 bidi-reordered, these two positions can be anywhere in the
19907 row, so we must determine them now. */
19908 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19909 }
19910
19911 /* If the start of this line is the overlay arrow-position, then
19912 mark this glyph row as the one containing the overlay arrow.
19913 This is clearly a mess with variable size fonts. It would be
19914 better to let it be displayed like cursors under X. */
19915 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19916 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19917 !NILP (overlay_arrow_string)))
19918 {
19919 /* Overlay arrow in window redisplay is a fringe bitmap. */
19920 if (STRINGP (overlay_arrow_string))
19921 {
19922 struct glyph_row *arrow_row
19923 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19924 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19925 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19926 struct glyph *p = row->glyphs[TEXT_AREA];
19927 struct glyph *p2, *end;
19928
19929 /* Copy the arrow glyphs. */
19930 while (glyph < arrow_end)
19931 *p++ = *glyph++;
19932
19933 /* Throw away padding glyphs. */
19934 p2 = p;
19935 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19936 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19937 ++p2;
19938 if (p2 > p)
19939 {
19940 while (p2 < end)
19941 *p++ = *p2++;
19942 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19943 }
19944 }
19945 else
19946 {
19947 eassert (INTEGERP (overlay_arrow_string));
19948 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19949 }
19950 overlay_arrow_seen = 1;
19951 }
19952
19953 /* Highlight trailing whitespace. */
19954 if (!NILP (Vshow_trailing_whitespace))
19955 highlight_trailing_whitespace (it->f, it->glyph_row);
19956
19957 /* Compute pixel dimensions of this line. */
19958 compute_line_metrics (it);
19959
19960 /* Implementation note: No changes in the glyphs of ROW or in their
19961 faces can be done past this point, because compute_line_metrics
19962 computes ROW's hash value and stores it within the glyph_row
19963 structure. */
19964
19965 /* Record whether this row ends inside an ellipsis. */
19966 row->ends_in_ellipsis_p
19967 = (it->method == GET_FROM_DISPLAY_VECTOR
19968 && it->ellipsis_p);
19969
19970 /* Save fringe bitmaps in this row. */
19971 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19972 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19973 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19974 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19975
19976 it->left_user_fringe_bitmap = 0;
19977 it->left_user_fringe_face_id = 0;
19978 it->right_user_fringe_bitmap = 0;
19979 it->right_user_fringe_face_id = 0;
19980
19981 /* Maybe set the cursor. */
19982 cvpos = it->w->cursor.vpos;
19983 if ((cvpos < 0
19984 /* In bidi-reordered rows, keep checking for proper cursor
19985 position even if one has been found already, because buffer
19986 positions in such rows change non-linearly with ROW->VPOS,
19987 when a line is continued. One exception: when we are at ZV,
19988 display cursor on the first suitable glyph row, since all
19989 the empty rows after that also have their position set to ZV. */
19990 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19991 lines' rows is implemented for bidi-reordered rows. */
19992 || (it->bidi_p
19993 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19994 && PT >= MATRIX_ROW_START_CHARPOS (row)
19995 && PT <= MATRIX_ROW_END_CHARPOS (row)
19996 && cursor_row_p (row))
19997 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19998
19999 /* Prepare for the next line. This line starts horizontally at (X
20000 HPOS) = (0 0). Vertical positions are incremented. As a
20001 convenience for the caller, IT->glyph_row is set to the next
20002 row to be used. */
20003 it->current_x = it->hpos = 0;
20004 it->current_y += row->height;
20005 SET_TEXT_POS (it->eol_pos, 0, 0);
20006 ++it->vpos;
20007 ++it->glyph_row;
20008 /* The next row should by default use the same value of the
20009 reversed_p flag as this one. set_iterator_to_next decides when
20010 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20011 the flag accordingly. */
20012 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20013 it->glyph_row->reversed_p = row->reversed_p;
20014 it->start = row->end;
20015 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
20016
20017 #undef RECORD_MAX_MIN_POS
20018 }
20019
20020 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20021 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20022 doc: /* Return paragraph direction at point in BUFFER.
20023 Value is either `left-to-right' or `right-to-left'.
20024 If BUFFER is omitted or nil, it defaults to the current buffer.
20025
20026 Paragraph direction determines how the text in the paragraph is displayed.
20027 In left-to-right paragraphs, text begins at the left margin of the window
20028 and the reading direction is generally left to right. In right-to-left
20029 paragraphs, text begins at the right margin and is read from right to left.
20030
20031 See also `bidi-paragraph-direction'. */)
20032 (Lisp_Object buffer)
20033 {
20034 struct buffer *buf = current_buffer;
20035 struct buffer *old = buf;
20036
20037 if (! NILP (buffer))
20038 {
20039 CHECK_BUFFER (buffer);
20040 buf = XBUFFER (buffer);
20041 }
20042
20043 if (NILP (BVAR (buf, bidi_display_reordering))
20044 || NILP (BVAR (buf, enable_multibyte_characters))
20045 /* When we are loading loadup.el, the character property tables
20046 needed for bidi iteration are not yet available. */
20047 || !NILP (Vpurify_flag))
20048 return Qleft_to_right;
20049 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20050 return BVAR (buf, bidi_paragraph_direction);
20051 else
20052 {
20053 /* Determine the direction from buffer text. We could try to
20054 use current_matrix if it is up to date, but this seems fast
20055 enough as it is. */
20056 struct bidi_it itb;
20057 ptrdiff_t pos = BUF_PT (buf);
20058 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20059 int c;
20060 void *itb_data = bidi_shelve_cache ();
20061
20062 set_buffer_temp (buf);
20063 /* bidi_paragraph_init finds the base direction of the paragraph
20064 by searching forward from paragraph start. We need the base
20065 direction of the current or _previous_ paragraph, so we need
20066 to make sure we are within that paragraph. To that end, find
20067 the previous non-empty line. */
20068 if (pos >= ZV && pos > BEGV)
20069 DEC_BOTH (pos, bytepos);
20070 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20071 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20072 {
20073 while ((c = FETCH_BYTE (bytepos)) == '\n'
20074 || c == ' ' || c == '\t' || c == '\f')
20075 {
20076 if (bytepos <= BEGV_BYTE)
20077 break;
20078 bytepos--;
20079 pos--;
20080 }
20081 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20082 bytepos--;
20083 }
20084 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20085 itb.paragraph_dir = NEUTRAL_DIR;
20086 itb.string.s = NULL;
20087 itb.string.lstring = Qnil;
20088 itb.string.bufpos = 0;
20089 itb.string.unibyte = 0;
20090 /* We have no window to use here for ignoring window-specific
20091 overlays. Using NULL for window pointer will cause
20092 compute_display_string_pos to use the current buffer. */
20093 itb.w = NULL;
20094 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20095 bidi_unshelve_cache (itb_data, 0);
20096 set_buffer_temp (old);
20097 switch (itb.paragraph_dir)
20098 {
20099 case L2R:
20100 return Qleft_to_right;
20101 break;
20102 case R2L:
20103 return Qright_to_left;
20104 break;
20105 default:
20106 emacs_abort ();
20107 }
20108 }
20109 }
20110
20111 DEFUN ("move-point-visually", Fmove_point_visually,
20112 Smove_point_visually, 1, 1, 0,
20113 doc: /* Move point in the visual order in the specified DIRECTION.
20114 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20115 left.
20116
20117 Value is the new character position of point. */)
20118 (Lisp_Object direction)
20119 {
20120 struct window *w = XWINDOW (selected_window);
20121 struct buffer *b = XBUFFER (w->contents);
20122 struct glyph_row *row;
20123 int dir;
20124 Lisp_Object paragraph_dir;
20125
20126 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20127 (!(ROW)->continued_p \
20128 && INTEGERP ((GLYPH)->object) \
20129 && (GLYPH)->type == CHAR_GLYPH \
20130 && (GLYPH)->u.ch == ' ' \
20131 && (GLYPH)->charpos >= 0 \
20132 && !(GLYPH)->avoid_cursor_p)
20133
20134 CHECK_NUMBER (direction);
20135 dir = XINT (direction);
20136 if (dir > 0)
20137 dir = 1;
20138 else
20139 dir = -1;
20140
20141 /* If current matrix is up-to-date, we can use the information
20142 recorded in the glyphs, at least as long as the goal is on the
20143 screen. */
20144 if (w->window_end_valid
20145 && !windows_or_buffers_changed
20146 && b
20147 && !b->clip_changed
20148 && !b->prevent_redisplay_optimizations_p
20149 && !window_outdated (w)
20150 && w->cursor.vpos >= 0
20151 && w->cursor.vpos < w->current_matrix->nrows
20152 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20153 {
20154 struct glyph *g = row->glyphs[TEXT_AREA];
20155 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20156 struct glyph *gpt = g + w->cursor.hpos;
20157
20158 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20159 {
20160 if (BUFFERP (g->object) && g->charpos != PT)
20161 {
20162 SET_PT (g->charpos);
20163 w->cursor.vpos = -1;
20164 return make_number (PT);
20165 }
20166 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20167 {
20168 ptrdiff_t new_pos;
20169
20170 if (BUFFERP (gpt->object))
20171 {
20172 new_pos = PT;
20173 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20174 new_pos += (row->reversed_p ? -dir : dir);
20175 else
20176 new_pos -= (row->reversed_p ? -dir : dir);;
20177 }
20178 else if (BUFFERP (g->object))
20179 new_pos = g->charpos;
20180 else
20181 break;
20182 SET_PT (new_pos);
20183 w->cursor.vpos = -1;
20184 return make_number (PT);
20185 }
20186 else if (ROW_GLYPH_NEWLINE_P (row, g))
20187 {
20188 /* Glyphs inserted at the end of a non-empty line for
20189 positioning the cursor have zero charpos, so we must
20190 deduce the value of point by other means. */
20191 if (g->charpos > 0)
20192 SET_PT (g->charpos);
20193 else if (row->ends_at_zv_p && PT != ZV)
20194 SET_PT (ZV);
20195 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20196 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20197 else
20198 break;
20199 w->cursor.vpos = -1;
20200 return make_number (PT);
20201 }
20202 }
20203 if (g == e || INTEGERP (g->object))
20204 {
20205 if (row->truncated_on_left_p || row->truncated_on_right_p)
20206 goto simulate_display;
20207 if (!row->reversed_p)
20208 row += dir;
20209 else
20210 row -= dir;
20211 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20212 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20213 goto simulate_display;
20214
20215 if (dir > 0)
20216 {
20217 if (row->reversed_p && !row->continued_p)
20218 {
20219 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20220 w->cursor.vpos = -1;
20221 return make_number (PT);
20222 }
20223 g = row->glyphs[TEXT_AREA];
20224 e = g + row->used[TEXT_AREA];
20225 for ( ; g < e; g++)
20226 {
20227 if (BUFFERP (g->object)
20228 /* Empty lines have only one glyph, which stands
20229 for the newline, and whose charpos is the
20230 buffer position of the newline. */
20231 || ROW_GLYPH_NEWLINE_P (row, g)
20232 /* When the buffer ends in a newline, the line at
20233 EOB also has one glyph, but its charpos is -1. */
20234 || (row->ends_at_zv_p
20235 && !row->reversed_p
20236 && INTEGERP (g->object)
20237 && g->type == CHAR_GLYPH
20238 && g->u.ch == ' '))
20239 {
20240 if (g->charpos > 0)
20241 SET_PT (g->charpos);
20242 else if (!row->reversed_p
20243 && row->ends_at_zv_p
20244 && PT != ZV)
20245 SET_PT (ZV);
20246 else
20247 continue;
20248 w->cursor.vpos = -1;
20249 return make_number (PT);
20250 }
20251 }
20252 }
20253 else
20254 {
20255 if (!row->reversed_p && !row->continued_p)
20256 {
20257 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20258 w->cursor.vpos = -1;
20259 return make_number (PT);
20260 }
20261 e = row->glyphs[TEXT_AREA];
20262 g = e + row->used[TEXT_AREA] - 1;
20263 for ( ; g >= e; g--)
20264 {
20265 if (BUFFERP (g->object)
20266 || (ROW_GLYPH_NEWLINE_P (row, g)
20267 && g->charpos > 0)
20268 /* Empty R2L lines on GUI frames have the buffer
20269 position of the newline stored in the stretch
20270 glyph. */
20271 || g->type == STRETCH_GLYPH
20272 || (row->ends_at_zv_p
20273 && row->reversed_p
20274 && INTEGERP (g->object)
20275 && g->type == CHAR_GLYPH
20276 && g->u.ch == ' '))
20277 {
20278 if (g->charpos > 0)
20279 SET_PT (g->charpos);
20280 else if (row->reversed_p
20281 && row->ends_at_zv_p
20282 && PT != ZV)
20283 SET_PT (ZV);
20284 else
20285 continue;
20286 w->cursor.vpos = -1;
20287 return make_number (PT);
20288 }
20289 }
20290 }
20291 }
20292 }
20293
20294 simulate_display:
20295
20296 /* If we wind up here, we failed to move by using the glyphs, so we
20297 need to simulate display instead. */
20298
20299 if (b)
20300 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
20301 else
20302 paragraph_dir = Qleft_to_right;
20303 if (EQ (paragraph_dir, Qright_to_left))
20304 dir = -dir;
20305 if (PT <= BEGV && dir < 0)
20306 xsignal0 (Qbeginning_of_buffer);
20307 else if (PT >= ZV && dir > 0)
20308 xsignal0 (Qend_of_buffer);
20309 else
20310 {
20311 struct text_pos pt;
20312 struct it it;
20313 int pt_x, target_x, pixel_width, pt_vpos;
20314 bool at_eol_p;
20315 bool overshoot_expected = false;
20316 bool target_is_eol_p = false;
20317
20318 /* Setup the arena. */
20319 SET_TEXT_POS (pt, PT, PT_BYTE);
20320 start_display (&it, w, pt);
20321
20322 if (it.cmp_it.id < 0
20323 && it.method == GET_FROM_STRING
20324 && it.area == TEXT_AREA
20325 && it.string_from_display_prop_p
20326 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
20327 overshoot_expected = true;
20328
20329 /* Find the X coordinate of point. We start from the beginning
20330 of this or previous line to make sure we are before point in
20331 the logical order (since the move_it_* functions can only
20332 move forward). */
20333 reseat_at_previous_visible_line_start (&it);
20334 it.current_x = it.hpos = it.current_y = it.vpos = 0;
20335 if (IT_CHARPOS (it) != PT)
20336 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
20337 -1, -1, -1, MOVE_TO_POS);
20338 pt_x = it.current_x;
20339 pt_vpos = it.vpos;
20340 if (dir > 0 || overshoot_expected)
20341 {
20342 struct glyph_row *row = it.glyph_row;
20343
20344 /* When point is at beginning of line, we don't have
20345 information about the glyph there loaded into struct
20346 it. Calling get_next_display_element fixes that. */
20347 if (pt_x == 0)
20348 get_next_display_element (&it);
20349 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20350 it.glyph_row = NULL;
20351 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
20352 it.glyph_row = row;
20353 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20354 it, lest it will become out of sync with it's buffer
20355 position. */
20356 it.current_x = pt_x;
20357 }
20358 else
20359 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
20360 pixel_width = it.pixel_width;
20361 if (overshoot_expected && at_eol_p)
20362 pixel_width = 0;
20363 else if (pixel_width <= 0)
20364 pixel_width = 1;
20365
20366 /* If there's a display string at point, we are actually at the
20367 glyph to the left of point, so we need to correct the X
20368 coordinate. */
20369 if (overshoot_expected)
20370 pt_x += pixel_width;
20371
20372 /* Compute target X coordinate, either to the left or to the
20373 right of point. On TTY frames, all characters have the same
20374 pixel width of 1, so we can use that. On GUI frames we don't
20375 have an easy way of getting at the pixel width of the
20376 character to the left of point, so we use a different method
20377 of getting to that place. */
20378 if (dir > 0)
20379 target_x = pt_x + pixel_width;
20380 else
20381 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
20382
20383 /* Target X coordinate could be one line above or below the line
20384 of point, in which case we need to adjust the target X
20385 coordinate. Also, if moving to the left, we need to begin at
20386 the left edge of the point's screen line. */
20387 if (dir < 0)
20388 {
20389 if (pt_x > 0)
20390 {
20391 start_display (&it, w, pt);
20392 reseat_at_previous_visible_line_start (&it);
20393 it.current_x = it.current_y = it.hpos = 0;
20394 if (pt_vpos != 0)
20395 move_it_by_lines (&it, pt_vpos);
20396 }
20397 else
20398 {
20399 move_it_by_lines (&it, -1);
20400 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
20401 target_is_eol_p = true;
20402 }
20403 }
20404 else
20405 {
20406 if (at_eol_p
20407 || (target_x >= it.last_visible_x
20408 && it.line_wrap != TRUNCATE))
20409 {
20410 if (pt_x > 0)
20411 move_it_by_lines (&it, 0);
20412 move_it_by_lines (&it, 1);
20413 target_x = 0;
20414 }
20415 }
20416
20417 /* Move to the target X coordinate. */
20418 #ifdef HAVE_WINDOW_SYSTEM
20419 /* On GUI frames, as we don't know the X coordinate of the
20420 character to the left of point, moving point to the left
20421 requires walking, one grapheme cluster at a time, until we
20422 find ourself at a place immediately to the left of the
20423 character at point. */
20424 if (FRAME_WINDOW_P (it.f) && dir < 0)
20425 {
20426 struct text_pos new_pos = it.current.pos;
20427 enum move_it_result rc = MOVE_X_REACHED;
20428
20429 while (it.current_x + it.pixel_width <= target_x
20430 && rc == MOVE_X_REACHED)
20431 {
20432 int new_x = it.current_x + it.pixel_width;
20433
20434 new_pos = it.current.pos;
20435 if (new_x == it.current_x)
20436 new_x++;
20437 rc = move_it_in_display_line_to (&it, ZV, new_x,
20438 MOVE_TO_POS | MOVE_TO_X);
20439 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
20440 break;
20441 }
20442 /* If we ended up on a composed character inside
20443 bidi-reordered text (e.g., Hebrew text with diacritics),
20444 the iterator gives us the buffer position of the last (in
20445 logical order) character of the composed grapheme cluster,
20446 which is not what we want. So we cheat: we compute the
20447 character position of the character that follows (in the
20448 logical order) the one where the above loop stopped. That
20449 character will appear on display to the left of point. */
20450 if (it.bidi_p
20451 && it.bidi_it.scan_dir == -1
20452 && new_pos.charpos - IT_CHARPOS (it) > 1)
20453 {
20454 new_pos.charpos = IT_CHARPOS (it) + 1;
20455 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
20456 }
20457 it.current.pos = new_pos;
20458 }
20459 else
20460 #endif
20461 if (it.current_x != target_x)
20462 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
20463
20464 /* When lines are truncated, the above loop will stop at the
20465 window edge. But we want to get to the end of line, even if
20466 it is beyond the window edge; automatic hscroll will then
20467 scroll the window to show point as appropriate. */
20468 if (target_is_eol_p && it.line_wrap == TRUNCATE
20469 && get_next_display_element (&it))
20470 {
20471 struct text_pos new_pos = it.current.pos;
20472
20473 while (!ITERATOR_AT_END_OF_LINE_P (&it))
20474 {
20475 set_iterator_to_next (&it, 0);
20476 if (it.method == GET_FROM_BUFFER)
20477 new_pos = it.current.pos;
20478 if (!get_next_display_element (&it))
20479 break;
20480 }
20481
20482 it.current.pos = new_pos;
20483 }
20484
20485 /* If we ended up in a display string that covers point, move to
20486 buffer position to the right in the visual order. */
20487 if (dir > 0)
20488 {
20489 while (IT_CHARPOS (it) == PT)
20490 {
20491 set_iterator_to_next (&it, 0);
20492 if (!get_next_display_element (&it))
20493 break;
20494 }
20495 }
20496
20497 /* Move point to that position. */
20498 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
20499 }
20500
20501 return make_number (PT);
20502
20503 #undef ROW_GLYPH_NEWLINE_P
20504 }
20505
20506 \f
20507 /***********************************************************************
20508 Menu Bar
20509 ***********************************************************************/
20510
20511 /* Redisplay the menu bar in the frame for window W.
20512
20513 The menu bar of X frames that don't have X toolkit support is
20514 displayed in a special window W->frame->menu_bar_window.
20515
20516 The menu bar of terminal frames is treated specially as far as
20517 glyph matrices are concerned. Menu bar lines are not part of
20518 windows, so the update is done directly on the frame matrix rows
20519 for the menu bar. */
20520
20521 static void
20522 display_menu_bar (struct window *w)
20523 {
20524 struct frame *f = XFRAME (WINDOW_FRAME (w));
20525 struct it it;
20526 Lisp_Object items;
20527 int i;
20528
20529 /* Don't do all this for graphical frames. */
20530 #ifdef HAVE_NTGUI
20531 if (FRAME_W32_P (f))
20532 return;
20533 #endif
20534 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20535 if (FRAME_X_P (f))
20536 return;
20537 #endif
20538
20539 #ifdef HAVE_NS
20540 if (FRAME_NS_P (f))
20541 return;
20542 #endif /* HAVE_NS */
20543
20544 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20545 eassert (!FRAME_WINDOW_P (f));
20546 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20547 it.first_visible_x = 0;
20548 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20549 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20550 if (FRAME_WINDOW_P (f))
20551 {
20552 /* Menu bar lines are displayed in the desired matrix of the
20553 dummy window menu_bar_window. */
20554 struct window *menu_w;
20555 menu_w = XWINDOW (f->menu_bar_window);
20556 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20557 MENU_FACE_ID);
20558 it.first_visible_x = 0;
20559 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20560 }
20561 else
20562 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20563 {
20564 /* This is a TTY frame, i.e. character hpos/vpos are used as
20565 pixel x/y. */
20566 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20567 MENU_FACE_ID);
20568 it.first_visible_x = 0;
20569 it.last_visible_x = FRAME_COLS (f);
20570 }
20571
20572 /* FIXME: This should be controlled by a user option. See the
20573 comments in redisplay_tool_bar and display_mode_line about
20574 this. */
20575 it.paragraph_embedding = L2R;
20576
20577 /* Clear all rows of the menu bar. */
20578 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20579 {
20580 struct glyph_row *row = it.glyph_row + i;
20581 clear_glyph_row (row);
20582 row->enabled_p = 1;
20583 row->full_width_p = 1;
20584 }
20585
20586 /* Display all items of the menu bar. */
20587 items = FRAME_MENU_BAR_ITEMS (it.f);
20588 for (i = 0; i < ASIZE (items); i += 4)
20589 {
20590 Lisp_Object string;
20591
20592 /* Stop at nil string. */
20593 string = AREF (items, i + 1);
20594 if (NILP (string))
20595 break;
20596
20597 /* Remember where item was displayed. */
20598 ASET (items, i + 3, make_number (it.hpos));
20599
20600 /* Display the item, pad with one space. */
20601 if (it.current_x < it.last_visible_x)
20602 display_string (NULL, string, Qnil, 0, 0, &it,
20603 SCHARS (string) + 1, 0, 0, -1);
20604 }
20605
20606 /* Fill out the line with spaces. */
20607 if (it.current_x < it.last_visible_x)
20608 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20609
20610 /* Compute the total height of the lines. */
20611 compute_line_metrics (&it);
20612 }
20613
20614
20615 \f
20616 /***********************************************************************
20617 Mode Line
20618 ***********************************************************************/
20619
20620 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20621 FORCE is non-zero, redisplay mode lines unconditionally.
20622 Otherwise, redisplay only mode lines that are garbaged. Value is
20623 the number of windows whose mode lines were redisplayed. */
20624
20625 static int
20626 redisplay_mode_lines (Lisp_Object window, int force)
20627 {
20628 int nwindows = 0;
20629
20630 while (!NILP (window))
20631 {
20632 struct window *w = XWINDOW (window);
20633
20634 if (WINDOWP (w->contents))
20635 nwindows += redisplay_mode_lines (w->contents, force);
20636 else if (force
20637 || FRAME_GARBAGED_P (XFRAME (w->frame))
20638 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20639 {
20640 struct text_pos lpoint;
20641 struct buffer *old = current_buffer;
20642
20643 /* Set the window's buffer for the mode line display. */
20644 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20645 set_buffer_internal_1 (XBUFFER (w->contents));
20646
20647 /* Point refers normally to the selected window. For any
20648 other window, set up appropriate value. */
20649 if (!EQ (window, selected_window))
20650 {
20651 struct text_pos pt;
20652
20653 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20654 if (CHARPOS (pt) < BEGV)
20655 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20656 else if (CHARPOS (pt) > (ZV - 1))
20657 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20658 else
20659 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20660 }
20661
20662 /* Display mode lines. */
20663 clear_glyph_matrix (w->desired_matrix);
20664 if (display_mode_lines (w))
20665 {
20666 ++nwindows;
20667 w->must_be_updated_p = 1;
20668 }
20669
20670 /* Restore old settings. */
20671 set_buffer_internal_1 (old);
20672 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20673 }
20674
20675 window = w->next;
20676 }
20677
20678 return nwindows;
20679 }
20680
20681
20682 /* Display the mode and/or header line of window W. Value is the
20683 sum number of mode lines and header lines displayed. */
20684
20685 static int
20686 display_mode_lines (struct window *w)
20687 {
20688 Lisp_Object old_selected_window = selected_window;
20689 Lisp_Object old_selected_frame = selected_frame;
20690 Lisp_Object new_frame = w->frame;
20691 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20692 int n = 0;
20693
20694 selected_frame = new_frame;
20695 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20696 or window's point, then we'd need select_window_1 here as well. */
20697 XSETWINDOW (selected_window, w);
20698 XFRAME (new_frame)->selected_window = selected_window;
20699
20700 /* These will be set while the mode line specs are processed. */
20701 line_number_displayed = 0;
20702 w->column_number_displayed = -1;
20703
20704 if (WINDOW_WANTS_MODELINE_P (w))
20705 {
20706 struct window *sel_w = XWINDOW (old_selected_window);
20707
20708 /* Select mode line face based on the real selected window. */
20709 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20710 BVAR (current_buffer, mode_line_format));
20711 ++n;
20712 }
20713
20714 if (WINDOW_WANTS_HEADER_LINE_P (w))
20715 {
20716 display_mode_line (w, HEADER_LINE_FACE_ID,
20717 BVAR (current_buffer, header_line_format));
20718 ++n;
20719 }
20720
20721 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20722 selected_frame = old_selected_frame;
20723 selected_window = old_selected_window;
20724 return n;
20725 }
20726
20727
20728 /* Display mode or header line of window W. FACE_ID specifies which
20729 line to display; it is either MODE_LINE_FACE_ID or
20730 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20731 display. Value is the pixel height of the mode/header line
20732 displayed. */
20733
20734 static int
20735 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20736 {
20737 struct it it;
20738 struct face *face;
20739 ptrdiff_t count = SPECPDL_INDEX ();
20740
20741 init_iterator (&it, w, -1, -1, NULL, face_id);
20742 /* Don't extend on a previously drawn mode-line.
20743 This may happen if called from pos_visible_p. */
20744 it.glyph_row->enabled_p = 0;
20745 prepare_desired_row (it.glyph_row);
20746
20747 it.glyph_row->mode_line_p = 1;
20748
20749 /* FIXME: This should be controlled by a user option. But
20750 supporting such an option is not trivial, since the mode line is
20751 made up of many separate strings. */
20752 it.paragraph_embedding = L2R;
20753
20754 record_unwind_protect (unwind_format_mode_line,
20755 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20756
20757 mode_line_target = MODE_LINE_DISPLAY;
20758
20759 /* Temporarily make frame's keyboard the current kboard so that
20760 kboard-local variables in the mode_line_format will get the right
20761 values. */
20762 push_kboard (FRAME_KBOARD (it.f));
20763 record_unwind_save_match_data ();
20764 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20765 pop_kboard ();
20766
20767 unbind_to (count, Qnil);
20768
20769 /* Fill up with spaces. */
20770 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20771
20772 compute_line_metrics (&it);
20773 it.glyph_row->full_width_p = 1;
20774 it.glyph_row->continued_p = 0;
20775 it.glyph_row->truncated_on_left_p = 0;
20776 it.glyph_row->truncated_on_right_p = 0;
20777
20778 /* Make a 3D mode-line have a shadow at its right end. */
20779 face = FACE_FROM_ID (it.f, face_id);
20780 extend_face_to_end_of_line (&it);
20781 if (face->box != FACE_NO_BOX)
20782 {
20783 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20784 + it.glyph_row->used[TEXT_AREA] - 1);
20785 last->right_box_line_p = 1;
20786 }
20787
20788 return it.glyph_row->height;
20789 }
20790
20791 /* Move element ELT in LIST to the front of LIST.
20792 Return the updated list. */
20793
20794 static Lisp_Object
20795 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20796 {
20797 register Lisp_Object tail, prev;
20798 register Lisp_Object tem;
20799
20800 tail = list;
20801 prev = Qnil;
20802 while (CONSP (tail))
20803 {
20804 tem = XCAR (tail);
20805
20806 if (EQ (elt, tem))
20807 {
20808 /* Splice out the link TAIL. */
20809 if (NILP (prev))
20810 list = XCDR (tail);
20811 else
20812 Fsetcdr (prev, XCDR (tail));
20813
20814 /* Now make it the first. */
20815 Fsetcdr (tail, list);
20816 return tail;
20817 }
20818 else
20819 prev = tail;
20820 tail = XCDR (tail);
20821 QUIT;
20822 }
20823
20824 /* Not found--return unchanged LIST. */
20825 return list;
20826 }
20827
20828 /* Contribute ELT to the mode line for window IT->w. How it
20829 translates into text depends on its data type.
20830
20831 IT describes the display environment in which we display, as usual.
20832
20833 DEPTH is the depth in recursion. It is used to prevent
20834 infinite recursion here.
20835
20836 FIELD_WIDTH is the number of characters the display of ELT should
20837 occupy in the mode line, and PRECISION is the maximum number of
20838 characters to display from ELT's representation. See
20839 display_string for details.
20840
20841 Returns the hpos of the end of the text generated by ELT.
20842
20843 PROPS is a property list to add to any string we encounter.
20844
20845 If RISKY is nonzero, remove (disregard) any properties in any string
20846 we encounter, and ignore :eval and :propertize.
20847
20848 The global variable `mode_line_target' determines whether the
20849 output is passed to `store_mode_line_noprop',
20850 `store_mode_line_string', or `display_string'. */
20851
20852 static int
20853 display_mode_element (struct it *it, int depth, int field_width, int precision,
20854 Lisp_Object elt, Lisp_Object props, int risky)
20855 {
20856 int n = 0, field, prec;
20857 int literal = 0;
20858
20859 tail_recurse:
20860 if (depth > 100)
20861 elt = build_string ("*too-deep*");
20862
20863 depth++;
20864
20865 switch (XTYPE (elt))
20866 {
20867 case Lisp_String:
20868 {
20869 /* A string: output it and check for %-constructs within it. */
20870 unsigned char c;
20871 ptrdiff_t offset = 0;
20872
20873 if (SCHARS (elt) > 0
20874 && (!NILP (props) || risky))
20875 {
20876 Lisp_Object oprops, aelt;
20877 oprops = Ftext_properties_at (make_number (0), elt);
20878
20879 /* If the starting string's properties are not what
20880 we want, translate the string. Also, if the string
20881 is risky, do that anyway. */
20882
20883 if (NILP (Fequal (props, oprops)) || risky)
20884 {
20885 /* If the starting string has properties,
20886 merge the specified ones onto the existing ones. */
20887 if (! NILP (oprops) && !risky)
20888 {
20889 Lisp_Object tem;
20890
20891 oprops = Fcopy_sequence (oprops);
20892 tem = props;
20893 while (CONSP (tem))
20894 {
20895 oprops = Fplist_put (oprops, XCAR (tem),
20896 XCAR (XCDR (tem)));
20897 tem = XCDR (XCDR (tem));
20898 }
20899 props = oprops;
20900 }
20901
20902 aelt = Fassoc (elt, mode_line_proptrans_alist);
20903 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20904 {
20905 /* AELT is what we want. Move it to the front
20906 without consing. */
20907 elt = XCAR (aelt);
20908 mode_line_proptrans_alist
20909 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20910 }
20911 else
20912 {
20913 Lisp_Object tem;
20914
20915 /* If AELT has the wrong props, it is useless.
20916 so get rid of it. */
20917 if (! NILP (aelt))
20918 mode_line_proptrans_alist
20919 = Fdelq (aelt, mode_line_proptrans_alist);
20920
20921 elt = Fcopy_sequence (elt);
20922 Fset_text_properties (make_number (0), Flength (elt),
20923 props, elt);
20924 /* Add this item to mode_line_proptrans_alist. */
20925 mode_line_proptrans_alist
20926 = Fcons (Fcons (elt, props),
20927 mode_line_proptrans_alist);
20928 /* Truncate mode_line_proptrans_alist
20929 to at most 50 elements. */
20930 tem = Fnthcdr (make_number (50),
20931 mode_line_proptrans_alist);
20932 if (! NILP (tem))
20933 XSETCDR (tem, Qnil);
20934 }
20935 }
20936 }
20937
20938 offset = 0;
20939
20940 if (literal)
20941 {
20942 prec = precision - n;
20943 switch (mode_line_target)
20944 {
20945 case MODE_LINE_NOPROP:
20946 case MODE_LINE_TITLE:
20947 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20948 break;
20949 case MODE_LINE_STRING:
20950 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20951 break;
20952 case MODE_LINE_DISPLAY:
20953 n += display_string (NULL, elt, Qnil, 0, 0, it,
20954 0, prec, 0, STRING_MULTIBYTE (elt));
20955 break;
20956 }
20957
20958 break;
20959 }
20960
20961 /* Handle the non-literal case. */
20962
20963 while ((precision <= 0 || n < precision)
20964 && SREF (elt, offset) != 0
20965 && (mode_line_target != MODE_LINE_DISPLAY
20966 || it->current_x < it->last_visible_x))
20967 {
20968 ptrdiff_t last_offset = offset;
20969
20970 /* Advance to end of string or next format specifier. */
20971 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20972 ;
20973
20974 if (offset - 1 != last_offset)
20975 {
20976 ptrdiff_t nchars, nbytes;
20977
20978 /* Output to end of string or up to '%'. Field width
20979 is length of string. Don't output more than
20980 PRECISION allows us. */
20981 offset--;
20982
20983 prec = c_string_width (SDATA (elt) + last_offset,
20984 offset - last_offset, precision - n,
20985 &nchars, &nbytes);
20986
20987 switch (mode_line_target)
20988 {
20989 case MODE_LINE_NOPROP:
20990 case MODE_LINE_TITLE:
20991 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20992 break;
20993 case MODE_LINE_STRING:
20994 {
20995 ptrdiff_t bytepos = last_offset;
20996 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20997 ptrdiff_t endpos = (precision <= 0
20998 ? string_byte_to_char (elt, offset)
20999 : charpos + nchars);
21000
21001 n += store_mode_line_string (NULL,
21002 Fsubstring (elt, make_number (charpos),
21003 make_number (endpos)),
21004 0, 0, 0, Qnil);
21005 }
21006 break;
21007 case MODE_LINE_DISPLAY:
21008 {
21009 ptrdiff_t bytepos = last_offset;
21010 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
21011
21012 if (precision <= 0)
21013 nchars = string_byte_to_char (elt, offset) - charpos;
21014 n += display_string (NULL, elt, Qnil, 0, charpos,
21015 it, 0, nchars, 0,
21016 STRING_MULTIBYTE (elt));
21017 }
21018 break;
21019 }
21020 }
21021 else /* c == '%' */
21022 {
21023 ptrdiff_t percent_position = offset;
21024
21025 /* Get the specified minimum width. Zero means
21026 don't pad. */
21027 field = 0;
21028 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
21029 field = field * 10 + c - '0';
21030
21031 /* Don't pad beyond the total padding allowed. */
21032 if (field_width - n > 0 && field > field_width - n)
21033 field = field_width - n;
21034
21035 /* Note that either PRECISION <= 0 or N < PRECISION. */
21036 prec = precision - n;
21037
21038 if (c == 'M')
21039 n += display_mode_element (it, depth, field, prec,
21040 Vglobal_mode_string, props,
21041 risky);
21042 else if (c != 0)
21043 {
21044 bool multibyte;
21045 ptrdiff_t bytepos, charpos;
21046 const char *spec;
21047 Lisp_Object string;
21048
21049 bytepos = percent_position;
21050 charpos = (STRING_MULTIBYTE (elt)
21051 ? string_byte_to_char (elt, bytepos)
21052 : bytepos);
21053 spec = decode_mode_spec (it->w, c, field, &string);
21054 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
21055
21056 switch (mode_line_target)
21057 {
21058 case MODE_LINE_NOPROP:
21059 case MODE_LINE_TITLE:
21060 n += store_mode_line_noprop (spec, field, prec);
21061 break;
21062 case MODE_LINE_STRING:
21063 {
21064 Lisp_Object tem = build_string (spec);
21065 props = Ftext_properties_at (make_number (charpos), elt);
21066 /* Should only keep face property in props */
21067 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
21068 }
21069 break;
21070 case MODE_LINE_DISPLAY:
21071 {
21072 int nglyphs_before, nwritten;
21073
21074 nglyphs_before = it->glyph_row->used[TEXT_AREA];
21075 nwritten = display_string (spec, string, elt,
21076 charpos, 0, it,
21077 field, prec, 0,
21078 multibyte);
21079
21080 /* Assign to the glyphs written above the
21081 string where the `%x' came from, position
21082 of the `%'. */
21083 if (nwritten > 0)
21084 {
21085 struct glyph *glyph
21086 = (it->glyph_row->glyphs[TEXT_AREA]
21087 + nglyphs_before);
21088 int i;
21089
21090 for (i = 0; i < nwritten; ++i)
21091 {
21092 glyph[i].object = elt;
21093 glyph[i].charpos = charpos;
21094 }
21095
21096 n += nwritten;
21097 }
21098 }
21099 break;
21100 }
21101 }
21102 else /* c == 0 */
21103 break;
21104 }
21105 }
21106 }
21107 break;
21108
21109 case Lisp_Symbol:
21110 /* A symbol: process the value of the symbol recursively
21111 as if it appeared here directly. Avoid error if symbol void.
21112 Special case: if value of symbol is a string, output the string
21113 literally. */
21114 {
21115 register Lisp_Object tem;
21116
21117 /* If the variable is not marked as risky to set
21118 then its contents are risky to use. */
21119 if (NILP (Fget (elt, Qrisky_local_variable)))
21120 risky = 1;
21121
21122 tem = Fboundp (elt);
21123 if (!NILP (tem))
21124 {
21125 tem = Fsymbol_value (elt);
21126 /* If value is a string, output that string literally:
21127 don't check for % within it. */
21128 if (STRINGP (tem))
21129 literal = 1;
21130
21131 if (!EQ (tem, elt))
21132 {
21133 /* Give up right away for nil or t. */
21134 elt = tem;
21135 goto tail_recurse;
21136 }
21137 }
21138 }
21139 break;
21140
21141 case Lisp_Cons:
21142 {
21143 register Lisp_Object car, tem;
21144
21145 /* A cons cell: five distinct cases.
21146 If first element is :eval or :propertize, do something special.
21147 If first element is a string or a cons, process all the elements
21148 and effectively concatenate them.
21149 If first element is a negative number, truncate displaying cdr to
21150 at most that many characters. If positive, pad (with spaces)
21151 to at least that many characters.
21152 If first element is a symbol, process the cadr or caddr recursively
21153 according to whether the symbol's value is non-nil or nil. */
21154 car = XCAR (elt);
21155 if (EQ (car, QCeval))
21156 {
21157 /* An element of the form (:eval FORM) means evaluate FORM
21158 and use the result as mode line elements. */
21159
21160 if (risky)
21161 break;
21162
21163 if (CONSP (XCDR (elt)))
21164 {
21165 Lisp_Object spec;
21166 spec = safe_eval (XCAR (XCDR (elt)));
21167 n += display_mode_element (it, depth, field_width - n,
21168 precision - n, spec, props,
21169 risky);
21170 }
21171 }
21172 else if (EQ (car, QCpropertize))
21173 {
21174 /* An element of the form (:propertize ELT PROPS...)
21175 means display ELT but applying properties PROPS. */
21176
21177 if (risky)
21178 break;
21179
21180 if (CONSP (XCDR (elt)))
21181 n += display_mode_element (it, depth, field_width - n,
21182 precision - n, XCAR (XCDR (elt)),
21183 XCDR (XCDR (elt)), risky);
21184 }
21185 else if (SYMBOLP (car))
21186 {
21187 tem = Fboundp (car);
21188 elt = XCDR (elt);
21189 if (!CONSP (elt))
21190 goto invalid;
21191 /* elt is now the cdr, and we know it is a cons cell.
21192 Use its car if CAR has a non-nil value. */
21193 if (!NILP (tem))
21194 {
21195 tem = Fsymbol_value (car);
21196 if (!NILP (tem))
21197 {
21198 elt = XCAR (elt);
21199 goto tail_recurse;
21200 }
21201 }
21202 /* Symbol's value is nil (or symbol is unbound)
21203 Get the cddr of the original list
21204 and if possible find the caddr and use that. */
21205 elt = XCDR (elt);
21206 if (NILP (elt))
21207 break;
21208 else if (!CONSP (elt))
21209 goto invalid;
21210 elt = XCAR (elt);
21211 goto tail_recurse;
21212 }
21213 else if (INTEGERP (car))
21214 {
21215 register int lim = XINT (car);
21216 elt = XCDR (elt);
21217 if (lim < 0)
21218 {
21219 /* Negative int means reduce maximum width. */
21220 if (precision <= 0)
21221 precision = -lim;
21222 else
21223 precision = min (precision, -lim);
21224 }
21225 else if (lim > 0)
21226 {
21227 /* Padding specified. Don't let it be more than
21228 current maximum. */
21229 if (precision > 0)
21230 lim = min (precision, lim);
21231
21232 /* If that's more padding than already wanted, queue it.
21233 But don't reduce padding already specified even if
21234 that is beyond the current truncation point. */
21235 field_width = max (lim, field_width);
21236 }
21237 goto tail_recurse;
21238 }
21239 else if (STRINGP (car) || CONSP (car))
21240 {
21241 Lisp_Object halftail = elt;
21242 int len = 0;
21243
21244 while (CONSP (elt)
21245 && (precision <= 0 || n < precision))
21246 {
21247 n += display_mode_element (it, depth,
21248 /* Do padding only after the last
21249 element in the list. */
21250 (! CONSP (XCDR (elt))
21251 ? field_width - n
21252 : 0),
21253 precision - n, XCAR (elt),
21254 props, risky);
21255 elt = XCDR (elt);
21256 len++;
21257 if ((len & 1) == 0)
21258 halftail = XCDR (halftail);
21259 /* Check for cycle. */
21260 if (EQ (halftail, elt))
21261 break;
21262 }
21263 }
21264 }
21265 break;
21266
21267 default:
21268 invalid:
21269 elt = build_string ("*invalid*");
21270 goto tail_recurse;
21271 }
21272
21273 /* Pad to FIELD_WIDTH. */
21274 if (field_width > 0 && n < field_width)
21275 {
21276 switch (mode_line_target)
21277 {
21278 case MODE_LINE_NOPROP:
21279 case MODE_LINE_TITLE:
21280 n += store_mode_line_noprop ("", field_width - n, 0);
21281 break;
21282 case MODE_LINE_STRING:
21283 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
21284 break;
21285 case MODE_LINE_DISPLAY:
21286 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
21287 0, 0, 0);
21288 break;
21289 }
21290 }
21291
21292 return n;
21293 }
21294
21295 /* Store a mode-line string element in mode_line_string_list.
21296
21297 If STRING is non-null, display that C string. Otherwise, the Lisp
21298 string LISP_STRING is displayed.
21299
21300 FIELD_WIDTH is the minimum number of output glyphs to produce.
21301 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21302 with spaces. FIELD_WIDTH <= 0 means don't pad.
21303
21304 PRECISION is the maximum number of characters to output from
21305 STRING. PRECISION <= 0 means don't truncate the string.
21306
21307 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21308 properties to the string.
21309
21310 PROPS are the properties to add to the string.
21311 The mode_line_string_face face property is always added to the string.
21312 */
21313
21314 static int
21315 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21316 int field_width, int precision, Lisp_Object props)
21317 {
21318 ptrdiff_t len;
21319 int n = 0;
21320
21321 if (string != NULL)
21322 {
21323 len = strlen (string);
21324 if (precision > 0 && len > precision)
21325 len = precision;
21326 lisp_string = make_string (string, len);
21327 if (NILP (props))
21328 props = mode_line_string_face_prop;
21329 else if (!NILP (mode_line_string_face))
21330 {
21331 Lisp_Object face = Fplist_get (props, Qface);
21332 props = Fcopy_sequence (props);
21333 if (NILP (face))
21334 face = mode_line_string_face;
21335 else
21336 face = list2 (face, mode_line_string_face);
21337 props = Fplist_put (props, Qface, face);
21338 }
21339 Fadd_text_properties (make_number (0), make_number (len),
21340 props, lisp_string);
21341 }
21342 else
21343 {
21344 len = XFASTINT (Flength (lisp_string));
21345 if (precision > 0 && len > precision)
21346 {
21347 len = precision;
21348 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21349 precision = -1;
21350 }
21351 if (!NILP (mode_line_string_face))
21352 {
21353 Lisp_Object face;
21354 if (NILP (props))
21355 props = Ftext_properties_at (make_number (0), lisp_string);
21356 face = Fplist_get (props, Qface);
21357 if (NILP (face))
21358 face = mode_line_string_face;
21359 else
21360 face = list2 (face, mode_line_string_face);
21361 props = list2 (Qface, face);
21362 if (copy_string)
21363 lisp_string = Fcopy_sequence (lisp_string);
21364 }
21365 if (!NILP (props))
21366 Fadd_text_properties (make_number (0), make_number (len),
21367 props, lisp_string);
21368 }
21369
21370 if (len > 0)
21371 {
21372 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21373 n += len;
21374 }
21375
21376 if (field_width > len)
21377 {
21378 field_width -= len;
21379 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21380 if (!NILP (props))
21381 Fadd_text_properties (make_number (0), make_number (field_width),
21382 props, lisp_string);
21383 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21384 n += field_width;
21385 }
21386
21387 return n;
21388 }
21389
21390
21391 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21392 1, 4, 0,
21393 doc: /* Format a string out of a mode line format specification.
21394 First arg FORMAT specifies the mode line format (see `mode-line-format'
21395 for details) to use.
21396
21397 By default, the format is evaluated for the currently selected window.
21398
21399 Optional second arg FACE specifies the face property to put on all
21400 characters for which no face is specified. The value nil means the
21401 default face. The value t means whatever face the window's mode line
21402 currently uses (either `mode-line' or `mode-line-inactive',
21403 depending on whether the window is the selected window or not).
21404 An integer value means the value string has no text
21405 properties.
21406
21407 Optional third and fourth args WINDOW and BUFFER specify the window
21408 and buffer to use as the context for the formatting (defaults
21409 are the selected window and the WINDOW's buffer). */)
21410 (Lisp_Object format, Lisp_Object face,
21411 Lisp_Object window, Lisp_Object buffer)
21412 {
21413 struct it it;
21414 int len;
21415 struct window *w;
21416 struct buffer *old_buffer = NULL;
21417 int face_id;
21418 int no_props = INTEGERP (face);
21419 ptrdiff_t count = SPECPDL_INDEX ();
21420 Lisp_Object str;
21421 int string_start = 0;
21422
21423 w = decode_any_window (window);
21424 XSETWINDOW (window, w);
21425
21426 if (NILP (buffer))
21427 buffer = w->contents;
21428 CHECK_BUFFER (buffer);
21429
21430 /* Make formatting the modeline a non-op when noninteractive, otherwise
21431 there will be problems later caused by a partially initialized frame. */
21432 if (NILP (format) || noninteractive)
21433 return empty_unibyte_string;
21434
21435 if (no_props)
21436 face = Qnil;
21437
21438 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21439 : EQ (face, Qt) ? (EQ (window, selected_window)
21440 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21441 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21442 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21443 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21444 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21445 : DEFAULT_FACE_ID;
21446
21447 old_buffer = current_buffer;
21448
21449 /* Save things including mode_line_proptrans_alist,
21450 and set that to nil so that we don't alter the outer value. */
21451 record_unwind_protect (unwind_format_mode_line,
21452 format_mode_line_unwind_data
21453 (XFRAME (WINDOW_FRAME (w)),
21454 old_buffer, selected_window, 1));
21455 mode_line_proptrans_alist = Qnil;
21456
21457 Fselect_window (window, Qt);
21458 set_buffer_internal_1 (XBUFFER (buffer));
21459
21460 init_iterator (&it, w, -1, -1, NULL, face_id);
21461
21462 if (no_props)
21463 {
21464 mode_line_target = MODE_LINE_NOPROP;
21465 mode_line_string_face_prop = Qnil;
21466 mode_line_string_list = Qnil;
21467 string_start = MODE_LINE_NOPROP_LEN (0);
21468 }
21469 else
21470 {
21471 mode_line_target = MODE_LINE_STRING;
21472 mode_line_string_list = Qnil;
21473 mode_line_string_face = face;
21474 mode_line_string_face_prop
21475 = NILP (face) ? Qnil : list2 (Qface, face);
21476 }
21477
21478 push_kboard (FRAME_KBOARD (it.f));
21479 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21480 pop_kboard ();
21481
21482 if (no_props)
21483 {
21484 len = MODE_LINE_NOPROP_LEN (string_start);
21485 str = make_string (mode_line_noprop_buf + string_start, len);
21486 }
21487 else
21488 {
21489 mode_line_string_list = Fnreverse (mode_line_string_list);
21490 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21491 empty_unibyte_string);
21492 }
21493
21494 unbind_to (count, Qnil);
21495 return str;
21496 }
21497
21498 /* Write a null-terminated, right justified decimal representation of
21499 the positive integer D to BUF using a minimal field width WIDTH. */
21500
21501 static void
21502 pint2str (register char *buf, register int width, register ptrdiff_t d)
21503 {
21504 register char *p = buf;
21505
21506 if (d <= 0)
21507 *p++ = '0';
21508 else
21509 {
21510 while (d > 0)
21511 {
21512 *p++ = d % 10 + '0';
21513 d /= 10;
21514 }
21515 }
21516
21517 for (width -= (int) (p - buf); width > 0; --width)
21518 *p++ = ' ';
21519 *p-- = '\0';
21520 while (p > buf)
21521 {
21522 d = *buf;
21523 *buf++ = *p;
21524 *p-- = d;
21525 }
21526 }
21527
21528 /* Write a null-terminated, right justified decimal and "human
21529 readable" representation of the nonnegative integer D to BUF using
21530 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21531
21532 static const char power_letter[] =
21533 {
21534 0, /* no letter */
21535 'k', /* kilo */
21536 'M', /* mega */
21537 'G', /* giga */
21538 'T', /* tera */
21539 'P', /* peta */
21540 'E', /* exa */
21541 'Z', /* zetta */
21542 'Y' /* yotta */
21543 };
21544
21545 static void
21546 pint2hrstr (char *buf, int width, ptrdiff_t d)
21547 {
21548 /* We aim to represent the nonnegative integer D as
21549 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21550 ptrdiff_t quotient = d;
21551 int remainder = 0;
21552 /* -1 means: do not use TENTHS. */
21553 int tenths = -1;
21554 int exponent = 0;
21555
21556 /* Length of QUOTIENT.TENTHS as a string. */
21557 int length;
21558
21559 char * psuffix;
21560 char * p;
21561
21562 if (quotient >= 1000)
21563 {
21564 /* Scale to the appropriate EXPONENT. */
21565 do
21566 {
21567 remainder = quotient % 1000;
21568 quotient /= 1000;
21569 exponent++;
21570 }
21571 while (quotient >= 1000);
21572
21573 /* Round to nearest and decide whether to use TENTHS or not. */
21574 if (quotient <= 9)
21575 {
21576 tenths = remainder / 100;
21577 if (remainder % 100 >= 50)
21578 {
21579 if (tenths < 9)
21580 tenths++;
21581 else
21582 {
21583 quotient++;
21584 if (quotient == 10)
21585 tenths = -1;
21586 else
21587 tenths = 0;
21588 }
21589 }
21590 }
21591 else
21592 if (remainder >= 500)
21593 {
21594 if (quotient < 999)
21595 quotient++;
21596 else
21597 {
21598 quotient = 1;
21599 exponent++;
21600 tenths = 0;
21601 }
21602 }
21603 }
21604
21605 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21606 if (tenths == -1 && quotient <= 99)
21607 if (quotient <= 9)
21608 length = 1;
21609 else
21610 length = 2;
21611 else
21612 length = 3;
21613 p = psuffix = buf + max (width, length);
21614
21615 /* Print EXPONENT. */
21616 *psuffix++ = power_letter[exponent];
21617 *psuffix = '\0';
21618
21619 /* Print TENTHS. */
21620 if (tenths >= 0)
21621 {
21622 *--p = '0' + tenths;
21623 *--p = '.';
21624 }
21625
21626 /* Print QUOTIENT. */
21627 do
21628 {
21629 int digit = quotient % 10;
21630 *--p = '0' + digit;
21631 }
21632 while ((quotient /= 10) != 0);
21633
21634 /* Print leading spaces. */
21635 while (buf < p)
21636 *--p = ' ';
21637 }
21638
21639 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21640 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21641 type of CODING_SYSTEM. Return updated pointer into BUF. */
21642
21643 static unsigned char invalid_eol_type[] = "(*invalid*)";
21644
21645 static char *
21646 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21647 {
21648 Lisp_Object val;
21649 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21650 const unsigned char *eol_str;
21651 int eol_str_len;
21652 /* The EOL conversion we are using. */
21653 Lisp_Object eoltype;
21654
21655 val = CODING_SYSTEM_SPEC (coding_system);
21656 eoltype = Qnil;
21657
21658 if (!VECTORP (val)) /* Not yet decided. */
21659 {
21660 *buf++ = multibyte ? '-' : ' ';
21661 if (eol_flag)
21662 eoltype = eol_mnemonic_undecided;
21663 /* Don't mention EOL conversion if it isn't decided. */
21664 }
21665 else
21666 {
21667 Lisp_Object attrs;
21668 Lisp_Object eolvalue;
21669
21670 attrs = AREF (val, 0);
21671 eolvalue = AREF (val, 2);
21672
21673 *buf++ = multibyte
21674 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21675 : ' ';
21676
21677 if (eol_flag)
21678 {
21679 /* The EOL conversion that is normal on this system. */
21680
21681 if (NILP (eolvalue)) /* Not yet decided. */
21682 eoltype = eol_mnemonic_undecided;
21683 else if (VECTORP (eolvalue)) /* Not yet decided. */
21684 eoltype = eol_mnemonic_undecided;
21685 else /* eolvalue is Qunix, Qdos, or Qmac. */
21686 eoltype = (EQ (eolvalue, Qunix)
21687 ? eol_mnemonic_unix
21688 : (EQ (eolvalue, Qdos) == 1
21689 ? eol_mnemonic_dos : eol_mnemonic_mac));
21690 }
21691 }
21692
21693 if (eol_flag)
21694 {
21695 /* Mention the EOL conversion if it is not the usual one. */
21696 if (STRINGP (eoltype))
21697 {
21698 eol_str = SDATA (eoltype);
21699 eol_str_len = SBYTES (eoltype);
21700 }
21701 else if (CHARACTERP (eoltype))
21702 {
21703 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21704 int c = XFASTINT (eoltype);
21705 eol_str_len = CHAR_STRING (c, tmp);
21706 eol_str = tmp;
21707 }
21708 else
21709 {
21710 eol_str = invalid_eol_type;
21711 eol_str_len = sizeof (invalid_eol_type) - 1;
21712 }
21713 memcpy (buf, eol_str, eol_str_len);
21714 buf += eol_str_len;
21715 }
21716
21717 return buf;
21718 }
21719
21720 /* Return a string for the output of a mode line %-spec for window W,
21721 generated by character C. FIELD_WIDTH > 0 means pad the string
21722 returned with spaces to that value. Return a Lisp string in
21723 *STRING if the resulting string is taken from that Lisp string.
21724
21725 Note we operate on the current buffer for most purposes. */
21726
21727 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21728
21729 static const char *
21730 decode_mode_spec (struct window *w, register int c, int field_width,
21731 Lisp_Object *string)
21732 {
21733 Lisp_Object obj;
21734 struct frame *f = XFRAME (WINDOW_FRAME (w));
21735 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21736 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21737 produce strings from numerical values, so limit preposterously
21738 large values of FIELD_WIDTH to avoid overrunning the buffer's
21739 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21740 bytes plus the terminating null. */
21741 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21742 struct buffer *b = current_buffer;
21743
21744 obj = Qnil;
21745 *string = Qnil;
21746
21747 switch (c)
21748 {
21749 case '*':
21750 if (!NILP (BVAR (b, read_only)))
21751 return "%";
21752 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21753 return "*";
21754 return "-";
21755
21756 case '+':
21757 /* This differs from %* only for a modified read-only buffer. */
21758 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21759 return "*";
21760 if (!NILP (BVAR (b, read_only)))
21761 return "%";
21762 return "-";
21763
21764 case '&':
21765 /* This differs from %* in ignoring read-only-ness. */
21766 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21767 return "*";
21768 return "-";
21769
21770 case '%':
21771 return "%";
21772
21773 case '[':
21774 {
21775 int i;
21776 char *p;
21777
21778 if (command_loop_level > 5)
21779 return "[[[... ";
21780 p = decode_mode_spec_buf;
21781 for (i = 0; i < command_loop_level; i++)
21782 *p++ = '[';
21783 *p = 0;
21784 return decode_mode_spec_buf;
21785 }
21786
21787 case ']':
21788 {
21789 int i;
21790 char *p;
21791
21792 if (command_loop_level > 5)
21793 return " ...]]]";
21794 p = decode_mode_spec_buf;
21795 for (i = 0; i < command_loop_level; i++)
21796 *p++ = ']';
21797 *p = 0;
21798 return decode_mode_spec_buf;
21799 }
21800
21801 case '-':
21802 {
21803 register int i;
21804
21805 /* Let lots_of_dashes be a string of infinite length. */
21806 if (mode_line_target == MODE_LINE_NOPROP
21807 || mode_line_target == MODE_LINE_STRING)
21808 return "--";
21809 if (field_width <= 0
21810 || field_width > sizeof (lots_of_dashes))
21811 {
21812 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21813 decode_mode_spec_buf[i] = '-';
21814 decode_mode_spec_buf[i] = '\0';
21815 return decode_mode_spec_buf;
21816 }
21817 else
21818 return lots_of_dashes;
21819 }
21820
21821 case 'b':
21822 obj = BVAR (b, name);
21823 break;
21824
21825 case 'c':
21826 /* %c and %l are ignored in `frame-title-format'.
21827 (In redisplay_internal, the frame title is drawn _before_ the
21828 windows are updated, so the stuff which depends on actual
21829 window contents (such as %l) may fail to render properly, or
21830 even crash emacs.) */
21831 if (mode_line_target == MODE_LINE_TITLE)
21832 return "";
21833 else
21834 {
21835 ptrdiff_t col = current_column ();
21836 w->column_number_displayed = col;
21837 pint2str (decode_mode_spec_buf, width, col);
21838 return decode_mode_spec_buf;
21839 }
21840
21841 case 'e':
21842 #ifndef SYSTEM_MALLOC
21843 {
21844 if (NILP (Vmemory_full))
21845 return "";
21846 else
21847 return "!MEM FULL! ";
21848 }
21849 #else
21850 return "";
21851 #endif
21852
21853 case 'F':
21854 /* %F displays the frame name. */
21855 if (!NILP (f->title))
21856 return SSDATA (f->title);
21857 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21858 return SSDATA (f->name);
21859 return "Emacs";
21860
21861 case 'f':
21862 obj = BVAR (b, filename);
21863 break;
21864
21865 case 'i':
21866 {
21867 ptrdiff_t size = ZV - BEGV;
21868 pint2str (decode_mode_spec_buf, width, size);
21869 return decode_mode_spec_buf;
21870 }
21871
21872 case 'I':
21873 {
21874 ptrdiff_t size = ZV - BEGV;
21875 pint2hrstr (decode_mode_spec_buf, width, size);
21876 return decode_mode_spec_buf;
21877 }
21878
21879 case 'l':
21880 {
21881 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21882 ptrdiff_t topline, nlines, height;
21883 ptrdiff_t junk;
21884
21885 /* %c and %l are ignored in `frame-title-format'. */
21886 if (mode_line_target == MODE_LINE_TITLE)
21887 return "";
21888
21889 startpos = marker_position (w->start);
21890 startpos_byte = marker_byte_position (w->start);
21891 height = WINDOW_TOTAL_LINES (w);
21892
21893 /* If we decided that this buffer isn't suitable for line numbers,
21894 don't forget that too fast. */
21895 if (w->base_line_pos == -1)
21896 goto no_value;
21897
21898 /* If the buffer is very big, don't waste time. */
21899 if (INTEGERP (Vline_number_display_limit)
21900 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21901 {
21902 w->base_line_pos = 0;
21903 w->base_line_number = 0;
21904 goto no_value;
21905 }
21906
21907 if (w->base_line_number > 0
21908 && w->base_line_pos > 0
21909 && w->base_line_pos <= startpos)
21910 {
21911 line = w->base_line_number;
21912 linepos = w->base_line_pos;
21913 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21914 }
21915 else
21916 {
21917 line = 1;
21918 linepos = BUF_BEGV (b);
21919 linepos_byte = BUF_BEGV_BYTE (b);
21920 }
21921
21922 /* Count lines from base line to window start position. */
21923 nlines = display_count_lines (linepos_byte,
21924 startpos_byte,
21925 startpos, &junk);
21926
21927 topline = nlines + line;
21928
21929 /* Determine a new base line, if the old one is too close
21930 or too far away, or if we did not have one.
21931 "Too close" means it's plausible a scroll-down would
21932 go back past it. */
21933 if (startpos == BUF_BEGV (b))
21934 {
21935 w->base_line_number = topline;
21936 w->base_line_pos = BUF_BEGV (b);
21937 }
21938 else if (nlines < height + 25 || nlines > height * 3 + 50
21939 || linepos == BUF_BEGV (b))
21940 {
21941 ptrdiff_t limit = BUF_BEGV (b);
21942 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21943 ptrdiff_t position;
21944 ptrdiff_t distance =
21945 (height * 2 + 30) * line_number_display_limit_width;
21946
21947 if (startpos - distance > limit)
21948 {
21949 limit = startpos - distance;
21950 limit_byte = CHAR_TO_BYTE (limit);
21951 }
21952
21953 nlines = display_count_lines (startpos_byte,
21954 limit_byte,
21955 - (height * 2 + 30),
21956 &position);
21957 /* If we couldn't find the lines we wanted within
21958 line_number_display_limit_width chars per line,
21959 give up on line numbers for this window. */
21960 if (position == limit_byte && limit == startpos - distance)
21961 {
21962 w->base_line_pos = -1;
21963 w->base_line_number = 0;
21964 goto no_value;
21965 }
21966
21967 w->base_line_number = topline - nlines;
21968 w->base_line_pos = BYTE_TO_CHAR (position);
21969 }
21970
21971 /* Now count lines from the start pos to point. */
21972 nlines = display_count_lines (startpos_byte,
21973 PT_BYTE, PT, &junk);
21974
21975 /* Record that we did display the line number. */
21976 line_number_displayed = 1;
21977
21978 /* Make the string to show. */
21979 pint2str (decode_mode_spec_buf, width, topline + nlines);
21980 return decode_mode_spec_buf;
21981 no_value:
21982 {
21983 char* p = decode_mode_spec_buf;
21984 int pad = width - 2;
21985 while (pad-- > 0)
21986 *p++ = ' ';
21987 *p++ = '?';
21988 *p++ = '?';
21989 *p = '\0';
21990 return decode_mode_spec_buf;
21991 }
21992 }
21993 break;
21994
21995 case 'm':
21996 obj = BVAR (b, mode_name);
21997 break;
21998
21999 case 'n':
22000 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
22001 return " Narrow";
22002 break;
22003
22004 case 'p':
22005 {
22006 ptrdiff_t pos = marker_position (w->start);
22007 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22008
22009 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
22010 {
22011 if (pos <= BUF_BEGV (b))
22012 return "All";
22013 else
22014 return "Bottom";
22015 }
22016 else if (pos <= BUF_BEGV (b))
22017 return "Top";
22018 else
22019 {
22020 if (total > 1000000)
22021 /* Do it differently for a large value, to avoid overflow. */
22022 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22023 else
22024 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
22025 /* We can't normally display a 3-digit number,
22026 so get us a 2-digit number that is close. */
22027 if (total == 100)
22028 total = 99;
22029 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22030 return decode_mode_spec_buf;
22031 }
22032 }
22033
22034 /* Display percentage of size above the bottom of the screen. */
22035 case 'P':
22036 {
22037 ptrdiff_t toppos = marker_position (w->start);
22038 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
22039 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22040
22041 if (botpos >= BUF_ZV (b))
22042 {
22043 if (toppos <= BUF_BEGV (b))
22044 return "All";
22045 else
22046 return "Bottom";
22047 }
22048 else
22049 {
22050 if (total > 1000000)
22051 /* Do it differently for a large value, to avoid overflow. */
22052 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
22053 else
22054 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
22055 /* We can't normally display a 3-digit number,
22056 so get us a 2-digit number that is close. */
22057 if (total == 100)
22058 total = 99;
22059 if (toppos <= BUF_BEGV (b))
22060 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
22061 else
22062 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
22063 return decode_mode_spec_buf;
22064 }
22065 }
22066
22067 case 's':
22068 /* status of process */
22069 obj = Fget_buffer_process (Fcurrent_buffer ());
22070 if (NILP (obj))
22071 return "no process";
22072 #ifndef MSDOS
22073 obj = Fsymbol_name (Fprocess_status (obj));
22074 #endif
22075 break;
22076
22077 case '@':
22078 {
22079 ptrdiff_t count = inhibit_garbage_collection ();
22080 Lisp_Object val = call1 (intern ("file-remote-p"),
22081 BVAR (current_buffer, directory));
22082 unbind_to (count, Qnil);
22083
22084 if (NILP (val))
22085 return "-";
22086 else
22087 return "@";
22088 }
22089
22090 case 'z':
22091 /* coding-system (not including end-of-line format) */
22092 case 'Z':
22093 /* coding-system (including end-of-line type) */
22094 {
22095 int eol_flag = (c == 'Z');
22096 char *p = decode_mode_spec_buf;
22097
22098 if (! FRAME_WINDOW_P (f))
22099 {
22100 /* No need to mention EOL here--the terminal never needs
22101 to do EOL conversion. */
22102 p = decode_mode_spec_coding (CODING_ID_NAME
22103 (FRAME_KEYBOARD_CODING (f)->id),
22104 p, 0);
22105 p = decode_mode_spec_coding (CODING_ID_NAME
22106 (FRAME_TERMINAL_CODING (f)->id),
22107 p, 0);
22108 }
22109 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
22110 p, eol_flag);
22111
22112 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22113 #ifdef subprocesses
22114 obj = Fget_buffer_process (Fcurrent_buffer ());
22115 if (PROCESSP (obj))
22116 {
22117 p = decode_mode_spec_coding
22118 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
22119 p = decode_mode_spec_coding
22120 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
22121 }
22122 #endif /* subprocesses */
22123 #endif /* 0 */
22124 *p = 0;
22125 return decode_mode_spec_buf;
22126 }
22127 }
22128
22129 if (STRINGP (obj))
22130 {
22131 *string = obj;
22132 return SSDATA (obj);
22133 }
22134 else
22135 return "";
22136 }
22137
22138
22139 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22140 means count lines back from START_BYTE. But don't go beyond
22141 LIMIT_BYTE. Return the number of lines thus found (always
22142 nonnegative).
22143
22144 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22145 either the position COUNT lines after/before START_BYTE, if we
22146 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22147 COUNT lines. */
22148
22149 static ptrdiff_t
22150 display_count_lines (ptrdiff_t start_byte,
22151 ptrdiff_t limit_byte, ptrdiff_t count,
22152 ptrdiff_t *byte_pos_ptr)
22153 {
22154 register unsigned char *cursor;
22155 unsigned char *base;
22156
22157 register ptrdiff_t ceiling;
22158 register unsigned char *ceiling_addr;
22159 ptrdiff_t orig_count = count;
22160
22161 /* If we are not in selective display mode,
22162 check only for newlines. */
22163 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
22164 && !INTEGERP (BVAR (current_buffer, selective_display)));
22165
22166 if (count > 0)
22167 {
22168 while (start_byte < limit_byte)
22169 {
22170 ceiling = BUFFER_CEILING_OF (start_byte);
22171 ceiling = min (limit_byte - 1, ceiling);
22172 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
22173 base = (cursor = BYTE_POS_ADDR (start_byte));
22174
22175 do
22176 {
22177 if (selective_display)
22178 {
22179 while (*cursor != '\n' && *cursor != 015
22180 && ++cursor != ceiling_addr)
22181 continue;
22182 if (cursor == ceiling_addr)
22183 break;
22184 }
22185 else
22186 {
22187 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
22188 if (! cursor)
22189 break;
22190 }
22191
22192 cursor++;
22193
22194 if (--count == 0)
22195 {
22196 start_byte += cursor - base;
22197 *byte_pos_ptr = start_byte;
22198 return orig_count;
22199 }
22200 }
22201 while (cursor < ceiling_addr);
22202
22203 start_byte += ceiling_addr - base;
22204 }
22205 }
22206 else
22207 {
22208 while (start_byte > limit_byte)
22209 {
22210 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
22211 ceiling = max (limit_byte, ceiling);
22212 ceiling_addr = BYTE_POS_ADDR (ceiling);
22213 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
22214 while (1)
22215 {
22216 if (selective_display)
22217 {
22218 while (--cursor >= ceiling_addr
22219 && *cursor != '\n' && *cursor != 015)
22220 continue;
22221 if (cursor < ceiling_addr)
22222 break;
22223 }
22224 else
22225 {
22226 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
22227 if (! cursor)
22228 break;
22229 }
22230
22231 if (++count == 0)
22232 {
22233 start_byte += cursor - base + 1;
22234 *byte_pos_ptr = start_byte;
22235 /* When scanning backwards, we should
22236 not count the newline posterior to which we stop. */
22237 return - orig_count - 1;
22238 }
22239 }
22240 start_byte += ceiling_addr - base;
22241 }
22242 }
22243
22244 *byte_pos_ptr = limit_byte;
22245
22246 if (count < 0)
22247 return - orig_count + count;
22248 return orig_count - count;
22249
22250 }
22251
22252
22253 \f
22254 /***********************************************************************
22255 Displaying strings
22256 ***********************************************************************/
22257
22258 /* Display a NUL-terminated string, starting with index START.
22259
22260 If STRING is non-null, display that C string. Otherwise, the Lisp
22261 string LISP_STRING is displayed. There's a case that STRING is
22262 non-null and LISP_STRING is not nil. It means STRING is a string
22263 data of LISP_STRING. In that case, we display LISP_STRING while
22264 ignoring its text properties.
22265
22266 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22267 FACE_STRING. Display STRING or LISP_STRING with the face at
22268 FACE_STRING_POS in FACE_STRING:
22269
22270 Display the string in the environment given by IT, but use the
22271 standard display table, temporarily.
22272
22273 FIELD_WIDTH is the minimum number of output glyphs to produce.
22274 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22275 with spaces. If STRING has more characters, more than FIELD_WIDTH
22276 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22277
22278 PRECISION is the maximum number of characters to output from
22279 STRING. PRECISION < 0 means don't truncate the string.
22280
22281 This is roughly equivalent to printf format specifiers:
22282
22283 FIELD_WIDTH PRECISION PRINTF
22284 ----------------------------------------
22285 -1 -1 %s
22286 -1 10 %.10s
22287 10 -1 %10s
22288 20 10 %20.10s
22289
22290 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22291 display them, and < 0 means obey the current buffer's value of
22292 enable_multibyte_characters.
22293
22294 Value is the number of columns displayed. */
22295
22296 static int
22297 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
22298 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
22299 int field_width, int precision, int max_x, int multibyte)
22300 {
22301 int hpos_at_start = it->hpos;
22302 int saved_face_id = it->face_id;
22303 struct glyph_row *row = it->glyph_row;
22304 ptrdiff_t it_charpos;
22305
22306 /* Initialize the iterator IT for iteration over STRING beginning
22307 with index START. */
22308 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22309 precision, field_width, multibyte);
22310 if (string && STRINGP (lisp_string))
22311 /* LISP_STRING is the one returned by decode_mode_spec. We should
22312 ignore its text properties. */
22313 it->stop_charpos = it->end_charpos;
22314
22315 /* If displaying STRING, set up the face of the iterator from
22316 FACE_STRING, if that's given. */
22317 if (STRINGP (face_string))
22318 {
22319 ptrdiff_t endptr;
22320 struct face *face;
22321
22322 it->face_id
22323 = face_at_string_position (it->w, face_string, face_string_pos,
22324 0, it->region_beg_charpos,
22325 it->region_end_charpos,
22326 &endptr, it->base_face_id, 0);
22327 face = FACE_FROM_ID (it->f, it->face_id);
22328 it->face_box_p = face->box != FACE_NO_BOX;
22329 }
22330
22331 /* Set max_x to the maximum allowed X position. Don't let it go
22332 beyond the right edge of the window. */
22333 if (max_x <= 0)
22334 max_x = it->last_visible_x;
22335 else
22336 max_x = min (max_x, it->last_visible_x);
22337
22338 /* Skip over display elements that are not visible. because IT->w is
22339 hscrolled. */
22340 if (it->current_x < it->first_visible_x)
22341 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22342 MOVE_TO_POS | MOVE_TO_X);
22343
22344 row->ascent = it->max_ascent;
22345 row->height = it->max_ascent + it->max_descent;
22346 row->phys_ascent = it->max_phys_ascent;
22347 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22348 row->extra_line_spacing = it->max_extra_line_spacing;
22349
22350 if (STRINGP (it->string))
22351 it_charpos = IT_STRING_CHARPOS (*it);
22352 else
22353 it_charpos = IT_CHARPOS (*it);
22354
22355 /* This condition is for the case that we are called with current_x
22356 past last_visible_x. */
22357 while (it->current_x < max_x)
22358 {
22359 int x_before, x, n_glyphs_before, i, nglyphs;
22360
22361 /* Get the next display element. */
22362 if (!get_next_display_element (it))
22363 break;
22364
22365 /* Produce glyphs. */
22366 x_before = it->current_x;
22367 n_glyphs_before = row->used[TEXT_AREA];
22368 PRODUCE_GLYPHS (it);
22369
22370 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22371 i = 0;
22372 x = x_before;
22373 while (i < nglyphs)
22374 {
22375 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22376
22377 if (it->line_wrap != TRUNCATE
22378 && x + glyph->pixel_width > max_x)
22379 {
22380 /* End of continued line or max_x reached. */
22381 if (CHAR_GLYPH_PADDING_P (*glyph))
22382 {
22383 /* A wide character is unbreakable. */
22384 if (row->reversed_p)
22385 unproduce_glyphs (it, row->used[TEXT_AREA]
22386 - n_glyphs_before);
22387 row->used[TEXT_AREA] = n_glyphs_before;
22388 it->current_x = x_before;
22389 }
22390 else
22391 {
22392 if (row->reversed_p)
22393 unproduce_glyphs (it, row->used[TEXT_AREA]
22394 - (n_glyphs_before + i));
22395 row->used[TEXT_AREA] = n_glyphs_before + i;
22396 it->current_x = x;
22397 }
22398 break;
22399 }
22400 else if (x + glyph->pixel_width >= it->first_visible_x)
22401 {
22402 /* Glyph is at least partially visible. */
22403 ++it->hpos;
22404 if (x < it->first_visible_x)
22405 row->x = x - it->first_visible_x;
22406 }
22407 else
22408 {
22409 /* Glyph is off the left margin of the display area.
22410 Should not happen. */
22411 emacs_abort ();
22412 }
22413
22414 row->ascent = max (row->ascent, it->max_ascent);
22415 row->height = max (row->height, it->max_ascent + it->max_descent);
22416 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22417 row->phys_height = max (row->phys_height,
22418 it->max_phys_ascent + it->max_phys_descent);
22419 row->extra_line_spacing = max (row->extra_line_spacing,
22420 it->max_extra_line_spacing);
22421 x += glyph->pixel_width;
22422 ++i;
22423 }
22424
22425 /* Stop if max_x reached. */
22426 if (i < nglyphs)
22427 break;
22428
22429 /* Stop at line ends. */
22430 if (ITERATOR_AT_END_OF_LINE_P (it))
22431 {
22432 it->continuation_lines_width = 0;
22433 break;
22434 }
22435
22436 set_iterator_to_next (it, 1);
22437 if (STRINGP (it->string))
22438 it_charpos = IT_STRING_CHARPOS (*it);
22439 else
22440 it_charpos = IT_CHARPOS (*it);
22441
22442 /* Stop if truncating at the right edge. */
22443 if (it->line_wrap == TRUNCATE
22444 && it->current_x >= it->last_visible_x)
22445 {
22446 /* Add truncation mark, but don't do it if the line is
22447 truncated at a padding space. */
22448 if (it_charpos < it->string_nchars)
22449 {
22450 if (!FRAME_WINDOW_P (it->f))
22451 {
22452 int ii, n;
22453
22454 if (it->current_x > it->last_visible_x)
22455 {
22456 if (!row->reversed_p)
22457 {
22458 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22459 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22460 break;
22461 }
22462 else
22463 {
22464 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22465 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22466 break;
22467 unproduce_glyphs (it, ii + 1);
22468 ii = row->used[TEXT_AREA] - (ii + 1);
22469 }
22470 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22471 {
22472 row->used[TEXT_AREA] = ii;
22473 produce_special_glyphs (it, IT_TRUNCATION);
22474 }
22475 }
22476 produce_special_glyphs (it, IT_TRUNCATION);
22477 }
22478 row->truncated_on_right_p = 1;
22479 }
22480 break;
22481 }
22482 }
22483
22484 /* Maybe insert a truncation at the left. */
22485 if (it->first_visible_x
22486 && it_charpos > 0)
22487 {
22488 if (!FRAME_WINDOW_P (it->f)
22489 || (row->reversed_p
22490 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22491 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22492 insert_left_trunc_glyphs (it);
22493 row->truncated_on_left_p = 1;
22494 }
22495
22496 it->face_id = saved_face_id;
22497
22498 /* Value is number of columns displayed. */
22499 return it->hpos - hpos_at_start;
22500 }
22501
22502
22503 \f
22504 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22505 appears as an element of LIST or as the car of an element of LIST.
22506 If PROPVAL is a list, compare each element against LIST in that
22507 way, and return 1/2 if any element of PROPVAL is found in LIST.
22508 Otherwise return 0. This function cannot quit.
22509 The return value is 2 if the text is invisible but with an ellipsis
22510 and 1 if it's invisible and without an ellipsis. */
22511
22512 int
22513 invisible_p (register Lisp_Object propval, Lisp_Object list)
22514 {
22515 register Lisp_Object tail, proptail;
22516
22517 for (tail = list; CONSP (tail); tail = XCDR (tail))
22518 {
22519 register Lisp_Object tem;
22520 tem = XCAR (tail);
22521 if (EQ (propval, tem))
22522 return 1;
22523 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22524 return NILP (XCDR (tem)) ? 1 : 2;
22525 }
22526
22527 if (CONSP (propval))
22528 {
22529 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22530 {
22531 Lisp_Object propelt;
22532 propelt = XCAR (proptail);
22533 for (tail = list; CONSP (tail); tail = XCDR (tail))
22534 {
22535 register Lisp_Object tem;
22536 tem = XCAR (tail);
22537 if (EQ (propelt, tem))
22538 return 1;
22539 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22540 return NILP (XCDR (tem)) ? 1 : 2;
22541 }
22542 }
22543 }
22544
22545 return 0;
22546 }
22547
22548 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22549 doc: /* Non-nil if the property makes the text invisible.
22550 POS-OR-PROP can be a marker or number, in which case it is taken to be
22551 a position in the current buffer and the value of the `invisible' property
22552 is checked; or it can be some other value, which is then presumed to be the
22553 value of the `invisible' property of the text of interest.
22554 The non-nil value returned can be t for truly invisible text or something
22555 else if the text is replaced by an ellipsis. */)
22556 (Lisp_Object pos_or_prop)
22557 {
22558 Lisp_Object prop
22559 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22560 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22561 : pos_or_prop);
22562 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22563 return (invis == 0 ? Qnil
22564 : invis == 1 ? Qt
22565 : make_number (invis));
22566 }
22567
22568 /* Calculate a width or height in pixels from a specification using
22569 the following elements:
22570
22571 SPEC ::=
22572 NUM - a (fractional) multiple of the default font width/height
22573 (NUM) - specifies exactly NUM pixels
22574 UNIT - a fixed number of pixels, see below.
22575 ELEMENT - size of a display element in pixels, see below.
22576 (NUM . SPEC) - equals NUM * SPEC
22577 (+ SPEC SPEC ...) - add pixel values
22578 (- SPEC SPEC ...) - subtract pixel values
22579 (- SPEC) - negate pixel value
22580
22581 NUM ::=
22582 INT or FLOAT - a number constant
22583 SYMBOL - use symbol's (buffer local) variable binding.
22584
22585 UNIT ::=
22586 in - pixels per inch *)
22587 mm - pixels per 1/1000 meter *)
22588 cm - pixels per 1/100 meter *)
22589 width - width of current font in pixels.
22590 height - height of current font in pixels.
22591
22592 *) using the ratio(s) defined in display-pixels-per-inch.
22593
22594 ELEMENT ::=
22595
22596 left-fringe - left fringe width in pixels
22597 right-fringe - right fringe width in pixels
22598
22599 left-margin - left margin width in pixels
22600 right-margin - right margin width in pixels
22601
22602 scroll-bar - scroll-bar area width in pixels
22603
22604 Examples:
22605
22606 Pixels corresponding to 5 inches:
22607 (5 . in)
22608
22609 Total width of non-text areas on left side of window (if scroll-bar is on left):
22610 '(space :width (+ left-fringe left-margin scroll-bar))
22611
22612 Align to first text column (in header line):
22613 '(space :align-to 0)
22614
22615 Align to middle of text area minus half the width of variable `my-image'
22616 containing a loaded image:
22617 '(space :align-to (0.5 . (- text my-image)))
22618
22619 Width of left margin minus width of 1 character in the default font:
22620 '(space :width (- left-margin 1))
22621
22622 Width of left margin minus width of 2 characters in the current font:
22623 '(space :width (- left-margin (2 . width)))
22624
22625 Center 1 character over left-margin (in header line):
22626 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22627
22628 Different ways to express width of left fringe plus left margin minus one pixel:
22629 '(space :width (- (+ left-fringe left-margin) (1)))
22630 '(space :width (+ left-fringe left-margin (- (1))))
22631 '(space :width (+ left-fringe left-margin (-1)))
22632
22633 */
22634
22635 static int
22636 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22637 struct font *font, int width_p, int *align_to)
22638 {
22639 double pixels;
22640
22641 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22642 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22643
22644 if (NILP (prop))
22645 return OK_PIXELS (0);
22646
22647 eassert (FRAME_LIVE_P (it->f));
22648
22649 if (SYMBOLP (prop))
22650 {
22651 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22652 {
22653 char *unit = SSDATA (SYMBOL_NAME (prop));
22654
22655 if (unit[0] == 'i' && unit[1] == 'n')
22656 pixels = 1.0;
22657 else if (unit[0] == 'm' && unit[1] == 'm')
22658 pixels = 25.4;
22659 else if (unit[0] == 'c' && unit[1] == 'm')
22660 pixels = 2.54;
22661 else
22662 pixels = 0;
22663 if (pixels > 0)
22664 {
22665 double ppi = (width_p ? FRAME_RES_X (it->f)
22666 : FRAME_RES_Y (it->f));
22667
22668 if (ppi > 0)
22669 return OK_PIXELS (ppi / pixels);
22670 return 0;
22671 }
22672 }
22673
22674 #ifdef HAVE_WINDOW_SYSTEM
22675 if (EQ (prop, Qheight))
22676 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22677 if (EQ (prop, Qwidth))
22678 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22679 #else
22680 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22681 return OK_PIXELS (1);
22682 #endif
22683
22684 if (EQ (prop, Qtext))
22685 return OK_PIXELS (width_p
22686 ? window_box_width (it->w, TEXT_AREA)
22687 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22688
22689 if (align_to && *align_to < 0)
22690 {
22691 *res = 0;
22692 if (EQ (prop, Qleft))
22693 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22694 if (EQ (prop, Qright))
22695 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22696 if (EQ (prop, Qcenter))
22697 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22698 + window_box_width (it->w, TEXT_AREA) / 2);
22699 if (EQ (prop, Qleft_fringe))
22700 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22701 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22702 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22703 if (EQ (prop, Qright_fringe))
22704 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22705 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22706 : window_box_right_offset (it->w, TEXT_AREA));
22707 if (EQ (prop, Qleft_margin))
22708 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22709 if (EQ (prop, Qright_margin))
22710 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22711 if (EQ (prop, Qscroll_bar))
22712 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22713 ? 0
22714 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22715 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22716 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22717 : 0)));
22718 }
22719 else
22720 {
22721 if (EQ (prop, Qleft_fringe))
22722 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22723 if (EQ (prop, Qright_fringe))
22724 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22725 if (EQ (prop, Qleft_margin))
22726 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22727 if (EQ (prop, Qright_margin))
22728 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22729 if (EQ (prop, Qscroll_bar))
22730 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22731 }
22732
22733 prop = buffer_local_value_1 (prop, it->w->contents);
22734 if (EQ (prop, Qunbound))
22735 prop = Qnil;
22736 }
22737
22738 if (INTEGERP (prop) || FLOATP (prop))
22739 {
22740 int base_unit = (width_p
22741 ? FRAME_COLUMN_WIDTH (it->f)
22742 : FRAME_LINE_HEIGHT (it->f));
22743 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22744 }
22745
22746 if (CONSP (prop))
22747 {
22748 Lisp_Object car = XCAR (prop);
22749 Lisp_Object cdr = XCDR (prop);
22750
22751 if (SYMBOLP (car))
22752 {
22753 #ifdef HAVE_WINDOW_SYSTEM
22754 if (FRAME_WINDOW_P (it->f)
22755 && valid_image_p (prop))
22756 {
22757 ptrdiff_t id = lookup_image (it->f, prop);
22758 struct image *img = IMAGE_FROM_ID (it->f, id);
22759
22760 return OK_PIXELS (width_p ? img->width : img->height);
22761 }
22762 #endif
22763 if (EQ (car, Qplus) || EQ (car, Qminus))
22764 {
22765 int first = 1;
22766 double px;
22767
22768 pixels = 0;
22769 while (CONSP (cdr))
22770 {
22771 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22772 font, width_p, align_to))
22773 return 0;
22774 if (first)
22775 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22776 else
22777 pixels += px;
22778 cdr = XCDR (cdr);
22779 }
22780 if (EQ (car, Qminus))
22781 pixels = -pixels;
22782 return OK_PIXELS (pixels);
22783 }
22784
22785 car = buffer_local_value_1 (car, it->w->contents);
22786 if (EQ (car, Qunbound))
22787 car = Qnil;
22788 }
22789
22790 if (INTEGERP (car) || FLOATP (car))
22791 {
22792 double fact;
22793 pixels = XFLOATINT (car);
22794 if (NILP (cdr))
22795 return OK_PIXELS (pixels);
22796 if (calc_pixel_width_or_height (&fact, it, cdr,
22797 font, width_p, align_to))
22798 return OK_PIXELS (pixels * fact);
22799 return 0;
22800 }
22801
22802 return 0;
22803 }
22804
22805 return 0;
22806 }
22807
22808 \f
22809 /***********************************************************************
22810 Glyph Display
22811 ***********************************************************************/
22812
22813 #ifdef HAVE_WINDOW_SYSTEM
22814
22815 #ifdef GLYPH_DEBUG
22816
22817 void
22818 dump_glyph_string (struct glyph_string *s)
22819 {
22820 fprintf (stderr, "glyph string\n");
22821 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22822 s->x, s->y, s->width, s->height);
22823 fprintf (stderr, " ybase = %d\n", s->ybase);
22824 fprintf (stderr, " hl = %d\n", s->hl);
22825 fprintf (stderr, " left overhang = %d, right = %d\n",
22826 s->left_overhang, s->right_overhang);
22827 fprintf (stderr, " nchars = %d\n", s->nchars);
22828 fprintf (stderr, " extends to end of line = %d\n",
22829 s->extends_to_end_of_line_p);
22830 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22831 fprintf (stderr, " bg width = %d\n", s->background_width);
22832 }
22833
22834 #endif /* GLYPH_DEBUG */
22835
22836 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22837 of XChar2b structures for S; it can't be allocated in
22838 init_glyph_string because it must be allocated via `alloca'. W
22839 is the window on which S is drawn. ROW and AREA are the glyph row
22840 and area within the row from which S is constructed. START is the
22841 index of the first glyph structure covered by S. HL is a
22842 face-override for drawing S. */
22843
22844 #ifdef HAVE_NTGUI
22845 #define OPTIONAL_HDC(hdc) HDC hdc,
22846 #define DECLARE_HDC(hdc) HDC hdc;
22847 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22848 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22849 #endif
22850
22851 #ifndef OPTIONAL_HDC
22852 #define OPTIONAL_HDC(hdc)
22853 #define DECLARE_HDC(hdc)
22854 #define ALLOCATE_HDC(hdc, f)
22855 #define RELEASE_HDC(hdc, f)
22856 #endif
22857
22858 static void
22859 init_glyph_string (struct glyph_string *s,
22860 OPTIONAL_HDC (hdc)
22861 XChar2b *char2b, struct window *w, struct glyph_row *row,
22862 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22863 {
22864 memset (s, 0, sizeof *s);
22865 s->w = w;
22866 s->f = XFRAME (w->frame);
22867 #ifdef HAVE_NTGUI
22868 s->hdc = hdc;
22869 #endif
22870 s->display = FRAME_X_DISPLAY (s->f);
22871 s->window = FRAME_X_WINDOW (s->f);
22872 s->char2b = char2b;
22873 s->hl = hl;
22874 s->row = row;
22875 s->area = area;
22876 s->first_glyph = row->glyphs[area] + start;
22877 s->height = row->height;
22878 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22879 s->ybase = s->y + row->ascent;
22880 }
22881
22882
22883 /* Append the list of glyph strings with head H and tail T to the list
22884 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22885
22886 static void
22887 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22888 struct glyph_string *h, struct glyph_string *t)
22889 {
22890 if (h)
22891 {
22892 if (*head)
22893 (*tail)->next = h;
22894 else
22895 *head = h;
22896 h->prev = *tail;
22897 *tail = t;
22898 }
22899 }
22900
22901
22902 /* Prepend the list of glyph strings with head H and tail T to the
22903 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22904 result. */
22905
22906 static void
22907 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22908 struct glyph_string *h, struct glyph_string *t)
22909 {
22910 if (h)
22911 {
22912 if (*head)
22913 (*head)->prev = t;
22914 else
22915 *tail = t;
22916 t->next = *head;
22917 *head = h;
22918 }
22919 }
22920
22921
22922 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22923 Set *HEAD and *TAIL to the resulting list. */
22924
22925 static void
22926 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22927 struct glyph_string *s)
22928 {
22929 s->next = s->prev = NULL;
22930 append_glyph_string_lists (head, tail, s, s);
22931 }
22932
22933
22934 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22935 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22936 make sure that X resources for the face returned are allocated.
22937 Value is a pointer to a realized face that is ready for display if
22938 DISPLAY_P is non-zero. */
22939
22940 static struct face *
22941 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22942 XChar2b *char2b, int display_p)
22943 {
22944 struct face *face = FACE_FROM_ID (f, face_id);
22945 unsigned code = 0;
22946
22947 if (face->font)
22948 {
22949 code = face->font->driver->encode_char (face->font, c);
22950
22951 if (code == FONT_INVALID_CODE)
22952 code = 0;
22953 }
22954 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22955
22956 /* Make sure X resources of the face are allocated. */
22957 #ifdef HAVE_X_WINDOWS
22958 if (display_p)
22959 #endif
22960 {
22961 eassert (face != NULL);
22962 PREPARE_FACE_FOR_DISPLAY (f, face);
22963 }
22964
22965 return face;
22966 }
22967
22968
22969 /* Get face and two-byte form of character glyph GLYPH on frame F.
22970 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22971 a pointer to a realized face that is ready for display. */
22972
22973 static struct face *
22974 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22975 XChar2b *char2b, int *two_byte_p)
22976 {
22977 struct face *face;
22978 unsigned code = 0;
22979
22980 eassert (glyph->type == CHAR_GLYPH);
22981 face = FACE_FROM_ID (f, glyph->face_id);
22982
22983 /* Make sure X resources of the face are allocated. */
22984 eassert (face != NULL);
22985 PREPARE_FACE_FOR_DISPLAY (f, face);
22986
22987 if (two_byte_p)
22988 *two_byte_p = 0;
22989
22990 if (face->font)
22991 {
22992 if (CHAR_BYTE8_P (glyph->u.ch))
22993 code = CHAR_TO_BYTE8 (glyph->u.ch);
22994 else
22995 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22996
22997 if (code == FONT_INVALID_CODE)
22998 code = 0;
22999 }
23000
23001 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23002 return face;
23003 }
23004
23005
23006 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
23007 Return 1 if FONT has a glyph for C, otherwise return 0. */
23008
23009 static int
23010 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
23011 {
23012 unsigned code;
23013
23014 if (CHAR_BYTE8_P (c))
23015 code = CHAR_TO_BYTE8 (c);
23016 else
23017 code = font->driver->encode_char (font, c);
23018
23019 if (code == FONT_INVALID_CODE)
23020 return 0;
23021 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
23022 return 1;
23023 }
23024
23025
23026 /* Fill glyph string S with composition components specified by S->cmp.
23027
23028 BASE_FACE is the base face of the composition.
23029 S->cmp_from is the index of the first component for S.
23030
23031 OVERLAPS non-zero means S should draw the foreground only, and use
23032 its physical height for clipping. See also draw_glyphs.
23033
23034 Value is the index of a component not in S. */
23035
23036 static int
23037 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
23038 int overlaps)
23039 {
23040 int i;
23041 /* For all glyphs of this composition, starting at the offset
23042 S->cmp_from, until we reach the end of the definition or encounter a
23043 glyph that requires the different face, add it to S. */
23044 struct face *face;
23045
23046 eassert (s);
23047
23048 s->for_overlaps = overlaps;
23049 s->face = NULL;
23050 s->font = NULL;
23051 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
23052 {
23053 int c = COMPOSITION_GLYPH (s->cmp, i);
23054
23055 /* TAB in a composition means display glyphs with padding space
23056 on the left or right. */
23057 if (c != '\t')
23058 {
23059 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
23060 -1, Qnil);
23061
23062 face = get_char_face_and_encoding (s->f, c, face_id,
23063 s->char2b + i, 1);
23064 if (face)
23065 {
23066 if (! s->face)
23067 {
23068 s->face = face;
23069 s->font = s->face->font;
23070 }
23071 else if (s->face != face)
23072 break;
23073 }
23074 }
23075 ++s->nchars;
23076 }
23077 s->cmp_to = i;
23078
23079 if (s->face == NULL)
23080 {
23081 s->face = base_face->ascii_face;
23082 s->font = s->face->font;
23083 }
23084
23085 /* All glyph strings for the same composition has the same width,
23086 i.e. the width set for the first component of the composition. */
23087 s->width = s->first_glyph->pixel_width;
23088
23089 /* If the specified font could not be loaded, use the frame's
23090 default font, but record the fact that we couldn't load it in
23091 the glyph string so that we can draw rectangles for the
23092 characters of the glyph string. */
23093 if (s->font == NULL)
23094 {
23095 s->font_not_found_p = 1;
23096 s->font = FRAME_FONT (s->f);
23097 }
23098
23099 /* Adjust base line for subscript/superscript text. */
23100 s->ybase += s->first_glyph->voffset;
23101
23102 /* This glyph string must always be drawn with 16-bit functions. */
23103 s->two_byte_p = 1;
23104
23105 return s->cmp_to;
23106 }
23107
23108 static int
23109 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
23110 int start, int end, int overlaps)
23111 {
23112 struct glyph *glyph, *last;
23113 Lisp_Object lgstring;
23114 int i;
23115
23116 s->for_overlaps = overlaps;
23117 glyph = s->row->glyphs[s->area] + start;
23118 last = s->row->glyphs[s->area] + end;
23119 s->cmp_id = glyph->u.cmp.id;
23120 s->cmp_from = glyph->slice.cmp.from;
23121 s->cmp_to = glyph->slice.cmp.to + 1;
23122 s->face = FACE_FROM_ID (s->f, face_id);
23123 lgstring = composition_gstring_from_id (s->cmp_id);
23124 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
23125 glyph++;
23126 while (glyph < last
23127 && glyph->u.cmp.automatic
23128 && glyph->u.cmp.id == s->cmp_id
23129 && s->cmp_to == glyph->slice.cmp.from)
23130 s->cmp_to = (glyph++)->slice.cmp.to + 1;
23131
23132 for (i = s->cmp_from; i < s->cmp_to; i++)
23133 {
23134 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
23135 unsigned code = LGLYPH_CODE (lglyph);
23136
23137 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
23138 }
23139 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
23140 return glyph - s->row->glyphs[s->area];
23141 }
23142
23143
23144 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23145 See the comment of fill_glyph_string for arguments.
23146 Value is the index of the first glyph not in S. */
23147
23148
23149 static int
23150 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
23151 int start, int end, int overlaps)
23152 {
23153 struct glyph *glyph, *last;
23154 int voffset;
23155
23156 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
23157 s->for_overlaps = overlaps;
23158 glyph = s->row->glyphs[s->area] + start;
23159 last = s->row->glyphs[s->area] + end;
23160 voffset = glyph->voffset;
23161 s->face = FACE_FROM_ID (s->f, face_id);
23162 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
23163 s->nchars = 1;
23164 s->width = glyph->pixel_width;
23165 glyph++;
23166 while (glyph < last
23167 && glyph->type == GLYPHLESS_GLYPH
23168 && glyph->voffset == voffset
23169 && glyph->face_id == face_id)
23170 {
23171 s->nchars++;
23172 s->width += glyph->pixel_width;
23173 glyph++;
23174 }
23175 s->ybase += voffset;
23176 return glyph - s->row->glyphs[s->area];
23177 }
23178
23179
23180 /* Fill glyph string S from a sequence of character glyphs.
23181
23182 FACE_ID is the face id of the string. START is the index of the
23183 first glyph to consider, END is the index of the last + 1.
23184 OVERLAPS non-zero means S should draw the foreground only, and use
23185 its physical height for clipping. See also draw_glyphs.
23186
23187 Value is the index of the first glyph not in S. */
23188
23189 static int
23190 fill_glyph_string (struct glyph_string *s, int face_id,
23191 int start, int end, int overlaps)
23192 {
23193 struct glyph *glyph, *last;
23194 int voffset;
23195 int glyph_not_available_p;
23196
23197 eassert (s->f == XFRAME (s->w->frame));
23198 eassert (s->nchars == 0);
23199 eassert (start >= 0 && end > start);
23200
23201 s->for_overlaps = overlaps;
23202 glyph = s->row->glyphs[s->area] + start;
23203 last = s->row->glyphs[s->area] + end;
23204 voffset = glyph->voffset;
23205 s->padding_p = glyph->padding_p;
23206 glyph_not_available_p = glyph->glyph_not_available_p;
23207
23208 while (glyph < last
23209 && glyph->type == CHAR_GLYPH
23210 && glyph->voffset == voffset
23211 /* Same face id implies same font, nowadays. */
23212 && glyph->face_id == face_id
23213 && glyph->glyph_not_available_p == glyph_not_available_p)
23214 {
23215 int two_byte_p;
23216
23217 s->face = get_glyph_face_and_encoding (s->f, glyph,
23218 s->char2b + s->nchars,
23219 &two_byte_p);
23220 s->two_byte_p = two_byte_p;
23221 ++s->nchars;
23222 eassert (s->nchars <= end - start);
23223 s->width += glyph->pixel_width;
23224 if (glyph++->padding_p != s->padding_p)
23225 break;
23226 }
23227
23228 s->font = s->face->font;
23229
23230 /* If the specified font could not be loaded, use the frame's font,
23231 but record the fact that we couldn't load it in
23232 S->font_not_found_p so that we can draw rectangles for the
23233 characters of the glyph string. */
23234 if (s->font == NULL || glyph_not_available_p)
23235 {
23236 s->font_not_found_p = 1;
23237 s->font = FRAME_FONT (s->f);
23238 }
23239
23240 /* Adjust base line for subscript/superscript text. */
23241 s->ybase += voffset;
23242
23243 eassert (s->face && s->face->gc);
23244 return glyph - s->row->glyphs[s->area];
23245 }
23246
23247
23248 /* Fill glyph string S from image glyph S->first_glyph. */
23249
23250 static void
23251 fill_image_glyph_string (struct glyph_string *s)
23252 {
23253 eassert (s->first_glyph->type == IMAGE_GLYPH);
23254 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
23255 eassert (s->img);
23256 s->slice = s->first_glyph->slice.img;
23257 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
23258 s->font = s->face->font;
23259 s->width = s->first_glyph->pixel_width;
23260
23261 /* Adjust base line for subscript/superscript text. */
23262 s->ybase += s->first_glyph->voffset;
23263 }
23264
23265
23266 /* Fill glyph string S from a sequence of stretch glyphs.
23267
23268 START is the index of the first glyph to consider,
23269 END is the index of the last + 1.
23270
23271 Value is the index of the first glyph not in S. */
23272
23273 static int
23274 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23275 {
23276 struct glyph *glyph, *last;
23277 int voffset, face_id;
23278
23279 eassert (s->first_glyph->type == STRETCH_GLYPH);
23280
23281 glyph = s->row->glyphs[s->area] + start;
23282 last = s->row->glyphs[s->area] + end;
23283 face_id = glyph->face_id;
23284 s->face = FACE_FROM_ID (s->f, face_id);
23285 s->font = s->face->font;
23286 s->width = glyph->pixel_width;
23287 s->nchars = 1;
23288 voffset = glyph->voffset;
23289
23290 for (++glyph;
23291 (glyph < last
23292 && glyph->type == STRETCH_GLYPH
23293 && glyph->voffset == voffset
23294 && glyph->face_id == face_id);
23295 ++glyph)
23296 s->width += glyph->pixel_width;
23297
23298 /* Adjust base line for subscript/superscript text. */
23299 s->ybase += voffset;
23300
23301 /* The case that face->gc == 0 is handled when drawing the glyph
23302 string by calling PREPARE_FACE_FOR_DISPLAY. */
23303 eassert (s->face);
23304 return glyph - s->row->glyphs[s->area];
23305 }
23306
23307 static struct font_metrics *
23308 get_per_char_metric (struct font *font, XChar2b *char2b)
23309 {
23310 static struct font_metrics metrics;
23311 unsigned code;
23312
23313 if (! font)
23314 return NULL;
23315 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23316 if (code == FONT_INVALID_CODE)
23317 return NULL;
23318 font->driver->text_extents (font, &code, 1, &metrics);
23319 return &metrics;
23320 }
23321
23322 /* EXPORT for RIF:
23323 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23324 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23325 assumed to be zero. */
23326
23327 void
23328 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23329 {
23330 *left = *right = 0;
23331
23332 if (glyph->type == CHAR_GLYPH)
23333 {
23334 struct face *face;
23335 XChar2b char2b;
23336 struct font_metrics *pcm;
23337
23338 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23339 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23340 {
23341 if (pcm->rbearing > pcm->width)
23342 *right = pcm->rbearing - pcm->width;
23343 if (pcm->lbearing < 0)
23344 *left = -pcm->lbearing;
23345 }
23346 }
23347 else if (glyph->type == COMPOSITE_GLYPH)
23348 {
23349 if (! glyph->u.cmp.automatic)
23350 {
23351 struct composition *cmp = composition_table[glyph->u.cmp.id];
23352
23353 if (cmp->rbearing > cmp->pixel_width)
23354 *right = cmp->rbearing - cmp->pixel_width;
23355 if (cmp->lbearing < 0)
23356 *left = - cmp->lbearing;
23357 }
23358 else
23359 {
23360 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23361 struct font_metrics metrics;
23362
23363 composition_gstring_width (gstring, glyph->slice.cmp.from,
23364 glyph->slice.cmp.to + 1, &metrics);
23365 if (metrics.rbearing > metrics.width)
23366 *right = metrics.rbearing - metrics.width;
23367 if (metrics.lbearing < 0)
23368 *left = - metrics.lbearing;
23369 }
23370 }
23371 }
23372
23373
23374 /* Return the index of the first glyph preceding glyph string S that
23375 is overwritten by S because of S's left overhang. Value is -1
23376 if no glyphs are overwritten. */
23377
23378 static int
23379 left_overwritten (struct glyph_string *s)
23380 {
23381 int k;
23382
23383 if (s->left_overhang)
23384 {
23385 int x = 0, i;
23386 struct glyph *glyphs = s->row->glyphs[s->area];
23387 int first = s->first_glyph - glyphs;
23388
23389 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23390 x -= glyphs[i].pixel_width;
23391
23392 k = i + 1;
23393 }
23394 else
23395 k = -1;
23396
23397 return k;
23398 }
23399
23400
23401 /* Return the index of the first glyph preceding glyph string S that
23402 is overwriting S because of its right overhang. Value is -1 if no
23403 glyph in front of S overwrites S. */
23404
23405 static int
23406 left_overwriting (struct glyph_string *s)
23407 {
23408 int i, k, x;
23409 struct glyph *glyphs = s->row->glyphs[s->area];
23410 int first = s->first_glyph - glyphs;
23411
23412 k = -1;
23413 x = 0;
23414 for (i = first - 1; i >= 0; --i)
23415 {
23416 int left, right;
23417 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23418 if (x + right > 0)
23419 k = i;
23420 x -= glyphs[i].pixel_width;
23421 }
23422
23423 return k;
23424 }
23425
23426
23427 /* Return the index of the last glyph following glyph string S that is
23428 overwritten by S because of S's right overhang. Value is -1 if
23429 no such glyph is found. */
23430
23431 static int
23432 right_overwritten (struct glyph_string *s)
23433 {
23434 int k = -1;
23435
23436 if (s->right_overhang)
23437 {
23438 int x = 0, i;
23439 struct glyph *glyphs = s->row->glyphs[s->area];
23440 int first = (s->first_glyph - glyphs
23441 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23442 int end = s->row->used[s->area];
23443
23444 for (i = first; i < end && s->right_overhang > x; ++i)
23445 x += glyphs[i].pixel_width;
23446
23447 k = i;
23448 }
23449
23450 return k;
23451 }
23452
23453
23454 /* Return the index of the last glyph following glyph string S that
23455 overwrites S because of its left overhang. Value is negative
23456 if no such glyph is found. */
23457
23458 static int
23459 right_overwriting (struct glyph_string *s)
23460 {
23461 int i, k, x;
23462 int end = s->row->used[s->area];
23463 struct glyph *glyphs = s->row->glyphs[s->area];
23464 int first = (s->first_glyph - glyphs
23465 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
23466
23467 k = -1;
23468 x = 0;
23469 for (i = first; i < end; ++i)
23470 {
23471 int left, right;
23472 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23473 if (x - left < 0)
23474 k = i;
23475 x += glyphs[i].pixel_width;
23476 }
23477
23478 return k;
23479 }
23480
23481
23482 /* Set background width of glyph string S. START is the index of the
23483 first glyph following S. LAST_X is the right-most x-position + 1
23484 in the drawing area. */
23485
23486 static void
23487 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23488 {
23489 /* If the face of this glyph string has to be drawn to the end of
23490 the drawing area, set S->extends_to_end_of_line_p. */
23491
23492 if (start == s->row->used[s->area]
23493 && s->area == TEXT_AREA
23494 && ((s->row->fill_line_p
23495 && (s->hl == DRAW_NORMAL_TEXT
23496 || s->hl == DRAW_IMAGE_RAISED
23497 || s->hl == DRAW_IMAGE_SUNKEN))
23498 || s->hl == DRAW_MOUSE_FACE))
23499 s->extends_to_end_of_line_p = 1;
23500
23501 /* If S extends its face to the end of the line, set its
23502 background_width to the distance to the right edge of the drawing
23503 area. */
23504 if (s->extends_to_end_of_line_p)
23505 s->background_width = last_x - s->x + 1;
23506 else
23507 s->background_width = s->width;
23508 }
23509
23510
23511 /* Compute overhangs and x-positions for glyph string S and its
23512 predecessors, or successors. X is the starting x-position for S.
23513 BACKWARD_P non-zero means process predecessors. */
23514
23515 static void
23516 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23517 {
23518 if (backward_p)
23519 {
23520 while (s)
23521 {
23522 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23523 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23524 x -= s->width;
23525 s->x = x;
23526 s = s->prev;
23527 }
23528 }
23529 else
23530 {
23531 while (s)
23532 {
23533 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23534 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23535 s->x = x;
23536 x += s->width;
23537 s = s->next;
23538 }
23539 }
23540 }
23541
23542
23543
23544 /* The following macros are only called from draw_glyphs below.
23545 They reference the following parameters of that function directly:
23546 `w', `row', `area', and `overlap_p'
23547 as well as the following local variables:
23548 `s', `f', and `hdc' (in W32) */
23549
23550 #ifdef HAVE_NTGUI
23551 /* On W32, silently add local `hdc' variable to argument list of
23552 init_glyph_string. */
23553 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23554 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23555 #else
23556 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23557 init_glyph_string (s, char2b, w, row, area, start, hl)
23558 #endif
23559
23560 /* Add a glyph string for a stretch glyph to the list of strings
23561 between HEAD and TAIL. START is the index of the stretch glyph in
23562 row area AREA of glyph row ROW. END is the index of the last glyph
23563 in that glyph row area. X is the current output position assigned
23564 to the new glyph string constructed. HL overrides that face of the
23565 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23566 is the right-most x-position of the drawing area. */
23567
23568 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23569 and below -- keep them on one line. */
23570 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23571 do \
23572 { \
23573 s = alloca (sizeof *s); \
23574 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23575 START = fill_stretch_glyph_string (s, START, END); \
23576 append_glyph_string (&HEAD, &TAIL, s); \
23577 s->x = (X); \
23578 } \
23579 while (0)
23580
23581
23582 /* Add a glyph string for an image glyph to the list of strings
23583 between HEAD and TAIL. START is the index of the image glyph in
23584 row area AREA of glyph row ROW. END is the index of the last glyph
23585 in that glyph row area. X is the current output position assigned
23586 to the new glyph string constructed. HL overrides that face of the
23587 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23588 is the right-most x-position of the drawing area. */
23589
23590 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23591 do \
23592 { \
23593 s = alloca (sizeof *s); \
23594 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23595 fill_image_glyph_string (s); \
23596 append_glyph_string (&HEAD, &TAIL, s); \
23597 ++START; \
23598 s->x = (X); \
23599 } \
23600 while (0)
23601
23602
23603 /* Add a glyph string for a sequence of character glyphs to the list
23604 of strings between HEAD and TAIL. START is the index of the first
23605 glyph in row area AREA of glyph row ROW that is part of the new
23606 glyph string. END is the index of the last glyph in that glyph row
23607 area. X is the current output position assigned to the new glyph
23608 string constructed. HL overrides that face of the glyph; e.g. it
23609 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23610 right-most x-position of the drawing area. */
23611
23612 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23613 do \
23614 { \
23615 int face_id; \
23616 XChar2b *char2b; \
23617 \
23618 face_id = (row)->glyphs[area][START].face_id; \
23619 \
23620 s = alloca (sizeof *s); \
23621 char2b = alloca ((END - START) * sizeof *char2b); \
23622 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23623 append_glyph_string (&HEAD, &TAIL, s); \
23624 s->x = (X); \
23625 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23626 } \
23627 while (0)
23628
23629
23630 /* Add a glyph string for a composite sequence to the list of strings
23631 between HEAD and TAIL. START is the index of the first glyph in
23632 row area AREA of glyph row ROW that is part of the new glyph
23633 string. END is the index of the last glyph in that glyph row area.
23634 X is the current output position assigned to the new glyph string
23635 constructed. HL overrides that face of the glyph; e.g. it is
23636 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23637 x-position of the drawing area. */
23638
23639 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23640 do { \
23641 int face_id = (row)->glyphs[area][START].face_id; \
23642 struct face *base_face = FACE_FROM_ID (f, face_id); \
23643 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23644 struct composition *cmp = composition_table[cmp_id]; \
23645 XChar2b *char2b; \
23646 struct glyph_string *first_s = NULL; \
23647 int n; \
23648 \
23649 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23650 \
23651 /* Make glyph_strings for each glyph sequence that is drawable by \
23652 the same face, and append them to HEAD/TAIL. */ \
23653 for (n = 0; n < cmp->glyph_len;) \
23654 { \
23655 s = alloca (sizeof *s); \
23656 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23657 append_glyph_string (&(HEAD), &(TAIL), s); \
23658 s->cmp = cmp; \
23659 s->cmp_from = n; \
23660 s->x = (X); \
23661 if (n == 0) \
23662 first_s = s; \
23663 n = fill_composite_glyph_string (s, base_face, overlaps); \
23664 } \
23665 \
23666 ++START; \
23667 s = first_s; \
23668 } while (0)
23669
23670
23671 /* Add a glyph string for a glyph-string sequence to the list of strings
23672 between HEAD and TAIL. */
23673
23674 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23675 do { \
23676 int face_id; \
23677 XChar2b *char2b; \
23678 Lisp_Object gstring; \
23679 \
23680 face_id = (row)->glyphs[area][START].face_id; \
23681 gstring = (composition_gstring_from_id \
23682 ((row)->glyphs[area][START].u.cmp.id)); \
23683 s = alloca (sizeof *s); \
23684 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23685 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23686 append_glyph_string (&(HEAD), &(TAIL), s); \
23687 s->x = (X); \
23688 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23689 } while (0)
23690
23691
23692 /* Add a glyph string for a sequence of glyphless character's glyphs
23693 to the list of strings between HEAD and TAIL. The meanings of
23694 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23695
23696 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23697 do \
23698 { \
23699 int face_id; \
23700 \
23701 face_id = (row)->glyphs[area][START].face_id; \
23702 \
23703 s = alloca (sizeof *s); \
23704 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23705 append_glyph_string (&HEAD, &TAIL, s); \
23706 s->x = (X); \
23707 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23708 overlaps); \
23709 } \
23710 while (0)
23711
23712
23713 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23714 of AREA of glyph row ROW on window W between indices START and END.
23715 HL overrides the face for drawing glyph strings, e.g. it is
23716 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23717 x-positions of the drawing area.
23718
23719 This is an ugly monster macro construct because we must use alloca
23720 to allocate glyph strings (because draw_glyphs can be called
23721 asynchronously). */
23722
23723 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23724 do \
23725 { \
23726 HEAD = TAIL = NULL; \
23727 while (START < END) \
23728 { \
23729 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23730 switch (first_glyph->type) \
23731 { \
23732 case CHAR_GLYPH: \
23733 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23734 HL, X, LAST_X); \
23735 break; \
23736 \
23737 case COMPOSITE_GLYPH: \
23738 if (first_glyph->u.cmp.automatic) \
23739 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23740 HL, X, LAST_X); \
23741 else \
23742 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23743 HL, X, LAST_X); \
23744 break; \
23745 \
23746 case STRETCH_GLYPH: \
23747 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23748 HL, X, LAST_X); \
23749 break; \
23750 \
23751 case IMAGE_GLYPH: \
23752 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23753 HL, X, LAST_X); \
23754 break; \
23755 \
23756 case GLYPHLESS_GLYPH: \
23757 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23758 HL, X, LAST_X); \
23759 break; \
23760 \
23761 default: \
23762 emacs_abort (); \
23763 } \
23764 \
23765 if (s) \
23766 { \
23767 set_glyph_string_background_width (s, START, LAST_X); \
23768 (X) += s->width; \
23769 } \
23770 } \
23771 } while (0)
23772
23773
23774 /* Draw glyphs between START and END in AREA of ROW on window W,
23775 starting at x-position X. X is relative to AREA in W. HL is a
23776 face-override with the following meaning:
23777
23778 DRAW_NORMAL_TEXT draw normally
23779 DRAW_CURSOR draw in cursor face
23780 DRAW_MOUSE_FACE draw in mouse face.
23781 DRAW_INVERSE_VIDEO draw in mode line face
23782 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23783 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23784
23785 If OVERLAPS is non-zero, draw only the foreground of characters and
23786 clip to the physical height of ROW. Non-zero value also defines
23787 the overlapping part to be drawn:
23788
23789 OVERLAPS_PRED overlap with preceding rows
23790 OVERLAPS_SUCC overlap with succeeding rows
23791 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23792 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23793
23794 Value is the x-position reached, relative to AREA of W. */
23795
23796 static int
23797 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23798 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23799 enum draw_glyphs_face hl, int overlaps)
23800 {
23801 struct glyph_string *head, *tail;
23802 struct glyph_string *s;
23803 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23804 int i, j, x_reached, last_x, area_left = 0;
23805 struct frame *f = XFRAME (WINDOW_FRAME (w));
23806 DECLARE_HDC (hdc);
23807
23808 ALLOCATE_HDC (hdc, f);
23809
23810 /* Let's rather be paranoid than getting a SEGV. */
23811 end = min (end, row->used[area]);
23812 start = clip_to_bounds (0, start, end);
23813
23814 /* Translate X to frame coordinates. Set last_x to the right
23815 end of the drawing area. */
23816 if (row->full_width_p)
23817 {
23818 /* X is relative to the left edge of W, without scroll bars
23819 or fringes. */
23820 area_left = WINDOW_LEFT_EDGE_X (w);
23821 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23822 }
23823 else
23824 {
23825 area_left = window_box_left (w, area);
23826 last_x = area_left + window_box_width (w, area);
23827 }
23828 x += area_left;
23829
23830 /* Build a doubly-linked list of glyph_string structures between
23831 head and tail from what we have to draw. Note that the macro
23832 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23833 the reason we use a separate variable `i'. */
23834 i = start;
23835 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23836 if (tail)
23837 x_reached = tail->x + tail->background_width;
23838 else
23839 x_reached = x;
23840
23841 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23842 the row, redraw some glyphs in front or following the glyph
23843 strings built above. */
23844 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23845 {
23846 struct glyph_string *h, *t;
23847 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23848 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23849 int check_mouse_face = 0;
23850 int dummy_x = 0;
23851
23852 /* If mouse highlighting is on, we may need to draw adjacent
23853 glyphs using mouse-face highlighting. */
23854 if (area == TEXT_AREA && row->mouse_face_p
23855 && hlinfo->mouse_face_beg_row >= 0
23856 && hlinfo->mouse_face_end_row >= 0)
23857 {
23858 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
23859
23860 if (row_vpos >= hlinfo->mouse_face_beg_row
23861 && row_vpos <= hlinfo->mouse_face_end_row)
23862 {
23863 check_mouse_face = 1;
23864 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
23865 ? hlinfo->mouse_face_beg_col : 0;
23866 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
23867 ? hlinfo->mouse_face_end_col
23868 : row->used[TEXT_AREA];
23869 }
23870 }
23871
23872 /* Compute overhangs for all glyph strings. */
23873 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23874 for (s = head; s; s = s->next)
23875 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23876
23877 /* Prepend glyph strings for glyphs in front of the first glyph
23878 string that are overwritten because of the first glyph
23879 string's left overhang. The background of all strings
23880 prepended must be drawn because the first glyph string
23881 draws over it. */
23882 i = left_overwritten (head);
23883 if (i >= 0)
23884 {
23885 enum draw_glyphs_face overlap_hl;
23886
23887 /* If this row contains mouse highlighting, attempt to draw
23888 the overlapped glyphs with the correct highlight. This
23889 code fails if the overlap encompasses more than one glyph
23890 and mouse-highlight spans only some of these glyphs.
23891 However, making it work perfectly involves a lot more
23892 code, and I don't know if the pathological case occurs in
23893 practice, so we'll stick to this for now. --- cyd */
23894 if (check_mouse_face
23895 && mouse_beg_col < start && mouse_end_col > i)
23896 overlap_hl = DRAW_MOUSE_FACE;
23897 else
23898 overlap_hl = DRAW_NORMAL_TEXT;
23899
23900 j = i;
23901 BUILD_GLYPH_STRINGS (j, start, h, t,
23902 overlap_hl, dummy_x, last_x);
23903 start = i;
23904 compute_overhangs_and_x (t, head->x, 1);
23905 prepend_glyph_string_lists (&head, &tail, h, t);
23906 clip_head = head;
23907 }
23908
23909 /* Prepend glyph strings for glyphs in front of the first glyph
23910 string that overwrite that glyph string because of their
23911 right overhang. For these strings, only the foreground must
23912 be drawn, because it draws over the glyph string at `head'.
23913 The background must not be drawn because this would overwrite
23914 right overhangs of preceding glyphs for which no glyph
23915 strings exist. */
23916 i = left_overwriting (head);
23917 if (i >= 0)
23918 {
23919 enum draw_glyphs_face overlap_hl;
23920
23921 if (check_mouse_face
23922 && mouse_beg_col < start && mouse_end_col > i)
23923 overlap_hl = DRAW_MOUSE_FACE;
23924 else
23925 overlap_hl = DRAW_NORMAL_TEXT;
23926
23927 clip_head = head;
23928 BUILD_GLYPH_STRINGS (i, start, h, t,
23929 overlap_hl, dummy_x, last_x);
23930 for (s = h; s; s = s->next)
23931 s->background_filled_p = 1;
23932 compute_overhangs_and_x (t, head->x, 1);
23933 prepend_glyph_string_lists (&head, &tail, h, t);
23934 }
23935
23936 /* Append glyphs strings for glyphs following the last glyph
23937 string tail that are overwritten by tail. The background of
23938 these strings has to be drawn because tail's foreground draws
23939 over it. */
23940 i = right_overwritten (tail);
23941 if (i >= 0)
23942 {
23943 enum draw_glyphs_face overlap_hl;
23944
23945 if (check_mouse_face
23946 && mouse_beg_col < i && mouse_end_col > end)
23947 overlap_hl = DRAW_MOUSE_FACE;
23948 else
23949 overlap_hl = DRAW_NORMAL_TEXT;
23950
23951 BUILD_GLYPH_STRINGS (end, i, h, t,
23952 overlap_hl, x, last_x);
23953 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23954 we don't have `end = i;' here. */
23955 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23956 append_glyph_string_lists (&head, &tail, h, t);
23957 clip_tail = tail;
23958 }
23959
23960 /* Append glyph strings for glyphs following the last glyph
23961 string tail that overwrite tail. The foreground of such
23962 glyphs has to be drawn because it writes into the background
23963 of tail. The background must not be drawn because it could
23964 paint over the foreground of following glyphs. */
23965 i = right_overwriting (tail);
23966 if (i >= 0)
23967 {
23968 enum draw_glyphs_face overlap_hl;
23969 if (check_mouse_face
23970 && mouse_beg_col < i && mouse_end_col > end)
23971 overlap_hl = DRAW_MOUSE_FACE;
23972 else
23973 overlap_hl = DRAW_NORMAL_TEXT;
23974
23975 clip_tail = tail;
23976 i++; /* We must include the Ith glyph. */
23977 BUILD_GLYPH_STRINGS (end, i, h, t,
23978 overlap_hl, x, last_x);
23979 for (s = h; s; s = s->next)
23980 s->background_filled_p = 1;
23981 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23982 append_glyph_string_lists (&head, &tail, h, t);
23983 }
23984 if (clip_head || clip_tail)
23985 for (s = head; s; s = s->next)
23986 {
23987 s->clip_head = clip_head;
23988 s->clip_tail = clip_tail;
23989 }
23990 }
23991
23992 /* Draw all strings. */
23993 for (s = head; s; s = s->next)
23994 FRAME_RIF (f)->draw_glyph_string (s);
23995
23996 #ifndef HAVE_NS
23997 /* When focus a sole frame and move horizontally, this sets on_p to 0
23998 causing a failure to erase prev cursor position. */
23999 if (area == TEXT_AREA
24000 && !row->full_width_p
24001 /* When drawing overlapping rows, only the glyph strings'
24002 foreground is drawn, which doesn't erase a cursor
24003 completely. */
24004 && !overlaps)
24005 {
24006 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
24007 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
24008 : (tail ? tail->x + tail->background_width : x));
24009 x0 -= area_left;
24010 x1 -= area_left;
24011
24012 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
24013 row->y, MATRIX_ROW_BOTTOM_Y (row));
24014 }
24015 #endif
24016
24017 /* Value is the x-position up to which drawn, relative to AREA of W.
24018 This doesn't include parts drawn because of overhangs. */
24019 if (row->full_width_p)
24020 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
24021 else
24022 x_reached -= area_left;
24023
24024 RELEASE_HDC (hdc, f);
24025
24026 return x_reached;
24027 }
24028
24029 /* Expand row matrix if too narrow. Don't expand if area
24030 is not present. */
24031
24032 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
24033 { \
24034 if (!fonts_changed_p \
24035 && (it->glyph_row->glyphs[area] \
24036 < it->glyph_row->glyphs[area + 1])) \
24037 { \
24038 it->w->ncols_scale_factor++; \
24039 fonts_changed_p = 1; \
24040 } \
24041 }
24042
24043 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24044 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24045
24046 static void
24047 append_glyph (struct it *it)
24048 {
24049 struct glyph *glyph;
24050 enum glyph_row_area area = it->area;
24051
24052 eassert (it->glyph_row);
24053 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
24054
24055 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24056 if (glyph < it->glyph_row->glyphs[area + 1])
24057 {
24058 /* If the glyph row is reversed, we need to prepend the glyph
24059 rather than append it. */
24060 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24061 {
24062 struct glyph *g;
24063
24064 /* Make room for the additional glyph. */
24065 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24066 g[1] = *g;
24067 glyph = it->glyph_row->glyphs[area];
24068 }
24069 glyph->charpos = CHARPOS (it->position);
24070 glyph->object = it->object;
24071 if (it->pixel_width > 0)
24072 {
24073 glyph->pixel_width = it->pixel_width;
24074 glyph->padding_p = 0;
24075 }
24076 else
24077 {
24078 /* Assure at least 1-pixel width. Otherwise, cursor can't
24079 be displayed correctly. */
24080 glyph->pixel_width = 1;
24081 glyph->padding_p = 1;
24082 }
24083 glyph->ascent = it->ascent;
24084 glyph->descent = it->descent;
24085 glyph->voffset = it->voffset;
24086 glyph->type = CHAR_GLYPH;
24087 glyph->avoid_cursor_p = it->avoid_cursor_p;
24088 glyph->multibyte_p = it->multibyte_p;
24089 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24090 {
24091 /* In R2L rows, the left and the right box edges need to be
24092 drawn in reverse direction. */
24093 glyph->right_box_line_p = it->start_of_box_run_p;
24094 glyph->left_box_line_p = it->end_of_box_run_p;
24095 }
24096 else
24097 {
24098 glyph->left_box_line_p = it->start_of_box_run_p;
24099 glyph->right_box_line_p = it->end_of_box_run_p;
24100 }
24101 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24102 || it->phys_descent > it->descent);
24103 glyph->glyph_not_available_p = it->glyph_not_available_p;
24104 glyph->face_id = it->face_id;
24105 glyph->u.ch = it->char_to_display;
24106 glyph->slice.img = null_glyph_slice;
24107 glyph->font_type = FONT_TYPE_UNKNOWN;
24108 if (it->bidi_p)
24109 {
24110 glyph->resolved_level = it->bidi_it.resolved_level;
24111 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24112 emacs_abort ();
24113 glyph->bidi_type = it->bidi_it.type;
24114 }
24115 else
24116 {
24117 glyph->resolved_level = 0;
24118 glyph->bidi_type = UNKNOWN_BT;
24119 }
24120 ++it->glyph_row->used[area];
24121 }
24122 else
24123 IT_EXPAND_MATRIX_WIDTH (it, area);
24124 }
24125
24126 /* Store one glyph for the composition IT->cmp_it.id in
24127 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24128 non-null. */
24129
24130 static void
24131 append_composite_glyph (struct it *it)
24132 {
24133 struct glyph *glyph;
24134 enum glyph_row_area area = it->area;
24135
24136 eassert (it->glyph_row);
24137
24138 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24139 if (glyph < it->glyph_row->glyphs[area + 1])
24140 {
24141 /* If the glyph row is reversed, we need to prepend the glyph
24142 rather than append it. */
24143 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
24144 {
24145 struct glyph *g;
24146
24147 /* Make room for the new glyph. */
24148 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
24149 g[1] = *g;
24150 glyph = it->glyph_row->glyphs[it->area];
24151 }
24152 glyph->charpos = it->cmp_it.charpos;
24153 glyph->object = it->object;
24154 glyph->pixel_width = it->pixel_width;
24155 glyph->ascent = it->ascent;
24156 glyph->descent = it->descent;
24157 glyph->voffset = it->voffset;
24158 glyph->type = COMPOSITE_GLYPH;
24159 if (it->cmp_it.ch < 0)
24160 {
24161 glyph->u.cmp.automatic = 0;
24162 glyph->u.cmp.id = it->cmp_it.id;
24163 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
24164 }
24165 else
24166 {
24167 glyph->u.cmp.automatic = 1;
24168 glyph->u.cmp.id = it->cmp_it.id;
24169 glyph->slice.cmp.from = it->cmp_it.from;
24170 glyph->slice.cmp.to = it->cmp_it.to - 1;
24171 }
24172 glyph->avoid_cursor_p = it->avoid_cursor_p;
24173 glyph->multibyte_p = it->multibyte_p;
24174 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24175 {
24176 /* In R2L rows, the left and the right box edges need to be
24177 drawn in reverse direction. */
24178 glyph->right_box_line_p = it->start_of_box_run_p;
24179 glyph->left_box_line_p = it->end_of_box_run_p;
24180 }
24181 else
24182 {
24183 glyph->left_box_line_p = it->start_of_box_run_p;
24184 glyph->right_box_line_p = it->end_of_box_run_p;
24185 }
24186 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24187 || it->phys_descent > it->descent);
24188 glyph->padding_p = 0;
24189 glyph->glyph_not_available_p = 0;
24190 glyph->face_id = it->face_id;
24191 glyph->font_type = FONT_TYPE_UNKNOWN;
24192 if (it->bidi_p)
24193 {
24194 glyph->resolved_level = it->bidi_it.resolved_level;
24195 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24196 emacs_abort ();
24197 glyph->bidi_type = it->bidi_it.type;
24198 }
24199 ++it->glyph_row->used[area];
24200 }
24201 else
24202 IT_EXPAND_MATRIX_WIDTH (it, area);
24203 }
24204
24205
24206 /* Change IT->ascent and IT->height according to the setting of
24207 IT->voffset. */
24208
24209 static void
24210 take_vertical_position_into_account (struct it *it)
24211 {
24212 if (it->voffset)
24213 {
24214 if (it->voffset < 0)
24215 /* Increase the ascent so that we can display the text higher
24216 in the line. */
24217 it->ascent -= it->voffset;
24218 else
24219 /* Increase the descent so that we can display the text lower
24220 in the line. */
24221 it->descent += it->voffset;
24222 }
24223 }
24224
24225
24226 /* Produce glyphs/get display metrics for the image IT is loaded with.
24227 See the description of struct display_iterator in dispextern.h for
24228 an overview of struct display_iterator. */
24229
24230 static void
24231 produce_image_glyph (struct it *it)
24232 {
24233 struct image *img;
24234 struct face *face;
24235 int glyph_ascent, crop;
24236 struct glyph_slice slice;
24237
24238 eassert (it->what == IT_IMAGE);
24239
24240 face = FACE_FROM_ID (it->f, it->face_id);
24241 eassert (face);
24242 /* Make sure X resources of the face is loaded. */
24243 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24244
24245 if (it->image_id < 0)
24246 {
24247 /* Fringe bitmap. */
24248 it->ascent = it->phys_ascent = 0;
24249 it->descent = it->phys_descent = 0;
24250 it->pixel_width = 0;
24251 it->nglyphs = 0;
24252 return;
24253 }
24254
24255 img = IMAGE_FROM_ID (it->f, it->image_id);
24256 eassert (img);
24257 /* Make sure X resources of the image is loaded. */
24258 prepare_image_for_display (it->f, img);
24259
24260 slice.x = slice.y = 0;
24261 slice.width = img->width;
24262 slice.height = img->height;
24263
24264 if (INTEGERP (it->slice.x))
24265 slice.x = XINT (it->slice.x);
24266 else if (FLOATP (it->slice.x))
24267 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24268
24269 if (INTEGERP (it->slice.y))
24270 slice.y = XINT (it->slice.y);
24271 else if (FLOATP (it->slice.y))
24272 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24273
24274 if (INTEGERP (it->slice.width))
24275 slice.width = XINT (it->slice.width);
24276 else if (FLOATP (it->slice.width))
24277 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24278
24279 if (INTEGERP (it->slice.height))
24280 slice.height = XINT (it->slice.height);
24281 else if (FLOATP (it->slice.height))
24282 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24283
24284 if (slice.x >= img->width)
24285 slice.x = img->width;
24286 if (slice.y >= img->height)
24287 slice.y = img->height;
24288 if (slice.x + slice.width >= img->width)
24289 slice.width = img->width - slice.x;
24290 if (slice.y + slice.height > img->height)
24291 slice.height = img->height - slice.y;
24292
24293 if (slice.width == 0 || slice.height == 0)
24294 return;
24295
24296 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24297
24298 it->descent = slice.height - glyph_ascent;
24299 if (slice.y == 0)
24300 it->descent += img->vmargin;
24301 if (slice.y + slice.height == img->height)
24302 it->descent += img->vmargin;
24303 it->phys_descent = it->descent;
24304
24305 it->pixel_width = slice.width;
24306 if (slice.x == 0)
24307 it->pixel_width += img->hmargin;
24308 if (slice.x + slice.width == img->width)
24309 it->pixel_width += img->hmargin;
24310
24311 /* It's quite possible for images to have an ascent greater than
24312 their height, so don't get confused in that case. */
24313 if (it->descent < 0)
24314 it->descent = 0;
24315
24316 it->nglyphs = 1;
24317
24318 if (face->box != FACE_NO_BOX)
24319 {
24320 if (face->box_line_width > 0)
24321 {
24322 if (slice.y == 0)
24323 it->ascent += face->box_line_width;
24324 if (slice.y + slice.height == img->height)
24325 it->descent += face->box_line_width;
24326 }
24327
24328 if (it->start_of_box_run_p && slice.x == 0)
24329 it->pixel_width += eabs (face->box_line_width);
24330 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24331 it->pixel_width += eabs (face->box_line_width);
24332 }
24333
24334 take_vertical_position_into_account (it);
24335
24336 /* Automatically crop wide image glyphs at right edge so we can
24337 draw the cursor on same display row. */
24338 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24339 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24340 {
24341 it->pixel_width -= crop;
24342 slice.width -= crop;
24343 }
24344
24345 if (it->glyph_row)
24346 {
24347 struct glyph *glyph;
24348 enum glyph_row_area area = it->area;
24349
24350 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24351 if (glyph < it->glyph_row->glyphs[area + 1])
24352 {
24353 glyph->charpos = CHARPOS (it->position);
24354 glyph->object = it->object;
24355 glyph->pixel_width = it->pixel_width;
24356 glyph->ascent = glyph_ascent;
24357 glyph->descent = it->descent;
24358 glyph->voffset = it->voffset;
24359 glyph->type = IMAGE_GLYPH;
24360 glyph->avoid_cursor_p = it->avoid_cursor_p;
24361 glyph->multibyte_p = it->multibyte_p;
24362 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24363 {
24364 /* In R2L rows, the left and the right box edges need to be
24365 drawn in reverse direction. */
24366 glyph->right_box_line_p = it->start_of_box_run_p;
24367 glyph->left_box_line_p = it->end_of_box_run_p;
24368 }
24369 else
24370 {
24371 glyph->left_box_line_p = it->start_of_box_run_p;
24372 glyph->right_box_line_p = it->end_of_box_run_p;
24373 }
24374 glyph->overlaps_vertically_p = 0;
24375 glyph->padding_p = 0;
24376 glyph->glyph_not_available_p = 0;
24377 glyph->face_id = it->face_id;
24378 glyph->u.img_id = img->id;
24379 glyph->slice.img = slice;
24380 glyph->font_type = FONT_TYPE_UNKNOWN;
24381 if (it->bidi_p)
24382 {
24383 glyph->resolved_level = it->bidi_it.resolved_level;
24384 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24385 emacs_abort ();
24386 glyph->bidi_type = it->bidi_it.type;
24387 }
24388 ++it->glyph_row->used[area];
24389 }
24390 else
24391 IT_EXPAND_MATRIX_WIDTH (it, area);
24392 }
24393 }
24394
24395
24396 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24397 of the glyph, WIDTH and HEIGHT are the width and height of the
24398 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24399
24400 static void
24401 append_stretch_glyph (struct it *it, Lisp_Object object,
24402 int width, int height, int ascent)
24403 {
24404 struct glyph *glyph;
24405 enum glyph_row_area area = it->area;
24406
24407 eassert (ascent >= 0 && ascent <= height);
24408
24409 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24410 if (glyph < it->glyph_row->glyphs[area + 1])
24411 {
24412 /* If the glyph row is reversed, we need to prepend the glyph
24413 rather than append it. */
24414 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24415 {
24416 struct glyph *g;
24417
24418 /* Make room for the additional glyph. */
24419 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24420 g[1] = *g;
24421 glyph = it->glyph_row->glyphs[area];
24422 }
24423 glyph->charpos = CHARPOS (it->position);
24424 glyph->object = object;
24425 glyph->pixel_width = width;
24426 glyph->ascent = ascent;
24427 glyph->descent = height - ascent;
24428 glyph->voffset = it->voffset;
24429 glyph->type = STRETCH_GLYPH;
24430 glyph->avoid_cursor_p = it->avoid_cursor_p;
24431 glyph->multibyte_p = it->multibyte_p;
24432 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24433 {
24434 /* In R2L rows, the left and the right box edges need to be
24435 drawn in reverse direction. */
24436 glyph->right_box_line_p = it->start_of_box_run_p;
24437 glyph->left_box_line_p = it->end_of_box_run_p;
24438 }
24439 else
24440 {
24441 glyph->left_box_line_p = it->start_of_box_run_p;
24442 glyph->right_box_line_p = it->end_of_box_run_p;
24443 }
24444 glyph->overlaps_vertically_p = 0;
24445 glyph->padding_p = 0;
24446 glyph->glyph_not_available_p = 0;
24447 glyph->face_id = it->face_id;
24448 glyph->u.stretch.ascent = ascent;
24449 glyph->u.stretch.height = height;
24450 glyph->slice.img = null_glyph_slice;
24451 glyph->font_type = FONT_TYPE_UNKNOWN;
24452 if (it->bidi_p)
24453 {
24454 glyph->resolved_level = it->bidi_it.resolved_level;
24455 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24456 emacs_abort ();
24457 glyph->bidi_type = it->bidi_it.type;
24458 }
24459 else
24460 {
24461 glyph->resolved_level = 0;
24462 glyph->bidi_type = UNKNOWN_BT;
24463 }
24464 ++it->glyph_row->used[area];
24465 }
24466 else
24467 IT_EXPAND_MATRIX_WIDTH (it, area);
24468 }
24469
24470 #endif /* HAVE_WINDOW_SYSTEM */
24471
24472 /* Produce a stretch glyph for iterator IT. IT->object is the value
24473 of the glyph property displayed. The value must be a list
24474 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24475 being recognized:
24476
24477 1. `:width WIDTH' specifies that the space should be WIDTH *
24478 canonical char width wide. WIDTH may be an integer or floating
24479 point number.
24480
24481 2. `:relative-width FACTOR' specifies that the width of the stretch
24482 should be computed from the width of the first character having the
24483 `glyph' property, and should be FACTOR times that width.
24484
24485 3. `:align-to HPOS' specifies that the space should be wide enough
24486 to reach HPOS, a value in canonical character units.
24487
24488 Exactly one of the above pairs must be present.
24489
24490 4. `:height HEIGHT' specifies that the height of the stretch produced
24491 should be HEIGHT, measured in canonical character units.
24492
24493 5. `:relative-height FACTOR' specifies that the height of the
24494 stretch should be FACTOR times the height of the characters having
24495 the glyph property.
24496
24497 Either none or exactly one of 4 or 5 must be present.
24498
24499 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24500 of the stretch should be used for the ascent of the stretch.
24501 ASCENT must be in the range 0 <= ASCENT <= 100. */
24502
24503 void
24504 produce_stretch_glyph (struct it *it)
24505 {
24506 /* (space :width WIDTH :height HEIGHT ...) */
24507 Lisp_Object prop, plist;
24508 int width = 0, height = 0, align_to = -1;
24509 int zero_width_ok_p = 0;
24510 double tem;
24511 struct font *font = NULL;
24512
24513 #ifdef HAVE_WINDOW_SYSTEM
24514 int ascent = 0;
24515 int zero_height_ok_p = 0;
24516
24517 if (FRAME_WINDOW_P (it->f))
24518 {
24519 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24520 font = face->font ? face->font : FRAME_FONT (it->f);
24521 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24522 }
24523 #endif
24524
24525 /* List should start with `space'. */
24526 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24527 plist = XCDR (it->object);
24528
24529 /* Compute the width of the stretch. */
24530 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24531 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24532 {
24533 /* Absolute width `:width WIDTH' specified and valid. */
24534 zero_width_ok_p = 1;
24535 width = (int)tem;
24536 }
24537 #ifdef HAVE_WINDOW_SYSTEM
24538 else if (FRAME_WINDOW_P (it->f)
24539 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24540 {
24541 /* Relative width `:relative-width FACTOR' specified and valid.
24542 Compute the width of the characters having the `glyph'
24543 property. */
24544 struct it it2;
24545 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24546
24547 it2 = *it;
24548 if (it->multibyte_p)
24549 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24550 else
24551 {
24552 it2.c = it2.char_to_display = *p, it2.len = 1;
24553 if (! ASCII_CHAR_P (it2.c))
24554 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24555 }
24556
24557 it2.glyph_row = NULL;
24558 it2.what = IT_CHARACTER;
24559 x_produce_glyphs (&it2);
24560 width = NUMVAL (prop) * it2.pixel_width;
24561 }
24562 #endif /* HAVE_WINDOW_SYSTEM */
24563 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24564 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24565 {
24566 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24567 align_to = (align_to < 0
24568 ? 0
24569 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24570 else if (align_to < 0)
24571 align_to = window_box_left_offset (it->w, TEXT_AREA);
24572 width = max (0, (int)tem + align_to - it->current_x);
24573 zero_width_ok_p = 1;
24574 }
24575 else
24576 /* Nothing specified -> width defaults to canonical char width. */
24577 width = FRAME_COLUMN_WIDTH (it->f);
24578
24579 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24580 width = 1;
24581
24582 #ifdef HAVE_WINDOW_SYSTEM
24583 /* Compute height. */
24584 if (FRAME_WINDOW_P (it->f))
24585 {
24586 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24587 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24588 {
24589 height = (int)tem;
24590 zero_height_ok_p = 1;
24591 }
24592 else if (prop = Fplist_get (plist, QCrelative_height),
24593 NUMVAL (prop) > 0)
24594 height = FONT_HEIGHT (font) * NUMVAL (prop);
24595 else
24596 height = FONT_HEIGHT (font);
24597
24598 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24599 height = 1;
24600
24601 /* Compute percentage of height used for ascent. If
24602 `:ascent ASCENT' is present and valid, use that. Otherwise,
24603 derive the ascent from the font in use. */
24604 if (prop = Fplist_get (plist, QCascent),
24605 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24606 ascent = height * NUMVAL (prop) / 100.0;
24607 else if (!NILP (prop)
24608 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24609 ascent = min (max (0, (int)tem), height);
24610 else
24611 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24612 }
24613 else
24614 #endif /* HAVE_WINDOW_SYSTEM */
24615 height = 1;
24616
24617 if (width > 0 && it->line_wrap != TRUNCATE
24618 && it->current_x + width > it->last_visible_x)
24619 {
24620 width = it->last_visible_x - it->current_x;
24621 #ifdef HAVE_WINDOW_SYSTEM
24622 /* Subtract one more pixel from the stretch width, but only on
24623 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24624 width -= FRAME_WINDOW_P (it->f);
24625 #endif
24626 }
24627
24628 if (width > 0 && height > 0 && it->glyph_row)
24629 {
24630 Lisp_Object o_object = it->object;
24631 Lisp_Object object = it->stack[it->sp - 1].string;
24632 int n = width;
24633
24634 if (!STRINGP (object))
24635 object = it->w->contents;
24636 #ifdef HAVE_WINDOW_SYSTEM
24637 if (FRAME_WINDOW_P (it->f))
24638 append_stretch_glyph (it, object, width, height, ascent);
24639 else
24640 #endif
24641 {
24642 it->object = object;
24643 it->char_to_display = ' ';
24644 it->pixel_width = it->len = 1;
24645 while (n--)
24646 tty_append_glyph (it);
24647 it->object = o_object;
24648 }
24649 }
24650
24651 it->pixel_width = width;
24652 #ifdef HAVE_WINDOW_SYSTEM
24653 if (FRAME_WINDOW_P (it->f))
24654 {
24655 it->ascent = it->phys_ascent = ascent;
24656 it->descent = it->phys_descent = height - it->ascent;
24657 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24658 take_vertical_position_into_account (it);
24659 }
24660 else
24661 #endif
24662 it->nglyphs = width;
24663 }
24664
24665 /* Get information about special display element WHAT in an
24666 environment described by IT. WHAT is one of IT_TRUNCATION or
24667 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24668 non-null glyph_row member. This function ensures that fields like
24669 face_id, c, len of IT are left untouched. */
24670
24671 static void
24672 produce_special_glyphs (struct it *it, enum display_element_type what)
24673 {
24674 struct it temp_it;
24675 Lisp_Object gc;
24676 GLYPH glyph;
24677
24678 temp_it = *it;
24679 temp_it.object = make_number (0);
24680 memset (&temp_it.current, 0, sizeof temp_it.current);
24681
24682 if (what == IT_CONTINUATION)
24683 {
24684 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24685 if (it->bidi_it.paragraph_dir == R2L)
24686 SET_GLYPH_FROM_CHAR (glyph, '/');
24687 else
24688 SET_GLYPH_FROM_CHAR (glyph, '\\');
24689 if (it->dp
24690 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24691 {
24692 /* FIXME: Should we mirror GC for R2L lines? */
24693 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24694 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24695 }
24696 }
24697 else if (what == IT_TRUNCATION)
24698 {
24699 /* Truncation glyph. */
24700 SET_GLYPH_FROM_CHAR (glyph, '$');
24701 if (it->dp
24702 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24703 {
24704 /* FIXME: Should we mirror GC for R2L lines? */
24705 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24706 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24707 }
24708 }
24709 else
24710 emacs_abort ();
24711
24712 #ifdef HAVE_WINDOW_SYSTEM
24713 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24714 is turned off, we precede the truncation/continuation glyphs by a
24715 stretch glyph whose width is computed such that these special
24716 glyphs are aligned at the window margin, even when very different
24717 fonts are used in different glyph rows. */
24718 if (FRAME_WINDOW_P (temp_it.f)
24719 /* init_iterator calls this with it->glyph_row == NULL, and it
24720 wants only the pixel width of the truncation/continuation
24721 glyphs. */
24722 && temp_it.glyph_row
24723 /* insert_left_trunc_glyphs calls us at the beginning of the
24724 row, and it has its own calculation of the stretch glyph
24725 width. */
24726 && temp_it.glyph_row->used[TEXT_AREA] > 0
24727 && (temp_it.glyph_row->reversed_p
24728 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24729 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24730 {
24731 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24732
24733 if (stretch_width > 0)
24734 {
24735 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24736 struct font *font =
24737 face->font ? face->font : FRAME_FONT (temp_it.f);
24738 int stretch_ascent =
24739 (((temp_it.ascent + temp_it.descent)
24740 * FONT_BASE (font)) / FONT_HEIGHT (font));
24741
24742 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24743 temp_it.ascent + temp_it.descent,
24744 stretch_ascent);
24745 }
24746 }
24747 #endif
24748
24749 temp_it.dp = NULL;
24750 temp_it.what = IT_CHARACTER;
24751 temp_it.len = 1;
24752 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24753 temp_it.face_id = GLYPH_FACE (glyph);
24754 temp_it.len = CHAR_BYTES (temp_it.c);
24755
24756 PRODUCE_GLYPHS (&temp_it);
24757 it->pixel_width = temp_it.pixel_width;
24758 it->nglyphs = temp_it.pixel_width;
24759 }
24760
24761 #ifdef HAVE_WINDOW_SYSTEM
24762
24763 /* Calculate line-height and line-spacing properties.
24764 An integer value specifies explicit pixel value.
24765 A float value specifies relative value to current face height.
24766 A cons (float . face-name) specifies relative value to
24767 height of specified face font.
24768
24769 Returns height in pixels, or nil. */
24770
24771
24772 static Lisp_Object
24773 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24774 int boff, int override)
24775 {
24776 Lisp_Object face_name = Qnil;
24777 int ascent, descent, height;
24778
24779 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24780 return val;
24781
24782 if (CONSP (val))
24783 {
24784 face_name = XCAR (val);
24785 val = XCDR (val);
24786 if (!NUMBERP (val))
24787 val = make_number (1);
24788 if (NILP (face_name))
24789 {
24790 height = it->ascent + it->descent;
24791 goto scale;
24792 }
24793 }
24794
24795 if (NILP (face_name))
24796 {
24797 font = FRAME_FONT (it->f);
24798 boff = FRAME_BASELINE_OFFSET (it->f);
24799 }
24800 else if (EQ (face_name, Qt))
24801 {
24802 override = 0;
24803 }
24804 else
24805 {
24806 int face_id;
24807 struct face *face;
24808
24809 face_id = lookup_named_face (it->f, face_name, 0);
24810 if (face_id < 0)
24811 return make_number (-1);
24812
24813 face = FACE_FROM_ID (it->f, face_id);
24814 font = face->font;
24815 if (font == NULL)
24816 return make_number (-1);
24817 boff = font->baseline_offset;
24818 if (font->vertical_centering)
24819 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24820 }
24821
24822 ascent = FONT_BASE (font) + boff;
24823 descent = FONT_DESCENT (font) - boff;
24824
24825 if (override)
24826 {
24827 it->override_ascent = ascent;
24828 it->override_descent = descent;
24829 it->override_boff = boff;
24830 }
24831
24832 height = ascent + descent;
24833
24834 scale:
24835 if (FLOATP (val))
24836 height = (int)(XFLOAT_DATA (val) * height);
24837 else if (INTEGERP (val))
24838 height *= XINT (val);
24839
24840 return make_number (height);
24841 }
24842
24843
24844 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24845 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24846 and only if this is for a character for which no font was found.
24847
24848 If the display method (it->glyphless_method) is
24849 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24850 length of the acronym or the hexadecimal string, UPPER_XOFF and
24851 UPPER_YOFF are pixel offsets for the upper part of the string,
24852 LOWER_XOFF and LOWER_YOFF are for the lower part.
24853
24854 For the other display methods, LEN through LOWER_YOFF are zero. */
24855
24856 static void
24857 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24858 short upper_xoff, short upper_yoff,
24859 short lower_xoff, short lower_yoff)
24860 {
24861 struct glyph *glyph;
24862 enum glyph_row_area area = it->area;
24863
24864 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24865 if (glyph < it->glyph_row->glyphs[area + 1])
24866 {
24867 /* If the glyph row is reversed, we need to prepend the glyph
24868 rather than append it. */
24869 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24870 {
24871 struct glyph *g;
24872
24873 /* Make room for the additional glyph. */
24874 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24875 g[1] = *g;
24876 glyph = it->glyph_row->glyphs[area];
24877 }
24878 glyph->charpos = CHARPOS (it->position);
24879 glyph->object = it->object;
24880 glyph->pixel_width = it->pixel_width;
24881 glyph->ascent = it->ascent;
24882 glyph->descent = it->descent;
24883 glyph->voffset = it->voffset;
24884 glyph->type = GLYPHLESS_GLYPH;
24885 glyph->u.glyphless.method = it->glyphless_method;
24886 glyph->u.glyphless.for_no_font = for_no_font;
24887 glyph->u.glyphless.len = len;
24888 glyph->u.glyphless.ch = it->c;
24889 glyph->slice.glyphless.upper_xoff = upper_xoff;
24890 glyph->slice.glyphless.upper_yoff = upper_yoff;
24891 glyph->slice.glyphless.lower_xoff = lower_xoff;
24892 glyph->slice.glyphless.lower_yoff = lower_yoff;
24893 glyph->avoid_cursor_p = it->avoid_cursor_p;
24894 glyph->multibyte_p = it->multibyte_p;
24895 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24896 {
24897 /* In R2L rows, the left and the right box edges need to be
24898 drawn in reverse direction. */
24899 glyph->right_box_line_p = it->start_of_box_run_p;
24900 glyph->left_box_line_p = it->end_of_box_run_p;
24901 }
24902 else
24903 {
24904 glyph->left_box_line_p = it->start_of_box_run_p;
24905 glyph->right_box_line_p = it->end_of_box_run_p;
24906 }
24907 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24908 || it->phys_descent > it->descent);
24909 glyph->padding_p = 0;
24910 glyph->glyph_not_available_p = 0;
24911 glyph->face_id = face_id;
24912 glyph->font_type = FONT_TYPE_UNKNOWN;
24913 if (it->bidi_p)
24914 {
24915 glyph->resolved_level = it->bidi_it.resolved_level;
24916 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24917 emacs_abort ();
24918 glyph->bidi_type = it->bidi_it.type;
24919 }
24920 ++it->glyph_row->used[area];
24921 }
24922 else
24923 IT_EXPAND_MATRIX_WIDTH (it, area);
24924 }
24925
24926
24927 /* Produce a glyph for a glyphless character for iterator IT.
24928 IT->glyphless_method specifies which method to use for displaying
24929 the character. See the description of enum
24930 glyphless_display_method in dispextern.h for the detail.
24931
24932 FOR_NO_FONT is nonzero if and only if this is for a character for
24933 which no font was found. ACRONYM, if non-nil, is an acronym string
24934 for the character. */
24935
24936 static void
24937 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24938 {
24939 int face_id;
24940 struct face *face;
24941 struct font *font;
24942 int base_width, base_height, width, height;
24943 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24944 int len;
24945
24946 /* Get the metrics of the base font. We always refer to the current
24947 ASCII face. */
24948 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24949 font = face->font ? face->font : FRAME_FONT (it->f);
24950 it->ascent = FONT_BASE (font) + font->baseline_offset;
24951 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24952 base_height = it->ascent + it->descent;
24953 base_width = font->average_width;
24954
24955 /* Get a face ID for the glyph by utilizing a cache (the same way as
24956 done for `escape-glyph' in get_next_display_element). */
24957 if (it->f == last_glyphless_glyph_frame
24958 && it->face_id == last_glyphless_glyph_face_id)
24959 {
24960 face_id = last_glyphless_glyph_merged_face_id;
24961 }
24962 else
24963 {
24964 /* Merge the `glyphless-char' face into the current face. */
24965 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24966 last_glyphless_glyph_frame = it->f;
24967 last_glyphless_glyph_face_id = it->face_id;
24968 last_glyphless_glyph_merged_face_id = face_id;
24969 }
24970
24971 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24972 {
24973 it->pixel_width = THIN_SPACE_WIDTH;
24974 len = 0;
24975 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24976 }
24977 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24978 {
24979 width = CHAR_WIDTH (it->c);
24980 if (width == 0)
24981 width = 1;
24982 else if (width > 4)
24983 width = 4;
24984 it->pixel_width = base_width * width;
24985 len = 0;
24986 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24987 }
24988 else
24989 {
24990 char buf[7];
24991 const char *str;
24992 unsigned int code[6];
24993 int upper_len;
24994 int ascent, descent;
24995 struct font_metrics metrics_upper, metrics_lower;
24996
24997 face = FACE_FROM_ID (it->f, face_id);
24998 font = face->font ? face->font : FRAME_FONT (it->f);
24999 PREPARE_FACE_FOR_DISPLAY (it->f, face);
25000
25001 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
25002 {
25003 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
25004 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
25005 if (CONSP (acronym))
25006 acronym = XCAR (acronym);
25007 str = STRINGP (acronym) ? SSDATA (acronym) : "";
25008 }
25009 else
25010 {
25011 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
25012 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
25013 str = buf;
25014 }
25015 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
25016 code[len] = font->driver->encode_char (font, str[len]);
25017 upper_len = (len + 1) / 2;
25018 font->driver->text_extents (font, code, upper_len,
25019 &metrics_upper);
25020 font->driver->text_extents (font, code + upper_len, len - upper_len,
25021 &metrics_lower);
25022
25023
25024
25025 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
25026 width = max (metrics_upper.width, metrics_lower.width) + 4;
25027 upper_xoff = upper_yoff = 2; /* the typical case */
25028 if (base_width >= width)
25029 {
25030 /* Align the upper to the left, the lower to the right. */
25031 it->pixel_width = base_width;
25032 lower_xoff = base_width - 2 - metrics_lower.width;
25033 }
25034 else
25035 {
25036 /* Center the shorter one. */
25037 it->pixel_width = width;
25038 if (metrics_upper.width >= metrics_lower.width)
25039 lower_xoff = (width - metrics_lower.width) / 2;
25040 else
25041 {
25042 /* FIXME: This code doesn't look right. It formerly was
25043 missing the "lower_xoff = 0;", which couldn't have
25044 been right since it left lower_xoff uninitialized. */
25045 lower_xoff = 0;
25046 upper_xoff = (width - metrics_upper.width) / 2;
25047 }
25048 }
25049
25050 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
25051 top, bottom, and between upper and lower strings. */
25052 height = (metrics_upper.ascent + metrics_upper.descent
25053 + metrics_lower.ascent + metrics_lower.descent) + 5;
25054 /* Center vertically.
25055 H:base_height, D:base_descent
25056 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25057
25058 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25059 descent = D - H/2 + h/2;
25060 lower_yoff = descent - 2 - ld;
25061 upper_yoff = lower_yoff - la - 1 - ud; */
25062 ascent = - (it->descent - (base_height + height + 1) / 2);
25063 descent = it->descent - (base_height - height) / 2;
25064 lower_yoff = descent - 2 - metrics_lower.descent;
25065 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
25066 - metrics_upper.descent);
25067 /* Don't make the height shorter than the base height. */
25068 if (height > base_height)
25069 {
25070 it->ascent = ascent;
25071 it->descent = descent;
25072 }
25073 }
25074
25075 it->phys_ascent = it->ascent;
25076 it->phys_descent = it->descent;
25077 if (it->glyph_row)
25078 append_glyphless_glyph (it, face_id, for_no_font, len,
25079 upper_xoff, upper_yoff,
25080 lower_xoff, lower_yoff);
25081 it->nglyphs = 1;
25082 take_vertical_position_into_account (it);
25083 }
25084
25085
25086 /* RIF:
25087 Produce glyphs/get display metrics for the display element IT is
25088 loaded with. See the description of struct it in dispextern.h
25089 for an overview of struct it. */
25090
25091 void
25092 x_produce_glyphs (struct it *it)
25093 {
25094 int extra_line_spacing = it->extra_line_spacing;
25095
25096 it->glyph_not_available_p = 0;
25097
25098 if (it->what == IT_CHARACTER)
25099 {
25100 XChar2b char2b;
25101 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25102 struct font *font = face->font;
25103 struct font_metrics *pcm = NULL;
25104 int boff; /* baseline offset */
25105
25106 if (font == NULL)
25107 {
25108 /* When no suitable font is found, display this character by
25109 the method specified in the first extra slot of
25110 Vglyphless_char_display. */
25111 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
25112
25113 eassert (it->what == IT_GLYPHLESS);
25114 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
25115 goto done;
25116 }
25117
25118 boff = font->baseline_offset;
25119 if (font->vertical_centering)
25120 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25121
25122 if (it->char_to_display != '\n' && it->char_to_display != '\t')
25123 {
25124 int stretched_p;
25125
25126 it->nglyphs = 1;
25127
25128 if (it->override_ascent >= 0)
25129 {
25130 it->ascent = it->override_ascent;
25131 it->descent = it->override_descent;
25132 boff = it->override_boff;
25133 }
25134 else
25135 {
25136 it->ascent = FONT_BASE (font) + boff;
25137 it->descent = FONT_DESCENT (font) - boff;
25138 }
25139
25140 if (get_char_glyph_code (it->char_to_display, font, &char2b))
25141 {
25142 pcm = get_per_char_metric (font, &char2b);
25143 if (pcm->width == 0
25144 && pcm->rbearing == 0 && pcm->lbearing == 0)
25145 pcm = NULL;
25146 }
25147
25148 if (pcm)
25149 {
25150 it->phys_ascent = pcm->ascent + boff;
25151 it->phys_descent = pcm->descent - boff;
25152 it->pixel_width = pcm->width;
25153 }
25154 else
25155 {
25156 it->glyph_not_available_p = 1;
25157 it->phys_ascent = it->ascent;
25158 it->phys_descent = it->descent;
25159 it->pixel_width = font->space_width;
25160 }
25161
25162 if (it->constrain_row_ascent_descent_p)
25163 {
25164 if (it->descent > it->max_descent)
25165 {
25166 it->ascent += it->descent - it->max_descent;
25167 it->descent = it->max_descent;
25168 }
25169 if (it->ascent > it->max_ascent)
25170 {
25171 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25172 it->ascent = it->max_ascent;
25173 }
25174 it->phys_ascent = min (it->phys_ascent, it->ascent);
25175 it->phys_descent = min (it->phys_descent, it->descent);
25176 extra_line_spacing = 0;
25177 }
25178
25179 /* If this is a space inside a region of text with
25180 `space-width' property, change its width. */
25181 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
25182 if (stretched_p)
25183 it->pixel_width *= XFLOATINT (it->space_width);
25184
25185 /* If face has a box, add the box thickness to the character
25186 height. If character has a box line to the left and/or
25187 right, add the box line width to the character's width. */
25188 if (face->box != FACE_NO_BOX)
25189 {
25190 int thick = face->box_line_width;
25191
25192 if (thick > 0)
25193 {
25194 it->ascent += thick;
25195 it->descent += thick;
25196 }
25197 else
25198 thick = -thick;
25199
25200 if (it->start_of_box_run_p)
25201 it->pixel_width += thick;
25202 if (it->end_of_box_run_p)
25203 it->pixel_width += thick;
25204 }
25205
25206 /* If face has an overline, add the height of the overline
25207 (1 pixel) and a 1 pixel margin to the character height. */
25208 if (face->overline_p)
25209 it->ascent += overline_margin;
25210
25211 if (it->constrain_row_ascent_descent_p)
25212 {
25213 if (it->ascent > it->max_ascent)
25214 it->ascent = it->max_ascent;
25215 if (it->descent > it->max_descent)
25216 it->descent = it->max_descent;
25217 }
25218
25219 take_vertical_position_into_account (it);
25220
25221 /* If we have to actually produce glyphs, do it. */
25222 if (it->glyph_row)
25223 {
25224 if (stretched_p)
25225 {
25226 /* Translate a space with a `space-width' property
25227 into a stretch glyph. */
25228 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25229 / FONT_HEIGHT (font));
25230 append_stretch_glyph (it, it->object, it->pixel_width,
25231 it->ascent + it->descent, ascent);
25232 }
25233 else
25234 append_glyph (it);
25235
25236 /* If characters with lbearing or rbearing are displayed
25237 in this line, record that fact in a flag of the
25238 glyph row. This is used to optimize X output code. */
25239 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25240 it->glyph_row->contains_overlapping_glyphs_p = 1;
25241 }
25242 if (! stretched_p && it->pixel_width == 0)
25243 /* We assure that all visible glyphs have at least 1-pixel
25244 width. */
25245 it->pixel_width = 1;
25246 }
25247 else if (it->char_to_display == '\n')
25248 {
25249 /* A newline has no width, but we need the height of the
25250 line. But if previous part of the line sets a height,
25251 don't increase that height */
25252
25253 Lisp_Object height;
25254 Lisp_Object total_height = Qnil;
25255
25256 it->override_ascent = -1;
25257 it->pixel_width = 0;
25258 it->nglyphs = 0;
25259
25260 height = get_it_property (it, Qline_height);
25261 /* Split (line-height total-height) list */
25262 if (CONSP (height)
25263 && CONSP (XCDR (height))
25264 && NILP (XCDR (XCDR (height))))
25265 {
25266 total_height = XCAR (XCDR (height));
25267 height = XCAR (height);
25268 }
25269 height = calc_line_height_property (it, height, font, boff, 1);
25270
25271 if (it->override_ascent >= 0)
25272 {
25273 it->ascent = it->override_ascent;
25274 it->descent = it->override_descent;
25275 boff = it->override_boff;
25276 }
25277 else
25278 {
25279 it->ascent = FONT_BASE (font) + boff;
25280 it->descent = FONT_DESCENT (font) - boff;
25281 }
25282
25283 if (EQ (height, Qt))
25284 {
25285 if (it->descent > it->max_descent)
25286 {
25287 it->ascent += it->descent - it->max_descent;
25288 it->descent = it->max_descent;
25289 }
25290 if (it->ascent > it->max_ascent)
25291 {
25292 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25293 it->ascent = it->max_ascent;
25294 }
25295 it->phys_ascent = min (it->phys_ascent, it->ascent);
25296 it->phys_descent = min (it->phys_descent, it->descent);
25297 it->constrain_row_ascent_descent_p = 1;
25298 extra_line_spacing = 0;
25299 }
25300 else
25301 {
25302 Lisp_Object spacing;
25303
25304 it->phys_ascent = it->ascent;
25305 it->phys_descent = it->descent;
25306
25307 if ((it->max_ascent > 0 || it->max_descent > 0)
25308 && face->box != FACE_NO_BOX
25309 && face->box_line_width > 0)
25310 {
25311 it->ascent += face->box_line_width;
25312 it->descent += face->box_line_width;
25313 }
25314 if (!NILP (height)
25315 && XINT (height) > it->ascent + it->descent)
25316 it->ascent = XINT (height) - it->descent;
25317
25318 if (!NILP (total_height))
25319 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25320 else
25321 {
25322 spacing = get_it_property (it, Qline_spacing);
25323 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25324 }
25325 if (INTEGERP (spacing))
25326 {
25327 extra_line_spacing = XINT (spacing);
25328 if (!NILP (total_height))
25329 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25330 }
25331 }
25332 }
25333 else /* i.e. (it->char_to_display == '\t') */
25334 {
25335 if (font->space_width > 0)
25336 {
25337 int tab_width = it->tab_width * font->space_width;
25338 int x = it->current_x + it->continuation_lines_width;
25339 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25340
25341 /* If the distance from the current position to the next tab
25342 stop is less than a space character width, use the
25343 tab stop after that. */
25344 if (next_tab_x - x < font->space_width)
25345 next_tab_x += tab_width;
25346
25347 it->pixel_width = next_tab_x - x;
25348 it->nglyphs = 1;
25349 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25350 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25351
25352 if (it->glyph_row)
25353 {
25354 append_stretch_glyph (it, it->object, it->pixel_width,
25355 it->ascent + it->descent, it->ascent);
25356 }
25357 }
25358 else
25359 {
25360 it->pixel_width = 0;
25361 it->nglyphs = 1;
25362 }
25363 }
25364 }
25365 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25366 {
25367 /* A static composition.
25368
25369 Note: A composition is represented as one glyph in the
25370 glyph matrix. There are no padding glyphs.
25371
25372 Important note: pixel_width, ascent, and descent are the
25373 values of what is drawn by draw_glyphs (i.e. the values of
25374 the overall glyphs composed). */
25375 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25376 int boff; /* baseline offset */
25377 struct composition *cmp = composition_table[it->cmp_it.id];
25378 int glyph_len = cmp->glyph_len;
25379 struct font *font = face->font;
25380
25381 it->nglyphs = 1;
25382
25383 /* If we have not yet calculated pixel size data of glyphs of
25384 the composition for the current face font, calculate them
25385 now. Theoretically, we have to check all fonts for the
25386 glyphs, but that requires much time and memory space. So,
25387 here we check only the font of the first glyph. This may
25388 lead to incorrect display, but it's very rare, and C-l
25389 (recenter-top-bottom) can correct the display anyway. */
25390 if (! cmp->font || cmp->font != font)
25391 {
25392 /* Ascent and descent of the font of the first character
25393 of this composition (adjusted by baseline offset).
25394 Ascent and descent of overall glyphs should not be less
25395 than these, respectively. */
25396 int font_ascent, font_descent, font_height;
25397 /* Bounding box of the overall glyphs. */
25398 int leftmost, rightmost, lowest, highest;
25399 int lbearing, rbearing;
25400 int i, width, ascent, descent;
25401 int left_padded = 0, right_padded = 0;
25402 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25403 XChar2b char2b;
25404 struct font_metrics *pcm;
25405 int font_not_found_p;
25406 ptrdiff_t pos;
25407
25408 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25409 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25410 break;
25411 if (glyph_len < cmp->glyph_len)
25412 right_padded = 1;
25413 for (i = 0; i < glyph_len; i++)
25414 {
25415 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25416 break;
25417 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25418 }
25419 if (i > 0)
25420 left_padded = 1;
25421
25422 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25423 : IT_CHARPOS (*it));
25424 /* If no suitable font is found, use the default font. */
25425 font_not_found_p = font == NULL;
25426 if (font_not_found_p)
25427 {
25428 face = face->ascii_face;
25429 font = face->font;
25430 }
25431 boff = font->baseline_offset;
25432 if (font->vertical_centering)
25433 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25434 font_ascent = FONT_BASE (font) + boff;
25435 font_descent = FONT_DESCENT (font) - boff;
25436 font_height = FONT_HEIGHT (font);
25437
25438 cmp->font = font;
25439
25440 pcm = NULL;
25441 if (! font_not_found_p)
25442 {
25443 get_char_face_and_encoding (it->f, c, it->face_id,
25444 &char2b, 0);
25445 pcm = get_per_char_metric (font, &char2b);
25446 }
25447
25448 /* Initialize the bounding box. */
25449 if (pcm)
25450 {
25451 width = cmp->glyph_len > 0 ? pcm->width : 0;
25452 ascent = pcm->ascent;
25453 descent = pcm->descent;
25454 lbearing = pcm->lbearing;
25455 rbearing = pcm->rbearing;
25456 }
25457 else
25458 {
25459 width = cmp->glyph_len > 0 ? font->space_width : 0;
25460 ascent = FONT_BASE (font);
25461 descent = FONT_DESCENT (font);
25462 lbearing = 0;
25463 rbearing = width;
25464 }
25465
25466 rightmost = width;
25467 leftmost = 0;
25468 lowest = - descent + boff;
25469 highest = ascent + boff;
25470
25471 if (! font_not_found_p
25472 && font->default_ascent
25473 && CHAR_TABLE_P (Vuse_default_ascent)
25474 && !NILP (Faref (Vuse_default_ascent,
25475 make_number (it->char_to_display))))
25476 highest = font->default_ascent + boff;
25477
25478 /* Draw the first glyph at the normal position. It may be
25479 shifted to right later if some other glyphs are drawn
25480 at the left. */
25481 cmp->offsets[i * 2] = 0;
25482 cmp->offsets[i * 2 + 1] = boff;
25483 cmp->lbearing = lbearing;
25484 cmp->rbearing = rbearing;
25485
25486 /* Set cmp->offsets for the remaining glyphs. */
25487 for (i++; i < glyph_len; i++)
25488 {
25489 int left, right, btm, top;
25490 int ch = COMPOSITION_GLYPH (cmp, i);
25491 int face_id;
25492 struct face *this_face;
25493
25494 if (ch == '\t')
25495 ch = ' ';
25496 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25497 this_face = FACE_FROM_ID (it->f, face_id);
25498 font = this_face->font;
25499
25500 if (font == NULL)
25501 pcm = NULL;
25502 else
25503 {
25504 get_char_face_and_encoding (it->f, ch, face_id,
25505 &char2b, 0);
25506 pcm = get_per_char_metric (font, &char2b);
25507 }
25508 if (! pcm)
25509 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25510 else
25511 {
25512 width = pcm->width;
25513 ascent = pcm->ascent;
25514 descent = pcm->descent;
25515 lbearing = pcm->lbearing;
25516 rbearing = pcm->rbearing;
25517 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25518 {
25519 /* Relative composition with or without
25520 alternate chars. */
25521 left = (leftmost + rightmost - width) / 2;
25522 btm = - descent + boff;
25523 if (font->relative_compose
25524 && (! CHAR_TABLE_P (Vignore_relative_composition)
25525 || NILP (Faref (Vignore_relative_composition,
25526 make_number (ch)))))
25527 {
25528
25529 if (- descent >= font->relative_compose)
25530 /* One extra pixel between two glyphs. */
25531 btm = highest + 1;
25532 else if (ascent <= 0)
25533 /* One extra pixel between two glyphs. */
25534 btm = lowest - 1 - ascent - descent;
25535 }
25536 }
25537 else
25538 {
25539 /* A composition rule is specified by an integer
25540 value that encodes global and new reference
25541 points (GREF and NREF). GREF and NREF are
25542 specified by numbers as below:
25543
25544 0---1---2 -- ascent
25545 | |
25546 | |
25547 | |
25548 9--10--11 -- center
25549 | |
25550 ---3---4---5--- baseline
25551 | |
25552 6---7---8 -- descent
25553 */
25554 int rule = COMPOSITION_RULE (cmp, i);
25555 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25556
25557 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25558 grefx = gref % 3, nrefx = nref % 3;
25559 grefy = gref / 3, nrefy = nref / 3;
25560 if (xoff)
25561 xoff = font_height * (xoff - 128) / 256;
25562 if (yoff)
25563 yoff = font_height * (yoff - 128) / 256;
25564
25565 left = (leftmost
25566 + grefx * (rightmost - leftmost) / 2
25567 - nrefx * width / 2
25568 + xoff);
25569
25570 btm = ((grefy == 0 ? highest
25571 : grefy == 1 ? 0
25572 : grefy == 2 ? lowest
25573 : (highest + lowest) / 2)
25574 - (nrefy == 0 ? ascent + descent
25575 : nrefy == 1 ? descent - boff
25576 : nrefy == 2 ? 0
25577 : (ascent + descent) / 2)
25578 + yoff);
25579 }
25580
25581 cmp->offsets[i * 2] = left;
25582 cmp->offsets[i * 2 + 1] = btm + descent;
25583
25584 /* Update the bounding box of the overall glyphs. */
25585 if (width > 0)
25586 {
25587 right = left + width;
25588 if (left < leftmost)
25589 leftmost = left;
25590 if (right > rightmost)
25591 rightmost = right;
25592 }
25593 top = btm + descent + ascent;
25594 if (top > highest)
25595 highest = top;
25596 if (btm < lowest)
25597 lowest = btm;
25598
25599 if (cmp->lbearing > left + lbearing)
25600 cmp->lbearing = left + lbearing;
25601 if (cmp->rbearing < left + rbearing)
25602 cmp->rbearing = left + rbearing;
25603 }
25604 }
25605
25606 /* If there are glyphs whose x-offsets are negative,
25607 shift all glyphs to the right and make all x-offsets
25608 non-negative. */
25609 if (leftmost < 0)
25610 {
25611 for (i = 0; i < cmp->glyph_len; i++)
25612 cmp->offsets[i * 2] -= leftmost;
25613 rightmost -= leftmost;
25614 cmp->lbearing -= leftmost;
25615 cmp->rbearing -= leftmost;
25616 }
25617
25618 if (left_padded && cmp->lbearing < 0)
25619 {
25620 for (i = 0; i < cmp->glyph_len; i++)
25621 cmp->offsets[i * 2] -= cmp->lbearing;
25622 rightmost -= cmp->lbearing;
25623 cmp->rbearing -= cmp->lbearing;
25624 cmp->lbearing = 0;
25625 }
25626 if (right_padded && rightmost < cmp->rbearing)
25627 {
25628 rightmost = cmp->rbearing;
25629 }
25630
25631 cmp->pixel_width = rightmost;
25632 cmp->ascent = highest;
25633 cmp->descent = - lowest;
25634 if (cmp->ascent < font_ascent)
25635 cmp->ascent = font_ascent;
25636 if (cmp->descent < font_descent)
25637 cmp->descent = font_descent;
25638 }
25639
25640 if (it->glyph_row
25641 && (cmp->lbearing < 0
25642 || cmp->rbearing > cmp->pixel_width))
25643 it->glyph_row->contains_overlapping_glyphs_p = 1;
25644
25645 it->pixel_width = cmp->pixel_width;
25646 it->ascent = it->phys_ascent = cmp->ascent;
25647 it->descent = it->phys_descent = cmp->descent;
25648 if (face->box != FACE_NO_BOX)
25649 {
25650 int thick = face->box_line_width;
25651
25652 if (thick > 0)
25653 {
25654 it->ascent += thick;
25655 it->descent += thick;
25656 }
25657 else
25658 thick = - thick;
25659
25660 if (it->start_of_box_run_p)
25661 it->pixel_width += thick;
25662 if (it->end_of_box_run_p)
25663 it->pixel_width += thick;
25664 }
25665
25666 /* If face has an overline, add the height of the overline
25667 (1 pixel) and a 1 pixel margin to the character height. */
25668 if (face->overline_p)
25669 it->ascent += overline_margin;
25670
25671 take_vertical_position_into_account (it);
25672 if (it->ascent < 0)
25673 it->ascent = 0;
25674 if (it->descent < 0)
25675 it->descent = 0;
25676
25677 if (it->glyph_row && cmp->glyph_len > 0)
25678 append_composite_glyph (it);
25679 }
25680 else if (it->what == IT_COMPOSITION)
25681 {
25682 /* A dynamic (automatic) composition. */
25683 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25684 Lisp_Object gstring;
25685 struct font_metrics metrics;
25686
25687 it->nglyphs = 1;
25688
25689 gstring = composition_gstring_from_id (it->cmp_it.id);
25690 it->pixel_width
25691 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25692 &metrics);
25693 if (it->glyph_row
25694 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25695 it->glyph_row->contains_overlapping_glyphs_p = 1;
25696 it->ascent = it->phys_ascent = metrics.ascent;
25697 it->descent = it->phys_descent = metrics.descent;
25698 if (face->box != FACE_NO_BOX)
25699 {
25700 int thick = face->box_line_width;
25701
25702 if (thick > 0)
25703 {
25704 it->ascent += thick;
25705 it->descent += thick;
25706 }
25707 else
25708 thick = - thick;
25709
25710 if (it->start_of_box_run_p)
25711 it->pixel_width += thick;
25712 if (it->end_of_box_run_p)
25713 it->pixel_width += thick;
25714 }
25715 /* If face has an overline, add the height of the overline
25716 (1 pixel) and a 1 pixel margin to the character height. */
25717 if (face->overline_p)
25718 it->ascent += overline_margin;
25719 take_vertical_position_into_account (it);
25720 if (it->ascent < 0)
25721 it->ascent = 0;
25722 if (it->descent < 0)
25723 it->descent = 0;
25724
25725 if (it->glyph_row)
25726 append_composite_glyph (it);
25727 }
25728 else if (it->what == IT_GLYPHLESS)
25729 produce_glyphless_glyph (it, 0, Qnil);
25730 else if (it->what == IT_IMAGE)
25731 produce_image_glyph (it);
25732 else if (it->what == IT_STRETCH)
25733 produce_stretch_glyph (it);
25734
25735 done:
25736 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25737 because this isn't true for images with `:ascent 100'. */
25738 eassert (it->ascent >= 0 && it->descent >= 0);
25739 if (it->area == TEXT_AREA)
25740 it->current_x += it->pixel_width;
25741
25742 if (extra_line_spacing > 0)
25743 {
25744 it->descent += extra_line_spacing;
25745 if (extra_line_spacing > it->max_extra_line_spacing)
25746 it->max_extra_line_spacing = extra_line_spacing;
25747 }
25748
25749 it->max_ascent = max (it->max_ascent, it->ascent);
25750 it->max_descent = max (it->max_descent, it->descent);
25751 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25752 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25753 }
25754
25755 /* EXPORT for RIF:
25756 Output LEN glyphs starting at START at the nominal cursor position.
25757 Advance the nominal cursor over the text. The global variable
25758 updated_row is the glyph row being updated, and updated_area is the
25759 area of that row being updated. */
25760
25761 void
25762 x_write_glyphs (struct window *w, struct glyph *start, int len)
25763 {
25764 int x, hpos, chpos = w->phys_cursor.hpos;
25765
25766 eassert (updated_row);
25767 /* When the window is hscrolled, cursor hpos can legitimately be out
25768 of bounds, but we draw the cursor at the corresponding window
25769 margin in that case. */
25770 if (!updated_row->reversed_p && chpos < 0)
25771 chpos = 0;
25772 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25773 chpos = updated_row->used[TEXT_AREA] - 1;
25774
25775 block_input ();
25776
25777 /* Write glyphs. */
25778
25779 hpos = start - updated_row->glyphs[updated_area];
25780 x = draw_glyphs (w, output_cursor.x,
25781 updated_row, updated_area,
25782 hpos, hpos + len,
25783 DRAW_NORMAL_TEXT, 0);
25784
25785 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25786 if (updated_area == TEXT_AREA
25787 && w->phys_cursor_on_p
25788 && w->phys_cursor.vpos == output_cursor.vpos
25789 && chpos >= hpos
25790 && chpos < hpos + len)
25791 w->phys_cursor_on_p = 0;
25792
25793 unblock_input ();
25794
25795 /* Advance the output cursor. */
25796 output_cursor.hpos += len;
25797 output_cursor.x = x;
25798 }
25799
25800
25801 /* EXPORT for RIF:
25802 Insert LEN glyphs from START at the nominal cursor position. */
25803
25804 void
25805 x_insert_glyphs (struct window *w, struct glyph *start, int len)
25806 {
25807 struct frame *f;
25808 int line_height, shift_by_width, shifted_region_width;
25809 struct glyph_row *row;
25810 struct glyph *glyph;
25811 int frame_x, frame_y;
25812 ptrdiff_t hpos;
25813
25814 eassert (updated_row);
25815 block_input ();
25816 f = XFRAME (WINDOW_FRAME (w));
25817
25818 /* Get the height of the line we are in. */
25819 row = updated_row;
25820 line_height = row->height;
25821
25822 /* Get the width of the glyphs to insert. */
25823 shift_by_width = 0;
25824 for (glyph = start; glyph < start + len; ++glyph)
25825 shift_by_width += glyph->pixel_width;
25826
25827 /* Get the width of the region to shift right. */
25828 shifted_region_width = (window_box_width (w, updated_area)
25829 - output_cursor.x
25830 - shift_by_width);
25831
25832 /* Shift right. */
25833 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25834 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25835
25836 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25837 line_height, shift_by_width);
25838
25839 /* Write the glyphs. */
25840 hpos = start - row->glyphs[updated_area];
25841 draw_glyphs (w, output_cursor.x, row, updated_area,
25842 hpos, hpos + len,
25843 DRAW_NORMAL_TEXT, 0);
25844
25845 /* Advance the output cursor. */
25846 output_cursor.hpos += len;
25847 output_cursor.x += shift_by_width;
25848 unblock_input ();
25849 }
25850
25851
25852 /* EXPORT for RIF:
25853 Erase the current text line from the nominal cursor position
25854 (inclusive) to pixel column TO_X (exclusive). The idea is that
25855 everything from TO_X onward is already erased.
25856
25857 TO_X is a pixel position relative to updated_area of currently
25858 updated window W. TO_X == -1 means clear to the end of this area. */
25859
25860 void
25861 x_clear_end_of_line (struct window *w, int to_x)
25862 {
25863 struct frame *f;
25864 int max_x, min_y, max_y;
25865 int from_x, from_y, to_y;
25866
25867 eassert (updated_row);
25868 f = XFRAME (w->frame);
25869
25870 if (updated_row->full_width_p)
25871 max_x = WINDOW_TOTAL_WIDTH (w);
25872 else
25873 max_x = window_box_width (w, updated_area);
25874 max_y = window_text_bottom_y (w);
25875
25876 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25877 of window. For TO_X > 0, truncate to end of drawing area. */
25878 if (to_x == 0)
25879 return;
25880 else if (to_x < 0)
25881 to_x = max_x;
25882 else
25883 to_x = min (to_x, max_x);
25884
25885 to_y = min (max_y, output_cursor.y + updated_row->height);
25886
25887 /* Notice if the cursor will be cleared by this operation. */
25888 if (!updated_row->full_width_p)
25889 notice_overwritten_cursor (w, updated_area,
25890 output_cursor.x, -1,
25891 updated_row->y,
25892 MATRIX_ROW_BOTTOM_Y (updated_row));
25893
25894 from_x = output_cursor.x;
25895
25896 /* Translate to frame coordinates. */
25897 if (updated_row->full_width_p)
25898 {
25899 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25900 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25901 }
25902 else
25903 {
25904 int area_left = window_box_left (w, updated_area);
25905 from_x += area_left;
25906 to_x += area_left;
25907 }
25908
25909 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25910 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25911 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25912
25913 /* Prevent inadvertently clearing to end of the X window. */
25914 if (to_x > from_x && to_y > from_y)
25915 {
25916 block_input ();
25917 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25918 to_x - from_x, to_y - from_y);
25919 unblock_input ();
25920 }
25921 }
25922
25923 #endif /* HAVE_WINDOW_SYSTEM */
25924
25925
25926 \f
25927 /***********************************************************************
25928 Cursor types
25929 ***********************************************************************/
25930
25931 /* Value is the internal representation of the specified cursor type
25932 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25933 of the bar cursor. */
25934
25935 static enum text_cursor_kinds
25936 get_specified_cursor_type (Lisp_Object arg, int *width)
25937 {
25938 enum text_cursor_kinds type;
25939
25940 if (NILP (arg))
25941 return NO_CURSOR;
25942
25943 if (EQ (arg, Qbox))
25944 return FILLED_BOX_CURSOR;
25945
25946 if (EQ (arg, Qhollow))
25947 return HOLLOW_BOX_CURSOR;
25948
25949 if (EQ (arg, Qbar))
25950 {
25951 *width = 2;
25952 return BAR_CURSOR;
25953 }
25954
25955 if (CONSP (arg)
25956 && EQ (XCAR (arg), Qbar)
25957 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25958 {
25959 *width = XINT (XCDR (arg));
25960 return BAR_CURSOR;
25961 }
25962
25963 if (EQ (arg, Qhbar))
25964 {
25965 *width = 2;
25966 return HBAR_CURSOR;
25967 }
25968
25969 if (CONSP (arg)
25970 && EQ (XCAR (arg), Qhbar)
25971 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25972 {
25973 *width = XINT (XCDR (arg));
25974 return HBAR_CURSOR;
25975 }
25976
25977 /* Treat anything unknown as "hollow box cursor".
25978 It was bad to signal an error; people have trouble fixing
25979 .Xdefaults with Emacs, when it has something bad in it. */
25980 type = HOLLOW_BOX_CURSOR;
25981
25982 return type;
25983 }
25984
25985 /* Set the default cursor types for specified frame. */
25986 void
25987 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25988 {
25989 int width = 1;
25990 Lisp_Object tem;
25991
25992 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25993 FRAME_CURSOR_WIDTH (f) = width;
25994
25995 /* By default, set up the blink-off state depending on the on-state. */
25996
25997 tem = Fassoc (arg, Vblink_cursor_alist);
25998 if (!NILP (tem))
25999 {
26000 FRAME_BLINK_OFF_CURSOR (f)
26001 = get_specified_cursor_type (XCDR (tem), &width);
26002 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
26003 }
26004 else
26005 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
26006 }
26007
26008
26009 #ifdef HAVE_WINDOW_SYSTEM
26010
26011 /* Return the cursor we want to be displayed in window W. Return
26012 width of bar/hbar cursor through WIDTH arg. Return with
26013 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
26014 (i.e. if the `system caret' should track this cursor).
26015
26016 In a mini-buffer window, we want the cursor only to appear if we
26017 are reading input from this window. For the selected window, we
26018 want the cursor type given by the frame parameter or buffer local
26019 setting of cursor-type. If explicitly marked off, draw no cursor.
26020 In all other cases, we want a hollow box cursor. */
26021
26022 static enum text_cursor_kinds
26023 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
26024 int *active_cursor)
26025 {
26026 struct frame *f = XFRAME (w->frame);
26027 struct buffer *b = XBUFFER (w->contents);
26028 int cursor_type = DEFAULT_CURSOR;
26029 Lisp_Object alt_cursor;
26030 int non_selected = 0;
26031
26032 *active_cursor = 1;
26033
26034 /* Echo area */
26035 if (cursor_in_echo_area
26036 && FRAME_HAS_MINIBUF_P (f)
26037 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
26038 {
26039 if (w == XWINDOW (echo_area_window))
26040 {
26041 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
26042 {
26043 *width = FRAME_CURSOR_WIDTH (f);
26044 return FRAME_DESIRED_CURSOR (f);
26045 }
26046 else
26047 return get_specified_cursor_type (BVAR (b, cursor_type), width);
26048 }
26049
26050 *active_cursor = 0;
26051 non_selected = 1;
26052 }
26053
26054 /* Detect a nonselected window or nonselected frame. */
26055 else if (w != XWINDOW (f->selected_window)
26056 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
26057 {
26058 *active_cursor = 0;
26059
26060 if (MINI_WINDOW_P (w) && minibuf_level == 0)
26061 return NO_CURSOR;
26062
26063 non_selected = 1;
26064 }
26065
26066 /* Never display a cursor in a window in which cursor-type is nil. */
26067 if (NILP (BVAR (b, cursor_type)))
26068 return NO_CURSOR;
26069
26070 /* Get the normal cursor type for this window. */
26071 if (EQ (BVAR (b, cursor_type), Qt))
26072 {
26073 cursor_type = FRAME_DESIRED_CURSOR (f);
26074 *width = FRAME_CURSOR_WIDTH (f);
26075 }
26076 else
26077 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
26078
26079 /* Use cursor-in-non-selected-windows instead
26080 for non-selected window or frame. */
26081 if (non_selected)
26082 {
26083 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
26084 if (!EQ (Qt, alt_cursor))
26085 return get_specified_cursor_type (alt_cursor, width);
26086 /* t means modify the normal cursor type. */
26087 if (cursor_type == FILLED_BOX_CURSOR)
26088 cursor_type = HOLLOW_BOX_CURSOR;
26089 else if (cursor_type == BAR_CURSOR && *width > 1)
26090 --*width;
26091 return cursor_type;
26092 }
26093
26094 /* Use normal cursor if not blinked off. */
26095 if (!w->cursor_off_p)
26096 {
26097 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26098 {
26099 if (cursor_type == FILLED_BOX_CURSOR)
26100 {
26101 /* Using a block cursor on large images can be very annoying.
26102 So use a hollow cursor for "large" images.
26103 If image is not transparent (no mask), also use hollow cursor. */
26104 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26105 if (img != NULL && IMAGEP (img->spec))
26106 {
26107 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26108 where N = size of default frame font size.
26109 This should cover most of the "tiny" icons people may use. */
26110 if (!img->mask
26111 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
26112 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
26113 cursor_type = HOLLOW_BOX_CURSOR;
26114 }
26115 }
26116 else if (cursor_type != NO_CURSOR)
26117 {
26118 /* Display current only supports BOX and HOLLOW cursors for images.
26119 So for now, unconditionally use a HOLLOW cursor when cursor is
26120 not a solid box cursor. */
26121 cursor_type = HOLLOW_BOX_CURSOR;
26122 }
26123 }
26124 return cursor_type;
26125 }
26126
26127 /* Cursor is blinked off, so determine how to "toggle" it. */
26128
26129 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26130 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
26131 return get_specified_cursor_type (XCDR (alt_cursor), width);
26132
26133 /* Then see if frame has specified a specific blink off cursor type. */
26134 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
26135 {
26136 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
26137 return FRAME_BLINK_OFF_CURSOR (f);
26138 }
26139
26140 #if 0
26141 /* Some people liked having a permanently visible blinking cursor,
26142 while others had very strong opinions against it. So it was
26143 decided to remove it. KFS 2003-09-03 */
26144
26145 /* Finally perform built-in cursor blinking:
26146 filled box <-> hollow box
26147 wide [h]bar <-> narrow [h]bar
26148 narrow [h]bar <-> no cursor
26149 other type <-> no cursor */
26150
26151 if (cursor_type == FILLED_BOX_CURSOR)
26152 return HOLLOW_BOX_CURSOR;
26153
26154 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
26155 {
26156 *width = 1;
26157 return cursor_type;
26158 }
26159 #endif
26160
26161 return NO_CURSOR;
26162 }
26163
26164
26165 /* Notice when the text cursor of window W has been completely
26166 overwritten by a drawing operation that outputs glyphs in AREA
26167 starting at X0 and ending at X1 in the line starting at Y0 and
26168 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26169 the rest of the line after X0 has been written. Y coordinates
26170 are window-relative. */
26171
26172 static void
26173 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
26174 int x0, int x1, int y0, int y1)
26175 {
26176 int cx0, cx1, cy0, cy1;
26177 struct glyph_row *row;
26178
26179 if (!w->phys_cursor_on_p)
26180 return;
26181 if (area != TEXT_AREA)
26182 return;
26183
26184 if (w->phys_cursor.vpos < 0
26185 || w->phys_cursor.vpos >= w->current_matrix->nrows
26186 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
26187 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
26188 return;
26189
26190 if (row->cursor_in_fringe_p)
26191 {
26192 row->cursor_in_fringe_p = 0;
26193 draw_fringe_bitmap (w, row, row->reversed_p);
26194 w->phys_cursor_on_p = 0;
26195 return;
26196 }
26197
26198 cx0 = w->phys_cursor.x;
26199 cx1 = cx0 + w->phys_cursor_width;
26200 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26201 return;
26202
26203 /* The cursor image will be completely removed from the
26204 screen if the output area intersects the cursor area in
26205 y-direction. When we draw in [y0 y1[, and some part of
26206 the cursor is at y < y0, that part must have been drawn
26207 before. When scrolling, the cursor is erased before
26208 actually scrolling, so we don't come here. When not
26209 scrolling, the rows above the old cursor row must have
26210 changed, and in this case these rows must have written
26211 over the cursor image.
26212
26213 Likewise if part of the cursor is below y1, with the
26214 exception of the cursor being in the first blank row at
26215 the buffer and window end because update_text_area
26216 doesn't draw that row. (Except when it does, but
26217 that's handled in update_text_area.) */
26218
26219 cy0 = w->phys_cursor.y;
26220 cy1 = cy0 + w->phys_cursor_height;
26221 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26222 return;
26223
26224 w->phys_cursor_on_p = 0;
26225 }
26226
26227 #endif /* HAVE_WINDOW_SYSTEM */
26228
26229 \f
26230 /************************************************************************
26231 Mouse Face
26232 ************************************************************************/
26233
26234 #ifdef HAVE_WINDOW_SYSTEM
26235
26236 /* EXPORT for RIF:
26237 Fix the display of area AREA of overlapping row ROW in window W
26238 with respect to the overlapping part OVERLAPS. */
26239
26240 void
26241 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26242 enum glyph_row_area area, int overlaps)
26243 {
26244 int i, x;
26245
26246 block_input ();
26247
26248 x = 0;
26249 for (i = 0; i < row->used[area];)
26250 {
26251 if (row->glyphs[area][i].overlaps_vertically_p)
26252 {
26253 int start = i, start_x = x;
26254
26255 do
26256 {
26257 x += row->glyphs[area][i].pixel_width;
26258 ++i;
26259 }
26260 while (i < row->used[area]
26261 && row->glyphs[area][i].overlaps_vertically_p);
26262
26263 draw_glyphs (w, start_x, row, area,
26264 start, i,
26265 DRAW_NORMAL_TEXT, overlaps);
26266 }
26267 else
26268 {
26269 x += row->glyphs[area][i].pixel_width;
26270 ++i;
26271 }
26272 }
26273
26274 unblock_input ();
26275 }
26276
26277
26278 /* EXPORT:
26279 Draw the cursor glyph of window W in glyph row ROW. See the
26280 comment of draw_glyphs for the meaning of HL. */
26281
26282 void
26283 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26284 enum draw_glyphs_face hl)
26285 {
26286 /* If cursor hpos is out of bounds, don't draw garbage. This can
26287 happen in mini-buffer windows when switching between echo area
26288 glyphs and mini-buffer. */
26289 if ((row->reversed_p
26290 ? (w->phys_cursor.hpos >= 0)
26291 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26292 {
26293 int on_p = w->phys_cursor_on_p;
26294 int x1;
26295 int hpos = w->phys_cursor.hpos;
26296
26297 /* When the window is hscrolled, cursor hpos can legitimately be
26298 out of bounds, but we draw the cursor at the corresponding
26299 window margin in that case. */
26300 if (!row->reversed_p && hpos < 0)
26301 hpos = 0;
26302 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26303 hpos = row->used[TEXT_AREA] - 1;
26304
26305 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26306 hl, 0);
26307 w->phys_cursor_on_p = on_p;
26308
26309 if (hl == DRAW_CURSOR)
26310 w->phys_cursor_width = x1 - w->phys_cursor.x;
26311 /* When we erase the cursor, and ROW is overlapped by other
26312 rows, make sure that these overlapping parts of other rows
26313 are redrawn. */
26314 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26315 {
26316 w->phys_cursor_width = x1 - w->phys_cursor.x;
26317
26318 if (row > w->current_matrix->rows
26319 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26320 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26321 OVERLAPS_ERASED_CURSOR);
26322
26323 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26324 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26325 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26326 OVERLAPS_ERASED_CURSOR);
26327 }
26328 }
26329 }
26330
26331
26332 /* EXPORT:
26333 Erase the image of a cursor of window W from the screen. */
26334
26335 void
26336 erase_phys_cursor (struct window *w)
26337 {
26338 struct frame *f = XFRAME (w->frame);
26339 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26340 int hpos = w->phys_cursor.hpos;
26341 int vpos = w->phys_cursor.vpos;
26342 int mouse_face_here_p = 0;
26343 struct glyph_matrix *active_glyphs = w->current_matrix;
26344 struct glyph_row *cursor_row;
26345 struct glyph *cursor_glyph;
26346 enum draw_glyphs_face hl;
26347
26348 /* No cursor displayed or row invalidated => nothing to do on the
26349 screen. */
26350 if (w->phys_cursor_type == NO_CURSOR)
26351 goto mark_cursor_off;
26352
26353 /* VPOS >= active_glyphs->nrows means that window has been resized.
26354 Don't bother to erase the cursor. */
26355 if (vpos >= active_glyphs->nrows)
26356 goto mark_cursor_off;
26357
26358 /* If row containing cursor is marked invalid, there is nothing we
26359 can do. */
26360 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26361 if (!cursor_row->enabled_p)
26362 goto mark_cursor_off;
26363
26364 /* If line spacing is > 0, old cursor may only be partially visible in
26365 window after split-window. So adjust visible height. */
26366 cursor_row->visible_height = min (cursor_row->visible_height,
26367 window_text_bottom_y (w) - cursor_row->y);
26368
26369 /* If row is completely invisible, don't attempt to delete a cursor which
26370 isn't there. This can happen if cursor is at top of a window, and
26371 we switch to a buffer with a header line in that window. */
26372 if (cursor_row->visible_height <= 0)
26373 goto mark_cursor_off;
26374
26375 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26376 if (cursor_row->cursor_in_fringe_p)
26377 {
26378 cursor_row->cursor_in_fringe_p = 0;
26379 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26380 goto mark_cursor_off;
26381 }
26382
26383 /* This can happen when the new row is shorter than the old one.
26384 In this case, either draw_glyphs or clear_end_of_line
26385 should have cleared the cursor. Note that we wouldn't be
26386 able to erase the cursor in this case because we don't have a
26387 cursor glyph at hand. */
26388 if ((cursor_row->reversed_p
26389 ? (w->phys_cursor.hpos < 0)
26390 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26391 goto mark_cursor_off;
26392
26393 /* When the window is hscrolled, cursor hpos can legitimately be out
26394 of bounds, but we draw the cursor at the corresponding window
26395 margin in that case. */
26396 if (!cursor_row->reversed_p && hpos < 0)
26397 hpos = 0;
26398 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26399 hpos = cursor_row->used[TEXT_AREA] - 1;
26400
26401 /* If the cursor is in the mouse face area, redisplay that when
26402 we clear the cursor. */
26403 if (! NILP (hlinfo->mouse_face_window)
26404 && coords_in_mouse_face_p (w, hpos, vpos)
26405 /* Don't redraw the cursor's spot in mouse face if it is at the
26406 end of a line (on a newline). The cursor appears there, but
26407 mouse highlighting does not. */
26408 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26409 mouse_face_here_p = 1;
26410
26411 /* Maybe clear the display under the cursor. */
26412 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26413 {
26414 int x, y, left_x;
26415 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26416 int width;
26417
26418 cursor_glyph = get_phys_cursor_glyph (w);
26419 if (cursor_glyph == NULL)
26420 goto mark_cursor_off;
26421
26422 width = cursor_glyph->pixel_width;
26423 left_x = window_box_left_offset (w, TEXT_AREA);
26424 x = w->phys_cursor.x;
26425 if (x < left_x)
26426 width -= left_x - x;
26427 width = min (width, window_box_width (w, TEXT_AREA) - x);
26428 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26429 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26430
26431 if (width > 0)
26432 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26433 }
26434
26435 /* Erase the cursor by redrawing the character underneath it. */
26436 if (mouse_face_here_p)
26437 hl = DRAW_MOUSE_FACE;
26438 else
26439 hl = DRAW_NORMAL_TEXT;
26440 draw_phys_cursor_glyph (w, cursor_row, hl);
26441
26442 mark_cursor_off:
26443 w->phys_cursor_on_p = 0;
26444 w->phys_cursor_type = NO_CURSOR;
26445 }
26446
26447
26448 /* EXPORT:
26449 Display or clear cursor of window W. If ON is zero, clear the
26450 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26451 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26452
26453 void
26454 display_and_set_cursor (struct window *w, int on,
26455 int hpos, int vpos, int x, int y)
26456 {
26457 struct frame *f = XFRAME (w->frame);
26458 int new_cursor_type;
26459 int new_cursor_width;
26460 int active_cursor;
26461 struct glyph_row *glyph_row;
26462 struct glyph *glyph;
26463
26464 /* This is pointless on invisible frames, and dangerous on garbaged
26465 windows and frames; in the latter case, the frame or window may
26466 be in the midst of changing its size, and x and y may be off the
26467 window. */
26468 if (! FRAME_VISIBLE_P (f)
26469 || FRAME_GARBAGED_P (f)
26470 || vpos >= w->current_matrix->nrows
26471 || hpos >= w->current_matrix->matrix_w)
26472 return;
26473
26474 /* If cursor is off and we want it off, return quickly. */
26475 if (!on && !w->phys_cursor_on_p)
26476 return;
26477
26478 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26479 /* If cursor row is not enabled, we don't really know where to
26480 display the cursor. */
26481 if (!glyph_row->enabled_p)
26482 {
26483 w->phys_cursor_on_p = 0;
26484 return;
26485 }
26486
26487 glyph = NULL;
26488 if (!glyph_row->exact_window_width_line_p
26489 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26490 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26491
26492 eassert (input_blocked_p ());
26493
26494 /* Set new_cursor_type to the cursor we want to be displayed. */
26495 new_cursor_type = get_window_cursor_type (w, glyph,
26496 &new_cursor_width, &active_cursor);
26497
26498 /* If cursor is currently being shown and we don't want it to be or
26499 it is in the wrong place, or the cursor type is not what we want,
26500 erase it. */
26501 if (w->phys_cursor_on_p
26502 && (!on
26503 || w->phys_cursor.x != x
26504 || w->phys_cursor.y != y
26505 || new_cursor_type != w->phys_cursor_type
26506 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26507 && new_cursor_width != w->phys_cursor_width)))
26508 erase_phys_cursor (w);
26509
26510 /* Don't check phys_cursor_on_p here because that flag is only set
26511 to zero in some cases where we know that the cursor has been
26512 completely erased, to avoid the extra work of erasing the cursor
26513 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26514 still not be visible, or it has only been partly erased. */
26515 if (on)
26516 {
26517 w->phys_cursor_ascent = glyph_row->ascent;
26518 w->phys_cursor_height = glyph_row->height;
26519
26520 /* Set phys_cursor_.* before x_draw_.* is called because some
26521 of them may need the information. */
26522 w->phys_cursor.x = x;
26523 w->phys_cursor.y = glyph_row->y;
26524 w->phys_cursor.hpos = hpos;
26525 w->phys_cursor.vpos = vpos;
26526 }
26527
26528 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26529 new_cursor_type, new_cursor_width,
26530 on, active_cursor);
26531 }
26532
26533
26534 /* Switch the display of W's cursor on or off, according to the value
26535 of ON. */
26536
26537 static void
26538 update_window_cursor (struct window *w, int on)
26539 {
26540 /* Don't update cursor in windows whose frame is in the process
26541 of being deleted. */
26542 if (w->current_matrix)
26543 {
26544 int hpos = w->phys_cursor.hpos;
26545 int vpos = w->phys_cursor.vpos;
26546 struct glyph_row *row;
26547
26548 if (vpos >= w->current_matrix->nrows
26549 || hpos >= w->current_matrix->matrix_w)
26550 return;
26551
26552 row = MATRIX_ROW (w->current_matrix, vpos);
26553
26554 /* When the window is hscrolled, cursor hpos can legitimately be
26555 out of bounds, but we draw the cursor at the corresponding
26556 window margin in that case. */
26557 if (!row->reversed_p && hpos < 0)
26558 hpos = 0;
26559 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26560 hpos = row->used[TEXT_AREA] - 1;
26561
26562 block_input ();
26563 display_and_set_cursor (w, on, hpos, vpos,
26564 w->phys_cursor.x, w->phys_cursor.y);
26565 unblock_input ();
26566 }
26567 }
26568
26569
26570 /* Call update_window_cursor with parameter ON_P on all leaf windows
26571 in the window tree rooted at W. */
26572
26573 static void
26574 update_cursor_in_window_tree (struct window *w, int on_p)
26575 {
26576 while (w)
26577 {
26578 if (WINDOWP (w->contents))
26579 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26580 else
26581 update_window_cursor (w, on_p);
26582
26583 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26584 }
26585 }
26586
26587
26588 /* EXPORT:
26589 Display the cursor on window W, or clear it, according to ON_P.
26590 Don't change the cursor's position. */
26591
26592 void
26593 x_update_cursor (struct frame *f, int on_p)
26594 {
26595 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26596 }
26597
26598
26599 /* EXPORT:
26600 Clear the cursor of window W to background color, and mark the
26601 cursor as not shown. This is used when the text where the cursor
26602 is about to be rewritten. */
26603
26604 void
26605 x_clear_cursor (struct window *w)
26606 {
26607 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26608 update_window_cursor (w, 0);
26609 }
26610
26611 #endif /* HAVE_WINDOW_SYSTEM */
26612
26613 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26614 and MSDOS. */
26615 static void
26616 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26617 int start_hpos, int end_hpos,
26618 enum draw_glyphs_face draw)
26619 {
26620 #ifdef HAVE_WINDOW_SYSTEM
26621 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26622 {
26623 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26624 return;
26625 }
26626 #endif
26627 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26628 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26629 #endif
26630 }
26631
26632 /* Display the active region described by mouse_face_* according to DRAW. */
26633
26634 static void
26635 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26636 {
26637 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26638 struct frame *f = XFRAME (WINDOW_FRAME (w));
26639
26640 if (/* If window is in the process of being destroyed, don't bother
26641 to do anything. */
26642 w->current_matrix != NULL
26643 /* Don't update mouse highlight if hidden */
26644 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26645 /* Recognize when we are called to operate on rows that don't exist
26646 anymore. This can happen when a window is split. */
26647 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26648 {
26649 int phys_cursor_on_p = w->phys_cursor_on_p;
26650 struct glyph_row *row, *first, *last;
26651
26652 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26653 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26654
26655 for (row = first; row <= last && row->enabled_p; ++row)
26656 {
26657 int start_hpos, end_hpos, start_x;
26658
26659 /* For all but the first row, the highlight starts at column 0. */
26660 if (row == first)
26661 {
26662 /* R2L rows have BEG and END in reversed order, but the
26663 screen drawing geometry is always left to right. So
26664 we need to mirror the beginning and end of the
26665 highlighted area in R2L rows. */
26666 if (!row->reversed_p)
26667 {
26668 start_hpos = hlinfo->mouse_face_beg_col;
26669 start_x = hlinfo->mouse_face_beg_x;
26670 }
26671 else if (row == last)
26672 {
26673 start_hpos = hlinfo->mouse_face_end_col;
26674 start_x = hlinfo->mouse_face_end_x;
26675 }
26676 else
26677 {
26678 start_hpos = 0;
26679 start_x = 0;
26680 }
26681 }
26682 else if (row->reversed_p && row == last)
26683 {
26684 start_hpos = hlinfo->mouse_face_end_col;
26685 start_x = hlinfo->mouse_face_end_x;
26686 }
26687 else
26688 {
26689 start_hpos = 0;
26690 start_x = 0;
26691 }
26692
26693 if (row == last)
26694 {
26695 if (!row->reversed_p)
26696 end_hpos = hlinfo->mouse_face_end_col;
26697 else if (row == first)
26698 end_hpos = hlinfo->mouse_face_beg_col;
26699 else
26700 {
26701 end_hpos = row->used[TEXT_AREA];
26702 if (draw == DRAW_NORMAL_TEXT)
26703 row->fill_line_p = 1; /* Clear to end of line */
26704 }
26705 }
26706 else if (row->reversed_p && row == first)
26707 end_hpos = hlinfo->mouse_face_beg_col;
26708 else
26709 {
26710 end_hpos = row->used[TEXT_AREA];
26711 if (draw == DRAW_NORMAL_TEXT)
26712 row->fill_line_p = 1; /* Clear to end of line */
26713 }
26714
26715 if (end_hpos > start_hpos)
26716 {
26717 draw_row_with_mouse_face (w, start_x, row,
26718 start_hpos, end_hpos, draw);
26719
26720 row->mouse_face_p
26721 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26722 }
26723 }
26724
26725 #ifdef HAVE_WINDOW_SYSTEM
26726 /* When we've written over the cursor, arrange for it to
26727 be displayed again. */
26728 if (FRAME_WINDOW_P (f)
26729 && phys_cursor_on_p && !w->phys_cursor_on_p)
26730 {
26731 int hpos = w->phys_cursor.hpos;
26732
26733 /* When the window is hscrolled, cursor hpos can legitimately be
26734 out of bounds, but we draw the cursor at the corresponding
26735 window margin in that case. */
26736 if (!row->reversed_p && hpos < 0)
26737 hpos = 0;
26738 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26739 hpos = row->used[TEXT_AREA] - 1;
26740
26741 block_input ();
26742 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26743 w->phys_cursor.x, w->phys_cursor.y);
26744 unblock_input ();
26745 }
26746 #endif /* HAVE_WINDOW_SYSTEM */
26747 }
26748
26749 #ifdef HAVE_WINDOW_SYSTEM
26750 /* Change the mouse cursor. */
26751 if (FRAME_WINDOW_P (f))
26752 {
26753 if (draw == DRAW_NORMAL_TEXT
26754 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26755 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26756 else if (draw == DRAW_MOUSE_FACE)
26757 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26758 else
26759 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26760 }
26761 #endif /* HAVE_WINDOW_SYSTEM */
26762 }
26763
26764 /* EXPORT:
26765 Clear out the mouse-highlighted active region.
26766 Redraw it un-highlighted first. Value is non-zero if mouse
26767 face was actually drawn unhighlighted. */
26768
26769 int
26770 clear_mouse_face (Mouse_HLInfo *hlinfo)
26771 {
26772 int cleared = 0;
26773
26774 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26775 {
26776 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26777 cleared = 1;
26778 }
26779
26780 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26781 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26782 hlinfo->mouse_face_window = Qnil;
26783 hlinfo->mouse_face_overlay = Qnil;
26784 return cleared;
26785 }
26786
26787 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26788 within the mouse face on that window. */
26789 static int
26790 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26791 {
26792 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26793
26794 /* Quickly resolve the easy cases. */
26795 if (!(WINDOWP (hlinfo->mouse_face_window)
26796 && XWINDOW (hlinfo->mouse_face_window) == w))
26797 return 0;
26798 if (vpos < hlinfo->mouse_face_beg_row
26799 || vpos > hlinfo->mouse_face_end_row)
26800 return 0;
26801 if (vpos > hlinfo->mouse_face_beg_row
26802 && vpos < hlinfo->mouse_face_end_row)
26803 return 1;
26804
26805 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26806 {
26807 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26808 {
26809 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26810 return 1;
26811 }
26812 else if ((vpos == hlinfo->mouse_face_beg_row
26813 && hpos >= hlinfo->mouse_face_beg_col)
26814 || (vpos == hlinfo->mouse_face_end_row
26815 && hpos < hlinfo->mouse_face_end_col))
26816 return 1;
26817 }
26818 else
26819 {
26820 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26821 {
26822 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26823 return 1;
26824 }
26825 else if ((vpos == hlinfo->mouse_face_beg_row
26826 && hpos <= hlinfo->mouse_face_beg_col)
26827 || (vpos == hlinfo->mouse_face_end_row
26828 && hpos > hlinfo->mouse_face_end_col))
26829 return 1;
26830 }
26831 return 0;
26832 }
26833
26834
26835 /* EXPORT:
26836 Non-zero if physical cursor of window W is within mouse face. */
26837
26838 int
26839 cursor_in_mouse_face_p (struct window *w)
26840 {
26841 int hpos = w->phys_cursor.hpos;
26842 int vpos = w->phys_cursor.vpos;
26843 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26844
26845 /* When the window is hscrolled, cursor hpos can legitimately be out
26846 of bounds, but we draw the cursor at the corresponding window
26847 margin in that case. */
26848 if (!row->reversed_p && hpos < 0)
26849 hpos = 0;
26850 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26851 hpos = row->used[TEXT_AREA] - 1;
26852
26853 return coords_in_mouse_face_p (w, hpos, vpos);
26854 }
26855
26856
26857 \f
26858 /* Find the glyph rows START_ROW and END_ROW of window W that display
26859 characters between buffer positions START_CHARPOS and END_CHARPOS
26860 (excluding END_CHARPOS). DISP_STRING is a display string that
26861 covers these buffer positions. This is similar to
26862 row_containing_pos, but is more accurate when bidi reordering makes
26863 buffer positions change non-linearly with glyph rows. */
26864 static void
26865 rows_from_pos_range (struct window *w,
26866 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26867 Lisp_Object disp_string,
26868 struct glyph_row **start, struct glyph_row **end)
26869 {
26870 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26871 int last_y = window_text_bottom_y (w);
26872 struct glyph_row *row;
26873
26874 *start = NULL;
26875 *end = NULL;
26876
26877 while (!first->enabled_p
26878 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26879 first++;
26880
26881 /* Find the START row. */
26882 for (row = first;
26883 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26884 row++)
26885 {
26886 /* A row can potentially be the START row if the range of the
26887 characters it displays intersects the range
26888 [START_CHARPOS..END_CHARPOS). */
26889 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26890 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26891 /* See the commentary in row_containing_pos, for the
26892 explanation of the complicated way to check whether
26893 some position is beyond the end of the characters
26894 displayed by a row. */
26895 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26896 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26897 && !row->ends_at_zv_p
26898 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26899 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26900 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26901 && !row->ends_at_zv_p
26902 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26903 {
26904 /* Found a candidate row. Now make sure at least one of the
26905 glyphs it displays has a charpos from the range
26906 [START_CHARPOS..END_CHARPOS).
26907
26908 This is not obvious because bidi reordering could make
26909 buffer positions of a row be 1,2,3,102,101,100, and if we
26910 want to highlight characters in [50..60), we don't want
26911 this row, even though [50..60) does intersect [1..103),
26912 the range of character positions given by the row's start
26913 and end positions. */
26914 struct glyph *g = row->glyphs[TEXT_AREA];
26915 struct glyph *e = g + row->used[TEXT_AREA];
26916
26917 while (g < e)
26918 {
26919 if (((BUFFERP (g->object) || INTEGERP (g->object))
26920 && start_charpos <= g->charpos && g->charpos < end_charpos)
26921 /* A glyph that comes from DISP_STRING is by
26922 definition to be highlighted. */
26923 || EQ (g->object, disp_string))
26924 *start = row;
26925 g++;
26926 }
26927 if (*start)
26928 break;
26929 }
26930 }
26931
26932 /* Find the END row. */
26933 if (!*start
26934 /* If the last row is partially visible, start looking for END
26935 from that row, instead of starting from FIRST. */
26936 && !(row->enabled_p
26937 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26938 row = first;
26939 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26940 {
26941 struct glyph_row *next = row + 1;
26942 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26943
26944 if (!next->enabled_p
26945 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26946 /* The first row >= START whose range of displayed characters
26947 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26948 is the row END + 1. */
26949 || (start_charpos < next_start
26950 && end_charpos < next_start)
26951 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26952 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26953 && !next->ends_at_zv_p
26954 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26955 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26956 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26957 && !next->ends_at_zv_p
26958 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26959 {
26960 *end = row;
26961 break;
26962 }
26963 else
26964 {
26965 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26966 but none of the characters it displays are in the range, it is
26967 also END + 1. */
26968 struct glyph *g = next->glyphs[TEXT_AREA];
26969 struct glyph *s = g;
26970 struct glyph *e = g + next->used[TEXT_AREA];
26971
26972 while (g < e)
26973 {
26974 if (((BUFFERP (g->object) || INTEGERP (g->object))
26975 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26976 /* If the buffer position of the first glyph in
26977 the row is equal to END_CHARPOS, it means
26978 the last character to be highlighted is the
26979 newline of ROW, and we must consider NEXT as
26980 END, not END+1. */
26981 || (((!next->reversed_p && g == s)
26982 || (next->reversed_p && g == e - 1))
26983 && (g->charpos == end_charpos
26984 /* Special case for when NEXT is an
26985 empty line at ZV. */
26986 || (g->charpos == -1
26987 && !row->ends_at_zv_p
26988 && next_start == end_charpos)))))
26989 /* A glyph that comes from DISP_STRING is by
26990 definition to be highlighted. */
26991 || EQ (g->object, disp_string))
26992 break;
26993 g++;
26994 }
26995 if (g == e)
26996 {
26997 *end = row;
26998 break;
26999 }
27000 /* The first row that ends at ZV must be the last to be
27001 highlighted. */
27002 else if (next->ends_at_zv_p)
27003 {
27004 *end = next;
27005 break;
27006 }
27007 }
27008 }
27009 }
27010
27011 /* This function sets the mouse_face_* elements of HLINFO, assuming
27012 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
27013 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
27014 for the overlay or run of text properties specifying the mouse
27015 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
27016 before-string and after-string that must also be highlighted.
27017 DISP_STRING, if non-nil, is a display string that may cover some
27018 or all of the highlighted text. */
27019
27020 static void
27021 mouse_face_from_buffer_pos (Lisp_Object window,
27022 Mouse_HLInfo *hlinfo,
27023 ptrdiff_t mouse_charpos,
27024 ptrdiff_t start_charpos,
27025 ptrdiff_t end_charpos,
27026 Lisp_Object before_string,
27027 Lisp_Object after_string,
27028 Lisp_Object disp_string)
27029 {
27030 struct window *w = XWINDOW (window);
27031 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27032 struct glyph_row *r1, *r2;
27033 struct glyph *glyph, *end;
27034 ptrdiff_t ignore, pos;
27035 int x;
27036
27037 eassert (NILP (disp_string) || STRINGP (disp_string));
27038 eassert (NILP (before_string) || STRINGP (before_string));
27039 eassert (NILP (after_string) || STRINGP (after_string));
27040
27041 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
27042 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
27043 if (r1 == NULL)
27044 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27045 /* If the before-string or display-string contains newlines,
27046 rows_from_pos_range skips to its last row. Move back. */
27047 if (!NILP (before_string) || !NILP (disp_string))
27048 {
27049 struct glyph_row *prev;
27050 while ((prev = r1 - 1, prev >= first)
27051 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
27052 && prev->used[TEXT_AREA] > 0)
27053 {
27054 struct glyph *beg = prev->glyphs[TEXT_AREA];
27055 glyph = beg + prev->used[TEXT_AREA];
27056 while (--glyph >= beg && INTEGERP (glyph->object));
27057 if (glyph < beg
27058 || !(EQ (glyph->object, before_string)
27059 || EQ (glyph->object, disp_string)))
27060 break;
27061 r1 = prev;
27062 }
27063 }
27064 if (r2 == NULL)
27065 {
27066 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27067 hlinfo->mouse_face_past_end = 1;
27068 }
27069 else if (!NILP (after_string))
27070 {
27071 /* If the after-string has newlines, advance to its last row. */
27072 struct glyph_row *next;
27073 struct glyph_row *last
27074 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
27075
27076 for (next = r2 + 1;
27077 next <= last
27078 && next->used[TEXT_AREA] > 0
27079 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
27080 ++next)
27081 r2 = next;
27082 }
27083 /* The rest of the display engine assumes that mouse_face_beg_row is
27084 either above mouse_face_end_row or identical to it. But with
27085 bidi-reordered continued lines, the row for START_CHARPOS could
27086 be below the row for END_CHARPOS. If so, swap the rows and store
27087 them in correct order. */
27088 if (r1->y > r2->y)
27089 {
27090 struct glyph_row *tem = r2;
27091
27092 r2 = r1;
27093 r1 = tem;
27094 }
27095
27096 hlinfo->mouse_face_beg_y = r1->y;
27097 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27098 hlinfo->mouse_face_end_y = r2->y;
27099 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27100
27101 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27102 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27103 could be anywhere in the row and in any order. The strategy
27104 below is to find the leftmost and the rightmost glyph that
27105 belongs to either of these 3 strings, or whose position is
27106 between START_CHARPOS and END_CHARPOS, and highlight all the
27107 glyphs between those two. This may cover more than just the text
27108 between START_CHARPOS and END_CHARPOS if the range of characters
27109 strides the bidi level boundary, e.g. if the beginning is in R2L
27110 text while the end is in L2R text or vice versa. */
27111 if (!r1->reversed_p)
27112 {
27113 /* This row is in a left to right paragraph. Scan it left to
27114 right. */
27115 glyph = r1->glyphs[TEXT_AREA];
27116 end = glyph + r1->used[TEXT_AREA];
27117 x = r1->x;
27118
27119 /* Skip truncation glyphs at the start of the glyph row. */
27120 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27121 for (; glyph < end
27122 && INTEGERP (glyph->object)
27123 && glyph->charpos < 0;
27124 ++glyph)
27125 x += glyph->pixel_width;
27126
27127 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27128 or DISP_STRING, and the first glyph from buffer whose
27129 position is between START_CHARPOS and END_CHARPOS. */
27130 for (; glyph < end
27131 && !INTEGERP (glyph->object)
27132 && !EQ (glyph->object, disp_string)
27133 && !(BUFFERP (glyph->object)
27134 && (glyph->charpos >= start_charpos
27135 && glyph->charpos < end_charpos));
27136 ++glyph)
27137 {
27138 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27139 are present at buffer positions between START_CHARPOS and
27140 END_CHARPOS, or if they come from an overlay. */
27141 if (EQ (glyph->object, before_string))
27142 {
27143 pos = string_buffer_position (before_string,
27144 start_charpos);
27145 /* If pos == 0, it means before_string came from an
27146 overlay, not from a buffer position. */
27147 if (!pos || (pos >= start_charpos && pos < end_charpos))
27148 break;
27149 }
27150 else if (EQ (glyph->object, after_string))
27151 {
27152 pos = string_buffer_position (after_string, end_charpos);
27153 if (!pos || (pos >= start_charpos && pos < end_charpos))
27154 break;
27155 }
27156 x += glyph->pixel_width;
27157 }
27158 hlinfo->mouse_face_beg_x = x;
27159 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27160 }
27161 else
27162 {
27163 /* This row is in a right to left paragraph. Scan it right to
27164 left. */
27165 struct glyph *g;
27166
27167 end = r1->glyphs[TEXT_AREA] - 1;
27168 glyph = end + r1->used[TEXT_AREA];
27169
27170 /* Skip truncation glyphs at the start of the glyph row. */
27171 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
27172 for (; glyph > end
27173 && INTEGERP (glyph->object)
27174 && glyph->charpos < 0;
27175 --glyph)
27176 ;
27177
27178 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27179 or DISP_STRING, and the first glyph from buffer whose
27180 position is between START_CHARPOS and END_CHARPOS. */
27181 for (; glyph > end
27182 && !INTEGERP (glyph->object)
27183 && !EQ (glyph->object, disp_string)
27184 && !(BUFFERP (glyph->object)
27185 && (glyph->charpos >= start_charpos
27186 && glyph->charpos < end_charpos));
27187 --glyph)
27188 {
27189 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27190 are present at buffer positions between START_CHARPOS and
27191 END_CHARPOS, or if they come from an overlay. */
27192 if (EQ (glyph->object, before_string))
27193 {
27194 pos = string_buffer_position (before_string, start_charpos);
27195 /* If pos == 0, it means before_string came from an
27196 overlay, not from a buffer position. */
27197 if (!pos || (pos >= start_charpos && pos < end_charpos))
27198 break;
27199 }
27200 else if (EQ (glyph->object, after_string))
27201 {
27202 pos = string_buffer_position (after_string, end_charpos);
27203 if (!pos || (pos >= start_charpos && pos < end_charpos))
27204 break;
27205 }
27206 }
27207
27208 glyph++; /* first glyph to the right of the highlighted area */
27209 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27210 x += g->pixel_width;
27211 hlinfo->mouse_face_beg_x = x;
27212 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27213 }
27214
27215 /* If the highlight ends in a different row, compute GLYPH and END
27216 for the end row. Otherwise, reuse the values computed above for
27217 the row where the highlight begins. */
27218 if (r2 != r1)
27219 {
27220 if (!r2->reversed_p)
27221 {
27222 glyph = r2->glyphs[TEXT_AREA];
27223 end = glyph + r2->used[TEXT_AREA];
27224 x = r2->x;
27225 }
27226 else
27227 {
27228 end = r2->glyphs[TEXT_AREA] - 1;
27229 glyph = end + r2->used[TEXT_AREA];
27230 }
27231 }
27232
27233 if (!r2->reversed_p)
27234 {
27235 /* Skip truncation and continuation glyphs near the end of the
27236 row, and also blanks and stretch glyphs inserted by
27237 extend_face_to_end_of_line. */
27238 while (end > glyph
27239 && INTEGERP ((end - 1)->object))
27240 --end;
27241 /* Scan the rest of the glyph row from the end, looking for the
27242 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27243 DISP_STRING, or whose position is between START_CHARPOS
27244 and END_CHARPOS */
27245 for (--end;
27246 end > glyph
27247 && !INTEGERP (end->object)
27248 && !EQ (end->object, disp_string)
27249 && !(BUFFERP (end->object)
27250 && (end->charpos >= start_charpos
27251 && end->charpos < end_charpos));
27252 --end)
27253 {
27254 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27255 are present at buffer positions between START_CHARPOS and
27256 END_CHARPOS, or if they come from an overlay. */
27257 if (EQ (end->object, before_string))
27258 {
27259 pos = string_buffer_position (before_string, start_charpos);
27260 if (!pos || (pos >= start_charpos && pos < end_charpos))
27261 break;
27262 }
27263 else if (EQ (end->object, after_string))
27264 {
27265 pos = string_buffer_position (after_string, end_charpos);
27266 if (!pos || (pos >= start_charpos && pos < end_charpos))
27267 break;
27268 }
27269 }
27270 /* Find the X coordinate of the last glyph to be highlighted. */
27271 for (; glyph <= end; ++glyph)
27272 x += glyph->pixel_width;
27273
27274 hlinfo->mouse_face_end_x = x;
27275 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27276 }
27277 else
27278 {
27279 /* Skip truncation and continuation glyphs near the end of the
27280 row, and also blanks and stretch glyphs inserted by
27281 extend_face_to_end_of_line. */
27282 x = r2->x;
27283 end++;
27284 while (end < glyph
27285 && INTEGERP (end->object))
27286 {
27287 x += end->pixel_width;
27288 ++end;
27289 }
27290 /* Scan the rest of the glyph row from the end, looking for the
27291 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27292 DISP_STRING, or whose position is between START_CHARPOS
27293 and END_CHARPOS */
27294 for ( ;
27295 end < glyph
27296 && !INTEGERP (end->object)
27297 && !EQ (end->object, disp_string)
27298 && !(BUFFERP (end->object)
27299 && (end->charpos >= start_charpos
27300 && end->charpos < end_charpos));
27301 ++end)
27302 {
27303 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27304 are present at buffer positions between START_CHARPOS and
27305 END_CHARPOS, or if they come from an overlay. */
27306 if (EQ (end->object, before_string))
27307 {
27308 pos = string_buffer_position (before_string, start_charpos);
27309 if (!pos || (pos >= start_charpos && pos < end_charpos))
27310 break;
27311 }
27312 else if (EQ (end->object, after_string))
27313 {
27314 pos = string_buffer_position (after_string, end_charpos);
27315 if (!pos || (pos >= start_charpos && pos < end_charpos))
27316 break;
27317 }
27318 x += end->pixel_width;
27319 }
27320 /* If we exited the above loop because we arrived at the last
27321 glyph of the row, and its buffer position is still not in
27322 range, it means the last character in range is the preceding
27323 newline. Bump the end column and x values to get past the
27324 last glyph. */
27325 if (end == glyph
27326 && BUFFERP (end->object)
27327 && (end->charpos < start_charpos
27328 || end->charpos >= end_charpos))
27329 {
27330 x += end->pixel_width;
27331 ++end;
27332 }
27333 hlinfo->mouse_face_end_x = x;
27334 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27335 }
27336
27337 hlinfo->mouse_face_window = window;
27338 hlinfo->mouse_face_face_id
27339 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
27340 mouse_charpos + 1,
27341 !hlinfo->mouse_face_hidden, -1);
27342 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27343 }
27344
27345 /* The following function is not used anymore (replaced with
27346 mouse_face_from_string_pos), but I leave it here for the time
27347 being, in case someone would. */
27348
27349 #if 0 /* not used */
27350
27351 /* Find the position of the glyph for position POS in OBJECT in
27352 window W's current matrix, and return in *X, *Y the pixel
27353 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27354
27355 RIGHT_P non-zero means return the position of the right edge of the
27356 glyph, RIGHT_P zero means return the left edge position.
27357
27358 If no glyph for POS exists in the matrix, return the position of
27359 the glyph with the next smaller position that is in the matrix, if
27360 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27361 exists in the matrix, return the position of the glyph with the
27362 next larger position in OBJECT.
27363
27364 Value is non-zero if a glyph was found. */
27365
27366 static int
27367 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27368 int *hpos, int *vpos, int *x, int *y, int right_p)
27369 {
27370 int yb = window_text_bottom_y (w);
27371 struct glyph_row *r;
27372 struct glyph *best_glyph = NULL;
27373 struct glyph_row *best_row = NULL;
27374 int best_x = 0;
27375
27376 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27377 r->enabled_p && r->y < yb;
27378 ++r)
27379 {
27380 struct glyph *g = r->glyphs[TEXT_AREA];
27381 struct glyph *e = g + r->used[TEXT_AREA];
27382 int gx;
27383
27384 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27385 if (EQ (g->object, object))
27386 {
27387 if (g->charpos == pos)
27388 {
27389 best_glyph = g;
27390 best_x = gx;
27391 best_row = r;
27392 goto found;
27393 }
27394 else if (best_glyph == NULL
27395 || ((eabs (g->charpos - pos)
27396 < eabs (best_glyph->charpos - pos))
27397 && (right_p
27398 ? g->charpos < pos
27399 : g->charpos > pos)))
27400 {
27401 best_glyph = g;
27402 best_x = gx;
27403 best_row = r;
27404 }
27405 }
27406 }
27407
27408 found:
27409
27410 if (best_glyph)
27411 {
27412 *x = best_x;
27413 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27414
27415 if (right_p)
27416 {
27417 *x += best_glyph->pixel_width;
27418 ++*hpos;
27419 }
27420
27421 *y = best_row->y;
27422 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
27423 }
27424
27425 return best_glyph != NULL;
27426 }
27427 #endif /* not used */
27428
27429 /* Find the positions of the first and the last glyphs in window W's
27430 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27431 (assumed to be a string), and return in HLINFO's mouse_face_*
27432 members the pixel and column/row coordinates of those glyphs. */
27433
27434 static void
27435 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27436 Lisp_Object object,
27437 ptrdiff_t startpos, ptrdiff_t endpos)
27438 {
27439 int yb = window_text_bottom_y (w);
27440 struct glyph_row *r;
27441 struct glyph *g, *e;
27442 int gx;
27443 int found = 0;
27444
27445 /* Find the glyph row with at least one position in the range
27446 [STARTPOS..ENDPOS], and the first glyph in that row whose
27447 position belongs to that range. */
27448 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27449 r->enabled_p && r->y < yb;
27450 ++r)
27451 {
27452 if (!r->reversed_p)
27453 {
27454 g = r->glyphs[TEXT_AREA];
27455 e = g + r->used[TEXT_AREA];
27456 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27457 if (EQ (g->object, object)
27458 && startpos <= g->charpos && g->charpos <= endpos)
27459 {
27460 hlinfo->mouse_face_beg_row
27461 = MATRIX_ROW_VPOS (r, w->current_matrix);
27462 hlinfo->mouse_face_beg_y = r->y;
27463 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27464 hlinfo->mouse_face_beg_x = gx;
27465 found = 1;
27466 break;
27467 }
27468 }
27469 else
27470 {
27471 struct glyph *g1;
27472
27473 e = r->glyphs[TEXT_AREA];
27474 g = e + r->used[TEXT_AREA];
27475 for ( ; g > e; --g)
27476 if (EQ ((g-1)->object, object)
27477 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27478 {
27479 hlinfo->mouse_face_beg_row
27480 = MATRIX_ROW_VPOS (r, w->current_matrix);
27481 hlinfo->mouse_face_beg_y = r->y;
27482 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27483 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27484 gx += g1->pixel_width;
27485 hlinfo->mouse_face_beg_x = gx;
27486 found = 1;
27487 break;
27488 }
27489 }
27490 if (found)
27491 break;
27492 }
27493
27494 if (!found)
27495 return;
27496
27497 /* Starting with the next row, look for the first row which does NOT
27498 include any glyphs whose positions are in the range. */
27499 for (++r; r->enabled_p && r->y < yb; ++r)
27500 {
27501 g = r->glyphs[TEXT_AREA];
27502 e = g + r->used[TEXT_AREA];
27503 found = 0;
27504 for ( ; g < e; ++g)
27505 if (EQ (g->object, object)
27506 && startpos <= g->charpos && g->charpos <= endpos)
27507 {
27508 found = 1;
27509 break;
27510 }
27511 if (!found)
27512 break;
27513 }
27514
27515 /* The highlighted region ends on the previous row. */
27516 r--;
27517
27518 /* Set the end row and its vertical pixel coordinate. */
27519 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27520 hlinfo->mouse_face_end_y = r->y;
27521
27522 /* Compute and set the end column and the end column's horizontal
27523 pixel coordinate. */
27524 if (!r->reversed_p)
27525 {
27526 g = r->glyphs[TEXT_AREA];
27527 e = g + r->used[TEXT_AREA];
27528 for ( ; e > g; --e)
27529 if (EQ ((e-1)->object, object)
27530 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27531 break;
27532 hlinfo->mouse_face_end_col = e - g;
27533
27534 for (gx = r->x; g < e; ++g)
27535 gx += g->pixel_width;
27536 hlinfo->mouse_face_end_x = gx;
27537 }
27538 else
27539 {
27540 e = r->glyphs[TEXT_AREA];
27541 g = e + r->used[TEXT_AREA];
27542 for (gx = r->x ; e < g; ++e)
27543 {
27544 if (EQ (e->object, object)
27545 && startpos <= e->charpos && e->charpos <= endpos)
27546 break;
27547 gx += e->pixel_width;
27548 }
27549 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27550 hlinfo->mouse_face_end_x = gx;
27551 }
27552 }
27553
27554 #ifdef HAVE_WINDOW_SYSTEM
27555
27556 /* See if position X, Y is within a hot-spot of an image. */
27557
27558 static int
27559 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27560 {
27561 if (!CONSP (hot_spot))
27562 return 0;
27563
27564 if (EQ (XCAR (hot_spot), Qrect))
27565 {
27566 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27567 Lisp_Object rect = XCDR (hot_spot);
27568 Lisp_Object tem;
27569 if (!CONSP (rect))
27570 return 0;
27571 if (!CONSP (XCAR (rect)))
27572 return 0;
27573 if (!CONSP (XCDR (rect)))
27574 return 0;
27575 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27576 return 0;
27577 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27578 return 0;
27579 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27580 return 0;
27581 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27582 return 0;
27583 return 1;
27584 }
27585 else if (EQ (XCAR (hot_spot), Qcircle))
27586 {
27587 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27588 Lisp_Object circ = XCDR (hot_spot);
27589 Lisp_Object lr, lx0, ly0;
27590 if (CONSP (circ)
27591 && CONSP (XCAR (circ))
27592 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27593 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27594 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27595 {
27596 double r = XFLOATINT (lr);
27597 double dx = XINT (lx0) - x;
27598 double dy = XINT (ly0) - y;
27599 return (dx * dx + dy * dy <= r * r);
27600 }
27601 }
27602 else if (EQ (XCAR (hot_spot), Qpoly))
27603 {
27604 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27605 if (VECTORP (XCDR (hot_spot)))
27606 {
27607 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27608 Lisp_Object *poly = v->contents;
27609 ptrdiff_t n = v->header.size;
27610 ptrdiff_t i;
27611 int inside = 0;
27612 Lisp_Object lx, ly;
27613 int x0, y0;
27614
27615 /* Need an even number of coordinates, and at least 3 edges. */
27616 if (n < 6 || n & 1)
27617 return 0;
27618
27619 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27620 If count is odd, we are inside polygon. Pixels on edges
27621 may or may not be included depending on actual geometry of the
27622 polygon. */
27623 if ((lx = poly[n-2], !INTEGERP (lx))
27624 || (ly = poly[n-1], !INTEGERP (lx)))
27625 return 0;
27626 x0 = XINT (lx), y0 = XINT (ly);
27627 for (i = 0; i < n; i += 2)
27628 {
27629 int x1 = x0, y1 = y0;
27630 if ((lx = poly[i], !INTEGERP (lx))
27631 || (ly = poly[i+1], !INTEGERP (ly)))
27632 return 0;
27633 x0 = XINT (lx), y0 = XINT (ly);
27634
27635 /* Does this segment cross the X line? */
27636 if (x0 >= x)
27637 {
27638 if (x1 >= x)
27639 continue;
27640 }
27641 else if (x1 < x)
27642 continue;
27643 if (y > y0 && y > y1)
27644 continue;
27645 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27646 inside = !inside;
27647 }
27648 return inside;
27649 }
27650 }
27651 return 0;
27652 }
27653
27654 Lisp_Object
27655 find_hot_spot (Lisp_Object map, int x, int y)
27656 {
27657 while (CONSP (map))
27658 {
27659 if (CONSP (XCAR (map))
27660 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27661 return XCAR (map);
27662 map = XCDR (map);
27663 }
27664
27665 return Qnil;
27666 }
27667
27668 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27669 3, 3, 0,
27670 doc: /* Lookup in image map MAP coordinates X and Y.
27671 An image map is an alist where each element has the format (AREA ID PLIST).
27672 An AREA is specified as either a rectangle, a circle, or a polygon:
27673 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27674 pixel coordinates of the upper left and bottom right corners.
27675 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27676 and the radius of the circle; r may be a float or integer.
27677 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27678 vector describes one corner in the polygon.
27679 Returns the alist element for the first matching AREA in MAP. */)
27680 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27681 {
27682 if (NILP (map))
27683 return Qnil;
27684
27685 CHECK_NUMBER (x);
27686 CHECK_NUMBER (y);
27687
27688 return find_hot_spot (map,
27689 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27690 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27691 }
27692
27693
27694 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27695 static void
27696 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27697 {
27698 /* Do not change cursor shape while dragging mouse. */
27699 if (!NILP (do_mouse_tracking))
27700 return;
27701
27702 if (!NILP (pointer))
27703 {
27704 if (EQ (pointer, Qarrow))
27705 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27706 else if (EQ (pointer, Qhand))
27707 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27708 else if (EQ (pointer, Qtext))
27709 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27710 else if (EQ (pointer, intern ("hdrag")))
27711 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27712 #ifdef HAVE_X_WINDOWS
27713 else if (EQ (pointer, intern ("vdrag")))
27714 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27715 #endif
27716 else if (EQ (pointer, intern ("hourglass")))
27717 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27718 else if (EQ (pointer, Qmodeline))
27719 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27720 else
27721 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27722 }
27723
27724 if (cursor != No_Cursor)
27725 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27726 }
27727
27728 #endif /* HAVE_WINDOW_SYSTEM */
27729
27730 /* Take proper action when mouse has moved to the mode or header line
27731 or marginal area AREA of window W, x-position X and y-position Y.
27732 X is relative to the start of the text display area of W, so the
27733 width of bitmap areas and scroll bars must be subtracted to get a
27734 position relative to the start of the mode line. */
27735
27736 static void
27737 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27738 enum window_part area)
27739 {
27740 struct window *w = XWINDOW (window);
27741 struct frame *f = XFRAME (w->frame);
27742 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27743 #ifdef HAVE_WINDOW_SYSTEM
27744 Display_Info *dpyinfo;
27745 #endif
27746 Cursor cursor = No_Cursor;
27747 Lisp_Object pointer = Qnil;
27748 int dx, dy, width, height;
27749 ptrdiff_t charpos;
27750 Lisp_Object string, object = Qnil;
27751 Lisp_Object pos IF_LINT (= Qnil), help;
27752
27753 Lisp_Object mouse_face;
27754 int original_x_pixel = x;
27755 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27756 struct glyph_row *row IF_LINT (= 0);
27757
27758 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27759 {
27760 int x0;
27761 struct glyph *end;
27762
27763 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27764 returns them in row/column units! */
27765 string = mode_line_string (w, area, &x, &y, &charpos,
27766 &object, &dx, &dy, &width, &height);
27767
27768 row = (area == ON_MODE_LINE
27769 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27770 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27771
27772 /* Find the glyph under the mouse pointer. */
27773 if (row->mode_line_p && row->enabled_p)
27774 {
27775 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27776 end = glyph + row->used[TEXT_AREA];
27777
27778 for (x0 = original_x_pixel;
27779 glyph < end && x0 >= glyph->pixel_width;
27780 ++glyph)
27781 x0 -= glyph->pixel_width;
27782
27783 if (glyph >= end)
27784 glyph = NULL;
27785 }
27786 }
27787 else
27788 {
27789 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27790 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27791 returns them in row/column units! */
27792 string = marginal_area_string (w, area, &x, &y, &charpos,
27793 &object, &dx, &dy, &width, &height);
27794 }
27795
27796 help = Qnil;
27797
27798 #ifdef HAVE_WINDOW_SYSTEM
27799 if (IMAGEP (object))
27800 {
27801 Lisp_Object image_map, hotspot;
27802 if ((image_map = Fplist_get (XCDR (object), QCmap),
27803 !NILP (image_map))
27804 && (hotspot = find_hot_spot (image_map, dx, dy),
27805 CONSP (hotspot))
27806 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27807 {
27808 Lisp_Object plist;
27809
27810 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27811 If so, we could look for mouse-enter, mouse-leave
27812 properties in PLIST (and do something...). */
27813 hotspot = XCDR (hotspot);
27814 if (CONSP (hotspot)
27815 && (plist = XCAR (hotspot), CONSP (plist)))
27816 {
27817 pointer = Fplist_get (plist, Qpointer);
27818 if (NILP (pointer))
27819 pointer = Qhand;
27820 help = Fplist_get (plist, Qhelp_echo);
27821 if (!NILP (help))
27822 {
27823 help_echo_string = help;
27824 XSETWINDOW (help_echo_window, w);
27825 help_echo_object = w->contents;
27826 help_echo_pos = charpos;
27827 }
27828 }
27829 }
27830 if (NILP (pointer))
27831 pointer = Fplist_get (XCDR (object), QCpointer);
27832 }
27833 #endif /* HAVE_WINDOW_SYSTEM */
27834
27835 if (STRINGP (string))
27836 pos = make_number (charpos);
27837
27838 /* Set the help text and mouse pointer. If the mouse is on a part
27839 of the mode line without any text (e.g. past the right edge of
27840 the mode line text), use the default help text and pointer. */
27841 if (STRINGP (string) || area == ON_MODE_LINE)
27842 {
27843 /* Arrange to display the help by setting the global variables
27844 help_echo_string, help_echo_object, and help_echo_pos. */
27845 if (NILP (help))
27846 {
27847 if (STRINGP (string))
27848 help = Fget_text_property (pos, Qhelp_echo, string);
27849
27850 if (!NILP (help))
27851 {
27852 help_echo_string = help;
27853 XSETWINDOW (help_echo_window, w);
27854 help_echo_object = string;
27855 help_echo_pos = charpos;
27856 }
27857 else if (area == ON_MODE_LINE)
27858 {
27859 Lisp_Object default_help
27860 = buffer_local_value_1 (Qmode_line_default_help_echo,
27861 w->contents);
27862
27863 if (STRINGP (default_help))
27864 {
27865 help_echo_string = default_help;
27866 XSETWINDOW (help_echo_window, w);
27867 help_echo_object = Qnil;
27868 help_echo_pos = -1;
27869 }
27870 }
27871 }
27872
27873 #ifdef HAVE_WINDOW_SYSTEM
27874 /* Change the mouse pointer according to what is under it. */
27875 if (FRAME_WINDOW_P (f))
27876 {
27877 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27878 if (STRINGP (string))
27879 {
27880 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27881
27882 if (NILP (pointer))
27883 pointer = Fget_text_property (pos, Qpointer, string);
27884
27885 /* Change the mouse pointer according to what is under X/Y. */
27886 if (NILP (pointer)
27887 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27888 {
27889 Lisp_Object map;
27890 map = Fget_text_property (pos, Qlocal_map, string);
27891 if (!KEYMAPP (map))
27892 map = Fget_text_property (pos, Qkeymap, string);
27893 if (!KEYMAPP (map))
27894 cursor = dpyinfo->vertical_scroll_bar_cursor;
27895 }
27896 }
27897 else
27898 /* Default mode-line pointer. */
27899 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27900 }
27901 #endif
27902 }
27903
27904 /* Change the mouse face according to what is under X/Y. */
27905 if (STRINGP (string))
27906 {
27907 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27908 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27909 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27910 && glyph)
27911 {
27912 Lisp_Object b, e;
27913
27914 struct glyph * tmp_glyph;
27915
27916 int gpos;
27917 int gseq_length;
27918 int total_pixel_width;
27919 ptrdiff_t begpos, endpos, ignore;
27920
27921 int vpos, hpos;
27922
27923 b = Fprevious_single_property_change (make_number (charpos + 1),
27924 Qmouse_face, string, Qnil);
27925 if (NILP (b))
27926 begpos = 0;
27927 else
27928 begpos = XINT (b);
27929
27930 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27931 if (NILP (e))
27932 endpos = SCHARS (string);
27933 else
27934 endpos = XINT (e);
27935
27936 /* Calculate the glyph position GPOS of GLYPH in the
27937 displayed string, relative to the beginning of the
27938 highlighted part of the string.
27939
27940 Note: GPOS is different from CHARPOS. CHARPOS is the
27941 position of GLYPH in the internal string object. A mode
27942 line string format has structures which are converted to
27943 a flattened string by the Emacs Lisp interpreter. The
27944 internal string is an element of those structures. The
27945 displayed string is the flattened string. */
27946 tmp_glyph = row_start_glyph;
27947 while (tmp_glyph < glyph
27948 && (!(EQ (tmp_glyph->object, glyph->object)
27949 && begpos <= tmp_glyph->charpos
27950 && tmp_glyph->charpos < endpos)))
27951 tmp_glyph++;
27952 gpos = glyph - tmp_glyph;
27953
27954 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27955 the highlighted part of the displayed string to which
27956 GLYPH belongs. Note: GSEQ_LENGTH is different from
27957 SCHARS (STRING), because the latter returns the length of
27958 the internal string. */
27959 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27960 tmp_glyph > glyph
27961 && (!(EQ (tmp_glyph->object, glyph->object)
27962 && begpos <= tmp_glyph->charpos
27963 && tmp_glyph->charpos < endpos));
27964 tmp_glyph--)
27965 ;
27966 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27967
27968 /* Calculate the total pixel width of all the glyphs between
27969 the beginning of the highlighted area and GLYPH. */
27970 total_pixel_width = 0;
27971 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27972 total_pixel_width += tmp_glyph->pixel_width;
27973
27974 /* Pre calculation of re-rendering position. Note: X is in
27975 column units here, after the call to mode_line_string or
27976 marginal_area_string. */
27977 hpos = x - gpos;
27978 vpos = (area == ON_MODE_LINE
27979 ? (w->current_matrix)->nrows - 1
27980 : 0);
27981
27982 /* If GLYPH's position is included in the region that is
27983 already drawn in mouse face, we have nothing to do. */
27984 if ( EQ (window, hlinfo->mouse_face_window)
27985 && (!row->reversed_p
27986 ? (hlinfo->mouse_face_beg_col <= hpos
27987 && hpos < hlinfo->mouse_face_end_col)
27988 /* In R2L rows we swap BEG and END, see below. */
27989 : (hlinfo->mouse_face_end_col <= hpos
27990 && hpos < hlinfo->mouse_face_beg_col))
27991 && hlinfo->mouse_face_beg_row == vpos )
27992 return;
27993
27994 if (clear_mouse_face (hlinfo))
27995 cursor = No_Cursor;
27996
27997 if (!row->reversed_p)
27998 {
27999 hlinfo->mouse_face_beg_col = hpos;
28000 hlinfo->mouse_face_beg_x = original_x_pixel
28001 - (total_pixel_width + dx);
28002 hlinfo->mouse_face_end_col = hpos + gseq_length;
28003 hlinfo->mouse_face_end_x = 0;
28004 }
28005 else
28006 {
28007 /* In R2L rows, show_mouse_face expects BEG and END
28008 coordinates to be swapped. */
28009 hlinfo->mouse_face_end_col = hpos;
28010 hlinfo->mouse_face_end_x = original_x_pixel
28011 - (total_pixel_width + dx);
28012 hlinfo->mouse_face_beg_col = hpos + gseq_length;
28013 hlinfo->mouse_face_beg_x = 0;
28014 }
28015
28016 hlinfo->mouse_face_beg_row = vpos;
28017 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
28018 hlinfo->mouse_face_beg_y = 0;
28019 hlinfo->mouse_face_end_y = 0;
28020 hlinfo->mouse_face_past_end = 0;
28021 hlinfo->mouse_face_window = window;
28022
28023 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
28024 charpos,
28025 0, 0, 0,
28026 &ignore,
28027 glyph->face_id,
28028 1);
28029 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28030
28031 if (NILP (pointer))
28032 pointer = Qhand;
28033 }
28034 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28035 clear_mouse_face (hlinfo);
28036 }
28037 #ifdef HAVE_WINDOW_SYSTEM
28038 if (FRAME_WINDOW_P (f))
28039 define_frame_cursor1 (f, cursor, pointer);
28040 #endif
28041 }
28042
28043
28044 /* EXPORT:
28045 Take proper action when the mouse has moved to position X, Y on
28046 frame F with regards to highlighting portions of display that have
28047 mouse-face properties. Also de-highlight portions of display where
28048 the mouse was before, set the mouse pointer shape as appropriate
28049 for the mouse coordinates, and activate help echo (tooltips).
28050 X and Y can be negative or out of range. */
28051
28052 void
28053 note_mouse_highlight (struct frame *f, int x, int y)
28054 {
28055 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28056 enum window_part part = ON_NOTHING;
28057 Lisp_Object window;
28058 struct window *w;
28059 Cursor cursor = No_Cursor;
28060 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
28061 struct buffer *b;
28062
28063 /* When a menu is active, don't highlight because this looks odd. */
28064 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28065 if (popup_activated ())
28066 return;
28067 #endif
28068
28069 if (!f->glyphs_initialized_p
28070 || f->pointer_invisible)
28071 return;
28072
28073 hlinfo->mouse_face_mouse_x = x;
28074 hlinfo->mouse_face_mouse_y = y;
28075 hlinfo->mouse_face_mouse_frame = f;
28076
28077 if (hlinfo->mouse_face_defer)
28078 return;
28079
28080 /* Which window is that in? */
28081 window = window_from_coordinates (f, x, y, &part, 1);
28082
28083 /* If displaying active text in another window, clear that. */
28084 if (! EQ (window, hlinfo->mouse_face_window)
28085 /* Also clear if we move out of text area in same window. */
28086 || (!NILP (hlinfo->mouse_face_window)
28087 && !NILP (window)
28088 && part != ON_TEXT
28089 && part != ON_MODE_LINE
28090 && part != ON_HEADER_LINE))
28091 clear_mouse_face (hlinfo);
28092
28093 /* Not on a window -> return. */
28094 if (!WINDOWP (window))
28095 return;
28096
28097 /* Reset help_echo_string. It will get recomputed below. */
28098 help_echo_string = Qnil;
28099
28100 /* Convert to window-relative pixel coordinates. */
28101 w = XWINDOW (window);
28102 frame_to_window_pixel_xy (w, &x, &y);
28103
28104 #ifdef HAVE_WINDOW_SYSTEM
28105 /* Handle tool-bar window differently since it doesn't display a
28106 buffer. */
28107 if (EQ (window, f->tool_bar_window))
28108 {
28109 note_tool_bar_highlight (f, x, y);
28110 return;
28111 }
28112 #endif
28113
28114 /* Mouse is on the mode, header line or margin? */
28115 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
28116 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
28117 {
28118 note_mode_line_or_margin_highlight (window, x, y, part);
28119 return;
28120 }
28121
28122 #ifdef HAVE_WINDOW_SYSTEM
28123 if (part == ON_VERTICAL_BORDER)
28124 {
28125 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28126 help_echo_string = build_string ("drag-mouse-1: resize");
28127 }
28128 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28129 || part == ON_SCROLL_BAR)
28130 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28131 else
28132 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28133 #endif
28134
28135 /* Are we in a window whose display is up to date?
28136 And verify the buffer's text has not changed. */
28137 b = XBUFFER (w->contents);
28138 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28139 {
28140 int hpos, vpos, dx, dy, area = LAST_AREA;
28141 ptrdiff_t pos;
28142 struct glyph *glyph;
28143 Lisp_Object object;
28144 Lisp_Object mouse_face = Qnil, position;
28145 Lisp_Object *overlay_vec = NULL;
28146 ptrdiff_t i, noverlays;
28147 struct buffer *obuf;
28148 ptrdiff_t obegv, ozv;
28149 int same_region;
28150
28151 /* Find the glyph under X/Y. */
28152 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
28153
28154 #ifdef HAVE_WINDOW_SYSTEM
28155 /* Look for :pointer property on image. */
28156 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28157 {
28158 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
28159 if (img != NULL && IMAGEP (img->spec))
28160 {
28161 Lisp_Object image_map, hotspot;
28162 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
28163 !NILP (image_map))
28164 && (hotspot = find_hot_spot (image_map,
28165 glyph->slice.img.x + dx,
28166 glyph->slice.img.y + dy),
28167 CONSP (hotspot))
28168 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28169 {
28170 Lisp_Object plist;
28171
28172 /* Could check XCAR (hotspot) to see if we enter/leave
28173 this hot-spot.
28174 If so, we could look for mouse-enter, mouse-leave
28175 properties in PLIST (and do something...). */
28176 hotspot = XCDR (hotspot);
28177 if (CONSP (hotspot)
28178 && (plist = XCAR (hotspot), CONSP (plist)))
28179 {
28180 pointer = Fplist_get (plist, Qpointer);
28181 if (NILP (pointer))
28182 pointer = Qhand;
28183 help_echo_string = Fplist_get (plist, Qhelp_echo);
28184 if (!NILP (help_echo_string))
28185 {
28186 help_echo_window = window;
28187 help_echo_object = glyph->object;
28188 help_echo_pos = glyph->charpos;
28189 }
28190 }
28191 }
28192 if (NILP (pointer))
28193 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28194 }
28195 }
28196 #endif /* HAVE_WINDOW_SYSTEM */
28197
28198 /* Clear mouse face if X/Y not over text. */
28199 if (glyph == NULL
28200 || area != TEXT_AREA
28201 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
28202 /* Glyph's OBJECT is an integer for glyphs inserted by the
28203 display engine for its internal purposes, like truncation
28204 and continuation glyphs and blanks beyond the end of
28205 line's text on text terminals. If we are over such a
28206 glyph, we are not over any text. */
28207 || INTEGERP (glyph->object)
28208 /* R2L rows have a stretch glyph at their front, which
28209 stands for no text, whereas L2R rows have no glyphs at
28210 all beyond the end of text. Treat such stretch glyphs
28211 like we do with NULL glyphs in L2R rows. */
28212 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28213 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
28214 && glyph->type == STRETCH_GLYPH
28215 && glyph->avoid_cursor_p))
28216 {
28217 if (clear_mouse_face (hlinfo))
28218 cursor = No_Cursor;
28219 #ifdef HAVE_WINDOW_SYSTEM
28220 if (FRAME_WINDOW_P (f) && NILP (pointer))
28221 {
28222 if (area != TEXT_AREA)
28223 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28224 else
28225 pointer = Vvoid_text_area_pointer;
28226 }
28227 #endif
28228 goto set_cursor;
28229 }
28230
28231 pos = glyph->charpos;
28232 object = glyph->object;
28233 if (!STRINGP (object) && !BUFFERP (object))
28234 goto set_cursor;
28235
28236 /* If we get an out-of-range value, return now; avoid an error. */
28237 if (BUFFERP (object) && pos > BUF_Z (b))
28238 goto set_cursor;
28239
28240 /* Make the window's buffer temporarily current for
28241 overlays_at and compute_char_face. */
28242 obuf = current_buffer;
28243 current_buffer = b;
28244 obegv = BEGV;
28245 ozv = ZV;
28246 BEGV = BEG;
28247 ZV = Z;
28248
28249 /* Is this char mouse-active or does it have help-echo? */
28250 position = make_number (pos);
28251
28252 if (BUFFERP (object))
28253 {
28254 /* Put all the overlays we want in a vector in overlay_vec. */
28255 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28256 /* Sort overlays into increasing priority order. */
28257 noverlays = sort_overlays (overlay_vec, noverlays, w);
28258 }
28259 else
28260 noverlays = 0;
28261
28262 if (NILP (Vmouse_highlight))
28263 {
28264 clear_mouse_face (hlinfo);
28265 goto check_help_echo;
28266 }
28267
28268 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28269
28270 if (same_region)
28271 cursor = No_Cursor;
28272
28273 /* Check mouse-face highlighting. */
28274 if (! same_region
28275 /* If there exists an overlay with mouse-face overlapping
28276 the one we are currently highlighting, we have to
28277 check if we enter the overlapping overlay, and then
28278 highlight only that. */
28279 || (OVERLAYP (hlinfo->mouse_face_overlay)
28280 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28281 {
28282 /* Find the highest priority overlay with a mouse-face. */
28283 Lisp_Object overlay = Qnil;
28284 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28285 {
28286 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28287 if (!NILP (mouse_face))
28288 overlay = overlay_vec[i];
28289 }
28290
28291 /* If we're highlighting the same overlay as before, there's
28292 no need to do that again. */
28293 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28294 goto check_help_echo;
28295 hlinfo->mouse_face_overlay = overlay;
28296
28297 /* Clear the display of the old active region, if any. */
28298 if (clear_mouse_face (hlinfo))
28299 cursor = No_Cursor;
28300
28301 /* If no overlay applies, get a text property. */
28302 if (NILP (overlay))
28303 mouse_face = Fget_text_property (position, Qmouse_face, object);
28304
28305 /* Next, compute the bounds of the mouse highlighting and
28306 display it. */
28307 if (!NILP (mouse_face) && STRINGP (object))
28308 {
28309 /* The mouse-highlighting comes from a display string
28310 with a mouse-face. */
28311 Lisp_Object s, e;
28312 ptrdiff_t ignore;
28313
28314 s = Fprevious_single_property_change
28315 (make_number (pos + 1), Qmouse_face, object, Qnil);
28316 e = Fnext_single_property_change
28317 (position, Qmouse_face, object, Qnil);
28318 if (NILP (s))
28319 s = make_number (0);
28320 if (NILP (e))
28321 e = make_number (SCHARS (object) - 1);
28322 mouse_face_from_string_pos (w, hlinfo, object,
28323 XINT (s), XINT (e));
28324 hlinfo->mouse_face_past_end = 0;
28325 hlinfo->mouse_face_window = window;
28326 hlinfo->mouse_face_face_id
28327 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
28328 glyph->face_id, 1);
28329 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28330 cursor = No_Cursor;
28331 }
28332 else
28333 {
28334 /* The mouse-highlighting, if any, comes from an overlay
28335 or text property in the buffer. */
28336 Lisp_Object buffer IF_LINT (= Qnil);
28337 Lisp_Object disp_string IF_LINT (= Qnil);
28338
28339 if (STRINGP (object))
28340 {
28341 /* If we are on a display string with no mouse-face,
28342 check if the text under it has one. */
28343 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28344 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28345 pos = string_buffer_position (object, start);
28346 if (pos > 0)
28347 {
28348 mouse_face = get_char_property_and_overlay
28349 (make_number (pos), Qmouse_face, w->contents, &overlay);
28350 buffer = w->contents;
28351 disp_string = object;
28352 }
28353 }
28354 else
28355 {
28356 buffer = object;
28357 disp_string = Qnil;
28358 }
28359
28360 if (!NILP (mouse_face))
28361 {
28362 Lisp_Object before, after;
28363 Lisp_Object before_string, after_string;
28364 /* To correctly find the limits of mouse highlight
28365 in a bidi-reordered buffer, we must not use the
28366 optimization of limiting the search in
28367 previous-single-property-change and
28368 next-single-property-change, because
28369 rows_from_pos_range needs the real start and end
28370 positions to DTRT in this case. That's because
28371 the first row visible in a window does not
28372 necessarily display the character whose position
28373 is the smallest. */
28374 Lisp_Object lim1 =
28375 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28376 ? Fmarker_position (w->start)
28377 : Qnil;
28378 Lisp_Object lim2 =
28379 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28380 ? make_number (BUF_Z (XBUFFER (buffer))
28381 - XFASTINT (w->window_end_pos))
28382 : Qnil;
28383
28384 if (NILP (overlay))
28385 {
28386 /* Handle the text property case. */
28387 before = Fprevious_single_property_change
28388 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28389 after = Fnext_single_property_change
28390 (make_number (pos), Qmouse_face, buffer, lim2);
28391 before_string = after_string = Qnil;
28392 }
28393 else
28394 {
28395 /* Handle the overlay case. */
28396 before = Foverlay_start (overlay);
28397 after = Foverlay_end (overlay);
28398 before_string = Foverlay_get (overlay, Qbefore_string);
28399 after_string = Foverlay_get (overlay, Qafter_string);
28400
28401 if (!STRINGP (before_string)) before_string = Qnil;
28402 if (!STRINGP (after_string)) after_string = Qnil;
28403 }
28404
28405 mouse_face_from_buffer_pos (window, hlinfo, pos,
28406 NILP (before)
28407 ? 1
28408 : XFASTINT (before),
28409 NILP (after)
28410 ? BUF_Z (XBUFFER (buffer))
28411 : XFASTINT (after),
28412 before_string, after_string,
28413 disp_string);
28414 cursor = No_Cursor;
28415 }
28416 }
28417 }
28418
28419 check_help_echo:
28420
28421 /* Look for a `help-echo' property. */
28422 if (NILP (help_echo_string)) {
28423 Lisp_Object help, overlay;
28424
28425 /* Check overlays first. */
28426 help = overlay = Qnil;
28427 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28428 {
28429 overlay = overlay_vec[i];
28430 help = Foverlay_get (overlay, Qhelp_echo);
28431 }
28432
28433 if (!NILP (help))
28434 {
28435 help_echo_string = help;
28436 help_echo_window = window;
28437 help_echo_object = overlay;
28438 help_echo_pos = pos;
28439 }
28440 else
28441 {
28442 Lisp_Object obj = glyph->object;
28443 ptrdiff_t charpos = glyph->charpos;
28444
28445 /* Try text properties. */
28446 if (STRINGP (obj)
28447 && charpos >= 0
28448 && charpos < SCHARS (obj))
28449 {
28450 help = Fget_text_property (make_number (charpos),
28451 Qhelp_echo, obj);
28452 if (NILP (help))
28453 {
28454 /* If the string itself doesn't specify a help-echo,
28455 see if the buffer text ``under'' it does. */
28456 struct glyph_row *r
28457 = MATRIX_ROW (w->current_matrix, vpos);
28458 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28459 ptrdiff_t p = string_buffer_position (obj, start);
28460 if (p > 0)
28461 {
28462 help = Fget_char_property (make_number (p),
28463 Qhelp_echo, w->contents);
28464 if (!NILP (help))
28465 {
28466 charpos = p;
28467 obj = w->contents;
28468 }
28469 }
28470 }
28471 }
28472 else if (BUFFERP (obj)
28473 && charpos >= BEGV
28474 && charpos < ZV)
28475 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28476 obj);
28477
28478 if (!NILP (help))
28479 {
28480 help_echo_string = help;
28481 help_echo_window = window;
28482 help_echo_object = obj;
28483 help_echo_pos = charpos;
28484 }
28485 }
28486 }
28487
28488 #ifdef HAVE_WINDOW_SYSTEM
28489 /* Look for a `pointer' property. */
28490 if (FRAME_WINDOW_P (f) && NILP (pointer))
28491 {
28492 /* Check overlays first. */
28493 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28494 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28495
28496 if (NILP (pointer))
28497 {
28498 Lisp_Object obj = glyph->object;
28499 ptrdiff_t charpos = glyph->charpos;
28500
28501 /* Try text properties. */
28502 if (STRINGP (obj)
28503 && charpos >= 0
28504 && charpos < SCHARS (obj))
28505 {
28506 pointer = Fget_text_property (make_number (charpos),
28507 Qpointer, obj);
28508 if (NILP (pointer))
28509 {
28510 /* If the string itself doesn't specify a pointer,
28511 see if the buffer text ``under'' it does. */
28512 struct glyph_row *r
28513 = MATRIX_ROW (w->current_matrix, vpos);
28514 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28515 ptrdiff_t p = string_buffer_position (obj, start);
28516 if (p > 0)
28517 pointer = Fget_char_property (make_number (p),
28518 Qpointer, w->contents);
28519 }
28520 }
28521 else if (BUFFERP (obj)
28522 && charpos >= BEGV
28523 && charpos < ZV)
28524 pointer = Fget_text_property (make_number (charpos),
28525 Qpointer, obj);
28526 }
28527 }
28528 #endif /* HAVE_WINDOW_SYSTEM */
28529
28530 BEGV = obegv;
28531 ZV = ozv;
28532 current_buffer = obuf;
28533 }
28534
28535 set_cursor:
28536
28537 #ifdef HAVE_WINDOW_SYSTEM
28538 if (FRAME_WINDOW_P (f))
28539 define_frame_cursor1 (f, cursor, pointer);
28540 #else
28541 /* This is here to prevent a compiler error, about "label at end of
28542 compound statement". */
28543 return;
28544 #endif
28545 }
28546
28547
28548 /* EXPORT for RIF:
28549 Clear any mouse-face on window W. This function is part of the
28550 redisplay interface, and is called from try_window_id and similar
28551 functions to ensure the mouse-highlight is off. */
28552
28553 void
28554 x_clear_window_mouse_face (struct window *w)
28555 {
28556 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28557 Lisp_Object window;
28558
28559 block_input ();
28560 XSETWINDOW (window, w);
28561 if (EQ (window, hlinfo->mouse_face_window))
28562 clear_mouse_face (hlinfo);
28563 unblock_input ();
28564 }
28565
28566
28567 /* EXPORT:
28568 Just discard the mouse face information for frame F, if any.
28569 This is used when the size of F is changed. */
28570
28571 void
28572 cancel_mouse_face (struct frame *f)
28573 {
28574 Lisp_Object window;
28575 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28576
28577 window = hlinfo->mouse_face_window;
28578 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28579 {
28580 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28581 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28582 hlinfo->mouse_face_window = Qnil;
28583 }
28584 }
28585
28586
28587 \f
28588 /***********************************************************************
28589 Exposure Events
28590 ***********************************************************************/
28591
28592 #ifdef HAVE_WINDOW_SYSTEM
28593
28594 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28595 which intersects rectangle R. R is in window-relative coordinates. */
28596
28597 static void
28598 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28599 enum glyph_row_area area)
28600 {
28601 struct glyph *first = row->glyphs[area];
28602 struct glyph *end = row->glyphs[area] + row->used[area];
28603 struct glyph *last;
28604 int first_x, start_x, x;
28605
28606 if (area == TEXT_AREA && row->fill_line_p)
28607 /* If row extends face to end of line write the whole line. */
28608 draw_glyphs (w, 0, row, area,
28609 0, row->used[area],
28610 DRAW_NORMAL_TEXT, 0);
28611 else
28612 {
28613 /* Set START_X to the window-relative start position for drawing glyphs of
28614 AREA. The first glyph of the text area can be partially visible.
28615 The first glyphs of other areas cannot. */
28616 start_x = window_box_left_offset (w, area);
28617 x = start_x;
28618 if (area == TEXT_AREA)
28619 x += row->x;
28620
28621 /* Find the first glyph that must be redrawn. */
28622 while (first < end
28623 && x + first->pixel_width < r->x)
28624 {
28625 x += first->pixel_width;
28626 ++first;
28627 }
28628
28629 /* Find the last one. */
28630 last = first;
28631 first_x = x;
28632 while (last < end
28633 && x < r->x + r->width)
28634 {
28635 x += last->pixel_width;
28636 ++last;
28637 }
28638
28639 /* Repaint. */
28640 if (last > first)
28641 draw_glyphs (w, first_x - start_x, row, area,
28642 first - row->glyphs[area], last - row->glyphs[area],
28643 DRAW_NORMAL_TEXT, 0);
28644 }
28645 }
28646
28647
28648 /* Redraw the parts of the glyph row ROW on window W intersecting
28649 rectangle R. R is in window-relative coordinates. Value is
28650 non-zero if mouse-face was overwritten. */
28651
28652 static int
28653 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28654 {
28655 eassert (row->enabled_p);
28656
28657 if (row->mode_line_p || w->pseudo_window_p)
28658 draw_glyphs (w, 0, row, TEXT_AREA,
28659 0, row->used[TEXT_AREA],
28660 DRAW_NORMAL_TEXT, 0);
28661 else
28662 {
28663 if (row->used[LEFT_MARGIN_AREA])
28664 expose_area (w, row, r, LEFT_MARGIN_AREA);
28665 if (row->used[TEXT_AREA])
28666 expose_area (w, row, r, TEXT_AREA);
28667 if (row->used[RIGHT_MARGIN_AREA])
28668 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28669 draw_row_fringe_bitmaps (w, row);
28670 }
28671
28672 return row->mouse_face_p;
28673 }
28674
28675
28676 /* Redraw those parts of glyphs rows during expose event handling that
28677 overlap other rows. Redrawing of an exposed line writes over parts
28678 of lines overlapping that exposed line; this function fixes that.
28679
28680 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28681 row in W's current matrix that is exposed and overlaps other rows.
28682 LAST_OVERLAPPING_ROW is the last such row. */
28683
28684 static void
28685 expose_overlaps (struct window *w,
28686 struct glyph_row *first_overlapping_row,
28687 struct glyph_row *last_overlapping_row,
28688 XRectangle *r)
28689 {
28690 struct glyph_row *row;
28691
28692 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28693 if (row->overlapping_p)
28694 {
28695 eassert (row->enabled_p && !row->mode_line_p);
28696
28697 row->clip = r;
28698 if (row->used[LEFT_MARGIN_AREA])
28699 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28700
28701 if (row->used[TEXT_AREA])
28702 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28703
28704 if (row->used[RIGHT_MARGIN_AREA])
28705 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28706 row->clip = NULL;
28707 }
28708 }
28709
28710
28711 /* Return non-zero if W's cursor intersects rectangle R. */
28712
28713 static int
28714 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28715 {
28716 XRectangle cr, result;
28717 struct glyph *cursor_glyph;
28718 struct glyph_row *row;
28719
28720 if (w->phys_cursor.vpos >= 0
28721 && w->phys_cursor.vpos < w->current_matrix->nrows
28722 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28723 row->enabled_p)
28724 && row->cursor_in_fringe_p)
28725 {
28726 /* Cursor is in the fringe. */
28727 cr.x = window_box_right_offset (w,
28728 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28729 ? RIGHT_MARGIN_AREA
28730 : TEXT_AREA));
28731 cr.y = row->y;
28732 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28733 cr.height = row->height;
28734 return x_intersect_rectangles (&cr, r, &result);
28735 }
28736
28737 cursor_glyph = get_phys_cursor_glyph (w);
28738 if (cursor_glyph)
28739 {
28740 /* r is relative to W's box, but w->phys_cursor.x is relative
28741 to left edge of W's TEXT area. Adjust it. */
28742 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28743 cr.y = w->phys_cursor.y;
28744 cr.width = cursor_glyph->pixel_width;
28745 cr.height = w->phys_cursor_height;
28746 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28747 I assume the effect is the same -- and this is portable. */
28748 return x_intersect_rectangles (&cr, r, &result);
28749 }
28750 /* If we don't understand the format, pretend we're not in the hot-spot. */
28751 return 0;
28752 }
28753
28754
28755 /* EXPORT:
28756 Draw a vertical window border to the right of window W if W doesn't
28757 have vertical scroll bars. */
28758
28759 void
28760 x_draw_vertical_border (struct window *w)
28761 {
28762 struct frame *f = XFRAME (WINDOW_FRAME (w));
28763
28764 /* We could do better, if we knew what type of scroll-bar the adjacent
28765 windows (on either side) have... But we don't :-(
28766 However, I think this works ok. ++KFS 2003-04-25 */
28767
28768 /* Redraw borders between horizontally adjacent windows. Don't
28769 do it for frames with vertical scroll bars because either the
28770 right scroll bar of a window, or the left scroll bar of its
28771 neighbor will suffice as a border. */
28772 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28773 return;
28774
28775 /* Note: It is necessary to redraw both the left and the right
28776 borders, for when only this single window W is being
28777 redisplayed. */
28778 if (!WINDOW_RIGHTMOST_P (w)
28779 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28780 {
28781 int x0, x1, y0, y1;
28782
28783 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28784 y1 -= 1;
28785
28786 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28787 x1 -= 1;
28788
28789 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28790 }
28791 if (!WINDOW_LEFTMOST_P (w)
28792 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28793 {
28794 int x0, x1, y0, y1;
28795
28796 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28797 y1 -= 1;
28798
28799 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28800 x0 -= 1;
28801
28802 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28803 }
28804 }
28805
28806
28807 /* Redraw the part of window W intersection rectangle FR. Pixel
28808 coordinates in FR are frame-relative. Call this function with
28809 input blocked. Value is non-zero if the exposure overwrites
28810 mouse-face. */
28811
28812 static int
28813 expose_window (struct window *w, XRectangle *fr)
28814 {
28815 struct frame *f = XFRAME (w->frame);
28816 XRectangle wr, r;
28817 int mouse_face_overwritten_p = 0;
28818
28819 /* If window is not yet fully initialized, do nothing. This can
28820 happen when toolkit scroll bars are used and a window is split.
28821 Reconfiguring the scroll bar will generate an expose for a newly
28822 created window. */
28823 if (w->current_matrix == NULL)
28824 return 0;
28825
28826 /* When we're currently updating the window, display and current
28827 matrix usually don't agree. Arrange for a thorough display
28828 later. */
28829 if (w->must_be_updated_p)
28830 {
28831 SET_FRAME_GARBAGED (f);
28832 return 0;
28833 }
28834
28835 /* Frame-relative pixel rectangle of W. */
28836 wr.x = WINDOW_LEFT_EDGE_X (w);
28837 wr.y = WINDOW_TOP_EDGE_Y (w);
28838 wr.width = WINDOW_TOTAL_WIDTH (w);
28839 wr.height = WINDOW_TOTAL_HEIGHT (w);
28840
28841 if (x_intersect_rectangles (fr, &wr, &r))
28842 {
28843 int yb = window_text_bottom_y (w);
28844 struct glyph_row *row;
28845 int cursor_cleared_p, phys_cursor_on_p;
28846 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28847
28848 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28849 r.x, r.y, r.width, r.height));
28850
28851 /* Convert to window coordinates. */
28852 r.x -= WINDOW_LEFT_EDGE_X (w);
28853 r.y -= WINDOW_TOP_EDGE_Y (w);
28854
28855 /* Turn off the cursor. */
28856 if (!w->pseudo_window_p
28857 && phys_cursor_in_rect_p (w, &r))
28858 {
28859 x_clear_cursor (w);
28860 cursor_cleared_p = 1;
28861 }
28862 else
28863 cursor_cleared_p = 0;
28864
28865 /* If the row containing the cursor extends face to end of line,
28866 then expose_area might overwrite the cursor outside the
28867 rectangle and thus notice_overwritten_cursor might clear
28868 w->phys_cursor_on_p. We remember the original value and
28869 check later if it is changed. */
28870 phys_cursor_on_p = w->phys_cursor_on_p;
28871
28872 /* Update lines intersecting rectangle R. */
28873 first_overlapping_row = last_overlapping_row = NULL;
28874 for (row = w->current_matrix->rows;
28875 row->enabled_p;
28876 ++row)
28877 {
28878 int y0 = row->y;
28879 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28880
28881 if ((y0 >= r.y && y0 < r.y + r.height)
28882 || (y1 > r.y && y1 < r.y + r.height)
28883 || (r.y >= y0 && r.y < y1)
28884 || (r.y + r.height > y0 && r.y + r.height < y1))
28885 {
28886 /* A header line may be overlapping, but there is no need
28887 to fix overlapping areas for them. KFS 2005-02-12 */
28888 if (row->overlapping_p && !row->mode_line_p)
28889 {
28890 if (first_overlapping_row == NULL)
28891 first_overlapping_row = row;
28892 last_overlapping_row = row;
28893 }
28894
28895 row->clip = fr;
28896 if (expose_line (w, row, &r))
28897 mouse_face_overwritten_p = 1;
28898 row->clip = NULL;
28899 }
28900 else if (row->overlapping_p)
28901 {
28902 /* We must redraw a row overlapping the exposed area. */
28903 if (y0 < r.y
28904 ? y0 + row->phys_height > r.y
28905 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28906 {
28907 if (first_overlapping_row == NULL)
28908 first_overlapping_row = row;
28909 last_overlapping_row = row;
28910 }
28911 }
28912
28913 if (y1 >= yb)
28914 break;
28915 }
28916
28917 /* Display the mode line if there is one. */
28918 if (WINDOW_WANTS_MODELINE_P (w)
28919 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28920 row->enabled_p)
28921 && row->y < r.y + r.height)
28922 {
28923 if (expose_line (w, row, &r))
28924 mouse_face_overwritten_p = 1;
28925 }
28926
28927 if (!w->pseudo_window_p)
28928 {
28929 /* Fix the display of overlapping rows. */
28930 if (first_overlapping_row)
28931 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28932 fr);
28933
28934 /* Draw border between windows. */
28935 x_draw_vertical_border (w);
28936
28937 /* Turn the cursor on again. */
28938 if (cursor_cleared_p
28939 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28940 update_window_cursor (w, 1);
28941 }
28942 }
28943
28944 return mouse_face_overwritten_p;
28945 }
28946
28947
28948
28949 /* Redraw (parts) of all windows in the window tree rooted at W that
28950 intersect R. R contains frame pixel coordinates. Value is
28951 non-zero if the exposure overwrites mouse-face. */
28952
28953 static int
28954 expose_window_tree (struct window *w, XRectangle *r)
28955 {
28956 struct frame *f = XFRAME (w->frame);
28957 int mouse_face_overwritten_p = 0;
28958
28959 while (w && !FRAME_GARBAGED_P (f))
28960 {
28961 if (WINDOWP (w->contents))
28962 mouse_face_overwritten_p
28963 |= expose_window_tree (XWINDOW (w->contents), r);
28964 else
28965 mouse_face_overwritten_p |= expose_window (w, r);
28966
28967 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28968 }
28969
28970 return mouse_face_overwritten_p;
28971 }
28972
28973
28974 /* EXPORT:
28975 Redisplay an exposed area of frame F. X and Y are the upper-left
28976 corner of the exposed rectangle. W and H are width and height of
28977 the exposed area. All are pixel values. W or H zero means redraw
28978 the entire frame. */
28979
28980 void
28981 expose_frame (struct frame *f, int x, int y, int w, int h)
28982 {
28983 XRectangle r;
28984 int mouse_face_overwritten_p = 0;
28985
28986 TRACE ((stderr, "expose_frame "));
28987
28988 /* No need to redraw if frame will be redrawn soon. */
28989 if (FRAME_GARBAGED_P (f))
28990 {
28991 TRACE ((stderr, " garbaged\n"));
28992 return;
28993 }
28994
28995 /* If basic faces haven't been realized yet, there is no point in
28996 trying to redraw anything. This can happen when we get an expose
28997 event while Emacs is starting, e.g. by moving another window. */
28998 if (FRAME_FACE_CACHE (f) == NULL
28999 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
29000 {
29001 TRACE ((stderr, " no faces\n"));
29002 return;
29003 }
29004
29005 if (w == 0 || h == 0)
29006 {
29007 r.x = r.y = 0;
29008 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
29009 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
29010 }
29011 else
29012 {
29013 r.x = x;
29014 r.y = y;
29015 r.width = w;
29016 r.height = h;
29017 }
29018
29019 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
29020 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
29021
29022 if (WINDOWP (f->tool_bar_window))
29023 mouse_face_overwritten_p
29024 |= expose_window (XWINDOW (f->tool_bar_window), &r);
29025
29026 #ifdef HAVE_X_WINDOWS
29027 #ifndef MSDOS
29028 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
29029 if (WINDOWP (f->menu_bar_window))
29030 mouse_face_overwritten_p
29031 |= expose_window (XWINDOW (f->menu_bar_window), &r);
29032 #endif /* not USE_X_TOOLKIT and not USE_GTK */
29033 #endif
29034 #endif
29035
29036 /* Some window managers support a focus-follows-mouse style with
29037 delayed raising of frames. Imagine a partially obscured frame,
29038 and moving the mouse into partially obscured mouse-face on that
29039 frame. The visible part of the mouse-face will be highlighted,
29040 then the WM raises the obscured frame. With at least one WM, KDE
29041 2.1, Emacs is not getting any event for the raising of the frame
29042 (even tried with SubstructureRedirectMask), only Expose events.
29043 These expose events will draw text normally, i.e. not
29044 highlighted. Which means we must redo the highlight here.
29045 Subsume it under ``we love X''. --gerd 2001-08-15 */
29046 /* Included in Windows version because Windows most likely does not
29047 do the right thing if any third party tool offers
29048 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
29049 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
29050 {
29051 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29052 if (f == hlinfo->mouse_face_mouse_frame)
29053 {
29054 int mouse_x = hlinfo->mouse_face_mouse_x;
29055 int mouse_y = hlinfo->mouse_face_mouse_y;
29056 clear_mouse_face (hlinfo);
29057 note_mouse_highlight (f, mouse_x, mouse_y);
29058 }
29059 }
29060 }
29061
29062
29063 /* EXPORT:
29064 Determine the intersection of two rectangles R1 and R2. Return
29065 the intersection in *RESULT. Value is non-zero if RESULT is not
29066 empty. */
29067
29068 int
29069 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
29070 {
29071 XRectangle *left, *right;
29072 XRectangle *upper, *lower;
29073 int intersection_p = 0;
29074
29075 /* Rearrange so that R1 is the left-most rectangle. */
29076 if (r1->x < r2->x)
29077 left = r1, right = r2;
29078 else
29079 left = r2, right = r1;
29080
29081 /* X0 of the intersection is right.x0, if this is inside R1,
29082 otherwise there is no intersection. */
29083 if (right->x <= left->x + left->width)
29084 {
29085 result->x = right->x;
29086
29087 /* The right end of the intersection is the minimum of
29088 the right ends of left and right. */
29089 result->width = (min (left->x + left->width, right->x + right->width)
29090 - result->x);
29091
29092 /* Same game for Y. */
29093 if (r1->y < r2->y)
29094 upper = r1, lower = r2;
29095 else
29096 upper = r2, lower = r1;
29097
29098 /* The upper end of the intersection is lower.y0, if this is inside
29099 of upper. Otherwise, there is no intersection. */
29100 if (lower->y <= upper->y + upper->height)
29101 {
29102 result->y = lower->y;
29103
29104 /* The lower end of the intersection is the minimum of the lower
29105 ends of upper and lower. */
29106 result->height = (min (lower->y + lower->height,
29107 upper->y + upper->height)
29108 - result->y);
29109 intersection_p = 1;
29110 }
29111 }
29112
29113 return intersection_p;
29114 }
29115
29116 #endif /* HAVE_WINDOW_SYSTEM */
29117
29118 \f
29119 /***********************************************************************
29120 Initialization
29121 ***********************************************************************/
29122
29123 void
29124 syms_of_xdisp (void)
29125 {
29126 Vwith_echo_area_save_vector = Qnil;
29127 staticpro (&Vwith_echo_area_save_vector);
29128
29129 Vmessage_stack = Qnil;
29130 staticpro (&Vmessage_stack);
29131
29132 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
29133 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
29134
29135 message_dolog_marker1 = Fmake_marker ();
29136 staticpro (&message_dolog_marker1);
29137 message_dolog_marker2 = Fmake_marker ();
29138 staticpro (&message_dolog_marker2);
29139 message_dolog_marker3 = Fmake_marker ();
29140 staticpro (&message_dolog_marker3);
29141
29142 #ifdef GLYPH_DEBUG
29143 defsubr (&Sdump_frame_glyph_matrix);
29144 defsubr (&Sdump_glyph_matrix);
29145 defsubr (&Sdump_glyph_row);
29146 defsubr (&Sdump_tool_bar_row);
29147 defsubr (&Strace_redisplay);
29148 defsubr (&Strace_to_stderr);
29149 #endif
29150 #ifdef HAVE_WINDOW_SYSTEM
29151 defsubr (&Stool_bar_lines_needed);
29152 defsubr (&Slookup_image_map);
29153 #endif
29154 defsubr (&Sline_pixel_height);
29155 defsubr (&Sformat_mode_line);
29156 defsubr (&Sinvisible_p);
29157 defsubr (&Scurrent_bidi_paragraph_direction);
29158 defsubr (&Smove_point_visually);
29159
29160 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
29161 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
29162 DEFSYM (Qoverriding_local_map, "overriding-local-map");
29163 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
29164 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
29165 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
29166 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
29167 DEFSYM (Qeval, "eval");
29168 DEFSYM (QCdata, ":data");
29169 DEFSYM (Qdisplay, "display");
29170 DEFSYM (Qspace_width, "space-width");
29171 DEFSYM (Qraise, "raise");
29172 DEFSYM (Qslice, "slice");
29173 DEFSYM (Qspace, "space");
29174 DEFSYM (Qmargin, "margin");
29175 DEFSYM (Qpointer, "pointer");
29176 DEFSYM (Qleft_margin, "left-margin");
29177 DEFSYM (Qright_margin, "right-margin");
29178 DEFSYM (Qcenter, "center");
29179 DEFSYM (Qline_height, "line-height");
29180 DEFSYM (QCalign_to, ":align-to");
29181 DEFSYM (QCrelative_width, ":relative-width");
29182 DEFSYM (QCrelative_height, ":relative-height");
29183 DEFSYM (QCeval, ":eval");
29184 DEFSYM (QCpropertize, ":propertize");
29185 DEFSYM (QCfile, ":file");
29186 DEFSYM (Qfontified, "fontified");
29187 DEFSYM (Qfontification_functions, "fontification-functions");
29188 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
29189 DEFSYM (Qescape_glyph, "escape-glyph");
29190 DEFSYM (Qnobreak_space, "nobreak-space");
29191 DEFSYM (Qimage, "image");
29192 DEFSYM (Qtext, "text");
29193 DEFSYM (Qboth, "both");
29194 DEFSYM (Qboth_horiz, "both-horiz");
29195 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29196 DEFSYM (QCmap, ":map");
29197 DEFSYM (QCpointer, ":pointer");
29198 DEFSYM (Qrect, "rect");
29199 DEFSYM (Qcircle, "circle");
29200 DEFSYM (Qpoly, "poly");
29201 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29202 DEFSYM (Qgrow_only, "grow-only");
29203 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29204 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29205 DEFSYM (Qposition, "position");
29206 DEFSYM (Qbuffer_position, "buffer-position");
29207 DEFSYM (Qobject, "object");
29208 DEFSYM (Qbar, "bar");
29209 DEFSYM (Qhbar, "hbar");
29210 DEFSYM (Qbox, "box");
29211 DEFSYM (Qhollow, "hollow");
29212 DEFSYM (Qhand, "hand");
29213 DEFSYM (Qarrow, "arrow");
29214 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29215
29216 list_of_error = list1 (list2 (intern_c_string ("error"),
29217 intern_c_string ("void-variable")));
29218 staticpro (&list_of_error);
29219
29220 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29221 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29222 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29223 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29224
29225 echo_buffer[0] = echo_buffer[1] = Qnil;
29226 staticpro (&echo_buffer[0]);
29227 staticpro (&echo_buffer[1]);
29228
29229 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29230 staticpro (&echo_area_buffer[0]);
29231 staticpro (&echo_area_buffer[1]);
29232
29233 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29234 staticpro (&Vmessages_buffer_name);
29235
29236 mode_line_proptrans_alist = Qnil;
29237 staticpro (&mode_line_proptrans_alist);
29238 mode_line_string_list = Qnil;
29239 staticpro (&mode_line_string_list);
29240 mode_line_string_face = Qnil;
29241 staticpro (&mode_line_string_face);
29242 mode_line_string_face_prop = Qnil;
29243 staticpro (&mode_line_string_face_prop);
29244 Vmode_line_unwind_vector = Qnil;
29245 staticpro (&Vmode_line_unwind_vector);
29246
29247 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29248
29249 help_echo_string = Qnil;
29250 staticpro (&help_echo_string);
29251 help_echo_object = Qnil;
29252 staticpro (&help_echo_object);
29253 help_echo_window = Qnil;
29254 staticpro (&help_echo_window);
29255 previous_help_echo_string = Qnil;
29256 staticpro (&previous_help_echo_string);
29257 help_echo_pos = -1;
29258
29259 DEFSYM (Qright_to_left, "right-to-left");
29260 DEFSYM (Qleft_to_right, "left-to-right");
29261
29262 #ifdef HAVE_WINDOW_SYSTEM
29263 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29264 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29265 For example, if a block cursor is over a tab, it will be drawn as
29266 wide as that tab on the display. */);
29267 x_stretch_cursor_p = 0;
29268 #endif
29269
29270 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29271 doc: /* Non-nil means highlight trailing whitespace.
29272 The face used for trailing whitespace is `trailing-whitespace'. */);
29273 Vshow_trailing_whitespace = Qnil;
29274
29275 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29276 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29277 If the value is t, Emacs highlights non-ASCII chars which have the
29278 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29279 or `escape-glyph' face respectively.
29280
29281 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29282 U+2011 (non-breaking hyphen) are affected.
29283
29284 Any other non-nil value means to display these characters as a escape
29285 glyph followed by an ordinary space or hyphen.
29286
29287 A value of nil means no special handling of these characters. */);
29288 Vnobreak_char_display = Qt;
29289
29290 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29291 doc: /* The pointer shape to show in void text areas.
29292 A value of nil means to show the text pointer. Other options are `arrow',
29293 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29294 Vvoid_text_area_pointer = Qarrow;
29295
29296 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29297 doc: /* Non-nil means don't actually do any redisplay.
29298 This is used for internal purposes. */);
29299 Vinhibit_redisplay = Qnil;
29300
29301 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29302 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29303 Vglobal_mode_string = Qnil;
29304
29305 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29306 doc: /* Marker for where to display an arrow on top of the buffer text.
29307 This must be the beginning of a line in order to work.
29308 See also `overlay-arrow-string'. */);
29309 Voverlay_arrow_position = Qnil;
29310
29311 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29312 doc: /* String to display as an arrow in non-window frames.
29313 See also `overlay-arrow-position'. */);
29314 Voverlay_arrow_string = build_pure_c_string ("=>");
29315
29316 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29317 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29318 The symbols on this list are examined during redisplay to determine
29319 where to display overlay arrows. */);
29320 Voverlay_arrow_variable_list
29321 = list1 (intern_c_string ("overlay-arrow-position"));
29322
29323 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29324 doc: /* The number of lines to try scrolling a window by when point moves out.
29325 If that fails to bring point back on frame, point is centered instead.
29326 If this is zero, point is always centered after it moves off frame.
29327 If you want scrolling to always be a line at a time, you should set
29328 `scroll-conservatively' to a large value rather than set this to 1. */);
29329
29330 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29331 doc: /* Scroll up to this many lines, to bring point back on screen.
29332 If point moves off-screen, redisplay will scroll by up to
29333 `scroll-conservatively' lines in order to bring point just barely
29334 onto the screen again. If that cannot be done, then redisplay
29335 recenters point as usual.
29336
29337 If the value is greater than 100, redisplay will never recenter point,
29338 but will always scroll just enough text to bring point into view, even
29339 if you move far away.
29340
29341 A value of zero means always recenter point if it moves off screen. */);
29342 scroll_conservatively = 0;
29343
29344 DEFVAR_INT ("scroll-margin", scroll_margin,
29345 doc: /* Number of lines of margin at the top and bottom of a window.
29346 Recenter the window whenever point gets within this many lines
29347 of the top or bottom of the window. */);
29348 scroll_margin = 0;
29349
29350 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29351 doc: /* Pixels per inch value for non-window system displays.
29352 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29353 Vdisplay_pixels_per_inch = make_float (72.0);
29354
29355 #ifdef GLYPH_DEBUG
29356 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29357 #endif
29358
29359 DEFVAR_LISP ("truncate-partial-width-windows",
29360 Vtruncate_partial_width_windows,
29361 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29362 For an integer value, truncate lines in each window narrower than the
29363 full frame width, provided the window width is less than that integer;
29364 otherwise, respect the value of `truncate-lines'.
29365
29366 For any other non-nil value, truncate lines in all windows that do
29367 not span the full frame width.
29368
29369 A value of nil means to respect the value of `truncate-lines'.
29370
29371 If `word-wrap' is enabled, you might want to reduce this. */);
29372 Vtruncate_partial_width_windows = make_number (50);
29373
29374 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29375 doc: /* Maximum buffer size for which line number should be displayed.
29376 If the buffer is bigger than this, the line number does not appear
29377 in the mode line. A value of nil means no limit. */);
29378 Vline_number_display_limit = Qnil;
29379
29380 DEFVAR_INT ("line-number-display-limit-width",
29381 line_number_display_limit_width,
29382 doc: /* Maximum line width (in characters) for line number display.
29383 If the average length of the lines near point is bigger than this, then the
29384 line number may be omitted from the mode line. */);
29385 line_number_display_limit_width = 200;
29386
29387 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29388 doc: /* Non-nil means highlight region even in nonselected windows. */);
29389 highlight_nonselected_windows = 0;
29390
29391 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29392 doc: /* Non-nil if more than one frame is visible on this display.
29393 Minibuffer-only frames don't count, but iconified frames do.
29394 This variable is not guaranteed to be accurate except while processing
29395 `frame-title-format' and `icon-title-format'. */);
29396
29397 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29398 doc: /* Template for displaying the title bar of visible frames.
29399 \(Assuming the window manager supports this feature.)
29400
29401 This variable has the same structure as `mode-line-format', except that
29402 the %c and %l constructs are ignored. It is used only on frames for
29403 which no explicit name has been set \(see `modify-frame-parameters'). */);
29404
29405 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29406 doc: /* Template for displaying the title bar of an iconified frame.
29407 \(Assuming the window manager supports this feature.)
29408 This variable has the same structure as `mode-line-format' (which see),
29409 and is used only on frames for which no explicit name has been set
29410 \(see `modify-frame-parameters'). */);
29411 Vicon_title_format
29412 = Vframe_title_format
29413 = listn (CONSTYPE_PURE, 3,
29414 intern_c_string ("multiple-frames"),
29415 build_pure_c_string ("%b"),
29416 listn (CONSTYPE_PURE, 4,
29417 empty_unibyte_string,
29418 intern_c_string ("invocation-name"),
29419 build_pure_c_string ("@"),
29420 intern_c_string ("system-name")));
29421
29422 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29423 doc: /* Maximum number of lines to keep in the message log buffer.
29424 If nil, disable message logging. If t, log messages but don't truncate
29425 the buffer when it becomes large. */);
29426 Vmessage_log_max = make_number (1000);
29427
29428 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29429 doc: /* Functions called before redisplay, if window sizes have changed.
29430 The value should be a list of functions that take one argument.
29431 Just before redisplay, for each frame, if any of its windows have changed
29432 size since the last redisplay, or have been split or deleted,
29433 all the functions in the list are called, with the frame as argument. */);
29434 Vwindow_size_change_functions = Qnil;
29435
29436 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29437 doc: /* List of functions to call before redisplaying a window with scrolling.
29438 Each function is called with two arguments, the window and its new
29439 display-start position. Note that these functions are also called by
29440 `set-window-buffer'. Also note that the value of `window-end' is not
29441 valid when these functions are called.
29442
29443 Warning: Do not use this feature to alter the way the window
29444 is scrolled. It is not designed for that, and such use probably won't
29445 work. */);
29446 Vwindow_scroll_functions = Qnil;
29447
29448 DEFVAR_LISP ("window-text-change-functions",
29449 Vwindow_text_change_functions,
29450 doc: /* Functions to call in redisplay when text in the window might change. */);
29451 Vwindow_text_change_functions = Qnil;
29452
29453 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29454 doc: /* Functions called when redisplay of a window reaches the end trigger.
29455 Each function is called with two arguments, the window and the end trigger value.
29456 See `set-window-redisplay-end-trigger'. */);
29457 Vredisplay_end_trigger_functions = Qnil;
29458
29459 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29460 doc: /* Non-nil means autoselect window with mouse pointer.
29461 If nil, do not autoselect windows.
29462 A positive number means delay autoselection by that many seconds: a
29463 window is autoselected only after the mouse has remained in that
29464 window for the duration of the delay.
29465 A negative number has a similar effect, but causes windows to be
29466 autoselected only after the mouse has stopped moving. \(Because of
29467 the way Emacs compares mouse events, you will occasionally wait twice
29468 that time before the window gets selected.\)
29469 Any other value means to autoselect window instantaneously when the
29470 mouse pointer enters it.
29471
29472 Autoselection selects the minibuffer only if it is active, and never
29473 unselects the minibuffer if it is active.
29474
29475 When customizing this variable make sure that the actual value of
29476 `focus-follows-mouse' matches the behavior of your window manager. */);
29477 Vmouse_autoselect_window = Qnil;
29478
29479 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29480 doc: /* Non-nil means automatically resize tool-bars.
29481 This dynamically changes the tool-bar's height to the minimum height
29482 that is needed to make all tool-bar items visible.
29483 If value is `grow-only', the tool-bar's height is only increased
29484 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29485 Vauto_resize_tool_bars = Qt;
29486
29487 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29488 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29489 auto_raise_tool_bar_buttons_p = 1;
29490
29491 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29492 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29493 make_cursor_line_fully_visible_p = 1;
29494
29495 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29496 doc: /* Border below tool-bar in pixels.
29497 If an integer, use it as the height of the border.
29498 If it is one of `internal-border-width' or `border-width', use the
29499 value of the corresponding frame parameter.
29500 Otherwise, no border is added below the tool-bar. */);
29501 Vtool_bar_border = Qinternal_border_width;
29502
29503 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29504 doc: /* Margin around tool-bar buttons in pixels.
29505 If an integer, use that for both horizontal and vertical margins.
29506 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29507 HORZ specifying the horizontal margin, and VERT specifying the
29508 vertical margin. */);
29509 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29510
29511 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29512 doc: /* Relief thickness of tool-bar buttons. */);
29513 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29514
29515 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29516 doc: /* Tool bar style to use.
29517 It can be one of
29518 image - show images only
29519 text - show text only
29520 both - show both, text below image
29521 both-horiz - show text to the right of the image
29522 text-image-horiz - show text to the left of the image
29523 any other - use system default or image if no system default.
29524
29525 This variable only affects the GTK+ toolkit version of Emacs. */);
29526 Vtool_bar_style = Qnil;
29527
29528 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29529 doc: /* Maximum number of characters a label can have to be shown.
29530 The tool bar style must also show labels for this to have any effect, see
29531 `tool-bar-style'. */);
29532 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29533
29534 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29535 doc: /* List of functions to call to fontify regions of text.
29536 Each function is called with one argument POS. Functions must
29537 fontify a region starting at POS in the current buffer, and give
29538 fontified regions the property `fontified'. */);
29539 Vfontification_functions = Qnil;
29540 Fmake_variable_buffer_local (Qfontification_functions);
29541
29542 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29543 unibyte_display_via_language_environment,
29544 doc: /* Non-nil means display unibyte text according to language environment.
29545 Specifically, this means that raw bytes in the range 160-255 decimal
29546 are displayed by converting them to the equivalent multibyte characters
29547 according to the current language environment. As a result, they are
29548 displayed according to the current fontset.
29549
29550 Note that this variable affects only how these bytes are displayed,
29551 but does not change the fact they are interpreted as raw bytes. */);
29552 unibyte_display_via_language_environment = 0;
29553
29554 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29555 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29556 If a float, it specifies a fraction of the mini-window frame's height.
29557 If an integer, it specifies a number of lines. */);
29558 Vmax_mini_window_height = make_float (0.25);
29559
29560 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29561 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29562 A value of nil means don't automatically resize mini-windows.
29563 A value of t means resize them to fit the text displayed in them.
29564 A value of `grow-only', the default, means let mini-windows grow only;
29565 they return to their normal size when the minibuffer is closed, or the
29566 echo area becomes empty. */);
29567 Vresize_mini_windows = Qgrow_only;
29568
29569 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29570 doc: /* Alist specifying how to blink the cursor off.
29571 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29572 `cursor-type' frame-parameter or variable equals ON-STATE,
29573 comparing using `equal', Emacs uses OFF-STATE to specify
29574 how to blink it off. ON-STATE and OFF-STATE are values for
29575 the `cursor-type' frame parameter.
29576
29577 If a frame's ON-STATE has no entry in this list,
29578 the frame's other specifications determine how to blink the cursor off. */);
29579 Vblink_cursor_alist = Qnil;
29580
29581 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29582 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29583 If non-nil, windows are automatically scrolled horizontally to make
29584 point visible. */);
29585 automatic_hscrolling_p = 1;
29586 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29587
29588 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29589 doc: /* How many columns away from the window edge point is allowed to get
29590 before automatic hscrolling will horizontally scroll the window. */);
29591 hscroll_margin = 5;
29592
29593 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29594 doc: /* How many columns to scroll the window when point gets too close to the edge.
29595 When point is less than `hscroll-margin' columns from the window
29596 edge, automatic hscrolling will scroll the window by the amount of columns
29597 determined by this variable. If its value is a positive integer, scroll that
29598 many columns. If it's a positive floating-point number, it specifies the
29599 fraction of the window's width to scroll. If it's nil or zero, point will be
29600 centered horizontally after the scroll. Any other value, including negative
29601 numbers, are treated as if the value were zero.
29602
29603 Automatic hscrolling always moves point outside the scroll margin, so if
29604 point was more than scroll step columns inside the margin, the window will
29605 scroll more than the value given by the scroll step.
29606
29607 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29608 and `scroll-right' overrides this variable's effect. */);
29609 Vhscroll_step = make_number (0);
29610
29611 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29612 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29613 Bind this around calls to `message' to let it take effect. */);
29614 message_truncate_lines = 0;
29615
29616 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29617 doc: /* Normal hook run to update the menu bar definitions.
29618 Redisplay runs this hook before it redisplays the menu bar.
29619 This is used to update submenus such as Buffers,
29620 whose contents depend on various data. */);
29621 Vmenu_bar_update_hook = Qnil;
29622
29623 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29624 doc: /* Frame for which we are updating a menu.
29625 The enable predicate for a menu binding should check this variable. */);
29626 Vmenu_updating_frame = Qnil;
29627
29628 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29629 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29630 inhibit_menubar_update = 0;
29631
29632 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29633 doc: /* Prefix prepended to all continuation lines at display time.
29634 The value may be a string, an image, or a stretch-glyph; it is
29635 interpreted in the same way as the value of a `display' text property.
29636
29637 This variable is overridden by any `wrap-prefix' text or overlay
29638 property.
29639
29640 To add a prefix to non-continuation lines, use `line-prefix'. */);
29641 Vwrap_prefix = Qnil;
29642 DEFSYM (Qwrap_prefix, "wrap-prefix");
29643 Fmake_variable_buffer_local (Qwrap_prefix);
29644
29645 DEFVAR_LISP ("line-prefix", Vline_prefix,
29646 doc: /* Prefix prepended to all non-continuation lines at display time.
29647 The value may be a string, an image, or a stretch-glyph; it is
29648 interpreted in the same way as the value of a `display' text property.
29649
29650 This variable is overridden by any `line-prefix' text or overlay
29651 property.
29652
29653 To add a prefix to continuation lines, use `wrap-prefix'. */);
29654 Vline_prefix = Qnil;
29655 DEFSYM (Qline_prefix, "line-prefix");
29656 Fmake_variable_buffer_local (Qline_prefix);
29657
29658 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29659 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29660 inhibit_eval_during_redisplay = 0;
29661
29662 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29663 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29664 inhibit_free_realized_faces = 0;
29665
29666 #ifdef GLYPH_DEBUG
29667 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29668 doc: /* Inhibit try_window_id display optimization. */);
29669 inhibit_try_window_id = 0;
29670
29671 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29672 doc: /* Inhibit try_window_reusing display optimization. */);
29673 inhibit_try_window_reusing = 0;
29674
29675 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29676 doc: /* Inhibit try_cursor_movement display optimization. */);
29677 inhibit_try_cursor_movement = 0;
29678 #endif /* GLYPH_DEBUG */
29679
29680 DEFVAR_INT ("overline-margin", overline_margin,
29681 doc: /* Space between overline and text, in pixels.
29682 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29683 margin to the character height. */);
29684 overline_margin = 2;
29685
29686 DEFVAR_INT ("underline-minimum-offset",
29687 underline_minimum_offset,
29688 doc: /* Minimum distance between baseline and underline.
29689 This can improve legibility of underlined text at small font sizes,
29690 particularly when using variable `x-use-underline-position-properties'
29691 with fonts that specify an UNDERLINE_POSITION relatively close to the
29692 baseline. The default value is 1. */);
29693 underline_minimum_offset = 1;
29694
29695 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29696 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29697 This feature only works when on a window system that can change
29698 cursor shapes. */);
29699 display_hourglass_p = 1;
29700
29701 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29702 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29703 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29704
29705 hourglass_atimer = NULL;
29706 hourglass_shown_p = 0;
29707
29708 DEFSYM (Qglyphless_char, "glyphless-char");
29709 DEFSYM (Qhex_code, "hex-code");
29710 DEFSYM (Qempty_box, "empty-box");
29711 DEFSYM (Qthin_space, "thin-space");
29712 DEFSYM (Qzero_width, "zero-width");
29713
29714 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29715 /* Intern this now in case it isn't already done.
29716 Setting this variable twice is harmless.
29717 But don't staticpro it here--that is done in alloc.c. */
29718 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29719 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29720
29721 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29722 doc: /* Char-table defining glyphless characters.
29723 Each element, if non-nil, should be one of the following:
29724 an ASCII acronym string: display this string in a box
29725 `hex-code': display the hexadecimal code of a character in a box
29726 `empty-box': display as an empty box
29727 `thin-space': display as 1-pixel width space
29728 `zero-width': don't display
29729 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29730 display method for graphical terminals and text terminals respectively.
29731 GRAPHICAL and TEXT should each have one of the values listed above.
29732
29733 The char-table has one extra slot to control the display of a character for
29734 which no font is found. This slot only takes effect on graphical terminals.
29735 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29736 `thin-space'. The default is `empty-box'. */);
29737 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29738 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29739 Qempty_box);
29740
29741 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29742 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29743 Vdebug_on_message = Qnil;
29744 }
29745
29746
29747 /* Initialize this module when Emacs starts. */
29748
29749 void
29750 init_xdisp (void)
29751 {
29752 current_header_line_height = current_mode_line_height = -1;
29753
29754 CHARPOS (this_line_start_pos) = 0;
29755
29756 if (!noninteractive)
29757 {
29758 struct window *m = XWINDOW (minibuf_window);
29759 Lisp_Object frame = m->frame;
29760 struct frame *f = XFRAME (frame);
29761 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29762 struct window *r = XWINDOW (root);
29763 int i;
29764
29765 echo_area_window = minibuf_window;
29766
29767 r->top_line = FRAME_TOP_MARGIN (f);
29768 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29769 r->total_cols = FRAME_COLS (f);
29770
29771 m->top_line = FRAME_LINES (f) - 1;
29772 m->total_lines = 1;
29773 m->total_cols = FRAME_COLS (f);
29774
29775 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29776 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29777 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29778
29779 /* The default ellipsis glyphs `...'. */
29780 for (i = 0; i < 3; ++i)
29781 default_invis_vector[i] = make_number ('.');
29782 }
29783
29784 {
29785 /* Allocate the buffer for frame titles.
29786 Also used for `format-mode-line'. */
29787 int size = 100;
29788 mode_line_noprop_buf = xmalloc (size);
29789 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29790 mode_line_noprop_ptr = mode_line_noprop_buf;
29791 mode_line_target = MODE_LINE_DISPLAY;
29792 }
29793
29794 help_echo_showing_p = 0;
29795 }
29796
29797 /* Platform-independent portion of hourglass implementation. */
29798
29799 /* Cancel a currently active hourglass timer, and start a new one. */
29800 void
29801 start_hourglass (void)
29802 {
29803 #if defined (HAVE_WINDOW_SYSTEM)
29804 EMACS_TIME delay;
29805
29806 cancel_hourglass ();
29807
29808 if (INTEGERP (Vhourglass_delay)
29809 && XINT (Vhourglass_delay) > 0)
29810 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29811 TYPE_MAXIMUM (time_t)),
29812 0);
29813 else if (FLOATP (Vhourglass_delay)
29814 && XFLOAT_DATA (Vhourglass_delay) > 0)
29815 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29816 else
29817 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29818
29819 #ifdef HAVE_NTGUI
29820 {
29821 extern void w32_note_current_window (void);
29822 w32_note_current_window ();
29823 }
29824 #endif /* HAVE_NTGUI */
29825
29826 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29827 show_hourglass, NULL);
29828 #endif
29829 }
29830
29831
29832 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29833 shown. */
29834 void
29835 cancel_hourglass (void)
29836 {
29837 #if defined (HAVE_WINDOW_SYSTEM)
29838 if (hourglass_atimer)
29839 {
29840 cancel_atimer (hourglass_atimer);
29841 hourglass_atimer = NULL;
29842 }
29843
29844 if (hourglass_shown_p)
29845 hide_hourglass ();
29846 #endif
29847 }